Make sure KeyManager is being ToFiled every time it's modified.
MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -2268,9 +2268,9 @@ namespace WalletWasabi.Tests
var txid1 = await rpc.SendToAddressAsync(bech1, amount1, replaceable: false);
var txid2 = await rpc.SendToAddressAsync(bech2, amount2, replaceable: false);
var txid3 = await rpc.SendToAddressAsync(bech3, amount3, replaceable: false);
- key1.KeyState = KeyState.Used;
- key2.KeyState = KeyState.Used;
- key3.KeyState = KeyState.Used;
+ key1.SetKeyState(KeyState.Used);
+ key2.SetKeyState(KeyState.Used);
+ key3.SetKeyState(KeyState.Used);
var tx1 = await rpc.GetRawTransactionAsync(txid1);
var tx2 = await rpc.GetRawTransactionAsync(txid2);
var tx3 = await rpc.GetRawTransactionAsync(txid3);
@@ -2378,9 +2378,9 @@ namespace WalletWasabi.Tests
var txid1 = await rpc.SendToAddressAsync(bech1, amount1, replaceable: false);
var txid2 = await rpc.SendToAddressAsync(bech2, amount2, replaceable: false);
var txid3 = await rpc.SendToAddressAsync(bech3, amount3, replaceable: false);
- key1.KeyState = KeyState.Used;
- key2.KeyState = KeyState.Used;
- key3.KeyState = KeyState.Used;
+ key1.SetKeyState(KeyState.Used);
+ key2.SetKeyState(KeyState.Used);
+ key3.SetKeyState(KeyState.Used);
var tx1 = await rpc.GetRawTransactionAsync(txid1);
var tx2 = await rpc.GetRawTransactionAsync(txid2);
var tx3 = await rpc.GetRawTransactionAsync(txid3);

MODIFY
WalletWasabi/Helpers/Guard.cs
WalletWasabi/Helpers/Guard.cs
@@ -129,6 +129,11 @@ namespace WalletWasabi.Helpers
return value;
}
+ /// <summary>
+ /// Corrects the string:
+ /// If the string is null, it'll be empty.
+ /// Trims the string.
+ /// </summary>
public static string Correct(string str)
{
return string.IsNullOrWhiteSpace(str)

MODIFY
WalletWasabi/KeyManagement/HdPubKey.cs
WalletWasabi/KeyManagement/HdPubKey.cs
@@ -21,9 +21,9 @@ namespace WalletWasabi.KeyManagement
public KeyPath FullKeyPath { get; }
[JsonProperty(Order = 3)]
- public string Label { get; set; }
+ public string Label { get; private set; }
[JsonProperty(Order = 4)]
- public KeyState KeyState { get; set; }
+ public KeyState KeyState { get; private set; }
public HdPubKey(PubKey pubKey, KeyPath fullKeyPath, string label, KeyState keyState)
{
@@ -33,6 +33,31 @@ namespace WalletWasabi.KeyManagement
KeyState = keyState;
}
+ public void SetLabel(string label, KeyManager kmToFile = null)
+ {
+ label = Guard.Correct(label);
+ if(Label != label)
+ {
+ Label = label;
+ if(kmToFile != null)
+ {
+ kmToFile.ToFile();
+ }
+ }
+ }
+
+ public void SetKeyState(KeyState state, KeyManager kmToFile = null)
+ {
+ if (KeyState != state)
+ {
+ KeyState = state;
+ if (kmToFile != null)
+ {
+ kmToFile.ToFile();
+ }
+ }
+ }
+
private Script _p2pkScript = null;
public Script GetP2pkScript()
{

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -597,7 +597,7 @@ namespace WalletWasabi.Services
var key = KeyManager.GetKeys().SingleOrDefault(x => x.GetP2wpkhScript() == coinWaitingForMix.ScriptPubKey);
if (key != null)
{
- key.Label = coinWaitingForMix.Label;
+ key.SetLabel(coinWaitingForMix.Label, KeyManager);
}
}
Logger.LogInfo<CcjClient>($"Coin dequeued: {coinWaitingForMix.Index}:{coinWaitingForMix.TransactionId}.");

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -204,7 +204,7 @@ namespace WalletWasabi.Services
var ret = KeyManager.GetKeys(KeyState.Clean, false).RandomElement();
- ret.Label = label;
+ ret.SetLabel(label, KeyManager);
return ret;
}
@@ -334,7 +334,7 @@ namespace WalletWasabi.Services
HdPubKey foundKey = keys.SingleOrDefault(x => x.GetP2wpkhScript() == output.ScriptPubKey);
if (foundKey != default)
{
- foundKey.KeyState = KeyState.Used;
+ foundKey.SetKeyState(KeyState.Used, KeyManager);
var coin = new SmartCoin(tx.GetHash(), i, output.ScriptPubKey, output.Value, tx.Transaction.Inputs.ToTxoRefs().ToArray(), tx.Height, tx.Transaction.RBF, foundKey.Label, spenderTransactionId: null, locked: false); // Don't inherit locked status from key, that's different.
Coins.Add(coin);
if (coin.Unspent && coin.Label == "ZeroLink Change" && ChaumianClient.OnePiece != null)
@@ -693,7 +693,7 @@ namespace WalletWasabi.Services
AssertCleanKeysIndexed(21, true);
var changeHdPubKey = KeyManager.GetKeys(KeyState.Clean, true).RandomElement();
- changeHdPubKey.Label = changeLabel;
+ changeHdPubKey.SetLabel(changeLabel, KeyManager);
changeScriptPubKey = changeHdPubKey.GetP2wpkhScript();
}
else
@@ -818,7 +818,7 @@ namespace WalletWasabi.Services
var key = KeyManager.GetKeys().SingleOrDefault(x => x.GetP2wpkhScript() == coin.ScriptPubKey);
if(key != null)
{
- key.Label = newLabel;
+ key.SetLabel(newLabel, KeyManager);
}
}

Make sure KeyManager is being ToFiled every time it's modified.