mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
core: include balance info in insufficient funds error
This commit is contained in:
parent
de686c6cbe
commit
9848cb3e80
1 changed files with 39 additions and 27 deletions
|
|
@ -27,6 +27,7 @@ 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/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
@ -258,33 +259,43 @@ 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)
|
||||||
mgval.Mul(mgval, st.msg.GasPrice)
|
|
||||||
balanceCheck := new(big.Int).Set(mgval)
|
|
||||||
if st.msg.GasFeeCap != nil {
|
if st.msg.GasFeeCap != nil {
|
||||||
balanceCheck.SetUint64(st.msg.GasLimit)
|
mgvalU256, _ := uint256.FromBig(st.msg.GasFeeCap)
|
||||||
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap)
|
mgval.Set(mgvalU256)
|
||||||
}
|
}
|
||||||
balanceCheck.Add(balanceCheck, st.msg.Value)
|
if st.msg.GasPrice != nil {
|
||||||
|
gasPriceU256, _ := uint256.FromBig(st.msg.GasPrice)
|
||||||
if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
|
if mgval.Cmp(gasPriceU256) < 0 {
|
||||||
if blobGas := st.blobGasUsed(); blobGas > 0 {
|
mgval.Set(gasPriceU256)
|
||||||
// Check that the user has enough funds to cover blobGasUsed * tx.BlobGasFeeCap
|
|
||||||
blobBalanceCheck := new(big.Int).SetUint64(blobGas)
|
|
||||||
blobBalanceCheck.Mul(blobBalanceCheck, st.msg.BlobGasFeeCap)
|
|
||||||
balanceCheck.Add(balanceCheck, blobBalanceCheck)
|
|
||||||
// Pay for blobGasUsed * actual blob fee
|
|
||||||
blobFee := new(big.Int).SetUint64(blobGas)
|
|
||||||
blobFee.Mul(blobFee, st.evm.Context.BlobBaseFee)
|
|
||||||
mgval.Add(mgval, blobFee)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
balanceCheckU256, overflow := uint256.FromBig(balanceCheck)
|
mgval.Mul(mgval, new(uint256.Int).SetUint64(st.msg.GasLimit))
|
||||||
if overflow {
|
log.Debug("buyGas: calculating gas cost",
|
||||||
return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex())
|
"gasLimit", st.msg.GasLimit,
|
||||||
}
|
"gasPrice", st.msg.GasPrice,
|
||||||
if have, want := st.state.GetBalance(st.msg.From), balanceCheckU256; have.Cmp(want) < 0 {
|
"gasFeeCap", st.msg.GasFeeCap,
|
||||||
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
|
"mgval", mgval)
|
||||||
|
|
||||||
|
balanceCheckU256 := new(uint256.Int)
|
||||||
|
valueU256, _ := uint256.FromBig(st.msg.Value)
|
||||||
|
balanceCheckU256.Add(mgval, valueU256)
|
||||||
|
log.Debug("buyGas: calculating total cost",
|
||||||
|
"mgval", mgval,
|
||||||
|
"value", st.msg.Value,
|
||||||
|
"total", balanceCheckU256)
|
||||||
|
|
||||||
|
// Check if the sender has enough balance
|
||||||
|
have := st.state.GetBalance(st.msg.From)
|
||||||
|
log.Debug("buyGas: checking balance",
|
||||||
|
"address", st.msg.From.Hex(),
|
||||||
|
"have", have,
|
||||||
|
"want", balanceCheckU256)
|
||||||
|
|
||||||
|
if have.Cmp(balanceCheckU256) < 0 {
|
||||||
|
err := fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have.Uint64(), balanceCheckU256.Uint64())
|
||||||
|
log.Debug("buyGas: insufficient funds error", "error", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
|
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -296,8 +307,8 @@ func (st *stateTransition) buyGas() error {
|
||||||
st.gasRemaining = st.msg.GasLimit
|
st.gasRemaining = st.msg.GasLimit
|
||||||
|
|
||||||
st.initialGas = st.msg.GasLimit
|
st.initialGas = st.msg.GasLimit
|
||||||
mgvalU256, _ := uint256.FromBig(mgval)
|
// No need to convert mgval since it's already uint256.Int
|
||||||
st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy)
|
st.state.SubBalance(st.msg.From, mgval, tracing.BalanceDecreaseGasBuy)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -398,7 +409,7 @@ func (st *stateTransition) preCheck() error {
|
||||||
// execute will transition the state by applying the current message and
|
// execute will transition the state by applying the current message and
|
||||||
// returning the evm execution result with following fields.
|
// returning the evm execution result with following fields.
|
||||||
//
|
//
|
||||||
// - used gas: total gas used (including gas being refunded)
|
// - used gas: total gas used (including gas refunds)
|
||||||
// - returndata: the returned data from evm
|
// - returndata: the returned data from evm
|
||||||
// - concrete execution error: various EVM errors which abort the execution, e.g.
|
// - concrete execution error: various EVM errors which abort the execution, e.g.
|
||||||
// ErrOutOfGas, ErrExecutionReverted
|
// ErrOutOfGas, ErrExecutionReverted
|
||||||
|
|
@ -465,7 +476,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
|
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
|
||||||
}
|
}
|
||||||
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())
|
have := st.state.GetBalance(msg.From)
|
||||||
|
return nil, fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFundsForTransfer, msg.From.Hex(), have.Uint64(), value.Uint64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the init code size has been exceeded.
|
// Check whether the init code size has been exceeded.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue