diff options
author | Péter Szilágyi <peterke@gmail.com> | 2017-03-23 23:36:38 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-23 23:36:38 +0800 |
commit | 8771c3061f340451d0966adcc547338a25f2231f (patch) | |
tree | c566cab81cf95a39f85fbe2c98a932af9495eb68 /eth | |
parent | 11e7a712f469fb24ddb88ecebcefab6ed8880eb8 (diff) | |
parent | 37dd9086ec491900311fc39837f4a62ef5fd3a4a (diff) | |
download | go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.tar go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.tar.gz go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.tar.bz2 go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.tar.lz go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.tar.xz go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.tar.zst go-tangerine-8771c3061f340451d0966adcc547338a25f2231f.zip |
Merge pull request #3794 from fjl/core-genesis-refactor
core: refactor genesis handling
Diffstat (limited to 'eth')
-rw-r--r-- | eth/backend.go | 87 | ||||
-rw-r--r-- | eth/backend_test.go | 2 | ||||
-rw-r--r-- | eth/filters/filter_system_test.go | 11 | ||||
-rw-r--r-- | eth/filters/filter_test.go | 6 | ||||
-rw-r--r-- | eth/handler_test.go | 13 | ||||
-rw-r--r-- | eth/helper_test.go | 24 |
6 files changed, 53 insertions, 90 deletions
diff --git a/eth/backend.go b/eth/backend.go index ef951a6c2..b8df98976 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -18,11 +18,9 @@ package eth import ( - "errors" "fmt" "math/big" "regexp" - "strings" "sync" "time" @@ -60,15 +58,17 @@ var ( ) type Config struct { - ChainConfig *params.ChainConfig // chain configuration + // The genesis block, which is inserted if the database is empty. + // If nil, the Ethereum main net block is used. + Genesis *core.Genesis - NetworkId int // Network ID to use for selecting peers to connect to - Genesis string // Genesis JSON to seed the chain database with - FastSync bool // Enables the state download based fast synchronisation algorithm - LightMode bool // Running in light client mode - LightServ int // Maximum percentage of time allowed for serving LES requests - LightPeers int // Maximum number of LES client peers - MaxPeers int // Maximum number of global peers + NetworkId int // Network ID to use for selecting peers to connect to + + FastSync bool // Enables the state download based fast synchronisation algorithm + LightMode bool // Running in light client mode + LightServ int // Maximum percentage of time allowed for serving LES requests + LightPeers int // Maximum number of LES client peers + MaxPeers int // Maximum number of global peers SkipBcVersionCheck bool // e.g. blockchain export DatabaseCache int @@ -100,9 +100,6 @@ type Config struct { GpobaseCorrectionFactor int EnablePreimageRecording bool - - TestGenesisBlock *types.Block // Genesis block to seed the chain database with (testing only!) - TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!) } type LesServer interface { @@ -155,11 +152,15 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { return nil, err } stopDbUpgrade := upgradeSequentialKeys(chainDb) - if err := SetupGenesisBlock(&chainDb, config); err != nil { - return nil, err + chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) + if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { + return nil, genesisErr } + log.Info("Initialised chain configuration", "config", chainConfig) + eth := &Ethereum{ chainDb: chainDb, + chainConfig: chainConfig, eventMux: ctx.EventMux, accountManager: ctx.AccountManager, pow: CreatePoW(ctx, config), @@ -184,33 +185,18 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { core.WriteBlockChainVersion(chainDb, core.BlockChainVersion) } - // load the genesis block or write a new one if no genesis - // block is prenent in the database. - genesis := core.GetBlock(chainDb, core.GetCanonicalHash(chainDb, 0), 0) - if genesis == nil { - genesis, err = core.WriteDefaultGenesisBlock(chainDb) - if err != nil { - return nil, err - } - log.Warn("Wrote default Ethereum genesis block") - } - - if config.ChainConfig == nil { - return nil, errors.New("missing chain config") - } - core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig) - - eth.chainConfig = config.ChainConfig - - log.Info("Initialised chain configuration", "config", eth.chainConfig) - - eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.EventMux(), vm.Config{EnablePreimageRecording: config.EnablePreimageRecording}) + vmConfig := vm.Config{EnablePreimageRecording: config.EnablePreimageRecording} + eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.eventMux, vmConfig) if err != nil { - if err == core.ErrNoGenesis { - return nil, fmt.Errorf(`No chain found. Please initialise a new chain using the "init" subcommand.`) - } return nil, err } + // Rewind the chain in case of an incompatible config upgrade. + if compat, ok := genesisErr.(*params.ConfigCompatError); ok { + log.Warn("Rewinding chain to upgrade configuration", "err", compat) + eth.blockchain.SetHead(compat.RewindTo) + core.WriteChainConfig(chainDb, genesisHash, chainConfig) + } + newPool := core.NewTxPool(eth.chainConfig, eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit) eth.txPool = newPool @@ -255,29 +241,6 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data return db, err } -// SetupGenesisBlock initializes the genesis block for an Ethereum service -func SetupGenesisBlock(chainDb *ethdb.Database, config *Config) error { - // Load up any custom genesis block if requested - if len(config.Genesis) > 0 { - block, err := core.WriteGenesisBlock(*chainDb, strings.NewReader(config.Genesis)) - if err != nil { - return err - } - log.Info("Successfully wrote custom genesis block", "hash", block.Hash()) - } - // Load up a test setup if directly injected - if config.TestGenesisState != nil { - *chainDb = config.TestGenesisState - } - if config.TestGenesisBlock != nil { - core.WriteTd(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty()) - core.WriteBlock(*chainDb, config.TestGenesisBlock) - core.WriteCanonicalHash(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64()) - core.WriteHeadBlockHash(*chainDb, config.TestGenesisBlock.Hash()) - } - return nil -} - // CreatePoW creates the required type of PoW instance for an Ethereum service func CreatePoW(ctx *node.ServiceContext, config *Config) pow.PoW { switch { diff --git a/eth/backend_test.go b/eth/backend_test.go index 574731fbe..f60e3214c 100644 --- a/eth/backend_test.go +++ b/eth/backend_test.go @@ -30,7 +30,7 @@ import ( func TestMipmapUpgrade(t *testing.T) { db, _ := ethdb.NewMemDatabase() addr := common.BytesToAddress([]byte("jeff")) - genesis := core.WriteGenesisBlockForTesting(db) + genesis := new(core.Genesis).MustCommit(db) chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) { var receipts types.Receipts diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index d9c245a85..822580b56 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -72,12 +72,11 @@ func TestBlockSubscription(t *testing.T) { t.Parallel() var ( - mux = new(event.TypeMux) - db, _ = ethdb.NewMemDatabase() - backend = &testBackend{mux, db} - api = NewPublicFilterAPI(backend, false) - - genesis = core.WriteGenesisBlockForTesting(db) + mux = new(event.TypeMux) + db, _ = ethdb.NewMemDatabase() + backend = &testBackend{mux, db} + api = NewPublicFilterAPI(backend, false) + genesis = new(core.Genesis).MustCommit(db) chain, _ = core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) {}) chainEvents = []core.ChainEvent{} ) diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index c2dc2b842..cd5e7cafd 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -60,7 +60,7 @@ func BenchmarkMipmaps(b *testing.B) { ) defer db.Close() - genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr1, Balance: big.NewInt(1000000)}) + genesis := core.GenesisBlockForTesting(db, addr1, big.NewInt(1000000)) chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 100010, func(i int, gen *core.BlockGen) { var receipts types.Receipts switch i { @@ -112,7 +112,7 @@ func BenchmarkMipmaps(b *testing.B) { for i := 0; i < b.N; i++ { logs, _ := filter.Find(context.Background()) if len(logs) != 4 { - b.Fatal("expected 4 log, got", len(logs)) + b.Fatal("expected 4 logs, got", len(logs)) } } } @@ -138,7 +138,7 @@ func TestFilters(t *testing.T) { ) defer db.Close() - genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr, Balance: big.NewInt(1000000)}) + genesis := core.GenesisBlockForTesting(db, addr, big.NewInt(1000000)) chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 1000, func(i int, gen *core.BlockGen) { var receipts types.Receipts switch i { diff --git a/eth/handler_test.go b/eth/handler_test.go index 683c8f71e..31435b331 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -315,12 +315,12 @@ func testGetNodeData(t *testing.T, protocol int) { switch i { case 0: // In block 1, the test bank sends account #1 some ether. - tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) block.AddTx(tx) case 1: // In block 2, the test bank sends some more ether to account #1. // acc1Addr passes it on to account #2. - tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) + tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key) block.AddTx(tx1) block.AddTx(tx2) @@ -372,7 +372,7 @@ func testGetNodeData(t *testing.T, protocol int) { for i := 0; i < len(data); i++ { statedb.Put(hashes[i].Bytes(), data[i]) } - accounts := []common.Address{testBank.Address, acc1Addr, acc2Addr} + accounts := []common.Address{testBank, acc1Addr, acc2Addr} for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ { trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), statedb) @@ -407,12 +407,12 @@ func testGetReceipt(t *testing.T, protocol int) { switch i { case 0: // In block 1, the test bank sends account #1 some ether. - tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey) block.AddTx(tx) case 1: // In block 2, the test bank sends some more ether to account #1. // acc1Addr passes it on to account #2. - tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) + tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey) tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key) block.AddTx(tx1) block.AddTx(tx2) @@ -471,8 +471,9 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool evmux = new(event.TypeMux) pow = new(pow.FakePow) db, _ = ethdb.NewMemDatabase() - genesis = core.WriteGenesisBlockForTesting(db) config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked} + gspec = &core.Genesis{Config: config} + genesis = gspec.MustCommit(db) blockchain, _ = core.NewBlockChain(db, config, pow, evmux, vm.Config{}) ) pm, err := NewProtocolManager(config, false, NetworkId, 1000, evmux, new(testTxPool), pow, blockchain, db) diff --git a/eth/helper_test.go b/eth/helper_test.go index 3ad31394a..e67b49691 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -42,10 +42,7 @@ import ( var ( testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - testBank = core.GenesisAccount{ - Address: crypto.PubkeyToAddress(testBankKey.PublicKey), - Balance: big.NewInt(1000000), - } + testBank = crypto.PubkeyToAddress(testBankKey.PublicKey) ) // newTestProtocolManager creates a new protocol manager for testing purposes, @@ -53,19 +50,22 @@ var ( // channels for different events. func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) { var ( - evmux = new(event.TypeMux) - pow = new(pow.FakePow) - db, _ = ethdb.NewMemDatabase() - genesis = core.WriteGenesisBlockForTesting(db, testBank) - chainConfig = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker - blockchain, _ = core.NewBlockChain(db, chainConfig, pow, evmux, vm.Config{}) + evmux = new(event.TypeMux) + pow = new(pow.FakePow) + db, _ = ethdb.NewMemDatabase() + gspec = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}}, + } + genesis = gspec.MustCommit(db) + blockchain, _ = core.NewBlockChain(db, gspec.Config, pow, evmux, vm.Config{}) ) - chain, _ := core.GenerateChain(chainConfig, genesis, db, blocks, generator) + chain, _ := core.GenerateChain(gspec.Config, genesis, db, blocks, generator) if _, err := blockchain.InsertChain(chain); err != nil { panic(err) } - pm, err := NewProtocolManager(chainConfig, fastSync, NetworkId, 1000, evmux, &testTxPool{added: newtx}, pow, blockchain, db) + pm, err := NewProtocolManager(gspec.Config, fastSync, NetworkId, 1000, evmux, &testTxPool{added: newtx}, pow, blockchain, db) if err != nil { return nil, err } |