diff options
author | Jeffrey Wilcke <geffobscura@gmail.com> | 2016-03-08 01:11:52 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2016-03-08 23:12:48 +0800 |
commit | ba3fb9e6f4c47edbb0ff99285a0b48dc4bd3f37c (patch) | |
tree | 33f5381f85d0ae776bf14dd25141021598df3d6b /core/blockchain_test.go | |
parent | d45f01d5f782857c6a65f65fdc67b630a8f028bd (diff) | |
download | dexon-ba3fb9e6f4c47edbb0ff99285a0b48dc4bd3f37c.tar.gz dexon-ba3fb9e6f4c47edbb0ff99285a0b48dc4bd3f37c.tar.zst dexon-ba3fb9e6f4c47edbb0ff99285a0b48dc4bd3f37c.zip |
core: announce ChainSideEvent during reorg
Previously all blocks that were already in our chain were never re
announced as potential uncle block (e.g. ChainSideEvent). This is
problematic during mining where you want to gather as much possible
uncles as possible increasing the profit. This is now addressed in this
PR where during reorganisations of chains the old chain is regarded as
uncles.
Fixed #2298
Diffstat (limited to 'core/blockchain_test.go')
-rw-r--r-- | core/blockchain_test.go | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 1bb5f646d..a7d3ea56e 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -25,6 +25,7 @@ import ( "runtime" "strconv" "testing" + "time" "github.com/ethereum/ethash" "github.com/ethereum/go-ethereum/common" @@ -1006,3 +1007,82 @@ func TestLogReorgs(t *testing.T) { t.Error("expected logs") } } + +func TestReorgSideEvent(t *testing.T) { + var ( + db, _ = ethdb.NewMemDatabase() + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + genesis = WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(10000000000000)}) + ) + + evmux := &event.TypeMux{} + blockchain, _ := NewBlockChain(db, FakePow{}, evmux) + + chain, _ := GenerateChain(genesis, db, 3, func(i int, gen *BlockGen) { + if i == 2 { + gen.OffsetTime(9) + } + }) + if _, err := blockchain.InsertChain(chain); err != nil { + t.Fatalf("failed to insert chain: %v", err) + } + + replacementBlocks, _ := GenerateChain(genesis, db, 4, func(i int, gen *BlockGen) { + tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key1) + if err != nil { + t.Fatalf("failed to create tx: %v", err) + } + gen.AddTx(tx) + }) + + subs := evmux.Subscribe(ChainSideEvent{}) + if _, err := blockchain.InsertChain(replacementBlocks); err != nil { + t.Fatalf("failed to insert chain: %v", err) + } + + // first two block of the secondary chain are for a brief moment considered + // side chains because up to that point the first one is considered the + // heavier chain. + expectedSideHashes := map[common.Hash]bool{ + replacementBlocks[0].Hash(): true, + replacementBlocks[1].Hash(): true, + chain[0].Hash(): true, + chain[1].Hash(): true, + chain[2].Hash(): true, + } + + i := 0 + + const timeoutDura = 10 * time.Second + timeout := time.NewTimer(timeoutDura) +done: + for { + select { + case ev := <-subs.Chan(): + block := ev.Data.(ChainSideEvent).Block + if _, ok := expectedSideHashes[block.Hash()]; !ok { + t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) + } + i++ + + if i == len(expectedSideHashes) { + timeout.Stop() + + break done + } + timeout.Reset(timeoutDura) + + case <-timeout.C: + t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") + } + } + + // make sure no more events are fired + select { + case e := <-subs.Chan(): + t.Errorf("unexectped event fired: %v", e) + case <-time.After(250 * time.Millisecond): + } + +} |