Exemplo n.º 1
0
        public IndexBuilderService(RPCClient rpc, TrustedNodeNotifyingBehavior trustedNodeNotifyingBehavior, string indexFilePath, string bech32UtxoSetFilePath)
        {
            RpcClient = Guard.NotNull(nameof(rpc), rpc);
            TrustedNodeNotifyingBehavior = Guard.NotNull(nameof(trustedNodeNotifyingBehavior), trustedNodeNotifyingBehavior);
            IndexFilePath         = Guard.NotNullOrEmptyOrWhitespace(nameof(indexFilePath), indexFilePath);
            Bech32UtxoSetFilePath = Guard.NotNullOrEmptyOrWhitespace(nameof(bech32UtxoSetFilePath), bech32UtxoSetFilePath);

            Bech32UtxoSet        = new Dictionary <OutPoint, Script>();
            Bech32UtxoSetHistory = new List <ActionHistoryHelper>(capacity: 100);
            Index     = new List <FilterModel>();
            IndexLock = new AsyncLock();

            StartingFilter = StartingFilters.GetStartingFilter(RpcClient.Network);
            StartingHeight = StartingFilters.GetStartingHeight(RpcClient.Network);

            _running = 0;

            IoHelpers.EnsureContainingDirectoryExists(IndexFilePath);
            if (File.Exists(IndexFilePath))
            {
                if (RpcClient.Network == Network.RegTest)
                {
                    File.Delete(IndexFilePath);                     // RegTest is not a global ledger, better to delete it.
                }
                else
                {
                    var height = StartingHeight;
                    foreach (var line in File.ReadAllLines(IndexFilePath))
                    {
                        var filter = FilterModel.FromHeightlessLine(line, height);
                        height++;
                        Index.Add(filter);
                    }
                }
            }

            IoHelpers.EnsureContainingDirectoryExists(bech32UtxoSetFilePath);
            if (File.Exists(bech32UtxoSetFilePath))
            {
                if (RpcClient.Network == Network.RegTest)
                {
                    File.Delete(bech32UtxoSetFilePath);                     // RegTest is not a global ledger, better to delete it.
                }
                else
                {
                    foreach (var line in File.ReadAllLines(Bech32UtxoSetFilePath))
                    {
                        var parts = line.Split(':');

                        var txHash = new uint256(parts[0]);
                        var nIn    = int.Parse(parts[1]);
                        var script = new Script(ByteHelpers.FromHex(parts[2]), true);
                        Bech32UtxoSet.Add(new OutPoint(txHash, nIn), script);
                    }
                }
            }

            TrustedNodeNotifyingBehavior.BlockInv += TrustedNodeNotifyingBehavior_BlockInv;
        }
        public void ShouldFindNeverUsedKey()
        {
            var filters = new[] {
                FilterModel.FromHeightlessLine("000000000000de90e633e1b1330859842795d39018d033044e8b003e8cbf58e4:050a2f58828c9820642769ae320a40", 0)
            };

            var unusedKeyIndex = ExtPubKeyExplorer.GetUnusedBech32Keys(1, true, ExtPubKey.GetWif(Network.Main), filters).First().ScriptPubKey.ToCompressedBytes();

            Assert.Equal(DerivateScript(true, 0), unusedKeyIndex);
        }
Exemplo n.º 3
0
 public static FilterModel GetStartingFilter(Network network)
 {
     if (network == Network.Main)
     {
         return(FilterModel.FromHeightlessLine("0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893:02832810ec08a0", GetStartingHeight(network)));
     }
     if (network == Network.TestNet)
     {
         return(FilterModel.FromHeightlessLine("00000000000f0d5edcaeba823db17f366be49a80d91d15b77747c2e017b8c20a:017821b8", GetStartingHeight(network)));
     }
     if (network == Network.RegTest)
     {
         return(FilterModel.FromHeightlessLine("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206", GetStartingHeight(network)));
     }
     throw new NotSupportedException($"{network} is not supported.");
 }
Exemplo n.º 4
0
        public async Task ForeachFiltersAsync(Func <FilterModel, Task> todo, Height fromHeight)
        {
            using (await MatureIndexFileManager.Mutex.LockAsync())
                using (await IndexLock.LockAsync())
                {
                    var firstImmatureHeight = ImmatureFilters.FirstOrDefault()?.BlockHeight;
                    if (!firstImmatureHeight.HasValue || firstImmatureHeight.Value > fromHeight)
                    {
                        if (MatureIndexFileManager.Exists())
                        {
                            Height height = StartingHeight;
                            using (var sr = MatureIndexFileManager.OpenText(16384))
                            {
                                while (!sr.EndOfStream)
                                {
                                    var line = await sr.ReadLineAsync();

                                    if (firstImmatureHeight == height)
                                    {
                                        break;                                 // Let's use our the immature filters from here on. The content is the same, just someone else modified the file.
                                    }

                                    if (height < fromHeight.Value)
                                    {
                                        height++;
                                        continue;
                                    }

                                    var filter = FilterModel.FromHeightlessLine(line, height);

                                    await todo(filter);

                                    height++;
                                }
                            }
                        }
                    }

                    foreach (FilterModel filter in ImmatureFilters)
                    {
                        await todo(filter);
                    }
                }
        }
Exemplo n.º 5
0
        private void ProcessLine(Height height, string line, bool enqueue)
        {
            var filter = FilterModel.FromHeightlessLine(line, height);

            ProcessFilter(filter, enqueue);
        }