示例#1
0
 /// <inheritdoc/>
 public void Start()
 {
     this.asyncLoop = this.asyncLoopFactory.Run("Notify", async token =>
     {
         await this.Notify(this.nodeLifetime.ApplicationStopping);
     },
                                                this.nodeLifetime.ApplicationStopping);
 }
示例#2
0
 /// <inheritdoc />
 public void Start()
 {
     this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop(nameof(PartialTransactionRequester), async token => {
         await this.BroadcastPartialTransactionsAsync().ConfigureAwait(false);
     },
                                                               this.nodeLifetime.ApplicationStopping,
                                                               TimeBetweenQueries);
 }
 ///<inheritdoc/>
 public void StopMining()
 {
     this.miningCancellationTokenSource.Cancel();
     this.miningLoop?.Dispose();
     this.miningLoop = null;
     this.miningCancellationTokenSource.Dispose();
     this.miningCancellationTokenSource = null;
 }
 /// <inheritdoc />
 public void Stop()
 {
     if (this.asyncLoop != null)
     {
         this.asyncLoop.Dispose();
         this.asyncLoop = null;
     }
 }
 /// <inheritdoc/>
 public void Start()
 {
     this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop("Notify", async token =>
     {
         await this.Notify(this.nodeLifetime.ApplicationStopping);
     },
                                                               this.nodeLifetime.ApplicationStopping);
 }
 /// <inheritdoc />
 public void Start()
 {
     this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop(nameof(MempoolCleaner), async token => {
         await this.CleanMempoolAsync().ConfigureAwait(false);
     },
                                                               this.nodeLifetime.ApplicationStopping,
                                                               TimeBetweenQueries);
 }
示例#7
0
 /// <inheritdoc/>
 public void StartConnectAsync()
 {
     this.asyncLoop = this.asyncLoopFactory.Run($"{this.GetType().Name}.{nameof(this.ConnectAsync)}", async token =>
     {
         await this.ConnectAsync();
     },
                                                this.nodeLifetime.ApplicationStopping,
                                                repeatEvery: TimeSpans.Second);
 }
 /// <inheritdoc />
 public void Start()
 {
     this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop(nameof(PartialTransactionRequester), token => {
         this.BroadcastPartialTransactionsAsync().GetAwaiter().GetResult();
         return(Task.CompletedTask);
     },
                                                               this.nodeLifetime.ApplicationStopping,
                                                               TimeBetweenQueries);
 }
 /// <inheritdoc />
 public void Start()
 {
     this.broadcastFullySignedTransfersTask = this.asyncProvider.CreateAndRunAsyncLoop($"{nameof(SignedMultisigTransactionBroadcaster)}.{nameof(this.broadcastFullySignedTransfersTask)}", async token =>
     {
         await this.BroadcastFullySignedTransfersAsync().ConfigureAwait(false);
     },
                                                                                       this.nodeLifetime.ApplicationStopping,
                                                                                       repeatEvery: TimeSpan.FromSeconds(RefreshDelaySeconds));
 }
示例#10
0
 /// <summary>
 /// Starts the loop to refresh the whitelist.
 /// </summary>
 private void StartWhitelistRefreshLoop()
 {
     this.whitelistRefreshLoop = this.asyncLoopFactory.Run($"{nameof(DnsFeature)}.WhitelistRefreshLoop", token =>
     {
         this.whitelistManager.RefreshWhitelist();
         return(Task.CompletedTask);
     },
                                                           this.nodeLifetime.ApplicationStopping,
                                                           repeatEvery: TimeSpan.FromSeconds(30));
 }
示例#11
0
 /// <inheritdoc />
 public void Start()
 {
     this.asyncLoop = this.asyncLoopFactory.Run(nameof(PartialTransactionRequester), _ =>
     {
         this.BroadcastTransactionsAsync().GetAwaiter().GetResult();
         return(Task.CompletedTask);
     },
                                                this.nodeLifetime.ApplicationStopping,
                                                TimeBetweenQueries);
 }
 /// <summary>
 /// Executes DownloadAndStoreBlocks()
 /// </summary>
 private void StartLoop()
 {
     this.asyncLoop = this.asyncLoopFactory.Run($"{this.StoreName}.DownloadAndStoreBlocks", async token =>
     {
         await DownloadAndStoreBlocksAsync(this.nodeLifetime.ApplicationStopping, false).ConfigureAwait(false);
     },
                                                this.nodeLifetime.ApplicationStopping,
                                                repeatEvery: TimeSpans.Second,
                                                startAfter: TimeSpans.FiveSeconds);
 }
        /// <inheritdoc/>
        public void Initialize()
        {
            this.PrunedUpToHeaderTip = this.chainState.BlockStoreTip.GetAncestor(this.prunedBlockRepository.PrunedTip.Height);

            this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop($"{this.GetType().Name}.{nameof(this.PruneBlocksAsync)}", async token =>
            {
                await this.PruneBlocksAsync().ConfigureAwait(false);
            },
                                                                      this.nodeLifetime.ApplicationStopping,
                                                                      repeatEvery: TimeSpans.TenSeconds);
        }
示例#14
0
        /// <inheritdoc />
        public void Stop()
        {
            if (this.asyncLoop != null)
            {
                this.asyncLoop.Dispose();
                this.asyncLoop = null;
            }

            this.signals.OnTransactionReceived.Detach(this.ProcessTransaction);
            this.signals.OnBlockConnected.Detach(this.OnBlockConnected);
        }
示例#15
0
        /// <inheritdoc />
        public void Stop()
        {
            if (this.asyncLoop != null)
            {
                this.asyncLoop.Dispose();
                this.asyncLoop = null;
            }

            this.signals.Unsubscribe(this.transactionReceivedSubscription);
            this.signals.Unsubscribe(this.blockConnectedSubscription);
        }
        /// <summary>
        /// Starts a loop that warns user via console message about problems with system time settings.
        /// </summary>
        private void StartWarningLoop()
        {
            this.logger.LogTrace("()");

            this.warningLoop = this.asyncLoopFactory.Run($"{nameof(TimeSyncBehavior)}.WarningLoop", token =>
            {
                this.logger.LogTrace("()");

                if (!this.SwitchedOffLimitReached)
                {
                    bool timeOffsetWrong     = false;
                    double timeOffsetSeconds = 0;
                    lock (this.lockObject)
                    {
                        timeOffsetSeconds = this.timeOffset.TotalSeconds;
                        timeOffsetWrong   = timeOffsetSeconds > TimeOffsetWarningThresholdSeconds;
                    }

                    if (timeOffsetWrong)
                    {
                        this.logger.LogCritical(Environment.NewLine
                                                + "============================== W A R N I N G ! ==============================" + Environment.NewLine
                                                + "Your system time is very different from the time of other network nodes." + Environment.NewLine
                                                + "It differs from the network median time by {0} seconds." + Environment.NewLine
                                                + "To prevent problems, adjust your system time or check the -synctime command line argument," + Environment.NewLine
                                                + "and restart the node." + Environment.NewLine
                                                + "=============================================================================" + Environment.NewLine,
                                                timeOffsetSeconds);
                    }
                }
                else
                {
                    this.logger.LogCritical(Environment.NewLine
                                            + "============================== W A R N I N G ! ==============================" + Environment.NewLine
                                            + "Your system time is very different from the time of other network nodes." + Environment.NewLine
                                            + "Your time difference to the network median time is over the allowed maximum of {0} seconds." + Environment.NewLine
                                            + "The time syncing feature has been switched off as it is no longer considered safe." + Environment.NewLine
                                            + "It is likely that you will now reject new blocks or be unable to mine new blocks." + Environment.NewLine
                                            + "You need to adjust your system time or check the -synctime command line argument," + Environment.NewLine
                                            + "and restart the node." + Environment.NewLine
                                            + "=============================================================================" + Environment.NewLine,
                                            MaxTimeOffsetSeconds);
                }

                this.logger.LogTrace("(-)");
                return(Task.CompletedTask);
            },
                                                         this.nodeLifetime.ApplicationStopping,
                                                         repeatEvery: TimeSpan.FromSeconds(57.3), // Weird number to prevent collisions with some other periodic console outputs.
                                                         startAfter: TimeSpans.FiveSeconds);

            this.logger.LogTrace("(-)");
        }
