mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 02:05:53 +00:00
Protobuf serialization for Wallet
This commit is contained in:
parent
0e7e583626
commit
6af16c863c
56
pom.xml
56
pom.xml
@ -213,6 +213,54 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile-protoc</id>
|
||||
<phase>generate-sources</phase>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<mkdir dir="${generated.sourceDirectory}" />
|
||||
<path id="proto.path">
|
||||
<fileset dir="src">
|
||||
<include name="**/*.proto" />
|
||||
</fileset>
|
||||
</path>
|
||||
<pathconvert pathsep=" " property="proto.files" refid="proto.path" />
|
||||
<exec executable="protoc" failonerror="true">
|
||||
<arg value="--java_out=${generated.sourceDirectory}" />
|
||||
<arg value="-I${project.basedir}/src" />
|
||||
<arg line="${proto.files}" />
|
||||
</exec>
|
||||
</tasks>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>gen</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@ -260,6 +308,12 @@
|
||||
<artifactId>bcprov-jdk15</artifactId>
|
||||
<version>${bcprov-jdk15.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>${protobuf.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
@ -270,6 +324,8 @@
|
||||
<junit.version>4.8.2</junit.version>
|
||||
<slf4j.version>1.6.2</slf4j.version>
|
||||
<derby.version>10.8.2.2</derby.version>
|
||||
<protobuf.version>2.2.0</protobuf.version>
|
||||
<generated.sourceDirectory>gen</generated.sourceDirectory>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
80
src/bitcoin.proto
Normal file
80
src/bitcoin.proto
Normal file
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<StoredBlock> getAppearsIn() {
|
||||
public Set<StoredBlock> 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<StoredBlock>();
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
/**
|
||||
* Returns the connected input.
|
||||
*/
|
||||
TransactionInput getSpentBy() {
|
||||
public TransactionInput getSpentBy() {
|
||||
return spentBy;
|
||||
}
|
||||
|
||||
|
@ -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<Sha256Hash, Transaction>();
|
||||
eventListeners = new ArrayList<WalletEventListener>();
|
||||
}
|
||||
|
||||
public NetworkParameters getNetworkParameters() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public Iterable<ECKey> 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<WalletTransaction> getWalletTransactions() {
|
||||
Set<WalletTransaction> all = new HashSet<WalletTransaction>();
|
||||
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<WalletTransaction> txs,
|
||||
Pool poolType, Map<Sha256Hash, Transaction> 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<Transaction> 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<Pool> getContainingPools(Transaction tx) {
|
||||
EnumSet<Pool> 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<Sha256Hash, Transaction> pool, Transaction tx) {
|
||||
|
58
src/com/google/bitcoin/core/WalletTransaction.java
Normal file
58
src/com/google/bitcoin/core/WalletTransaction.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
102
src/com/google/bitcoin/store/WalletProtobufSerializer.java
Normal file
102
src/com/google/bitcoin/store/WalletProtobufSerializer.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user