From 048c46309b937c2d08c65cc43139b22593692ed9 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Tue, 18 Feb 2025 13:49:19 -0800 Subject: [PATCH 1/2] Wallet.SendResult: remove deprecations --- .../main/java/org/bitcoinj/wallet/Wallet.java | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java index 4304e95b2..a165730e6 100644 --- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java +++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java @@ -3968,37 +3968,13 @@ public class Wallet extends BaseTaggableObject /** 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()} - */ - @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 broadcastComplete; /** * The broadcast object returned by the linked TransactionBroadcaster - * @deprecated Use {@link #getBroadcast()} */ - @Deprecated - public final TransactionBroadcast broadcast; - - /** - * @deprecated Use {@link #SendResult(TransactionBroadcast)} - */ - @Deprecated - public SendResult(Transaction tx, TransactionBroadcast broadcast) { - this(broadcast); - } + private final TransactionBroadcast broadcast; public SendResult(TransactionBroadcast broadcast) { - this.tx = broadcast.transaction(); this.broadcast = broadcast; - this.broadcastComplete = broadcast.awaitRelayed().thenApply(TransactionBroadcast::transaction); } public Transaction transaction() { From 230cd71bc7f745c268518901dd96f13d9b2f31f0 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Tue, 18 Feb 2025 14:43:59 -0800 Subject: [PATCH 2/2] Wallet: deprecate SendResult * Make SendResult an interface * TransactionBroadcast temporarily implements SendResult * Remove all other uses of SendResult Any clients declaring instances of Wallet.SendResult must convert to TransactionBroadcast before SendResult is removed. --- .../bitcoinj/core/TransactionBroadcast.java | 12 +++++- .../main/java/org/bitcoinj/wallet/Wallet.java | 40 +++++++------------ .../org/bitcoinj/examples/SendRequest.java | 3 +- .../core/TransactionBroadcastTest.java | 4 +- .../wallettemplate/SendMoneyController.java | 3 +- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java b/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java index d0024350b..0d3984335 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java @@ -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. + *

+ * 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 future) { return new TransactionBroadcast(tx) { diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java index a165730e6..27b47399b 100644 --- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java +++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java @@ -3966,28 +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 broadcast object returned by the linked TransactionBroadcaster - */ - private final TransactionBroadcast broadcast; + /** + * A SendResult is returned to you as part of sending coins to a recipient. + * @deprecated Use {@link TransactionBroadcast} + */ + @Deprecated + public interface SendResult { + Transaction transaction(); - public SendResult(TransactionBroadcast broadcast) { - this.broadcast = broadcast; - } + @Deprecated + TransactionBroadcast getBroadcast(); - public Transaction transaction() { - return broadcast.transaction(); - } - - public TransactionBroadcast getBroadcast() { - return broadcast; - } - - public CompletableFuture awaitRelayed() { - return broadcast.awaitRelayed(); - } + CompletableFuture awaitRelayed(); } /** @@ -4141,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); @@ -4169,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. @@ -4178,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 @@ -4202,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, () -> @@ -4255,7 +4245,7 @@ public class Wallet extends BaseTaggableObject public CompletableFuture 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); diff --git a/examples/src/main/java/org/bitcoinj/examples/SendRequest.java b/examples/src/main/java/org/bitcoinj/examples/SendRequest.java index 3b642b1b8..02b84fc12 100644 --- a/examples/src/main/java/org/bitcoinj/examples/SendRequest.java +++ b/examples/src/main/java/org/bitcoinj/examples/SendRequest.java @@ -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) { diff --git a/integration-test/src/test/java/org/bitcoinj/core/TransactionBroadcastTest.java b/integration-test/src/test/java/org/bitcoinj/core/TransactionBroadcastTest.java index 4ce63e8a6..981f4d3a8 100644 --- a/integration-test/src/test/java/org/bitcoinj/core/TransactionBroadcastTest.java +++ b/integration-test/src/test/java/org/bitcoinj/core/TransactionBroadcastTest.java @@ -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()); diff --git a/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java b/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java index 1e0a09112..f0829ecaf 100644 --- a/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java +++ b/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java @@ -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> overlayUI; - private Wallet.SendResult sendResult; + private TransactionBroadcast sendResult; private AesKey aesKey; @Override