aboutsummaryrefslogtreecommitdiffstats
path: root/core/blockchain_test.go
diff options
context:
space:
mode:
authorJeffrey Wilcke <geffobscura@gmail.com>2016-03-08 01:11:52 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2016-03-08 23:12:48 +0800
commitba3fb9e6f4c47edbb0ff99285a0b48dc4bd3f37c (patch)
tree33f5381f85d0ae776bf14dd25141021598df3d6b /core/blockchain_test.go
parentd45f01d5f782857c6a65f65fdc67b630a8f028bd (diff)
downloaddexon-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.go80
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):
+ }
+
+}