Make UtxoHistory rollbackable until 100 blocks
MODIFY
MagicalCryptoWallet.Tests/RegTests.cs
MagicalCryptoWallet.Tests/RegTests.cs
@@ -358,11 +358,11 @@ namespace MagicalCryptoWallet.Tests
times = 0;
while ((filterCount = downloader.GetFiltersIncluding(new Height(0)).Count()) < 116)
{
- if (times > 240) // 4 min
+ if (times > 2400) // 4 min
{
throw new TimeoutException($"{nameof(IndexDownloader)} test timed out. Needed filters: {116}, got only: {filterCount}.");
}
- await Task.Delay(1000);
+ await Task.Delay(100);
times++;
}

MODIFY
MagicalCryptoWallet/Services/IndexBuilderService.cs
MagicalCryptoWallet/Services/IndexBuilderService.cs
@@ -25,7 +25,7 @@ namespace MagicalCryptoWallet.Services
private AsyncLock IndexLock { get; }
private Dictionary<OutPoint, Script> Bech32UtxoSet { get; }
- private ActionHistoryHelper Bech32UtxoSetHistory { get; }
+ private List<ActionHistoryHelper> Bech32UtxoSetHistory { get; }
private class ActionHistoryHelper
{
@@ -124,7 +124,7 @@ namespace MagicalCryptoWallet.Services
Bech32UtxoSetFilePath = Guard.NotNullOrEmptyOrWhitespace(nameof(bech32UtxoSetFilePath), bech32UtxoSetFilePath);
Bech32UtxoSet = new Dictionary<OutPoint, Script>();
- Bech32UtxoSetHistory = new ActionHistoryHelper();
+ Bech32UtxoSetHistory = new List<ActionHistoryHelper>(capacity: 100);
Index = new List<FilterModel>();
IndexLock = new AsyncLock();
@@ -219,7 +219,7 @@ namespace MagicalCryptoWallet.Services
// 1. Rollback index
using (await IndexLock.LockAsync())
{
- Index.RemoveAt(Index.Count - 1);
+ Index.RemoveLast();
}
// 2. Serialize Index. (Remove last line.)
@@ -227,18 +227,26 @@ namespace MagicalCryptoWallet.Services
File.WriteAllLines(IndexFilePath, lines.Take(lines.Length - 1).ToArray());
// 3. Rollback Bech32UtxoSet
- Bech32UtxoSetHistory.Rollback(Bech32UtxoSet); // The Bech32UtxoSet MUST be recovered to its previous state.
+ if (Bech32UtxoSetHistory.Count != 0)
+ {
+ Bech32UtxoSetHistory.Last().Rollback(Bech32UtxoSet); // The Bech32UtxoSet MUST be recovered to its previous state.
+ Bech32UtxoSetHistory.RemoveLast();
// 4. Serialize Bech32UtxoSet.
await File.WriteAllLinesAsync(Bech32UtxoSetFilePath, Bech32UtxoSet
.Select(entry => entry.Key.Hash + ":" + entry.Key.N + ":" + ByteHelpers.ToHex(entry.Value.ToCompressedBytes())));
+ }
// 5. Skip the current block.
continue;
}
}
- Bech32UtxoSetHistory.ClearActionHistory(); //reset history.
+ if(Bech32UtxoSetHistory.Count >= 100)
+ {
+ Bech32UtxoSetHistory.RemoveFirst();
+ }
+ Bech32UtxoSetHistory.Add(new ActionHistoryHelper());
var scripts = new HashSet<Script>();
@@ -251,7 +259,7 @@ namespace MagicalCryptoWallet.Services
{
var outpoint = new OutPoint(tx.GetHash(), i);
Bech32UtxoSet.Add(outpoint, output.ScriptPubKey);
- Bech32UtxoSetHistory.StoreAction(ActionHistoryHelper.Operation.Add, outpoint, output.ScriptPubKey);
+ Bech32UtxoSetHistory.Last().StoreAction(ActionHistoryHelper.Operation.Add, outpoint, output.ScriptPubKey);
scripts.Add(output.ScriptPubKey);
}
}
@@ -263,7 +271,7 @@ namespace MagicalCryptoWallet.Services
{
Script val = Bech32UtxoSet[input.PrevOut];
Bech32UtxoSet.Remove(input.PrevOut);
- Bech32UtxoSetHistory.StoreAction(ActionHistoryHelper.Operation.Remove, input.PrevOut, val);
+ Bech32UtxoSetHistory.Last().StoreAction(ActionHistoryHelper.Operation.Remove, input.PrevOut, val);
scripts.Add(found.Value);
}
}

Make UtxoHistory rollbackable until 100 blocks