3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-31 15:22:16 +00:00

Fix failing deserialization of wallet with an empty HD chain

Error occurred when deserializing wallet if either internal or external
zero account key chain of this wallet has no keys issued
This commit is contained in:
troggy 2014-06-11 23:53:45 +04:00 committed by Mike Hearn
parent b5911c1ee4
commit 5840c8a66a
2 changed files with 15 additions and 8 deletions

View File

@ -468,19 +468,25 @@ public class KeyChainGroup {
private static EnumMap<KeyChain.KeyPurpose, DeterministicKey> createCurrentKeysMap(List<DeterministicKeyChain> chains) {
DeterministicKeyChain activeChain = chains.get(chains.size() - 1);
DeterministicKey currentExternalKey = activeChain.getKeyByPath(
ImmutableList.of(ChildNumber.ZERO_HARDENED, ChildNumber.ZERO, new ChildNumber(activeChain.getIssuedExternalKeys() - 1))
);
DeterministicKey currentInternalKey = activeChain.getKeyByPath(
ImmutableList.of(ChildNumber.ZERO_HARDENED, new ChildNumber(1), new ChildNumber(activeChain.getIssuedInternalKeys() - 1))
);
EnumMap<KeyChain.KeyPurpose, DeterministicKey> currentKeys = new EnumMap<KeyChain.KeyPurpose, DeterministicKey>(KeyChain.KeyPurpose.class);
// assuming that only RECEIVE and CHANGE keys are being used at the moment, we will treat latest issued external key
// as current RECEIVE key and latest issued internal key as CHANGE key. This should be changed as soon as other
// kinds of KeyPurpose are introduced.
currentKeys.put(KeyChain.KeyPurpose.RECEIVE_FUNDS, currentExternalKey);
currentKeys.put(KeyChain.KeyPurpose.CHANGE, currentInternalKey);
if (activeChain.getIssuedExternalKeys() > 0) {
DeterministicKey currentExternalKey = activeChain.getKeyByPath(
ImmutableList.of(ChildNumber.ZERO_HARDENED, ChildNumber.ZERO, new ChildNumber(activeChain.getIssuedExternalKeys() - 1))
);
currentKeys.put(KeyChain.KeyPurpose.RECEIVE_FUNDS, currentExternalKey);
}
if (activeChain.getIssuedInternalKeys() > 0) {
DeterministicKey currentInternalKey = activeChain.getKeyByPath(
ImmutableList.of(ChildNumber.ZERO_HARDENED, new ChildNumber(1), new ChildNumber(activeChain.getIssuedInternalKeys() - 1))
);
currentKeys.put(KeyChain.KeyPurpose.CHANGE, currentInternalKey);
}
return currentKeys;
}

View File

@ -284,6 +284,7 @@ public class KeyChainGroupTest {
@Test
public void serialization() throws Exception {
assertEquals(INITIAL_KEYS + 1 /* for the seed */, group.serializeToProtobuf().size());
group = KeyChainGroup.fromProtobufUnencrypted(group.serializeToProtobuf());
group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
DeterministicKey key1 = group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
DeterministicKey key2 = group.freshKey(KeyChain.KeyPurpose.CHANGE);