Thanks for your recommendation. I implemented it now and it seems it works 
like expected (still testing). Please note that I have a bit different use 
case as usual replace by fee style txs. I need to "unlock" inputs which 
were use for a trade MultiSig tx where the other users inputs come from a 
never confirming tx (too low fees). So I just grab my inputs and transfer 
it to a new address I control with a fee higher as the double spent tx.

public void doubleSpendTransaction(Transaction txToDoubleSpend, Address 
newOutputAddress, Runnable resultHandler, ErrorMessageHandler 
errorMessageHandler) throws InsufficientMoneyException {
    final TransactionConfidence.ConfidenceType confidenceType = 
txToDoubleSpend.getConfidence().getConfidenceType();
    if (confidenceType == TransactionConfidence.ConfidenceType.PENDING) {
        Transaction newTransaction = new Transaction(params);
        txToDoubleSpend.getInputs().stream().forEach(input -> {
                    if (input.getConnectedOutput() != null && 
input.getConnectedOutput().isMine(wallet) &&
                            input.getConnectedOutput().getParentTransaction() 
!= null && input.getValue() != null) {
                        newTransaction.addInput(new TransactionInput(params,
                                newTransaction,
                                new byte[]{},
                                new TransactionOutPoint(params, 
input.getOutpoint().getIndex(),
                                        new Transaction(params, 
input.getConnectedOutput().getParentTransaction().bitcoinSerialize())),
                                Coin.valueOf(input.getValue().value)));
                    } else {
                        log.error("Input had null values: " + input.toString());
                    }
                }
        );
        if (!newTransaction.getInputs().isEmpty() && txToDoubleSpend.getFee() 
!= null) {
            // We use a higher fee to be sure we get that tx confirmed
            final Coin newFee = 
txToDoubleSpend.getFee().add(FeePolicy.getFixedTxFeeForTrades());
            
newTransaction.addOutput(txToDoubleSpend.getValueSentFromMe(wallet).subtract(newFee),
 newOutputAddress);

            Wallet.SendRequest sendRequest = 
Wallet.SendRequest.forTx(newTransaction);
            sendRequest.aesKey = aesKey;
            sendRequest.coinSelector = new TradeWalletCoinSelector(params, 
newOutputAddress);
            // We don't expect change but set it just in case
            sendRequest.changeAddress = newOutputAddress;
            sendRequest.feePerKb = newFee;
            Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
            Futures.addCallback(sendResult.broadcastComplete, new 
FutureCallback<Transaction>() {
                @Override
                public void onSuccess(Transaction result) {
                    log.error(result.toString());
                    resultHandler.run();
                }

                @Override
                public void onFailure(@NotNull Throwable t) {
                    errorMessageHandler.handleErrorMessage(t.getMessage());
                }
            });
        } else {
            errorMessageHandler.handleErrorMessage("We could not find inputs we 
control in the transaction we want to double spend.");
        }
    } else if (confidenceType == TransactionConfidence.ConfidenceType.BUILDING) 
{
        errorMessageHandler.handleErrorMessage("That transaction is already in 
the blockchain so we cannot double spend it.");
    } else if (confidenceType == TransactionConfidence.ConfidenceType.DEAD) {
        errorMessageHandler.handleErrorMessage("One of the inputs of that 
transaction has been already double spent.");
    }
}


-- 
You received this message because you are subscribed to the Google Groups 
"bitcoinj" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to bitcoinj+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to