Example #1
0
 public void PurgeNodes()
 {
     if (_group.ConnectedNodes.Count > 0)
     {
         _group.Purge("Group Purge::Replenishing Bloom Filters for Privacy reasons");
     }
 }
Example #2
0
 private void PurgeNodes()
 {
     if (_wallet.IsConnected())
     {
         _group.Purge("Group Purge::Replenishing Bloom Filters for Privacy reasons");
         return;
     }
     throw new Exception("Cannot purge nodes because wallet is not connected.");
 }
Example #3
0
        private async void PeriodicKick()
        {
            while (!_disposed)
            {
                await Task.Delay(TimeSpan.FromMinutes(10));

                _group.Purge("For privacy concerns, will renew bloom filters on fresh nodes");
            }
        }
Example #4
0
        /// <summary>
        /// Connect the wallet with the given connection parameters
        /// </summary>
        /// <param name="group">The group to use</param>
        public void Connect(NodesGroup group)
        {
            if (group == null)
            {
                throw new ArgumentNullException("group");
            }
            if (State != WalletState.Created)
            {
                throw new InvalidOperationException("The wallet is already connecting or connected");
            }
            var parameters = group.NodeConnectionParameters;

            group.Requirements.MinVersion        = ProtocolVersion.PROTOCOL_VERSION;
            group.Requirements.RequiredServices |= NodeServices.Network;

            var chain = parameters.TemplateBehaviors.Find <ChainBehavior>();

            if (chain == null)
            {
                chain = new ChainBehavior(new ConcurrentChain(_Parameters.Network));
                parameters.TemplateBehaviors.Add(chain);
            }
            if (chain.Chain.Genesis.HashBlock != _Parameters.Network.GetGenesis().GetHash())
            {
                throw new InvalidOperationException("ChainBehavior with invalid network chain detected");
            }

            var addrman = parameters.TemplateBehaviors.Find <AddressManagerBehavior>();

            if (addrman == null)
            {
                addrman = new AddressManagerBehavior(new AddressManager());
                parameters.TemplateBehaviors.Add(addrman);
            }

            var tracker = parameters.TemplateBehaviors.Find <TrackerBehavior>();

            if (tracker == null)
            {
                tracker = new TrackerBehavior(new Tracker(), chain.Chain);
                parameters.TemplateBehaviors.Add(tracker);
            }

            _Chain           = chain.Chain;
            _AddressManager  = addrman.AddressManager;
            _Tracker         = tracker.Tracker;
            _TrackerBehavior = tracker;
            _Group           = group;
            if (AddKnownScriptToTracker())
            {
                _Group.Purge("Bloom filter renew");
            }
            _State = WalletState.Disconnected;
            _Group.Connect();
            _Group.ConnectedNodes.Added   += ConnectedNodes_Added;
            _Group.ConnectedNodes.Removed += ConnectedNodes_Added;
            foreach (var node in _Group.ConnectedNodes)
            {
                node.Behaviors.Find <TrackerBehavior>().Scan(_ScanLocation, Created);
            }
        }
 /// <summary>
 /// Reconnects to the network.
 /// </summary>
 private void Reconnect()
 {
     _peers.Purge("Reconnect");
 }
Example #6
0
        private static async Task BlockPullerJobAsync(CancellationToken ctsToken)
        {
            while (true)
            {
                if (ctsToken.IsCancellationRequested)
                {
                    Console.WriteLine($"{nameof(BlockPullerJobAsync)} is stopped.");
                    return;
                }

                if (LocalSpvChain.Height < WalletCreationHeight)
                {
                    await Task.Delay(1000, ctsToken).ContinueWith(tsk => { }).ConfigureAwait(false);

                    continue;
                }

                int height;
                if (LocalPartialChain.BlockCount == 0)
                {
                    height = WalletCreationHeight;
                }
                else if (LocalSpvChain.Height <= LocalPartialChain.BestHeight)
                {
                    await Task.Delay(100, ctsToken).ContinueWith(tsk => { }).ConfigureAwait(false);

                    continue;
                }
                else
                {
                    height = LocalPartialChain.BestHeight + 1;
                }

                var chainedBlock = LocalSpvChain.GetBlock(height);
                BlockPuller.SetLocation(new ChainedBlock(chainedBlock.Previous.Header, chainedBlock.Previous.Height));
                Block block = null;
                CancellationTokenSource ctsBlockDownload = CancellationTokenSource.CreateLinkedTokenSource(
                    new CancellationTokenSource(TimeSpan.FromSeconds(timeoutDownSec)).Token,
                    ctsToken);
                try
                {
                    block = await Task.Run(() => BlockPuller.NextBlock(ctsBlockDownload.Token)).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    if (ctsToken.IsCancellationRequested)
                    {
                        return;
                    }
                    Console.WriteLine($"Failed to download block {chainedBlock.Height} within {timeoutDownSec} seconds. Retry");
                    if (timeoutDownSec > 180)
                    {
                        timeoutDownSec = 20;
                        _nodes.Purge("no reason");
                    }
                    else
                    {
                        timeoutDownSec = timeoutDownSec * 2;                      // adjust to the network speed
                    }
                    continue;
                }

                //reorg test
                //if(new Random().Next(100) >= 60) block = null;

                if (block == null)                 // then reorg happened
                {
                    Reorg();
                    continue;
                }

                LocalPartialChain.Add(chainedBlock.Height, block);

                // check if chains are in sync, to be sure
                var bh = LocalPartialChain.BestHeight;
                for (int i = bh; i > bh - 6; i--)
                {
                    if (!LocalPartialChain.Chain[i].MerkleProof.Header.GetHash()
                        .Equals(LocalSpvChain.GetBlock(i).Header.GetHash()))
                    {
                        // something worng, reorg
                        Reorg();
                    }
                }

                Console.WriteLine($"Full blocks left to download:  {LocalSpvChain.Height - LocalPartialChain.BestHeight}");
            }
        }