示例#1
0
        private static async Task StartSwarmAsync(
            Swarm <AppAgnosticAction> swarm,
            IEnumerable <Peer> seeds,
            CancellationToken cancellationToken)
        {
            if (swarm is null)
            {
                return;
            }

            try
            {
                Console.WriteLine("Bootstrapping.");
                await swarm.BootstrapAsync(
                    seeds,
                    5000,
                    5000,
                    cancellationToken : cancellationToken
                    );
            }
            catch (TimeoutException)
            {
                Console.Error.WriteLine("No any neighbors.");
            }

            // Since explorer does not require states, turn off trustedPeer option.
            var trustedPeers = ImmutableHashSet <Address> .Empty;

            Console.WriteLine("Starts preloading.");
            await swarm.PreloadAsync(
                dialTimeout : TimeSpan.FromSeconds(15),
                trustedStateValidators : trustedPeers,
                cancellationToken : cancellationToken,
                blockDownloadFailed : (obj, args) =>
            {
                foreach (var exception in args.InnerExceptions)
                {
                    if (exception is InvalidGenesisBlockException invalidGenesisBlockException)
                    {
                        Log.Error(
                            "It seems you use different genesis block with the network. " +
                            "The hash stored was {Stored} but network was {Network}",
                            invalidGenesisBlockException.Stored.ToString(),
                            invalidGenesisBlockException.NetworkExpected.ToString());
                    }
                }
            }
                );

            Console.WriteLine("Finished preloading.");

            await swarm.StartAsync(cancellationToken : cancellationToken);
        }
示例#2
0
        private static async Task StartSwarmAsync(
            Swarm <AppAgnosticAction> swarm,
            Peer seed,
            CancellationToken cancellationToken)
        {
            if (swarm is null)
            {
                return;
            }

            var peers = new HashSet <Peer>();

            if (!(seed is null))
            {
                peers.Add(seed);
            }

            try
            {
                await swarm.BootstrapAsync(
                    peers,
                    5000,
                    5000,
                    cancellationToken : cancellationToken
                    );
            }
            catch (TimeoutException)
            {
                Console.Error.WriteLine("No any neighbors.");
            }

            // Since explorer does not require states, turn off trustedPeer option.
            var trustedPeers = ImmutableHashSet <Address> .Empty;

            Console.Error.WriteLine("Starts preloading.");
            await swarm.PreloadAsync(
                dialTimeout : TimeSpan.FromSeconds(15),
                trustedStateValidators : trustedPeers,
                cancellationToken : cancellationToken
                );

            Console.Error.WriteLine("Finished preloading.");

            await swarm.StartAsync(cancellationToken : cancellationToken);
        }
示例#3
0
        private static async Task StartSwarmAsync(
            Swarm <NullAction> swarm,
            IEnumerable <Peer> seeds,
            CancellationToken cancellationToken)
        {
            if (swarm is null)
            {
                Startup.PreloadedSingleton = true;
                return;
            }

            try
            {
                Console.Error.WriteLine("Bootstrapping.");
                await swarm.BootstrapAsync(
                    seeds,
                    5000,
                    5000,
                    cancellationToken : cancellationToken
                    );
            }
            catch (TimeoutException)
            {
                Console.Error.WriteLine("No any neighbors.");
            }

            Console.Error.WriteLine("Starts preloading.");
            await swarm.PreloadAsync(
                dialTimeout : TimeSpan.FromSeconds(15),
                cancellationToken : cancellationToken
                );

            Console.Error.WriteLine("Finished preloading.");
            Startup.PreloadedSingleton = true;

            await swarm.StartAsync(cancellationToken : cancellationToken);
        }
