mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
internal/ethapi: fix merge transition in eth_simulate (#32616)
This PR fixes the fork detection of `eth_simulateV1`, particularly for networks that are post-merge since genesis, like Hoodi.
This commit is contained in:
parent
1cd004871b
commit
4074f745bd
3 changed files with 23 additions and 15 deletions
|
|
@ -71,16 +71,6 @@ func New(ethone consensus.Engine) *Beacon {
|
||||||
return &Beacon{ethone: ethone}
|
return &Beacon{ethone: ethone}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isPostMerge reports whether the given block number is assumed to be post-merge.
|
|
||||||
// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or
|
|
||||||
// PoA chain for unit testing purposes.
|
|
||||||
func isPostMerge(config *params.ChainConfig, blockNum uint64, timestamp uint64) bool {
|
|
||||||
mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0
|
|
||||||
return mergedAtGenesis ||
|
|
||||||
config.MergeNetsplitBlock != nil && blockNum >= config.MergeNetsplitBlock.Uint64() ||
|
|
||||||
config.ShanghaiTime != nil && timestamp >= *config.ShanghaiTime
|
|
||||||
}
|
|
||||||
|
|
||||||
// Author implements consensus.Engine, returning the verified author of the block.
|
// Author implements consensus.Engine, returning the verified author of the block.
|
||||||
func (beacon *Beacon) Author(header *types.Header) (common.Address, error) {
|
func (beacon *Beacon) Author(header *types.Header) (common.Address, error) {
|
||||||
if !beacon.IsPoSHeader(header) {
|
if !beacon.IsPoSHeader(header) {
|
||||||
|
|
@ -328,7 +318,7 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [
|
||||||
// Prepare implements consensus.Engine, initializing the difficulty field of a
|
// Prepare implements consensus.Engine, initializing the difficulty field of a
|
||||||
// header to conform to the beacon protocol. The changes are done inline.
|
// header to conform to the beacon protocol. The changes are done inline.
|
||||||
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
|
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
|
||||||
if !isPostMerge(chain.Config(), header.Number.Uint64(), header.Time) {
|
if !chain.Config().IsPostMerge(header.Number.Uint64(), header.Time) {
|
||||||
return beacon.ethone.Prepare(chain, header)
|
return beacon.ethone.Prepare(chain, header)
|
||||||
}
|
}
|
||||||
header.Difficulty = beaconDifficulty
|
header.Difficulty = beaconDifficulty
|
||||||
|
|
@ -442,7 +432,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash {
|
||||||
// the difficulty that a new block should have when created at time
|
// the difficulty that a new block should have when created at time
|
||||||
// given the parent block's time and difficulty.
|
// given the parent block's time and difficulty.
|
||||||
func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
|
func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
|
||||||
if !isPostMerge(chain.Config(), parent.Number.Uint64()+1, time) {
|
if !chain.Config().IsPostMerge(parent.Number.Uint64()+1, time) {
|
||||||
return beacon.ethone.CalcDifficulty(chain, time, parent)
|
return beacon.ethone.CalcDifficulty(chain, time, parent)
|
||||||
}
|
}
|
||||||
return beaconDifficulty
|
return beaconDifficulty
|
||||||
|
|
|
||||||
|
|
@ -474,22 +474,30 @@ func (sim *simulator) makeHeaders(blocks []simBlock) ([]*types.Header, error) {
|
||||||
overrides := block.BlockOverrides
|
overrides := block.BlockOverrides
|
||||||
|
|
||||||
var withdrawalsHash *common.Hash
|
var withdrawalsHash *common.Hash
|
||||||
if sim.chainConfig.IsShanghai(overrides.Number.ToInt(), (uint64)(*overrides.Time)) {
|
number := overrides.Number.ToInt()
|
||||||
|
timestamp := (uint64)(*overrides.Time)
|
||||||
|
if sim.chainConfig.IsShanghai(number, timestamp) {
|
||||||
withdrawalsHash = &types.EmptyWithdrawalsHash
|
withdrawalsHash = &types.EmptyWithdrawalsHash
|
||||||
}
|
}
|
||||||
var parentBeaconRoot *common.Hash
|
var parentBeaconRoot *common.Hash
|
||||||
if sim.chainConfig.IsCancun(overrides.Number.ToInt(), (uint64)(*overrides.Time)) {
|
if sim.chainConfig.IsCancun(number, timestamp) {
|
||||||
parentBeaconRoot = &common.Hash{}
|
parentBeaconRoot = &common.Hash{}
|
||||||
if overrides.BeaconRoot != nil {
|
if overrides.BeaconRoot != nil {
|
||||||
parentBeaconRoot = overrides.BeaconRoot
|
parentBeaconRoot = overrides.BeaconRoot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Set difficulty to zero if the given block is post-merge. Without this, all post-merge hardforks would remain inactive.
|
||||||
|
// For example, calling eth_simulateV1(..., blockParameter: 0x0) on hoodi network will cause all blocks to have a difficulty of 1 and be treated as pre-merge.
|
||||||
|
difficulty := header.Difficulty
|
||||||
|
if sim.chainConfig.IsPostMerge(number.Uint64(), timestamp) {
|
||||||
|
difficulty = big.NewInt(0)
|
||||||
|
}
|
||||||
header = overrides.MakeHeader(&types.Header{
|
header = overrides.MakeHeader(&types.Header{
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
ReceiptHash: types.EmptyReceiptsHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
TxHash: types.EmptyTxsHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
Coinbase: header.Coinbase,
|
Coinbase: header.Coinbase,
|
||||||
Difficulty: header.Difficulty,
|
Difficulty: difficulty,
|
||||||
GasLimit: header.GasLimit,
|
GasLimit: header.GasLimit,
|
||||||
WithdrawalsHash: withdrawalsHash,
|
WithdrawalsHash: withdrawalsHash,
|
||||||
ParentBeaconRoot: parentBeaconRoot,
|
ParentBeaconRoot: parentBeaconRoot,
|
||||||
|
|
|
||||||
|
|
@ -678,6 +678,16 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi
|
||||||
return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0
|
return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsPostMerge reports whether the given block number is assumed to be post-merge.
|
||||||
|
// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or
|
||||||
|
// PoA chain for unit testing purposes.
|
||||||
|
func (c *ChainConfig) IsPostMerge(blockNum uint64, timestamp uint64) bool {
|
||||||
|
mergedAtGenesis := c.TerminalTotalDifficulty != nil && c.TerminalTotalDifficulty.Sign() == 0
|
||||||
|
return mergedAtGenesis ||
|
||||||
|
c.MergeNetsplitBlock != nil && blockNum >= c.MergeNetsplitBlock.Uint64() ||
|
||||||
|
c.ShanghaiTime != nil && timestamp >= *c.ShanghaiTime
|
||||||
|
}
|
||||||
|
|
||||||
// IsShanghai returns whether time is either equal to the Shanghai fork time or greater.
|
// IsShanghai returns whether time is either equal to the Shanghai fork time or greater.
|
||||||
func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool {
|
func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool {
|
||||||
return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time)
|
return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue