Improve locked key usage
MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/RecoverWalletViewModel.cs
WalletWasabi.Fluent/ViewModels/AddWallet/RecoverWalletViewModel.cs
@@ -123,7 +123,7 @@ public partial class RecoverWalletViewModel : RoutableViewModel
private KeyPath AccountKeyPath { get; set; } = KeyManager.GetAccountKeyPath(Services.WalletManager.Network);
- private int MinGapLimit { get; set; } = 100;
+ private int MinGapLimit { get; set; } = 114;
public ObservableCollection<string> Mnemonics { get; } = new();

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/WabiSabiHttpApiIntegrationTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/WabiSabiHttpApiIntegrationTests.cs
@@ -199,7 +199,7 @@ public class WabiSabiHttpApiIntegrationTests : IClassFixture<WabiSabiApiApplicat
.ToArray();
_output.WriteLine("Coins were created successfully");
- keyManager.AssertLockedInternalKeysIndexed();
+ keyManager.AssertLockedInternalKeysIndexed(14);
var outputScriptCandidates = keyManager
.GetKeys(x => x.IsInternal && x.KeyState == KeyState.Locked)
.Select(x => x.PubKey.WitHash.ScriptPubKey)

MODIFY
WalletWasabi/Blockchain/Keys/KeyManager.cs
WalletWasabi/Blockchain/Keys/KeyManager.cs
@@ -569,7 +569,7 @@ public class KeyManager
/// Make sure there's always clean keys generated and indexed.
/// Call SetMinGapLimit() to set how many keys should be asserted.
/// </summary>
- public IEnumerable<HdPubKey> AssertCleanKeysIndexed(bool? isInternal = null)
+ public IEnumerable<HdPubKey> AssertCleanKeysIndexed(bool? isInternal = null, bool toFile = true)
{
var newKeys = new List<HdPubKey>();
@@ -592,7 +592,7 @@ public class KeyManager
}
}
- if (newKeys.Any())
+ if (toFile && newKeys.Any())
{
ToFile();
}
@@ -603,22 +603,35 @@ public class KeyManager
/// <summary>
/// Make sure there's always locked internal keys generated and indexed.
/// </summary>
- public bool AssertLockedInternalKeysIndexed(int howMany = 14)
+ public bool AssertLockedInternalKeysIndexed(int howMany)
{
- var generated = false;
+ var changed = false;
while (GetKeys(KeyState.Locked, true).Count() < howMany)
{
+ var firstUnusedInternalKey = GetKeys(x => x.IsInternal == true && x.KeyState == KeyState.Clean && x.Label.IsEmpty).FirstOrDefault();
+
+ if (firstUnusedInternalKey is null)
+ {
+ // If not found, generate a new.
GenerateNewKey(SmartLabel.Empty, KeyState.Locked, true, toFile: false);
- generated = true;
}
+ else
+ {
+ firstUnusedInternalKey.SetKeyState(KeyState.Locked);
+ }
+
+ changed = true;
+ }
+
+ AssertCleanKeysIndexed(isInternal: true, toFile: false);
- if (generated)
+ if (changed)
{
ToFile();
}
- return generated;
+ return changed;
}
private void SetMinGapLimit(int? minGapLimit)

MODIFY
WalletWasabi/Blockchain/TransactionProcessing/TransactionProcessor.cs
WalletWasabi/Blockchain/TransactionProcessing/TransactionProcessor.cs
@@ -238,12 +238,6 @@ public class TransactionProcessor
// Make sure there's always 21 clean keys generated and indexed.
KeyManager.AssertCleanKeysIndexed(isInternal: foundKey.IsInternal);
-
- if (foundKey.IsInternal)
- {
- // Make sure there's always 14 internal locked keys generated and indexed.
- KeyManager.AssertLockedInternalKeysIndexed(14);
- }
}
else // If we had this coin already.
{

MODIFY
WalletWasabi/Blockchain/Transactions/TransactionFactory.cs
WalletWasabi/Blockchain/Transactions/TransactionFactory.cs
@@ -143,7 +143,6 @@ public class TransactionFactory
else
{
KeyManager.AssertCleanKeysIndexed(isInternal: true);
- KeyManager.AssertLockedInternalKeysIndexed(14);
changeHdPubKey = KeyManager.GetKeys(KeyState.Clean, true).First();
builder.SetChange(changeHdPubKey.P2wpkhScript);

MODIFY
WalletWasabi/Wallets/Wallet.cs
WalletWasabi/Wallets/Wallet.cs
@@ -42,7 +42,6 @@ public class Wallet : BackgroundService
HandleFiltersLock = new AsyncLock();
KeyManager.AssertCleanKeysIndexed();
- KeyManager.AssertLockedInternalKeysIndexed(14);
}
public event EventHandler<ProcessedResult>? WalletRelevantTransactionProcessed;

Improve locked key usage