HD Wallets: let you specify the creation time for a WatchingKey

If the creation time for a WatchingKey is known, it should be taken into
account and stored.

Signed-off-by: Harald Hoyer <harald@harald-hoyer.de>
This commit is contained in:
Harald Hoyer 2014-04-11 12:15:46 +02:00 committed by Mike Hearn
parent 960b9d686e
commit 9ff7a91c8c
3 changed files with 21 additions and 2 deletions

View File

@ -214,6 +214,10 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
return new Wallet(params, new KeyChainGroup(seed));
}
public static Wallet fromWatchingKey(NetworkParameters params, DeterministicKey watchKey, long creationTimeSeconds) {
return new Wallet(params, new KeyChainGroup(watchKey, creationTimeSeconds));
}
public static Wallet fromWatchingKey(NetworkParameters params, DeterministicKey watchKey) {
return new Wallet(params, new KeyChainGroup(watchKey));
}

View File

@ -81,6 +81,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
private DeterministicHierarchy hierarchy;
private DeterministicKey rootKey;
private DeterministicSeed seed;
private long creationTimeSeconds = MnemonicCode.BIP39_STANDARDISATION_TIME_SECS;
// Paths through the key tree. External keys are ones that are communicated to other parties. Internal keys are
// keys created for change addresses, coinbases, mixing, etc - anything that isn't communicated. The distinction
@ -141,17 +142,27 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
* balances and generally follow along, but spending is not possible with such a chain. Currently you can't use
* this method to watch an arbitrary fragment of some other tree, this limitation may be removed in future.
*/
public DeterministicKeyChain(DeterministicKey watchingKey) {
public DeterministicKeyChain(DeterministicKey watchingKey, long creationTimeSeconds) {
checkArgument(watchingKey.isPubKeyOnly(), "Private subtrees not currently supported");
checkArgument(watchingKey.getPath().size() == 1, "You can only watch an account key currently");
basicKeyChain = new BasicKeyChain();
this.creationTimeSeconds = creationTimeSeconds;
this.seed = null;
initializeHierarchyUnencrypted(watchingKey);
}
public DeterministicKeyChain(DeterministicKey watchingKey) {
this(watchingKey, Utils.currentTimeSeconds());
}
public static DeterministicKeyChain watch(DeterministicKey accountKey) {
return new DeterministicKeyChain(accountKey);
}
public static DeterministicKeyChain watch(DeterministicKey accountKey, long seedCreationTimeSecs) {
return new DeterministicKeyChain(accountKey, seedCreationTimeSecs);
}
DeterministicKeyChain(DeterministicSeed seed, @Nullable KeyCrypter crypter) {
this.seed = seed;
basicKeyChain = new BasicKeyChain(crypter);
@ -325,7 +336,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
@Override
public long getEarliestKeyCreationTime() {
return seed != null ? seed.getCreationTimeSeconds() : Utils.currentTimeSeconds();
return seed != null ? seed.getCreationTimeSeconds() : creationTimeSeconds;
}
@Override

View File

@ -76,6 +76,10 @@ public class KeyChainGroup {
this(null, ImmutableList.of(new DeterministicKeyChain(watchKey)), null);
}
public KeyChainGroup(DeterministicKey watchKey, long creationTimeSeconds) {
this(null, ImmutableList.of(new DeterministicKeyChain(watchKey, creationTimeSeconds)), null);
}
// Used for deserialization.
private KeyChainGroup(@Nullable BasicKeyChain basicKeyChain, List<DeterministicKeyChain> chains, @Nullable KeyCrypter crypter) {
this.basic = basicKeyChain == null ? new BasicKeyChain() : basicKeyChain;