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);
            }
        }
        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);
            }
        }
        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);
            }
        }