mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
* refactor(all): cleanup the APIs for initializing genesis #25473 * fix(core): fix accessor mismatch for genesis state #26747
This commit is contained in:
parent
f744e86dd7
commit
e39a523260
18 changed files with 187 additions and 116 deletions
|
|
@ -103,7 +103,7 @@ func runCmd(ctx *cli.Context) error {
|
|||
gen := readGenesis(ctx.String(GenesisFlag.Name))
|
||||
genesisConfig = gen
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := gen.ToBlock(db)
|
||||
genesis := gen.MustCommit(db)
|
||||
statedb, _ = state.New(genesis.Root(), state.NewDatabase(db))
|
||||
chainConfig = gen.Config
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -161,9 +161,9 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
|
|||
|
||||
// Generate a chain of b.N blocks using the supplied block
|
||||
// generator function.
|
||||
gspec := Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
gspec := &Genesis{
|
||||
Alloc: types.GenesisAlloc{benchRootAddr: {Balance: benchRootFunds}},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis := gspec.MustCommit(db)
|
||||
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, b.N, gen)
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ func TestHeaderVerification(t *testing.T) {
|
|||
testdb = rawdb.NewMemoryDatabase()
|
||||
gspec = &Genesis{Config: params.TestChainConfig}
|
||||
genesis = gspec.MustCommit(testdb)
|
||||
blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil)
|
||||
blocks, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), testdb, 8, nil)
|
||||
)
|
||||
headers := make([]*types.Header, len(blocks))
|
||||
for i, block := range blocks {
|
||||
headers[i] = block.Header()
|
||||
}
|
||||
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
|
||||
chain, err := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{})
|
||||
chain, err := NewBlockChain(testdb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
|
||||
defer chain.Stop()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -592,9 +592,9 @@ func TestFastVsFullChains(t *testing.T) {
|
|||
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||
funds = big.NewInt(1000000000000000)
|
||||
gspec = &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{address: {Balance: funds}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(gendb)
|
||||
signer = types.LatestSigner(gspec.Config)
|
||||
|
|
@ -681,9 +681,9 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|||
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||
funds = big.NewInt(1000000000000000)
|
||||
gspec = &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{address: {Balance: funds}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(gendb)
|
||||
)
|
||||
|
|
@ -767,13 +767,13 @@ func TestChainTxReorgs(t *testing.T) {
|
|||
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
gspec = &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
GasLimit: 3141592,
|
||||
Alloc: types.GenesisAlloc{
|
||||
addr1: {Balance: big.NewInt(1000000000000000)},
|
||||
addr2: {Balance: big.NewInt(1000000000000000)},
|
||||
addr3: {Balance: big.NewInt(1000000000000000)},
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(db)
|
||||
signer = types.LatestSigner(gspec.Config)
|
||||
|
|
@ -878,8 +878,11 @@ func TestLogReorgs(t *testing.T) {
|
|||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
// this code generates a log
|
||||
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
||||
gspec = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
|
||||
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
|
||||
gspec = &Genesis{
|
||||
Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(db)
|
||||
signer = types.LatestSigner(gspec.Config)
|
||||
)
|
||||
|
|
@ -889,7 +892,7 @@ func TestLogReorgs(t *testing.T) {
|
|||
|
||||
rmLogsCh := make(chan RemovedLogsEvent)
|
||||
blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
|
||||
chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
|
||||
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
|
||||
if i == 1 {
|
||||
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
|
||||
if err != nil {
|
||||
|
|
@ -902,7 +905,7 @@ func TestLogReorgs(t *testing.T) {
|
|||
t.Fatalf("failed to insert chain: %v", err)
|
||||
}
|
||||
|
||||
chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
|
||||
chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
|
||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||
t.Fatalf("failed to insert forked chain: %v", err)
|
||||
}
|
||||
|
|
@ -1228,11 +1231,11 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
|||
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
gspec := &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis := gspec.MustCommit(db)
|
||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||
blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||
|
||||
// Generate a bunch of fork blocks, each side forking from the canonical chain
|
||||
forks := make([]*types.Block, len(blocks))
|
||||
|
|
@ -1241,7 +1244,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
|||
if i > 0 {
|
||||
parent = blocks[i-1]
|
||||
}
|
||||
fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||
fork, _ := GenerateChain(gspec.Config, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||
forks[i] = fork[0]
|
||||
}
|
||||
// Import the canonical and fork chain side by side, verifying the current block
|
||||
|
|
@ -1249,7 +1252,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
|||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
|
|
@ -1276,11 +1279,12 @@ func TestTrieForkGC(t *testing.T) {
|
|||
engine := ethash.NewFaker()
|
||||
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := (&Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
gspec := &Genesis{
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
}).MustCommit(db)
|
||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis := gspec.MustCommit(db)
|
||||
blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||
|
||||
// Generate a bunch of fork blocks, each side forking from the canonical chain
|
||||
forks := make([]*types.Block, len(blocks))
|
||||
|
|
@ -1289,17 +1293,14 @@ func TestTrieForkGC(t *testing.T) {
|
|||
if i > 0 {
|
||||
parent = blocks[i-1]
|
||||
}
|
||||
fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||
fork, _ := GenerateChain(gspec.Config, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||
forks[i] = fork[0]
|
||||
}
|
||||
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
(&Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
}).MustCommit(diskdb)
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
|
|
@ -1327,22 +1328,22 @@ func TestLargeReorgTrieGC(t *testing.T) {
|
|||
// Generate the original common chain segment and the two competing forks
|
||||
engine := ethash.NewFaker()
|
||||
gspec := &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := gspec.MustCommit(db)
|
||||
|
||||
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||
original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||
competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
|
||||
shared, _ := GenerateChain(gspec.Config, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
||||
original, _ := GenerateChain(gspec.Config, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||
competitor, _ := GenerateChain(gspec.Config, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
|
||||
|
||||
// Import the shared chain and the original canonical one
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
|
|
@ -1385,8 +1386,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
|||
testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
|
||||
bankFunds = big.NewInt(100000000000000000)
|
||||
gspec = Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
gspec = &Genesis{
|
||||
Alloc: GenesisAlloc{
|
||||
testBankAddress: {Balance: bankFunds},
|
||||
common.HexToAddress("0xc0de"): {
|
||||
|
|
@ -1394,6 +1394,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
|||
Balance: big.NewInt(0),
|
||||
}, // push 1, pop
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
GasLimit: 100e6, // 100 M
|
||||
}
|
||||
)
|
||||
|
|
@ -1416,7 +1417,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
|||
}
|
||||
}
|
||||
|
||||
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
|
||||
shared, _ := GenerateChain(gspec.Config, genesis, engine, db, numBlocks, blockGenerator)
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
|
@ -1424,7 +1425,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
|||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
|
|
@ -1710,10 +1711,10 @@ func TestTransientStorageReset(t *testing.T) {
|
|||
byte(vm.RETURN), // return 6 bytes of zero-code
|
||||
}...)
|
||||
gspec := &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{
|
||||
address: {Balance: funds},
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
nonce := uint64(0)
|
||||
signer := types.HomesteadSigner{}
|
||||
|
|
@ -1781,7 +1782,6 @@ func TestEIP3651(t *testing.T) {
|
|||
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
||||
funds = big.NewInt(8000000000000000)
|
||||
gspec = &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{
|
||||
addr1: {Balance: funds},
|
||||
addr2: {Balance: funds},
|
||||
|
|
@ -1813,6 +1813,7 @@ func TestEIP3651(t *testing.T) {
|
|||
Balance: big.NewInt(0),
|
||||
},
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -1899,7 +1900,6 @@ func TestDeleteCreateRevert(t *testing.T) {
|
|||
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||
funds = big.NewInt(10000000000000000)
|
||||
gspec = &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: GenesisAlloc{
|
||||
address: {Balance: funds},
|
||||
// The address 0xAAAAA selfdestructs if called
|
||||
|
|
@ -1925,11 +1925,12 @@ func TestDeleteCreateRevert(t *testing.T) {
|
|||
Balance: big.NewInt(1),
|
||||
},
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(db)
|
||||
)
|
||||
|
||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
|
||||
blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
|
||||
b.SetCoinbase(common.Address{1})
|
||||
// One transaction to AAAA
|
||||
tx, _ := types.SignTx(types.NewTransaction(0, aa,
|
||||
|
|
@ -1944,7 +1945,7 @@ func TestDeleteCreateRevert(t *testing.T) {
|
|||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(nil), engine, db, n, gen)
|
||||
blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen)
|
||||
return db, blocks, receipts
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||
}
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := gspec.MustCommit(db)
|
||||
prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
||||
prefix, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
||||
|
||||
// Create the concurrent, conflicting two nodes
|
||||
proDb := rawdb.NewMemoryDatabase()
|
||||
|
|
|
|||
107
core/genesis.go
107
core/genesis.go
|
|
@ -99,6 +99,63 @@ func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.Gene
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// hashAlloc computes the state root according to the genesis specification.
|
||||
func hashAlloc(ga *types.GenesisAlloc) (common.Hash, error) {
|
||||
// Create an ephemeral in-memory database for computing hash,
|
||||
// all the derived states will be discarded to not pollute disk.
|
||||
db := state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), nil)
|
||||
statedb, err := state.New(types.EmptyRootHash, db)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
for addr, account := range *ga {
|
||||
if account.Balance != nil {
|
||||
statedb.AddBalance(addr, account.Balance, tracing.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
for key, value := range account.Storage {
|
||||
statedb.SetState(addr, key, value)
|
||||
}
|
||||
}
|
||||
return statedb.Commit(0, false)
|
||||
}
|
||||
|
||||
// flushAlloc is very similar to hashAlloc, but the main difference is
|
||||
// all the generated states will be persisted into the given database.
|
||||
// Also, the genesis state specification will be flushed as well.
|
||||
func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, blockhash common.Hash) error {
|
||||
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(db))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for addr, account := range *ga {
|
||||
if account.Balance != nil {
|
||||
statedb.AddBalance(addr, account.Balance, tracing.BalanceIncreaseGenesisBalance)
|
||||
}
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
for key, value := range account.Storage {
|
||||
statedb.SetState(addr, key, value)
|
||||
}
|
||||
}
|
||||
root, err := statedb.Commit(0, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = statedb.Database().TrieDB().Commit(root, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Marshal the genesis state specification and persist.
|
||||
blob, err := json.Marshal(ga)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawdb.WriteGenesisStateSpec(db, blockhash, blob)
|
||||
return nil
|
||||
}
|
||||
|
||||
// field type overrides for gencodec
|
||||
type genesisSpecMarshaling struct {
|
||||
Nonce math.HexOrDecimal64
|
||||
|
|
@ -181,7 +238,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
|
|||
|
||||
// Check whether the genesis block is already written.
|
||||
if genesis != nil {
|
||||
hash := genesis.ToBlock(nil).Hash()
|
||||
hash := genesis.ToBlock().Hash()
|
||||
if hash != stored {
|
||||
return genesis.Config, hash, &GenesisMismatchError{stored, hash}
|
||||
}
|
||||
|
|
@ -248,22 +305,12 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
|||
}
|
||||
}
|
||||
|
||||
// ToBlock creates the genesis block and writes state of a genesis specification
|
||||
// to the given database (or discards it if nil).
|
||||
func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
||||
if db == nil {
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
// ToBlock returns the genesis block according to genesis specification.
|
||||
func (g *Genesis) ToBlock() *types.Block {
|
||||
root, err := hashAlloc(&g.Alloc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(db))
|
||||
for addr, account := range g.Alloc {
|
||||
statedb.AddBalance(addr, account.Balance, tracing.BalanceIncreaseGenesisBalance)
|
||||
statedb.SetCode(addr, account.Code)
|
||||
statedb.SetNonce(addr, account.Nonce)
|
||||
for key, value := range account.Storage {
|
||||
statedb.SetState(addr, key, value)
|
||||
}
|
||||
}
|
||||
root := statedb.IntermediateRoot(false)
|
||||
head := &types.Header{
|
||||
Number: new(big.Int).SetUint64(g.Number),
|
||||
Nonce: types.EncodeNonce(g.Nonce),
|
||||
|
|
@ -284,7 +331,6 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
|||
if g.Difficulty == nil {
|
||||
head.Difficulty = params.GenesisDifficulty
|
||||
}
|
||||
|
||||
// Notice: Eip1559Block affects the block hash, we must set:
|
||||
// 1. g.Config.Eip1559Block
|
||||
// 2. or common.Eip1559Block
|
||||
|
|
@ -295,30 +341,29 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
|||
head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
|
||||
}
|
||||
}
|
||||
|
||||
statedb.Commit(0, false)
|
||||
statedb.Database().TrieDB().Commit(root, true)
|
||||
|
||||
return types.NewBlock(head, nil, nil, trie.NewStackTrie(nil))
|
||||
}
|
||||
|
||||
// Commit writes the block and state of a genesis specification to the database.
|
||||
// The block is committed as the canonical head block.
|
||||
func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
|
||||
if g.Number != 0 {
|
||||
block := g.ToBlock()
|
||||
if block.Number().Sign() != 0 {
|
||||
return nil, errors.New("can't commit genesis block with number > 0")
|
||||
}
|
||||
config := g.Config
|
||||
// if config == nil {
|
||||
// config = params.AllEthashProtocolChanges
|
||||
// }
|
||||
if config == nil {
|
||||
return nil, errors.New("invalid genesis without chain config")
|
||||
}
|
||||
if config.XDPoS != nil && len(g.ExtraData) < 32+crypto.SignatureLength {
|
||||
return nil, errors.New("can't start XDPoS chain without signers")
|
||||
}
|
||||
block := g.ToBlock(db)
|
||||
// All the checks have passed, flushAlloc the states derived from the genesis
|
||||
// specification as well as the specification itself into the provided
|
||||
// database.
|
||||
if err := flushAlloc(&g.Alloc, db, block.Hash()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
batch := db.NewBatch()
|
||||
rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), g.Difficulty)
|
||||
rawdb.WriteBlock(batch, block)
|
||||
|
|
@ -341,16 +386,6 @@ func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
|
|||
return block
|
||||
}
|
||||
|
||||
// GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
|
||||
func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
|
||||
g := Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{addr: {Balance: balance}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
}
|
||||
return g.MustCommit(db)
|
||||
}
|
||||
|
||||
// DefaultGenesisBlock returns the XDC mainnet genesis block.
|
||||
func DefaultGenesisBlock() *Genesis {
|
||||
return &Genesis{
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ import (
|
|||
)
|
||||
|
||||
func TestDefaultGenesisBlock(t *testing.T) {
|
||||
block := DefaultGenesisBlock().ToBlock(nil)
|
||||
block := DefaultGenesisBlock().ToBlock()
|
||||
if block.Hash() != params.MainnetGenesisHash {
|
||||
t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash().String(), params.MainnetGenesisHash.String())
|
||||
}
|
||||
block = DefaultTestnetGenesisBlock().ToBlock(nil)
|
||||
block = DefaultTestnetGenesisBlock().ToBlock()
|
||||
if block.Hash() != params.TestnetGenesisHash {
|
||||
t.Errorf("wrong testnet genesis hash, got %v, want %v", block.Hash().String(), params.TestnetGenesisHash.String())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package rawdb
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||
|
|
@ -62,7 +63,8 @@ func ReadChainConfig(db ethdb.KeyValueReader, hash common.Hash) (*params.ChainCo
|
|||
|
||||
var config params.ChainConfig
|
||||
if err := json.Unmarshal(jsonChainConfig, &config); err != nil {
|
||||
return nil, err
|
||||
log.Error("Invalid chain config JSON", "hash", hash, "err", err)
|
||||
return nil, fmt.Errorf("invalid chain config JSON for hash %s: %w", hash.Hex(), err)
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
|
|
@ -88,3 +90,10 @@ func ReadGenesisStateSpec(db ethdb.KeyValueReader, blockhash common.Hash) []byte
|
|||
data, _ := db.Get(genesisStateSpecKey(blockhash))
|
||||
return data
|
||||
}
|
||||
|
||||
// WriteGenesisStateSpec writes the genesis state specification into the disk.
|
||||
func WriteGenesisStateSpec(db ethdb.KeyValueWriter, blockhash common.Hash, data []byte) {
|
||||
if err := db.Put(genesisStateSpecKey(blockhash), data); err != nil {
|
||||
log.Crit("Failed to store genesis state", "err", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,23 +29,17 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
)
|
||||
|
||||
var (
|
||||
testdb = rawdb.NewMemoryDatabase()
|
||||
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
||||
)
|
||||
|
||||
// makeChain creates a chain of n blocks starting at and including parent.
|
||||
// the returned hash chain is ordered head->parent. In addition, every 3rd block
|
||||
// contains a transaction and every 5th an uncle to allow testing correct block
|
||||
// reassembly.
|
||||
func makeChain(n int, seed byte, parent *types.Block, empty bool) ([]*types.Block, []types.Receipts) {
|
||||
blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), testdb, n, func(i int, block *core.BlockGen) {
|
||||
blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), testDB, n, func(i int, block *core.BlockGen) {
|
||||
block.SetCoinbase(common.Address{seed})
|
||||
// Add one tx to every secondblock
|
||||
if !empty && i%2 == 0 {
|
||||
|
|
@ -71,10 +65,10 @@ var emptyChain *chainData
|
|||
func init() {
|
||||
// Create a chain of blocks to import
|
||||
targetBlocks := 128
|
||||
blocks, _ := makeChain(targetBlocks, 0, genesis, false)
|
||||
blocks, _ := makeChain(targetBlocks, 0, testGenesis, false)
|
||||
chain = &chainData{blocks, 0}
|
||||
|
||||
blocks, _ = makeChain(targetBlocks, 0, genesis, true)
|
||||
blocks, _ = makeChain(targetBlocks, 0, testGenesis, true)
|
||||
emptyChain = &chainData{blocks, 0}
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +229,7 @@ func TestEmptyBlocks(t *testing.T) {
|
|||
// some more advanced scenarios
|
||||
func XTestDelivery(t *testing.T) {
|
||||
// the outside network, holding blocks
|
||||
blo, rec := makeChain(128, 0, genesis, false)
|
||||
blo, rec := makeChain(128, 0, testGenesis, false)
|
||||
world := newNetwork()
|
||||
world.receipts = rec
|
||||
world.chain = blo
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
||||
|
|
@ -35,18 +36,33 @@ var (
|
|||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
testDB = rawdb.NewMemoryDatabase()
|
||||
testGenesis = core.GenesisBlockForTesting(testDB, testAddress, big.NewInt(1000000000000000000))
|
||||
|
||||
testGspec = core.Genesis{
|
||||
Alloc: types.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000000)}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
testGenesis = testGspec.MustCommit(testDB)
|
||||
)
|
||||
|
||||
// The common prefix of all test chains:
|
||||
var testChainBase = newTestChain(blockCacheMaxItems+200, testGenesis)
|
||||
var testChainBase *testChain
|
||||
|
||||
// Different forks on top of the base chain:
|
||||
var testChainForkLightA, testChainForkLightB, testChainForkHeavy *testChain
|
||||
|
||||
func init() {
|
||||
// Reduce some of the parameters to make the tester faster
|
||||
blockCacheMaxItems = 1024
|
||||
fsHeaderSafetyNet = 256
|
||||
fsHeaderContCheck = 500 * time.Millisecond
|
||||
|
||||
testChainBase = newTestChain(blockCacheMaxItems+200, testGenesis)
|
||||
|
||||
var forkLen = int(MaxForkAncestry + 50)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Generate the test chains to seed the peers with
|
||||
wg.Go(func() { testChainForkLightA = testChainBase.makeFork(forkLen, false, 1) })
|
||||
wg.Go(func() { testChainForkLightB = testChainBase.makeFork(forkLen, false, 2) })
|
||||
wg.Go(func() { testChainForkHeavy = testChainBase.makeFork(forkLen, true, 3) })
|
||||
|
|
|
|||
|
|
@ -36,10 +36,17 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
testdb = rawdb.NewMemoryDatabase()
|
||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
|
||||
testdb = rawdb.NewMemoryDatabase()
|
||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
|
||||
gspec = core.Genesis{
|
||||
Alloc: types.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000)}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(testdb)
|
||||
|
||||
unknownBlock = types.NewBlock(&types.Header{Root: types.EmptyRootHash, GasLimit: params.GenesisGasLimit}, nil, nil, trie.NewStackTrie(nil))
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -189,11 +189,12 @@ func TestBlockSubscription(t *testing.T) {
|
|||
db = rawdb.NewMemoryDatabase()
|
||||
backend, sys = newTestFilterSystem(t, db, Config{})
|
||||
api = NewFilterAPI(sys, false)
|
||||
genesis = (&core.Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
gspec = &core.Genesis{
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
}).MustCommit(db)
|
||||
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(db)
|
||||
chain, _ = core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
|
||||
chainEvents = []core.ChainEvent{}
|
||||
)
|
||||
|
||||
|
|
@ -793,10 +794,11 @@ func TestLightFilterLogs(t *testing.T) {
|
|||
|
||||
key, _ = crypto.GenerateKey()
|
||||
addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||
genesis = &core.Genesis{Config: params.TestChainConfig,
|
||||
genesis = &core.Genesis{
|
||||
Alloc: types.GenesisAlloc{
|
||||
addr: {Balance: big.NewInt(params.Ether)},
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
receipts = []*types.Receipt{{
|
||||
Logs: []*types.Log{allLogs[0]},
|
||||
|
|
|
|||
|
|
@ -56,11 +56,19 @@ func BenchmarkFilters(b *testing.B) {
|
|||
addr2 = common.BytesToAddress([]byte("jeff"))
|
||||
addr3 = common.BytesToAddress([]byte("ethereum"))
|
||||
addr4 = common.BytesToAddress([]byte("random addresses please"))
|
||||
|
||||
gspec = core.Genesis{
|
||||
Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.ToBlock()
|
||||
)
|
||||
defer db.Close()
|
||||
|
||||
genesis := core.GenesisBlockForTesting(db, addr1, big.NewInt(1000000))
|
||||
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 100010, func(i int, gen *core.BlockGen) {
|
||||
gspec.MustCommit(db)
|
||||
|
||||
chain, receipts := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 100010, func(i int, gen *core.BlockGen) {
|
||||
switch i {
|
||||
case 2403:
|
||||
receipt := makeReceipt(addr1)
|
||||
|
|
@ -162,16 +170,17 @@ func TestFilters(t *testing.T) {
|
|||
},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
}
|
||||
genesis = gspec.ToBlock()
|
||||
)
|
||||
defer db.Close()
|
||||
|
||||
gspec.MustCommit(db)
|
||||
|
||||
contractABI, err := abi.JSON(strings.NewReader(abiStr))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Hack: GenerateChainWithGenesis creates a new db.
|
||||
// Commit the genesis manually and use GenerateChain.
|
||||
genesis := gspec.MustCommit(db)
|
||||
chain, _ := core.GenerateChain(&config, genesis, ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {
|
||||
switch i {
|
||||
case 1:
|
||||
|
|
@ -357,9 +366,9 @@ func TestRangeLimit(t *testing.T) {
|
|||
defer db.Close()
|
||||
|
||||
gspec := &core.Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis := gspec.MustCommit(db)
|
||||
chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ func newTestBackend(t *testing.T, eip1559Block *big.Int, pending bool) *testBack
|
|||
)
|
||||
engine := ethash.NewFaker()
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis, _ := gspec.Commit(db)
|
||||
genesis := gspec.MustCommit(db)
|
||||
|
||||
// Generate testing blocks
|
||||
blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, testHead+1, func(i int, b *core.BlockGen) {
|
||||
|
|
@ -153,7 +153,7 @@ func newTestBackend(t *testing.T, eip1559Block *big.Int, pending bool) *testBack
|
|||
})
|
||||
// Construct testing chain
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.Commit(diskdb)
|
||||
gspec.MustCommit(diskdb)
|
||||
chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create local chain, %v", err)
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
|
|||
engine = ethash.NewFaker()
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
gspec = &core.Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
genesis = gspec.MustCommit(db)
|
||||
blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
|
||||
|
|
|
|||
|
|
@ -846,13 +846,12 @@ func TestTraceCallBlockSigners(t *testing.T) {
|
|||
|
||||
// Initialize test accounts
|
||||
accounts := newAccounts(1)
|
||||
config := *params.TestChainConfig
|
||||
genesis := &core.Genesis{
|
||||
Config: &config,
|
||||
Alloc: types.GenesisAlloc{
|
||||
accounts[0].addr: {Balance: big.NewInt(params.Ether)},
|
||||
common.BlockSignersBinary: {Balance: big.NewInt(0)}, // System contract
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
|
||||
// Just create an empty block
|
||||
|
|
@ -913,13 +912,12 @@ func TestTraceCallBlockSignersNonceValidation(t *testing.T) {
|
|||
|
||||
// Initialize test accounts
|
||||
accounts := newAccounts(1)
|
||||
config := *params.TestChainConfig
|
||||
genesis := &core.Genesis{
|
||||
Config: &config,
|
||||
Alloc: types.GenesisAlloc{
|
||||
accounts[0].addr: {Balance: big.NewInt(params.Ether), Nonce: 5}, // Account has nonce 5
|
||||
common.BlockSignersBinary: {Balance: big.NewInt(0)}, // System contract
|
||||
},
|
||||
Config: params.TestChainConfig,
|
||||
}
|
||||
backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
|
||||
// Just create an empty block
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
|||
if !ok {
|
||||
return nil, UnsupportedForkError{subtest.Fork}
|
||||
}
|
||||
block := t.genesis(config).ToBlock(nil)
|
||||
block := t.genesis(config).ToBlock()
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
statedb := MakePreState(db, t.json.Pre)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue