diff --git a/action/protocol/execution/evm/evm.go b/action/protocol/execution/evm/evm.go index 7b050fbe34..891e33d7a9 100644 --- a/action/protocol/execution/evm/evm.go +++ b/action/protocol/execution/evm/evm.go @@ -187,7 +187,9 @@ func newParams( if vmCfg, ok := protocol.GetVMConfigCtx(ctx); ok { vmConfig = vmCfg } - chainConfig, err := getChainConfig(g.Blockchain, blkCtx.BlockHeight, evmNetworkID, helperCtx.GetBlockTime) + chainConfig, err := getChainConfig(g.Blockchain, blkCtx.BlockHeight, evmNetworkID, func(height uint64) (*time.Time, error) { + return blockHeightToTime(ctx, height) + }) if err != nil { return nil, err } @@ -399,7 +401,7 @@ func prepareStateDB(ctx context.Context, sm protocol.StateManager) (*StateDBAdap ) } -func getChainConfig(g genesis.Blockchain, height uint64, id uint32, getBlockTime GetBlockTime) (*params.ChainConfig, error) { +func getChainConfig(g genesis.Blockchain, height uint64, id uint32, getBlockTime func(uint64) (*time.Time, error)) (*params.ChainConfig, error) { var chainConfig params.ChainConfig chainConfig.ConstantinopleBlock = new(big.Int).SetUint64(0) // Constantinople switch block (nil = no fork, 0 = already activated) chainConfig.BeringBlock = new(big.Int).SetUint64(g.BeringBlockHeight) @@ -423,19 +425,40 @@ func getChainConfig(g genesis.Blockchain, height uint64, id uint32, getBlockTime sumatraTime, err := getBlockTime(g.SumatraBlockHeight) if err != nil { return nil, err + } else if sumatraTime != nil { + sumatraTimestamp := (uint64)(sumatraTime.Unix()) + chainConfig.ShanghaiTime = &sumatraTimestamp } - sumatraTimestamp := (uint64)(sumatraTime.Unix()) - chainConfig.ShanghaiTime = &sumatraTimestamp // enable Cancun at Vanuatu cancunTime, err := getBlockTime(g.VanuatuBlockHeight) if err != nil { return nil, err + } else if cancunTime != nil { + cancunTimestamp := (uint64)(cancunTime.Unix()) + chainConfig.CancunTime = &cancunTimestamp } - cancunTimestamp := (uint64)(cancunTime.Unix()) - chainConfig.CancunTime = &cancunTimestamp return &chainConfig, nil } +// blockHeightToTime returns the block time by height +// if height is greater than current block height, return nil +// if height is equal to current block height, return current block time +// otherwise, return the block time by height from the blockchain +func blockHeightToTime(ctx context.Context, height uint64) (*time.Time, error) { + blkCtx := protocol.MustGetBlockCtx(ctx) + if height > blkCtx.BlockHeight { + return nil, nil + } + if height == blkCtx.BlockHeight { + return &blkCtx.BlockTimeStamp, nil + } + t, err := mustGetHelperCtx(ctx).GetBlockTime(height) + if err != nil { + return nil, err + } + return &t, nil +} + // Error in executeInEVM is a consensus issue func executeInEVM(ctx context.Context, evmParams *Params, stateDB stateDB) ([]byte, uint64, uint64, string, iotextypes.ReceiptStatus, error) { var ( diff --git a/chainservice/builder.go b/chainservice/builder.go index f986851bd1..71825d9cc3 100644 --- a/chainservice/builder.go +++ b/chainservice/builder.go @@ -47,7 +47,6 @@ import ( "github.com/iotexproject/iotex-core/v2/nodeinfo" "github.com/iotexproject/iotex-core/v2/p2p" "github.com/iotexproject/iotex-core/v2/pkg/log" - "github.com/iotexproject/iotex-core/v2/pkg/util/blockutil" "github.com/iotexproject/iotex-core/v2/server/itx/nodestats" "github.com/iotexproject/iotex-core/v2/state/factory" "github.com/iotexproject/iotex-core/v2/systemcontractindex/stakingindex" @@ -703,7 +702,14 @@ func (builder *Builder) registerAccountProtocol() error { } func (builder *Builder) registerExecutionProtocol() error { - return execution.NewProtocol(builder.cs.blockdao.GetBlockHash, rewarding.DepositGas, builder.cs.blockTimeCalculator.CalculateBlockTime).Register(builder.cs.registry) + dao := builder.cs.BlockDAO() + return execution.NewProtocol(builder.cs.blockdao.GetBlockHash, rewarding.DepositGas, func(u uint64) (time.Time, error) { + header, err := dao.HeaderByHeight(u) + if err != nil { + return time.Time{}, err + } + return header.Timestamp(), nil + }).Register(builder.cs.registry) } func (builder *Builder) registerRollDPoSProtocol() error { @@ -721,7 +727,13 @@ func (builder *Builder) registerRollDPoSProtocol() error { factory := builder.cs.factory dao := builder.cs.blockdao chain := builder.cs.chain - getBlockTime := builder.cs.blockTimeCalculator.CalculateBlockTime + getBlockTime := func(height uint64) (time.Time, error) { + header, err := chain.BlockHeaderByHeight(height) + if err != nil { + return time.Time{}, err + } + return header.Timestamp(), nil + } pollProtocol, err := poll.NewProtocol( builder.cfg.Consensus.Scheme, builder.cfg.Chain, @@ -779,19 +791,6 @@ func (builder *Builder) registerRollDPoSProtocol() error { return pollProtocol.Register(builder.cs.registry) } -func (builder *Builder) buildBlockTimeCalculator() (err error) { - consensusCfg := consensusfsm.NewConsensusConfig(builder.cfg.Consensus.RollDPoS.FSM, builder.cfg.DardanellesUpgrade, builder.cfg.Genesis, builder.cfg.Consensus.RollDPoS.Delay) - dao := builder.cs.BlockDAO() - builder.cs.blockTimeCalculator, err = blockutil.NewBlockTimeCalculator(consensusCfg.BlockInterval, builder.cs.Blockchain().TipHeight, func(height uint64) (time.Time, error) { - blk, err := dao.GetBlockByHeight(height) - if err != nil { - return time.Time{}, err - } - return blk.Timestamp(), nil - }) - return err -} - func (builder *Builder) buildConsensusComponent() error { p2pAgent := builder.cs.p2pAgent copts := []consensus.Option{ @@ -852,9 +851,6 @@ func (builder *Builder) build(forSubChain, forTest bool) (*ChainService, error) if err := builder.buildBlockchain(forSubChain, forTest); err != nil { return nil, err } - if err := builder.buildBlockTimeCalculator(); err != nil { - return nil, err - } // staking protocol need to be put in registry before poll protocol when enabling if err := builder.registerStakingProtocol(); err != nil { return nil, errors.Wrap(err, "failed to register staking protocol") diff --git a/chainservice/chainservice.go b/chainservice/chainservice.go index a71bb2a7ce..78571e3f2e 100644 --- a/chainservice/chainservice.go +++ b/chainservice/chainservice.go @@ -7,6 +7,7 @@ package chainservice import ( "context" + "time" "github.com/libp2p/go-libp2p/core/peer" "github.com/pkg/errors" @@ -36,7 +37,6 @@ import ( "github.com/iotexproject/iotex-core/v2/p2p" "github.com/iotexproject/iotex-core/v2/pkg/lifecycle" "github.com/iotexproject/iotex-core/v2/pkg/log" - "github.com/iotexproject/iotex-core/v2/pkg/util/blockutil" "github.com/iotexproject/iotex-core/v2/server/itx/nodestats" "github.com/iotexproject/iotex-core/v2/state/factory" "github.com/iotexproject/iotex-core/v2/systemcontractindex/stakingindex" @@ -77,7 +77,6 @@ type ChainService struct { registry *protocol.Registry nodeInfoManager *nodeinfo.InfoManager apiStats *nodestats.APILocalStats - blockTimeCalculator *blockutil.BlockTimeCalculator actionsync *actsync.ActionSync } @@ -242,7 +241,13 @@ func (cs *ChainService) NewAPIServer(cfg api.Config, archive bool) (*api.ServerV cs.bfIndexer, cs.actpool, cs.registry, - cs.blockTimeCalculator.CalculateBlockTime, + func(u uint64) (time.Time, error) { + header, err := cs.chain.BlockHeaderByHeight(u) + if err != nil { + return time.Time{}, err + } + return header.Timestamp(), nil + }, apiServerOptions..., ) if err != nil {