aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-09-19 06:56:10 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-09-19 06:56:10 +0800
commitb94b9b0158ed2549eb025aad3da63c3cf2015a51 (patch)
treec1fb4ecc636d71a3346253cd7e89fb434d0d9ba1
parent216c486a3aef2c4e7b4c1dc37b14d321ce912723 (diff)
parentb60a27627b32dd0e76269732b834ece1fe7d5c3a (diff)
downloadgo-tangerine-b94b9b0158ed2549eb025aad3da63c3cf2015a51.tar.gz
go-tangerine-b94b9b0158ed2549eb025aad3da63c3cf2015a51.tar.zst
go-tangerine-b94b9b0158ed2549eb025aad3da63c3cf2015a51.zip
Merge pull request #1817 from obscuren/nonce-fix
core: transaction nonce recovery
-rw-r--r--core/transaction_pool.go4
-rw-r--r--core/transaction_pool_test.go19
2 files changed, 21 insertions, 2 deletions
diff --git a/core/transaction_pool.go b/core/transaction_pool.go
index 42e26b3b3..513600be3 100644
--- a/core/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -121,8 +121,8 @@ func (pool *TxPool) resetState() {
if addr, err := tx.From(); err == nil {
// Set the nonce. Transaction nonce can never be lower
// than the state nonce; validatePool took care of that.
- if pool.pendingState.GetNonce(addr) < tx.Nonce() {
- pool.pendingState.SetNonce(addr, tx.Nonce())
+ if pool.pendingState.GetNonce(addr) <= tx.Nonce() {
+ pool.pendingState.SetNonce(addr, tx.Nonce()+1)
}
}
}
diff --git a/core/transaction_pool_test.go b/core/transaction_pool_test.go
index 7d0984740..d9267cc43 100644
--- a/core/transaction_pool_test.go
+++ b/core/transaction_pool_test.go
@@ -219,3 +219,22 @@ func TestMissingNonce(t *testing.T) {
t.Error("expected 1 queued transaction, got", len(pool.queue[addr]))
}
}
+
+func TestNonceRecovery(t *testing.T) {
+ const n = 10
+ pool, key := setupTxPool()
+ addr := crypto.PubkeyToAddress(key.PublicKey)
+ pool.currentState().SetNonce(addr, n)
+ pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
+ pool.resetState()
+ tx := transaction(n, big.NewInt(100000), key)
+ if err := pool.Add(tx); err != nil {
+ t.Error(err)
+ }
+ // simulate some weird re-order of transactions and missing nonce(s)
+ pool.currentState().SetNonce(addr, n-1)
+ pool.resetState()
+ if fn := pool.pendingState.GetNonce(addr); fn != n+1 {
+ t.Errorf("expected nonce to be %d, got %d", n+1, fn)
+ }
+}