Program: 30959
Project: 30959
Buggy source:
/** 
 * Runs completeContract to get a feeless contract, then attaches an extra input of size MIN_FEE, potentially creating and broadcasting a tx to create an output of the right size first (as we cannot add change outputs to an assurance contract). The returned future completes once both dependency and contract are broadcast OK.
 */
public CompletionProgress completeContractWithFee(Project project,Set<LHProtos.Pledge> pledges,@Nullable KeyParameter aesKey) throws InsufficientMoneyException {
  final Coin feeSize=Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(2);
  log.info("String_Node_Str");
  CompletionProgress progress=new CompletionProgress();
  TransactionConfidence.Listener broadcastListener=new TransactionConfidence.Listener(){
    private Set<PeerAddress> addrs=new HashSet<>();
    @Override public void onConfidenceChanged(    TransactionConfidence conf,    ChangeReason reason){
      if (reason == TransactionConfidence.Listener.ChangeReason.SEEN_PEERS) {
        addrs.addAll(Sets.newHashSet(conf.getBroadcastBy()));
        progress.setPeersSeen(addrs.size());
      }
 else       if (reason == ChangeReason.TYPE) {
        progress.setPeersSeen(-1);
      }
    }
  }
;
  Transaction contract=project.completeContract(pledges);
  Wallet.SendRequest request=Wallet.SendRequest.to(freshReceiveKey().toAddress(params),feeSize);
  request.aesKey=aesKey;
  Wallet.SendResult result=sendCoins(vTransactionBroadcaster,request);
  ListenableFuture<Transaction> future=Futures.transform(result.broadcastComplete,(AsyncFunction<Transaction,Transaction>)tx -> {
    log.info("String_Node_Str");
    TransactionOutput feeOut=tx.getOutputs().stream().filter(output -> output.getValue().equals(feeSize)).findAny().get();
    contract.addInput(feeOut);
    SendRequest req=SendRequest.forTx(contract);
    req.aesKey=aesKey;
    signTransaction(req);
    log.info("String_Node_Str",contract);
    contract.getConfidence().addEventListener(broadcastListener);
    return vTransactionBroadcaster.broadcastTransaction(contract);
  }
);
  result.tx.getConfidence().addEventListener(broadcastListener);
  progress.txFuture=convertFuture(future);
  return progress;
}

Fixed version (ground truth):
/** 
 * Runs completeContract to get a feeless contract, then attaches an extra input of size MIN_FEE, potentially creating and broadcasting a tx to create an output of the right size first (as we cannot add change outputs to an assurance contract). The returned future completes once both dependency and contract are broadcast OK.
 */
public void completeContractWithFee(Project project,Set<LHProtos.Pledge> pledges,@Nullable KeyParameter aesKey,TransactionBroadcast.ProgressCallback progress,Consumer<Throwable> error,Executor callbackExecutor) throws InsufficientMoneyException {
  final Coin feeSize=Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(2);
  log.info("String_Node_Str");
  Transaction contract=project.completeContract(pledges);
  Wallet.SendRequest request=Wallet.SendRequest.to(freshReceiveKey().toAddress(params),feeSize);
  request.aesKey=aesKey;
  Wallet.SendResult result=sendCoins(vTransactionBroadcaster,request);
  TransactionBroadcast.ProgressCallback mergingCallback=new TransactionBroadcast.ProgressCallback(){
    double total, last;
    @Override public void onBroadcastProgress(    double val){
      if (val < last)       last=0.0;
      total+=val - last;
      last=val;
      progress.onBroadcastProgress(total / 2.0);
    }
  }
;
  result.broadcast.setProgressCallback(mergingCallback,callbackExecutor);
  Futures.addCallback(result.broadcastComplete,new FutureCallback<Transaction>(){
    @Override public void onSuccess(    @Nullable Transaction tx){
      log.info("String_Node_Str");
      TransactionOutput feeOut=tx.getOutputs().stream().filter(output -> output.getValue().equals(feeSize)).findAny().get();
      contract.addInput(feeOut);
      SendRequest req=SendRequest.forTx(contract);
      req.aesKey=aesKey;
      signTransaction(req);
      log.info("String_Node_Str",contract);
      TransactionBroadcast broadcast=vTransactionBroadcaster.broadcastTransaction(contract);
      broadcast.setProgressCallback(mergingCallback,callbackExecutor);
      Futures.addCallback(broadcast.future(),new FutureCallback<Transaction>(){
        @Override public void onSuccess(        @Nullable Transaction result){
          log.info("String_Node_Str");
        }
        @Override public void onFailure(        Throwable t){
          log.error("String_Node_Str",t);
          error.accept(t);
        }
      }
,callbackExecutor);
    }
    @Override public void onFailure(    Throwable t){
      log.error("String_Node_Str",t);
      callbackExecutor.execute(() -> error.accept(t));
    }
  }
);
}