Beispiel #1
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);
            }
        }