/** * Sets that the specified status is currently updating i.e. getting transactions. * * Returns true if registered successfully or false if status already updating */ @VisibleForTesting boolean registerStatusForUpdate(AddressStatus status) { checkNotNull(status.getStatus()); lock.lock(); try { // If current address is updating if (statusPendingUpdates.containsKey(status.getAddress())) { AddressStatus updatingAddressStatus = statusPendingUpdates.get(status.getAddress()); String updatingStatus = updatingAddressStatus.getStatus(); // If the same status is updating, don't update again if (updatingStatus != null && updatingStatus.equals(status.getStatus())) { return false; } else { // Status is newer, so replace the updating status statusPendingUpdates.put(status.getAddress(), status); return true; } } else { // This status is new statusPendingUpdates.put(status.getAddress(), status); return true; } } finally { lock.unlock(); } }
void commitAddressStatus(AddressStatus newStatus) { if (!newStatus.canCommitStatus()) { log.warn("Tried to commit an address status with a non applied state: {}:{}", newStatus.getAddress(), newStatus.getStatus()); return; } lock.lock(); try { AddressStatus updatingStatus = statusPendingUpdates.get(newStatus.getAddress()); if (updatingStatus != null && updatingStatus.equals(newStatus)) { statusPendingUpdates.remove(newStatus.getAddress()); } addressesStatus.put(newStatus.getAddress(), newStatus.getStatus()); queueOnConnectivity(); } finally { lock.unlock(); } // Skip saving null statuses if (newStatus.getStatus() != null) { walletSaveLater(); } }
private boolean isAddressStatusChanged(AddressStatus addressStatus) { lock.lock(); try { AbstractAddress address = addressStatus.getAddress(); String newStatus = addressStatus.getStatus(); if (addressesStatus.containsKey(address)) { String previousStatus = addressesStatus.get(address); if (previousStatus == null) { return newStatus != null; // Status changed if newStatus is not null } else { return !previousStatus.equals(newStatus); } } else { // Unused address, just mark it that we watch it if (newStatus == null) { commitAddressStatus(addressStatus); return false; } else { return true; } } } finally { lock.unlock(); } }
private boolean isAddressStatusChanged(AddressStatus addressStatus) { lock.lock(); try { AbstractAddress address = addressStatus.getAddress(); String newStatus = addressStatus.getStatus(); if (addressesStatus.containsKey(address)) { String previousStatus = addressesStatus.get(address); if (previousStatus == null) { return newStatus != null; // Status changed if newStatus is not null } else { return !previousStatus.equals(newStatus); } } else { // Unused address, just mark it that we watch it if (newStatus == null) { commitAddressStatus(addressStatus); return false; } else { return true; } } } finally { lock.unlock(); } }
void commitAddressStatus(AddressStatus newStatus) { lock.lock(); try { /*AddressStatus updatingStatus = statusPendingUpdates.get(newStatus.getAddress()); if (updatingStatus != null && updatingStatus.equals(newStatus)) { statusPendingUpdates.remove(newStatus.getAddress()); }*/ addressesStatus.put(newStatus.getAddress(), newStatus.getStatus()); } finally { lock.unlock(); } // Skip saving null statuses if (newStatus.getStatus() != null) { walletSaveLater(); } }
@Override public void onUnspentTransactionUpdate(AddressStatus status, List<UnspentTx> unspentTxes) { lock.lock(); try { AddressStatus updatingStatus = statusPendingUpdates.get(status.getAddress()); // Check if this updating status is valid if (updatingStatus != null && updatingStatus.equals(status)) { updatingStatus.queueUnspentTransactions(unspentTxes); fetchTransactionsIfNeeded(unspentTxes); tryToApplyState(updatingStatus); } else { log.info("Ignoring unspent tx call because no entry found or newer entry."); } } finally { lock.unlock(); } }
@Override public void onTransactionHistory(AddressStatus status, List<HistoryTx> historyTxes) { lock.lock(); try { AddressStatus updatingStatus = statusPendingUpdates.get(status.getAddress()); // Check if this updating status is valid if (updatingStatus != null && updatingStatus.equals(status)) { updatingStatus.queueHistoryTransactions(historyTxes); fetchTransactionsIfNeeded(historyTxes); tryToApplyState(); } else { log.info("Ignoring history tx call because no entry found or newer entry."); } } finally { lock.unlock(); } }
@Override public void getUnspentTx(AddressStatus status, BitTransactionEventListener listener) { List<UnspentTx> utx = unspentTxs.get(status.getAddress()); if (utx == null) { utx = ImmutableList.of(); } listener.onUnspentTransactionUpdate(status, utx); }
@Override public void getHistoryTx(AddressStatus status, TransactionEventListener<BitTransaction> listener) { List<HistoryTx> htx = historyTxs.get(status.getAddress()); if (htx == null) { htx = ImmutableList.of(); } listener.onTransactionHistory(status, htx); }
@Override public void getUnspentTx(final AddressStatus status, final BitTransactionEventListener listener) { checkNotNull(stratumClient); CallMessage message = new CallMessage("blockchain.address.listunspent", Arrays.asList(status.getAddress().toString())); final ListenableFuture<ResultMessage> result = stratumClient.call(message); Futures.addCallback(result, new FutureCallback<ResultMessage>() { @Override public void onSuccess(ResultMessage result) { JSONArray resTxs = result.getResult(); ImmutableList.Builder<UnspentTx> utxes = ImmutableList.builder(); try { for (int i = 0; i < resTxs.length(); i++) { utxes.add(new UnspentTx(resTxs.getJSONObject(i))); } } catch (JSONException e) { onFailure(e); return; } listener.onUnspentTransactionUpdate(status, utxes.build()); } @Override public void onFailure(Throwable t) { log.error("Could not get reply for blockchain.address.listunspent", t); } }, Threading.USER_THREAD); }
Arrays.asList(status.getAddress().toString())); final ListenableFuture<ResultMessage> result = stratumClient.call(message);
@Override public void onAddressStatusUpdate(AddressStatus status) { log.debug("Got a status {}", status); lock.lock(); try { if (status.getStatus() != null) { if (isAddressStatusChanged(status)) { this.balance = Value.valueOf(this.type, Long.valueOf(status.getStatus())); //if (registerStatusForUpdate(status)) { log.info("Must get transactions for address {}, status {}", status.getAddress(), status.getStatus()); if (blockchainConnection != null) { blockchainConnection.getHistoryTx(status, this); } } //} else { // log.info("Status {} already updating", status.getStatus()); //} } else { commitAddressStatus(status); } } finally { lock.unlock(); } }
lock.lock(); try { confirmAddressSubscription(status.getAddress()); if (status.getStatus() != null) { markAddressAsUsed(status.getAddress()); subscribeToAddressesIfNeeded(); status.getAddress(), status.getStatus());
/** * Try to apply the status state */ private void tryToApplyState(AddressStatus status) { lock.lock(); try { if (statusPendingUpdates.containsKey(status.getAddress())) { if (status.isUnspentTxQueued() && !status.isUnspentTxStateApplied()) { Set<Sha256Hash> txHashes = status.getUnspentTxHashes(); HashMap<Sha256Hash, BitTransaction> txs = getTransactions(txHashes); // We have all the transactions, apply state if (txs.size() == txHashes.size()) { applyUnspentState(status, txs); } } if (status.isHistoryTxQueued() && !status.isHistoryTxStateApplied()) { Set<Sha256Hash> txHashes = status.getHistoryTxHashes(); HashMap<Sha256Hash, BitTransaction> txs = getTransactions(txHashes); // We have all the transactions, apply state if (txs.size() == txHashes.size()) { applyHistoryState(status, txs); } } } } finally { lock.unlock(); } }
@Override public void run() { log.info("Going to fetch txs for {}", status.getAddress().toString()); getBlockChainTxsUrl(status.getAddress().toString())).build(); getHttpClient().newCall(request).enqueue(new Callback() { @Override
AbstractAddress address = status.getAddress(); Set<TrimmedOutPoint> notPresentInStatus = new HashSet<>(); for (Map.Entry<TrimmedOutPoint, OutPointOutput> utxo : unspentOutputs.entrySet()) {
continue; // Don't serialize null statuses addressStatus.setAddress(status.getAddress().toString()); addressStatus.setStatus(status.getStatus());
assertEquals(status, newPocket.getAddressStatus(status.getAddress()));