mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 10:20:44 +00:00
core/vm: implement EIP-2681: Limit account nonce to 2^64-1 (#23853)
This commit is contained in:
parent
7aeb9bd8f9
commit
6f1d1b6688
4 changed files with 20 additions and 9 deletions
|
|
@ -37,6 +37,10 @@ var (
|
||||||
// next one expected based on the local chain.
|
// next one expected based on the local chain.
|
||||||
ErrNonceTooHigh = errors.New("nonce too high")
|
ErrNonceTooHigh = errors.New("nonce too high")
|
||||||
|
|
||||||
|
// ErrNonceMax is returned if the nonce of a transaction sender account has
|
||||||
|
// maximum allowed value and would become invalid if incremented.
|
||||||
|
ErrNonceMax = errors.New("nonce has max value")
|
||||||
|
|
||||||
ErrNotXDPoS = errors.New("XDPoS not found in config")
|
ErrNotXDPoS = errors.New("XDPoS not found in config")
|
||||||
|
|
||||||
ErrNotFoundM1 = errors.New("list M1 not found ")
|
ErrNotFoundM1 = errors.New("list M1 not found ")
|
||||||
|
|
|
||||||
|
|
@ -197,16 +197,19 @@ func (st *StateTransition) buyGas() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *StateTransition) preCheck() error {
|
func (st *StateTransition) preCheck() error {
|
||||||
msg := st.msg
|
|
||||||
sender := st.from()
|
|
||||||
|
|
||||||
// Make sure this transaction's nonce is correct
|
// Make sure this transaction's nonce is correct
|
||||||
if msg.CheckNonce() {
|
if st.msg.CheckNonce() {
|
||||||
nonce := st.state.GetNonce(sender.Address())
|
// Make sure this transaction's nonce is correct.
|
||||||
if nonce < msg.Nonce() {
|
stNonce := st.state.GetNonce(st.from().Address())
|
||||||
return ErrNonceTooHigh
|
if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
|
||||||
} else if nonce > msg.Nonce() {
|
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
|
||||||
return ErrNonceTooLow
|
st.msg.From().Hex(), msgNonce, stNonce)
|
||||||
|
} else if stNonce > msgNonce {
|
||||||
|
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
|
||||||
|
st.msg.From().Hex(), msgNonce, stNonce)
|
||||||
|
} else if stNonce+1 < stNonce {
|
||||||
|
return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
|
||||||
|
st.msg.From().Hex(), stNonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return st.buyGas()
|
return st.buyGas()
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ var (
|
||||||
ErrWriteProtection = errors.New("write protection")
|
ErrWriteProtection = errors.New("write protection")
|
||||||
ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
|
ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
|
||||||
ErrGasUintOverflow = errors.New("gas uint64 overflow")
|
ErrGasUintOverflow = errors.New("gas uint64 overflow")
|
||||||
|
ErrNonceUintOverflow = errors.New("nonce uint64 overflow")
|
||||||
|
|
||||||
// errStopToken is an internal token indicating interpreter loop termination,
|
// errStopToken is an internal token indicating interpreter loop termination,
|
||||||
// never returned to outside callers.
|
// never returned to outside callers.
|
||||||
|
|
|
||||||
|
|
@ -443,6 +443,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||||
return nil, common.Address{}, gas, ErrInsufficientBalance
|
return nil, common.Address{}, gas, ErrInsufficientBalance
|
||||||
}
|
}
|
||||||
nonce := evm.StateDB.GetNonce(caller.Address())
|
nonce := evm.StateDB.GetNonce(caller.Address())
|
||||||
|
if nonce+1 < nonce {
|
||||||
|
return nil, common.Address{}, gas, ErrNonceUintOverflow
|
||||||
|
}
|
||||||
evm.StateDB.SetNonce(caller.Address(), nonce+1)
|
evm.StateDB.SetNonce(caller.Address(), nonce+1)
|
||||||
// We add this to the access list _before_ taking a snapshot. Even if the creation fails,
|
// We add this to the access list _before_ taking a snapshot. Even if the creation fails,
|
||||||
// the access-list change should not be rolled back
|
// the access-list change should not be rolled back
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue