From 54d7951084aa41474da4c0aab499e9cf05a27ba0 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 10 Mar 2015 12:40:44 -0400 Subject: [PATCH] Process orphans on block acceptance. For every transaction in a newly accepted block, process the orphan pool moving now no longer orphan transactions to the mempool. Previously, no longer orphan transactions would remain in the orphan pool. --- blockmanager.go | 1 + mempool.go | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/blockmanager.go b/blockmanager.go index 7000840f..68d34bc2 100644 --- a/blockmanager.go +++ b/blockmanager.go @@ -1129,6 +1129,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) { b.server.txMemPool.RemoveTransaction(tx) b.server.txMemPool.RemoveDoubleSpends(tx) b.server.txMemPool.RemoveOrphan(tx.Sha()) + b.server.txMemPool.ProcessOrphans(tx.Sha()) } if r := b.server.rpcServer; r != nil { diff --git a/mempool.go b/mempool.go index ce10164b..5c1004fd 100644 --- a/mempool.go +++ b/mempool.go @@ -391,6 +391,7 @@ func calcMinRequiredTxRelayFee(serializedSize int64) int64 { // removeOrphan is the internal function which implements the public // RemoveOrphan. See the comment for RemoveOrphan for more details. +// // This function MUST be called with the mempool lock held (for writes). func (mp *txMemPool) removeOrphan(txHash *wire.ShaHash) { // Nothing to do if passed tx is not an orphan. @@ -424,6 +425,7 @@ func (mp *txMemPool) removeOrphan(txHash *wire.ShaHash) { // RemoveOrphan removes the passed orphan transaction from the orphan pool and // previous orphan index. +// // This function is safe for concurrent access. func (mp *txMemPool) RemoveOrphan(txHash *wire.ShaHash) { mp.Lock() @@ -1261,11 +1263,8 @@ func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo return mp.maybeAcceptTransaction(tx, isNew, rateLimit) } -// processOrphans determines if there are any orphans which depend on the passed -// transaction hash (it is possible that they are no longer orphans) and -// potentially accepts them to the memory pool. It repeats the process for the -// newly accepted transactions (to detect further orphans which may no longer be -// orphans) until there are no more. +// processOrphans is the internal function which implements the public +// ProcessOrphans. See the comment for ProcessOrphans for more details. // // This function MUST be called with the mempool lock held (for writes). func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error { @@ -1350,6 +1349,20 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error { return nil } +// ProcessOrphans determines if there are any orphans which depend on the passed +// transaction hash (it is possible that they are no longer orphans) and +// potentially accepts them to the memory pool. It repeats the process for the +// newly accepted transactions (to detect further orphans which may no longer be +// orphans) until there are no more. +// +// This function is safe for concurrent access. +func (mp *txMemPool) ProcessOrphans(hash *wire.ShaHash) error { + mp.Lock() + defer mp.Unlock() + + return mp.processOrphans(hash) +} + // ProcessTransaction is the main workhorse for handling insertion of new // free-standing transactions into the memory pool. It includes functionality // such as rejecting duplicate transactions, ensuring transactions follow all