@Override public void onSuccess(ResultMessage result) { try { String rawTx = result.getResult().getString(0); byte[] txBytes = Utils.HEX.decode(rawTx); BitTransaction tx = new BitTransaction(type, txBytes); if (!tx.getHash().equals(txHash)) { throw new Exception("Requested TX " + txHash + " but got " + tx.getHashAsString()); } listener.onTransactionUpdate(tx); if (cacheDir != null) { try { Files.write(txBytes, getTxCacheFile(txHash)); } catch (IOException e) { log.warn("Error writing cached transaction", e); } } } catch (Exception e) { onFailure(e); } }
@Override public String getHashAsString() { return getHash().toString(); }
@Override public byte[] getHashBytes() { return getHash().getBytes(); }
/** * If the transactions outputs are all marked as spent, and it's in the unspent map, move it. * If the owned transactions outputs are not all marked as spent, and it's in the spent map, move it. */ private void maybeMovePool(BitTransaction tx) { lock.lock(); try { if (tx.getConfidenceType() == BUILDING) { // Transaction is confirmed, move it if (pending.remove(tx.getHash()) != null) { confirmed.put(tx.getHash(), tx); trimTransaction(tx.getHash()); } } } finally { lock.unlock(); } }
@Override public void onTransactionUpdate(BitTransaction tx) { if (log.isInfoEnabled()) log.info("Got a new transaction {}", tx.getHash()); lock.lock(); try { addNewTransactionIfNeeded(tx); tryToApplyState(); } finally { lock.unlock(); } }
/** * Just adds the transaction to a pool without doing anything else */ private void simpleAddTransaction(WalletTransaction.Pool pool, BitTransaction tx) { lock.lock(); try { if (rawTransactions.containsKey(tx.getHash())) return; rawTransactions.put(tx.getHash(), tx); switch (pool) { case CONFIRMED: checkState(confirmed.put(tx.getHash(), tx) == null); break; case PENDING: checkState(pending.put(tx.getHash(), tx) == null); break; default: throw new RuntimeException("Unknown wallet transaction type " + pool); } } finally { lock.unlock(); } }
private void fetchTimestamp(BitTransaction tx, Integer height) { checkState(lock.isHeldByCurrentThread(), "Lock is held by another thread"); if (blockTimes.containsKey(height)) { tx.setTimestamp(blockTimes.get(height)); } else { if (log.isDebugEnabled()) log.debug("Must get timestamp for {} block on height {}", type.getName(), height); if (!missingTimestamps.containsKey(height)) { missingTimestamps.put(height, new HashSet<Sha256Hash>()); missingTimestamps.get(height).add(tx.getHash()); if (blockchainConnection != null) { blockchainConnection.getBlock(height, this); } } else { missingTimestamps.get(height).add(tx.getHash()); } } }
@Override public void onSuccess(ResultMessage result) { try { String txId = result.getResult().getString(0); // FIXME could return {u'message': u'', u'code': -25} log.info("got tx {} =?= {}", txId, tx.getHash()); checkState(tx.getHash().toString().equals(txId)); if (listener != null) listener.onTransactionBroadcast(tx); } catch (Exception e) { onFailure(e); } }
@Override public boolean broadcastTxSync(final BitTransaction tx) { checkNotNull(stratumClient); CallMessage message = new CallMessage("blockchain.transaction.broadcast", Arrays.asList(Utils.HEX.encode(tx.bitcoinSerialize()))); try { ResultMessage result = stratumClient.call(message).get(); String txId = result.getResult().getString(0); // FIXME could return {u'message': u'', u'code': -25} log.info("got tx {} =?= {}", txId, tx.getHash()); checkState(tx.getHash().toString().equals(txId)); return true; } catch (Exception e) { log.error("Could not get reply for blockchain.transaction.broadcast", e); } return false; }
@Override public void run() { File txCachedFile = getTxCacheFile(txHash); if (txCachedFile.exists()) { try { byte[] txBytes = Files.toByteArray(txCachedFile); BitTransaction tx = new BitTransaction(type, txBytes); if (!tx.getHash().equals(txHash)) { if (!txCachedFile.delete()) { log.warn("Error deleting cached transaction {}", txCachedFile); } } else { listener.onTransactionUpdate(tx); return; } } catch (IOException e) { log.warn("Error reading cached transaction", e); } } // Fallback to fetching from the network getTransactionFromNetwork(txHash, listener); } });
public OutPointOutput(BitTransaction tx, long index) { this(new TrimmedOutput(tx.getOutput((int) index), index, tx.getHash()), tx.isGenerated()); }
tx.getHash(), outPoint.getHash(), outPoint.getIndex()); isDoubleSpending = true; break;
trimTransaction(tx.getHash()); if (tx.getSource() == Source.SELF) queueOnNewBalance(); } finally {
txHashes.add(tx.getHash()); for (TransactionOutput txo : tx.getOutputs()) { if (txo.isAvailableForSpending() && txo.isMineOrWatched(account)) {
private Sha256Hash send(Value value, WalletPocketHD w1, WalletPocketHD w2) throws Exception { assertEquals(w1.getCoinType(), w2.getCoinType()); CoinType type = w1.getCoinType(); BitSendRequest req = w1.sendCoinsOffline(w2.getReceiveAddress(), value); req.feePerTxSize = type.value("0.01"); w1.completeAndSignTx(req); byte[] txBytes = req.tx.bitcoinSerialize(); w1.addNewTransactionIfNeeded(new BitTransaction(type, txBytes)); w2.addNewTransactionIfNeeded(new BitTransaction(type, txBytes)); return req.tx.getHash(); }
.setHash(hashToByteString(bitTx.getHash())) .setVersion((int) tx.getVersion());
if (!bitTx.getHash().equals(hash)) throw new UnreadableWalletException(String.format("Transaction did not deserialize completely: %s vs %s", tx.getHash(), hash)); if (txMap.containsKey(txProto.getHash()))