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; } } }
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; } } } }
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, }); }); }
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())); } }
public async Task <ConcurrentChain> LoadChain() { var chain = new ConcurrentChain(Constants.CurrentNetwork); await persistenceService.LoadFromStream(Constants.ChainFile, stream => { chain.Load(stream); return(chain); }); return(chain); }
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); } }
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)); } }
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; } } }
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 { } }
/// <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); }
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); }
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)); }
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)); }
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)); }
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(); } }
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); } }
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; } } } } }