core: copy genesis before modifying (#31097)
This PR fixes a data race in SetupGenesisWithOverride.
This commit is contained in:
parent
0ad0966cec
commit
665c8512f3
|
@ -75,6 +75,19 @@ type Genesis struct {
|
||||||
BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844
|
BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy copies the genesis.
|
||||||
|
func (g *Genesis) copy() *Genesis {
|
||||||
|
if g != nil {
|
||||||
|
cpy := *g
|
||||||
|
if g.Config != nil {
|
||||||
|
conf := *g.Config
|
||||||
|
cpy.Config = &conf
|
||||||
|
}
|
||||||
|
return &cpy
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
||||||
var genesis Genesis
|
var genesis Genesis
|
||||||
stored := rawdb.ReadCanonicalHash(db, 0)
|
stored := rawdb.ReadCanonicalHash(db, 0)
|
||||||
|
@ -248,21 +261,17 @@ type ChainOverrides struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply applies the chain overrides on the supplied chain config.
|
// apply applies the chain overrides on the supplied chain config.
|
||||||
func (o *ChainOverrides) apply(cfg *params.ChainConfig) (*params.ChainConfig, error) {
|
func (o *ChainOverrides) apply(cfg *params.ChainConfig) error {
|
||||||
if o == nil || cfg == nil {
|
if o == nil || cfg == nil {
|
||||||
return cfg, nil
|
return nil
|
||||||
}
|
}
|
||||||
cpy := *cfg
|
|
||||||
if o.OverrideCancun != nil {
|
if o.OverrideCancun != nil {
|
||||||
cpy.CancunTime = o.OverrideCancun
|
cfg.CancunTime = o.OverrideCancun
|
||||||
}
|
}
|
||||||
if o.OverrideVerkle != nil {
|
if o.OverrideVerkle != nil {
|
||||||
cpy.VerkleTime = o.OverrideVerkle
|
cfg.VerkleTime = o.OverrideVerkle
|
||||||
}
|
}
|
||||||
if err := cpy.CheckConfigForkOrder(); err != nil {
|
return cfg.CheckConfigForkOrder()
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &cpy, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupGenesisBlock writes or updates the genesis block in db.
|
// SetupGenesisBlock writes or updates the genesis block in db.
|
||||||
|
@ -281,6 +290,8 @@ func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Gene
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
|
||||||
|
// Copy the genesis, so we can operate on a copy.
|
||||||
|
genesis = genesis.copy()
|
||||||
// Sanitize the supplied genesis, ensuring it has the associated chain
|
// Sanitize the supplied genesis, ensuring it has the associated chain
|
||||||
// config attached.
|
// config attached.
|
||||||
if genesis != nil && genesis.Config == nil {
|
if genesis != nil && genesis.Config == nil {
|
||||||
|
@ -295,17 +306,15 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
|
||||||
} else {
|
} else {
|
||||||
log.Info("Writing custom genesis block")
|
log.Info("Writing custom genesis block")
|
||||||
}
|
}
|
||||||
chainCfg, err := overrides.apply(genesis.Config)
|
if err := overrides.apply(genesis.Config); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, common.Hash{}, nil, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
genesis.Config = chainCfg
|
|
||||||
|
|
||||||
block, err := genesis.Commit(db, triedb)
|
block, err := genesis.Commit(db, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.Hash{}, nil, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
return chainCfg, block.Hash(), nil, nil
|
return genesis.Config, block.Hash(), nil, nil
|
||||||
}
|
}
|
||||||
// Commit the genesis if the genesis block exists in the ancient database
|
// Commit the genesis if the genesis block exists in the ancient database
|
||||||
// but the key-value database is empty without initializing the genesis
|
// but the key-value database is empty without initializing the genesis
|
||||||
|
@ -322,11 +331,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
|
||||||
} else {
|
} else {
|
||||||
log.Info("Writing custom genesis block")
|
log.Info("Writing custom genesis block")
|
||||||
}
|
}
|
||||||
chainCfg, err := overrides.apply(genesis.Config)
|
if err := overrides.apply(genesis.Config); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, common.Hash{}, nil, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
genesis.Config = chainCfg
|
|
||||||
|
|
||||||
if hash := genesis.ToBlock().Hash(); hash != ghash {
|
if hash := genesis.ToBlock().Hash(); hash != ghash {
|
||||||
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
|
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
|
||||||
|
@ -335,17 +342,15 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.Hash{}, nil, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
return chainCfg, block.Hash(), nil, nil
|
return genesis.Config, block.Hash(), nil, nil
|
||||||
}
|
}
|
||||||
// The genesis block has already been committed previously. Verify that the
|
// The genesis block has already been committed previously. Verify that the
|
||||||
// provided genesis with chain overrides matches the existing one, and update
|
// provided genesis with chain overrides matches the existing one, and update
|
||||||
// the stored chain config if necessary.
|
// the stored chain config if necessary.
|
||||||
if genesis != nil {
|
if genesis != nil {
|
||||||
chainCfg, err := overrides.apply(genesis.Config)
|
if err := overrides.apply(genesis.Config); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, common.Hash{}, nil, err
|
return nil, common.Hash{}, nil, err
|
||||||
}
|
}
|
||||||
genesis.Config = chainCfg
|
|
||||||
|
|
||||||
if hash := genesis.ToBlock().Hash(); hash != ghash {
|
if hash := genesis.ToBlock().Hash(); hash != ghash {
|
||||||
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
|
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
|
||||||
|
|
Loading…
Reference in New Issue