List of usage examples for com.google.common.util.concurrent MoreExecutors sameThreadExecutor
@Deprecated @GwtIncompatible("TODO") public static ListeningExecutorService sameThreadExecutor()
From source file:com.woollysammoth.nubitj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Nubit network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) * @return a future that completes when the server acknowledges receipt and acceptance of the payment. *///ww w .ja v a 2 s . co m @Override public ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToNubit())) .setClientChangeValue(state.getValueRefunded().longValue()); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:com.google.sha1coin.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) * @return a future that completes when the server acknowledges receipt and acceptance of the payment. *///from w w w.jav a 2 s .co m @Override public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin())) .setClientChangeValue(state.getValueRefunded().value); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:io.mappum.altcoinj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) */// ww w. j av a2 s. c o m @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:io.xpydev.paycoinj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) */// w w w . j av a2 s . com @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToPaycoin())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:com.github.kryptohash.kryptohashj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) */// www .j a v a 2 s. co m @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToKryptohash())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:com.matthewmitchell.nubitsj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) *//*from w ww . j a va 2 s .co m*/ @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToNubits())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:com.matthewmitchell.peercoinj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) *///from w w w . j ava2 s. c om @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToPeercoin())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:org.neoscoinj.protocols.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Neoscoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @param userKey Key derived from a user password, needed for any signing when the wallet is encrypted. * The wallet KeyCrypter is assumed. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) * @throws ECKey.KeyIsEncryptedException If the keys are encrypted and no AES key has been provided, *//*from ww w .jav a 2 s.co m*/ @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info, @Nullable KeyParameter userKey) throws ValueOutOfRangeException, IllegalStateException, ECKey.KeyIsEncryptedException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); if (wallet.isEncrypted() && userKey == null) throw new ECKey.KeyIsEncryptedException(); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size, userKey); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToNeoscoin())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:network.bitmesh.channels.PaymentChannelClient.java
/** * Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the * amount of money actually requested. It can be larger if the amount left over in the channel would be too small to * be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money * left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure * you wait for the previous increase payment future to complete before incrementing the payment again. * * @param size How many satoshis to increment the payment by (note: not the new total). * @param info Information about this update, used to extend this protocol. * @param userKey Key derived from a user password, needed for any signing when the wallet is encrypted. * The wallet KeyCrypter is assumed. * @return a future that completes when the server acknowledges receipt and acceptance of the payment. * @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value * ({@link PaymentChannelClientConnection#state()}.getTotalValue()) * @throws IllegalStateException If the channel has been closed or is not yet open * (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second) * @throws ECKey.KeyIsEncryptedException If the keys are encrypted and no AES key has been provided, *//* w w w . j ava 2s.com*/ @Override public ListenableFuture<PaymentIncrementAck> incrementPayment(Coin size, @Nullable ByteString info, @Nullable KeyParameter userKey) throws ValueOutOfRangeException, IllegalStateException, ECKey.KeyIsEncryptedException { lock.lock(); try { if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN) throw new IllegalStateException("Channel is not fully initialized/has already been closed"); if (increasePaymentFuture != null) throw new IllegalStateException( "Already incrementing paying, wait for previous payment to complete."); if (wallet.isEncrypted() && userKey == null) throw new ECKey.KeyIsEncryptedException(); PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(size, userKey); Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder() .setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin())) .setClientChangeValue(state.getValueRefunded().value); if (info != null) updatePaymentBuilder.setInfo(info); increasePaymentFuture = SettableFuture.create(); increasePaymentFuture.addListener(new Runnable() { @Override public void run() { lock.lock(); increasePaymentFuture = null; lock.unlock(); } }, MoreExecutors.sameThreadExecutor()); conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder().setUpdatePayment(updatePaymentBuilder) .setType(Protos.TwoWayChannelMessage.MessageType.UPDATE_PAYMENT).build()); lastPaymentActualAmount = payment.amount; return increasePaymentFuture; } finally { lock.unlock(); } }
From source file:com.google.casinocoin.core.Peer.java
private ListenableFuture<Object> downloadDependenciesInternal(final Transaction tx, final Object marker, final List<Transaction> results) { final SettableFuture<Object> resultFuture = SettableFuture.create(); final Sha256Hash rootTxHash = tx.getHash(); // We want to recursively grab its dependencies. This is so listeners can learn important information like // whether a transaction is dependent on a timelocked transaction or has an unexpectedly deep dependency tree // or depends on a no-fee transaction. ///*from w w w. j a v a2 s .c o m*/ // Firstly find any that are already in the memory pool so if they weren't garbage collected yet, they won't // be deleted. Use COW sets to make unit tests deterministic and because they are small. It's slower for // the case of transactions with tons of inputs. Set<Transaction> dependencies = new CopyOnWriteArraySet<Transaction>(); Set<Sha256Hash> needToRequest = new CopyOnWriteArraySet<Sha256Hash>(); for (TransactionInput input : tx.getInputs()) { // There may be multiple inputs that connect to the same transaction. Sha256Hash hash = input.getOutpoint().getHash(); Transaction dep = memoryPool.get(hash); if (dep == null) { needToRequest.add(hash); } else { dependencies.add(dep); } } results.addAll(dependencies); lock.lock(); try { // Build the request for the missing dependencies. List<ListenableFuture<Transaction>> futures = Lists.newArrayList(); GetDataMessage getdata = new GetDataMessage(params); final long nonce = (long) (Math.random() * Long.MAX_VALUE); if (needToRequest.size() > 1) log.info("{}: Requesting {} transactions for dep resolution", needToRequest.size()); for (Sha256Hash hash : needToRequest) { getdata.addTransaction(hash); GetDataRequest req = new GetDataRequest(); req.hash = hash; req.future = SettableFuture.create(); if (!isNotFoundMessageSupported()) { req.nonce = nonce; } futures.add(req.future); getDataFutures.add(req); } // The transactions we already grabbed out of the mempool must still be considered by the code below. for (Transaction dep : dependencies) { futures.add(Futures.immediateFuture(dep)); } ListenableFuture<List<Transaction>> successful = Futures.successfulAsList(futures); Futures.addCallback(successful, new FutureCallback<List<Transaction>>() { public void onSuccess(List<Transaction> transactions) { // Once all transactions either were received, or we know there are no more to come ... // Note that transactions will contain "null" for any positions that weren't successful. List<ListenableFuture<Object>> childFutures = Lists.newLinkedList(); for (Transaction tx : transactions) { if (tx == null) continue; log.info("{}: Downloaded dependency of {}: {}", new Object[] { vAddress, rootTxHash, tx.getHashAsString() }); results.add(tx); // Now recurse into the dependencies of this transaction too. childFutures.add(downloadDependenciesInternal(tx, marker, results)); } if (childFutures.size() == 0) { // Short-circuit: we're at the bottom of this part of the tree. resultFuture.set(marker); } else { // There are some children to download. Wait until it's done (and their children and their // children...) to inform the caller that we're finished. Futures.addCallback(Futures.successfulAsList(childFutures), new FutureCallback<List<Object>>() { public void onSuccess(List<Object> objects) { resultFuture.set(marker); } public void onFailure(Throwable throwable) { resultFuture.setException(throwable); } }); } } public void onFailure(Throwable throwable) { resultFuture.setException(throwable); } }); // Start the operation. sendMessage(getdata); if (!isNotFoundMessageSupported()) { // If the peer isn't new enough to support the notfound message, we use a nasty hack instead and // assume if we send a ping message after the getdata message, it'll be processed after all answers // from getdata are done, so we can watch for the pong message as a substitute. log.info("{}: Dep resolution waiting for a pong with nonce {}", this, nonce); ping(nonce).addListener(new Runnable() { public void run() { // The pong came back so clear out any transactions we requested but didn't get. for (GetDataRequest req : getDataFutures) { if (req.nonce == nonce) { log.info("{}: Bottomed out dep tree at {}", this, req.hash); req.future.cancel(true); getDataFutures.remove(req); } } } }, MoreExecutors.sameThreadExecutor()); } } catch (Exception e) { log.error("{}: Couldn't send getdata in downloadDependencies({})", this, tx.getHash()); resultFuture.setException(e); return resultFuture; } finally { lock.unlock(); } return resultFuture; }