From bbab968677357b6757f372eca18d154749000a6a Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 5 Jun 2024 14:32:53 +0200 Subject: [PATCH 1/3] Add chain.Config to NewEVMBlockContext --- accounts/abi/bind/backends/simulated.go | 2 +- cmd/state/exec3/trace_worker.go | 2 +- cmd/state/exec3/trace_worker2.go | 2 +- core/blockchain.go | 8 ++++---- core/evm.go | 3 ++- core/genesis_write.go | 18 ++++++++++-------- core/state_processor.go | 2 +- eth/stagedsync/exec3.go | 4 ++-- tests/state_test_util.go | 2 +- turbo/jsonrpc/eth_block.go | 2 +- turbo/jsonrpc/eth_call.go | 2 +- turbo/jsonrpc/eth_callMany.go | 2 +- turbo/jsonrpc/otterscan_search_trace.go | 2 +- turbo/jsonrpc/trace_adhoc.go | 4 ++-- turbo/jsonrpc/trace_filtering.go | 2 +- turbo/jsonrpc/tracing.go | 4 ++-- turbo/transactions/call.go | 10 ++++++---- turbo/transactions/tracing.go | 2 +- 18 files changed, 39 insertions(+), 34 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 1f822ca40d3..9bbb565135e 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -720,7 +720,7 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg txContext := core.NewEVMTxContext(msg) header := block.Header() - evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil) + evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil, b.m.ChainConfig) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmEnv := vm.NewEVM(evmContext, txContext, statedb, b.m.ChainConfig, vm.Config{}) diff --git a/cmd/state/exec3/trace_worker.go b/cmd/state/exec3/trace_worker.go index fb251f34e57..e979358c2e6 100644 --- a/cmd/state/exec3/trace_worker.go +++ b/cmd/state/exec3/trace_worker.go @@ -69,7 +69,7 @@ func NewTraceWorker(tx kv.TemporalTx, cc *chain.Config, engine consensus.EngineR func (e *TraceWorker) ChangeBlock(header *types.Header) { e.blockNum = header.Number.Uint64() - blockCtx := transactions.NewEVMBlockContext(e.engine, header, true /* requireCanonical */, e.tx, e.headerReader) + blockCtx := transactions.NewEVMBlockContext(e.engine, header, true /* requireCanonical */, e.tx, e.headerReader, e.evm.ChainConfig()) e.blockCtx = &blockCtx e.blockHash = header.Hash() e.header = header diff --git a/cmd/state/exec3/trace_worker2.go b/cmd/state/exec3/trace_worker2.go index 2d80b9b9100..90f37b20947 100644 --- a/cmd/state/exec3/trace_worker2.go +++ b/cmd/state/exec3/trace_worker2.go @@ -413,7 +413,7 @@ func CustomTraceMapReduce(fromBlock, toBlock uint64, consumer TraceConsumer, ctx defer getHashFnMute.Unlock() return f(n) } - blockContext := core.NewEVMBlockContext(header, getHashFn, cfg.Engine, nil /* author */) + blockContext := core.NewEVMBlockContext(header, getHashFn, cfg.Engine, nil /* author */, chainConfig) rules := chainConfig.Rules(blockNum, b.Time()) for txIndex := -1; txIndex <= len(txs); txIndex++ { diff --git a/core/blockchain.go b/core/blockchain.go index 2c8ef71d71b..7d2b3013087 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -279,7 +279,7 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig *chain author = &state.SystemAddress txContext = NewEVMTxContext(msg) } - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author, chainConfig) evm := vm.NewEVM(blockContext, txContext, ibs, chainConfig, vmConfig) ret, _, err := evm.Call( @@ -297,7 +297,7 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig *chain } // SysCreate is a special (system) contract creation methods for genesis constructors. -func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header) (result []byte, err error) { +func SysCreate(contract libcommon.Address, data []byte, chainConfig *chain.Config, ibs *state.IntraBlockState, header *types.Header) (result []byte, err error) { msg := types.NewMessage( contract, nil, // to @@ -313,8 +313,8 @@ func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config // Create a new context to be used in the EVM environment author := &contract txContext := NewEVMTxContext(msg) - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), nil, author) - evm := vm.NewEVM(blockContext, txContext, ibs, &chainConfig, vmConfig) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), nil, author, chainConfig) + evm := vm.NewEVM(blockContext, txContext, ibs, chainConfig, vmConfig) ret, _, err := evm.SysCreate( vm.AccountRef(msg.From()), diff --git a/core/evm.go b/core/evm.go index 3421f8a9a45..cc8413fb7d0 100644 --- a/core/evm.go +++ b/core/evm.go @@ -32,7 +32,8 @@ import ( ) // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address) evmtypes.BlockContext { +func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libcommon.Hash, + engine consensus.EngineReader, author *libcommon.Address, config *chain.Config) evmtypes.BlockContext { // If we don't have an explicit author (i.e. not mining), extract from the header var beneficiary libcommon.Address if author == nil { diff --git a/core/genesis_write.go b/core/genesis_write.go index 9df7b718408..c58aac1f57d 100644 --- a/core/genesis_write.go +++ b/core/genesis_write.go @@ -22,25 +22,27 @@ import ( "embed" "encoding/json" "fmt" + "math/big" + "os" + "slices" + "github.com/c2h5oh/datasize" "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/common/datadir" - "github.com/ledgerwatch/erigon-lib/config3" - "github.com/ledgerwatch/erigon-lib/kv/temporal" - state2 "github.com/ledgerwatch/erigon-lib/state" "github.com/ledgerwatch/log/v3" "golang.org/x/sync/errgroup" - "math/big" - "os" - "slices" "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/chain/networkname" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/datadir" "github.com/ledgerwatch/erigon-lib/common/hexutil" + "github.com/ledgerwatch/erigon-lib/config3" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" + "github.com/ledgerwatch/erigon-lib/kv/temporal" + state2 "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/consensus/merge" @@ -601,7 +603,7 @@ func GenesisToBlock(g *types.Genesis, tmpDir string, logger log.Logger) (*types. } if len(account.Constructor) > 0 { - if _, err = SysCreate(addr, account.Constructor, *g.Config, statedb, head); err != nil { + if _, err = SysCreate(addr, account.Constructor, g.Config, statedb, head); err != nil { return err } } diff --git a/core/state_processor.go b/core/state_processor.go index c5b81a49786..aacf8a0e5bd 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -112,7 +112,7 @@ func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcomm // about the transaction and calling mechanisms. cfg.SkipAnalysis = SkipAnalysis(config, header.Number.Uint64()) - blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author) + blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author, config) vmenv := vm.NewEVM(blockContext, evmtypes.TxContext{}, ibs, config, cfg) return applyTransaction(config, engine, gp, ibs, stateWriter, header, tx, usedGas, usedBlobGas, vmenv, cfg) diff --git a/eth/stagedsync/exec3.go b/eth/stagedsync/exec3.go index d31d5e93131..408d287b5d8 100644 --- a/eth/stagedsync/exec3.go +++ b/eth/stagedsync/exec3.go @@ -642,7 +642,7 @@ Loop: defer getHashFnMute.Unlock() return f(n) } - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, chainConfig) if parallel { select { case err := <-rwLoopErrCh: @@ -1445,7 +1445,7 @@ func reconstituteStep(last bool, defer getHashFnMute.Unlock() return f(n) } - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, chainConfig) rules := chainConfig.Rules(bn, b.Time()) for txIndex := -1; txIndex <= len(txs); txIndex++ { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 389261d4df4..07ad57c89aa 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -243,7 +243,7 @@ func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Co // Prepare the EVM. txContext := core.NewEVMTxContext(msg) header := block.HeaderNoCopy() - context := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), nil, &t.json.Env.Coinbase) + context := core.NewEVMBlockContext(header, core.GetHashFn(header, nil), nil, &t.json.Env.Coinbase, config) context.GetHash = vmTestBlockHash if baseFee != nil { context.BaseFee = new(uint256.Int) diff --git a/turbo/jsonrpc/eth_block.go b/turbo/jsonrpc/eth_block.go index 5fc462a588b..775947abc52 100644 --- a/turbo/jsonrpc/eth_block.go +++ b/turbo/jsonrpc/eth_block.go @@ -121,7 +121,7 @@ func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stat return nil, err } - blockCtx := transactions.NewEVMBlockContext(engine, header, stateBlockNumberOrHash.RequireCanonical, tx, api._blockReader) + blockCtx := transactions.NewEVMBlockContext(engine, header, stateBlockNumberOrHash.RequireCanonical, tx, api._blockReader, chainConfig) txCtx := core.NewEVMTxContext(firstMsg) // Get a new instance of the EVM evm := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: false}) diff --git a/turbo/jsonrpc/eth_call.go b/turbo/jsonrpc/eth_call.go index c011c098da8..b38e7fe4ecf 100644 --- a/turbo/jsonrpc/eth_call.go +++ b/turbo/jsonrpc/eth_call.go @@ -523,7 +523,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi2.CallArgs, // Apply the transaction with the access list tracer tracer := logger.NewAccessListTracer(accessList, excl, state) config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} - blockCtx := transactions.NewEVMBlockContext(engine, header, bNrOrHash.RequireCanonical, tx, api._blockReader) + blockCtx := transactions.NewEVMBlockContext(engine, header, bNrOrHash.RequireCanonical, tx, api._blockReader, chainConfig) txCtx := core.NewEVMTxContext(msg) evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, config) diff --git a/turbo/jsonrpc/eth_callMany.go b/turbo/jsonrpc/eth_callMany.go index fa9b9c59ffa..1fea2d73cae 100644 --- a/turbo/jsonrpc/eth_callMany.go +++ b/turbo/jsonrpc/eth_callMany.go @@ -155,7 +155,7 @@ func (api *APIImpl) CallMany(ctx context.Context, bundles []Bundle, simulateCont return hash } - blockCtx = core.NewEVMBlockContext(header, getHash, api.engine(), nil /* author */) + blockCtx = core.NewEVMBlockContext(header, getHash, api.engine(), nil /* author */, chainConfig) // Get a new instance of the EVM evm = vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) diff --git a/turbo/jsonrpc/otterscan_search_trace.go b/turbo/jsonrpc/otterscan_search_trace.go index 57f5682df5f..b25b2d0fcea 100644 --- a/turbo/jsonrpc/otterscan_search_trace.go +++ b/turbo/jsonrpc/otterscan_search_trace.go @@ -91,7 +91,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu msg, _ := tx.AsMessage(*signer, header.BaseFee, rules) tracer := NewTouchTracer(searchAddr) - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, chainConfig) TxContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) diff --git a/turbo/jsonrpc/trace_adhoc.go b/turbo/jsonrpc/trace_adhoc.go index 6350d87449e..5173aef7105 100644 --- a/turbo/jsonrpc/trace_adhoc.go +++ b/turbo/jsonrpc/trace_adhoc.go @@ -972,7 +972,7 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp return nil, err } - blockCtx := transactions.NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, tx, api._blockReader) + blockCtx := transactions.NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, tx, api._blockReader, chainConfig) txCtx := core.NewEVMTxContext(msg) blockCtx.GasLimit = math.MaxUint64 @@ -1197,7 +1197,7 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type vmConfig.Tracer = &ot } - blockCtx := transactions.NewEVMBlockContext(engine, header, parentNrOrHash.RequireCanonical, dbtx, api._blockReader) + blockCtx := transactions.NewEVMBlockContext(engine, header, parentNrOrHash.RequireCanonical, dbtx, api._blockReader, chainConfig) if useParent { blockCtx.GasLimit = math.MaxUint64 blockCtx.MaxGasLimit = true diff --git a/turbo/jsonrpc/trace_filtering.go b/turbo/jsonrpc/trace_filtering.go index 31f871e8465..ef619da22e3 100644 --- a/turbo/jsonrpc/trace_filtering.go +++ b/turbo/jsonrpc/trace_filtering.go @@ -570,7 +570,7 @@ func (api *TraceAPIImpl) filterV3(ctx context.Context, dbtx kv.TemporalTx, fromB vmConfig.Tracer = &ot ibs := state.New(cachedReader) - blockCtx := transactions.NewEVMBlockContext(engine, lastHeader, true /* requireCanonical */, dbtx, api._blockReader) + blockCtx := transactions.NewEVMBlockContext(engine, lastHeader, true /* requireCanonical */, dbtx, api._blockReader, chainConfig) txCtx := core.NewEVMTxContext(msg) evm := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vmConfig) diff --git a/turbo/jsonrpc/tracing.go b/turbo/jsonrpc/tracing.go index 3de0b21253d..59ccdaab4e4 100644 --- a/turbo/jsonrpc/tracing.go +++ b/turbo/jsonrpc/tracing.go @@ -361,7 +361,7 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA return fmt.Errorf("convert args to msg: %v", err) } - blockCtx := transactions.NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, dbtx, api._blockReader) + blockCtx := transactions.NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, dbtx, api._blockReader, chainConfig) txCtx := core.NewEVMTxContext(msg) // Trace the transaction and return return transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream, api.evmCallTimeout) @@ -472,7 +472,7 @@ func (api *PrivateDebugAPIImpl) TraceCallMany(ctx context.Context, bundles []Bun return hash } - blockCtx = core.NewEVMBlockContext(header, getHash, api.engine(), nil /* author */) + blockCtx = core.NewEVMBlockContext(header, getHash, api.engine(), nil /* author */, chainConfig) // Get a new instance of the EVM evm = vm.NewEVM(blockCtx, txCtx, st, chainConfig, vm.Config{Debug: false}) signer := types.MakeSigner(chainConfig, blockNum, block.Time()) diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index 56e19ee675f..edc0a312d95 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -80,7 +80,7 @@ func DoCall( if err != nil { return nil, err } - blockCtx := NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, tx, headerReader) + blockCtx := NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, tx, headerReader, chainConfig) txCtx := core.NewEVMTxContext(msg) evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, vm.Config{NoBaseFee: true}) @@ -105,8 +105,10 @@ func DoCall( return result, nil } -func NewEVMBlockContext(engine consensus.EngineReader, header *types.Header, requireCanonical bool, tx kv.Getter, headerReader services.HeaderReader) evmtypes.BlockContext { - return core.NewEVMBlockContext(header, MakeHeaderGetter(requireCanonical, tx, headerReader), engine, nil /* author */) +func NewEVMBlockContext(engine consensus.EngineReader, header *types.Header, requireCanonical bool, tx kv.Getter, + headerReader services.HeaderReader, config *chain.Config) evmtypes.BlockContext { + blockHashFunc := MakeHeaderGetter(requireCanonical, tx, headerReader) + return core.NewEVMBlockContext(header, blockHashFunc, engine, nil /* author */, config) } func MakeHeaderGetter(requireCanonical bool, tx kv.Getter, headerReader services.HeaderReader) func(uint64) libcommon.Hash { @@ -212,7 +214,7 @@ func NewReusableCaller( return nil, err } - blockCtx := NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, tx, headerReader) + blockCtx := NewEVMBlockContext(engine, header, blockNrOrHash.RequireCanonical, tx, headerReader, chainConfig) txCtx := core.NewEVMTxContext(msg) evm := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{NoBaseFee: true}) diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 26da6f5b9c5..ff2165c5db9 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -51,7 +51,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ } header := block.HeaderNoCopy() - blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, cfg) // Recompute transactions up to the target index. signer := types.MakeSigner(cfg, block.NumberU64(), block.Time()) From 2b42d6a95520eb84769da13d3e59082204e254ee Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 5 Jun 2024 14:57:53 +0200 Subject: [PATCH 2/3] Optimize BLOBBASEFEE --- core/evm.go | 32 ++++++++++++++----------- core/state_transition.go | 20 +++++----------- core/vm/eips.go | 7 +----- core/vm/evmtypes/evmtypes.go | 18 +++++++------- eth/tracers/tracers_test.go | 26 ++++++++++---------- turbo/jsonrpc/overlay_api.go | 46 +++++------------------------------- 6 files changed, 53 insertions(+), 96 deletions(-) diff --git a/core/evm.go b/core/evm.go index cc8413fb7d0..83549abb12c 100644 --- a/core/evm.go +++ b/core/evm.go @@ -27,6 +27,7 @@ import ( "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/merge" + "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm/evmtypes" ) @@ -56,10 +57,13 @@ func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libco *prevRandDao = header.MixDigest } - var excessBlobGas *uint64 + var blobBaseFee *uint256.Int if header.ExcessBlobGas != nil { - excessBlobGas = new(uint64) - *excessBlobGas = *header.ExcessBlobGas + var err error + blobBaseFee, err = misc.GetBlobGasPrice(config, *header.ExcessBlobGas) + if err != nil { + panic(err) + } } var transferFunc evmtypes.TransferFunc @@ -69,17 +73,17 @@ func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libco transferFunc = Transfer } return evmtypes.BlockContext{ - CanTransfer: CanTransfer, - Transfer: transferFunc, - GetHash: blockHashFunc, - Coinbase: beneficiary, - BlockNumber: header.Number.Uint64(), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: &baseFee, - GasLimit: header.GasLimit, - PrevRanDao: prevRandDao, - ExcessBlobGas: excessBlobGas, + CanTransfer: CanTransfer, + Transfer: transferFunc, + GetHash: blockHashFunc, + Coinbase: beneficiary, + BlockNumber: header.Number.Uint64(), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + BaseFee: &baseFee, + GasLimit: header.GasLimit, + PrevRanDao: prevRandDao, + BlobBaseFee: blobBaseFee, } } diff --git a/core/state_transition.go b/core/state_transition.go index 7e1e29993dd..37ef5100376 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -27,7 +27,6 @@ import ( cmath "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" - "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/core/vm/evmtypes" "github.com/ledgerwatch/erigon/crypto" @@ -204,13 +203,10 @@ func (st *StateTransition) buyGas(gasBailout bool) error { // compute blob fee for eip-4844 data blobs if any blobGasVal := new(uint256.Int) if st.evm.ChainRules().IsCancun { - if st.evm.Context.ExcessBlobGas == nil { + blobGasPrice := st.evm.Context.BlobBaseFee + if blobGasPrice == nil { return fmt.Errorf("%w: Cancun is active but ExcessBlobGas is nil", ErrInternalFailure) } - blobGasPrice, err := misc.GetBlobGasPrice(st.evm.ChainConfig(), *st.evm.Context.ExcessBlobGas) - if err != nil { - return err - } blobGasVal, overflow = blobGasVal.MulOverflow(blobGasPrice, new(uint256.Int).SetUint64(st.msg.BlobGas())) if overflow { return fmt.Errorf("%w: overflow converting blob gas: %v", ErrInsufficientFunds, blobGasVal) @@ -313,18 +309,14 @@ func (st *StateTransition) preCheck(gasBailout bool) error { } } if st.msg.BlobGas() > 0 && st.evm.ChainRules().IsCancun { - if st.evm.Context.ExcessBlobGas == nil { + blobGasPrice := st.evm.Context.BlobBaseFee + if blobGasPrice == nil { return fmt.Errorf("%w: Cancun is active but ExcessBlobGas is nil", ErrInternalFailure) } - blobGasPrice, err := misc.GetBlobGasPrice(st.evm.ChainConfig(), *st.evm.Context.ExcessBlobGas) - if err != nil { - return err - } maxFeePerBlobGas := st.msg.MaxFeePerBlobGas() if blobGasPrice.Cmp(maxFeePerBlobGas) > 0 { - return fmt.Errorf("%w: address %v, maxFeePerBlobGas: %v blobGasPrice: %v, excessBlobGas: %v", - ErrMaxFeePerBlobGas, - st.msg.From().Hex(), st.msg.MaxFeePerBlobGas(), blobGasPrice, st.evm.Context.ExcessBlobGas) + return fmt.Errorf("%w: address %v, maxFeePerBlobGas: %v < blobGasPrice: %v", + ErrMaxFeePerBlobGas, st.msg.From().Hex(), st.msg.MaxFeePerBlobGas(), blobGasPrice) } } diff --git a/core/vm/eips.go b/core/vm/eips.go index 24e3f1b09e7..9bdbb5cbdda 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -24,7 +24,6 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/params" ) @@ -303,11 +302,7 @@ func enable6780(jt *JumpTable) { // opBlobBaseFee implements the BLOBBASEFEE opcode func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) { - excessBlobGas := interpreter.evm.Context.ExcessBlobGas - blobBaseFee, err := misc.GetBlobGasPrice(interpreter.evm.ChainConfig(), *excessBlobGas) - if err != nil { - return nil, err - } + blobBaseFee := interpreter.evm.Context.BlobBaseFee callContext.Stack.Push(blobBaseFee) return nil, nil } diff --git a/core/vm/evmtypes/evmtypes.go b/core/vm/evmtypes/evmtypes.go index 4b919f6b3e3..fcfbc59aa6a 100644 --- a/core/vm/evmtypes/evmtypes.go +++ b/core/vm/evmtypes/evmtypes.go @@ -24,15 +24,15 @@ type BlockContext struct { GetHash GetHashFunc // Block information - Coinbase common.Address // Provides information for COINBASE - GasLimit uint64 // Provides information for GASLIMIT - MaxGasLimit bool // Use GasLimit override for 2^256-1 (to be compatible with OpenEthereum's trace_call) - BlockNumber uint64 // Provides information for NUMBER - Time uint64 // Provides information for TIME - Difficulty *big.Int // Provides information for DIFFICULTY - BaseFee *uint256.Int // Provides information for BASEFEE - PrevRanDao *common.Hash // Provides information for PREVRANDAO - ExcessBlobGas *uint64 // Provides information for handling data blobs + Coinbase common.Address // Provides information for COINBASE + GasLimit uint64 // Provides information for GASLIMIT + MaxGasLimit bool // Use GasLimit override for 2^256-1 (to be compatible with OpenEthereum's trace_call) + BlockNumber uint64 // Provides information for NUMBER + Time uint64 // Provides information for TIME + Difficulty *big.Int // Provides information for DIFFICULTY + BaseFee *uint256.Int // Provides information for BASEFEE + PrevRanDao *common.Hash // Provides information for PREVRANDAO + BlobBaseFee *uint256.Int // Provides information for BLOBBASEFEE } // TxContext provides the EVM with information about a transaction. diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 5d2b53c5984..e7f015a945c 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -20,11 +20,14 @@ import ( "crypto/ecdsa" "crypto/rand" "encoding/json" - "github.com/ledgerwatch/erigon-lib/common/hexutil" "math/big" "testing" + "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutil" + "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" @@ -35,8 +38,6 @@ import ( "github.com/ledgerwatch/erigon/turbo/stages/mock" "github.com/stretchr/testify/require" - "github.com/holiman/uint256" - // Force-load native and js packages, to trigger registration "github.com/ledgerwatch/erigon/eth/tracers" _ "github.com/ledgerwatch/erigon/eth/tracers/js" @@ -70,18 +71,17 @@ func TestPrestateTracerCreate2(t *testing.T) { Origin: origin, GasPrice: uint256.NewInt(1), } - excessBlobGas := uint64(50000) context := evmtypes.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: libcommon.Address{}, - BlockNumber: 8000000, - Time: 5, - Difficulty: big.NewInt(0x30000), - GasLimit: uint64(6000000), - ExcessBlobGas: &excessBlobGas, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: libcommon.Address{}, + BlockNumber: 8000000, + Time: 5, + Difficulty: big.NewInt(0x30000), + GasLimit: uint64(6000000), + BaseFee: uint256.NewInt(0), + BlobBaseFee: uint256.NewInt(50000), } - context.BaseFee = uint256.NewInt(0) alloc := types.GenesisAlloc{} // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns diff --git a/turbo/jsonrpc/overlay_api.go b/turbo/jsonrpc/overlay_api.go index 86290ca7717..1c775113abb 100644 --- a/turbo/jsonrpc/overlay_api.go +++ b/turbo/jsonrpc/overlay_api.go @@ -3,14 +3,12 @@ package jsonrpc import ( "context" "fmt" - "math/big" "runtime" "sync" "time" "github.com/RoaringBitmap/roaring" "github.com/RoaringBitmap/roaring/roaring64" - "github.com/holiman/uint256" "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon-lib/chain" @@ -80,7 +78,6 @@ func (api *OverlayAPIImpl) CallConstructor(ctx context.Context, address common.A blockCtx evmtypes.BlockContext txCtx evmtypes.TxContext overrideBlockHash map[uint64]common.Hash - baseFee uint256.Int ) tx, err := api.db.BeginRo(ctx) @@ -142,9 +139,9 @@ func (api *OverlayAPIImpl) CallConstructor(ctx context.Context, address common.A statedb := state.New(stateReader) - parent := block.Header() + header := block.Header() - if parent == nil { + if header == nil { return nil, fmt.Errorf("block %d(%x) not found", blockNum, block.Hash()) } @@ -159,21 +156,7 @@ func (api *OverlayAPIImpl) CallConstructor(ctx context.Context, address common.A return hash } - if parent.BaseFee != nil { - baseFee.SetFromBig(parent.BaseFee) - } - - blockCtx = evmtypes.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHash, - Coinbase: parent.Coinbase, - BlockNumber: parent.Number.Uint64(), - Time: parent.Time, - Difficulty: new(big.Int).Set(parent.Difficulty), - GasLimit: parent.GasLimit, - BaseFee: &baseFee, - } + blockCtx = core.NewEVMBlockContext(header, getHash, api.engine(), nil, chainConfig) // Get a new instance of the EVM evm = vm.NewEVM(blockCtx, txCtx, statedb, chainConfig, vm.Config{Debug: false}) @@ -413,7 +396,6 @@ func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, sta blockCtx evmtypes.BlockContext txCtx evmtypes.TxContext overrideBlockHash map[uint64]common.Hash - baseFee uint256.Int ) blockLogs := []*types.Log{} @@ -433,9 +415,9 @@ func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, sta replayTransactions = block.Transactions() log.Debug("[replayBlock] replayTx", "length", len(replayTransactions)) - parent := block.Header() + header := block.Header() - if parent == nil { + if header == nil { return nil, fmt.Errorf("block %d(%x) not found", blockNum, hash) } @@ -450,23 +432,7 @@ func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, sta return hash } - if parent.BaseFee != nil { - baseFee.SetFromBig(parent.BaseFee) - } - - var excessBlobGas uint64 = 0 - blockCtx = evmtypes.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - GetHash: getHash, - Coinbase: parent.Coinbase, - BlockNumber: parent.Number.Uint64(), - Time: parent.Time, - Difficulty: new(big.Int).Set(parent.Difficulty), - GasLimit: parent.GasLimit, - BaseFee: &baseFee, - ExcessBlobGas: &excessBlobGas, - } + blockCtx = core.NewEVMBlockContext(header, getHash, api.engine(), nil, chainConfig) signer := types.MakeSigner(chainConfig, blockNum, blockCtx.Time) rules := chainConfig.Rules(blockNum, blockCtx.Time) From 6d6cd4261bf78b7ea3840255833591d0fe80b456 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 5 Jun 2024 15:29:44 +0200 Subject: [PATCH 3/3] improve error handling slightly --- consensus/misc/eip1559.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/consensus/misc/eip1559.go b/consensus/misc/eip1559.go index f07e80f6236..c7646223605 100644 --- a/consensus/misc/eip1559.go +++ b/consensus/misc/eip1559.go @@ -22,7 +22,6 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/polygon/bor/borcfg" @@ -66,7 +65,7 @@ type eip1559Calculator struct{} func (f eip1559Calculator) CurrentFees(chainConfig *chain.Config, db kv.Getter) (baseFee, blobFee, minBlobGasPrice, blockGasLimit uint64, err error) { hash := rawdb.ReadHeadHeaderHash(db) - if hash == (libcommon.Hash{}) { + if hash == (common.Hash{}) { return 0, 0, 0, 0, fmt.Errorf("can't get head header hash") } @@ -86,9 +85,10 @@ func (f eip1559Calculator) CurrentFees(chainConfig *chain.Config, db kv.Getter) if currentHeader.ExcessBlobGas != nil { excessBlobGas := CalcExcessBlobGas(chainConfig, currentHeader) b, err := GetBlobGasPrice(chainConfig, excessBlobGas) - if err == nil { - blobFee = b.Uint64() + if err != nil { + return 0, 0, 0, 0, err } + blobFee = b.Uint64() } }