diff --git a/chain/block_manager.go b/chain/block_manager.go index e652ad10e1..4707c83800 100644 --- a/chain/block_manager.go +++ b/chain/block_manager.go @@ -3,7 +3,7 @@ package chain import ( "bytes" "container/list" - "errors" + // "errors" "fmt" "math/big" "sync" @@ -266,11 +266,15 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I sm.transState = state.Copy() + // XXX: the only reference to the eth object + // if this could be moved to BlockManager, testing wouldn't require + // the eth object sm.eth.TxPool().RemoveSet(block.Transactions()) return td, messages, nil } else { - return nil, nil, errors.New("total diff failed") + // this is a fork, so return the td + return td, nil, nil } } @@ -288,16 +292,12 @@ func (sm *BlockManager) ApplyDiff(state *state.State, parent, block *types.Block } func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) { - uncleDiff := new(big.Int) - for _, uncle := range block.Uncles { - uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) + td, err := sm.bc.CalcTotalDiff(block) + if err != nil { + fmt.Println(err) + return nil, false } - // TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty - td := new(big.Int) - td = td.Add(sm.bc.TD, uncleDiff) - td = td.Add(td, block.Difficulty) - // The new TD will only be accepted if the new difficulty is // is greater than the previous. if td.Cmp(sm.bc.TD) > 0 { @@ -307,7 +307,7 @@ func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) { //sm.bc.SetTotalDifficulty(td) } - return nil, false + return td, false } // Validates the current block. Returns an error if the block was invalid, diff --git a/chain/chain_manager_test.go b/chain/chain_manager_test.go index f93ca5840e..1849c48f5e 100644 --- a/chain/chain_manager_test.go +++ b/chain/chain_manager_test.go @@ -1,19 +1,19 @@ package chain import ( + "container/list" "fmt" "math/big" "testing" "time" - "container/list" "github.com/ethereum/go-ethereum/chain/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/wire" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/crypto" ) // In these tests, TD = block.Number @@ -33,27 +33,28 @@ func (self fakeproc) ProcessWithParent(a, b *types.Block) (*big.Int, state.Messa } // So we can generate blocks easily -type fakePow struct {} -func (f fakePow) Search(block *types.Block, stop <-chan struct{}) []byte{return nil} -func (f fakePow) Verify(hash []byte, diff *big.Int, nonce []byte) bool {return true} -func (f fakePow) GetHashrate() int64 {return 0} -func (f fakePow) Turbo(bool){} +type fakePow struct{} + +func (f fakePow) Search(block *types.Block, stop <-chan struct{}) []byte { return nil } +func (f fakePow) Verify(hash []byte, diff *big.Int, nonce []byte) bool { return true } +func (f fakePow) GetHashrate() int64 { return 0 } +func (f fakePow) Turbo(bool) {} // We need this guy because ProcessWithParent clears txs from the pool type fakeEth struct{} -func (e *fakeEth) BlockManager() *BlockManager{ return nil } -func (e *fakeEth) ChainManager() *ChainManager{ return nil } -func (e *fakeEth) TxPool() *TxPool{ return &TxPool{} } -func (e *fakeEth) Broadcast(msgType wire.MsgType, data []interface{}){} -func (e *fakeEth) PeerCount() int {return 0} -func (e *fakeEth) IsMining() bool { return false } -func (e *fakeEth) IsListening() bool { return false } -func (e *fakeEth) Peers() *list.List { return nil } -func (e *fakeEth) KeyManager() *crypto.KeyManager { return nil } -func (e *fakeEth) ClientIdentity() wire.ClientIdentity { return nil } -func (e *fakeEth) Db() ethutil.Database { return nil } -func (e *fakeEth) EventMux() *event.TypeMux { return nil } +func (e *fakeEth) BlockManager() *BlockManager { return nil } +func (e *fakeEth) ChainManager() *ChainManager { return nil } +func (e *fakeEth) TxPool() *TxPool { return &TxPool{} } +func (e *fakeEth) Broadcast(msgType wire.MsgType, data []interface{}) {} +func (e *fakeEth) PeerCount() int { return 0 } +func (e *fakeEth) IsMining() bool { return false } +func (e *fakeEth) IsListening() bool { return false } +func (e *fakeEth) Peers() *list.List { return nil } +func (e *fakeEth) KeyManager() *crypto.KeyManager { return nil } +func (e *fakeEth) ClientIdentity() wire.ClientIdentity { return nil } +func (e *fakeEth) Db() ethutil.Database { return nil } +func (e *fakeEth) EventMux() *event.TypeMux { return nil } func makechain(cman *ChainManager, max int) *BlockChain { blocks := make(types.Blocks, max) @@ -69,49 +70,49 @@ func makechain(cman *ChainManager, max int) *BlockChain { } func makechain2(bman *BlockManager, max int) *BlockChain { - parent := bman.bc.CurrentBlock + parent := bman.bc.CurrentBlock blocks := make(types.Blocks, max) for i := 0; i < max; i++ { addr := ethutil.LeftPadBytes([]byte{byte(i)}, 20) block := bman.bc.NewBlock(addr) - cbase := block.State().GetOrNewStateObject(addr) - cbase.SetGasPool(block.CalcGasLimit(parent)) - receipts, txs, _, _, _ := bman.ProcessTransactions(cbase, block.State(), block, block, types.Transactions{}) - block.SetTransactions(txs) - block.SetReceipts(receipts) + cbase := block.State().GetOrNewStateObject(addr) + cbase.SetGasPool(block.CalcGasLimit(parent)) + receipts, txs, _, _, _ := bman.ProcessTransactions(cbase, block.State(), block, block, types.Transactions{}) + block.SetTransactions(txs) + block.SetReceipts(receipts) - bman.AccumelateRewards(block.State(), block, parent) + bman.AccumelateRewards(block.State(), block, parent) - block.State().Update() - lchain := NewChain(types.Blocks{block}) - _, err := bman.bc.TestChain(lchain) - if err != nil{ - fmt.Println("failed to run test chain!:", err) - } - bman.bc.InsertChain(lchain, func(block *types.Block, _ state.Messages){}) + block.State().Update() + lchain := NewChain(types.Blocks{block}) + _, err := bman.bc.TestChain(lchain) + if err != nil { + fmt.Println("failed to run test chain!:", err) + } + bman.bc.InsertChain(lchain, func(block *types.Block, _ state.Messages) {}) blocks[i] = block - parent = block + parent = block } return NewChain(blocks) } func TestShorterFork(t *testing.T) { cman := NewChainManager() - bman := &BlockManager{bc: cman, Pow: fakePow{}, eth:&fakeEth{}} + bman := &BlockManager{bc: cman, Pow: fakePow{}, eth: &fakeEth{}} bman.bc.SetProcessor(bman) makechain2(bman, 5) cman2 := NewChainManager() - cman2.Reset() // so we don't end up with last block of cman1 - bman2 := &BlockManager{bc: cman2, Pow: fakePow{}, eth:&fakeEth{}} + cman2.Reset() // so we don't end up with last block of cman1 + bman2 := &BlockManager{bc: cman2, Pow: fakePow{}, eth: &fakeEth{}} bman2.bc.SetProcessor(bman2) chainB := makechain2(bman2, 3) td2, err := bman.bc.TestChain(chainB) - if err != nil && !IsTDError(err){ + if err != nil && !IsTDError(err) { t.Error("expected chainB not to give errors:", err) }