diff options
author | obscuren <geffobscura@gmail.com> | 2015-01-04 21:39:15 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-01-04 21:39:15 +0800 |
commit | 987119cd4adcdbc7ebfd0bbb027a0c9e2a7487e9 (patch) | |
tree | 32ff13edca8c3d9b61b303f7d314291d0f216574 /core | |
parent | 1b905675465d96227f1a8144fe592e76f646f559 (diff) | |
parent | 08b03afa4bb3a40d2faf6543bc884a8ece5be2a1 (diff) | |
download | go-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.go | 25 | ||||
-rw-r--r-- | core/chain_manager.go | 16 | ||||
-rw-r--r-- | core/dagger.go | 160 | ||||
-rw-r--r-- | core/dagger_test.go | 19 | ||||
-rw-r--r-- | core/state_transition.go | 41 | ||||
-rw-r--r-- | core/vm_env.go | 13 |
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) } |