Esempio n. 1
0
    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);
        }