Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BEP-440: Implement EIP-2935: Serve historical block hashes from state #2721

Merged
merged 3 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,11 +651,11 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
if header.RequestsHash != nil {
return fmt.Errorf("invalid RequestsHash, have %#x, expected nil", header.ParentBeaconRoot)
}
} else {
// TODO(Nathan): need a BEP to define this and `Requests` in struct Body
if !header.EmptyRequestsHash() {
return errors.New("header has wrong RequestsHash")
}
// } else {
// // TODO(Nathan): need a BEP to define this and `Requests` in struct Body
// if !header.EmptyRequestsHash() {
buddh0 marked this conversation as resolved.
Show resolved Hide resolved
// return errors.New("header has wrong RequestsHash")
// }
}

// All basic checks passed, verify cascading fields
Expand Down Expand Up @@ -1287,9 +1287,7 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
return errors.New("parent not found")
}

if p.chainConfig.IsFeynman(header.Number, header.Time) {
systemcontracts.UpgradeBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state)
}
systemcontracts.TryUpdateBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state, false)

if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
err := p.initializeFeynmanContract(state, header, cx, txs, receipts, systemTxs, usedGas, false)
Expand Down Expand Up @@ -1374,9 +1372,7 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
return nil, nil, errors.New("parent not found")
}

if p.chainConfig.IsFeynman(header.Number, header.Time) {
systemcontracts.UpgradeBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state)
}
systemcontracts.TryUpdateBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state, false)

if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
err := p.initializeFeynmanContract(state, header, cx, &body.Transactions, &receipts, nil, &header.GasUsed, true)
Expand Down
4 changes: 1 addition & 3 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
misc.ApplyDAOHardFork(statedb)
}

if !config.IsFeynman(b.header.Number, b.header.Time) {
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, parent.Time(), b.header.Time, statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(config, b.header.Number, parent.Time(), b.header.Time, statedb, true)

// Execute any user modifications to the block
if gen != nil {
Expand Down
6 changes: 2 additions & 4 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if lastBlock == nil {
return nil, errors.New("could not get parent block")
}
if !p.config.IsFeynman(block.Number(), block.Time()) {
// Handle upgrade build-in system contract code
systemcontracts.UpgradeBuildInSystemContract(p.config, blockNumber, lastBlock.Time, block.Time(), statedb)
}
// Handle upgrade build-in system contract code
systemcontracts.TryUpdateBuildInSystemContract(p.config, blockNumber, lastBlock.Time, block.Time(), statedb, true)

var (
context vm.BlockContext
Expand Down
20 changes: 19 additions & 1 deletion core/systemcontracts/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,25 @@ func init() {
}
}

func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB) {
func TryUpdateBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB, atBlockBegin bool) {
if atBlockBegin {
if !config.IsFeynman(blockNumber, lastBlockTime) {
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
}
// HistoryStorageAddress is a special system contract in bsc, which can't be upgraded
if config.IsOnPrague(blockNumber, lastBlockTime, blockTime) {
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
statedb.SetNonce(params.HistoryStorageAddress, 1)
log.Info("Set code for HistoryStorageAddress", "blockNumber", blockNumber.Int64(), "blockTime", blockTime)
}
} else {
if config.IsFeynman(blockNumber, lastBlockTime) {
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
}
}
}

func upgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB) {
if config == nil || blockNumber == nil || statedb == nil || reflect.ValueOf(statedb).IsNil() {
return
}
Expand Down
4 changes: 2 additions & 2 deletions core/systemcontracts/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestUpgradeBuildInSystemContractNilInterface(t *testing.T) {

GenesisHash = params.BSCGenesisHash

UpgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
}

func TestUpgradeBuildInSystemContractNilValue(t *testing.T) {
Expand All @@ -69,5 +69,5 @@ func TestUpgradeBuildInSystemContractNilValue(t *testing.T) {

GenesisHash = params.BSCGenesisHash

UpgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
}
8 changes: 2 additions & 6 deletions eth/state_accessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
return nil, vm.BlockContext{}, nil, nil, err
}
// upgrade build-in system contract before normal txs if Feynman is not enabled
if !eth.blockchain.Config().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb, true)
// Insert parent beacon block root in the state as per EIP-4788.
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
Expand Down Expand Up @@ -276,9 +274,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified)
}

if eth.blockchain.Config().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb, false)
beforeSystemTx = false
}
}
Expand Down
45 changes: 14 additions & 31 deletions eth/tracers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
task.statedb.AddBalance(blockCtx.Coinbase, balance, tracing.BalanceChangeUnspecified)
}

if api.backend.ChainConfig().IsFeynman(task.block.Number(), task.block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), task.block.Number(), task.parent.Time(), task.block.Time(), task.statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), task.block.Number(), task.parent.Time(), task.block.Time(), task.statedb, false)
beforeSystemTx = false
}
}
Expand Down Expand Up @@ -402,6 +400,10 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
failed = err
break
}

// upgrade build-in system contract before normal txs if Feynman is not enabled
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), next.Number(), block.Time(), next.Time(), statedb, true)

// Insert block's parent beacon block root in the state
// as per EIP-4788.
if beaconRoot := next.BeaconRoot(); beaconRoot != nil {
Expand All @@ -421,11 +423,6 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
// may fail if we release too early.
tracker.callReleases()

// upgrade build-in system contract before normal txs if Feynman is not enabled
if !api.backend.ChainConfig().IsFeynman(next.Number(), next.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), next.Number(), block.Time(), next.Time(), statedb)
}

// Send the block over to the concurrent tracers (if not in the fast-forward phase)
txs := next.Transactions()
select {
Expand Down Expand Up @@ -563,9 +560,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
defer release()

// upgrade build-in system contract before normal txs if Feynman is not enabled
if !api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, true)

var (
roots []common.Hash
Expand Down Expand Up @@ -600,8 +595,8 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
statedb.AddBalance(vmctx.Coinbase, balance, tracing.BalanceChangeUnspecified)
}

if beforeSystemTx && api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
if beforeSystemTx {
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
beforeSystemTx = false
}
}
Expand Down Expand Up @@ -661,9 +656,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
defer release()

// upgrade build-in system contract before normal txs if Feynman is not enabled
if !api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, true)

// JS tracers have high overhead. In this case run a parallel
// process that generates states in one thread and traces txes
Expand Down Expand Up @@ -702,9 +695,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
statedb.AddBalance(blockCtx.Coinbase, balance, tracing.BalanceChangeUnspecified)
}

if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
beforeSystemTx = false
}
}
Expand Down Expand Up @@ -795,9 +786,7 @@ txloop:
statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified)
}

if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
beforeSystemTx = false
}
}
Expand Down Expand Up @@ -863,9 +852,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
defer release()

// upgrade build-in system contract before normal txs if Feynman is not enabled
if !api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, true)

// Retrieve the tracing configurations, or use default values
var (
Expand Down Expand Up @@ -915,9 +902,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
statedb.AddBalance(vmctx.Coinbase, balance, tracing.BalanceChangeUnspecified)
}

if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
beforeSystemTx = false
}
}
Expand Down Expand Up @@ -1099,9 +1084,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
if err != nil {
return nil, err
}
if !api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
}
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, true)
}

vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
Expand Down
6 changes: 2 additions & 4 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1042,10 +1042,8 @@ func (w *worker) prepareWork(genParams *generateParams, witness bool) (*environm
return nil, err
}

if !w.chainConfig.IsFeynman(header.Number, header.Time) {
// Handle upgrade build-in system contract code
systemcontracts.UpgradeBuildInSystemContract(w.chainConfig, header.Number, parent.Time, header.Time, env.state)
}
// Handle upgrade build-in system contract code
systemcontracts.TryUpdateBuildInSystemContract(w.chainConfig, header.Number, parent.Time, header.Time, env.state, true)

if header.ParentBeaconRoot != nil {
context := core.NewEVMBlockContext(header, w.chain, nil)
Expand Down
9 changes: 9 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,15 @@ func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
}

// IsOnPrague returns whether currentBlockTime is either equal to the Prague fork time or greater firstly.
func (c *ChainConfig) IsOnPrague(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool {
lastBlockNumber := new(big.Int)
if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 {
lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1))
}
return !c.IsPrague(lastBlockNumber, lastBlockTime) && c.IsPrague(currentBlockNumber, currentBlockTime)
}

// IsVerkle returns whether time is either equal to the Verkle fork time or greater.
func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
Expand Down