Commit b60a2762 authored by Jeffrey Wilcke's avatar Jeffrey Wilcke

core: transaction nonce recovery fix

When the transaction state recovery kicked in it assigned the last
(incorrect) nonce to the pending state which caused transactions with
the same nonce to occur.

Added test for nonce recovery
parent 985b5f29
...@@ -121,8 +121,8 @@ func (pool *TxPool) resetState() { ...@@ -121,8 +121,8 @@ func (pool *TxPool) resetState() {
if addr, err := tx.From(); err == nil { if addr, err := tx.From(); err == nil {
// Set the nonce. Transaction nonce can never be lower // Set the nonce. Transaction nonce can never be lower
// than the state nonce; validatePool took care of that. // than the state nonce; validatePool took care of that.
if pool.pendingState.GetNonce(addr) < tx.Nonce() { if pool.pendingState.GetNonce(addr) <= tx.Nonce() {
pool.pendingState.SetNonce(addr, tx.Nonce()) pool.pendingState.SetNonce(addr, tx.Nonce()+1)
} }
} }
} }
......
...@@ -219,3 +219,22 @@ func TestMissingNonce(t *testing.T) { ...@@ -219,3 +219,22 @@ func TestMissingNonce(t *testing.T) {
t.Error("expected 1 queued transaction, got", len(pool.queue[addr])) 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)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment