private void handleNewExternalTransactionsInt(Collection<TransactionEx> transactions) throws WapiException { // Transform and put into two arrays with matching indexes ArrayList<TransactionEx> texArray = new ArrayList<TransactionEx>(transactions.size()); ArrayList<Transaction> txArray = new ArrayList<Transaction>(transactions.size()); for (TransactionEx tex : transactions) { try { txArray.add(Transaction.fromByteReader(new ByteReader(tex.binary))); texArray.add(tex); } catch (TransactionParsingException e) { // We hit a transaction that we cannot parse. Log but otherwise ignore it _logger.logError("Received transaction that we cannot parse: " + tex.txid.toString()); continue; } } // Grab and handle parent transactions fetchStoreAndValidateParentOutputs(txArray); // Store transaction locally for (int i = 0; i < txArray.size(); i++) { _backing.putTransaction(texArray.get(i)); onNewTransaction(texArray.get(i), txArray.get(i)); } }
protected TransactionSummary transform(TransactionEx tex, int blockChainHeight) { Transaction tx; try { tx = Transaction.fromByteReader(new ByteReader(tex.binary)); } catch (TransactionParsingException e) { // Should not happen as we have parsed the transaction earlier _logger.logError("Unable to parse "); return null; } return transform(tx, tex.time, tex.height, blockChainHeight); }
protected Balance calculateLocalBalance() { Collection<TransactionOutputEx> unspentOutputs = new HashSet<TransactionOutputEx>(_backing.getAllUnspentOutputs()); long confirmed = 0; long pendingChange = 0; long pendingSending = 0; long pendingReceiving = 0; // // Determine the value we are receiving and create a set of outpoints for fast lookup // Set<OutPoint> unspentOutPoints = new HashSet<OutPoint>(); for (TransactionOutputEx output : unspentOutputs) { if (output.height == -1) { if (isFromMe(output.outPoint.hash)) { pendingChange += output.value; } else { pendingReceiving += output.value; } } else { confirmed += output.value; } unspentOutPoints.add(output.outPoint); } // // Determine the value we are sending // // Get the current set of unconfirmed transactions List<Transaction> unconfirmed = new ArrayList<Transaction>(); for (TransactionEx tex : _backing.getUnconfirmedTransactions()) { try { Transaction t = Transaction.fromByteReader(new ByteReader(tex.binary)); unconfirmed.add(t); } catch (TransactionParsingException e) { // never happens, we have parsed it before } } for (Transaction t : unconfirmed) { // For each input figure out if WE are sending it by fetching the // parent transaction and looking at the address boolean weSend = false; for (TransactionInput input : t.inputs) { // Find the parent transaction if (input.outPoint.hash.equals(Sha256Hash.ZERO_HASH)) { continue; } TransactionOutputEx parent = _backing.getParentTransactionOutput(input.outPoint); if (parent == null) { _logger.logError("Unable to find parent transaction output: " + input.outPoint); continue; } TransactionOutput parentOutput = transform(parent); Address fundingAddress = parentOutput.script.getAddress(_network); if (isMine(fundingAddress)) { // One of our addresses are sending coins pendingSending += parentOutput.value; weSend = true; } } // Now look at the outputs and if it contains change for us, then subtract that from the // sending amount // if it is already spent in another transaction for (int i = 0; i < t.outputs.length; i++) { TransactionOutput output = t.outputs[i]; Address destination = output.script.getAddress(_network); if (weSend && isMine(destination)) { // The funds are sent from us to us OutPoint outPoint = new OutPoint(t.getHash(), i); if (!unspentOutPoints.contains(outPoint)) { // This output has been spent, subtract it from the amount sent pendingSending -= output.value; } } } } int blockHeight = getBlockChainHeight(); return new Balance( confirmed, pendingReceiving, pendingSending, pendingChange, System.currentTimeMillis(), blockHeight, true, _allowZeroConfSpending); }