Example #1
0
        private void LoadChainFromCache()
        {
            var suffix = _Network.CryptoCode == "BTC" ? "" : _Network.CryptoCode;
            {
                var legacyCachePath = Path.Combine(_Configuration.DataDir, $"{suffix}chain.dat");
                if (_Configuration.CacheChain && File.Exists(legacyCachePath))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Loading chain from cache...");
                    _Chain.Load(File.ReadAllBytes(legacyCachePath), _Network.NBitcoinNetwork);
                    File.Delete(legacyCachePath);
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Height: " + _Chain.Height);
                    return;
                }
            }

            {
                var cachePath = Path.Combine(_Configuration.DataDir, $"{suffix}chain-stripped.dat");
                if (_Configuration.CacheChain && File.Exists(cachePath))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Loading chain from cache...");
                    _Chain.Load(File.ReadAllBytes(cachePath), _Network.NBitcoinNetwork, new ConcurrentChain.ChainSerializationFormat()
                    {
                        SerializeBlockHeader          = false,
                        SerializePrecomputedBlockHash = true,
                    });
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Height: " + _Chain.Height);
                    return;
                }
            }
        }
Example #2
0
        public void ValidSomeBlocks()
        {
            using (NodeContext ctx = NodeContext.Create(network: Network.Main))
            {
                var network = ctx.Network;
                var chain   = new ConcurrentChain(network.GetGenesis().Header);
                if (network == NBitcoin.Network.Main)
                {
                    chain.Load(GetFile("main.data", "https://aois.blob.core.windows.net/public/main.data"));
                }
                else
                {
                    chain.Load(GetFile("test.data", "https://aois.blob.core.windows.net/public/test.data"));
                }

                var stack = new CoinViewStack(
                    new CacheCoinView(
                        new PrefetcherCoinView(
                            new BackgroundCommiterCoinView(
                                ctx.PersistentCoinView))));

                var cache = stack.Find <CacheCoinView>();
                var backgroundCommiter   = stack.Find <BackgroundCommiterCoinView>();
                ConsensusValidator valid = new ConsensusValidator(network.Consensus);
                valid.UseConsensusLib = false;
                Node node = Node.Connect(network, "yournode");
                node.VersionHandshake();
                var puller        = new CustomNodeBlockPuller(chain, node);
                var lastSnapshot  = valid.PerformanceCounter.Snapshot();
                var lastSnapshot2 = ctx.PersistentCoinView.PerformanceCounter.Snapshot();
                var lastSnapshot3 = cache.PerformanceCounter.Snapshot();
                foreach (var block in valid.Run(stack, puller))
                {
                    if ((DateTimeOffset.UtcNow - lastSnapshot.Taken) > TimeSpan.FromSeconds(5.0))
                    {
                        Console.WriteLine();

                        Console.WriteLine("ActualLookahead :\t" + puller.ActualLookahead + " blocks");
                        Console.WriteLine("Downloaded Count :\t" + puller.RollingAverageDownloadedCount + " blocks");
                        Console.WriteLine("CoinViewTip :\t" + backgroundCommiter.Tip.Height);
                        Console.WriteLine("CommitingTip :\t" + backgroundCommiter.CommitingTip.Height);
                        Console.WriteLine("InnerTip :\t" + backgroundCommiter.InnerTip.Height);
                        Console.WriteLine("Cache entries :\t" + cache.CacheEntryCount);

                        var snapshot = valid.PerformanceCounter.Snapshot();
                        Console.Write(snapshot - lastSnapshot);
                        lastSnapshot = snapshot;

                        var snapshot2 = ctx.PersistentCoinView.PerformanceCounter.Snapshot();
                        Console.Write(snapshot2 - lastSnapshot2);
                        lastSnapshot2 = snapshot2;

                        var snapshot3 = cache.PerformanceCounter.Snapshot();
                        Console.Write(snapshot3 - lastSnapshot3);
                        lastSnapshot3 = snapshot3;
                    }
                }
            }
        }
Example #3
0
        public void CanPersistMainchain()
        {
            var          main = new ConcurrentChain(LoadMainChain(), Network.Main);
            MemoryStream ms   = new MemoryStream();

            main.WriteTo(ms);
            ms.Position = 0;
            main.SetTip(main.Genesis);
            main.Load(ms);
            Assert.True(main.Tip.HasHeader);

            var original = main;

            foreach (var options in new[] {
                new ConcurrentChain.ChainSerializationFormat()
                {
                    SerializeBlockHeader = true,
                    SerializePrecomputedBlockHash = true,
                },
                new ConcurrentChain.ChainSerializationFormat()
                {
                    SerializeBlockHeader = true,
                    SerializePrecomputedBlockHash = false,
                },
                new ConcurrentChain.ChainSerializationFormat()
                {
                    SerializeBlockHeader = false,
                    SerializePrecomputedBlockHash = true,
                }
            })
            {
                main = new ConcurrentChain();
                main.SetTip(original.Tip);
                ms = new MemoryStream();
                main.WriteTo(ms, options);
                ms.Position = 0;
                main.SetTip(main.Genesis);
                main.Load(ms, Network.Main, options);
                Assert.Equal(options.SerializeBlockHeader, main.Tip.HasHeader);
                if (main.Tip.HasHeader)
                {
                    Assert.True(main.Tip.TryGetHeader(out var unused));
                }
                else
                {
                    Assert.False(main.Tip.TryGetHeader(out var unused));
                    Assert.Throws <InvalidOperationException>(() => main.Tip.Header);
                }
                Assert.Equal(original.Tip.HashBlock, main.Tip.HashBlock);
            }

            Assert.Throws <InvalidOperationException>(() =>
            {
                main.WriteTo(new MemoryStream(), new ConcurrentChain.ChainSerializationFormat()
                {
                    SerializeBlockHeader          = false,
                    SerializePrecomputedBlockHash = false,
                });
            });
        }
Example #4
0
 private void LoadChain()
 {
     _logger.Information("Checking chain file on disk ... ");
     if (File.Exists(ChainFile()))
     {
         _logger.Information("Exists, loading now..");
         _chain = new ConcurrentChain(_settings.Network);
         _chain.Load(File.ReadAllBytes(ChainFile()));
     }
 }
Example #5
0
        public async Task <ConcurrentChain> LoadChain()
        {
            var chain = new ConcurrentChain(Constants.CurrentNetwork);
            await persistenceService.LoadFromStream(Constants.ChainFile, stream =>
            {
                chain.Load(stream);
                return(chain);
            });

            return(chain);
        }
Example #6
0
        private void LoadChainFromCache()
        {
            var suffix    = _Network.CryptoCode == "BTC" ? "" : _Network.CryptoCode;
            var cachePath = Path.Combine(_Configuration.DataDir, $"{suffix}chain.dat");

            if (_Configuration.CacheChain && File.Exists(cachePath))
            {
                Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Loading chain from cache...");
                _Chain.Load(File.ReadAllBytes(cachePath));
                Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Height: " + _Chain.Height);
            }
        }
Example #7
0
        public void CanCalculatePowCorrectly()
        {
            var chain = new ConcurrentChain(Network.Main);

            EnsureDownloaded("MainChain.dat", "https://aois.blob.core.windows.net/public/MainChain.dat");
            chain.Load(File.ReadAllBytes("MainChain.dat"));
            foreach (ChainedHeader block in chain.EnumerateAfter(chain.Genesis))
            {
                Target thisWork  = block.GetWorkRequired(Network.Main);
                Target thisWork2 = block.Previous.GetNextWorkRequired(Network.Main);
                Assert.Equal(thisWork, thisWork2);
                Assert.True(block.CheckProofOfWorkAndTarget(Network.Main));
            }
        }
Example #8
0
        private void LoadChainFromCache()
        {
            var suffix = _Network.CryptoCode == "BTC" ? "" : _Network.CryptoCode;
            {
                var legacyCachePath = Path.Combine(_Configuration.DataDir, $"{suffix}chain.dat");
                if (_Configuration.CacheChain && File.Exists(legacyCachePath))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Loading chain from cache...");
                    var chain = new ConcurrentChain(_Network.NBitcoinNetwork);
                    chain.Load(File.ReadAllBytes(legacyCachePath), _Network.NBitcoinNetwork);
                    LoadSlimAndSaveToSlimFormat(chain);
                    File.Delete(legacyCachePath);
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Height: " + _Chain.Height);
                    return;
                }
            }

            {
                var cachePath = Path.Combine(_Configuration.DataDir, $"{suffix}chain-stripped.dat");
                if (_Configuration.CacheChain && File.Exists(cachePath))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Loading chain from cache...");
                    var chain = new ConcurrentChain(_Network.NBitcoinNetwork);
                    chain.Load(File.ReadAllBytes(cachePath), _Network.NBitcoinNetwork, new ConcurrentChain.ChainSerializationFormat()
                    {
                        SerializeBlockHeader          = false,
                        SerializePrecomputedBlockHash = true,
                    });
                    LoadSlimAndSaveToSlimFormat(chain);
                    File.Delete(cachePath);
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Height: " + _Chain.Height);
                    return;
                }
            }

            {
                var slimCachePath = Path.Combine(_Configuration.DataDir, $"{suffix}chain-slim.dat");
                if (_Configuration.CacheChain && File.Exists(slimCachePath))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Loading chain from cache...");
                    using (var file = new FileStream(slimCachePath, FileMode.Open, FileAccess.Read, FileShare.None, 1024 * 1024))
                    {
                        _Chain.Load(file);
                    }
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Height: " + _Chain.Height);
                    return;
                }
            }
        }
Example #9
0
 private static void LoadCache(ConcurrentChain chain, string cacheLocation)
 {
     if (string.IsNullOrEmpty(cacheLocation))
     {
         return;
     }
     try
     {
         var bytes = File.ReadAllBytes(cacheLocation);
         chain.Load(bytes);
     }
     catch //We don't care if it don't succeed
     {
     }
 }
Example #10
0
        /// <summary>
        /// Attempts to load the persisted blockchain headers from persistent storage. This is
        /// a lot quicker than loading from a peer node.
        /// </summary>
        private async static Task LoadChain(ConcurrentChain chain, CancellationToken ct)
        {
            logger.DebugFormat("Commencing blockchain headers load from disk...");

            ct.ThrowIfCancellationRequested();

            Stopwatch sw = new Stopwatch();

            sw.Start();

            if (File.Exists(_chainFile))
            {
                await Task.Run(() => { chain.Load(File.ReadAllBytes(_chainFile)); });
            }

            sw.Stop();

            logger.DebugFormat("Block headers load from disk, chain height {0} in {1}s.", chain.Height, sw.Elapsed.Seconds);
        }
Example #11
0
        private ConcurrentChain GetChain()
        {
            if (_ConnectionParameters != null)
            {
                return(_ConnectionParameters.TemplateBehaviors.Find <ChainBehavior>().Chain);
            }
            var chain = new ConcurrentChain(App.Network);

            try
            {
                lock (App.Saving)
                {
                    chain.Load(File.ReadAllBytes(ChainFile()));
                }
            }
            catch
            {
            }
            return(chain);
        }
Example #12
0
		public void CanLoadAndSaveConcurrentChain()
		{
			ConcurrentChain cchain = new ConcurrentChain();
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AddBlock(chain);
			AddBlock(chain);
			AddBlock(chain);

			cchain.SetTip(chain);

			var bytes = cchain.ToBytes();
			cchain = new ConcurrentChain();
			cchain.Load(bytes);

			Assert.Equal(cchain.Tip, chain.Tip);
			Assert.NotNull(cchain.GetBlock(0));

			cchain = new ConcurrentChain(Network.TestNet);
			cchain.Load(cchain.ToBytes());
			Assert.NotNull(cchain.GetBlock(0));
		}
Example #13
0
        public void CanLoadAndSaveConcurrentChain()
        {
            var cchain = new ConcurrentChain(this.network);
            var chain  = new ConcurrentChain(this.network);

            this.AddBlock(chain);
            this.AddBlock(chain);
            this.AddBlock(chain);

            cchain.SetTip(chain);

            byte[] bytes = cchain.ToBytes();
            cchain = new ConcurrentChain(this.network);
            cchain.Load(bytes);

            Assert.Equal(cchain.Tip, chain.Tip);
            Assert.NotNull(cchain.GetBlock(0));

            cchain = new ConcurrentChain(this.networkTest);
            cchain.Load(cchain.ToBytes());
            Assert.NotNull(cchain.GetBlock(0));
        }
Example #14
0
        public void CanLoadAndSaveConcurrentChain()
        {
            ConcurrentChain cchain = new ConcurrentChain();
            ConcurrentChain chain  = new ConcurrentChain(Network.Main);

            AddBlock(chain);
            AddBlock(chain);
            AddBlock(chain);

            cchain.SetTip(chain);

            var bytes = cchain.ToBytes();

            cchain = new ConcurrentChain();
            cchain.Load(bytes, Network.TestNet);

            Assert.Equal(cchain.Tip, chain.Tip);
            Assert.NotNull(cchain.GetBlock(0));

            cchain = new ConcurrentChain(Network.TestNet);
            cchain.Load(cchain.ToBytes(), Network.TestNet);
            Assert.NotNull(cchain.GetBlock(0));
        }