示例#17
0
        /// <inheritdoc/>
        public void Initialize()
        {
            this.PrunedUpToHeaderTip = this.chainState.BlockStoreTip.GetAncestor(this.prunedBlockRepository.PrunedTip.Height);

            this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop($"{this.GetType().Name}.{nameof(this.PruneBlocks)}", token =>
            {
                this.PruneBlocks();
                return(Task.CompletedTask);
            },
                                                                      this.nodeLifetime.ApplicationStopping,
                                                                      repeatEvery: TimeSpans.TenSeconds);
        }
 /// <summary>
 /// Starts an asynchronous loop that periodicly tries to discover new peers to add to the
 /// <see cref="PeerAddressManager"/>.
 /// </summary>
 public void DiscoverPeers()
 {
     this.asyncLoop = this.asyncLoopFactory.Run(nameof(this.DiscoverPeersAsync), async token =>
     {
         if (this.peerAddressManager.Peers.Count < this.peersToFind)
         {
             await this.DiscoverPeersAsync();
         }
     },
                                                this.nodeLifetime.ApplicationStopping,
                                                TimeSpans.Minute);
 }
示例#19
0
        /// <inheritdoc />
        public void Mine(Script reserveScript)
        {
            if (this.miningLoop != null)
            {
                return;
            }

            this.miningCancellationTokenSource =
                CancellationTokenSource.CreateLinkedTokenSource(this.nodeLifetime.ApplicationStopping);

            this.miningLoop = this.asyncProvider.CreateAndRunAsyncLoop("PowMining.Mine", token =>
            {
                try
                {
                    GenerateBlocks(new ReserveScript {
                        ReserveFullNodeScript = reserveScript
                    }, int.MaxValue,
                                   int.MaxValue);
                }
                catch (OperationCanceledException)
                {
                    // Application stopping, nothing to do as the loop will be stopped.
                }
                catch (MinerException me)
                {
                    // Block not accepted by peers or invalid. Should not halt mining.
                    this.logger.LogDebug("Miner exception occurred in miner loop: {0}", me.ToString());
                }
                catch (ConsensusErrorException cee)
                {
                    // Issues constructing block or verifying it. Should not halt mining.
                    this.logger.LogDebug("Consensus error exception occurred in miner loop: {0}", cee.ToString());
                }
                catch (ConsensusException ce)
                {
                    // All consensus exceptions should be ignored. It means that the miner
                    // run into problems while constructing block or verifying it
                    // but it should not halted the staking operation.
                    this.logger.LogDebug("Consensus exception occurred in miner loop: {0}", ce.ToString());
                }
                catch
                {
                    this.logger.LogTrace("(-)[UNHANDLED_EXCEPTION]");
                    throw;
                }

                return(Task.CompletedTask);
            },
                                                                       this.miningCancellationTokenSource.Token,
                                                                       TimeSpans.Second,
                                                                       TimeSpans.TenSeconds);
        }
示例#20
0
        /// <summary>
        /// Initializes node's chain repository.
        /// Creates periodic task to persist changes to the database.
        /// </summary>
        private async Task StartChainAsync()
        {
            if (!Directory.Exists(this.dataFolder.ChainPath))
            {
                this.logger.LogInformation("Creating {0}.", this.dataFolder.ChainPath);
                Directory.CreateDirectory(this.dataFolder.ChainPath);
            }

            if (!Directory.Exists(this.dataFolder.KeyValueRepositoryPath))
            {
                this.logger.LogInformation("Creating {0}.", this.dataFolder.KeyValueRepositoryPath);
                Directory.CreateDirectory(this.dataFolder.KeyValueRepositoryPath);
            }

            this.logger.LogInformation("Loading finalized block height.");
            await this.finalizedBlockInfoRepository.LoadFinalizedBlockInfoAsync(this.network).ConfigureAwait(false);

            this.logger.LogInformation("Loading chain.");
            ChainedHeader chainTip = await this.chainRepository.LoadAsync(this.chainIndexer.Genesis).ConfigureAwait(false);

            this.chainIndexer.Initialize(chainTip);

            this.logger.LogInformation("Chain loaded at height {0}.", this.chainIndexer.Height);

            this.flushChainLoop = this.asyncProvider.CreateAndRunAsyncLoop("FlushChain", async token =>
            {
                await this.chainRepository.SaveAsync(this.chainIndexer).ConfigureAwait(false);

                if (this.provenBlockHeaderStore != null)
                {
                    await this.provenBlockHeaderStore.SaveAsync().ConfigureAwait(false);
                }

                // Get latest flags (often cached) and persist.
                if (this.consensusManager.Tip != null)
                {
                    var flags = this.nodeDeployments.GetFlags(this.consensusManager.Tip);

                    if (this.deploymentFlags == null || flags.ScriptFlags != this.deploymentFlags.ScriptFlags)
                    {
                        // Update the persistent disk cache of Flags when we retrieve it.
                        this.keyValueRepo.SaveValueJson("deploymentflags", flags);

                        // Update the local cached copy used to validate against. We don't want to persist to disk unless the flags actually has changed.
                        this.deploymentFlags = flags;
                    }
                }
            },
                                                                           this.nodeLifetime.ApplicationStopping,
                                                                           repeatEvery: TimeSpan.FromMinutes(1.0),
                                                                           startAfter: TimeSpan.FromMinutes(1.0));
        }
