public static async Task ReportMemPoolStateAsync(MemPoolJob memPool, CancellationToken ctsToken) { while (true) { if (ctsToken.IsCancellationRequested) { Console.WriteLine($"{nameof(ReportMemPoolStateAsync)} is stopped."); return; } if (_prevMempoolState != memPool.State) { _prevMempoolState = memPool.State; Console.WriteLine($"MemPool state changed: {memPool.State}"); } if (memPool.State == MemPoolJob.MemPoolState.Syncing) { while (true) { if (ctsToken.IsCancellationRequested) { Console.WriteLine($"{nameof(ReportMemPoolStateAsync)} is stopped."); return; } if (memPool.State != MemPoolJob.MemPoolState.Syncing) { break; } Console.WriteLine($"Number of transactions in mempool: {memPool.Transactions.Count}"); await Task.Delay(5000, ctsToken).ContinueWith(tsk => { }).ConfigureAwait(false); } } await Task.Delay(100, ctsToken).ContinueWith(tsk => { }).ConfigureAwait(false); } }
public static void Main(string[] args) { Directory.CreateDirectory(SpvFolderPath); // TestNet addresses, first time used //var a1 = BitcoinAddress.Create("2Mz3BiReit6sNrSh9EMuhwUnhtqf2B35HpN"); // testnet, 1088037 //var a2 = BitcoinAddress.Create("mwiSUHLGngZd849Sz3TE6kRb7fHjJCuwKe"); // testnet, 1088031 //var a3 = BitcoinAddress.Create("muE3Z5Lhdk3WerqVevH49htmV96HJu4RLJ"); // testnet, 1088031 //LocalPartialChain.Track(a1.ScriptPubKey); //LocalPartialChain.Track(a2.ScriptPubKey); //LocalPartialChain.Track(a3.ScriptPubKey); //Console.WriteLine($"Tracking {a1}"); //Console.WriteLine($"Tracking {a2}"); //Console.WriteLine($"Tracking {a3}"); _connectionParameters = new NodeConnectionParameters(); //So we find nodes faster _connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager)); //So we don't have to load the chain each time we start _connectionParameters.TemplateBehaviors.Add(new ChainBehavior(LocalSpvChain)); _nodes = new NodesGroup(Network, _connectionParameters, new NodeRequirement { RequiredServices = NodeServices.Network, MinVersion = ProtocolVersion.SENDHEADERS_VERSION }); var bp = new NodesBlockPuller(LocalSpvChain, _nodes.ConnectedNodes); _connectionParameters.TemplateBehaviors.Add(new NodesBlockPuller.NodesBlockPullerBehavior(bp)); _nodes.NodeConnectionParameters = _connectionParameters; BlockPuller = (LookaheadBlockPuller)bp; MemPoolJob memPool = new MemPoolJob(_nodes, LocalPartialChain); Console.WriteLine("Start connecting to nodes..."); _nodes.Connect(); CancellationTokenSource cts = new CancellationTokenSource(); var t1 = ReportConnectedNodeCountAsync(cts.Token); var t2 = ReportHeightAsync(cts.Token); var t3 = PeriodicSaveAsync(TimeSpan.FromMinutes(3), cts.Token); var t4 = BlockPullerJobAsync(cts.Token); //var t5 = ReportTransactionsWhenAllBlocksDownAsync(cts.Token); var t6 = memPool.StartAsync(cts.Token); var t7 = ReportMemPoolStateAsync(memPool, cts.Token); //ReportTransactions(); Console.WriteLine("Press a key to exit..."); Console.ReadKey(); Console.WriteLine("Exiting..."); cts.Cancel(); Task.WhenAll(t1, t2, t3, t4, t6, t7).Wait(); //, t5, t6).Wait(); SaveAllAsync().Wait(); _nodes.Dispose(); }