diff --git a/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java b/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java
index 472917e12..17ccc87f5 100644
--- a/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java
+++ b/core/src/main/java/org/bitcoinj/core/TransactionBroadcast.java
@@ -46,15 +46,17 @@ 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)
- private final CompletableFuture sentFuture = new CompletableFuture<>();
+ protected final CompletableFuture sentFuture = new CompletableFuture<>();
// This future completes when we have verified that more than numWaitingFor Peers have seen the broadcast
- private final CompletableFuture seenFuture = new CompletableFuture<>();
+ protected final CompletableFuture seenFuture = new CompletableFuture<>();
private final PeerGroup peerGroup;
private final Transaction tx;
private int minConnections;
@@ -84,28 +86,40 @@ public class TransactionBroadcast {
return tx;
}
- @VisibleForTesting
- public static TransactionBroadcast createMockBroadcast(Transaction tx, final CompletableFuture future) {
- return new TransactionBroadcast(tx) {
- @Override
- public CompletableFuture broadcast() {
- return future;
- }
-
- @Override
- public CompletableFuture future() {
- return future;
- }
- };
+ /**
+ * @deprecated If you are using {@link Wallet.SendResult} switch to {@link TransactionBroadcast}
+ */
+ @Override
+ public TransactionBroadcast getBroadcast() {
+ return this;
}
- /**
- * @return future that completes when some number of remote peers has rebroadcast the transaction
- * @deprecated Use {@link #awaitRelayed()} (and maybe {@link CompletableFuture#thenApply(Function)})
- */
- @Deprecated
- public CompletableFuture future() {
- return awaitRelayed().thenApply(TransactionBroadcast::transaction);
+ @VisibleForTesting
+ public static TransactionBroadcast createMockBroadcast(Transaction tx, final CompletableFuture future) {
+ return new MockTransactionBroadcast(tx, future);
+ }
+
+ static class MockTransactionBroadcast extends TransactionBroadcast {
+ private final CompletableFuture future;
+
+ MockTransactionBroadcast(Transaction tx, final CompletableFuture future) {
+ super(tx);
+ this.future = future;
+ }
+
+ @Override
+ public CompletableFuture broadcastOnly() {
+ future.whenComplete((transaction, ex) -> {
+ if (transaction != null) {
+ this.sentFuture.complete(this);
+ this.seenFuture.complete(this);
+ } else {
+ this.sentFuture.completeExceptionally(ex);
+ this.seenFuture.completeExceptionally(ex);
+ }
+ });
+ return sentFuture;
+ }
}
public void setMinConnections(int minConnections) {
@@ -234,21 +248,6 @@ public class TransactionBroadcast {
return sentFuture;
}
- /**
- * If you migrate to {@link #broadcastAndAwaitRelay()} and need a {@link CompletableFuture} that returns
- * {@link Transaction} you can use:
- * {@code
- * CompletableFuture seenFuture = broadcast
- * .broadcastAndAwaitRelay()
- * .thenApply(TransactionBroadcast::transaction);
- * }
- * @deprecated Use {@link #broadcastAndAwaitRelay()} or {@link #broadcastOnly()} as appropriate
- */
- @Deprecated
- public CompletableFuture broadcast() {
- return broadcastAndAwaitRelay().thenApply(TransactionBroadcast::transaction);
- }
-
private CompletableFuture broadcastOne(Peer peer) {
try {
CompletableFuture future = peer.sendMessage(tx);
diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java
index 0b706831d..8586cd6d9 100644
--- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java
+++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java
@@ -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 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 awaitRelayed() {
- return broadcast.awaitRelayed();
- }
+ CompletableFuture 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 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