示例#4
0
        public IEnumerator CoSwarmRunner()
        {
            BootstrapStarted?.Invoke(this, null);
            var bootstrapTask = Task.Run(async() =>
            {
                try
                {
                    await _swarm.BootstrapAsync(
                        _seedPeers,
                        5000,
                        5000,
                        _cancellationTokenSource.Token);
                }
                catch (Exception e)
                {
                    Debug.LogFormat("Exception occurred during bootstrap {0}", e);
                }
            });

            yield return(new WaitUntil(() => bootstrapTask.IsCompleted));

            PreloadStarted?.Invoke(this, null);
            Debug.Log("PreloadingStarted event was invoked");

            DateTimeOffset started        = DateTimeOffset.UtcNow;
            long           existingBlocks = _blocks?.Tip?.Index ?? 0;

            Debug.Log("Preloading starts");

            var swarmPreloadTask = Task.Run(async() =>
            {
                await _swarm.PreloadAsync(
                    TimeSpan.FromMilliseconds(SwarmDialTimeout),
                    new Progress <PreloadState>(state =>
                                                PreloadProcessed?.Invoke(this, state)
                                                ),
                    trustedStateValidators: _trustedPeers,
                    cancellationToken: _cancellationTokenSource.Token
                    );
            });

            yield return(new WaitUntil(() => swarmPreloadTask.IsCompleted));

            DateTimeOffset ended = DateTimeOffset.UtcNow;

            if (swarmPreloadTask.Exception is Exception exc)
            {
                Debug.LogErrorFormat(
                    "Preloading terminated with an exception: {0}",
                    exc
                    );
                throw exc;
            }

            var index = _blocks?.Tip?.Index ?? 0;

            Debug.LogFormat(
                "Preloading finished; elapsed time: {0}; blocks: {1}",
                ended - started,
                index - existingBlocks
                );


            PreloadEnded?.Invoke(this, null);

            var swarmStartTask = Task.Run(async() =>
            {
                try
                {
                    await _swarm.StartAsync();
                }
                catch (TaskCanceledException)
                {
                }
                catch (Exception e)
                {
                    Debug.LogErrorFormat(
                        "Swarm terminated with an exception: {0}",
                        e
                        );
                    throw;
                }
            });

            Task.Run(async() =>
            {
                await _swarm.WaitForRunningAsync();

                Debug.LogFormat(
                    "The address of this node: {0},{1},{2}",
                    ByteUtil.Hex(PrivateKey.PublicKey.Format(true)),
                    _swarm.EndPoint.Host,
                    _swarm.EndPoint.Port
                    );
            });

            yield return(new WaitUntil(() => swarmStartTask.IsCompleted));
        }
        private async Task StartSwarm(bool preload, CancellationToken cancellationToken)
        {
            Log.Debug("Starting swarms.");
            var peers = Properties.Peers.ToImmutableArray();

            Task BootstrapMainSwarmAsync(int depth)
            => Swarm.BootstrapAsync(
                peers,
                pingSeedTimeout: PingSeedTimeout,
                findNeighborsTimeout: FindNeighborsTimeout,
                depth: depth,
                cancellationToken: cancellationToken
                );

            if (peers.Any())
            {
                try
                {
                    // FIXME: It's safe to increase depth.
                    await BootstrapMainSwarmAsync(1);

                    BootstrapEnded.Set();
                }
                catch (PeerDiscoveryException e)
                {
                    Log.Error(e, "Bootstrap failed: {Exception}", e);

                    if (!IgnoreBootstrapFailure)
                    {
                        throw;
                    }
                }

                if (preload)
                {
                    await Swarm.PreloadAsync(
                        TimeSpan.FromSeconds(5),
                        PreloadProgress,
                        Properties.TrustedStateValidators,
                        cancellationToken : cancellationToken
                        );

                    PreloadEnded.Set();
                }
            }

            async Task ReconnectToSeedPeers(CancellationToken token)
            {
                while (!token.IsCancellationRequested)
                {
                    await Task.Delay(BootstrapInterval);
                    await BootstrapMainSwarmAsync(0).ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            Log.Error(t.Exception, "Periodic bootstrap failed.");
                        }
                    });

                    token.ThrowIfCancellationRequested();
                }
            }

            SwarmCancellationToken = cancellationToken;

            try
            {
                var t = Swarm.StartAsync(
                    cancellationToken: cancellationToken,
                    millisecondsBroadcastTxInterval: 15000
                    );
                await Swarm.WaitForRunningAsync();

                await SubSwarm.BootstrapAsync(
                    new [] { Swarm.AsPeer },
                    PingSeedTimeout,
                    FindNeighborsTimeout,
                    1,
                    cancellationToken);

                await await Task.WhenAny(
                    t,
                    SubSwarm.StartAsync(
                        cancellationToken: cancellationToken,
                        millisecondsBroadcastTxInterval: 15000
                        ),
                    ReconnectToSeedPeers(cancellationToken)
                    );
            }
            catch (Exception e)
            {
                Log.Error(e, "Unexpected exception occurred during Swarm.StartAsync(). {e}", e);
            }
        }
        private async Task StartSwarm(bool preload, CancellationToken cancellationToken)
        {
            var peers = Properties.Peers.ToImmutableArray();

            Task BootstrapSwarmAsync(int depth)
            => Swarm.BootstrapAsync(
                peers,
                pingSeedTimeout: PingSeedTimeout,
                findNeighborsTimeout: FindNeighborsTimeout,
                depth: depth,
                cancellationToken: cancellationToken
                );

            // We assume the first phase of preloading is BlockHashDownloadState...
            ((IProgress <PreloadState>)PreloadProgress)?.Report(new BlockHashDownloadState());

            if (peers.Any())
            {
                try
                {
                    // FIXME: It's safe to increase depth.
                    await BootstrapSwarmAsync(1);

                    BootstrapEnded.Set();
                }
                catch (PeerDiscoveryException e)
                {
                    Log.Error(e, "Bootstrap failed: {Exception}", e);

                    if (!IgnoreBootstrapFailure)
                    {
                        throw;
                    }
                }

                if (preload)
                {
                    _preloadStatusHandlerAction(true);
                    try
                    {
                        await Swarm.PreloadAsync(
                            TimeSpan.FromSeconds(5),
                            PreloadProgress,
                            cancellationToken : cancellationToken
                            );
                    }
                    catch (AggregateException e)
                    {
                        Log.Error(e, "{Message}", e.Message);
                        if (!_ignorePreloadFailure)
                        {
                            throw;
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(
                            e,
                            $"An unexpected exception occurred during {nameof(Swarm.PreloadAsync)}: {{Message}}",
                            e.Message
                            );
                        if (!_ignorePreloadFailure)
                        {
                            throw;
                        }
                    }

                    PreloadEnded.Set();
                    _preloadStatusHandlerAction(false);
                }
            }
            else if (preload)
            {
                _preloadStatusHandlerAction(true);
                BootstrapEnded.Set();
                PreloadEnded.Set();
                _preloadStatusHandlerAction(false);
            }

            async Task ReconnectToSeedPeers(CancellationToken token)
            {
                while (!token.IsCancellationRequested)
                {
                    await Task.Delay(BootstrapInterval, token);
                    await BootstrapSwarmAsync(0).ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            Log.Information(t.Exception, "Periodic bootstrap failed.");
                        }
                    }, token);

                    token.ThrowIfCancellationRequested();
                }
            }

            SwarmCancellationToken = cancellationToken;

            try
            {
                if (peers.Any())
                {
                    await await Task.WhenAny(
                        Swarm.StartAsync(
                            cancellationToken: cancellationToken,
                            millisecondsBroadcastTxInterval: 15000
                            ),
                        ReconnectToSeedPeers(cancellationToken)
                        );
                }
                else
                {
                    await Swarm.StartAsync(
                        cancellationToken : cancellationToken,
                        millisecondsBroadcastTxInterval : 15000);
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Unexpected exception occurred during Swarm.StartAsync(). {e}", e);
            }
        }
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            var peers = _properties.Peers.ToImmutableArray();

            Task BootstrapSwarmAsync(int depth)
            => Swarm.BootstrapAsync(
                peers,
                pingSeedTimeout: PingSeedTimeout,
                findNeighborsTimeout: FindNeighborsTimeout,
                depth: depth,
                cancellationToken: cancellationToken
                );

            if (peers.Any())
            {
                try
                {
                    await BootstrapSwarmAsync(1);

                    BootstrapEnded.Set();
                }
                catch (PeerDiscoveryException e)
                {
                    Log.Error(e, "Bootstrap failed: {Exception}", e);

                    if (!_ignoreBootstrapFailure)
                    {
                        throw;
                    }
                }

                await Swarm.PreloadAsync(
                    TimeSpan.FromSeconds(5),
                    _preloadProgress,
                    _properties.TrustedStateValidators,
                    cancellationToken : cancellationToken
                    );

                PreloadEnded.Set();
            }
            else
            {
                BootstrapEnded.Set();
                PreloadEnded.Set();
            }

            async Task ReconnectToSeedPeers(CancellationToken token)
            {
                while (!token.IsCancellationRequested)
                {
                    await Task.Delay(BootstrapInterval);
                    await BootstrapSwarmAsync(0).ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            Log.Error(t.Exception, "Periodic bootstrap failed.");
                        }
                    });

                    token.ThrowIfCancellationRequested();
                }
            }

            _swarmCancellationToken = cancellationToken;
            try
            {
                await await Task.WhenAny(
                    Swarm.StartAsync(
                        cancellationToken: cancellationToken,
                        millisecondsBroadcastTxInterval: 15000
                        ),
                    ReconnectToSeedPeers(cancellationToken)
                    );
            }
            catch (Exception e)
            {
                Log.Error(e, "Unexpected exception occurred during Swarm.StartAsync(). {e}", e);
            }
        }