示例#1
0
 @Override
 public synchronized boolean deleteTransaction(Sha256Hash transactionId) {
   TransactionEx tex = _backing.getTransaction(transactionId);
   if (tex == null) return false;
   Transaction tx = TransactionEx.toTransaction(tex);
   _backing.beginTransaction();
   try {
     // See if any of the outputs are stored locally and remove them
     for (int i = 0; i < tx.outputs.length; i++) {
       TransactionOutput output = tx.outputs[i];
       OutPoint outPoint = new OutPoint(tx.getHash(), i);
       TransactionOutputEx utxo = _backing.getUnspentOutput(outPoint);
       if (utxo != null) {
         _backing.deleteUnspentOutput(outPoint);
       }
     }
     // remove it from the backing
     _backing.deleteTransaction(transactionId);
     _backing.setTransactionSuccessful();
   } finally {
     _backing.endTransaction();
   }
   updateLocalBalance(); // will still need a new sync besides re-calculating
   return true;
 }
示例#2
0
  /**
   * Broadcast outgoing transactions.
   *
   * <p>This method should only be called from the wallet manager
   *
   * @return false if synchronization failed due to failed blockchain connection
   */
  public synchronized boolean broadcastOutgoingTransactions() {
    checkNotArchived();
    List<Sha256Hash> broadcastedIds = new LinkedList<Sha256Hash>();
    Map<Sha256Hash, byte[]> transactions = _backing.getOutgoingTransactions();

    for (byte[] rawTransaction : transactions.values()) {
      TransactionEx tex = TransactionEx.fromUnconfirmedTransaction(rawTransaction);

      BroadcastResult result = broadcastTransaction(TransactionEx.toTransaction(tex));
      if (result == BroadcastResult.SUCCESS) {
        broadcastedIds.add(tex.txid);
        _backing.removeOutgoingTransaction(tex.txid);
      } else {
        if (result == BroadcastResult.REJECTED) {
          // invalid tx
          _backing.deleteTransaction(tex.txid);
          _backing.removeOutgoingTransaction(tex.txid);
        } else {
          // No connection --> retry next sync
        }
      }
    }
    if (!broadcastedIds.isEmpty()) {
      onTransactionsBroadcasted(broadcastedIds);
    }
    return true;
  }
示例#3
0
 /**
  * Determine whether a transaction was sent from one of our own addresses.
  *
  * <p>This is a costly operation as we first have to lookup the transaction and then it's funding
  * outputs
  *
  * @param txid the ID of the transaction to investigate
  * @return true if one of the funding outputs were sent from one of our own addresses
  */
 protected boolean isFromMe(Sha256Hash txid) {
   Transaction t = TransactionEx.toTransaction(_backing.getTransaction(txid));
   if (t == null) {
     return false;
   }
   return isFromMe(t);
 }
示例#4
0
  @Override
  public TransactionDetails getTransactionDetails(Sha256Hash txid) {
    // Note that this method is not synchronized, and we might fetch the transaction history while
    // synchronizing
    // accounts. That should be ok as we write to the DB in a sane order.

    TransactionEx tex = _backing.getTransaction(txid);
    Transaction tx = TransactionEx.toTransaction(tex);
    if (tx == null) {
      throw new RuntimeException();
    }

    List<TransactionDetails.Item> inputs = new ArrayList<TransactionDetails.Item>(tx.inputs.length);
    if (tx.isCoinbase()) {
      // We have a coinbase transaction. Create one input with the sum of the outputs as its value,
      // and make the address the null address
      long value = 0;
      for (TransactionOutput out : tx.outputs) {
        value += out.value;
      }
      inputs.add(new TransactionDetails.Item(Address.getNullAddress(_network), value, true));
    } else {
      // Populate the inputs
      for (TransactionInput input : tx.inputs) {
        Sha256Hash parentHash = input.outPoint.hash;
        // Get the parent transaction
        TransactionOutputEx parentOutput = _backing.getParentTransactionOutput(input.outPoint);
        if (parentOutput == null) {
          // We never heard about the parent, skip
          continue;
        }
        // Determine the parent address
        Address parentAddress;
        ScriptOutput parentScript = ScriptOutput.fromScriptBytes(parentOutput.script);
        if (parentScript == null) {
          // Null address means we couldn't figure out the address, strange script
          parentAddress = Address.getNullAddress(_network);
        } else {
          parentAddress = parentScript.getAddress(_network);
        }
        inputs.add(new TransactionDetails.Item(parentAddress, parentOutput.value, false));
      }
    }
    // Populate the outputs
    TransactionDetails.Item[] outputs = new TransactionDetails.Item[tx.outputs.length];
    for (int i = 0; i < tx.outputs.length; i++) {
      Address address = tx.outputs[i].script.getAddress(_network);
      outputs[i] = new TransactionDetails.Item(address, tx.outputs[i].value, false);
    }

    return new TransactionDetails(
        txid, tex.height, tex.time, inputs.toArray(new TransactionDetails.Item[] {}), outputs);
  }