예제 #1
0
  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));
    }
  }
예제 #2
0
  private void markTransactionAsSpent(Transaction transaction) {
    _backing.beginTransaction();
    try {
      // Remove inputs from unspent, marking them as spent
      for (TransactionInput input : transaction.inputs) {
        TransactionOutputEx parentOutput = _backing.getUnspentOutput(input.outPoint);
        if (parentOutput != null) {
          _backing.deleteUnspentOutput(input.outPoint);
          _backing.putParentTransactionOutput(parentOutput);
        }
      }

      // See if any of the outputs are for ourselves and store them as
      // unspent
      for (int i = 0; i < transaction.outputs.length; i++) {
        TransactionOutput output = transaction.outputs[i];
        if (isMine(output.script)) {
          _backing.putUnspentOutput(
              new TransactionOutputEx(
                  new OutPoint(transaction.getHash(), i),
                  -1,
                  output.value,
                  output.script.getScriptBytes(),
                  false));
        }
      }

      // Store transaction locally, so we have it in our history and don't
      // need to fetch it in a minute
      _backing.putTransaction(TransactionEx.fromUnconfirmedTransaction(transaction));
      _backing.setTransactionSuccessful();
    } finally {
      _backing.endTransaction();
    }

    // Tell account that we have a new transaction
    onNewTransaction(TransactionEx.fromUnconfirmedTransaction(transaction), transaction);

    // Calculate local balance cache. It has changed because we have done
    // some spending
    updateLocalBalance();
    persistContextIfNecessary();
  }
예제 #3
0
  protected boolean monitorYoungTransactions() {
    Collection<TransactionEx> list = _backing.getYoungTransactions(5, getBlockChainHeight());
    if (list.isEmpty()) {
      return true;
    }
    List<Sha256Hash> txids = new ArrayList<Sha256Hash>(list.size());
    for (TransactionEx tex : list) {
      txids.add(tex.txid);
    }
    CheckTransactionsResponse result;
    try {
      result = _wapi.checkTransactions(new CheckTransactionsRequest(txids)).getResult();
    } catch (WapiException e) {
      postEvent(Event.SERVER_CONNECTION_ERROR);
      _logger.logError("Server connection failed with error code: " + e.errorCode, e);
      // We failed to check transactions
      return false;
    }
    for (TransactionStatus t : result.transactions) {
      if (!t.found) {
        // We have a transaction locally that does not exist in the
        // blockchain. Must be a residue due to double-spend or malleability

        _backing.deleteTransaction(t.txid);
        continue;
      }
      TransactionEx tex = _backing.getTransaction(t.txid);
      Preconditions.checkNotNull(tex);
      if (tex.height != t.height || tex.time != t.time) {
        // The transaction got a new height or timestamp. There could be
        // several reasons for that. It got a new timestamp from the server,
        // it confirmed, or might also be a reorg.
        TransactionEx newTex = new TransactionEx(tex.txid, t.height, t.time, tex.binary);
        System.out.println("Replacing:\n" + tex.toString() + "\nWith:\n" + newTex.toString());
        postEvent(Event.TRANSACTION_HISTORY_CHANGED);
        _backing.deleteTransaction(tex.txid);
        _backing.putTransaction(newTex);
      }
    }
    return true;
  }