Beispiel #1
0
        public WalletJob(Safe safeToTrack, HttpClientHandler handler = null, bool trackDefaultSafe = true, params SafeAccount[] accountsToTrack)
        {
            _creationHeight = Height.Unknown;
            _tracker        = null;

            Safe               = safeToTrack;
            CurrentNetwork     = safeToTrack.Network;
            MemPoolJob.Enabled = false;

            _qBitClient = new QBitNinjaClient(safeToTrack.Network);
            _httpClient = new HttpClient();
            if (handler != null)
            {
                _qBitClient.SetHttpMessageHandler(handler);
                _httpClient = new HttpClient(handler);
            }

            if (accountsToTrack == null || !accountsToTrack.Any())
            {
                SafeAccounts = new ConcurrentHashSet <SafeAccount>();
            }
            else
            {
                SafeAccounts = new ConcurrentHashSet <SafeAccount>(accountsToTrack);
            }

            TracksDefaultSafe = trackDefaultSafe;

            State = WalletState.NotStarted;

            Directory.CreateDirectory(WorkFolderPath);

            Tracker.TrackedTransactions.CollectionChanged += delegate
            {
                UpdateSafeTracking();
            };

            _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(HeaderChain));

            UpdateSafeTracking();

            Nodes = new NodesGroup(Safe.Network, _connectionParameters,
                                   new NodeRequirement
            {
                RequiredServices = NodeServices.Network,
                MinVersion       = ProtocolVersion.SENDHEADERS_VERSION
            });
            var bp = new NodesBlockPuller(HeaderChain, Nodes.ConnectedNodes);

            _connectionParameters.TemplateBehaviors.Add(new NodesBlockPuller.NodesBlockPullerBehavior(bp));
            Nodes.NodeConnectionParameters = _connectionParameters;
            BlockPuller = (LookaheadBlockPuller)bp;

            MemPoolJob.Synced += delegate
            {
                State = WalletState.Synced;

                var trackedMemPoolTransactions = Tracker.TrackedTransactions.Where(x => x.Height == Height.MemPool);
                foreach (var tx in trackedMemPoolTransactions)
                {
                    // If we are tracking a tx that is malleated or fall out of mempool (too long to confirm) then stop tracking
                    if (!MemPoolJob.Transactions.Contains(tx.GetHash()))
                    {
                        Tracker.TrackedTransactions.TryRemove(tx);
                        Debug.WriteLine($"Transaction fall out of MemPool: {tx.GetHash()}");
                    }
                }

                Debug.WriteLine("MemPool updated");
            };

            MemPoolJob.NewTransaction += MemPoolJob_NewTransaction;

            Nodes.ConnectedNodes.Removed += delegate { OnConnectedNodeCountChanged(); };
            Nodes.ConnectedNodes.Added   += delegate { OnConnectedNodeCountChanged(); };

            Tracker.BestHeightChanged += delegate { OnBestHeightChanged(); };
        }
Beispiel #2
0
        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();
        }