Skip to content

Commit

Permalink
core/vm: implement EIP-2681: Limit account nonce to 2^64-1 (ethereum#…
Browse files Browse the repository at this point in the history
  • Loading branch information
gzliudan committed Aug 25, 2024
1 parent d773520 commit 3a4dd01
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
4 changes: 4 additions & 0 deletions core/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ var (
// next one expected based on the local chain.
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")

ErrNotFoundM1 = errors.New("list M1 not found ")
Expand Down
21 changes: 12 additions & 9 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,19 @@ func (st *StateTransition) buyGas() error {
}

func (st *StateTransition) preCheck() error {
msg := st.msg
sender := st.from()

// Make sure this transaction's nonce is correct
if msg.CheckNonce() {
nonce := st.state.GetNonce(sender.Address())
if nonce < msg.Nonce() {
return ErrNonceTooHigh
} else if nonce > msg.Nonce() {
return ErrNonceTooLow
if st.msg.CheckNonce() {
// Make sure this transaction's nonce is correct.
stNonce := st.state.GetNonce(st.from().Address())
if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
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()
Expand Down
1 change: 1 addition & 0 deletions core/vm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
ErrWriteProtection = errors.New("write protection")
ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
ErrGasUintOverflow = errors.New("gas uint64 overflow")
ErrNonceUintOverflow = errors.New("nonce uint64 overflow")

// errStopToken is an internal token indicating interpreter loop termination,
// never returned to outside callers.
Expand Down
3 changes: 3 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
return nil, common.Address{}, gas, ErrInsufficientBalance
}
nonce := evm.StateDB.GetNonce(caller.Address())
if nonce+1 < nonce {
return nil, common.Address{}, gas, ErrNonceUintOverflow
}
evm.StateDB.SetNonce(caller.Address(), nonce+1)
// 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
Expand Down

0 comments on commit 3a4dd01

Please sign in to comment.