Program: 85666
Project: 85666
Buggy source:
/** 
 * Given a spend request containing an incomplete transaction, makes it valid by adding outputs and signed inputs according to the instructions in the request. The transaction in the request is modified by this method.
 * @param req a SendRequest that contains the incomplete transaction and details for how to make it valid.
 * @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
 * @throws IllegalArgumentException if you try and complete the same SendRequest twice
 * @throws DustySendRequested if the resultant transaction would violate the dust rules (an output that's too small to be worthwhile)
 * @throws CouldNotAdjustDownwards if emptying the wallet was requested and the output can't be shrunk for fees without violating a protocol rule.
 * @throws ExceededMaxTransactionSize if the resultant transaction is too big for Bitcoin to process (try breaking up the amounts of value)
 */
public void completeTx(SendRequest req) throws InsufficientMoneyException {
  lock.lock();
  try {
    checkArgument(!req.completed,"String_Node_Str");
    Coin value=Coin.ZERO;
    for (    TransactionOutput output : req.tx.getOutputs()) {
      value=value.add(output.getValue());
    }
    log.info("String_Node_Str",req.tx.getOutputs().size(),value.toFriendlyString());
    Coin totalInput=Coin.ZERO;
    for (    TransactionInput input : req.tx.getInputs())     if (input.getConnectedOutput() != null)     totalInput=totalInput.add(input.getConnectedOutput().getValue());
 else     log.warn("String_Node_Str");
    value=value.subtract(totalInput);
    List<TransactionInput> originalInputs=new ArrayList<TransactionInput>(req.tx.getInputs());
    boolean needAtLeastReferenceFee=false;
    if (req.ensureMinRequiredFee && !req.emptyWallet) {
      for (      TransactionOutput output : req.tx.getOutputs())       if (output.getValue().compareTo(Coin.CENT) < 0) {
        if (output.getValue().compareTo(output.getMinNonDustValue()) < 0)         throw new DustySendRequested();
        needAtLeastReferenceFee=true;
        break;
      }
    }
    LinkedList<TransactionOutput> candidates=calculateAllSpendCandidates(true);
    CoinSelection bestCoinSelection;
    TransactionOutput bestChangeOutput=null;
    if (!req.emptyWallet) {
      FeeCalculation feeCalculation;
      feeCalculation=calculateFee(req,value,originalInputs,needAtLeastReferenceFee,candidates);
      bestCoinSelection=feeCalculation.bestCoinSelection;
      bestChangeOutput=feeCalculation.bestChangeOutput;
    }
 else {
      checkState(req.tx.getOutputs().size() == 1,"String_Node_Str");
      CoinSelector selector=req.coinSelector == null ? coinSelector : req.coinSelector;
      bestCoinSelection=selector.select(NetworkParameters.MAX_MONEY,candidates);
      candidates=null;
      req.tx.getOutput(0).setValue(bestCoinSelection.valueGathered);
      log.info("String_Node_Str",bestCoinSelection.valueGathered.toFriendlyString());
    }
    for (    TransactionOutput output : bestCoinSelection.gathered)     req.tx.addInput(output);
    if (req.ensureMinRequiredFee && req.emptyWallet) {
      final Coin baseFee=req.fee == null ? Coin.ZERO : req.fee;
      final Coin feePerKb=req.feePerKb == null ? Coin.ZERO : req.feePerKb;
      Transaction tx=req.tx;
      if (!adjustOutputDownwardsForFee(tx,bestCoinSelection,baseFee,feePerKb))       throw new CouldNotAdjustDownwards();
    }
    if (bestChangeOutput != null) {
      req.tx.addOutput(bestChangeOutput);
      log.info("String_Node_Str",bestChangeOutput.getValue().toFriendlyString());
    }
    if (req.shuffleOutputs)     req.tx.shuffleOutputs();
    if (req.signInputs) {
      signTransaction(req);
    }
    int size=req.tx.bitcoinSerialize().length;
    if (size > Transaction.MAX_STANDARD_TX_SIZE)     throw new ExceededMaxTransactionSize();
    final Coin calculatedFee=req.tx.getFee();
    if (calculatedFee != null) {
      log.info("String_Node_Str",calculatedFee.toFriendlyString());
    }
    req.tx.getConfidence().setSource(TransactionConfidence.Source.SELF);
    req.tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
    req.tx.setExchangeRate(req.exchangeRate);
    req.tx.setMemo(req.memo);
    req.completed=true;
    req.fee=calculatedFee;
    log.info("String_Node_Str",req.tx);
  }
  finally {
    lock.unlock();
  }
}

