Commit b4a52513 authored by Péter Szilágyi's avatar Péter Szilágyi

core: abstract out a sorted transaction hash map

parent a183ea29
This diff is collapsed.
......@@ -41,18 +41,12 @@ func TestStrictTxListAdd(t *testing.T) {
list.Add(txs[v])
}
// Verify internal state
if list.first != 0 {
t.Errorf("lowest nonce mismatch: have %d, want %d", list.first, 0)
}
if int(list.last) != len(txs)-1 {
t.Errorf("highest nonce mismatch: have %d, want %d", list.last, len(txs)-1)
}
if len(list.items) != len(txs) {
t.Errorf("transaction count mismatch: have %d, want %d", len(list.items), len(txs))
if len(list.txs.items) != len(txs) {
t.Errorf("transaction count mismatch: have %d, want %d", len(list.txs.items), len(txs))
}
for i, tx := range txs {
if list.items[tx.Nonce()] != tx {
t.Errorf("item %d: transaction mismatch: have %v, want %v", i, list.items[tx.Nonce()], tx)
if list.txs.items[tx.Nonce()] != tx {
t.Errorf("item %d: transaction mismatch: have %v, want %v", i, list.txs.items[tx.Nonce()], tx)
}
}
}
......@@ -154,7 +154,8 @@ func (pool *TxPool) resetState() {
// Update all accounts to the latest known pending nonce
for addr, list := range pool.pending {
pool.pendingState.SetNonce(addr, list.last+1)
txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1)
}
// Check the queue and move transactions over to the pending if possible
// or remove those that have become invalid
......@@ -366,7 +367,7 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T
// Set the potentially new pending nonce and notify any subsystems of the new tx
pool.beats[addr] = time.Now()
pool.pendingState.SetNonce(addr, list.last+1)
pool.pendingState.SetNonce(addr, tx.Nonce()+1)
go pool.eventMux.Post(TxPreEvent{tx})
}
......@@ -439,19 +440,20 @@ func (pool *TxPool) removeTx(hash common.Hash) {
// Remove the transaction from the pending lists and reset the account nonce
if pending := pool.pending[addr]; pending != nil {
if removed, invalids := pending.Remove(tx); removed {
// If no more transactions are left, remove the list and reset the nonce
// If no more transactions are left, remove the list
if pending.Empty() {
delete(pool.pending, addr)
delete(pool.beats, addr)
pool.pendingState.SetNonce(addr, tx.Nonce())
} else {
// Otherwise update the nonce and postpone any invalidated transactions
pool.pendingState.SetNonce(addr, pending.last)
// Otherwise postpone any invalidated transactions
for _, tx := range invalids {
pool.enqueueTx(tx.Hash(), tx)
}
}
// Update the account nonce if needed
if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
pool.pendingState.SetNonce(addr, tx.Nonce())
}
}
}
// Transaction is in the future queue
......
......@@ -105,7 +105,7 @@ func TestTransactionQueue(t *testing.T) {
currentState.SetNonce(from, 2)
pool.enqueueTx(tx.Hash(), tx)
pool.promoteExecutables()
if _, ok := pool.pending[from].items[tx.Nonce()]; ok {
if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok {
t.Error("expected transaction to be in tx pool")
}
......@@ -224,7 +224,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
if pool.pending[addr].Len() != 1 {
t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
}
if tx := pool.pending[addr].items[0]; tx.Hash() != tx2.Hash() {
if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
}
// Add the thid transaction and ensure it's not saved (smaller price)
......@@ -235,7 +235,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
if pool.pending[addr].Len() != 1 {
t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
}
if tx := pool.pending[addr].items[0]; tx.Hash() != tx2.Hash() {
if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
}
// Ensure the total transaction count is correct
......@@ -346,16 +346,16 @@ func TestTransactionDropping(t *testing.T) {
state.AddBalance(account, big.NewInt(-750))
pool.resetState()
if _, ok := pool.pending[account].items[tx0.Nonce()]; !ok {
if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
t.Errorf("funded pending transaction missing: %v", tx0)
}
if _, ok := pool.pending[account].items[tx1.Nonce()]; ok {
if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok {
t.Errorf("out-of-fund pending transaction present: %v", tx1)
}
if _, ok := pool.queue[account].items[tx10.Nonce()]; !ok {
if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
t.Errorf("funded queued transaction missing: %v", tx10)
}
if _, ok := pool.queue[account].items[tx11.Nonce()]; ok {
if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok {
t.Errorf("out-of-fund queued transaction present: %v", tx11)
}
if len(pool.all) != 2 {
......@@ -410,25 +410,25 @@ func TestTransactionPostponing(t *testing.T) {
state.AddBalance(account, big.NewInt(-750))
pool.resetState()
if _, ok := pool.pending[account].items[txns[0].Nonce()]; !ok {
if _, ok := pool.pending[account].txs.items[txns[0].Nonce()]; !ok {
t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txns[0])
}
if _, ok := pool.queue[account].items[txns[0].Nonce()]; ok {
if _, ok := pool.queue[account].txs.items[txns[0].Nonce()]; ok {
t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txns[0])
}
for i, tx := range txns[1:] {
if i%2 == 1 {
if _, ok := pool.pending[account].items[tx.Nonce()]; ok {
if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
}
if _, ok := pool.queue[account].items[tx.Nonce()]; !ok {
if _, ok := pool.queue[account].txs.items[tx.Nonce()]; !ok {
t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
}
} else {
if _, ok := pool.pending[account].items[tx.Nonce()]; ok {
if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
}
if _, ok := pool.queue[account].items[tx.Nonce()]; ok {
if _, ok := pool.queue[account].txs.items[tx.Nonce()]; ok {
t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
}
}
......
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