Skip to content

Commit e874fb1

Browse files
authored
BEP-440: Implement EIP-2935: Serve historical block hashes from state (bnb-chain#2721)
1 parent e2f2111 commit e874fb1

File tree

9 files changed

+58
-62
lines changed

9 files changed

+58
-62
lines changed

consensus/parlia/parlia.go

+7-11
Original file line numberDiff line numberDiff line change
@@ -651,11 +651,11 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
651651
if header.RequestsHash != nil {
652652
return fmt.Errorf("invalid RequestsHash, have %#x, expected nil", header.ParentBeaconRoot)
653653
}
654-
} else {
655-
// TODO(Nathan): need a BEP to define this and `Requests` in struct Body
656-
if !header.EmptyRequestsHash() {
657-
return errors.New("header has wrong RequestsHash")
658-
}
654+
// } else {
655+
// // TODO(Nathan): need a BEP to define this and `Requests` in struct Body
656+
// if !header.EmptyRequestsHash() {
657+
// return errors.New("header has wrong RequestsHash")
658+
// }
659659
}
660660

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

1290-
if p.chainConfig.IsFeynman(header.Number, header.Time) {
1291-
systemcontracts.UpgradeBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state)
1292-
}
1290+
systemcontracts.TryUpdateBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state, false)
12931291

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

1377-
if p.chainConfig.IsFeynman(header.Number, header.Time) {
1378-
systemcontracts.UpgradeBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state)
1379-
}
1375+
systemcontracts.TryUpdateBuildInSystemContract(p.chainConfig, header.Number, parent.Time, header.Time, state, false)
13801376

13811377
if p.chainConfig.IsOnFeynman(header.Number, parent.Time, header.Time) {
13821378
err := p.initializeFeynmanContract(state, header, cx, &body.Transactions, &receipts, nil, &header.GasUsed, true)

core/chain_makers.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
363363
misc.ApplyDAOHardFork(statedb)
364364
}
365365

366-
if !config.IsFeynman(b.header.Number, b.header.Time) {
367-
systemcontracts.UpgradeBuildInSystemContract(config, b.header.Number, parent.Time(), b.header.Time, statedb)
368-
}
366+
systemcontracts.TryUpdateBuildInSystemContract(config, b.header.Number, parent.Time(), b.header.Time, statedb, true)
369367

370368
// Execute any user modifications to the block
371369
if gen != nil {

core/state_processor.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
7676
if lastBlock == nil {
7777
return nil, errors.New("could not get parent block")
7878
}
79-
if !p.config.IsFeynman(block.Number(), block.Time()) {
80-
// Handle upgrade build-in system contract code
81-
systemcontracts.UpgradeBuildInSystemContract(p.config, blockNumber, lastBlock.Time, block.Time(), statedb)
82-
}
79+
// Handle upgrade build-in system contract code
80+
systemcontracts.TryUpdateBuildInSystemContract(p.config, blockNumber, lastBlock.Time, block.Time(), statedb, true)
8381

8482
var (
8583
context vm.BlockContext

core/systemcontracts/upgrade.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,25 @@ func init() {
10501050
}
10511051
}
10521052

1053-
func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB) {
1053+
func TryUpdateBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB, atBlockBegin bool) {
1054+
if atBlockBegin {
1055+
if !config.IsFeynman(blockNumber, lastBlockTime) {
1056+
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
1057+
}
1058+
// HistoryStorageAddress is a special system contract in bsc, which can't be upgraded
1059+
if config.IsOnPrague(blockNumber, lastBlockTime, blockTime) {
1060+
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
1061+
statedb.SetNonce(params.HistoryStorageAddress, 1)
1062+
log.Info("Set code for HistoryStorageAddress", "blockNumber", blockNumber.Int64(), "blockTime", blockTime)
1063+
}
1064+
} else {
1065+
if config.IsFeynman(blockNumber, lastBlockTime) {
1066+
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
1067+
}
1068+
}
1069+
}
1070+
1071+
func upgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, lastBlockTime uint64, blockTime uint64, statedb vm.StateDB) {
10541072
if config == nil || blockNumber == nil || statedb == nil || reflect.ValueOf(statedb).IsNil() {
10551073
return
10561074
}

core/systemcontracts/upgrade_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestUpgradeBuildInSystemContractNilInterface(t *testing.T) {
5555

5656
GenesisHash = params.BSCGenesisHash
5757

58-
UpgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
58+
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
5959
}
6060

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

7070
GenesisHash = params.BSCGenesisHash
7171

72-
UpgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
72+
upgradeBuildInSystemContract(config, blockNumber, lastBlockTime, blockTime, statedb)
7373
}