Fixed version (ground truth):
/** 
 * Given a spend request containing an incomplete transaction, makes it valid by adding outputs and signed inputs according to the instructions in the request. The transaction in the request is modified by this method.
 * @param req a SendRequest that contains the incomplete transaction and details for how to make it valid.
 * @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
 * @throws IllegalArgumentException if you try and complete the same SendRequest twice
 * @throws DustySendRequested if the resultant transaction would violate the dust rules (an output that's too small to be worthwhile)
 * @throws CouldNotAdjustDownwards if emptying the wallet was requested and the output can't be shrunk for fees without violating a protocol rule.
 * @throws ExceededMaxTransactionSize if the resultant transaction is too big for Bitcoin to process (try breaking up the amounts of value)
 */
public void completeTx(SendRequest req) throws InsufficientMoneyException {
  lock.lock();
  try {
    checkArgument(!req.completed,"String_Node_Str");
    Coin value=Coin.ZERO;
    for (    TransactionOutput output : req.tx.getOutputs()) {
      value=value.add(output.getValue());
    }
    log.info("String_Node_Str",req.tx.getOutputs().size(),value.toFriendlyString());
    Coin totalInput=Coin.ZERO;
    for (    TransactionInput input : req.tx.getInputs())     if (input.getConnectedOutput() != null)     totalInput=totalInput.add(input.getConnectedOutput().getValue());
 else     log.warn("String_Node_Str");
    value=value.subtract(totalInput);
    List<TransactionInput> originalInputs=new ArrayList<TransactionInput>(req.tx.getInputs());
    int opReturnCount=0;
    boolean needAtLeastReferenceFee=false;
    if (req.ensureMinRequiredFee && !req.emptyWallet) {
      for (      TransactionOutput output : req.tx.getOutputs()) {
        if (output.getValue().compareTo(Coin.CENT) < 0) {
          needAtLeastReferenceFee=true;
          if (output.getValue().compareTo(output.getMinNonDustValue()) < 0) {
            if (output.getScriptPubKey().isOpReturn()) {
              ++opReturnCount;
              continue;
            }
 else {
              throw new DustySendRequested();
            }
          }
          break;
        }
      }
    }
    if (opReturnCount > 1) {
      throw new MultipleOpReturnRequested();
    }
    LinkedList<TransactionOutput> candidates=calculateAllSpendCandidates(true);
    CoinSelection bestCoinSelection;
    TransactionOutput bestChangeOutput=null;
    if (!req.emptyWallet) {
      FeeCalculation feeCalculation;
      feeCalculation=calculateFee(req,value,originalInputs,needAtLeastReferenceFee,candidates);
      bestCoinSelection=feeCalculation.bestCoinSelection;
      bestChangeOutput=feeCalculation.bestChangeOutput;
    }
 else {
      checkState(req.tx.getOutputs().size() == 1,"String_Node_Str");
      CoinSelector selector=req.coinSelector == null ? coinSelector : req.coinSelector;
      bestCoinSelection=selector.select(NetworkParameters.MAX_MONEY,candidates);
      candidates=null;
      req.tx.getOutput(0).setValue(bestCoinSelection.valueGathered);
      log.info("String_Node_Str",bestCoinSelection.valueGathered.toFriendlyString());
    }
    for (    TransactionOutput output : bestCoinSelection.gathered)     req.tx.addInput(output);
    if (req.ensureMinRequiredFee && req.emptyWallet) {
      final Coin baseFee=req.fee == null ? Coin.ZERO : req.fee;
      final Coin feePerKb=req.feePerKb == null ? Coin.ZERO : req.feePerKb;
      Transaction tx=req.tx;
      if (!adjustOutputDownwardsForFee(tx,bestCoinSelection,baseFee,feePerKb))       throw new CouldNotAdjustDownwards();
    }
    if (bestChangeOutput != null) {
      req.tx.addOutput(bestChangeOutput);
      log.info("String_Node_Str",bestChangeOutput.getValue().toFriendlyString());
    }
    if (req.shuffleOutputs)     req.tx.shuffleOutputs();
    if (req.signInputs) {
      signTransaction(req);
    }
    int size=req.tx.bitcoinSerialize().length;
    if (size > Transaction.MAX_STANDARD_TX_SIZE)     throw new ExceededMaxTransactionSize();
    final Coin calculatedFee=req.tx.getFee();
    if (calculatedFee != null) {
      log.info("String_Node_Str",calculatedFee.toFriendlyString());
    }
    req.tx.getConfidence().setSource(TransactionConfidence.Source.SELF);
    req.tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
    req.tx.setExchangeRate(req.exchangeRate);
    req.tx.setMemo(req.memo);
    req.completed=true;
    req.fee=calculatedFee;
    log.info("String_Node_Str",req.tx);
  }
  finally {
    lock.unlock();
  }
}