示例#21
0
        /// <inheritdoc />
        public override void Initialize()
        {
            this.connectionManager.Parameters.TemplateBehaviors.Add(new DropNodesBehaviour(this.chain, this.connectionManager, this.loggerFactory));

            this.walletManager.Start();
            this.walletSyncManager.Start();

            this.asyncLoop = this.StartDeploymentsChecksLoop();

            this.walletFeePolicy.Start();

            this.connectionManager.Parameters.TemplateBehaviors.Add(this.broadcasterBehavior);
        }
示例#22
0
        /// <summary>
        /// Starts the loop to refresh the whitelist.
        /// </summary>
        private void StartWhitelistRefreshLoop()
        {
            this.logger.LogTrace("()");

            this.whitelistRefreshLoop = this.asyncLoopFactory.Run($"{nameof(DnsFeature)}.WhitelistRefreshLoop", token =>
            {
                this.whitelistManager.RefreshWhitelist();
                return(Task.CompletedTask);
            },
                                                                  this.nodeLifetime.ApplicationStopping,
                                                                  repeatEvery: new TimeSpan(0, 0, 30));

            this.logger.LogTrace("(-)");
        }
示例#23
0
 public void Init(ClientEventBroadcasterSettings broadcasterSettings)
 {
     this.logger.LogDebug($"Initialising SignalR Broadcaster {this.GetType().Name}");
     this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop(
         $"Broadcast {this.GetType().Name}",
         async token =>
     {
         foreach (IClientEvent clientEvent in this.GetMessages())
         {
             await this.eventsHub.SendToClientsAsync(clientEvent).ConfigureAwait(false);
         }
     },
         this.nodeLifetime.ApplicationStopping,
         repeatEvery: TimeSpan.FromSeconds(Math.Max(broadcasterSettings.BroadcastFrequencySeconds, 5)));
 }
示例#24
0
        /// <inheritdoc/>
        public void StartConnectAsync(NetworkPeerConnectionParameters parameters, PeerAddressManagerBehaviourMode mode)
        {
            this.parentParameters = parameters;

            this.CurrentParameters = this.parentParameters.Clone();
            this.CurrentParameters.ConnectCancellation = this.nodeLifetime.ApplicationStopping;
            this.CurrentParameters.PeerAddressManagerBehaviour().Mode = mode;
            this.CurrentParameters.TemplateBehaviors.Add(new PeerConnectorBehaviour(this));

            this.asyncLoop = this.asyncLoopFactory.Run($"{this.GetType().Name}.{nameof(this.ConnectAsync)}", async token =>
            {
                await this.ConnectAsync();
            },
                                                       this.nodeLifetime.ApplicationStopping, repeatEvery: TimeSpans.Second);
        }
        /// <inheritdoc />
        public override Task InitializeAsync()
        {
            this.connectionManager.Parameters.TemplateBehaviors.Add(new DropNodesBehaviour(this.chain, this.connectionManager, this.loggerFactory));
            this.walletSettings.IsLightWallet = true;

            this.walletManager.Start();
            this.walletSyncManager.Start();

            this.asyncLoop = this.StartDeploymentsChecksLoop();

            this.walletFeePolicy.Start();

            this.connectionManager.Parameters.TemplateBehaviors.Add(this.broadcasterBehavior);
            return(Task.CompletedTask);
        }
