public void UtxoRefereeSerialization() { var record = BannedUtxoRecord.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 DateTimeOffset(dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond), TimeSpan.Zero); var record2Init = new BannedUtxoRecord(record.Utxo, 3, now, false, 99); string record2Line = record2Init.ToString(); var record2 = BannedUtxoRecord.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); }
public async Task BanUtxosAsync(int severity, DateTimeOffset timeOfBan, bool forceNoted, long bannedForRound, params OutPoint[] toBan) { if (RoundConfig.DosSeverity == 0) { return; } var lines = new List <string>(); var updated = false; foreach (var utxo in toBan) { BannedUtxoRecord foundElem = null; if (BannedUtxos.TryGetValue(utxo, out BannedUtxoRecord fe)) { foundElem = fe; bool bannedForTheSameRound = foundElem.BannedForRound == bannedForRound; if (bannedForTheSameRound && (!forceNoted || foundElem.IsNoted)) { continue; // We would be simply duplicating this ban. } } var isNoted = true; if (!forceNoted) { if (RoundConfig.DosNoteBeforeBan) { if (foundElem != null) { isNoted = false; } } else { isNoted = false; } } var newElem = new BannedUtxoRecord(utxo, severity, timeOfBan, isNoted, bannedForRound); if (BannedUtxos.TryAdd(newElem.Utxo, newElem)) { string line = newElem.ToString(); lines.Add(line); } else { var elem = BannedUtxos[utxo]; if (elem.IsNoted != isNoted || elem.BannedForRound != bannedForRound) { BannedUtxos[utxo] = new BannedUtxoRecord(elem.Utxo, elem.Severity, elem.TimeOfBan, isNoted, bannedForRound); updated = true; } } Logger.LogInfo($"UTXO {(isNoted ? "noted" : "banned")} with severity: {severity}. UTXO: {utxo.N}:{utxo.Hash} for disrupting Round {bannedForRound}."); } if (updated) // If at any time we set updated then we must update the whole thing. { var allLines = BannedUtxos.Select(x => x.Value.ToString()); await File.WriteAllLinesAsync(BannedUtxosFilePath, allLines); } else if (lines.Count != 0) // If we do not have to update the whole thing, we must check if we added a line and so only append. { await File.AppendAllLinesAsync(BannedUtxosFilePath, lines); } }