From 176e6e5e85fdf20334669a826a696811c3ef1d5c Mon Sep 17 00:00:00 2001 From: villanuevawill Date: Thu, 2 Jul 2020 11:25:41 -0500 Subject: [PATCH 1/2] Transactions are removed/re-validated properly for aa --- core/tx_pool.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/core/tx_pool.go b/core/tx_pool.go index 17904ee2da09..3f6bf394ecab 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1270,6 +1270,15 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { pool.pendingNonces = newTxNoncer(statedb) pool.currentMaxGas = newHead.GasLimit + // re-validate aa transactions for accounts where a transaction was included + if oldHead != nil && oldHead.Hash() == newHead.ParentHash { + includedTransactions := pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64()).Transactions() + pool.validateAAExecutables(includedTransactions) + } + + // for AA we need to re-validate accounts that were included after forking + pool.validateAAExecutables(included) + // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) senderCacher.recover(pool.signer, reinject) @@ -1280,6 +1289,32 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { pool.istanbul = pool.chainconfig.IsIstanbul(next) } +// This re-validates accounts which have been touched in a recent block +func (pool *TxPool) validateAAExecutables(txs []*types.Transaction) { + for _, tx := range txs { + var account = tx.To() + if account != nil && tx.IsAA() { + if pool.Has(tx.Hash()) { + pool.removeTx(tx.Hash(), true) + } else { + if pending := pool.pending[*account]; pending != nil { + pending_tx := pending.txs.Flatten()[0] + pool.removeTx(pending_tx.Hash(), true) + // ignore locals for now + pool.add(pending_tx, false) + } + + if queued := pool.queue[*account]; queued != nil { + queued_tx := queued.txs.Flatten()[0] + pool.removeTx(queued_tx.Hash(), true) + // ignore locals for now + pool.add(queued_tx, false) + } + } + } + } +} + // promoteExecutables moves transactions that have become processable from the // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. From 63210149c1a9ee5b121cbfb9a5748c5bcfea5b20 Mon Sep 17 00:00:00 2001 From: villanuevawill Date: Thu, 2 Jul 2020 12:00:32 -0500 Subject: [PATCH 2/2] Split into elif in order to deal with pending or queue --- core/tx_pool.go | 50 ++++++++++--------------------------------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/core/tx_pool.go b/core/tx_pool.go index 3f6bf394ecab..aed6e9f3b7b5 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1231,32 +1231,6 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { } } - // for AA we need to re-validate accounts that were included - // split into separate function - // This introduces some basic race conditions, so this needs to be refactored - for _, tx := range included { - var account = tx.To() - if account != nil && tx.IsAA() { - if pool.Has(tx.Hash()) { - pool.removeTx(tx.Hash(), true) - } else { - if pending := pool.pending[*account]; pending != nil { - pending_tx := pending.txs.Flatten()[0] - pool.removeTx(pending_tx.Hash(), true) - // ignore locals for now - pool.add(pending_tx, false) - } - - if queued := pool.queue[*account]; queued != nil { - queued_tx := queued.txs.Flatten()[0] - pool.removeTx(queued_tx.Hash(), true) - // ignore locals for now - pool.add(queued_tx, false) - } - } - } - } - // Initialize the internal state to the current head if newHead == nil { newHead = pool.chain.CurrentBlock().Header() // Special case during testing @@ -1296,20 +1270,16 @@ func (pool *TxPool) validateAAExecutables(txs []*types.Transaction) { if account != nil && tx.IsAA() { if pool.Has(tx.Hash()) { pool.removeTx(tx.Hash(), true) - } else { - if pending := pool.pending[*account]; pending != nil { - pending_tx := pending.txs.Flatten()[0] - pool.removeTx(pending_tx.Hash(), true) - // ignore locals for now - pool.add(pending_tx, false) - } - - if queued := pool.queue[*account]; queued != nil { - queued_tx := queued.txs.Flatten()[0] - pool.removeTx(queued_tx.Hash(), true) - // ignore locals for now - pool.add(queued_tx, false) - } + } else if pending := pool.pending[*account]; pending != nil { + pending_tx := pending.txs.Flatten()[0] + pool.removeTx(pending_tx.Hash(), true) + // ignore locals for now + pool.add(pending_tx, false) + } else if queued := pool.queue[*account]; queued != nil { + queued_tx := queued.txs.Flatten()[0] + pool.removeTx(queued_tx.Hash(), true) + // ignore locals for now + pool.add(queued_tx, false) } } }