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) { private static EnumMap<KeyChain.KeyPurpose, DeterministicKey> createCurrentKeysMap(List<DeterministicKeyChain> chains) {
DeterministicKeyChain activeChain = chains.get(chains.size() - 1); 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); 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 // 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 // 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. // kinds of KeyPurpose are introduced.
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); 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); currentKeys.put(KeyChain.KeyPurpose.CHANGE, currentInternalKey);
}
return currentKeys; return currentKeys;
} }

View File

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