From 51dd8ea82035affb04bf3f4a09dd32180037aad8 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Fri, 30 Apr 2021 15:45:31 +0200 Subject: [PATCH] core,eth,les: calculate effective gas price in tx.AsMessage(..) --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/state_prefetcher.go | 2 +- core/state_processor.go | 4 ++-- core/state_transition.go | 19 +++++-------------- core/types/transaction.go | 8 +++++++- eth/state_accessor.go | 2 +- eth/tracers/api.go | 8 ++++---- eth/tracers/api_test.go | 2 +- eth/tracers/tracers_test.go | 4 ++-- les/state_accessor.go | 2 +- 10 files changed, 25 insertions(+), 28 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 5696dba5187b..982c4bebb8e1 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -125,7 +125,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } for i, tx := range txs { - msg, err := tx.AsMessage(signer) + msg, err := tx.AsMessage(signer, pre.Env.BaseFee) if err != nil { log.Info("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, i) diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 05394321f74b..ecdfa67f00dd 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -63,7 +63,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c return } // Convert the transaction into an executable message and pre-cache its sender - msg, err := tx.AsMessage(signer) + msg, err := tx.AsMessage(signer, header.BaseFee) if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index e5861b983574..1e55329d7f29 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -77,7 +77,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { - msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number)) + msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee) if err != nil { return nil, nil, 0, err } @@ -145,7 +145,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) + msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), header.BaseFee) if err != nil { return nil, err } diff --git a/core/state_transition.go b/core/state_transition.go index f10917c9b36d..ff88f70216b0 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -187,12 +187,7 @@ func (st *StateTransition) to() common.Address { } func (st *StateTransition) buyGas() error { - price := st.gasPrice - if st.evm.ChainConfig().IsAleut(st.evm.Context.BlockNumber) { - // price = min(tip, feeCap - baseFee) + baseFee - price = cmath.BigMin(new(big.Int).Add(st.tip, st.evm.Context.BaseFee), st.feeCap) - } - mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), price) + mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice) if have, want := st.state.GetBalance(st.msg.From()), mgval; have.Cmp(want) < 0 { return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want) } @@ -301,11 +296,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } st.refundGas() - price := st.gasPrice + effectiveTip := st.gasPrice if st.evm.ChainConfig().IsAleut(st.evm.Context.BlockNumber) { - price = cmath.BigMin(st.tip, new(big.Int).Sub(st.feeCap, st.evm.Context.BaseFee)) + effectiveTip = cmath.BigMin(st.tip, new(big.Int).Sub(st.feeCap, st.evm.Context.BaseFee)) } - st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), price)) + st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) return &ExecutionResult{ UsedGas: st.gasUsed(), @@ -323,11 +318,7 @@ func (st *StateTransition) refundGas() { st.gas += refund // Return ETH for remaining gas, exchanged at the original rate. - price := st.gasPrice - if st.evm.ChainConfig().IsAleut(st.evm.Context.BlockNumber) { - price = cmath.BigMin(new(big.Int).Add(st.tip, st.evm.Context.BaseFee), st.feeCap) - } - remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), price) + remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) st.state.AddBalance(st.msg.From(), remaining) // Also return remaining gas to the block gas counter so it is diff --git a/core/types/transaction.go b/core/types/transaction.go index 96f4d6af1c4b..ace1843e932b 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -26,6 +26,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" ) @@ -523,7 +524,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b } // AsMessage returns the transaction as a core.Message. -func (tx *Transaction) AsMessage(s Signer) (Message, error) { +func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) { msg := Message{ nonce: tx.Nonce(), gasLimit: tx.Gas(), @@ -537,6 +538,11 @@ func (tx *Transaction) AsMessage(s Signer) (Message, error) { checkNonce: true, } + // If baseFee provided, set gasPrice to effectiveGasPrice. + if baseFee != nil { + msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.tip, baseFee), msg.feeCap) + } + var err error msg.from, err = Sender(s, tx) return msg, err diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 84cfaf4d738d..8d53739721fb 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -162,7 +162,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec signer := types.MakeSigner(eth.blockchain.Config(), block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := tx.AsMessage(signer) + msg, _ := tx.AsMessage(signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) if idx == txIndex { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 1c727f1366c2..172054e9b8ee 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -271,7 +271,7 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config blockCtx := core.NewEVMBlockContext(task.block.Header(), api.chainContext(localctx), nil) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { - msg, _ := tx.AsMessage(signer) + msg, _ := tx.AsMessage(signer, task.block.BaseFee()) txctx := &txTraceContext{ index: i, hash: tx.Hash(), @@ -523,7 +523,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac defer pend.Done() // Fetch and execute the next transaction trace tasks for task := range jobs { - msg, _ := txs[task.index].AsMessage(signer) + msg, _ := txs[task.index].AsMessage(signer, block.BaseFee()) txctx := &txTraceContext{ index: task.index, hash: txs[task.index].Hash(), @@ -545,7 +545,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac jobs <- &txTraceTask{statedb: statedb.Copy(), index: i} // Generate the next state snapshot fast without tracing - msg, _ := tx.AsMessage(signer) + msg, _ := tx.AsMessage(signer, block.BaseFee()) statedb.Prepare(tx.Hash(), block.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil { @@ -630,7 +630,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block for i, tx := range block.Transactions() { // Prepare the trasaction for un-traced execution var ( - msg, _ = tx.AsMessage(signer) + msg, _ = tx.AsMessage(signer, block.BaseFee()) txContext = core.NewEVMTxContext(msg) vmConf vm.Config dump *os.File diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 4c0240cd2c5b..24bce320cf00 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -161,7 +161,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block // Recompute transactions up to the target index. signer := types.MakeSigner(b.chainConfig, block.Number()) for idx, tx := range block.Transactions() { - msg, _ := tx.AsMessage(signer) + msg, _ := tx.AsMessage(signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), b.chain, nil) if idx == txIndex { diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 9dc4c696311c..8b01edd7b4cc 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -179,7 +179,7 @@ func TestPrestateTracerCreate2(t *testing.T) { } evm := vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer}) - msg, err := tx.AsMessage(signer) + msg, err := tx.AsMessage(signer, nil) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } @@ -254,7 +254,7 @@ func TestCallTracer(t *testing.T) { } evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) - msg, err := tx.AsMessage(signer) + msg, err := tx.AsMessage(signer, nil) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } diff --git a/les/state_accessor.go b/les/state_accessor.go index af5df36508ec..e276b06dc748 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -55,7 +55,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. signer := types.MakeSigner(leth.blockchain.Config(), block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := tx.AsMessage(signer) + msg, _ := tx.AsMessage(signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil) statedb.Prepare(tx.Hash(), block.Hash(), idx)