Skip to content

Commit

Permalink
Introduce ErrNonceUintOverflow as error for nonce overflow (#1905)
Browse files Browse the repository at this point in the history
* new error for nonce overflow

* added unit test for `IncrNonce`

* lint fix

* Fix description for chain-id flag

* bug fix

* fix

---------

Co-authored-by: Stefan Negovanović <stefan@ethernal.tech>
  • Loading branch information
dusannosovic-ethernal and Stefan-Ethernal authored Sep 14, 2023
1 parent dcfc044 commit f2b24e7
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 5 deletions.
2 changes: 1 addition & 1 deletion command/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func setFlags(cmd *cobra.Command) {
&params.chainID,
chainIDFlag,
command.DefaultChainID,
"the ID of the chain (only used for IBFT consensus)",
"the ID of the chain",
)

cmd.Flags().StringVar(
Expand Down
16 changes: 13 additions & 3 deletions state/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,9 @@ var (
// ErrFeeCapTooLow is returned if the transaction fee cap is less than the
// the base fee of the block.
ErrFeeCapTooLow = errors.New("max fee per gas less than block base fee")

// ErrNonceUintOverflow is returned if uint64 overflow happens
ErrNonceUintOverflow = errors.New("nonce uint64 overflow")
)

type TransitionApplicationError struct {
Expand Down Expand Up @@ -581,7 +584,9 @@ func (t *Transition) apply(msg *types.Transaction) (*runtime.ExecutionResult, er
if msg.IsContractCreation() {
result = t.Create2(msg.From, msg.Input, value, gasLeft)
} else {
t.state.IncrNonce(msg.From)
if err := t.state.IncrNonce(msg.From); err != nil {
return nil, err
}
result = t.Call2(msg.From, *msg.To, msg.Input, value, gasLeft)
}

Expand Down Expand Up @@ -782,7 +787,9 @@ func (t *Transition) applyCreate(c *runtime.Contract, host runtime.Host) *runtim
}

// Increment the nonce of the caller
t.state.IncrNonce(c.Caller)
if err := t.state.IncrNonce(c.Caller); err != nil {
return &runtime.ExecutionResult{Err: err}
}

// Check if there is a collision and the address already exists
if t.hasCodeOrNonce(c.Address) {
Expand All @@ -798,7 +805,10 @@ func (t *Transition) applyCreate(c *runtime.Contract, host runtime.Host) *runtim
if t.config.EIP158 {
// Force the creation of the account
t.state.CreateAccount(c.Address)
t.state.IncrNonce(c.Address)

if err := t.state.IncrNonce(c.Address); err != nil {
return &runtime.ExecutionResult{Err: err}
}
}

// Transfer the value
Expand Down
11 changes: 10 additions & 1 deletion state/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,19 @@ func (txn *Txn) GetState(addr types.Address, key types.Hash) types.Hash {
// Nonce

// IncrNonce increases the nonce of the address
func (txn *Txn) IncrNonce(addr types.Address) {
func (txn *Txn) IncrNonce(addr types.Address) error {
var err error

txn.upsertAccount(addr, true, func(object *StateObject) {
if object.Account.Nonce+1 < object.Account.Nonce {
err = ErrNonceUintOverflow

return
}
object.Account.Nonce++
})

return err
}

// SetNonce reduces the balance
Expand Down
22 changes: 22 additions & 0 deletions state/txn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package state

import (
"fmt"
"math"
"math/big"
"testing"

"github.com/0xPolygon/polygon-edge/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type mockSnapshot struct {
Expand Down Expand Up @@ -70,3 +72,23 @@ func TestSnapshotUpdateData(t *testing.T) {
assert.NoError(t, txn.RevertToSnapshot(ss))
assert.Equal(t, hash1, txn.GetState(addr1, hash1))
}

func TestIncrNonce(t *testing.T) {
t.Parallel()

var (
address0 = types.StringToAddress("0")
address1 = types.StringToAddress("1")
maxUint64NonceValue = uint64(math.MaxUint64)
nonMaxUint64NonceValue = uint64(3)
)

txn := newTestTxn(defaultPreState)

txn.SetNonce(address0, maxUint64NonceValue)
txn.SetNonce(address1, nonMaxUint64NonceValue)

require.Error(t, txn.IncrNonce(address0))
require.NoError(t, txn.IncrNonce(address1))
require.Equal(t, nonMaxUint64NonceValue+1, txn.GetNonce(address1))
}

0 comments on commit f2b24e7

Please sign in to comment.