diff --git a/core/src/main/java/org/bitcoinj/wallet/DefaultKeyChainFactory.java b/core/src/main/java/org/bitcoinj/wallet/DefaultKeyChainFactory.java index c258e417..af2fdd4a 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DefaultKeyChainFactory.java +++ b/core/src/main/java/org/bitcoinj/wallet/DefaultKeyChainFactory.java @@ -41,8 +41,10 @@ public class DefaultKeyChainFactory implements KeyChainFactory { DeterministicKeyChain chain; if (isMarried) chain = new MarriedKeyChain(accountKey); + else if (isFollowingKey) + chain = DeterministicKeyChain.builder().watchAndFollow(accountKey).build(); else - chain = new DeterministicKeyChain(accountKey, isFollowingKey); + chain = DeterministicKeyChain.builder().watch(accountKey).build(); return chain; } @@ -53,7 +55,7 @@ public class DefaultKeyChainFactory implements KeyChainFactory { if (isMarried) chain = new MarriedKeyChain(accountKey); else - chain = DeterministicKeyChain.spend(accountKey); + chain = DeterministicKeyChain.builder().spend(accountKey).build(); return chain; } } diff --git a/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java index 0debf8f7..87944f4a 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java @@ -65,7 +65,7 @@ import static com.google.common.collect.Lists.newLinkedList; * sufficient information about the account key to create a watching chain via * {@link DeterministicKey#deserializeB58(DeterministicKey, String, NetworkParameters)} * (with null as the first parameter) and then - * {@link DeterministicKeyChain#DeterministicKeyChain(DeterministicKey)}.

+ * {@link Builder#watch(DeterministicKey)}.

* *

This class builds on {@link DeterministicHierarchy} and * {@link DeterministicKey} by adding support for serialization to and from protobufs, @@ -164,10 +164,12 @@ public class DeterministicKeyChain implements EncryptableKeyChain { protected SecureRandom random; protected int bits = DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS; protected String passphrase; - protected long creationTimeSecs; + protected long creationTimeSecs = 0; protected byte[] entropy; protected DeterministicSeed seed; protected DeterministicKey watchingKey = null; + protected boolean isFollowing = false; + protected DeterministicKey spendingKey = null; protected ImmutableList accountPath = null; protected Builder() { @@ -222,9 +224,34 @@ public class DeterministicKeyChain implements EncryptableKeyChain { return self(); } - public T watchingKey(DeterministicKey watchingKey) { - checkState(accountPath == null, "either watchingKey or accountPath"); - this.watchingKey = watchingKey; + /** + * Creates a key chain that watches the given account key. + */ + public T watch(DeterministicKey accountKey) { + checkState(accountPath == null, "either watch or accountPath"); + this.watchingKey = accountKey; + this.isFollowing = false; + return self(); + } + + /** + * Creates a deterministic key chain with the given watch key and that follows some other keychain. In a married + * wallet following keychain represents "spouse". Watch key has to be an account key. + */ + public T watchAndFollow(DeterministicKey accountKey) { + checkState(accountPath == null, "either watchAndFollow or accountPath"); + this.watchingKey = accountKey; + this.isFollowing = true; + return self(); + } + + /** + * Creates a key chain that can spend from the given account key. + */ + public T spend(DeterministicKey accountKey) { + checkState(accountPath == null, "either spend or accountPath"); + this.spendingKey = accountKey; + this.isFollowing = false; return self(); } @@ -239,7 +266,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { * Use an account path other than the default {@link DeterministicKeyChain#ACCOUNT_ZERO_PATH}. */ public T accountPath(ImmutableList accountPath) { - checkState(watchingKey == null, "either watchingKey or accountPath"); + checkState(watchingKey == null, "either watch or accountPath"); this.accountPath = accountPath; return self(); } @@ -260,7 +287,9 @@ public class DeterministicKeyChain implements EncryptableKeyChain { else if (seed != null) return new DeterministicKeyChain(seed, null, accountPath); else if (watchingKey != null) - return new DeterministicKeyChain(watchingKey); + return new DeterministicKeyChain(watchingKey, isFollowing, true); + else if (spendingKey != null) + return new DeterministicKeyChain(spendingKey, false, false); else throw new IllegalStateException(); } @@ -275,77 +304,19 @@ public class DeterministicKeyChain implements EncryptableKeyChain { } /** - * Generates a new key chain with entropy selected randomly from the given {@link SecureRandom} - * object and the default entropy size. - */ - public DeterministicKeyChain(SecureRandom random) { - this(random, DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS, DEFAULT_PASSPHRASE_FOR_MNEMONIC); - } - - /** - * Generates a new key chain with entropy selected randomly from the given {@link SecureRandom} - * object and of the requested size in bits. - */ - public DeterministicKeyChain(SecureRandom random, int bits) { - this(random, bits, DEFAULT_PASSPHRASE_FOR_MNEMONIC); - } - - /** - * Generates a new key chain with entropy selected randomly from the given {@link SecureRandom} - * object and of the requested size in bits. The derived seed is further protected with a user selected passphrase - * (see BIP 39). - */ - public DeterministicKeyChain(SecureRandom random, int bits, String passphrase) { - this(new DeterministicSeed(random, bits, passphrase)); - } - - /** - * Creates a deterministic key chain starting from the given entropy. All keys yielded by this chain will be the same - * if the starting seed is the same. You should provide the creation time in seconds since the UNIX epoch for the - * seed: this lets us know from what part of the chain we can expect to see derived keys appear. - */ - public DeterministicKeyChain(byte[] entropy, String passphrase, long seedCreationTimeSecs) { - this(new DeterministicSeed(entropy, passphrase, seedCreationTimeSecs)); - } - - /** - * Creates a deterministic key chain starting from the given seed. All keys yielded by this chain will be the same - * if the starting seed is the same. - */ - protected DeterministicKeyChain(DeterministicSeed seed) { - this(seed, null, ACCOUNT_ZERO_PATH); - } - - /** - * Creates a deterministic key chain starting from the given seed. This deterministic Key chain - * will follow the account path defined. - */ - public DeterministicKeyChain(DeterministicSeed seed, ImmutableList accountPath) { - this(seed, null, accountPath); - } - - /** - * Creates a deterministic key chain that watches the given (public only) root key. You can use this to calculate - * balances and generally follow along, but spending is not possible with such a chain. - */ - public DeterministicKeyChain(DeterministicKey watchingKey) { - checkArgument(watchingKey.isPubKeyOnly(), "Private subtrees not currently supported: if you got this key from DKC.getWatchingKey() then use .dropPrivate().dropParent() on it first."); - this.accountPath = watchingKey.getPath(); - basicKeyChain = new BasicKeyChain(); - this.seed = null; - this.rootKey = null; - basicKeyChain.importKey(watchingKey); - hierarchy = new DeterministicHierarchy(watchingKey); - initializeHierarchyUnencrypted(watchingKey); - } - - /** - * Creates a deterministic key chain from a watched or spendable account key. If {@code isWatching} flag is set, - * then creates a deterministic key chain that watches the given (public only) root key. You can use this to calculate - * balances and generally follow along, but spending is not possible with such a chain. If it is not set, then this - * creates a deterministic key chain that allows spending. If {@code isFollowing} flag is set(only allowed - * if {@code isWatching} is set) then this keychain follows some other keychain. In a married wallet following + *

+ * Creates a deterministic key chain from a watched or spendable account key. If {@code isWatching} flag is set, + * then creates a deterministic key chain that watches the given (public only) root key. You can use this to + * calculate balances and generally follow along, but spending is not possible with such a chain. If it is not set, + * then this creates a deterministic key chain that allows spending. If {@code isFollowing} flag is set(only allowed + * if {@code isWatching} is set) then this keychain follows some other keychain. In a married wallet following * keychain represents "spouse's" keychain. + *

+ * + *

+ * This constructor is not stable across releases! If you need a stable API, use {@link #builder()} to use a + * {@link Builder}. + *

*/ public DeterministicKeyChain(DeterministicKey key, boolean isFollowing, boolean isWatching) { if (isWatching) @@ -365,48 +336,15 @@ public class DeterministicKeyChain implements EncryptableKeyChain { } /** - *

Creates a deterministic key chain with the given watch key. If {@code isFollowing} flag is set then this keychain follows - * some other keychain. In a married wallet following keychain represents "spouse's" keychain.

- *

Watch key has to be an account key.

- */ - protected DeterministicKeyChain(DeterministicKey watchKey, boolean isFollowing) { - this(watchKey); - this.isFollowing = isFollowing; - } - - /** - * Creates a deterministic key chain with the given watch key and that follows some other keychain. In a married - * wallet following keychain represents "spouse" - * Watch key has to be an account key. - */ - public static DeterministicKeyChain watchAndFollow(DeterministicKey watchKey) { - return new DeterministicKeyChain(watchKey, true); - } - - /** - * Creates a key chain that watches the given account key. - */ - public static DeterministicKeyChain watch(DeterministicKey accountKey) { - return new DeterministicKeyChain(accountKey); - } - - /** - * Creates a key chain that can spend from the given account key. - */ - public static DeterministicKeyChain spend(DeterministicKey accountKey) { - return new DeterministicKeyChain(accountKey, false, false); - } - - /** - * For use in {@link KeyChainFactory} during deserialization. - */ - protected DeterministicKeyChain(DeterministicSeed seed, @Nullable KeyCrypter crypter) { - this(seed, crypter, ACCOUNT_ZERO_PATH); - } - - /** - * Creates a deterministic key chain with an encrypted deterministic seed using the provided account path. - * Using {@link KeyCrypter KeyCrypter} to decrypt. + *

+ * Creates a deterministic key chain with an encrypted deterministic seed using the provided account path. Using + * {@link KeyCrypter KeyCrypter} to decrypt. + *

+ * + *

+ * This constructor is not stable across releases! If you need a stable API, use {@link #builder()} to use a + * {@link Builder}. + *

*/ protected DeterministicKeyChain(DeterministicSeed seed, @Nullable KeyCrypter crypter, ImmutableList accountPath) { @@ -676,7 +614,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { *

An alias for {@code getKeyByPath(getAccountPath())}.

* *

Use this when you would like to create a watching key chain that follows this one, but can't spend money from it. - * The returned key can be serialized and then passed into {@link #watch(DeterministicKey)} + * The returned key can be serialized and then passed into {@link Builder#watch(DeterministicKey)} * on another system to watch the hierarchy.

* *

Note that the returned key is not pubkey only unless this key chain already is: the returned key can still @@ -1077,7 +1015,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { * This is used in encryption/decryption. */ protected DeterministicKeyChain makeKeyChainFromSeed(DeterministicSeed seed, ImmutableList accountPath) { - return new DeterministicKeyChain(seed, accountPath); + return new DeterministicKeyChain(seed, null, accountPath); } @Override diff --git a/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java b/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java index df2a8a2b..d439d483 100644 --- a/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java +++ b/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java @@ -88,7 +88,7 @@ public class KeyChainGroup implements KeyBag { /** Creates a keychain group with no basic chain, and an HD chain initialized from the given seed. */ public KeyChainGroup(NetworkParameters params, DeterministicSeed seed) { - this(params, null, ImmutableList.of(new DeterministicKeyChain(seed)), null, null); + this(params, null, ImmutableList.of(DeterministicKeyChain.builder().seed(seed).build()), null, null); } /** @@ -96,7 +96,9 @@ public class KeyChainGroup implements KeyBag { * provided. */ public KeyChainGroup(NetworkParameters params, DeterministicSeed seed, ImmutableList accountPath) { - this(params, null, ImmutableList.of(new DeterministicKeyChain(seed, accountPath)), null, null); + this(params, null, + ImmutableList.of(DeterministicKeyChain.builder().seed(seed).accountPath(accountPath).build()), null, + null); } /** @@ -104,7 +106,7 @@ public class KeyChainGroup implements KeyBag { * This HAS to be an account key as returned by {@link DeterministicKeyChain#getWatchingKey()}. */ public KeyChainGroup(NetworkParameters params, DeterministicKey watchKey) { - this(params, null, ImmutableList.of(DeterministicKeyChain.watch(watchKey)), null, null); + this(params, null, ImmutableList.of(DeterministicKeyChain.builder().watch(watchKey).build()), null, null); } /** @@ -112,7 +114,8 @@ public class KeyChainGroup implements KeyBag { * This HAS to be an account key as returned by {@link DeterministicKeyChain#getWatchingKey()}. */ public KeyChainGroup(NetworkParameters params, DeterministicKey accountKey, boolean watch) { - this(params, null, ImmutableList.of(watch ? DeterministicKeyChain.watch(accountKey) : DeterministicKeyChain.spend(accountKey)), null, null); + this(params, null, ImmutableList.of(watch ? DeterministicKeyChain.builder().watch(accountKey).build() + : DeterministicKeyChain.builder().spend(accountKey).build()), null, null); } private KeyChainGroup(NetworkParameters params, @Nullable BasicKeyChain basicKeyChain, List chains, @@ -145,7 +148,7 @@ public class KeyChainGroup implements KeyBag { /** Adds a new HD chain to the chains list, and make it the default chain (from which keys are issued). */ public void createAndActivateNewHDChain() { // We can't do auto upgrade here because we don't know the rotation time, if any. - final DeterministicKeyChain chain = new DeterministicKeyChain(new SecureRandom()); + final DeterministicKeyChain chain = DeterministicKeyChain.builder().random(new SecureRandom()).build(); addAndActivateHDChain(chain); } @@ -752,7 +755,8 @@ public class KeyChainGroup implements KeyBag { entropy = Arrays.copyOfRange(entropy, 0, DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8); // final argument is exclusive range. checkState(entropy.length == DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8); String passphrase = ""; // FIXME allow non-empty passphrase - DeterministicKeyChain chain = new DeterministicKeyChain(entropy, passphrase, keyToUse.getCreationTimeSeconds()); + DeterministicKeyChain chain = DeterministicKeyChain.builder() + .entropy(entropy, keyToUse.getCreationTimeSeconds()).passphrase(passphrase).build(); if (aesKey != null) { chain = chain.toEncrypted(checkNotNull(basic.getKeyCrypter()), aesKey); } diff --git a/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java index 5cd7eda0..d5edca33 100644 --- a/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java @@ -31,7 +31,6 @@ import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptBuilder; import org.bouncycastle.crypto.params.KeyParameter; -import java.security.SecureRandom; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -122,28 +121,22 @@ public class MarriedKeyChain extends DeterministicKeyChain { return new Builder(); } - // Protobuf deserialization constructors - MarriedKeyChain(DeterministicKey accountKey) { - super(accountKey, false); + /** + * This constructor is not stable across releases! If you need a stable API, use {@link #builder()} to use a + * {@link Builder}. + */ + protected MarriedKeyChain(DeterministicKey accountKey) { + super(accountKey, false, true); } + /** + * This constructor is not stable across releases! If you need a stable API, use {@link #builder()} to use a + * {@link Builder}. + */ protected MarriedKeyChain(DeterministicSeed seed, KeyCrypter crypter, ImmutableList accountPath) { super(seed, crypter, accountPath); } - // Builder constructors - private MarriedKeyChain(SecureRandom random, int bits, String passphrase) { - super(random, bits, passphrase); - } - - private MarriedKeyChain(byte[] entropy, String passphrase, long seedCreationTimeSecs) { - super(entropy, passphrase, seedCreationTimeSecs); - } - - private MarriedKeyChain(DeterministicSeed seed) { - super(seed); - } - void setFollowingKeyChains(List followingKeyChains) { checkArgument(!followingKeyChains.isEmpty()); this.followingKeyChains = followingKeyChains; @@ -196,7 +189,7 @@ public class MarriedKeyChain extends DeterministicKeyChain { for (DeterministicKey key : followingAccountKeys) { checkArgument(key.getPath().size() == getAccountPath().size(), "Following keys have to be account keys"); - DeterministicKeyChain chain = DeterministicKeyChain.watchAndFollow(key); + DeterministicKeyChain chain = DeterministicKeyChain.builder().watchAndFollow(key).build(); if (lookaheadSize >= 0) chain.setLookaheadSize(lookaheadSize); if (lookaheadThreshold >= 0) diff --git a/core/src/test/java/org/bitcoinj/store/WalletProtobufSerializerTest.java b/core/src/test/java/org/bitcoinj/store/WalletProtobufSerializerTest.java index e5ded93d..f912f0e9 100644 --- a/core/src/test/java/org/bitcoinj/store/WalletProtobufSerializerTest.java +++ b/core/src/test/java/org/bitcoinj/store/WalletProtobufSerializerTest.java @@ -362,7 +362,7 @@ public class WalletProtobufSerializerTest { public void testRoundTripMarriedWallet() throws Exception { // create 2-of-2 married wallet myWallet = new Wallet(UNITTEST); - final DeterministicKeyChain partnerChain = new DeterministicKeyChain(new SecureRandom()); + final DeterministicKeyChain partnerChain = DeterministicKeyChain.builder().random(new SecureRandom()).build(); DeterministicKey partnerKey = DeterministicKey.deserializeB58(null, partnerChain.getWatchingKey().serializePubB58(UNITTEST), UNITTEST); MarriedKeyChain chain = MarriedKeyChain.builder() .random(new SecureRandom()) diff --git a/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java b/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java index 2ee4367e..54476ec4 100644 --- a/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java @@ -63,11 +63,11 @@ public class DeterministicKeyChainTest { // You should use a random seed instead. The secs constant comes from the unit test file, so we can compare // serialized data properly. long secs = 1389353062L; - chain = new DeterministicKeyChain(ENTROPY, "", secs); + chain = DeterministicKeyChain.builder().entropy(ENTROPY, secs).build(); chain.setLookaheadSize(10); assertEquals(secs, checkNotNull(chain.getSeed()).getCreationTimeSeconds()); - bip44chain = new DeterministicKeyChain(new DeterministicSeed(ENTROPY, "", secs), BIP44_ACCOUNT_ONE_PATH); + bip44chain = DeterministicKeyChain.builder().entropy(ENTROPY, secs).accountPath(BIP44_ACCOUNT_ONE_PATH).build(); bip44chain.setLookaheadSize(10); assertEquals(secs, checkNotNull(bip44chain.getSeed()).getCreationTimeSeconds()); } @@ -167,7 +167,7 @@ public class DeterministicKeyChainTest { // Check that we get the right events at the right time. final List> listenerKeys = Lists.newArrayList(); long secs = 1389353062L; - chain = new DeterministicKeyChain(ENTROPY, "", secs); + chain = DeterministicKeyChain.builder().entropy(ENTROPY, secs).build(); chain.addEventListener(new AbstractKeyChainEventListener() { @Override public void onKeysAdded(List keys) { @@ -203,7 +203,7 @@ public class DeterministicKeyChainTest { public void random() { // Can't test much here but verify the constructor worked and the class is functional. The other tests rely on // a fixed seed to be deterministic. - chain = new DeterministicKeyChain(new SecureRandom(), 384); + chain = DeterministicKeyChain.builder().random(new SecureRandom(), 384).build(); chain.setLookaheadSize(10); chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS).sign(Sha256Hash.ZERO_HASH); chain.getKey(KeyChain.KeyPurpose.CHANGE).sign(Sha256Hash.ZERO_HASH); @@ -358,7 +358,7 @@ public class DeterministicKeyChainTest { assertEquals("xpub69KR9epSNBM59KLuasxMU5CyKytMJjBP5HEZ5p8YoGUCpM6cM9hqxB9DDPCpUUtqmw5duTckvPfwpoWGQUFPmRLpxs5jYiTf2u6xRMcdhDf", pub58); watchingKey = DeterministicKey.deserializeB58(null, pub58, MAINNET); watchingKey.setCreationTimeSeconds(100000); - chain = DeterministicKeyChain.watch(watchingKey); + chain = DeterministicKeyChain.builder().watch(watchingKey).build(); assertEquals(100000, chain.getEarliestKeyCreationTime()); chain.setLookaheadSize(10); chain.maybeLookAhead(); @@ -394,7 +394,7 @@ public class DeterministicKeyChainTest { DeterministicKey watchingKey = bip44chain.getWatchingKey(); watchingKey = watchingKey.dropPrivateBytes().dropParent(); watchingKey.setCreationTimeSeconds(100000); - chain = DeterministicKeyChain.watch(watchingKey); + chain = DeterministicKeyChain.builder().watch(watchingKey).build(); assertEquals(100000, chain.getEarliestKeyCreationTime()); chain.setLookaheadSize(10); chain.maybeLookAhead(); @@ -435,7 +435,7 @@ public class DeterministicKeyChainTest { assertEquals("xpub69KR9epJ2Wp6ywiv4Xu5WfBUpX4GLu6D5NUMd4oUkCFoZoRNyk3ZCxfKPDkkGvCPa16dPgEdY63qoyLqEa5TQQy1nmfSmgWcagRzimyV7uA", pub58); watchingKey = DeterministicKey.deserializeB58(null, pub58, MAINNET); watchingKey.setCreationTimeSeconds(100000); - chain = DeterministicKeyChain.watch(watchingKey); + chain = DeterministicKeyChain.builder().watch(watchingKey).build(); assertEquals(accountOne, chain.getAccountPath()); assertEquals(100000, chain.getEarliestKeyCreationTime()); chain.setLookaheadSize(10); @@ -475,7 +475,7 @@ public class DeterministicKeyChainTest { assertEquals("xprv9vL4k9HYXonmvqGSUrRM6wGEmx3ruGTXi4JxHRiwEvwDwYmTocPbQNpjN89gpqPrFofmfvALwgnNFBCH2grse1YDf8ERAwgdvbjRtoMfsbV", prv58); watchingKey = DeterministicKey.deserializeB58(null, prv58, params); watchingKey.setCreationTimeSeconds(100000); - chain = DeterministicKeyChain.spend(watchingKey); + chain = DeterministicKeyChain.builder().spend(watchingKey).build(); assertEquals(100000, chain.getEarliestKeyCreationTime()); chain.setLookaheadSize(10); chain.maybeLookAhead(); @@ -517,7 +517,7 @@ public class DeterministicKeyChainTest { assertEquals("xprv9vL4k9HYXonmzR7UC1ngJ3hTjxkmjLLUo3RexSfUGSWcACHzghWBLJAwW6xzs59XeFizQxFQWtscoTfrF9PSXrUgAtBgr13Nuojax8xTBRz", prv58); watchingKey = DeterministicKey.deserializeB58(null, prv58, params); watchingKey.setCreationTimeSeconds(secs); - chain = DeterministicKeyChain.spend(watchingKey); + chain = DeterministicKeyChain.builder().spend(watchingKey).build(); assertEquals(accountTwo, chain.getAccountPath()); assertEquals(secs, chain.getEarliestKeyCreationTime()); chain.setLookaheadSize(10); @@ -544,7 +544,7 @@ public class DeterministicKeyChainTest { assertEquals("xprv9yYQhynAmWWuz62PScx5Q2frBET2F1raaXna5A2E9Lj8XWgmKBL7S98Yand8F736j9UCTNWQeiB4yL5pLZP7JDY2tY8eszGQkiKDwBkezeS", prv58); watchingKey = DeterministicKey.deserializeB58(null, prv58, params); watchingKey.setCreationTimeSeconds(secs); - DeterministicKeyChain fromPrivBase58Chain = DeterministicKeyChain.spend(watchingKey); + DeterministicKeyChain fromPrivBase58Chain = DeterministicKeyChain.builder().spend(watchingKey).build(); assertEquals(secs, fromPrivBase58Chain.getEarliestKeyCreationTime()); fromPrivBase58Chain.setLookaheadSize(10); fromPrivBase58Chain.maybeLookAhead(); @@ -610,7 +610,7 @@ public class DeterministicKeyChainTest { @Test(expected = IllegalStateException.class) public void watchingCannotEncrypt() throws Exception { final DeterministicKey accountKey = chain.getKeyByPath(DeterministicKeyChain.ACCOUNT_ZERO_PATH); - chain = DeterministicKeyChain.watch(accountKey.dropPrivateBytes().dropParent()); + chain = DeterministicKeyChain.builder().watch(accountKey.dropPrivateBytes().dropParent()).build(); assertEquals(DeterministicKeyChain.ACCOUNT_ZERO_PATH, chain.getAccountPath()); chain = chain.toEncrypted("this doesn't make any sense"); } @@ -641,7 +641,7 @@ public class DeterministicKeyChainTest { DeterministicKey[] keys = new DeterministicKey[100]; for (int i = 0; i < keys.length; i++) keys[i] = chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); - chain = DeterministicKeyChain.watch(chain.getWatchingKey().dropPrivateBytes().dropParent()); + chain = DeterministicKeyChain.builder().watch(chain.getWatchingKey().dropPrivateBytes().dropParent()).build(); int e = chain.numBloomFilterEntries(); BloomFilter filter = chain.getFilter(e, 0.001, 1); for (DeterministicKey key : keys) diff --git a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java index 295de250..cc2d9fa8 100644 --- a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java @@ -120,7 +120,7 @@ public class WalletTest extends TestWithWallet { List followingKeys = Lists.newArrayList(); for (int i = 0; i < numKeys - 1; i++) { - final DeterministicKeyChain keyChain = new DeterministicKeyChain(new SecureRandom()); + final DeterministicKeyChain keyChain = DeterministicKeyChain.builder().random(new SecureRandom()).build(); DeterministicKey partnerKey = DeterministicKey.deserializeB58(null, keyChain.getWatchingKey().serializePubB58(UNITTEST), UNITTEST); followingKeys.add(partnerKey); if (addSigners && i < threshold - 1) @@ -3326,7 +3326,7 @@ public class WalletTest extends TestWithWallet { blockStore = new MemoryBlockStore(UNITTEST); chain = new BlockChain(UNITTEST, wallet, blockStore); - final DeterministicKeyChain keyChain = new DeterministicKeyChain(new SecureRandom()); + final DeterministicKeyChain keyChain = DeterministicKeyChain.builder().random(new SecureRandom()).build(); DeterministicKey partnerKey = DeterministicKey.deserializeB58(null, keyChain.getWatchingKey().serializePubB58(UNITTEST), UNITTEST); TransactionSigner signer = new TransactionSigner() {