@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; }
@Override public synchronized boolean cancelQueuedTransaction(Sha256Hash transaction) { Map<Sha256Hash, byte[]> outgoingTransactions = _backing.getOutgoingTransactions(); if (!outgoingTransactions.containsKey(transaction)) { return false; } Transaction tx; try { tx = Transaction.fromBytes(outgoingTransactions.get(transaction)); } catch (TransactionParsingException e) { return false; } _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 a queued transaction from our outgoing buffer _backing.removeOutgoingTransaction(transaction); // remove it from the backing _backing.deleteTransaction(transaction); _backing.setTransactionSuccessful(); } finally { _backing.endTransaction(); } // calc the new balance to remove the outgoing amount // the total balance will still be wrong, as we already deleted some UTXOs to build the queued // transaction // these will get restored after the next sync updateLocalBalance(); // markTransactionAsSpent(transaction); return true; }
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(); }