This commit is contained in:
Sean Gilligan 2025-03-11 12:21:09 -05:00 committed by GitHub
commit 4d01f80ccc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 32 additions and 54 deletions

View file

@ -46,8 +46,10 @@ import static org.bitcoinj.base.internal.Preconditions.checkState;
* defined as seeing the transaction be announced by peers via inv messages, thus indicating their acceptance. A failure
* is defined as not reaching acceptance within a timeout period, or getting an explicit reject message from a peer
* indicating that the transaction was not acceptable.
* <p>
* This class temporarily implements {@link Wallet.SendResult} to allow migration away from that deprecated interface.
*/
public class TransactionBroadcast {
public class TransactionBroadcast implements Wallet.SendResult {
private static final Logger log = LoggerFactory.getLogger(TransactionBroadcast.class);
// This future completes when all broadcast messages were sent (to a buffer)
@ -84,6 +86,14 @@ public class TransactionBroadcast {
return tx;
}
/**
* @deprecated If you are using {@link Wallet.SendResult} switch to {@link TransactionBroadcast}
*/
@Override
public TransactionBroadcast getBroadcast() {
return this;
}
@VisibleForTesting
public static TransactionBroadcast createMockBroadcast(Transaction tx, final CompletableFuture<Transaction> future) {
return new TransactionBroadcast(tx) {

View file

@ -3966,52 +3966,18 @@ public class Wallet extends BaseTaggableObject
//region Creating and sending transactions
/** A SendResult is returned to you as part of sending coins to a recipient. */
public static class SendResult {
/**
* The Bitcoin transaction message that moves the money.
* @deprecated Use {@link #transaction()}
*/
/**
* A SendResult is returned to you as part of sending coins to a recipient.
* @deprecated Use {@link TransactionBroadcast}
*/
@Deprecated
public interface SendResult {
Transaction transaction();
@Deprecated
public final Transaction tx;
/**
* A future that will complete once the tx message has been successfully broadcast to the network. This is just the result of calling broadcast.future()
* @deprecated Use {@link #awaitRelayed()}
*/
@Deprecated
public final CompletableFuture<Transaction> broadcastComplete;
/**
* The broadcast object returned by the linked TransactionBroadcaster
* @deprecated Use {@link #getBroadcast()}
*/
@Deprecated
public final TransactionBroadcast broadcast;
TransactionBroadcast getBroadcast();
/**
* @deprecated Use {@link #SendResult(TransactionBroadcast)}
*/
@Deprecated
public SendResult(Transaction tx, TransactionBroadcast broadcast) {
this(broadcast);
}
public SendResult(TransactionBroadcast broadcast) {
this.tx = broadcast.transaction();
this.broadcast = broadcast;
this.broadcastComplete = broadcast.awaitRelayed().thenApply(TransactionBroadcast::transaction);
}
public Transaction transaction() {
return broadcast.transaction();
}
public TransactionBroadcast getBroadcast() {
return broadcast;
}
public CompletableFuture<TransactionBroadcast> awaitRelayed() {
return broadcast.awaitRelayed();
}
CompletableFuture<TransactionBroadcast> awaitRelayed();
}
/**
@ -4165,7 +4131,7 @@ public class Wallet extends BaseTaggableObject
* @throws MultipleOpReturnRequested if there is more than one OP_RETURN output for the resultant transaction.
* @throws BadWalletEncryptionKeyException if the supplied {@link SendRequest#aesKey} is wrong.
*/
public SendResult sendCoins(TransactionBroadcaster broadcaster, Address to, Coin value)
public TransactionBroadcast sendCoins(TransactionBroadcaster broadcaster, Address to, Coin value)
throws InsufficientMoneyException, TransactionCompletionException {
SendRequest request = SendRequest.to(to, value);
return sendCoins(broadcaster, request);
@ -4193,7 +4159,7 @@ public class Wallet extends BaseTaggableObject
* @throws MultipleOpReturnRequested if there is more than one OP_RETURN output for the resultant transaction.
* @throws BadWalletEncryptionKeyException if the supplied {@link SendRequest#aesKey} is wrong.
*/
public SendResult sendCoins(TransactionBroadcaster broadcaster, SendRequest request)
public TransactionBroadcast sendCoins(TransactionBroadcaster broadcaster, SendRequest request)
throws InsufficientMoneyException, TransactionCompletionException {
// Should not be locked here, as we're going to call into the broadcaster and that might want to hold its
// own lock. sendCoinsOffline handles everything that needs to be locked.
@ -4202,7 +4168,7 @@ public class Wallet extends BaseTaggableObject
// Commit the TX to the wallet immediately so the spent coins won't be reused.
// TODO: We should probably allow the request to specify tx commit only after the network has accepted it.
Transaction tx = sendCoinsOffline(request);
SendResult result = new SendResult(broadcaster.broadcastTransaction(tx));
TransactionBroadcast result = broadcaster.broadcastTransaction(tx);
// The tx has been committed to the pending pool by this point (via sendCoinsOffline -> commitTx), so it has
// a txConfidenceListener registered. Once the tx is broadcast the peers will update the memory pool with the
// count of seen peers, the memory pool will update the transaction confidence object, that will invoke the
@ -4226,7 +4192,7 @@ public class Wallet extends BaseTaggableObject
* @throws MultipleOpReturnRequested if there is more than one OP_RETURN output for the resultant transaction.
* @throws BadWalletEncryptionKeyException if the supplied {@link SendRequest#aesKey} is wrong.
*/
public SendResult sendCoins(SendRequest request)
public TransactionBroadcast sendCoins(SendRequest request)
throws InsufficientMoneyException, TransactionCompletionException {
TransactionBroadcaster broadcaster = vTransactionBroadcaster;
checkState(broadcaster != null, () ->
@ -4279,7 +4245,7 @@ public class Wallet extends BaseTaggableObject
public CompletableFuture<TransactionBroadcast> sendTransaction(SendRequest sendRequest) {
try {
// Complete successfully when the transaction has been sent (or buffered, at least) to peers.
return sendCoins(sendRequest).broadcast.awaitSent();
return sendCoins(sendRequest).awaitSent();
} catch (KeyCrypterException | InsufficientMoneyException e) {
// We should never try to send more coins than we have, if we do we get an InsufficientMoneyException
return FutureUtils.failedFuture(e);

View file

@ -20,6 +20,7 @@ import org.bitcoinj.base.Address;
import org.bitcoinj.base.BitcoinNetwork;
import org.bitcoinj.base.Coin;
import org.bitcoinj.core.InsufficientMoneyException;
import org.bitcoinj.core.TransactionBroadcast;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.wallet.Wallet;
import org.bitcoinj.wallet.Wallet.BalanceType;
@ -54,7 +55,7 @@ public class SendRequest {
// When using the testnet you can use a faucet to get testnet coins.
// In this example we catch the InsufficientMoneyException and register a BalanceFuture callback that runs once the wallet has enough balance.
try {
Wallet.SendResult result = kit.wallet().sendCoins(kit.peerGroup(), to, value);
TransactionBroadcast result = kit.wallet().sendCoins(kit.peerGroup(), to, value);
System.out.println("coins sent. transaction hash: " + result.transaction().getTxId());
// you can use a block explorer like https://www.biteasy.com/ to inspect the transaction with the printed transaction hash.
} catch (InsufficientMoneyException e) {

View file

@ -171,7 +171,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
// Now create a spend, and expect the announcement on p1.
Address dest = new ECKey().toAddress(ScriptType.P2PKH, BitcoinNetwork.TESTNET);
Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, dest, COIN);
TransactionBroadcast sendResult = wallet.sendCoins(peerGroup, dest, COIN);
assertFalse(sendResult.awaitRelayed().isDone());
Transaction t1;
{
@ -215,7 +215,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
// Now create a spend, and expect the announcement on p1.
Address dest = new ECKey().toAddress(ScriptType.P2PKH, BitcoinNetwork.TESTNET);
Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, dest, COIN);
TransactionBroadcast sendResult = wallet.sendCoins(peerGroup, dest, COIN);
assertNotNull(sendResult.transaction());
Threading.waitForUserCode();
assertFalse(sendResult.awaitRelayed().isDone());

View file

@ -25,6 +25,7 @@ import javafx.scene.layout.HBox;
import org.bitcoinj.base.Address;
import org.bitcoinj.base.Coin;
import org.bitcoinj.core.InsufficientMoneyException;
import org.bitcoinj.core.TransactionBroadcast;
import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.crypto.AesKey;
import org.bitcoinj.crypto.ECKey;
@ -54,7 +55,7 @@ public class SendMoneyController implements OverlayController<SendMoneyControlle
private OverlayableStackPaneController rootController;
private OverlayableStackPaneController.OverlayUI<? extends OverlayController<SendMoneyController>> overlayUI;
private Wallet.SendResult sendResult;
private TransactionBroadcast sendResult;
private AesKey aesKey;
@Override