コード例 #1
0
  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);
  }