mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-16 04:56:36 +00:00
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:
parent
2f11dccca0
commit
e1047b9c84
8 changed files with 142 additions and 87 deletions
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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: ¶ms.BeaconRootsAddress,
|
To: ¶ms.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: ¶ms.HistoryStorageAddress,
|
To: ¶ms.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))
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue