aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-01-04 21:39:15 +0800
committerobscuren <geffobscura@gmail.com>2015-01-04 21:39:15 +0800
commit987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9 (patch)
tree32ff13edca8c3d9b61b303f7d314291d0f216574 /core
parent1b905675465d96227f1a8144fe592e76f646f559 (diff)
parent08b03afa4bb3a40d2faf6543bc884a8ece5be2a1 (diff)
downloadgo-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.tar
go-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.tar.gz
go-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.tar.bz2
go-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.tar.lz
go-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.tar.xz
go-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.tar.zst
go-tangerine-987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9.zip
Merge branch 'poc8' into docbranch
Diffstat (limited to 'core')
-rw-r--r--core/block_manager.go25
-rw-r--r--core/chain_manager.go16
-rw-r--r--core/dagger.go160
-rw-r--r--core/dagger_test.go19
-rw-r--r--core/state_transition.go41
-rw-r--r--core/vm_env.go13
6 files changed, 46 insertions, 228 deletions
diff --git a/core/block_manager.go b/core/block_manager.go
index 8a5455306..76385ea1f 100644
--- a/core/block_manager.go
+++ b/core/block_manager.go
@@ -6,7 +6,6 @@ import (
"fmt"
"math/big"
"sync"
- "time"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
@@ -22,18 +21,6 @@ import (
var statelogger = logger.NewLogger("BLOCK")
-type Peer interface {
- Inbound() bool
- LastSend() time.Time
- LastPong() int64
- Host() []byte
- Port() uint16
- Version() string
- PingTime() string
- Connected() *int32
- Caps() *ethutil.Value
-}
-
type EthManager interface {
BlockManager() *BlockManager
ChainManager() *ChainManager
@@ -113,7 +100,7 @@ done:
txGas := new(big.Int).Set(tx.Gas())
cb := state.GetStateObject(coinbase.Address())
- st := NewStateTransition(cb, tx, state, block)
+ st := NewStateTransition(NewEnv(state, self.bc, tx, block), tx, cb)
_, err = st.TransitionState()
if err != nil {
switch {
@@ -232,6 +219,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
// Sync the current block's state to the database and cancelling out the deferred Undo
state.Sync()
+ state.Manifest().SetHash(block.Hash())
+
messages := state.Manifest().Messages
state.Manifest().Reset()
@@ -339,10 +328,10 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
account.AddAmount(reward)
statedb.Manifest().AddMessage(&state.Message{
- To: block.Header().Coinbase,
- Input: nil,
- Origin: nil,
- Block: block.Hash(), Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
+ To: block.Header().Coinbase,
+ Input: nil,
+ Origin: nil,
+ Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
Value: new(big.Int).Add(reward, block.Reward),
})
diff --git a/core/chain_manager.go b/core/chain_manager.go
index ece98d783..82b17cd93 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -271,15 +271,15 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
self.mu.RLock()
defer self.mu.RUnlock()
- block := self.currentBlock
- for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
- if block.Header().Number.Uint64() == num {
- break
- }
- }
+ var block *types.Block
- if block != nil && block.Header().Number.Uint64() == 0 && num != 0 {
- return nil
+ if num <= self.currentBlock.Number().Uint64() {
+ block = self.currentBlock
+ for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
+ if block.Header().Number.Uint64() == num {
+ break
+ }
+ }
}
return block
diff --git a/core/dagger.go b/core/dagger.go
deleted file mode 100644
index 3039d8995..000000000
--- a/core/dagger.go
+++ /dev/null
@@ -1,160 +0,0 @@
-package core
-
-import (
- "hash"
- "math/big"
- "math/rand"
- "time"
-
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/obscuren/sha3"
-)
-
-var powlogger = logger.NewLogger("POW")
-
-type Dagger struct {
- hash *big.Int
- xn *big.Int
-}
-
-var Found bool
-
-func (dag *Dagger) Find(obj *big.Int, resChan chan int64) {
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
-
- for i := 0; i < 1000; i++ {
- rnd := r.Int63()
-
- res := dag.Eval(big.NewInt(rnd))
- powlogger.Infof("rnd %v\nres %v\nobj %v\n", rnd, res, obj)
- if res.Cmp(obj) < 0 {
- // Post back result on the channel
- resChan <- rnd
- // Notify other threads we've found a valid nonce
- Found = true
- }
-
- // Break out if found
- if Found {
- break
- }
- }
-
- resChan <- 0
-}
-
-func (dag *Dagger) Search(hash, diff *big.Int) *big.Int {
- // TODO fix multi threading. Somehow it results in the wrong nonce
- amountOfRoutines := 1
-
- dag.hash = hash
-
- obj := ethutil.BigPow(2, 256)
- obj = obj.Div(obj, diff)
-
- Found = false
- resChan := make(chan int64, 3)
- var res int64
-
- for k := 0; k < amountOfRoutines; k++ {
- go dag.Find(obj, resChan)
-
- // Wait for each go routine to finish
- }
- for k := 0; k < amountOfRoutines; k++ {
- // Get the result from the channel. 0 = quit
- if r := <-resChan; r != 0 {
- res = r
- }
- }
-
- return big.NewInt(res)
-}
-
-func (dag *Dagger) Verify(hash, diff, nonce *big.Int) bool {
- dag.hash = hash
-
- obj := ethutil.BigPow(2, 256)
- obj = obj.Div(obj, diff)
-
- return dag.Eval(nonce).Cmp(obj) < 0
-}
-
-func DaggerVerify(hash, diff, nonce *big.Int) bool {
- dagger := &Dagger{}
- dagger.hash = hash
-
- obj := ethutil.BigPow(2, 256)
- obj = obj.Div(obj, diff)
-
- return dagger.Eval(nonce).Cmp(obj) < 0
-}
-
-func (dag *Dagger) Node(L uint64, i uint64) *big.Int {
- if L == i {
- return dag.hash
- }
-
- var m *big.Int
- if L == 9 {
- m = big.NewInt(16)
- } else {
- m = big.NewInt(3)
- }
-
- sha := sha3.NewKeccak256()
- sha.Reset()
- d := sha3.NewKeccak256()
- b := new(big.Int)
- ret := new(big.Int)
-
- for k := 0; k < int(m.Uint64()); k++ {
- d.Reset()
- d.Write(dag.hash.Bytes())
- d.Write(dag.xn.Bytes())
- d.Write(big.NewInt(int64(L)).Bytes())
- d.Write(big.NewInt(int64(i)).Bytes())
- d.Write(big.NewInt(int64(k)).Bytes())
-
- b.SetBytes(Sum(d))
- pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1)
- sha.Write(dag.Node(L-1, pk).Bytes())
- }
-
- ret.SetBytes(Sum(sha))
-
- return ret
-}
-
-func Sum(sha hash.Hash) []byte {
- //in := make([]byte, 32)
- return sha.Sum(nil)
-}
-
-func (dag *Dagger) Eval(N *big.Int) *big.Int {
- pow := ethutil.BigPow(2, 26)
- dag.xn = pow.Div(N, pow)
-
- sha := sha3.NewKeccak256()
- sha.Reset()
- ret := new(big.Int)
-
- for k := 0; k < 4; k++ {
- d := sha3.NewKeccak256()
- b := new(big.Int)
-
- d.Reset()
- d.Write(dag.hash.Bytes())
- d.Write(dag.xn.Bytes())
- d.Write(N.Bytes())
- d.Write(big.NewInt(int64(k)).Bytes())
-
- b.SetBytes(Sum(d))
- pk := (b.Uint64() & 0x1ffffff)
-
- sha.Write(dag.Node(9, pk).Bytes())
- }
-
- return ret.SetBytes(Sum(sha))
-}
diff --git a/core/dagger_test.go b/core/dagger_test.go
deleted file mode 100644
index e80064e6b..000000000
--- a/core/dagger_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package core
-
-import (
- "math/big"
- "testing"
-
- "github.com/ethereum/go-ethereum/ethutil"
-)
-
-func BenchmarkDaggerSearch(b *testing.B) {
- hash := big.NewInt(0)
- diff := ethutil.BigPow(2, 36)
- o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity
-
- // Reset timer so the big generation isn't included in the benchmark
- b.ResetTimer()
- // Validate
- DaggerVerify(hash, diff, o)
-}
diff --git a/core/state_transition.go b/core/state_transition.go
index 91cfd5fe3..b22c5bf21 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -4,7 +4,6 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
@@ -28,18 +27,17 @@ import (
* 6) Derive new state root
*/
type StateTransition struct {
- coinbase, receiver []byte
- msg Message
- gas, gasPrice *big.Int
- initialGas *big.Int
- value *big.Int
- data []byte
- state *state.StateDB
- block *types.Block
+ coinbase []byte
+ msg Message
+ gas, gasPrice *big.Int
+ initialGas *big.Int
+ value *big.Int
+ data []byte
+ state *state.StateDB
cb, rec, sen *state.StateObject
- Env vm.Environment
+ env vm.Environment
}
type Message interface {
@@ -69,16 +67,19 @@ func MessageGasValue(msg Message) *big.Int {
return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
}
-func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
- return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
-}
-
-func (self *StateTransition) VmEnv() vm.Environment {
- if self.Env == nil {
- self.Env = NewEnv(self.state, self.msg, self.block)
+func NewStateTransition(env vm.Environment, msg Message, coinbase *state.StateObject) *StateTransition {
+ return &StateTransition{
+ coinbase: coinbase.Address(),
+ env: env,
+ msg: msg,
+ gas: new(big.Int),
+ gasPrice: new(big.Int).Set(msg.GasPrice()),
+ initialGas: new(big.Int),
+ value: msg.Value(),
+ data: msg.Data(),
+ state: env.State(),
+ cb: coinbase,
}
-
- return self.Env
}
func (self *StateTransition) Coinbase() *state.StateObject {
@@ -183,7 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
return
}
- vmenv := self.VmEnv()
+ vmenv := self.env
var ref vm.ContextRef
if MessageCreatesContract(msg) {
contract := MakeContract(msg, self.state)
diff --git a/core/vm_env.go b/core/vm_env.go
index 4e0315ff3..624a63333 100644
--- a/core/vm_env.go
+++ b/core/vm_env.go
@@ -13,10 +13,12 @@ type VMEnv struct {
block *types.Block
msg Message
depth int
+ chain *ChainManager
}
-func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
+func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, block *types.Block) *VMEnv {
return &VMEnv{
+ chain: chain,
state: state,
block: block,
msg: msg,
@@ -25,16 +27,21 @@ func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
func (self *VMEnv) Origin() []byte { return self.msg.From() }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
-func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) Depth() int { return self.depth }
func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+ if block := self.chain.GetBlockByNumber(n); block != nil {
+ return block.Hash()
+ }
+
+ return nil
+}
func (self *VMEnv) AddLog(log state.Log) {
self.state.AddLog(log)
}