@Test public void testRetrieveAddressHistory() throws Exception { ECKey key = new ECKey(); String address = key.toAddress(params).toString(); Transaction tx = new Transaction(params, Utils.HEX.decode(TEST_TX)); supplyTransactionForAddress(address, tx); control.replay(); multiWallet.retrieveAddressHistory(address); control.verify(); assertEquals(1, multiWallet.getTransactions().size()); }
@VisibleForTesting void retrieveAddressHistory(final String address) { ListenableFuture<StratumMessage> future = client.call("blockchain.address.get_history", address); Futures.addCallback(future, new FutureCallback<StratumMessage>() { @Override public void onSuccess(StratumMessage result) { final List<AddressHistoryItem> history; try { history = mapper.readValue(mapper.treeAsTokens(result.result), new TypeReference<List<AddressHistoryItem>>() {}); } catch (IOException e) { log.error("unable to parse history for {}", address); return; } log.info("got history of length {} for {}", history.size(), address); final List<ListenableFuture<Transaction>> futures = Lists.newArrayList(); for (AddressHistoryItem item : history) { Sha256Hash hash = Sha256Hash.wrap(item.txHash); if (pendingDownload.containsKey(hash)) continue; Transaction existing = txs.get(hash); if (existing != null && !existing.isPending()) continue; SettableFuture<Transaction> future = addPendingDownload(hash); retrieveTransaction(hash, item.height); futures.add(future); } ListenableFuture completeFuture = Futures.allAsList(futures); Futures.addCallback(completeFuture, new FutureCallback() { @Override public void onSuccess(Object result) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.set(futures.size()); } } @Override public void onFailure(Throwable t) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.setException(t); } } }); } @Override public void onFailure(@Nonnull Throwable t) { log.error("failed to retrieve {}", address); } }); }
ElectrumMultiWallet extends SmartMultiWallet implements WalletExtension, StratumChain.Listener { @VisibleForTesting void retrieveAddressHistory(final String address) { ListenableFuture<StratumMessage> future = client.call("blockchain.address.get_history", address); Futures.addCallback(future, new FutureCallback<StratumMessage>() { @Override public void onSuccess(StratumMessage result) { final List<AddressHistoryItem> history; try { history = mapper.readValue(mapper.treeAsTokens(result.result), new TypeReference<List<AddressHistoryItem>>() {}); } catch (IOException e) { log.error("unable to parse history for {}", address); return; } log.info("got history of length {} for {}", history.size(), address); final List<ListenableFuture<Transaction>> futures = Lists.newArrayList(); for (AddressHistoryItem item : history) { Sha256Hash hash = Sha256Hash.wrap(item.txHash); if (pendingDownload.containsKey(hash)) continue; Transaction existing = txs.get(hash); if (existing != null && !existing.isPending()) continue; SettableFuture<Transaction> future = addPendingDownload(hash); retrieveTransaction(hash, item.height); futures.add(future); } ListenableFuture completeFuture = Futures.allAsList(futures); Futures.addCallback(completeFuture, new FutureCallback() { @Override public void onSuccess(Object result) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.set(futures.size()); } } @Override public void onFailure(Throwable t) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.setException(t); } } }); } @Override public void onFailure(@Nonnull Throwable t) { log.error("failed to retrieve {}", address); } }); } }
ElectrumMultiWallet extends SmartMultiWallet implements WalletExtension, StratumChain.Listener { @VisibleForTesting void retrieveAddressHistory(final String address) { ListenableFuture<StratumMessage> future = client.call("blockchain.address.get_history", address); Futures.addCallback(future, new FutureCallback<StratumMessage>() { @Override public void onSuccess(StratumMessage result) { final List<AddressHistoryItem> history; try { history = mapper.readValue(mapper.treeAsTokens(result.result), new TypeReference<List<AddressHistoryItem>>() {}); } catch (IOException e) { log.error("unable to parse history for {}", address); return; } log.info("got history of length {} for {}", history.size(), address); final List<ListenableFuture<Transaction>> futures = Lists.newArrayList(); for (AddressHistoryItem item : history) { Sha256Hash hash = Sha256Hash.wrap(item.txHash); if (pendingDownload.containsKey(hash)) continue; Transaction existing = txs.get(hash); if (existing != null && !existing.isPending()) continue; SettableFuture<Transaction> future = addPendingDownload(hash); retrieveTransaction(hash, item.height); futures.add(future); } ListenableFuture completeFuture = Futures.allAsList(futures); Futures.addCallback(completeFuture, new FutureCallback() { @Override public void onSuccess(Object result) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.set(futures.size()); } } @Override public void onFailure(Throwable t) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.setException(t); } } }); } @Override public void onFailure(@Nonnull Throwable t) { log.error("failed to retrieve {}", address); } }); } ElectrumMultiWallet(SmartWallet wallet, File baseDirectory);  ElectrumMultiWallet(SmartWallet wallet); }
ElectrumMultiWallet extends SmartMultiWallet implements WalletExtension, StratumChain.Listener { @VisibleForTesting void retrieveAddressHistory(final String address) { ListenableFuture<StratumMessage> future = client.call("blockchain.address.get_history", address); Futures.addCallback(future, new FutureCallback<StratumMessage>() { @Override public void onSuccess(StratumMessage result) { final List<AddressHistoryItem> history; try { history = mapper.readValue(mapper.treeAsTokens(result.result), new TypeReference<List<AddressHistoryItem>>() {}); } catch (IOException e) { log.error("unable to parse history for {}", address); return; } log.info("got history of length {} for {}", history.size(), address); final List<ListenableFuture<Transaction>> futures = Lists.newArrayList(); for (AddressHistoryItem item : history) { Sha256Hash hash = Sha256Hash.wrap(item.txHash); if (pendingDownload.containsKey(hash)) continue; Transaction existing = txs.get(hash); if (existing != null && !existing.isPending()) continue; SettableFuture<Transaction> future = addPendingDownload(hash); retrieveTransaction(hash, item.height); futures.add(future); } ListenableFuture completeFuture = Futures.allAsList(futures); Futures.addCallback(completeFuture, new FutureCallback() { @Override public void onSuccess(Object result) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.set(futures.size()); } } @Override public void onFailure(Throwable t) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.setException(t); } } }); } @Override public void onFailure(@Nonnull Throwable t) { log.error("failed to retrieve {}", address); } }); } ElectrumMultiWallet(SmartWallet wallet, File baseDirectory);  ElectrumMultiWallet(SmartWallet wallet); @Override void addEventListener(MultiWalletEventListener listener, Executor executor); void setCheckpoints(CheckpointManager checkpoints); void setInitialStore(URL url); @Override boolean removeEventListener(MultiWalletEventListener listener); @Override Set<Transaction> getTransactions(); @Override Transaction getTransaction(Sha256Hash hash); @Override Map<Sha256Hash, Transaction> getTransactionPool(WalletTransaction.Pool pool); @Override void markKeysAsUsed(Transaction tx); @Override void completeTx(Wallet.SendRequest req); @Override void commitTx(Transaction tx); @Override List<TransactionOutput> calculateAllSpendCandidates(boolean excludeImmatureCoinbases, boolean excludeUnsignable); @Override ListenableFuture<Transaction> broadcastTransaction(final Transaction tx); @Override void start(); @Override void startAsync(); @Override void stopAsync(); void stop(); @Override void resetBlockchain(); void safeAwaitClientTerminated(); @Override void awaitDownload(); @Override String getWalletExtensionID(); @Override boolean isWalletExtensionMandatory(); @Override byte[] serializeWalletExtension(); @Override void deserializeWalletExtension(Wallet containingWallet, byte[] data); @Override void onHeight(long height, Block block, boolean isSynced); int currentHeight(); @Override boolean isSynced(); @Override List<VersionMessage> getPeers(); @Override List<StoredBlock> getRecentBlocks(int maxBlocks); }
ElectrumMultiWallet extends SmartMultiWallet implements WalletExtension, StratumChain.Listener { @VisibleForTesting void retrieveAddressHistory(final String address) { ListenableFuture<StratumMessage> future = client.call("blockchain.address.get_history", address); Futures.addCallback(future, new FutureCallback<StratumMessage>() { @Override public void onSuccess(StratumMessage result) { final List<AddressHistoryItem> history; try { history = mapper.readValue(mapper.treeAsTokens(result.result), new TypeReference<List<AddressHistoryItem>>() {}); } catch (IOException e) { log.error("unable to parse history for {}", address); return; } log.info("got history of length {} for {}", history.size(), address); final List<ListenableFuture<Transaction>> futures = Lists.newArrayList(); for (AddressHistoryItem item : history) { Sha256Hash hash = Sha256Hash.wrap(item.txHash); if (pendingDownload.containsKey(hash)) continue; Transaction existing = txs.get(hash); if (existing != null && !existing.isPending()) continue; SettableFuture<Transaction> future = addPendingDownload(hash); retrieveTransaction(hash, item.height); futures.add(future); } ListenableFuture completeFuture = Futures.allAsList(futures); Futures.addCallback(completeFuture, new FutureCallback() { @Override public void onSuccess(Object result) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.set(futures.size()); } } @Override public void onFailure(Throwable t) { SettableFuture<Integer> settable = downloadFutures.get(address); if (settable != null && !settable.isDone()) { settable.setException(t); } } }); } @Override public void onFailure(@Nonnull Throwable t) { log.error("failed to retrieve {}", address); } }); } ElectrumMultiWallet(SmartWallet wallet, File baseDirectory);  ElectrumMultiWallet(SmartWallet wallet); @Override void addEventListener(MultiWalletEventListener listener, Executor executor); void setCheckpoints(CheckpointManager checkpoints); void setInitialStore(URL url); @Override boolean removeEventListener(MultiWalletEventListener listener); @Override Set<Transaction> getTransactions(); @Override Transaction getTransaction(Sha256Hash hash); @Override Map<Sha256Hash, Transaction> getTransactionPool(WalletTransaction.Pool pool); @Override void markKeysAsUsed(Transaction tx); @Override void completeTx(Wallet.SendRequest req); @Override void commitTx(Transaction tx); @Override List<TransactionOutput> calculateAllSpendCandidates(boolean excludeImmatureCoinbases, boolean excludeUnsignable); @Override ListenableFuture<Transaction> broadcastTransaction(final Transaction tx); @Override void start(); @Override void startAsync(); @Override void stopAsync(); void stop(); @Override void resetBlockchain(); void safeAwaitClientTerminated(); @Override void awaitDownload(); @Override String getWalletExtensionID(); @Override boolean isWalletExtensionMandatory(); @Override byte[] serializeWalletExtension(); @Override void deserializeWalletExtension(Wallet containingWallet, byte[] data); @Override void onHeight(long height, Block block, boolean isSynced); int currentHeight(); @Override boolean isSynced(); @Override List<VersionMessage> getPeers(); @Override List<StoredBlock> getRecentBlocks(int maxBlocks); static final String EXTENSION_ID; static final int CHECKPOINT_TIME_BUFFER; }