eth/state_accessor.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
242242
return nil, vm.BlockContext{}, nil, nil, err
243243
}
244244
// upgrade build-in system contract before normal txs if Feynman is not enabled
245-
if !eth.blockchain.Config().IsFeynman(block.Number(), block.Time()) {
246-
systemcontracts.UpgradeBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb)
247-
}
245+
systemcontracts.TryUpdateBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb, true)
248246
// Insert parent beacon block root in the state as per EIP-4788.
249247
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
250248
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
@@ -276,9 +274,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
276274
statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified)
277275
}
278276

279-
if eth.blockchain.Config().IsFeynman(block.Number(), block.Time()) {
280-
systemcontracts.UpgradeBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb)
281-
}
277+
systemcontracts.TryUpdateBuildInSystemContract(eth.blockchain.Config(), block.Number(), parent.Time(), block.Time(), statedb, false)
282278
beforeSystemTx = false
283279
}
284280
}

eth/tracers/api.go

+14-31
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
288288
task.statedb.AddBalance(blockCtx.Coinbase, balance, tracing.BalanceChangeUnspecified)
289289
}
290290

291-
if api.backend.ChainConfig().IsFeynman(task.block.Number(), task.block.Time()) {
292-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), task.block.Number(), task.parent.Time(), task.block.Time(), task.statedb)
293-
}
291+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), task.block.Number(), task.parent.Time(), task.block.Time(), task.statedb, false)
294292
beforeSystemTx = false
295293
}
296294
}
@@ -402,6 +400,10 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
402400
failed = err
403401
break
404402
}
403+
404+
// upgrade build-in system contract before normal txs if Feynman is not enabled
405+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), next.Number(), block.Time(), next.Time(), statedb, true)
406+
405407
// Insert block's parent beacon block root in the state
406408
// as per EIP-4788.
407409
if beaconRoot := next.BeaconRoot(); beaconRoot != nil {
@@ -421,11 +423,6 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
421423
// may fail if we release too early.
422424
tracker.callReleases()
423425

424-
// upgrade build-in system contract before normal txs if Feynman is not enabled
425-
if !api.backend.ChainConfig().IsFeynman(next.Number(), next.Time()) {
426-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), next.Number(), block.Time(), next.Time(), statedb)
427-
}
428-
429426
// Send the block over to the concurrent tracers (if not in the fast-forward phase)
430427
txs := next.Transactions()
431428
select {
@@ -563,9 +560,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
563560
defer release()
564561

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

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

603-
if beforeSystemTx && api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
604-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
598+
if beforeSystemTx {
599+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
605600
beforeSystemTx = false
606601
}
607602
}
@@ -661,9 +656,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
661656
defer release()
662657

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

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

705-
if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
706-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
707-
}
698+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
708699
beforeSystemTx = false
709700
}
710701
}
@@ -795,9 +786,7 @@ txloop:
795786
statedb.AddBalance(block.Header().Coinbase, balance, tracing.BalanceChangeUnspecified)
796787
}
797788

798-
if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
799-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
800-
}
789+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
801790
beforeSystemTx = false
802791
}
803792
}
@@ -863,9 +852,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
863852
defer release()
864853

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

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

918-
if api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
919-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
920-
}
905+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, false)
921906
beforeSystemTx = false
922907
}
923908
}
@@ -1099,9 +1084,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
10991084
if err != nil {
11001085
return nil, err
11011086
}
1102-
if !api.backend.ChainConfig().IsFeynman(block.Number(), block.Time()) {
1103-
systemcontracts.UpgradeBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb)
1104-
}
1087+
systemcontracts.TryUpdateBuildInSystemContract(api.backend.ChainConfig(), block.Number(), parent.Time(), block.Time(), statedb, true)
11051088
}
11061089

11071090
vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)

miner/worker.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -1042,10 +1042,8 @@ func (w *worker) prepareWork(genParams *generateParams, witness bool) (*environm
10421042
return nil, err
10431043
}
10441044

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

10501048
if header.ParentBeaconRoot != nil {
10511049
context := core.NewEVMBlockContext(header, w.chain, nil)

params/config.go

+9
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,15 @@ func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {
10241024
return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
10251025
}
10261026

1027+
// IsOnPrague returns whether currentBlockTime is either equal to the Prague fork time or greater firstly.
1028+
func (c *ChainConfig) IsOnPrague(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool {
1029+
lastBlockNumber := new(big.Int)
1030+
if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 {
1031+
lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1))
1032+
}
1033+
return !c.IsPrague(lastBlockNumber, lastBlockTime) && c.IsPrague(currentBlockNumber, currentBlockTime)
1034+
}
1035+
10271036
// IsVerkle returns whether time is either equal to the Verkle fork time or greater.
10281037
func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
10291038
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)

0 commit comments

Comments
 (0)