mempool: Remove returned error from ProcessOrphans

ProcessTransaction could have accepted a new transaction into mempool
but could have returned a reject message if a no-longer-orphan
transaction failed to be accepted.  This would also skip any
additional no-longer-orphans, keeping them in the orphan pool.

Instead of returning an error incorrectly, log the error and skip
the no-longer-orphan transaction.  This allows the rest of the
no-longer-orphans to be processed as well.
This commit is contained in:
David Hill 2015-11-10 17:04:16 -05:00
parent 5016675d40
commit d765c73a41

View file

@ -823,7 +823,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
missingParents = append(missingParents, txD.Hash)
}
}
if len(missingParents) != 0 {
if len(missingParents) > 0 {
return missingParents, nil
}
@ -996,7 +996,7 @@ func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
// 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 {
func (mp *txMemPool) processOrphans(hash *wire.ShaHash) {
// Start with processing at least the passed hash.
processHashes := list.New()
processHashes.PushBack(hash)
@ -1041,23 +1041,26 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error {
missingParents, err := mp.maybeAcceptTransaction(tx,
true, true)
if err != nil {
return err
// TODO: Remove orphans that depend on this
// failed transaction.
txmpLog.Debugf("Unable to move "+
"orphan transaction %v to mempool: %v",
tx.Sha(), err)
continue
}
if len(missingParents) == 0 {
// Generate and relay the inventory vector for the
// newly accepted transaction.
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
mp.server.RelayInventory(iv, tx)
} else {
// Transaction is still an orphan.
// TODO(jrick): This removeOrphan call is
// likely unnecessary as it was unconditionally
// removed above and maybeAcceptTransaction won't
// add it back.
mp.removeOrphan(orphanHash)
if len(missingParents) > 0 {
// Transaction is still an orphan, so add it
// back.
mp.addOrphan(tx)
continue
}
// Generate and relay the inventory vector for the
// newly accepted transaction.
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
mp.server.RelayInventory(iv, tx)
// Add this transaction to the list of transactions to
// process so any orphans that depend on this one are
// handled too.
@ -1074,8 +1077,6 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error {
processHashes.PushBack(orphanHash)
}
}
return nil
}
// ProcessOrphans determines if there are any orphans which depend on the passed
@ -1085,11 +1086,10 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error {
// orphans) until there are no more.
//
// This function is safe for concurrent access.
func (mp *txMemPool) ProcessOrphans(hash *wire.ShaHash) error {
func (mp *txMemPool) ProcessOrphans(hash *wire.ShaHash) {
mp.Lock()
defer mp.Unlock()
return mp.processOrphans(hash)
mp.processOrphans(hash)
mp.Unlock()
}
// ProcessTransaction is the main workhorse for handling insertion of new
@ -1120,10 +1120,7 @@ func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit b
// transaction (they may no longer be orphans if all inputs
// are now available) and repeat for those accepted
// transactions until there are no more.
err := mp.processOrphans(tx.Sha())
if err != nil {
return err
}
mp.processOrphans(tx.Sha())
} else {
// The transaction is an orphan (has inputs missing). Reject
// it if the flag to allow orphans is not set.