diff --git a/core/src/main/java/com/google/bitcoin/core/Transaction.java b/core/src/main/java/com/google/bitcoin/core/Transaction.java
index 2c1103cc..116c2ede 100644
--- a/core/src/main/java/com/google/bitcoin/core/Transaction.java
+++ b/core/src/main/java/com/google/bitcoin/core/Transaction.java
@@ -23,6 +23,7 @@ import com.google.bitcoin.script.Script;
import com.google.bitcoin.script.ScriptBuilder;
import com.google.bitcoin.script.ScriptOpCodes;
import com.google.bitcoin.utils.ExchangeRate;
+import com.google.bitcoin.wallet.WalletTransaction.Pool;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
@@ -250,12 +251,12 @@ public class Transaction extends ChildMessage implements Serializable {
* Calculates the sum of the outputs that are sending coins to a key in the wallet. The flag controls whether to
* include spent outputs or not.
*/
- Coin getValueSentToMe(Wallet wallet, boolean includeSpent) {
+ Coin getValueSentToMe(TransactionBag transactionBag, boolean includeSpent) {
maybeParse();
// This is tested in WalletTest.
Coin v = Coin.ZERO;
for (TransactionOutput o : outputs) {
- if (!o.isMineOrWatched(wallet)) continue;
+ if (!o.isMineOrWatched(transactionBag)) continue;
if (!includeSpent && !o.isAvailableForSpending()) continue;
v = v.add(o.getValue());
}
@@ -266,11 +267,11 @@ public class Transaction extends ChildMessage implements Serializable {
* If isSpent - check that all my outputs spent, otherwise check that there at least
* one unspent.
*/
- boolean isConsistent(Wallet wallet, boolean isSpent) {
+ boolean isConsistent(TransactionBag transactionBag, boolean isSpent) {
boolean isActuallySpent = true;
for (TransactionOutput o : outputs) {
if (o.isAvailableForSpending()) {
- if (o.isMineOrWatched(wallet)) isActuallySpent = false;
+ if (o.isMineOrWatched(transactionBag)) isActuallySpent = false;
if (o.getSpentBy() != null) {
log.error("isAvailableForSpending != spentBy");
return false;
@@ -288,8 +289,8 @@ public class Transaction extends ChildMessage implements Serializable {
/**
* Calculates the sum of the outputs that are sending coins to a key in the wallet.
*/
- public Coin getValueSentToMe(Wallet wallet) {
- return getValueSentToMe(wallet, true);
+ public Coin getValueSentToMe(TransactionBag transactionBag) {
+ return getValueSentToMe(transactionBag, true);
}
/**
@@ -354,18 +355,18 @@ public class Transaction extends ChildMessage implements Serializable {
*
* @return sum of the inputs that are spending coins with keys in the wallet
*/
- public Coin getValueSentFromMe(Wallet wallet) throws ScriptException {
+ public Coin getValueSentFromMe(TransactionBag wallet) throws ScriptException {
maybeParse();
// This is tested in WalletTest.
Coin v = Coin.ZERO;
for (TransactionInput input : inputs) {
// This input is taking value from a transaction in our wallet. To discover the value,
// we must find the connected transaction.
- TransactionOutput connected = input.getConnectedOutput(wallet.unspent);
+ TransactionOutput connected = input.getConnectedOutput(wallet.getTransactionPool(Pool.UNSPENT));
if (connected == null)
- connected = input.getConnectedOutput(wallet.spent);
+ connected = input.getConnectedOutput(wallet.getTransactionPool(Pool.SPENT));
if (connected == null)
- connected = input.getConnectedOutput(wallet.pending);
+ connected = input.getConnectedOutput(wallet.getTransactionPool(Pool.PENDING));
if (connected == null)
continue;
// The connected output may be the change to the sender of a previous input sent to this wallet. In this
@@ -378,9 +379,9 @@ public class Transaction extends ChildMessage implements Serializable {
}
/**
- * Returns the difference of {@link Transaction#getValueSentFromMe(Wallet)} and {@link Transaction#getValueSentToMe(Wallet)}.
+ * Returns the difference of {@link Transaction#getValueSentFromMe(TransactionBag)} and {@link Transaction#getValueSentToMe(TransactionBag)}.
*/
- public Coin getValue(Wallet wallet) throws ScriptException {
+ public Coin getValue(TransactionBag wallet) throws ScriptException {
return getValueSentToMe(wallet).subtract(getValueSentFromMe(wallet));
}
@@ -440,10 +441,10 @@ public class Transaction extends ChildMessage implements Serializable {
* Returns false if this transaction has at least one output that is owned by the given wallet and unspent, true
* otherwise.
*/
- public boolean isEveryOwnedOutputSpent(Wallet wallet) {
+ public boolean isEveryOwnedOutputSpent(TransactionBag transactionBag) {
maybeParse();
for (TransactionOutput output : outputs) {
- if (output.isAvailableForSpending() && output.isMineOrWatched(wallet))
+ if (output.isAvailableForSpending() && output.isMineOrWatched(transactionBag))
return false;
}
return true;
@@ -1091,15 +1092,15 @@ public class Transaction extends ChildMessage implements Serializable {
* watched by a wallet, i.e., transaction outputs whose script's address is controlled by the wallet and transaction
* outputs whose script is watched by the wallet.
*
- * @param wallet The wallet that controls addresses and watches scripts.
+ * @param transactionBag The wallet that controls addresses and watches scripts.
* @return linked list of outputs relevant to the wallet in this transaction
*/
- public List getWalletOutputs(Wallet wallet){
+ public List getWalletOutputs(TransactionBag transactionBag){
maybeParse();
List walletOutputs = new LinkedList();
Coin v = Coin.ZERO;
for (TransactionOutput o : outputs) {
- if (!o.isMineOrWatched(wallet)) continue;
+ if (!o.isMineOrWatched(transactionBag)) continue;
walletOutputs.add(o);
}
diff --git a/core/src/main/java/com/google/bitcoin/core/TransactionBag.java b/core/src/main/java/com/google/bitcoin/core/TransactionBag.java
new file mode 100644
index 00000000..7c8fa137
--- /dev/null
+++ b/core/src/main/java/com/google/bitcoin/core/TransactionBag.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright 2014 Giannis Dzegoutanis
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.bitcoin.core;
+
+import com.google.bitcoin.script.Script;
+import com.google.bitcoin.wallet.WalletTransaction;
+
+import java.util.Map;
+
+/**
+ * This interface is used to abstract the {@link com.google.bitcoin.core.Wallet} and the {@link com.google.bitcoin.core.Transaction}
+ */
+public interface TransactionBag {
+ /** Returns true if this wallet contains a public key which hashes to the given hash. */
+ public boolean isPubKeyHashMine(byte[] pubkeyHash);
+
+ /** Returns true if this wallet is watching transactions for outputs with the script. */
+ public boolean isWatchedScript(Script script);
+
+ /** Returns true if this wallet contains a keypair with the given public key. */
+ public boolean isPubKeyMine(byte[] pubkey);
+
+ /** Returns true if this wallet knows the script corresponding to the given hash. */
+ public boolean isPayToScriptHashMine(byte[] payToScriptHash);
+
+ /** Returns transactions from a specific pool. */
+ public Map getTransactionPool(WalletTransaction.Pool pool);
+}
diff --git a/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java b/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java
index 07f8aa3c..39d6a983 100644
--- a/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java
+++ b/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java
@@ -310,17 +310,17 @@ public class TransactionOutput extends ChildMessage implements Serializable {
/**
* Returns true if this output is to a key in the wallet or to an address/script we are watching.
*/
- public boolean isMineOrWatched(Wallet wallet) {
- return isMine(wallet) || isWatched(wallet);
+ public boolean isMineOrWatched(TransactionBag transactionBag) {
+ return isMine(transactionBag) || isWatched(transactionBag);
}
/**
* Returns true if this output is to a key, or an address we have the keys for, in the wallet.
*/
- public boolean isWatched(Wallet wallet) {
+ public boolean isWatched(TransactionBag transactionBag) {
try {
Script script = getScriptPubKey();
- return wallet.isWatchedScript(script);
+ return transactionBag.isWatchedScript(script);
} catch (ScriptException e) {
// Just means we didn't understand the output of this transaction: ignore it.
log.debug("Could not parse tx output script: {}", e.toString());
@@ -331,17 +331,17 @@ public class TransactionOutput extends ChildMessage implements Serializable {
/**
* Returns true if this output is to a key, or an address we have the keys for, in the wallet.
*/
- public boolean isMine(Wallet wallet) {
+ public boolean isMine(TransactionBag transactionBag) {
try {
Script script = getScriptPubKey();
if (script.isSentToRawPubKey()) {
byte[] pubkey = script.getPubKey();
- return wallet.isPubKeyMine(pubkey);
+ return transactionBag.isPubKeyMine(pubkey);
} if (script.isPayToScriptHash()) {
- return wallet.isPayToScriptHashMine(script.getPubKeyHash());
+ return transactionBag.isPayToScriptHashMine(script.getPubKeyHash());
} else {
byte[] pubkeyHash = script.getPubKeyHash();
- return wallet.isPubKeyHashMine(pubkeyHash);
+ return transactionBag.isPubKeyHashMine(pubkeyHash);
}
} catch (ScriptException e) {
// Just means we didn't understand the output of this transaction: ignore it.
diff --git a/core/src/main/java/com/google/bitcoin/core/Wallet.java b/core/src/main/java/com/google/bitcoin/core/Wallet.java
index 84eb5d07..de05febb 100644
--- a/core/src/main/java/com/google/bitcoin/core/Wallet.java
+++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java
@@ -102,7 +102,7 @@ import static com.google.common.base.Preconditions.*;
* {@link Wallet#autosaveToFile(java.io.File, long, java.util.concurrent.TimeUnit, com.google.bitcoin.wallet.WalletFiles.Listener)}
* for more information about this.
*/
-public class Wallet extends BaseTaggableObject implements Serializable, BlockChainListener, PeerFilterProvider, KeyBag {
+public class Wallet extends BaseTaggableObject implements Serializable, BlockChainListener, PeerFilterProvider, KeyBag, TransactionBag {
private static final Logger log = LoggerFactory.getLogger(Wallet.class);
private static final long serialVersionUID = 2L;
private static final int MINIMUM_BLOOM_DATA_LENGTH = 8;
@@ -829,14 +829,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
}
}
- /**
- * Returns true if this wallet contains a public key which hashes to the given hash.
- */
+ /** {@inheritDoc} */
+ @Override
public boolean isPubKeyHashMine(byte[] pubkeyHash) {
return findKeyFromPubHash(pubkeyHash) != null;
}
- /** Returns true if this wallet is watching transactions for outputs with the script. */
+ /** {@inheritDoc} */
+ @Override
public boolean isWatchedScript(Script script) {
lock.lock();
try {
@@ -861,9 +861,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
}
}
- /**
- * Returns true if this wallet contains a keypair with the given public key.
- */
+ /** {@inheritDoc} */
+ @Override
public boolean isPubKeyMine(byte[] pubkey) {
return findKeyFromPubKey(pubkey) != null;
}
@@ -883,9 +882,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
}
}
- /**
- * Returns true if this wallet knows the script corresponding to the given hash
- */
+ /** {@inheritDoc} */
+ @Override
public boolean isPayToScriptHashMine(byte[] payToScriptHash) {
return findRedeemDataFromScriptHash(payToScriptHash) != null;
}
@@ -2356,6 +2354,28 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
}
}
+ /** {@inheritDoc} */
+ @Override
+ public Map getTransactionPool(Pool pool) {
+ lock.lock();
+ try {
+ switch (pool) {
+ case UNSPENT:
+ return unspent;
+ case SPENT:
+ return spent;
+ case PENDING:
+ return pending;
+ case DEAD:
+ return dead;
+ default:
+ throw new RuntimeException("Unknown wallet transaction type " + pool);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
/**
* Deletes transactions which appeared above the given block height from the wallet, but does not touch the keys.
* This is useful if you have some keys and wish to replay the block chain into the wallet in order to pick them up.