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:
parent
5016675d40
commit
d765c73a41
1 changed files with 22 additions and 25 deletions
47
mempool.go
47
mempool.go
|
@ -823,7 +823,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
missingParents = append(missingParents, txD.Hash)
|
missingParents = append(missingParents, txD.Hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(missingParents) != 0 {
|
if len(missingParents) > 0 {
|
||||||
return missingParents, nil
|
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.
|
// ProcessOrphans. See the comment for ProcessOrphans for more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// 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.
|
// Start with processing at least the passed hash.
|
||||||
processHashes := list.New()
|
processHashes := list.New()
|
||||||
processHashes.PushBack(hash)
|
processHashes.PushBack(hash)
|
||||||
|
@ -1041,23 +1041,26 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error {
|
||||||
missingParents, err := mp.maybeAcceptTransaction(tx,
|
missingParents, err := mp.maybeAcceptTransaction(tx,
|
||||||
true, true)
|
true, true)
|
||||||
if err != nil {
|
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 {
|
if len(missingParents) > 0 {
|
||||||
// Generate and relay the inventory vector for the
|
// Transaction is still an orphan, so add it
|
||||||
// newly accepted transaction.
|
// back.
|
||||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Sha())
|
mp.addOrphan(tx)
|
||||||
mp.server.RelayInventory(iv, tx)
|
continue
|
||||||
} 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// Add this transaction to the list of transactions to
|
||||||
// process so any orphans that depend on this one are
|
// process so any orphans that depend on this one are
|
||||||
// handled too.
|
// handled too.
|
||||||
|
@ -1074,8 +1077,6 @@ func (mp *txMemPool) processOrphans(hash *wire.ShaHash) error {
|
||||||
processHashes.PushBack(orphanHash)
|
processHashes.PushBack(orphanHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessOrphans determines if there are any orphans which depend on the passed
|
// 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.
|
// orphans) until there are no more.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) ProcessOrphans(hash *wire.ShaHash) error {
|
func (mp *txMemPool) ProcessOrphans(hash *wire.ShaHash) {
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
mp.processOrphans(hash)
|
||||||
|
mp.Unlock()
|
||||||
return mp.processOrphans(hash)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessTransaction is the main workhorse for handling insertion of new
|
// 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
|
// transaction (they may no longer be orphans if all inputs
|
||||||
// are now available) and repeat for those accepted
|
// are now available) and repeat for those accepted
|
||||||
// transactions until there are no more.
|
// transactions until there are no more.
|
||||||
err := mp.processOrphans(tx.Sha())
|
mp.processOrphans(tx.Sha())
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// The transaction is an orphan (has inputs missing). Reject
|
// The transaction is an orphan (has inputs missing). Reject
|
||||||
// it if the flag to allow orphans is not set.
|
// it if the flag to allow orphans is not set.
|
||||||
|
|
Loading…
Add table
Reference in a new issue