refactor(all): cleanup the APIs for initializing genesis #25473 #26747 (#2017)

* refactor(all): cleanup the APIs for initializing genesis #25473

* fix(core): fix accessor mismatch for genesis state #26747
This commit is contained in:
Daniel Liu 2026-02-07 02:48:39 +08:00 committed by GitHub
parent f744e86dd7
commit e39a523260
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 187 additions and 116 deletions

View file

@ -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 {

View file

@ -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)

View file

@ -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)

View file

@ -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)
}

View file

@ -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
}

View file

@ -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()

View file

@ -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{

View file

@ -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())
}

View file

@ -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)
}
}

View file

@ -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

View file

@ -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) })

View file

@ -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))
)

View file

@ -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]},

View file

@ -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) {})

View file

@ -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)

View file

@ -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{})

View file

@ -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

View file

@ -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)