Fix recovery
MODIFY
WalletWasabi/KeyManagement/KeyManager.cs
WalletWasabi/KeyManagement/KeyManager.cs
@@ -248,5 +248,63 @@ namespace WalletWasabi.KeyManagement
return extKeys;
}
}
+
+ /// <summary>
+ /// Make sure there's always clean keys generated and indexed.
+ /// </summary>
+ public bool AssertCleanKeysIndexed(int howMany = 21, bool? isInternal = null)
+ {
+ var generated = false;
+
+ if (isInternal == null)
+ {
+ while (GetKeys(KeyState.Clean, true).Count() < howMany)
+ {
+ GenerateNewKey("", KeyState.Clean, true, toFile: false);
+ generated = true;
+ }
+ while (GetKeys(KeyState.Clean, false).Count() < howMany)
+ {
+ GenerateNewKey("", KeyState.Clean, false, toFile: false);
+ generated = true;
+ }
+ }
+ else
+ {
+ while (GetKeys(KeyState.Clean, isInternal).Count() < howMany)
+ {
+ GenerateNewKey("", KeyState.Clean, (bool)isInternal, toFile: false);
+ generated = true;
+ }
+ }
+
+ if (generated)
+ {
+ ToFile();
+ }
+
+ return generated;
+ }
+
+ /// <summary>
+ /// Make sure there's always locked internal keys generated and indexed.
+ /// </summary>
+ public bool AssertLockedInternalKeysIndexed(int howMany = 14)
+ {
+ var generated = false;
+
+ while (GetKeys(KeyState.Locked, true).Count() < howMany)
+ {
+ GenerateNewKey("", KeyState.Locked, true, toFile: false);
+ generated = true;
+ }
+
+ if (generated)
+ {
+ ToFile();
+ }
+
+ return generated;
+ }
}
}

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -408,7 +408,11 @@ namespace WalletWasabi.Services
string changeLabel = "ZeroLink Change";
IEnumerable<HdPubKey> allChangeKeys = allUnusedInternalKeys.Where(x => x.Label == changeLabel);
HdPubKey changeKey = null;
- if (allChangeKeys.Count() >= 7) // Then don't generate new keys, because it'd bloat the wallet.
+
+ KeyManager.AssertLockedInternalKeysIndexed(14);
+ IEnumerable<HdPubKey> internalNotCachedLockedKeys = KeyManager.GetKeys(KeyState.Locked, isInternal: true).Except(AccessCache.Keys);
+
+ if (allChangeKeys.Count() >= 7 || !internalNotCachedLockedKeys.Any()) // Then don't generate new keys, because it'd bloat the wallet.
{
// Find the first one that we did not try to register in the current session.
changeKey = allChangeKeys.FirstOrDefault(x => !AccessCache.ContainsKey(x));
@@ -422,7 +426,8 @@ namespace WalletWasabi.Services
}
else
{
- changeKey = KeyManager.GenerateNewKey(changeLabel, KeyState.Locked, isInternal: true, toFile: false);
+ changeKey = internalNotCachedLockedKeys.RandomElement();
+ changeKey.SetLabel(changeLabel);
}
changeAddress = changeKey.GetP2wpkhAddress(Network);
AccessCache.AddOrReplace(changeKey, DateTimeOffset.UtcNow);
@@ -430,10 +435,14 @@ namespace WalletWasabi.Services
if (activeAddress == null)
{
- const string activeLabel = "ZeroLink Mixed Coin";
+ string activeLabel = "ZeroLink Mixed Coin";
IEnumerable<HdPubKey> allActiveKeys = allUnusedInternalKeys.Where(x => x.Label == activeLabel);
HdPubKey activeKey = null;
- if (allActiveKeys.Count() >= 7) // Then don't generate new keys, because it'd bloat the wallet.
+
+ KeyManager.AssertLockedInternalKeysIndexed(14);
+ IEnumerable<HdPubKey> internalNotCachedLockedKeys = KeyManager.GetKeys(KeyState.Locked, isInternal: true).Except(AccessCache.Keys);
+
+ if (allActiveKeys.Count() >= 7 || !internalNotCachedLockedKeys.Any()) // Then don't generate new keys, because it'd bloat the wallet.
{
// Find the first one that we did not try to register in the current session.
activeKey = allActiveKeys.FirstOrDefault(x => !AccessCache.ContainsKey(x));
@@ -448,7 +457,8 @@ namespace WalletWasabi.Services
}
else
{
- activeKey = KeyManager.GenerateNewKey(activeLabel, KeyState.Locked, isInternal: true, toFile: false);
+ activeKey = internalNotCachedLockedKeys.RandomElement();
+ activeKey.SetLabel(activeLabel);
}
activeAddress = activeKey.GetP2wpkhAddress(Network);
AccessCache.AddOrReplace(activeKey, DateTimeOffset.UtcNow);

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -95,7 +95,8 @@ namespace WalletWasabi.Services
BlockFolderLock = new AsyncLock();
BlockDownloadLock = new AsyncLock();
- AssertCleanKeysIndexed(21);
+ KeyManager.AssertCleanKeysIndexed(21);
+ KeyManager.AssertLockedInternalKeysIndexed(14);
_running = 0;
@@ -274,7 +275,7 @@ namespace WalletWasabi.Services
label = Guard.Correct(label);
// Make sure there's always 21 clean keys generated and indexed.
- AssertCleanKeysIndexed(21, false);
+ KeyManager.AssertCleanKeysIndexed(21, false);
IEnumerable<HdPubKey> keys = KeyManager.GetKeys(KeyState.Clean, isInternal: false);
if (dontTouch != null)
@@ -365,42 +366,6 @@ namespace WalletWasabi.Services
return history;
}
- /// <summary>
- /// Make sure there's always clean keys generated and indexed.
- /// </summary>
- private bool AssertCleanKeysIndexed(int howMany = 21, bool? isInternal = null)
- {
- var generated = false;
-
- if (isInternal == null)
- {
- while (KeyManager.GetKeys(KeyState.Clean, true).Count() < howMany)
- {
- KeyManager.GenerateNewKey("", KeyState.Clean, true, toFile: false);
- generated = true;
- }
- while (KeyManager.GetKeys(KeyState.Clean, false).Count() < howMany)
- {
- KeyManager.GenerateNewKey("", KeyState.Clean, false, toFile: false);
- generated = true;
- }
- }
- else
- {
- while (KeyManager.GetKeys(KeyState.Clean, isInternal).Count() < howMany)
- {
- KeyManager.GenerateNewKey("", KeyState.Clean, (bool)isInternal, toFile: false);
- generated = true;
- }
- }
-
- if (generated)
- {
- KeyManager.ToFile();
- }
- return generated;
- }
-
private void ProcessBlock(Height height, Block block)
{
var keys = KeyManager.GetKeys().ToList();
@@ -532,11 +497,21 @@ namespace WalletWasabi.Services
}
// Make sure there's always 21 clean keys generated and indexed.
- if (AssertCleanKeysIndexed(21, foundKey.IsInternal()))
+ if (KeyManager.AssertCleanKeysIndexed(21, foundKey.IsInternal()))
{
// If it generated a new key refresh the keys:
keys = KeyManager.GetKeys().ToList();
}
+
+ if (foundKey.IsInternal())
+ {
+ // Make sure there's always 14 internal locked keys generated and indexed.
+ if (KeyManager.AssertLockedInternalKeysIndexed(14))
+ {
+ // If it generated a new key refresh the keys:
+ keys = KeyManager.GetKeys().ToList();
+ }
+ }
}
}
@@ -888,7 +863,8 @@ namespace WalletWasabi.Services
if (customChange == null)
{
- AssertCleanKeysIndexed(21, true);
+ KeyManager.AssertCleanKeysIndexed(21, true);
+ KeyManager.AssertLockedInternalKeysIndexed(14);
var changeHdPubKey = KeyManager.GetKeys(KeyState.Clean, true).RandomElement();
changeHdPubKey.SetLabel(changeLabel, KeyManager);

Fix recovery