示例#26
0
        private void StartFeeFilterBroadcast(INetworkPeer sender)
        {
            if (this.settings.FeeFilter)
            {
                INetworkPeer peer = sender;

                if (peer.PeerVersion != null &&
                    peer.PeerVersion.Relay &&
                    peer.PeerVersion.Version >= ProtocolVersion.FEEFILTER_VERSION)
                {
                    if (this.asyncLoop != null)
                    {
                        this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop($"MemoryPool.FeeFilter:{peer.Connection.Id}", async token =>
                        {
                            if (this.initialBlockDownloadState.IsInitialBlockDownload())
                            {
                                return;
                            }

                            var feeRate       = await this.mempoolManager.GetMempoolMinFeeAsync(MempoolValidator.DefaultMaxMempoolSize * 1000000).ConfigureAwait(false);
                            var currentFilter = feeRate.FeePerK;

                            // We always have a fee filter of at least minRelayTxFee
                            Money filterToSend = Math.Max(currentFilter, new FeeRate(this.network.MinRelayTxFee).FeePerK);

                            if (filterToSend != this.lastSendFilter)
                            {
                                INetworkPeer peer = this.AttachedPeer;

                                if (peer != null && peer.IsConnected)
                                {
                                    this.logger.LogDebug("Sending for transaction data from peer '{0}'.", peer.RemoteSocketEndpoint);
                                    var filterPayload = new FeeFilterPayload()
                                    {
                                        NewFeeFilter = filterToSend
                                    };
                                    await peer.SendMessageAsync(filterPayload).ConfigureAwait(false);
                                    this.lastSendFilter = filterToSend;
                                }
                            }
                        },
                                                                                  this.nodeLifetime.ApplicationStopping,
                                                                                  repeatEvery: TimeSpan.FromMinutes(10),
                                                                                  startAfter: TimeSpans.TenSeconds);
                    }
                }
            }
        }
示例#27
0
        private async Task OnStateChangedAsync(INetworkPeer sender, NetworkPeerState arg)
        {
            if (arg == NetworkPeerState.HandShaked)
            {
                this.StartFeeFilterBroadcast(sender);
            }

            if (arg == NetworkPeerState.Disconnecting)
            {
                if (this.asyncLoop != null)
                {
                    this.asyncLoop?.Dispose();
                    this.asyncLoop = null;
                }
            }
        }
示例#28
0
        /// <summary>
        /// Starts the loop to save the masterfile.
        /// </summary>
        private void StartSaveMasterfileLoop()
        {
            this.saveMasterfileLoop = this.asyncProvider.CreateAndRunAsyncLoop($"{nameof(DnsFeature)}.WhitelistRefreshLoop", token =>
            {
                string path = Path.Combine(this.dataFolders.DnsMasterFilePath, DnsFeature.DnsMasterFileName);

                this.logger.LogInformation("Saving cached DNS masterfile to {0}", path);

                using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
                {
                    this.MasterFile.Save(stream);
                }
                return(Task.CompletedTask);
            },
                                                                               this.nodeLifetime.ApplicationStopping,
                                                                               repeatEvery: TimeSpan.FromSeconds(SaveMasterfileRate));
        }
        public void Init(ClientEventBroadcasterSettings broadcasterSettings)
        {
            this.log.LogDebug($"Initialising Web Socket Broadcaster {this.GetType().Name}");

            this.asyncLoop = this.asyncProvider.CreateAndRunAsyncLoop(
                $"Broadcast {this.GetType().Name}",
                async token =>
            {
                foreach (EventBase clientEvent in this.GetMessages())
                {
                    this.eventsHub.OnEvent(clientEvent);
                }
            },
                this.nodeLifetime.ApplicationStopping,
                repeatEvery: TimeSpan.FromSeconds(Math.Max(broadcasterSettings.BroadcastFrequencySeconds, 5)),
                startAfter: TimeSpans.FiveSeconds);
        }
示例#30
0
        /// <summary>
        /// Starts a loop to periodically log statistics about node's status very couple of seconds.
        /// <para>
        /// These logs are also displayed on the console.
        /// </para>
        /// </summary>
        private void StartPeriodicLog()
        {
            IAsyncLoop periodicLogLoop = this.AsyncLoopFactory.Run("PeriodicLog", (cancellation) =>
            {
                string stats = this.nodeStats.GetStats();

                this.logger.LogInformation(stats);
                this.LastLogOutput = stats;

                return(Task.CompletedTask);
            },
                                                                   this.nodeLifetime.ApplicationStopping,
                                                                   repeatEvery: TimeSpans.FiveSeconds,
                                                                   startAfter: TimeSpans.FiveSeconds);

            this.Resources.Add(periodicLogLoop);
        }