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