|
|
@@ -25,6 +25,7 @@ import (
|
|
|
"time"
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
+ "github.com/ethereum/go-ethereum/consensus"
|
|
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
|
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
|
"github.com/ethereum/go-ethereum/core/state"
|
|
|
@@ -35,6 +36,39 @@ import (
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
|
)
|
|
|
|
|
|
+// So we can deterministically seed different blockchains
|
|
|
+var (
|
|
|
+ canonicalSeed = 1
|
|
|
+ forkSeed = 2
|
|
|
+)
|
|
|
+
|
|
|
+// newCanonical creates a chain database, and injects a deterministic canonical
|
|
|
+// chain. Depending on the full flag, if creates either a full block chain or a
|
|
|
+// header only chain.
|
|
|
+func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
|
|
|
+ var (
|
|
|
+ db = ethdb.NewMemDatabase()
|
|
|
+ genesis = new(Genesis).MustCommit(db)
|
|
|
+ )
|
|
|
+
|
|
|
+ // Initialize a fresh chain with only a genesis block
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
|
|
|
+ // Create and inject the requested chain
|
|
|
+ if n == 0 {
|
|
|
+ return db, blockchain, nil
|
|
|
+ }
|
|
|
+ if full {
|
|
|
+ // Full block-chain requested
|
|
|
+ blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
|
|
|
+ _, err := blockchain.InsertChain(blocks)
|
|
|
+ return db, blockchain, err
|
|
|
+ }
|
|
|
+ // Header-only chain requested
|
|
|
+ headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
|
|
|
+ _, err := blockchain.InsertHeaderChain(headers, 1)
|
|
|
+ return db, blockchain, err
|
|
|
+}
|
|
|
+
|
|
|
// Test fork of length N starting from block i
|
|
|
func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
|
|
|
// Copy old chain up to #i into a new db
|