Don't fail when deserializing a parentless HD key having depth greater than one.

Currently, deserializing an HD key will fail if both (1) the parent object is null, and
(2) the hierarchy depth is greater than one.  This patch changes that; rather than
throwing an exception, the parent is considered to be the root of the deterministic hierarchy.
This commit is contained in:
Adam Mackler 2014-09-22 14:54:38 -04:00 committed by Mike Hearn
parent cc8925ed0f
commit 2834b7730f
2 changed files with 17 additions and 10 deletions

View File

@ -381,17 +381,13 @@ public class DeterministicKey extends ECKey {
if (path.size() != depth)
throw new IllegalArgumentException("Depth does not match");
} else {
if (depth == 0) {
path = ImmutableList.of();
} else if (depth == 1) {
// We have been given a key that is not a root key, yet we also don't have any object representing
// the parent. This can happen when deserializing an account key for a watching wallet. In this case,
// we assume that the parent has a path of zero.
if (depth >= 1)
// We have been given a key that is not a root key, yet we lack any object representing the parent.
// This can happen when deserializing an account key for a watching wallet. In this case, we assume that
// the client wants to conceal the key's position in the hierarchy. The parent is deemed to be the
// root of the hierarchy.
path = ImmutableList.of(childNumber);
} else {
throw new IllegalArgumentException("Depth is " + depth + " and no parent key was provided, so we " +
"cannot reconstruct the key path from the provided data.");
}
else path = ImmutableList.of();
}
byte[] chainCode = new byte[32];
buffer.get(chainCode);

View File

@ -208,6 +208,17 @@ public class ChildKeyDerivationTest {
}
}
@Test
public void parentlessDeserialization() {
DeterministicKey key1 = HDKeyDerivation.createMasterPrivateKey("satoshi lives!".getBytes());
DeterministicKey key2 = HDKeyDerivation.deriveChildKey(key1, ChildNumber.ZERO_HARDENED);
DeterministicKey key3 = HDKeyDerivation.deriveChildKey(key2, ChildNumber.ZERO_HARDENED);
DeterministicKey key4 = HDKeyDerivation.deriveChildKey(key3, ChildNumber.ZERO_HARDENED);
assertEquals(key4.getPath().size(), 3);
assertEquals(DeterministicKey.deserialize(key3, key4.serializePrivate()).getPath().size(), 3);
assertEquals(DeterministicKey.deserialize(null, key4.serializePrivate()).getPath().size(), 1);
}
private static String hexEncodePub(DeterministicKey pubKey) {
return HEX.encode(pubKey.getPubKey());
}