mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
Merge pull request #922 from gzliudan/commit-genesis
core: improve commit genesis
This commit is contained in:
commit
9c144eee05
5 changed files with 85 additions and 46 deletions
|
|
@ -26,15 +26,50 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// newCanonical creates a chain database, and injects a deterministic canonical
|
||||||
|
// chain. Depending on the full flag, it creates either a full block chain or a
|
||||||
|
// header only chain. The database and genesis specification for block generation
|
||||||
|
// are also returned in case more test blocks are needed later.
|
||||||
|
func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
|
||||||
|
var (
|
||||||
|
gspec = &Genesis{
|
||||||
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
Config: params.AllEthashProtocolChanges,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
db := rawdb.NewMemoryDatabase()
|
||||||
|
genesis := gspec.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
|
// 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)) {
|
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
|
// Copy old chain up to #i into a new db
|
||||||
|
|
@ -1192,7 +1227,11 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
|
gspec := &Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
}
|
||||||
|
genesis := gspec.MustCommit(db)
|
||||||
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
blocks, _ := GenerateChain(params.TestChainConfig, 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
|
// Generate a bunch of fork blocks, each side forking from the canonical chain
|
||||||
|
|
@ -1208,7 +1247,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
||||||
// Import the canonical and fork chain side by side, verifying the current block
|
// Import the canonical and fork chain side by side, verifying the current block
|
||||||
// and current header consistency
|
// and current header consistency
|
||||||
diskdb := rawdb.NewMemoryDatabase()
|
diskdb := rawdb.NewMemoryDatabase()
|
||||||
(&Genesis{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, params.TestChainConfig, engine, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1237,7 +1276,10 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
|
genesis := (&Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
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}) })
|
blocks, _ := GenerateChain(params.TestChainConfig, 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
|
// Generate a bunch of fork blocks, each side forking from the canonical chain
|
||||||
|
|
@ -1252,7 +1294,10 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
|
// Import the canonical and fork chain side by side, forcing the trie cache to cache both
|
||||||
diskdb := rawdb.NewMemoryDatabase()
|
diskdb := rawdb.NewMemoryDatabase()
|
||||||
(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
|
(&Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
}).MustCommit(diskdb)
|
||||||
|
|
||||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1281,9 +1326,13 @@ func TestTrieForkGC(t *testing.T) {
|
||||||
func TestLargeReorgTrieGC(t *testing.T) {
|
func TestLargeReorgTrieGC(t *testing.T) {
|
||||||
// Generate the original common chain segment and the two competing forks
|
// Generate the original common chain segment and the two competing forks
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
|
gspec := &Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
}
|
||||||
|
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
|
|
||||||
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
|
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}) })
|
original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
|
||||||
|
|
@ -1291,7 +1340,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
|
||||||
|
|
||||||
// Import the shared chain and the original canonical one
|
// Import the shared chain and the original canonical one
|
||||||
diskdb := rawdb.NewMemoryDatabase()
|
diskdb := rawdb.NewMemoryDatabase()
|
||||||
(&Genesis{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, params.TestChainConfig, engine, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -304,32 +304,6 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
|
||||||
// Initialize a fresh chain with only a genesis block
|
|
||||||
gspec := new(Genesis)
|
|
||||||
db := rawdb.NewMemoryDatabase()
|
|
||||||
genesis := gspec.MustCommit(db)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeHeaderChain creates a deterministic chain of headers rooted at parent.
|
// makeHeaderChain creates a deterministic chain of headers rooted at parent.
|
||||||
func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header {
|
func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header {
|
||||||
blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed)
|
blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed)
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,11 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
forkBlock := big.NewInt(32)
|
forkBlock := big.NewInt(32)
|
||||||
|
|
||||||
// Generate a common prefix for both pro-forkers and non-forkers
|
// Generate a common prefix for both pro-forkers and non-forkers
|
||||||
|
gspec := &Genesis{
|
||||||
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
}
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
gspec := &Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}
|
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,21 +234,30 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
||||||
// Commit writes the block and state of a genesis specification to the database.
|
// Commit writes the block and state of a genesis specification to the database.
|
||||||
// The block is committed as the canonical head block.
|
// The block is committed as the canonical head block.
|
||||||
func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
|
func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
|
||||||
block := g.ToBlock(db)
|
if g.Number != 0 {
|
||||||
if block.Number().Sign() != 0 {
|
|
||||||
return nil, errors.New("can't commit genesis block with number > 0")
|
return nil, errors.New("can't commit genesis block with number > 0")
|
||||||
}
|
}
|
||||||
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
|
|
||||||
rawdb.WriteBlock(db, block)
|
|
||||||
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
|
|
||||||
rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
|
|
||||||
rawdb.WriteHeadBlockHash(db, block.Hash())
|
|
||||||
rawdb.WriteHeadHeaderHash(db, block.Hash())
|
|
||||||
config := g.Config
|
config := g.Config
|
||||||
|
// if config == nil {
|
||||||
|
// config = params.AllEthashProtocolChanges
|
||||||
|
// }
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = params.AllEthashProtocolChanges
|
return nil, errors.New("invalid genesis without chain config")
|
||||||
}
|
}
|
||||||
return block, rawdb.WriteChainConfig(db, block.Hash(), 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)
|
||||||
|
batch := db.NewBatch()
|
||||||
|
rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), g.Difficulty)
|
||||||
|
rawdb.WriteBlock(batch, block)
|
||||||
|
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), nil)
|
||||||
|
rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
|
||||||
|
rawdb.WriteHeadBlockHash(batch, block.Hash())
|
||||||
|
rawdb.WriteHeadFastBlockHash(batch, block.Hash())
|
||||||
|
rawdb.WriteHeadHeaderHash(batch, block.Hash())
|
||||||
|
rawdb.WriteChainConfig(db, block.Hash(), config)
|
||||||
|
return block, batch.Write()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustCommit writes the genesis block and state to db, panicking on error.
|
// MustCommit writes the genesis block and state to db, panicking on error.
|
||||||
|
|
@ -264,6 +273,7 @@ func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
|
||||||
// GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
|
// 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 {
|
func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
|
||||||
g := Genesis{
|
g := Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
Alloc: types.GenesisAlloc{addr: {Balance: balance}},
|
Alloc: types.GenesisAlloc{addr: {Balance: balance}},
|
||||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,9 +187,12 @@ func TestBlockSubscription(t *testing.T) {
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
backend, sys = newTestFilterSystem(t, db, Config{})
|
backend, sys = newTestFilterSystem(t, db, Config{})
|
||||||
api = NewFilterAPI(sys, false)
|
api = NewFilterAPI(sys, false)
|
||||||
genesis = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
|
genesis = (&core.Genesis{
|
||||||
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
|
Config: params.TestChainConfig,
|
||||||
chainEvents = []core.ChainEvent{}
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
}).MustCommit(db)
|
||||||
|
chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
|
||||||
|
chainEvents = []core.ChainEvent{}
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, blk := range chain {
|
for _, blk := range chain {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue