Adds Wallet tests, extracts FooWalletExtension for testing.

This commit is contained in:
Wojciech Langiewicz
2014-11-06 16:10:41 +01:00
committed by Mike Hearn
parent e830ab87b0
commit b279c40801
4 changed files with 170 additions and 38 deletions

View File

@@ -0,0 +1,40 @@
package org.bitcoinj.testing;
import org.bitcoinj.core.Wallet;
import org.bitcoinj.core.WalletExtension;
import java.util.Arrays;
import static com.google.common.base.Preconditions.checkArgument;
public class FooWalletExtension implements WalletExtension {
private final byte[] data = new byte[]{1, 2, 3};
private final boolean isMandatory;
private final String id;
public FooWalletExtension(String id, boolean isMandatory) {
this.isMandatory = isMandatory;
this.id = id;
}
@Override
public String getWalletExtensionID() {
return id;
}
@Override
public boolean isWalletExtensionMandatory() {
return isMandatory;
}
@Override
public byte[] serializeWalletExtension() {
return data;
}
@Override
public void deserializeWalletExtension(Wallet wallet, byte[] data) {
checkArgument(Arrays.equals(this.data, data));
}
}

View File

@@ -0,0 +1,23 @@
package org.bitcoinj.core;
import org.bitcoinj.testing.FooWalletExtension;
import org.bitcoinj.testing.TestWithWallet;
import org.junit.Before;
import org.junit.Test;
public class WalletExtensionsTest extends TestWithWallet {
@Before
@Override
public void setUp() throws Exception {
super.setUp();
}
@Test(expected = java.lang.IllegalStateException.class)
public void duplicateWalletExtensionTest() {
wallet.addExtension(new FooWalletExtension("com.whatever.required", true));
wallet.addExtension(new FooWalletExtension("com.whatever.required", true));
}
}

View File

@@ -1167,6 +1167,22 @@ public class WalletTest extends TestWithWallet {
key2.sign(Sha256Hash.ZERO_HASH);
}
@Test(expected = ECKey.MissingPrivateKeyException.class)
public void watchingWalletWithCreationTime() throws Exception {
DeterministicKey watchKey = wallet.getWatchingKey();
String serialized = watchKey.serializePubB58();
watchKey = DeterministicKey.deserializeB58(null, serialized);
Wallet watchingWallet = Wallet.fromWatchingKey(params, watchKey, 1415282801);
DeterministicKey key2 = watchingWallet.freshReceiveKey();
assertEquals(myKey, key2);
ECKey key = wallet.freshKey(KeyChain.KeyPurpose.CHANGE);
key2 = watchingWallet.freshKey(KeyChain.KeyPurpose.CHANGE);
assertEquals(key, key2);
key.sign(Sha256Hash.ZERO_HASH);
key2.sign(Sha256Hash.ZERO_HASH);
}
@Test
public void watchingScripts() throws Exception {
// Verify that pending transactions to watched addresses are relevant
@@ -1267,6 +1283,15 @@ public class WalletTest extends TestWithWallet {
assertFalse(wallet.isRequiringUpdateAllBloomFilter());
}
@Test
public void removeWatchedAddress() {
Address watchedAddress = new ECKey().toAddress(params);
wallet.addWatchedAddress(watchedAddress);
wallet.removeWatchedAddress(watchedAddress);
assertFalse(wallet.isAddressWatched(watchedAddress));
assertFalse(wallet.isRequiringUpdateAllBloomFilter());
}
@Test
public void removeScriptsBloomFilter() throws Exception {
List<Address> addressesForRemoval = new ArrayList<Address>();
@@ -1464,9 +1489,10 @@ public class WalletTest extends TestWithWallet {
}
@Test
public void encryptionDecryptionBasic() throws Exception {
public void encryptionDecryptionAESBasic() throws Exception {
assertEquals(EncryptionType.ENCRYPTED_SCRYPT_AES, encryptedWallet.getEncryptionType());
assertTrue(encryptedWallet.checkPassword(PASSWORD1));
assertTrue(encryptedWallet.checkAESKey(aesKey));
assertFalse(encryptedWallet.checkPassword(WRONG_PASSWORD));
assertTrue("The keyCrypter is missing but should not be", keyCrypter != null);
encryptedWallet.decrypt(aesKey);
@@ -1480,12 +1506,28 @@ public class WalletTest extends TestWithWallet {
}
}
@Test
public void encryptionDecryptionPasswordBasic() throws Exception {
assertTrue(encryptedWallet.isEncrypted());
encryptedWallet.decrypt(PASSWORD1);
assertFalse(encryptedWallet.isEncrypted());
// Wallet should now be unencrypted.
assertTrue("Wallet is not an unencrypted wallet", encryptedWallet.getKeyCrypter() == null);
try {
encryptedWallet.checkPassword(PASSWORD1);
fail();
} catch (IllegalStateException e) {
}
}
@Test
public void encryptionDecryptionBadPassword() throws Exception {
// Check the wallet is currently encrypted
assertTrue("Wallet is not an encrypted wallet", encryptedWallet.getEncryptionType() == EncryptionType.ENCRYPTED_SCRYPT_AES);
assertFalse(encryptedWallet.checkAESKey(wrongAesKey));
// Chek that the wrong password does not decrypt the wallet.
// Check that the wrong password does not decrypt the wallet.
try {
encryptedWallet.decrypt(wrongAesKey);
fail("Incorrectly decoded wallet with wrong password");
@@ -1703,6 +1745,22 @@ public class WalletTest extends TestWithWallet {
wallet.completeTx(request);
}
@Test
public void sendRequestP2PKTest() {
ECKey key = new ECKey();
Address notMyAddr = key.toAddress(params);
SendRequest req = SendRequest.to(notMyAddr.getParameters(), key, SATOSHI.multiply(12));
assertArrayEquals(key.getPubKey(), req.tx.getOutputs().get(0).getScriptPubKey().getPubKey());
}
@Test
public void sendRequestP2PKHTest() {
ECKey key = new ECKey();
Address notMyAddr = key.toAddress(params);
SendRequest req = SendRequest.to(notMyAddr, SATOSHI.multiply(12));
assertEquals(notMyAddr, req.tx.getOutputs().get(0).getScriptPubKey().getToAddress(params));
}
@Test
public void feeSolverAndCoinSelectionTest() throws Exception {
// Tests basic fee solving works
@@ -2763,6 +2821,30 @@ public class WalletTest extends TestWithWallet {
assertEquals(COIN, wallet.getBalance());
}
@Test
public void transactionInBlockNotification() {
final Transaction tx = createFakeTx(params, COIN, myAddress);
StoredBlock block = createFakeBlock(blockStore, tx).storedBlock;
wallet.receivePending(tx, null);
boolean notification = wallet.notifyTransactionIsInBlock(tx.getHash(), block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
assertTrue(notification);
Address notMyAddr = new ECKey().toAddress(params);
final Transaction tx2 = createFakeTx(params, COIN, notMyAddr);
wallet.receivePending(tx2, null);
StoredBlock block2 = createFakeBlock(blockStore, tx2).storedBlock;
boolean notification2 = wallet.notifyTransactionIsInBlock(tx2.getHash(), block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
assertFalse(notification2);
}
@Test
public void duplicatedBlock() {
final Transaction tx = createFakeTx(params, COIN, myAddress);
StoredBlock block = createFakeBlock(blockStore, tx).storedBlock;
wallet.notifyNewBestBlock(block);
wallet.notifyNewBestBlock(block);
}
@Test
public void keyEvents() throws Exception {
// Check that we can register an event listener, generate some keys and the callbacks are invoked properly.
@@ -2895,4 +2977,23 @@ public class WalletTest extends TestWithWallet {
wallet.completeTx(sendRequest);
assertEquals(sendRequest.memo, sendRequest.tx.getMemo());
}
@Test(expected = java.lang.IllegalStateException.class)
public void sendCoinsNoBroadcasterTest() throws InsufficientMoneyException {
ECKey key = ECKey.fromPrivate(BigInteger.ONE);
Address notMyAddr = key.toAddress(params);
SendRequest req = SendRequest.to(notMyAddr.getParameters(), key, SATOSHI.multiply(12));
wallet.sendCoins(req);
}
@Test
public void sendCoinsWithBroadcasterTest() throws InsufficientMoneyException, IOException {
ECKey key = ECKey.fromPrivate(BigInteger.ONE);
Address notMyAddr = key.toAddress(params);
receiveATransactionAmount(wallet, myAddress, Coin.COIN);
MockTransactionBroadcaster broadcaster = new MockTransactionBroadcaster(wallet);
wallet.setTransactionBroadcaster(broadcaster);
SendRequest req = SendRequest.to(notMyAddr.getParameters(), key, Coin.CENT);
wallet.sendCoins(req);
}
}

View File

@@ -25,11 +25,11 @@ import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.UnitTestParams;
import org.bitcoinj.script.ScriptBuilder;
import org.bitcoinj.testing.FakeTxBuilder;
import org.bitcoinj.testing.FooWalletExtension;
import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.utils.Threading;
import org.bitcoinj.wallet.DeterministicKeyChain;
import org.bitcoinj.wallet.KeyChain;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.ByteString;
import org.bitcoinj.wallet.MarriedKeyChain;
@@ -332,7 +332,7 @@ public class WalletProtobufSerializerTest {
@Test
public void testExtensions() throws Exception {
myWallet.addExtension(new SomeFooExtension("com.whatever.required", true));
myWallet.addExtension(new FooWalletExtension("com.whatever.required", true));
Protos.Wallet proto = new WalletProtobufSerializer().walletToProto(myWallet);
// Initial extension is mandatory: try to read it back into a wallet that doesn't know about it.
try {
@@ -342,13 +342,13 @@ public class WalletProtobufSerializerTest {
assertTrue(e.getMessage().contains("mandatory"));
}
Wallet wallet = new WalletProtobufSerializer().readWallet(params,
new WalletExtension[]{ new SomeFooExtension("com.whatever.required", true) },
new WalletExtension[]{ new FooWalletExtension("com.whatever.required", true) },
proto);
assertTrue(wallet.getExtensions().containsKey("com.whatever.required"));
// Non-mandatory extensions are ignored if the wallet doesn't know how to read them.
Wallet wallet2 = new Wallet(params);
wallet2.addExtension(new SomeFooExtension("com.whatever.optional", false));
wallet2.addExtension(new FooWalletExtension("com.whatever.optional", false));
Protos.Wallet proto2 = new WalletProtobufSerializer().walletToProto(wallet2);
Wallet wallet5 = new WalletProtobufSerializer().readWallet(params, null, proto2);
assertEquals(0, wallet5.getExtensions().size());
@@ -360,36 +360,4 @@ public class WalletProtobufSerializerTest {
proto.setVersion(2);
new WalletProtobufSerializer().readWallet(params, null, proto.build());
}
private static class SomeFooExtension implements WalletExtension {
private final byte[] data = new byte[]{1, 2, 3};
private final boolean isMandatory;
private final String id;
public SomeFooExtension(String id, boolean isMandatory) {
this.isMandatory = isMandatory;
this.id = id;
}
@Override
public String getWalletExtensionID() {
return id;
}
@Override
public boolean isWalletExtensionMandatory() {
return isMandatory;
}
@Override
public byte[] serializeWalletExtension() {
return data;
}
@Override
public void deserializeWalletExtension(Wallet wallet, byte[] data) {
assertArrayEquals(this.data, data);
}
}
}