diff --git a/core/src/main/java/com/google/bitcoin/core/AbstractBlockChain.java b/core/src/main/java/com/google/bitcoin/core/AbstractBlockChain.java index 1f2553aa5..2f8de7d52 100644 --- a/core/src/main/java/com/google/bitcoin/core/AbstractBlockChain.java +++ b/core/src/main/java/com/google/bitcoin/core/AbstractBlockChain.java @@ -20,6 +20,8 @@ import com.google.bitcoin.store.BlockStore; import com.google.bitcoin.store.BlockStoreException; import com.google.bitcoin.utils.Locks; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -873,4 +875,22 @@ public abstract class AbstractBlockChain { return new Date(estimated); } } + + /** + * Returns a future that completes when the block chain has reached the given height. Yields the + * {@link StoredBlock} of the block that reaches that height first. The future completes on a peer thread. + */ + public ListenableFuture getHeightFuture(final int height) { + final SettableFuture result = SettableFuture.create(); + addListener(new AbstractBlockChainListener() { + @Override + public void notifyNewBestBlock(StoredBlock block) throws VerificationException { + if (block.getHeight() >= height) { + removeListener(this); + result.set(block); + } + } + }); + return result; + } } diff --git a/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java b/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java index 28a7f4675..0a62df710 100644 --- a/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java +++ b/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java @@ -20,6 +20,7 @@ import com.google.bitcoin.core.Wallet.BalanceType; import com.google.bitcoin.store.BlockStore; import com.google.bitcoin.store.MemoryBlockStore; import com.google.bitcoin.utils.BriefLogFormatter; +import com.google.common.util.concurrent.ListenableFuture; import org.junit.Before; import org.junit.Test; @@ -74,10 +75,12 @@ public class BlockChainTest { @Test public void testBasicChaining() throws Exception { - // Check that we can plug a few blocks together. + // Check that we can plug a few blocks together and the futures work. + ListenableFuture future = testNetChain.getHeightFuture(2); // Block 1 from the testnet. Block b1 = getBlock1(); assertTrue(testNetChain.add(b1)); + assertFalse(future.isDone()); // Block 2 from the testnet. Block b2 = getBlock2(); @@ -93,6 +96,8 @@ public class BlockChainTest { // Now it works because we reset the nonce. assertTrue(testNetChain.add(b2)); + assertTrue(future.isDone()); + assertEquals(2, future.get().getHeight()); } @Test