From 3b436402e0c260c6d54df7c1bd1c5a12d453d3f6 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Thu, 19 Jun 2014 11:39:43 -0500 Subject: [PATCH] Search unconfirmed txs when finding prev credits. If a transaction is added that debits from previous transaction outputs, and those outputs are still unconfirmed, it is possible that if the credits were not already known (as is the case with transactions notified after a sendrawtransaction), only mined unspent transaction outputs would be searched and the unconfirmed unspent credits would be missed. This results in spent outputs still being marked unspent. This change fixes the above by also searching through unconfirmed transactions when the previous credits must be lookup up, rather than being pass from an AddDebits call. Fixes issue #91. --- txstore/tx.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/txstore/tx.go b/txstore/tx.go index 5c547bf..3f9c0eb 100644 --- a/txstore/tx.go +++ b/txstore/tx.go @@ -639,7 +639,26 @@ func (s *Store) findPreviousCredits(tx *btcutil.Tx) ([]Credit, error) { go func(i int, op btcwire.OutPoint) { key, ok := s.unspent[op] if !ok { - close(creditChans[i]) + // Does this input spend an unconfirmed output? + r, ok := s.unconfirmed.txs[op.Hash] + switch { + // Not an unconfirmed tx. + case !ok: + fallthrough + // Output isn't a credit. + case len(r.credits) <= int(op.Index): + fallthrough + // Output isn't a credit. + case r.credits[op.Index] == nil: + fallthrough + // Credit already spent. + case s.unconfirmed.spentUnconfirmed[op] != nil: + close(creditChans[i]) + return + } + t := &TxRecord{BlockTxKey{BlockHeight: -1}, r, s} + c := Credit{t, op.Index} + creditChans[i] <- createdCredit{credit: c} return } r, err := s.lookupBlockTx(key)