public UtxoReferee(Network network, string folderPath, IRPCClient rpc, CoordinatorRoundConfig roundConfig) { Network = Guard.NotNull(nameof(network), network); FolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(folderPath), folderPath, trim: true); RpcClient = Guard.NotNull(nameof(rpc), rpc); RoundConfig = Guard.NotNull(nameof(roundConfig), roundConfig); BannedUtxos = new ConcurrentDictionary <OutPoint, BannedUtxo>(); Directory.CreateDirectory(FolderPath); if (File.Exists(BannedUtxosFilePath)) { try { var toRemove = new List <string>(); // what's been confirmed string[] allLines = File.ReadAllLines(BannedUtxosFilePath); foreach (string line in allLines) { var bannedRecord = BannedUtxo.FromString(line); var getTxOutResponse = RpcClient.GetTxOutAsync(bannedRecord.Utxo.Hash, (int)bannedRecord.Utxo.N, includeMempool: true).GetAwaiter().GetResult(); // Check if inputs are unspent. if (getTxOutResponse is null) { toRemove.Add(line); } else { BannedUtxos.TryAdd(bannedRecord.Utxo, bannedRecord); } } if (toRemove.Count != 0) // a little performance boost, often it'll be empty { var newAllLines = allLines.Where(x => !toRemove.Contains(x)); File.WriteAllLines(BannedUtxosFilePath, newAllLines); } Logger.LogInfo($"{allLines.Length} banned UTXOs are loaded from {BannedUtxosFilePath}."); } catch (Exception ex) { Logger.LogWarning($"Banned UTXO file got corrupted. Deleting {BannedUtxosFilePath}. {ex.GetType()}: {ex.Message}"); File.Delete(BannedUtxosFilePath); } } else { Logger.LogInfo($"No banned UTXOs are loaded from {BannedUtxosFilePath}."); } }
public void UtxoRefereeSerialization() { var record = BannedUtxo.FromString("2018-11-23 15-23-14:1:44:2716e680f47d74c1bc6f031da22331564dd4c6641d7216576aad1b846c85d492:True:195"); Assert.Equal(new DateTimeOffset(2018, 11, 23, 15, 23, 14, TimeSpan.Zero), record.TimeOfBan); Assert.Equal(1, record.Severity); Assert.Equal(44u, record.Utxo.N); Assert.Equal(new uint256("2716e680f47d74c1bc6f031da22331564dd4c6641d7216576aad1b846c85d492"), record.Utxo.Hash); Assert.True(record.IsNoted); Assert.Equal(195, record.BannedForRound); DateTimeOffset dateTime = DateTimeOffset.UtcNow; DateTimeOffset now = new(dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond), TimeSpan.Zero); var record2Init = new BannedUtxo(record.Utxo, 3, now, false, 99); string record2Line = record2Init.ToString(); var record2 = BannedUtxo.FromString(record2Line); Assert.Equal(now, record2.TimeOfBan); Assert.Equal(3, record2.Severity); Assert.Equal(44u, record2.Utxo.N); Assert.Equal(new uint256("2716e680f47d74c1bc6f031da22331564dd4c6641d7216576aad1b846c85d492"), record2.Utxo.Hash); Assert.False(record2.IsNoted); Assert.Equal(99, record2.BannedForRound); }