Example #15
0
        private ConcurrentChain GetChain()
        {
            if (_connectionparameters != null)
            {
                return(_connectionparameters.TemplateBehaviors.Find <ChainBehavior>().Chain);
            }
            var chain = new ConcurrentChain(_wallet.NetworkChoice);

            if (File.Exists(GetChainFile()))
            {
                try
                {
                    lock (App.Saving)
                    {
                        chain.Load(File.ReadAllBytes(GetChainFile()));
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            return(chain);
        }
        public async Task StartAsync()
        {
            if (_Disposed)
            {
                throw new ObjectDisposedException(nameof(NBxplorerInitializer));
            }
            _Starting.Reset();
            try
            {
                if (_Network.IsRegTest)
                {
                    if (await _RPC.GetBlockCountAsync() < 100)
                    {
                        Logs.Configuration.LogInformation($"Less than 100 blocks, mining some block for regtest");
                        await _RPC.GenerateAsync(101);
                    }
                    else
                    {
                        var header = await _RPC.GetBlockHeaderAsync(await _RPC.GetBestBlockHashAsync());

                        if ((DateTimeOffset.UtcNow - header.BlockTime) > TimeSpan.FromSeconds(24 * 60 * 60))
                        {
                            Logs.Configuration.LogInformation($"It has been a while nothing got mined on regtest... mining 10 blocks");
                            await _RPC.GenerateAsync(10);
                        }
                    }
                }

                var cachePath = Path.Combine(_Configuration.DataDir, "chain.dat");
                if (_Configuration.CacheChain && File.Exists(cachePath))
                {
                    Logs.Configuration.LogInformation($"Loading chain from cache...");
                    _Chain.Load(File.ReadAllBytes(cachePath));
                    Logs.Configuration.LogInformation($"Height: " + _Chain.Height);
                }

                var heightBefore = _Chain.Height;
                Logs.Configuration.LogInformation($"Loading chain from node...");
                using (var node = Node.Connect(_Network.Network, _Configuration.NodeEndpoint))
                {
                    var cts = new CancellationTokenSource();
                    cts.CancelAfter(5000);
                    node.VersionHandshake(cts.Token);
                    node.SynchronizeChain(_Chain);
                }
                Logs.Configuration.LogInformation("Height: " + _Chain.Height);

                if (_Configuration.CacheChain && heightBefore != _Chain.Height)
                {
                    Logs.Configuration.LogInformation($"Saving chain to cache...");
                    var ms = new MemoryStream();
                    _Chain.WriteTo(ms);
                    File.WriteAllBytes(cachePath, ms.ToArray());
                    Logs.Configuration.LogInformation($"Saved");
                }


                AddressManager manager = new AddressManager();
                manager.Add(new NetworkAddress(_Configuration.NodeEndpoint), IPAddress.Loopback);
                NodesGroup group = new NodesGroup(_Network.Network, new NodeConnectionParameters()
                {
                    Services          = NodeServices.Nothing,
                    IsRelay           = true,
                    TemplateBehaviors =
                    {
                        new AddressManagerBehavior(manager)
                        {
                            PeersToDiscover = 1,
                            Mode            = AddressManagerBehaviorMode.None
                        },
                        new ExplorerBehavior(_Repository, _Chain, _Invoker, _Events)
                        {
                            StartHeight = _Configuration.StartHeight
                        },
                        new ChainBehavior(_Chain)
                        {
                            CanRespondToGetHeaders = false
                        }
                    }
                });
                group.AllowSameGroup        = true;
                group.MaximumNodeConnection = 1;
                group.Connect();
                _Group = group;
            }
            finally { _Starting.Set(); }
        }
Example #17
0
        public ExplorerRuntime(ExplorerConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }
            Network      = configuration.Network;
            Chain        = new ConcurrentChain(Network.GetGenesis().Header);
            RPC          = configuration.RPC.ConfigureRPCClient(configuration.Network);
            NodeEndpoint = configuration.NodeEndpoint;
            ServerUrls   = configuration.GetUrls();

            var cachePath = Path.Combine(configuration.DataDir, "chain.dat");

            if (configuration.CacheChain)
            {
                Logs.Configuration.LogInformation($"Loading chain from cache...");
                if (File.Exists(cachePath))
                {
                    Chain.Load(File.ReadAllBytes(cachePath));
                }
            }

            Logs.Configuration.LogInformation($"Loading chain from node...");
            var heightBefore = Chain.Height;

            try
            {
                if (!configuration.RPC.NoTest)
                {
                    Logs.Configuration.LogInformation("Trying to connect to node: " + configuration.NodeEndpoint);
                    using (var node = Node.Connect(Network, configuration.NodeEndpoint))
                    {
                        var cts = new CancellationTokenSource();
                        cts.CancelAfter(5000);
                        node.VersionHandshake(cts.Token);
                        node.SynchronizeChain(Chain);
                    }
                    Logs.Configuration.LogInformation("Node connection successfull");
                }
            }
            catch (Exception ex)
            {
                Logs.Configuration.LogError("Error while connecting to node: " + ex.Message);
                throw new ConfigException();
            }

            Logs.Configuration.LogInformation($"Chain loaded from node");

            if (configuration.CacheChain && heightBefore != Chain.Height)
            {
                Logs.Configuration.LogInformation($"Saving chain to cache...");
                var ms = new MemoryStream();
                Chain.WriteTo(ms);
                File.WriteAllBytes(cachePath, ms.ToArray());
            }

            var dbPath = Path.Combine(configuration.DataDir, "db");

            Repository = new Repository(dbPath, true);
            if (configuration.Rescan)
            {
                Logs.Configuration.LogInformation("Rescanning...");
                Repository.SetIndexProgress(null);
            }
        }
Example #18
0
        public void ValidSomeBlocks()
        {
            using (NodeContext ctx = NodeContext.Create(network: Network.Main, clean: false))
            {
                var network = ctx.Network;
                var chain   = new ConcurrentChain(network.GetGenesis().Header);
                if (network == NBitcoin.Network.Main)
                {
                    chain.Load(GetFile("main.data", "https://aois.blob.core.windows.net/public/main.data"));
                }
                else
                {
                    chain.Load(GetFile("test.data", "https://aois.blob.core.windows.net/public/test.data"));
                }

                //var threads = new CustomThreadPoolTaskScheduler(10, 100, "Parallel Coin Fetcher");

                var stack = new CoinViewStack(
                    new CacheCoinView(
                        // PrefetcherCoinView(
                        //new ParallelCoinView(threads,
                        new BackgroundCommiterCoinView(
                            ctx.PersistentCoinView)));                    //);
                //new InMemoryCoinView(chain.Genesis));

                var bottom               = stack.Bottom;
                var cache                = stack.Find <CacheCoinView>();
                var backgroundCommiter   = stack.Find <BackgroundCommiterCoinView>();
                ConsensusValidator valid = new ConsensusValidator(network.Consensus);
                valid.UseConsensusLib = false;
                Node node = Node.Connect(network, "yournode");
                node.VersionHandshake();
                var puller        = new CustomNodeBlockPuller(chain, node);
                var lastSnapshot  = valid.PerformanceCounter.Snapshot();
                var lastSnapshot2 = ctx.PersistentCoinView.PerformanceCounter.Snapshot();
                var lastSnapshot3 = cache == null ? null : cache.PerformanceCounter.Snapshot();
                foreach (var block in valid.Run(stack, puller))
                {
                    if ((DateTimeOffset.UtcNow - lastSnapshot.Taken) > TimeSpan.FromSeconds(5.0))
                    {
                        Console.WriteLine();

                        Console.WriteLine("ActualLookahead :\t" + puller.ActualLookahead + " blocks");
                        Console.WriteLine("Median Downloaded :\t" + puller.MedianDownloadCount + " blocks");
                        if (backgroundCommiter != null)
                        {
                            Console.WriteLine("CoinViewTip :\t" + backgroundCommiter.Tip.Height);
                            Console.WriteLine("CommitingTip :\t" + backgroundCommiter.CommitingTip.Height);
                        }
                        Console.WriteLine("Bottom Tip :\t" + bottom.Tip.Height);
                        if (cache != null)
                        {
                            Console.WriteLine("Cache entries :\t" + cache.CacheEntryCount);
                        }

                        var snapshot = valid.PerformanceCounter.Snapshot();
                        Console.Write(snapshot - lastSnapshot);
                        lastSnapshot = snapshot;

                        var snapshot2 = ctx.PersistentCoinView.PerformanceCounter.Snapshot();
                        Console.Write(snapshot2 - lastSnapshot2);
                        lastSnapshot2 = snapshot2;
                        if (cache != null)
                        {
                            var snapshot3 = cache.PerformanceCounter.Snapshot();
                            Console.Write(snapshot3 - lastSnapshot3);
                            lastSnapshot3 = snapshot3;
                        }
                    }
                }
            }
        }