diff --git a/pom.xml b/pom.xml
index 320024700..65252472d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -213,6 +213,54 @@
+
+ maven-antrun-plugin
+
+
+ compile-protoc
+ generate-sources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 1.1
+
+
+ add-source
+ generate-sources
+
+ add-source
+
+
+
+ gen
+
+
+
+
+
+
@@ -260,6 +308,12 @@
bcprov-jdk15
${bcprov-jdk15.version}
+
+
+ com.google.protobuf
+ protobuf-java
+ ${protobuf.version}
+
@@ -270,6 +324,8 @@
4.8.2
1.6.2
10.8.2.2
+ 2.2.0
+ gen
diff --git a/src/bitcoin.proto b/src/bitcoin.proto
new file mode 100644
index 000000000..338971d6e
--- /dev/null
+++ b/src/bitcoin.proto
@@ -0,0 +1,80 @@
+/**
+ * Copyright 2012 Google Inc.
+ *
+ * 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.
+ */
+
+/*
+ * Author: Jim Burton
+ */
+
+package wallet;
+
+option java_package = "org.bitcoinj.wallet";
+option java_outer_classname = "Protos";
+
+message Wallet {
+ required string network_identifier = 1; // the network used by this wallet
+ // org.bitcoin.production = production network (Satoshi genesis block)
+ // org.bitcoin.test = test network (Andresen genesis block)
+
+ optional bytes last_seen_block_hash = 2; // the Sha256 hash of the block last seen by this wallet
+
+ message Key {
+ required string private_key = 1; // base58 representation of private key
+ optional string label = 2; // for presentation purposes
+ optional int64 creation_timestamp = 3; // datetime stored as millis since epoch.
+ }
+ repeated Key key = 3;
+
+
+ message Transaction {
+ enum Pool {
+ UNSPENT = 0;
+ SPENT = 1;
+ PENDING = 2;
+ INACTIVE = 3;
+ DEAD = 4;
+ }
+
+ // See com.google.bitcoin.core.Wallet.java for detailed description of pool semantics
+ required Pool pool = 1;
+
+ optional int64 updated_at = 2; // millis since epoch the transaction was last updated
+
+ message TransactionInput {
+ required bytes transaction_out_point_hash = 1;
+ // Sha256Hash of transaction output this input is using
+ required int32 transaction_out_point_index = 2;
+ // index of transaction output used by this input if in this wallet
+
+ required bytes script_bytes = 3; // script of transaction input
+ }
+
+ repeated TransactionInput transaction_input = 3;
+
+ message TransactionOutput {
+ required int64 value = 1;
+ required bytes script_bytes = 2; // script of transaction output
+ optional bytes spent_by_transaction_hash = 3; // if spent, the Sha256Hash of the transaction doing the spend
+ optional int32 spent_by_transaction_index = 4;
+ // if spent, the index of the transaction output of the transaction doing the spend
+ }
+ repeated TransactionOutput transaction_output = 4;
+
+
+ repeated bytes block_hash = 5;
+ // Sha256Hash of block in block chain in which this transaction appears
+ }
+ repeated Transaction transaction = 4;
+} // end of Wallet
diff --git a/src/com/google/bitcoin/core/NetworkParameters.java b/src/com/google/bitcoin/core/NetworkParameters.java
index 434d1a46c..08853f8c3 100644
--- a/src/com/google/bitcoin/core/NetworkParameters.java
+++ b/src/com/google/bitcoin/core/NetworkParameters.java
@@ -78,6 +78,8 @@ public class NetworkParameters implements Serializable {
* signatures using it.
*/
public byte[] alertSigningKey;
+
+ public String id;
private static Block createGenesis(NetworkParameters n) {
Block genesisBlock = new Block(n);
@@ -122,6 +124,7 @@ public class NetworkParameters implements Serializable {
n.genesisBlock.setTime(1296688602L);
n.genesisBlock.setDifficultyTarget(0x1d07fff8L);
n.genesisBlock.setNonce(384568319);
+ n.id = "org.bitcoin.test";
String genesisHash = n.genesisBlock.getHashAsString();
assert genesisHash.equals("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008") : genesisHash;
return n;
@@ -148,6 +151,7 @@ public class NetworkParameters implements Serializable {
n.genesisBlock.setDifficultyTarget(0x1d00ffffL);
n.genesisBlock.setTime(1231006505L);
n.genesisBlock.setNonce(2083236893);
+ n.id = "org.bitcoin.production";
String genesisHash = n.genesisBlock.getHashAsString();
assert genesisHash.equals("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") : genesisHash;
return n;
@@ -162,6 +166,14 @@ public class NetworkParameters implements Serializable {
n.genesisBlock.setDifficultyTarget(Block.EASIEST_DIFFICULTY_TARGET);
n.interval = 10;
n.targetTimespan = 200000000; // 6 years. Just a very big number.
+ n.id = "com.google.bitcoin.unittest";
return n;
}
+
+ /**
+ * A java package style string acting as unique ID for these parameters
+ */
+ public String getId() {
+ return id;
+ }
}
diff --git a/src/com/google/bitcoin/core/Transaction.java b/src/com/google/bitcoin/core/Transaction.java
index 432e25608..6805a7a19 100644
--- a/src/com/google/bitcoin/core/Transaction.java
+++ b/src/com/google/bitcoin/core/Transaction.java
@@ -180,7 +180,7 @@ public class Transaction extends ChildMessage implements Serializable {
* Returns a set of blocks which contain the transaction, or null if this transaction doesn't have that data
* because it's not stored in the wallet or because it has never appeared in a block.
*/
- Set getAppearsIn() {
+ public Set getAppearsIn() {
return appearsIn;
}
@@ -204,6 +204,9 @@ public class Transaction extends ChildMessage implements Serializable {
* @param bestChain whether to set the updatedAt timestamp from the block header (only if not already set)
*/
void setBlockAppearance(StoredBlock block, boolean bestChain) {
+ if (bestChain && updatedAt == null) {
+ updatedAt = new Date(block.getHeader().getTimeSeconds() * 1000);
+ }
if (appearsIn == null) {
appearsIn = new HashSet();
}
diff --git a/src/com/google/bitcoin/core/TransactionOutput.java b/src/com/google/bitcoin/core/TransactionOutput.java
index 2143a95ac..afbe224cf 100644
--- a/src/com/google/bitcoin/core/TransactionOutput.java
+++ b/src/com/google/bitcoin/core/TransactionOutput.java
@@ -205,7 +205,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
/**
* Returns the connected input.
*/
- TransactionInput getSpentBy() {
+ public TransactionInput getSpentBy() {
return spentBy;
}
diff --git a/src/com/google/bitcoin/core/Wallet.java b/src/com/google/bitcoin/core/Wallet.java
index d25735c89..75020caaf 100644
--- a/src/com/google/bitcoin/core/Wallet.java
+++ b/src/com/google/bitcoin/core/Wallet.java
@@ -16,6 +16,8 @@
package com.google.bitcoin.core;
+import com.google.bitcoin.core.WalletTransaction.Pool;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -150,6 +152,14 @@ public class Wallet implements Serializable {
dead = new HashMap();
eventListeners = new ArrayList();
}
+
+ public NetworkParameters getNetworkParameters() {
+ return params;
+ }
+
+ public Iterable getKeys() {
+ return keychain;
+ }
/**
* Uses Java serialization to save the wallet to the given file.
@@ -185,6 +195,12 @@ public class Wallet implements Serializable {
public static Wallet loadFromFile(File f) throws IOException {
return loadFromFileStream(new FileInputStream(f));
}
+
+ private void checkInvariants() {
+ if (getTransactions(true, true).size() !=
+ unspent.size() + spent.size() + pending.size() + dead.size() + inactive.size())
+ throw new RuntimeException("Invariant broken - a tx appears in more than one pool");
+ }
/**
* Returns a wallet deserialized from the given file input stream.
@@ -429,6 +445,8 @@ public class Wallet implements Serializable {
if (!reorg && bestChain && valueDifference.compareTo(BigInteger.ZERO) > 0 && wtx == null) {
invokeOnCoinsReceived(tx, prevBalance, getBalance());
}
+
+ checkInvariants();
}
/**
@@ -604,6 +622,8 @@ public class Wallet implements Serializable {
// Add to the pending pool. It'll be moved out once we receive this transaction on the best chain.
log.info("->pending: {}", tx.getHashAsString());
pending.put(tx.getHash(), tx);
+
+ checkInvariants();
}
/**
@@ -624,6 +644,48 @@ public class Wallet implements Serializable {
return all;
}
+ /**
+ * Returns a set of all WalletTransactions in the wallet.
+ */
+ public Iterable getWalletTransactions() {
+ Set all = new HashSet();
+ addWalletTransactionsToSet(all, Pool.UNSPENT, unspent);
+ addWalletTransactionsToSet(all, Pool.SPENT, spent);
+ addWalletTransactionsToSet(all, Pool.PENDING, pending);
+ addWalletTransactionsToSet(all, Pool.DEAD, dead);
+ addWalletTransactionsToSet(all, Pool.INACTIVE, inactive);
+ return all;
+ }
+
+ static private void addWalletTransactionsToSet(Set txs,
+ Pool poolType, Map pool) {
+ for (Transaction tx : pool.values()) {
+ txs.add(new WalletTransaction(poolType, tx));
+ }
+ }
+
+ public void addWalletTransaction(WalletTransaction wtx) {
+ switch (wtx.getPool()) {
+ case UNSPENT:
+ unspent.put(wtx.getTransaction().getHash(), wtx.getTransaction());
+ break;
+ case SPENT:
+ spent.put(wtx.getTransaction().getHash(), wtx.getTransaction());
+ break;
+ case PENDING:
+ pending.put(wtx.getTransaction().getHash(), wtx.getTransaction());
+ break;
+ case DEAD:
+ dead.put(wtx.getTransaction().getHash(), wtx.getTransaction());
+ break;
+ case INACTIVE:
+ inactive.put(wtx.getTransaction().getHash(), wtx.getTransaction());
+ break;
+ default:
+ throw new RuntimeException("Unknown wallet transaction type " + wtx.getPool());
+ }
+ }
+
/**
* Returns all non-dead, active transactions ordered by recency.
*/
@@ -642,7 +704,9 @@ public class Wallet implements Serializable {
public List getRecentTransactions(int numTransactions, boolean includeDead) {
assert numTransactions >= 0;
// Firstly, put all transactions into an array.
- int size = getPoolSize(Pool.UNSPENT) + getPoolSize(Pool.SPENT) + getPoolSize(Pool.PENDING);
+ int size = getPoolSize(WalletTransaction.Pool.UNSPENT) +
+ getPoolSize(WalletTransaction.Pool.SPENT) +
+ getPoolSize(WalletTransaction.Pool.PENDING);
if (numTransactions > size || numTransactions == 0) {
numTransactions = size;
}
@@ -695,16 +759,6 @@ public class Wallet implements Serializable {
}
}
- // This is used only for unit testing, it's an internal API.
- enum Pool {
- UNSPENT,
- SPENT,
- PENDING,
- INACTIVE,
- DEAD,
- ALL,
- }
-
EnumSet getContainingPools(Transaction tx) {
EnumSet result = EnumSet.noneOf(Pool.class);
Sha256Hash txHash = tx.getHash();
@@ -726,7 +780,7 @@ public class Wallet implements Serializable {
return result;
}
- int getPoolSize(Pool pool) {
+ int getPoolSize(WalletTransaction.Pool pool) {
switch (pool) {
case UNSPENT:
return unspent.size();
@@ -1218,6 +1272,8 @@ public class Wallet implements Serializable {
l.onReorganize(this);
}
}
+
+ checkInvariants();
}
private void reprocessTxAfterReorg(Map pool, Transaction tx) {
diff --git a/src/com/google/bitcoin/core/WalletTransaction.java b/src/com/google/bitcoin/core/WalletTransaction.java
new file mode 100644
index 000000000..ddf53a837
--- /dev/null
+++ b/src/com/google/bitcoin/core/WalletTransaction.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2012 Google Inc.
+ *
+ * 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;
+
+/**
+ * A Transaction in a Wallet - includes the pool ID
+ *
+ * @author Miron Cuperman
+ */
+public class WalletTransaction {
+ public enum Pool {
+ UNSPENT(0),
+ SPENT(1),
+ PENDING(2),
+ INACTIVE(3),
+ DEAD(4),
+ ALL(-1);
+
+ private int value;
+ Pool(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+ private Transaction transaction;
+ private Pool pool;
+
+ public WalletTransaction(Pool pool, Transaction transaction) {
+ this.pool = pool;
+ this.transaction = transaction;
+ }
+
+ public Transaction getTransaction() {
+ return transaction;
+ }
+
+ public Pool getPool() {
+ return pool;
+ }
+}
+
diff --git a/src/com/google/bitcoin/store/WalletProtobufSerializer.java b/src/com/google/bitcoin/store/WalletProtobufSerializer.java
new file mode 100644
index 000000000..41657d5c6
--- /dev/null
+++ b/src/com/google/bitcoin/store/WalletProtobufSerializer.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright 2012 Google Inc.
+ *
+ * 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.store;
+
+import com.google.bitcoin.core.ECKey;
+import com.google.bitcoin.core.StoredBlock;
+import com.google.bitcoin.core.Transaction;
+import com.google.bitcoin.core.TransactionInput;
+import com.google.bitcoin.core.TransactionOutput;
+import com.google.bitcoin.core.Wallet;
+import com.google.bitcoin.core.WalletTransaction;
+import com.google.protobuf.ByteString;
+
+import org.bitcoinj.wallet.Protos;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Serialize and de-serialize a wallet to a protobuf stream.
+ *
+ * @author Miron Cuperman
+ */
+public class WalletProtobufSerializer {
+ void writeWallet(Wallet wallet, OutputStream output) throws IOException {
+ Protos.Wallet.Builder walletBuilder = Protos.Wallet.newBuilder();
+ walletBuilder
+ .setNetworkIdentifier(wallet.getNetworkParameters().getId())
+ .setLastSeenBlockHash(null) // TODO
+ ;
+ for (WalletTransaction wtx : wallet.getWalletTransactions()) {
+ Protos.Wallet.Transaction txProto = makeTxProto(wtx);
+ walletBuilder.addTransaction(txProto);
+ }
+
+ for (ECKey key : wallet.getKeys()) {
+ final String base58PrivateKey =
+ key.getPrivateKeyEncoded(wallet.getNetworkParameters()).toString();
+ walletBuilder.addKey(
+ Protos.Wallet.Key.newBuilder()
+ // .setCreationTimestamp() TODO
+ // .setLabel() TODO
+ .setPrivateKey(base58PrivateKey));
+ }
+
+ walletBuilder.build().writeTo(output);
+ }
+
+ private Protos.Wallet.Transaction makeTxProto(WalletTransaction wtx) {
+ Transaction tx = wtx.getTransaction();
+ Protos.Wallet.Transaction.Builder txBuilder = Protos.Wallet.Transaction.newBuilder();
+
+ txBuilder
+ .setUpdatedAt(tx.getUpdateTime().getTime())
+ .setPool(Protos.Wallet.Transaction.Pool.valueOf(wtx.getPool().getValue()));
+
+ // Handle inputs
+ for (TransactionInput input : tx.getInputs()) {
+ txBuilder.addTransactionInput(
+ Protos.Wallet.Transaction.TransactionInput.newBuilder()
+ .setScriptBytes(ByteString.copyFrom(input.getScriptBytes()))
+ .setTransactionOutPointHash(ByteString.copyFrom(
+ input.getOutpoint().getHash().getBytes()))
+ .setTransactionOutPointIndex((int)input.getOutpoint().getIndex()) // FIXME
+ );
+ }
+
+ // Handle outputs
+ for (TransactionOutput output : tx.getOutputs()) {
+ final TransactionInput spentBy = output.getSpentBy();
+ txBuilder.addTransactionOutput(
+ Protos.Wallet.Transaction.TransactionOutput.newBuilder()
+ .setScriptBytes(ByteString.copyFrom(output.getScriptBytes()))
+ .setSpentByTransactionHash(ByteString.copyFrom(
+ spentBy.getHash().getBytes()))
+ .setSpentByTransactionIndex((int)spentBy.getOutpoint().getIndex()) // FIXME
+ .setValue(output.getValue().longValue())
+ );
+ }
+
+ // Handle which blocks tx was seen in
+ for (StoredBlock block : tx.getAppearsIn()) {
+ txBuilder.addBlockHash(ByteString.copyFrom(block.getHeader().getHash().getBytes()));
+ }
+
+ return txBuilder.build();
+ }
+}
diff --git a/tests/com/google/bitcoin/core/WalletTest.java b/tests/com/google/bitcoin/core/WalletTest.java
index 88e207a26..cc7255732 100644
--- a/tests/com/google/bitcoin/core/WalletTest.java
+++ b/tests/com/google/bitcoin/core/WalletTest.java
@@ -61,14 +61,14 @@ public class WalletTest {
wallet.receiveFromBlock(t1, null, BlockChain.NewBlockType.BEST_CHAIN);
assertEquals(v1, wallet.getBalance());
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.UNSPENT));
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
ECKey k2 = new ECKey();
BigInteger v2 = toNanoCoins(0, 50);
Transaction t2 = wallet.createSend(k2.toAddress(params), v2);
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.UNSPENT));
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
// Do some basic sanity checks.
assertEquals(1, t2.getInputs().size());
@@ -77,9 +77,9 @@ public class WalletTest {
// We have NOT proven that the signature is correct!
wallet.commitTx(t2);
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.PENDING));
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.SPENT));
- assertEquals(2, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.SPENT));
+ assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.ALL));
}
@Test
@@ -90,14 +90,14 @@ public class WalletTest {
wallet.receiveFromBlock(t1, null, BlockChain.NewBlockType.BEST_CHAIN);
assertEquals(v1, wallet.getBalance());
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.UNSPENT));
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
BigInteger v2 = toNanoCoins(0, 50);
Transaction t2 = createFakeTx(params, v2, myAddress);
wallet.receiveFromBlock(t2, null, BlockChain.NewBlockType.SIDE_CHAIN);
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.INACTIVE));
- assertEquals(2, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.INACTIVE));
+ assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.ALL));
assertEquals(v1, wallet.getBalance());
}
@@ -107,6 +107,7 @@ public class WalletTest {
final Transaction fakeTx = createFakeTx(params, Utils.toNanoCoins(1, 0), myAddress);
final boolean[] didRun = new boolean[1];
WalletEventListener listener = new AbstractWalletEventListener() {
+ @Override
public void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
assertTrue(prevBalance.equals(BigInteger.ZERO));
assertTrue(newBalance.equals(Utils.toNanoCoins(1, 0)));
@@ -130,18 +131,18 @@ public class WalletTest {
StoredBlock b1 = createFakeBlock(params, blockStore, t1).storedBlock;
StoredBlock b2 = createFakeBlock(params, blockStore, t2).storedBlock;
BigInteger expected = toNanoCoins(5, 50);
- assertEquals(0, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.ALL));
wallet.receiveFromBlock(t1, b1, BlockChain.NewBlockType.BEST_CHAIN);
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.UNSPENT));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
wallet.receiveFromBlock(t2, b2, BlockChain.NewBlockType.BEST_CHAIN);
- assertEquals(2, wallet.getPoolSize(Wallet.Pool.UNSPENT));
+ assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
assertEquals(expected, wallet.getBalance());
// Now spend one coin.
BigInteger v3 = toNanoCoins(1, 0);
Transaction spend = wallet.createSend(new ECKey().toAddress(params), v3);
wallet.commitTx(spend);
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.PENDING));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
// Available and estimated balances should not be the same. We don't check the exact available balance here
// because it depends on the coin selection algorithm.
@@ -229,8 +230,8 @@ public class WalletTest {
wallet.receiveFromBlock(inbound1, null, BlockChain.NewBlockType.BEST_CHAIN);
// Send half to some other guy. Sending only half then waiting for a confirm is important to ensure the tx is
// in the unspent pool, not pending or spent.
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.UNSPENT));
- assertEquals(1, wallet.getPoolSize(Wallet.Pool.ALL));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
+ assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
Address someOtherGuy = new ECKey().toAddress(params);
Transaction outbound1 = wallet.createSend(someOtherGuy, coinHalf);
wallet.commitTx(outbound1);