3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-07 14:54:15 +00:00

Wallet: Add a Wallet.waitForBalance() method.

This commit is contained in:
Mike Hearn 2013-05-02 16:51:29 +02:00
parent dddf02d6a1
commit e8f1418865
2 changed files with 49 additions and 0 deletions

View File

@ -19,6 +19,7 @@ package com.google.bitcoin.core;
import com.google.bitcoin.crypto.KeyCrypterScrypt;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.SettableFuture;
import org.bitcoinj.wallet.Protos.Wallet.EncryptionType;
import org.spongycastle.crypto.params.KeyParameter;
@ -2807,6 +2808,45 @@ public class Wallet implements Serializable, BlockChainListener {
setCoinSelector(Wallet.AllowUnconfirmedCoinSelector.get());
}
/**
* Returns a future that will complete when the balance of the given type is equal or larger to the given value.
* If the wallet already has a large enough balance the future is returned in a pre-completed state. Note that this
* method is not blocking, if you want to <i>actually</i> wait immediately, you have to call .get() on the result.
*/
public ListenableFuture<BigInteger> waitForBalance(final BigInteger value, final BalanceType type) {
final SettableFuture<BigInteger> future = SettableFuture.create();
final BigInteger current = getBalance(type);
if (current.compareTo(value) >= 0) {
// Already have enough.
future.set(current);
return future;
}
addEventListener(new AbstractWalletEventListener() {
private boolean done = false;
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
check();
}
private void check() {
final BigInteger newBalance = getBalance(type);
if (!done && newBalance.compareTo(value) >= 0) {
// Have enough now.
done = true;
removeEventListener(this);
future.set(newBalance);
}
}
@Override
public void onCoinsReceived(Wallet w, Transaction t, BigInteger b1, BigInteger b2) {
check();
}
});
return future;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Boilerplate for running event listeners - unlocks the wallet, runs, re-locks.

View File

@ -22,6 +22,7 @@ import com.google.bitcoin.crypto.KeyCrypter;
import com.google.bitcoin.crypto.KeyCrypterException;
import com.google.bitcoin.crypto.KeyCrypterScrypt;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.protobuf.ByteString;
import org.bitcoinj.wallet.Protos;
@ -175,9 +176,15 @@ public class WalletTest extends TestWithWallet {
private void receiveAPendingTransaction(Wallet wallet, Address toAddress) throws Exception {
BigInteger v1 = Utils.toNanoCoins(1, 0);
final ListenableFuture<BigInteger> availFuture = wallet.waitForBalance(v1, Wallet.BalanceType.AVAILABLE);
final ListenableFuture<BigInteger> estimatedFuture = wallet.waitForBalance(v1, Wallet.BalanceType.ESTIMATED);
assertFalse(availFuture.isDone());
assertFalse(estimatedFuture.isDone());
Transaction t1 = sendMoneyToWallet(wallet, v1, toAddress, null);
assertEquals(BigInteger.ZERO, wallet.getBalance());
assertEquals(v1, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
assertFalse(availFuture.isDone());
assertTrue(estimatedFuture.isDone());
assertEquals(1, wallet.getPoolSize(Pool.PENDING));
assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
sendMoneyToWallet(wallet, t1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
@ -185,6 +192,8 @@ public class WalletTest extends TestWithWallet {
assertEquals("Incorrect confirmed tx PENDING pool size", 0, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
assertEquals("Incorrect confirmed tx UNSPENT pool size", 1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
assertEquals("Incorrect confirmed tx ALL pool size", 1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
assertTrue(availFuture.isDone());
assertTrue(estimatedFuture.isDone());
}
private void basicSanityChecks(Wallet wallet, Transaction t, Address fromAddress, Address destination) throws ScriptException {