mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-03-13 11:36:15 +01:00
Wallet: move methods sendTransaction()
and waitForConfirmation()
from ForwardingService
`waitForConfirmation()` now has two variants for convenience.
This commit is contained in:
parent
b24964d056
commit
774fde99fb
2 changed files with 51 additions and 56 deletions
|
@ -4276,6 +4276,55 @@ public class Wallet extends BaseTaggableObject
|
|||
return tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate sending the transaction in a {@link SendRequest}. Calls {@link Wallet#sendCoins(SendRequest)} which
|
||||
* performs the following significant operations internally:
|
||||
* <ol>
|
||||
* <li>{@link Wallet#completeTx(SendRequest)} -- calculate change and sign</li>
|
||||
* <li>{@link Wallet#commitTx(Transaction)} -- puts the transaction in the {@code Wallet}'s pending pool</li>
|
||||
* <li>{@link org.bitcoinj.core.TransactionBroadcaster#broadcastTransaction(Transaction)} typically implemented by {@link org.bitcoinj.core.PeerGroup#broadcastTransaction(Transaction)} -- queues requests to send the transaction to a single remote {@code Peer}</li>
|
||||
* </ol>
|
||||
* This method will <i>complete</i> and return a {@link TransactionBroadcast} when the send to the remote peer occurs (is buffered.)
|
||||
* The broadcast process includes the following steps:
|
||||
* <ol>
|
||||
* <li>Wait until enough {@link org.bitcoinj.core.Peer}s are connected.</li>
|
||||
* <li>Broadcast (buffer for send) the transaction to a single remote {@link org.bitcoinj.core.Peer}</li>
|
||||
* <li>Mark {@link TransactionBroadcast#awaitSent()} as complete</li>
|
||||
* <li>Wait for a number of remote peers to confirm they have received the broadcast</li>
|
||||
* <li>Mark {@link TransactionBroadcast#future()} as complete</li>
|
||||
* </ol>
|
||||
* @param sendRequest transaction to send
|
||||
* @return A future for the transaction broadcast
|
||||
*/
|
||||
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();
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for at least 1 confirmation on a transaction.
|
||||
* @param tx the transaction we are waiting for
|
||||
* @return a future for an object that contains transaction confidence information
|
||||
*/
|
||||
public CompletableFuture<TransactionConfidence> waitForConfirmation(Transaction tx) {
|
||||
return waitForConfirmations(tx, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a required number of confirmations on a transaction.
|
||||
* @param tx the transaction we are waiting for
|
||||
* @param requiredConfirmations the minimum required confirmations before completing
|
||||
* @return a future for an object that contains transaction confidence information
|
||||
*/
|
||||
public CompletableFuture<TransactionConfidence> waitForConfirmations(Transaction tx, int requiredConfirmations) {
|
||||
return tx.getConfidence().getDepthFuture(requiredConfirmations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class of exceptions thrown in {@link Wallet#completeTx(SendRequest)}.
|
||||
*/
|
||||
|
|
|
@ -24,11 +24,8 @@ import org.bitcoinj.base.Coin;
|
|||
import org.bitcoinj.base.AddressParser;
|
||||
import org.bitcoinj.core.Context;
|
||||
import org.bitcoinj.base.DefaultAddressParser;
|
||||
import org.bitcoinj.core.InsufficientMoneyException;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionBroadcast;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
import org.bitcoinj.crypto.KeyCrypterException;
|
||||
import org.bitcoinj.kits.WalletAppKit;
|
||||
import org.bitcoinj.utils.BriefLogFormatter;
|
||||
import org.bitcoinj.wallet.CoinSelection;
|
||||
|
@ -40,7 +37,6 @@ import org.bitcoinj.wallet.listeners.WalletCoinsReceivedEventListener;
|
|||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
@ -175,7 +171,7 @@ public class ForwardingService implements Closeable {
|
|||
System.out.printf("Received tx for %s : %s\n", value.toFriendlyString(), incomingTx);
|
||||
System.out.println("Transaction will be forwarded after it confirms.");
|
||||
System.out.println("Waiting for confirmation...");
|
||||
waitForConfirmation(incomingTx)
|
||||
wallet.waitForConfirmations(incomingTx, REQUIRED_CONFIRMATIONS)
|
||||
.thenCompose(confidence -> {
|
||||
// Required confirmations received, now compose a call to broadcast the forwarding transaction
|
||||
System.out.printf("Incoming tx has received %d confirmations.\n", confidence.getDepthInBlocks());
|
||||
|
@ -183,7 +179,7 @@ public class ForwardingService implements Closeable {
|
|||
SendRequest sendRequest = SendRequest.emptyWallet(forwardingAddress);
|
||||
sendRequest.coinSelector = forwardingCoinSelector(incomingTx.getTxId());
|
||||
System.out.printf("Creating outgoing transaction for %s...\n", forwardingAddress);
|
||||
return sendTransaction(sendRequest);
|
||||
return wallet.sendTransaction(sendRequest);
|
||||
})
|
||||
.thenCompose(broadcast -> {
|
||||
System.out.printf("Transaction %s is signed and is being delivered to %s...\n", broadcast.transaction().getTxId(), network);
|
||||
|
@ -194,56 +190,6 @@ public class ForwardingService implements Closeable {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for confirmation on a transaction.
|
||||
* <p>
|
||||
* TODO: Consider changing this so that the returned object contains a reference to the actual transaction rather than just its hash (id)
|
||||
* <p>
|
||||
* TODO: Consider adding this method (or equivalent) to the main bitcoinj API (Wallet or other class)
|
||||
* @param tx the transaction we are waiting for
|
||||
* @return a future for an object that contains transaction confidence information
|
||||
*/
|
||||
CompletableFuture<TransactionConfidence> waitForConfirmation(Transaction tx) {
|
||||
return tx.getConfidence().getDepthFuture(REQUIRED_CONFIRMATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate sending the transaction in a {@link SendRequest}. Calls {@link Wallet#sendCoins(SendRequest)} which
|
||||
* performs the following significant operations internally:
|
||||
* <ol>
|
||||
* <li>{@link Wallet#completeTx(SendRequest)} -- calculate change and sign</li>
|
||||
* <li>{@link Wallet#commitTx(Transaction)} -- puts the transaction in the {@code Wallet}'s pending pool</li>
|
||||
* <li>{@link org.bitcoinj.core.TransactionBroadcaster#broadcastTransaction(Transaction)} typically implemented by {@link org.bitcoinj.core.PeerGroup#broadcastTransaction(Transaction)} -- queues requests to send the transaction to a determined number of {@code Peer}s</li>
|
||||
* </ol>
|
||||
* Note that this method will <i>complete</i> and return a {@link TransactionBroadcast} <i>before</i> the broadcast actually occurs. The broadcast process includes the following steps:
|
||||
* <ol>
|
||||
* <li>Wait until enough {@link org.bitcoinj.core.Peer}s are connected.</li>
|
||||
* <li>Broadcast the transaction by a determined number of {@link org.bitcoinj.core.Peer}s</li>
|
||||
* <li>Wait for confirmation from a determined number of remote peers that they have received the broadcast</li>
|
||||
* <li>Mark {@link TransactionBroadcast#awaitRelayed()} as complete</li>
|
||||
* </ol>
|
||||
* Note: There is a pending PR (#2548) which will make available an additional {@link CompletableFuture} that will complete
|
||||
* after step 3 above. When and if that PR is merged, this method should probably return that future.
|
||||
* <p>
|
||||
* TODO: Check the status of PR #2548
|
||||
* <p>
|
||||
* TODO: Consider adding this method (or equivalent) to the Wallet class
|
||||
* @param sendRequest transaction to send
|
||||
* @return A future for the transaction broadcast
|
||||
*/
|
||||
CompletableFuture<TransactionBroadcast> sendTransaction(SendRequest sendRequest) {
|
||||
CompletableFuture<TransactionBroadcast> future = new CompletableFuture<>();
|
||||
try {
|
||||
// Complete successfully when the transaction is ready to be sent to peers.
|
||||
future.complete(kit.wallet().sendCoins(sendRequest).broadcast);
|
||||
} catch (KeyCrypterException | InsufficientMoneyException e) {
|
||||
// We should never try to send more coins than we have, if we do we get an InsufficientMoneyException
|
||||
// We don't use encrypted wallets in this example - KeyCrypterException can never happen.
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
static String getPrefix(BitcoinNetwork network) {
|
||||
return String.format("forwarding-service-%s", network.toString());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue