diff --git a/core/src/main/java/com/google/bitcoin/wallet/KeyChainGroup.java b/core/src/main/java/com/google/bitcoin/wallet/KeyChainGroup.java index b872f7ef..ef2d4e79 100644 --- a/core/src/main/java/com/google/bitcoin/wallet/KeyChainGroup.java +++ b/core/src/main/java/com/google/bitcoin/wallet/KeyChainGroup.java @@ -220,8 +220,12 @@ public class KeyChainGroup { throw new UnsupportedOperationException("Key is not suitable to receive coins for married keychains." + " Use freshAddress to get P2SH address instead"); } - final DeterministicKey current = currentKeys.get(purpose); - return current != null ? current : freshKey(purpose); + DeterministicKey current = currentKeys.get(purpose); + if (current == null) { + current = freshKey(purpose); + currentKeys.put(purpose, current); + } + return current; } /** @@ -231,7 +235,11 @@ public class KeyChainGroup { DeterministicKeyChain chain = getActiveKeyChain(); if (isMarried(chain)) { Address current = currentAddresses.get(purpose); - return current != null ? current : freshAddress(purpose); + if (current == null) { + current = freshAddress(purpose); + currentAddresses.put(purpose, current); + } + return current; } else { return currentKey(purpose).toAddress(params); } @@ -271,10 +279,7 @@ public class KeyChainGroup { throw new UnsupportedOperationException("Key is not suitable to receive coins for married keychains." + " Use freshAddress to get P2SH address instead"); } - - List keys = chain.getKeys(purpose, numberOfKeys); // Always returns the next key along the key chain. - currentKeys.put(purpose, keys.get(keys.size() - 1)); - return keys; + return chain.getKeys(purpose, numberOfKeys); // Always returns the next key along the key chain. } /** @@ -453,9 +458,10 @@ public class KeyChainGroup { /** If the given key is "current", advance the current key to a new one. */ private void markKeyAsUsed(DeterministicKey key) { for (Map.Entry entry : currentKeys.entrySet()) { - if (entry.getValue().equals(key)) { + if (entry.getValue() != null && entry.getValue().equals(key)) { log.info("Marking key as used: {}", key); - freshKey(entry.getKey()); + currentKeys.put(entry.getKey(), null); + return; } } } diff --git a/core/src/test/java/com/google/bitcoin/wallet/KeyChainGroupTest.java b/core/src/test/java/com/google/bitcoin/wallet/KeyChainGroupTest.java index c1496916..51ff31f4 100644 --- a/core/src/test/java/com/google/bitcoin/wallet/KeyChainGroupTest.java +++ b/core/src/test/java/com/google/bitcoin/wallet/KeyChainGroupTest.java @@ -86,10 +86,15 @@ public class KeyChainGroupTest { assertNotEquals(r1, r3); ECKey c2 = group.freshKey(KeyChain.KeyPurpose.CHANGE); assertNotEquals(r3, c2); + // Current key has not moved and will not under marked as used. ECKey r4 = group.currentKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); - assertEquals(r3, r4); + assertEquals(r2, r4); ECKey c3 = group.currentKey(KeyChain.KeyPurpose.CHANGE); - assertEquals(c2, c3); + assertEquals(c1, c3); + // Mark as used. Current key is now different. + group.markPubKeyAsUsed(r4.getPubKey()); + ECKey r5 = group.currentKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); + assertNotEquals(r4, r5); } @Test