core: use uint256 in core.Message (#34934)

Changes core.Message to use Uint256 which is faster

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
This commit is contained in:
Marius van der Wijden 2026-05-11 16:25:57 +02:00 committed by GitHub
parent 2f11dccca0
commit e1047b9c84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 142 additions and 87 deletions

View file

@ -204,6 +204,10 @@ func (b *Big) ToInt() *big.Int {
return (*big.Int)(b) return (*big.Int)(b)
} }
func (b *Big) ToUint256() (*uint256.Int, bool) {
return uint256.FromBig((*big.Int)(b))
}
// String returns the hex encoding of b. // String returns the hex encoding of b.
func (b *Big) String() string { func (b *Big) String() string {
return EncodeBig(b.ToInt()) return EncodeBig(b.ToInt())

View file

@ -87,7 +87,7 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
func NewEVMTxContext(msg *Message) vm.TxContext { func NewEVMTxContext(msg *Message) vm.TxContext {
ctx := vm.TxContext{ ctx := vm.TxContext{
Origin: msg.From, Origin: msg.From,
GasPrice: uint256.MustFromBig(msg.GasPrice), GasPrice: msg.GasPrice,
BlobHashes: msg.BlobHashes, BlobHashes: msg.BlobHashes,
} }
return ctx return ctx

View file

@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/internal/telemetry" "github.com/ethereum/go-ethereum/internal/telemetry"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256"
) )
// StateProcessor is a basic Processor, which takes care of transitioning // StateProcessor is a basic Processor, which takes care of transitioning
@ -254,9 +255,9 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) {
msg := &Message{ msg := &Message{
From: params.SystemAddress, From: params.SystemAddress,
GasLimit: 30_000_000, GasLimit: 30_000_000,
GasPrice: common.Big0, GasPrice: uint256.NewInt(0),
GasFeeCap: common.Big0, GasFeeCap: uint256.NewInt(0),
GasTipCap: common.Big0, GasTipCap: uint256.NewInt(0),
To: &params.BeaconRootsAddress, To: &params.BeaconRootsAddress,
Data: beaconRoot[:], Data: beaconRoot[:],
} }
@ -281,9 +282,9 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) {
msg := &Message{ msg := &Message{
From: params.SystemAddress, From: params.SystemAddress,
GasLimit: 30_000_000, GasLimit: 30_000_000,
GasPrice: common.Big0, GasPrice: uint256.NewInt(0),
GasFeeCap: common.Big0, GasFeeCap: uint256.NewInt(0),
GasTipCap: common.Big0, GasTipCap: uint256.NewInt(0),
To: &params.HistoryStorageAddress, To: &params.HistoryStorageAddress,
Data: prevHash.Bytes(), Data: prevHash.Bytes(),
} }
@ -321,9 +322,9 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte
msg := &Message{ msg := &Message{
From: params.SystemAddress, From: params.SystemAddress,
GasLimit: 30_000_000, GasLimit: 30_000_000,
GasPrice: common.Big0, GasPrice: uint256.NewInt(0),
GasFeeCap: common.Big0, GasFeeCap: uint256.NewInt(0),
GasTipCap: common.Big0, GasTipCap: uint256.NewInt(0),
To: &addr, To: &addr,
} }
evm.SetTxContext(NewEVMTxContext(msg)) evm.SetTxContext(NewEVMTxContext(msg))

View file

@ -210,14 +210,14 @@ type Message struct {
To *common.Address To *common.Address
From common.Address From common.Address
Nonce uint64 Nonce uint64
Value *big.Int Value *uint256.Int
GasLimit uint64 GasLimit uint64
GasPrice *big.Int GasPrice *uint256.Int
GasFeeCap *big.Int GasFeeCap *uint256.Int
GasTipCap *big.Int GasTipCap *uint256.Int
Data []byte Data []byte
AccessList types.AccessList AccessList types.AccessList
BlobGasFeeCap *big.Int BlobGasFeeCap *uint256.Int
BlobHashes []common.Hash BlobHashes []common.Hash
SetCodeAuthorizations []types.SetCodeAuthorization SetCodeAuthorizations []types.SetCodeAuthorization
@ -238,32 +238,64 @@ type Message struct {
// TransactionToMessage converts a transaction into a Message. // TransactionToMessage converts a transaction into a Message.
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) { func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
from, err := types.Sender(s, tx)
if err != nil {
return nil, err
}
gasPrice, overflow := uint256.FromBig(tx.GasPrice())
if overflow {
return nil, fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
from.Hex(), tx.GasPrice().BitLen())
}
txGasFeeCap := tx.GasFeeCap()
gasFeeCap, overflow := uint256.FromBig(txGasFeeCap)
if overflow {
return nil, fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
from.Hex(), tx.GasFeeCap().BitLen())
}
txGasTipCap := tx.GasTipCap()
gasTipCap, overflow := uint256.FromBig(txGasTipCap)
if overflow {
return nil, fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
from.Hex(), tx.GasTipCap().BitLen())
}
value, overflow := uint256.FromBig(tx.Value())
if overflow {
return nil, fmt.Errorf("value exceeds 256 bits: address %v", from.Hex())
}
blobGasFeeCap, overflow := uint256.FromBig(tx.BlobGasFeeCap())
if overflow {
return nil, fmt.Errorf("blobGasFeeCap exceeds 256 bits: address %v", from.Hex())
}
msg := &Message{ msg := &Message{
From: from,
Nonce: tx.Nonce(), Nonce: tx.Nonce(),
GasLimit: tx.Gas(), GasLimit: tx.Gas(),
GasPrice: tx.GasPrice(), GasPrice: gasPrice,
GasFeeCap: tx.GasFeeCap(), GasFeeCap: gasFeeCap,
GasTipCap: tx.GasTipCap(), GasTipCap: gasTipCap,
To: tx.To(), To: tx.To(),
Value: tx.Value(), Value: value,
Data: tx.Data(), Data: tx.Data(),
AccessList: tx.AccessList(), AccessList: tx.AccessList(),
SetCodeAuthorizations: tx.SetCodeAuthorizations(), SetCodeAuthorizations: tx.SetCodeAuthorizations(),
SkipNonceChecks: false, SkipNonceChecks: false,
SkipTransactionChecks: false, SkipTransactionChecks: false,
BlobHashes: tx.BlobHashes(), BlobHashes: tx.BlobHashes(),
BlobGasFeeCap: tx.BlobGasFeeCap(), BlobGasFeeCap: blobGasFeeCap,
} }
// If baseFee provided, set gasPrice to effectiveGasPrice. // If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil { if baseFee != nil {
msg.GasPrice = msg.GasPrice.Add(msg.GasTipCap, baseFee) effectiveGasPrice := new(big.Int).Add(baseFee, txGasTipCap)
if msg.GasPrice.Cmp(msg.GasFeeCap) > 0 { if effectiveGasPrice.Cmp(txGasFeeCap) > 0 {
msg.GasPrice = msg.GasFeeCap effectiveGasPrice = txGasFeeCap
} }
// EffectiveGasPrice is already capped by txGasFeeCap, therefore
// the overflow check is not required.
msg.GasPrice = uint256.MustFromBig(effectiveGasPrice)
} }
var err error return msg, nil
msg.From, err = types.Sender(s, tx)
return msg, err
} }
// ApplyMessage computes the new state by applying the given message // ApplyMessage computes the new state by applying the given message
@ -333,32 +365,55 @@ func (st *stateTransition) to() common.Address {
} }
func (st *stateTransition) buyGas() error { func (st *stateTransition) buyGas() error {
mgval := new(big.Int).SetUint64(st.msg.GasLimit) mgval := new(uint256.Int).SetUint64(st.msg.GasLimit)
mgval.Mul(mgval, st.msg.GasPrice) _, overflow := mgval.MulOverflow(mgval, st.msg.GasPrice)
balanceCheck := new(big.Int).Set(mgval) if overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
balanceCheck := new(uint256.Int).Set(mgval)
if st.msg.GasFeeCap != nil { if st.msg.GasFeeCap != nil {
balanceCheck.SetUint64(st.msg.GasLimit) balanceCheck.SetUint64(st.msg.GasLimit)
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap) if _, overflow := balanceCheck.MulOverflow(balanceCheck, st.msg.GasFeeCap); overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
}
if st.msg.Value != nil {
if _, overflow := balanceCheck.AddOverflow(balanceCheck, st.msg.Value); overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
} }
balanceCheck.Add(balanceCheck, st.msg.Value)
if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
if blobGas := st.blobGasUsed(); blobGas > 0 { if blobGas := st.blobGasUsed(); blobGas > 0 {
// Check that the user has enough funds to cover blobGasUsed * tx.BlobGasFeeCap // Check that the user has enough funds to cover blobGasUsed * tx.BlobGasFeeCap
blobBalanceCheck := new(big.Int).SetUint64(blobGas) blobBalanceCheck := new(uint256.Int).SetUint64(blobGas)
blobBalanceCheck.Mul(blobBalanceCheck, st.msg.BlobGasFeeCap) if _, overflow := blobBalanceCheck.MulOverflow(blobBalanceCheck, st.msg.BlobGasFeeCap); overflow {
balanceCheck.Add(balanceCheck, blobBalanceCheck) return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
if _, overflow := balanceCheck.AddOverflow(balanceCheck, blobBalanceCheck); overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
// Pay for blobGasUsed * actual blob fee // Pay for blobGasUsed * actual blob fee
blobFee := new(big.Int).SetUint64(blobGas) blobBaseFee, overflow := uint256.FromBig(st.evm.Context.BlobBaseFee)
blobFee.Mul(blobFee, st.evm.Context.BlobBaseFee) if overflow {
mgval.Add(mgval, blobFee) return fmt.Errorf("invalid blobBaseFee: %v", st.evm.Context.BlobBaseFee)
}
blobFee := new(uint256.Int).SetUint64(blobGas)
// In practice, overflow checking is unnecessary, as blobBaseFee cannot exceed
// BlobGasFeeCap. However, in eth_call it is still possible for users to specify
// an excessively large blob base fee and bypass the blob base fee validation.
_, overflow = blobFee.MulOverflow(blobFee, blobBaseFee)
if overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
_, overflow = mgval.AddOverflow(mgval, blobFee)
if overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
} }
} }
balanceCheckU256, overflow := uint256.FromBig(balanceCheck) if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
if overflow {
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
}
if have, want := st.state.GetBalance(st.msg.From), balanceCheckU256; have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want) return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
} }
if err := st.gp.SubGas(st.msg.GasLimit); err != nil { if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
@ -371,8 +426,7 @@ func (st *stateTransition) buyGas() error {
st.gasRemaining = vm.NewGasBudget(st.msg.GasLimit) st.gasRemaining = vm.NewGasBudget(st.msg.GasLimit)
st.initialBudget = st.gasRemaining.Copy() st.initialBudget = st.gasRemaining.Copy()
mgvalU256, _ := uint256.FromBig(mgval) st.state.SubBalance(st.msg.From, mgval, tracing.BalanceDecreaseGasBuy)
st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy)
return nil return nil
} }
@ -412,21 +466,13 @@ func (st *stateTransition) preCheck() error {
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call) // Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
skipCheck := st.evm.Config.NoBaseFee && msg.GasFeeCap.BitLen() == 0 && msg.GasTipCap.BitLen() == 0 skipCheck := st.evm.Config.NoBaseFee && msg.GasFeeCap.BitLen() == 0 && msg.GasTipCap.BitLen() == 0
if !skipCheck { if !skipCheck {
if l := msg.GasFeeCap.BitLen(); l > 256 {
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
msg.From.Hex(), l)
}
if l := msg.GasTipCap.BitLen(); l > 256 {
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
msg.From.Hex(), l)
}
if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 { if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 {
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap, return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap) msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap)
} }
// This will panic if baseFee is nil, but basefee presence is verified // This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation. // as part of header validation.
if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 { if msg.GasFeeCap.CmpBig(st.evm.Context.BaseFee) < 0 {
return fmt.Errorf("%w: address %v, maxFeePerGas: %s, baseFee: %s", ErrFeeCapTooLow, return fmt.Errorf("%w: address %v, maxFeePerGas: %s, baseFee: %s", ErrFeeCapTooLow,
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee) msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
} }
@ -460,7 +506,7 @@ func (st *stateTransition) preCheck() error {
if !skipCheck { if !skipCheck {
// This will panic if blobBaseFee is nil, but blobBaseFee presence // This will panic if blobBaseFee is nil, but blobBaseFee presence
// is verified as part of header validation. // is verified as part of header validation.
if msg.BlobGasFeeCap.Cmp(st.evm.Context.BlobBaseFee) < 0 { if msg.BlobGasFeeCap.CmpBig(st.evm.Context.BlobBaseFee) < 0 {
return fmt.Errorf("%w: address %v blobGasFeeCap: %v, blobBaseFee: %v", ErrBlobFeeCapTooLow, return fmt.Errorf("%w: address %v blobGasFeeCap: %v, blobBaseFee: %v", ErrBlobFeeCapTooLow,
msg.From.Hex(), msg.BlobGasFeeCap, st.evm.Context.BlobBaseFee) msg.From.Hex(), msg.BlobGasFeeCap, st.evm.Context.BlobBaseFee)
} }
@ -543,9 +589,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
} }
// Check clause 6 // Check clause 6
value, overflow := uint256.FromBig(msg.Value) value := msg.Value
if overflow { if value == nil {
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex()) value = new(uint256.Int)
} }
if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From, value) { if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From, value) {
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex()) return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
@ -629,9 +675,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
} }
effectiveTip := msg.GasPrice effectiveTip := msg.GasPrice
if rules.IsLondon { if rules.IsLondon {
effectiveTip = new(big.Int).Sub(msg.GasPrice, st.evm.Context.BaseFee) baseFee, overflow := uint256.FromBig(st.evm.Context.BaseFee)
if overflow {
return nil, fmt.Errorf("invalid baseFee: %v", st.evm.Context.BaseFee)
}
effectiveTip = new(uint256.Int).Sub(msg.GasPrice, baseFee)
} }
effectiveTipU256, _ := uint256.FromBig(effectiveTip)
if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 { if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 {
// Skip fee payment when NoBaseFee is set and the fee fields // Skip fee payment when NoBaseFee is set and the fee fields
@ -639,7 +688,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
// the coinbase when simulating calls. // the coinbase when simulating calls.
} else { } else {
fee := new(uint256.Int).SetUint64(st.gasUsed()) fee := new(uint256.Int).SetUint64(st.gasUsed())
fee.Mul(fee, effectiveTipU256) fee.Mul(fee, effectiveTip)
st.state.AddBalance(st.evm.Context.Coinbase, fee, tracing.BalanceIncreaseRewardTransactionFee) st.state.AddBalance(st.evm.Context.Coinbase, fee, tracing.BalanceIncreaseRewardTransactionFee)
// add the coinbase to the witness iff the fee is greater than 0 // add the coinbase to the witness iff the fee is greater than 0
@ -741,7 +790,7 @@ func (st *stateTransition) calcRefund() vm.GasBudget {
// exchanged at the original rate. // exchanged at the original rate.
func (st *stateTransition) returnGas() { func (st *stateTransition) returnGas() {
remaining := uint256.NewInt(st.gasRemaining.RegularGas) remaining := uint256.NewInt(st.gasRemaining.RegularGas)
remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice)) remaining.Mul(remaining, st.msg.GasPrice)
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn) st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)
if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && st.gasRemaining.RegularGas > 0 { if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && st.gasRemaining.RegularGas > 0 {

View file

@ -22,13 +22,13 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
) )
// Options are the contextual parameters to execute the requested call. // Options are the contextual parameters to execute the requested call.
@ -70,17 +70,17 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
} }
// Normalize the max fee per gas the call is willing to spend. // Normalize the max fee per gas the call is willing to spend.
var feeCap *big.Int var feeCap *uint256.Int
if call.GasFeeCap != nil { if call.GasFeeCap != nil {
feeCap = call.GasFeeCap feeCap = call.GasFeeCap
} else if call.GasPrice != nil { } else if call.GasPrice != nil {
feeCap = call.GasPrice feeCap = call.GasPrice
} else { } else {
feeCap = common.Big0 feeCap = uint256.NewInt(0)
} }
// Recap the highest gas limit with account's available balance. // Recap the highest gas limit with account's available balance.
if feeCap.BitLen() != 0 { if feeCap.BitLen() != 0 {
balance := opts.State.GetBalance(call.From).ToBig() balance := opts.State.GetBalance(call.From).Clone()
available := balance available := balance
if call.Value != nil { if call.Value != nil {
@ -90,8 +90,8 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
available.Sub(available, call.Value) available.Sub(available, call.Value)
} }
if opts.Config.IsCancun(opts.Header.Number, opts.Header.Time) && len(call.BlobHashes) > 0 { if opts.Config.IsCancun(opts.Header.Number, opts.Header.Time) && len(call.BlobHashes) > 0 {
blobGasPerBlob := new(big.Int).SetInt64(params.BlobTxBlobGasPerBlob) blobGasPerBlob := uint256.NewInt(params.BlobTxBlobGasPerBlob)
blobBalanceUsage := new(big.Int).SetInt64(int64(len(call.BlobHashes))) blobBalanceUsage := uint256.NewInt(uint64(len(call.BlobHashes)))
blobBalanceUsage.Mul(blobBalanceUsage, blobGasPerBlob) blobBalanceUsage.Mul(blobBalanceUsage, blobGasPerBlob)
blobBalanceUsage.Mul(blobBalanceUsage, call.BlobGasFeeCap) blobBalanceUsage.Mul(blobBalanceUsage, call.BlobGasFeeCap)
if blobBalanceUsage.Cmp(available) >= 0 { if blobBalanceUsage.Cmp(available) >= 0 {
@ -99,13 +99,13 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
} }
available.Sub(available, blobBalanceUsage) available.Sub(available, blobBalanceUsage)
} }
allowance := new(big.Int).Div(available, feeCap) allowance := new(uint256.Int).Div(available, feeCap)
// If the allowance is larger than maximum uint64, skip checking // If the allowance is larger than maximum uint64, skip checking
if allowance.IsUint64() && hi > allowance.Uint64() { if allowance.IsUint64() && hi > allowance.Uint64() {
transfer := call.Value transfer := call.Value
if transfer == nil { if transfer == nil {
transfer = new(big.Int) transfer = new(uint256.Int)
} }
log.Debug("Gas estimation capped by limited funds", "original", hi, "balance", balance, log.Debug("Gas estimation capped by limited funds", "original", hi, "balance", balance,
"sent", transfer, "maxFeePerGas", feeCap, "fundable", allowance) "sent", transfer, "maxFeePerGas", feeCap, "fundable", allowance)

View file

@ -446,27 +446,27 @@ func (args *TransactionArgs) CallDefaults(globalGasCap uint64, baseFee *big.Int,
// Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called. // Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called.
func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck bool) *core.Message { func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck bool) *core.Message {
var ( var (
gasPrice *big.Int gasPrice *uint256.Int
gasFeeCap *big.Int gasFeeCap *uint256.Int
gasTipCap *big.Int gasTipCap *uint256.Int
) )
if baseFee == nil { if baseFee == nil {
gasPrice = args.GasPrice.ToInt() gasPrice, _ = args.GasPrice.ToUint256()
gasFeeCap, gasTipCap = gasPrice, gasPrice gasFeeCap, gasTipCap = gasPrice, gasPrice
} else { } else {
// A basefee is provided, necessitating 1559-type execution // A basefee is provided, necessitating 1559-type execution
if args.GasPrice != nil { if args.GasPrice != nil {
// User specified the legacy gas field, convert to 1559 gas typing // User specified the legacy gas field, convert to 1559 gas typing
gasPrice = args.GasPrice.ToInt() gasPrice, _ = args.GasPrice.ToUint256()
gasFeeCap, gasTipCap = gasPrice, gasPrice gasFeeCap, gasTipCap = gasPrice, gasPrice
} else { } else {
// User specified 1559 gas fields (or none), use those // User specified 1559 gas fields (or none), use those
gasFeeCap = args.MaxFeePerGas.ToInt() gasFeeCap, _ = args.MaxFeePerGas.ToUint256()
gasTipCap = args.MaxPriorityFeePerGas.ToInt() gasTipCap, _ = args.MaxPriorityFeePerGas.ToUint256()
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes // Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
gasPrice = new(big.Int) gasPrice = uint256.NewInt(0)
if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 { if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
gasPrice = gasPrice.Add(gasTipCap, baseFee) gasPrice = gasPrice.Add(gasTipCap, uint256.MustFromBig(baseFee))
if gasPrice.Cmp(gasFeeCap) > 0 { if gasPrice.Cmp(gasFeeCap) > 0 {
gasPrice = gasFeeCap gasPrice = gasFeeCap
} }
@ -477,10 +477,12 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck bool) *c
if args.AccessList != nil { if args.AccessList != nil {
accessList = *args.AccessList accessList = *args.AccessList
} }
value, _ := args.Value.ToUint256()
blobFeeCap, _ := args.BlobFeeCap.ToUint256()
return &core.Message{ return &core.Message{
From: args.from(), From: args.from(),
To: args.To, To: args.To,
Value: (*big.Int)(args.Value), Value: value,
Nonce: uint64(*args.Nonce), Nonce: uint64(*args.Nonce),
GasLimit: uint64(*args.Gas), GasLimit: uint64(*args.Gas),
GasPrice: gasPrice, GasPrice: gasPrice,
@ -488,7 +490,7 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck bool) *c
GasTipCap: gasTipCap, GasTipCap: gasTipCap,
Data: args.data(), Data: args.data(),
AccessList: accessList, AccessList: accessList,
BlobGasFeeCap: (*big.Int)(args.BlobFeeCap), BlobGasFeeCap: blobFeeCap,
BlobHashes: args.BlobHashes, BlobHashes: args.BlobHashes,
SetCodeAuthorizations: args.AuthorizationList, SetCodeAuthorizations: args.AuthorizationList,
SkipNonceChecks: skipNonceCheck, SkipNonceChecks: skipNonceCheck,

View file

@ -35,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/holiman/uint256"
) )
func initMatcher(st *testMatcher) { func initMatcher(st *testMatcher) {
@ -329,7 +328,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
initialGas := vm.NewGasBudget(msg.GasLimit) initialGas := vm.NewGasBudget(msg.GasLimit)
// Execute the message. // Execute the message.
_, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, initialGas.Copy(), uint256.MustFromBig(msg.Value)) _, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, initialGas.Copy(), msg.Value)
if err != nil { if err != nil {
b.Error(err) b.Error(err)
return return

View file

@ -479,15 +479,15 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess
From: from, From: from,
To: to, To: to,
Nonce: tx.Nonce, Nonce: tx.Nonce,
Value: value, Value: uint256.MustFromBig(value),
GasLimit: gasLimit, GasLimit: gasLimit,
GasPrice: gasPrice, GasPrice: uint256.MustFromBig(gasPrice),
GasFeeCap: tx.MaxFeePerGas, GasFeeCap: uint256.MustFromBig(tx.MaxFeePerGas),
GasTipCap: tx.MaxPriorityFeePerGas, GasTipCap: uint256.MustFromBig(tx.MaxPriorityFeePerGas),
Data: data, Data: data,
AccessList: accessList, AccessList: accessList,
BlobHashes: tx.BlobVersionedHashes, BlobHashes: tx.BlobVersionedHashes,
BlobGasFeeCap: tx.BlobGasFeeCap, BlobGasFeeCap: uint256.MustFromBig(tx.BlobGasFeeCap),
SetCodeAuthorizations: authList, SetCodeAuthorizations: authList,
} }
return msg, nil return msg, nil