Program: 85681
Project: 85681
Buggy source:
/** 
 * <p>Updates the wallet by checking if this TX spends any of our outputs, and marking them as spent if so. If fromChain is true, also checks to see if any pending transaction spends outputs of this transaction and marks the spent flags appropriately.</p> <p>It can be called in two contexts. One is when we receive a transaction on the best chain but it wasn't pending, this most commonly happens when we have a set of keys but the wallet transactions were wiped and we are catching up with the block chain. It can also happen if a block includes a transaction we never saw at broadcast time. If this tx double spends, it takes precedence over our pending transactions and the pending tx goes dead.</p> <p>The other context it can be called is from   {@link Wallet#receivePending(Transaction,java.util.List)}, ie we saw a tx be broadcast or one was submitted directly that spends our own coins. If this tx double spends it does NOT take precedence because the winner will be resolved by the miners - we assume that our version will win, if we are wrong then when a block appears the tx will go dead.</p>
 * @param tx The transaction which is being updated.
 * @param fromChain If true, the tx appeared on the current best chain, if false it was pending.
 */
private void updateForSpends(Transaction tx,boolean fromChain) throws VerificationException {
  checkState(lock.isHeldByCurrentThread());
  if (fromChain)   checkState(!pending.containsKey(tx.getHash()));
  for (  TransactionInput input : tx.getInputs()) {
    TransactionInput.ConnectionResult result=input.connect(unspent,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
    if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
      result=input.connect(spent,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
      if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
        result=input.connect(pending,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
        if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
          continue;
        }
      }
    }
    if (result == TransactionInput.ConnectionResult.ALREADY_SPENT) {
      if (fromChain) {
        log.warn("String_Node_Str");
      }
 else {
        log.warn("String_Node_Str");
        log.warn("String_Node_Str",tx.getInputs().indexOf(input));
        log.warn("String_Node_Str",tx.getHash(),Utils.HEX.encode(tx.unsafeBitcoinSerialize()));
        Transaction other=input.getConnectedOutput().getSpentBy().getParentTransaction();
        log.warn("String_Node_Str",other.getHash(),Utils.HEX.encode(tx.unsafeBitcoinSerialize()));
      }
    }
 else     if (result == TransactionInput.ConnectionResult.SUCCESS) {
      Transaction connected=checkNotNull(input.getOutpoint().fromTx);
      log.info("String_Node_Str",input.getOutpoint());
      maybeMovePool(connected,"String_Node_Str");
    }
  }
  if (fromChain) {
    for (    Transaction pendingTx : pending.values()) {
      for (      TransactionInput input : pendingTx.getInputs()) {
        TransactionInput.ConnectionResult result=input.connect(tx,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
        checkState(result != TransactionInput.ConnectionResult.ALREADY_SPENT);
        if (result == TransactionInput.ConnectionResult.SUCCESS) {
          log.info("String_Node_Str",pendingTx.getHashAsString(),pendingTx.getInputs().indexOf(input));
        }
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * <p>Updates the wallet by checking if this TX spends any of our outputs, and marking them as spent if so. If fromChain is true, also checks to see if any pending transaction spends outputs of this transaction and marks the spent flags appropriately.</p> <p>It can be called in two contexts. One is when we receive a transaction on the best chain but it wasn't pending, this most commonly happens when we have a set of keys but the wallet transactions were wiped and we are catching up with the block chain. It can also happen if a block includes a transaction we never saw at broadcast time. If this tx double spends, it takes precedence over our pending transactions and the pending tx goes dead.</p> <p>The other context it can be called is from   {@link Wallet#receivePending(Transaction,java.util.List)}, ie we saw a tx be broadcast or one was submitted directly that spends our own coins. If this tx double spends it does NOT take precedence because the winner will be resolved by the miners - we assume that our version will win, if we are wrong then when a block appears the tx will go dead.</p>
 * @param tx The transaction which is being updated.
 * @param fromChain If true, the tx appeared on the current best chain, if false it was pending.
 */
private void updateForSpends(Transaction tx,boolean fromChain) throws VerificationException {
  checkState(lock.isHeldByCurrentThread());
  if (fromChain)   checkState(!pending.containsKey(tx.getHash()));
  for (  TransactionInput input : tx.getInputs()) {
    TransactionInput.ConnectionResult result=input.connect(unspent,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
    if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
      result=input.connect(spent,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
      if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
        result=input.connect(pending,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
        if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
          continue;
        }
      }
    }
    if (result == TransactionInput.ConnectionResult.ALREADY_SPENT) {
      if (fromChain) {
      }
 else {
        log.warn("String_Node_Str");
        log.warn("String_Node_Str",tx.getInputs().indexOf(input));
        log.warn("String_Node_Str",tx.getHash(),Utils.HEX.encode(tx.unsafeBitcoinSerialize()));
        Transaction other=input.getConnectedOutput().getSpentBy().getParentTransaction();
        log.warn("String_Node_Str",other.getHash(),Utils.HEX.encode(tx.unsafeBitcoinSerialize()));
      }
    }
 else     if (result == TransactionInput.ConnectionResult.SUCCESS) {
      Transaction connected=checkNotNull(input.getOutpoint().fromTx);
      log.info("String_Node_Str",input.getOutpoint());
      maybeMovePool(connected,"String_Node_Str");
    }
  }
  if (fromChain) {
    for (    Transaction pendingTx : pending.values()) {
      for (      TransactionInput input : pendingTx.getInputs()) {
        TransactionInput.ConnectionResult result=input.connect(tx,TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
        checkState(result != TransactionInput.ConnectionResult.ALREADY_SPENT);
        if (result == TransactionInput.ConnectionResult.SUCCESS) {
          log.info("String_Node_Str",pendingTx.getHashAsString(),pendingTx.getInputs().indexOf(input));
        }
      }
    }
  }
}