/// <inheritdoc />
        protected override void AttachCore()
        {
            this.logger.LogTrace("()");

            INetworkPeer peer         = this.AttachedPeer;
            var          peerBehavior = peer.Behavior <IConnectionManagerBehavior>();

            if (peer.State == NetworkPeerState.Connected && !peerBehavior.Whitelisted)
            {
                if (this.peerBanning.IsBanned(peer.RemoteSocketEndpoint))
                {
                    this.logger.LogDebug("Peer '{0}' was previously banned.", peer.RemoteSocketEndpoint);
                    peer.Disconnect("A banned node tried to connect.");
                    this.logger.LogTrace("(-)[PEER_BANNED]");
                    return;
                }
            }

            this.AttachedPeer.MessageReceived.Register(this.OnMessageReceivedAsync);
            this.chainHeadersBehavior      = this.AttachedPeer.Behaviors.Find <ChainHeadersBehavior>();
            this.connectionManagerBehavior = this.AttachedPeer.Behaviors.Find <IConnectionManagerBehavior>();
            this.eventHandlerRegistered    = true;

            this.logger.LogTrace("(-)");
        }
        protected override void AttachCore()
        {
            this.logger.LogTrace("()");

            this.AttachedPeer.StateChanged += this.AttachedNode_StateChanged;
            this.chainHeadersBehavior       = this.AttachedPeer.Behaviors.Find <ChainHeadersBehavior>();

            this.logger.LogTrace("(-)");
        }
Exemple #3
0
        protected override void AttachCore()
        {
            this.logger.LogTrace("()");

            this.AttachedPeer.MessageReceived.Register(this.OnMessageReceivedAsync);
            this.headersBehavior = this.AttachedPeer.Behavior <ChainHeadersBehavior>();

            this.logger.LogTrace("(-)");
        }
        public IActionResult Status()
        {
            StatusModel model = new StatusModel
            {
                Version           = this.fullNode.Version?.ToString() ?? "0",
                Agent             = this.nodeSettings.Agent,
                ProcessId         = Process.GetCurrentProcess().Id,
                Network           = this.fullNode.Network.Name,
                ConsensusHeight   = this.chainState.ConsensusTip.Height,
                DataDirectoryPath = this.nodeSettings.DataDir,
                RunningTime       = this.dateTimeProvider.GetUtcNow() - this.fullNode.StartTime
            };

            // Add the list of features that are enabled.
            foreach (IFullNodeFeature feature in this.fullNode.Services.Features)
            {
                model.EnabledFeatures.Add(feature.GetType().ToString());
            }

            // Include BlockStore Height if enabled
            if (this.chainState.BlockStoreTip != null)
            {
                model.BlockStoreHeight = this.chainState.BlockStoreTip.Height;
            }

            // Add the details of connected nodes.
            foreach (INetworkPeer peer in this.connectionManager.ConnectedPeers)
            {
                ConnectionManagerBehavior connectionManagerBehavior = peer.Behavior <ConnectionManagerBehavior>();
                ChainHeadersBehavior      chainHeadersBehavior      = peer.Behavior <ChainHeadersBehavior>();

                ConnectedPeerModel connectedPeer = new ConnectedPeerModel
                {
                    Version = peer.PeerVersion != null ? peer.PeerVersion.UserAgent : "[Unknown]",
                    RemoteSocketEndpoint = peer.RemoteSocketEndpoint.ToString(),
                    TipHeight            = chainHeadersBehavior.PendingTip != null ? chainHeadersBehavior.PendingTip.Height : peer.PeerVersion?.StartHeight ?? -1,
                    IsInbound            = connectionManagerBehavior.Inbound
                };

                if (connectedPeer.IsInbound)
                {
                    model.InboundPeers.Add(connectedPeer);
                }
                else
                {
                    model.OutboundPeers.Add(connectedPeer);
                }
            }

            return(this.Json(model));
        }
Exemple #5
0
        public string GetNodeStats()
        {
            var builder = new StringBuilder();

            foreach (Node node in this.ConnectedNodes)
            {
                ConnectionManagerBehavior connectionManagerBehavior = node.Behavior <ConnectionManagerBehavior>();
                ChainHeadersBehavior      chainHeadersBehavior      = node.Behavior <ChainHeadersBehavior>();
                builder.AppendLine(
                    "Node:" + (node.RemoteInfo() + ", ").PadRight(LogsExtension.ColumnLength + 15) +
                    (" connected" + " (" + (connectionManagerBehavior.Inbound ? "inbound" : "outbound") + "),").PadRight(LogsExtension.ColumnLength + 7) +
                    (" agent " + node.PeerVersion.UserAgent + ", ").PadRight(LogsExtension.ColumnLength + 2) +
                    " height=" + chainHeadersBehavior.PendingTip.Height);
            }
            return(builder.ToString());
        }
Exemple #6
0
        public string GetNodeStats()
        {
            var builder = new StringBuilder();

            foreach (INetworkPeer peer in this.ConnectedPeers)
            {
                ConnectionManagerBehavior connectionManagerBehavior = peer.Behavior <ConnectionManagerBehavior>();
                ChainHeadersBehavior      chainHeadersBehavior      = peer.Behavior <ChainHeadersBehavior>();

                string agent = peer.PeerVersion != null ? peer.PeerVersion.UserAgent : "[Unknown]";
                builder.AppendLine(
                    "Peer:" + (peer.RemoteSocketEndpoint + ", ").PadRight(LoggingConfiguration.ColumnLength + 15) +
                    (" connected:" + (connectionManagerBehavior.Inbound ? "inbound" : "outbound") + ",").PadRight(LoggingConfiguration.ColumnLength + 7) +
                    (" height:" + (chainHeadersBehavior.PendingTip != null ? chainHeadersBehavior.PendingTip.Height.ToString() : peer.PeerVersion?.StartHeight.ToString() ?? "unknown") + ",").PadRight(LoggingConfiguration.ColumnLength + 2) +
                    " agent:" + agent);
            }

            return(builder.ToString());
        }
        public string GetNodeStats()
        {
            var builder = new StringBuilder();

            foreach (NetworkPeer node in this.ConnectedPeers)
            {
                ConnectionManagerBehavior connectionManagerBehavior = node.Behavior <ConnectionManagerBehavior>();
                ChainHeadersBehavior      chainHeadersBehavior      = node.Behavior <ChainHeadersBehavior>();

                string agent = node.PeerVersion != null ? node.PeerVersion.UserAgent : "[Unknown]";
                builder.AppendLine(
                    "Peer:" + (node.RemoteInfo() + ", ").PadRight(LoggingConfiguration.ColumnLength + 15) +
                    (" connected" + " (" + (connectionManagerBehavior.Inbound ? "inbound" : "outbound") + "),").PadRight(LoggingConfiguration.ColumnLength + 7) +
                    (" agent " + agent + ", ").PadRight(LoggingConfiguration.ColumnLength + 2) +
                    " height=" + (chainHeadersBehavior.PendingTip != null ? chainHeadersBehavior.PendingTip.Height.ToString() : "unknown"));
            }

            return(builder.ToString());
        }
Exemple #8
0
        /// <inheritdoc />
        protected override void AttachCore()
        {
            this.logger.LogTrace("()");

            var peer = this.AttachedPeer;

            if (peer.State == NetworkPeerState.Connected)
            {
                if (this.peerBanning.IsBanned(peer.RemoteSocketEndpoint))
                {
                    this.logger.LogDebug("Peer '{0}' was previously banned.", peer.RemoteSocketEndpoint);
                    peer.Disconnect("A banned node tried to connect.");
                    return;
                }
            }

            this.AttachedPeer.MessageReceived += this.AttachedNode_MessageReceived;
            this.chainHeadersBehavior          = this.AttachedPeer.Behaviors.Find <ChainHeadersBehavior>();
            this.connectionManagerBehavior     = this.AttachedPeer.Behaviors.Find <ConnectionManagerBehavior>();

            this.logger.LogTrace("(-)");
        }
        /// <inheritdoc />
        protected override void AttachCore()
        {
            this.logger.LogTrace("()");

            var node = this.AttachedNode;

            if (node.State == NodeState.Connected)
            {
                if (this.peerBanning.IsBanned(node.RemoteSocketEndpoint))
                {
                    this.logger.LogDebug("Node '{0}' was previously banned.", node.RemoteSocketEndpoint);
                    node.DisconnectAsync("A banned node tried to connect.");
                    return;
                }
            }

            this.AttachedNode.MessageReceived += this.AttachedNode_MessageReceived;
            this.chainHeadersBehavior          = this.AttachedNode.Behaviors.Find <ChainHeadersBehavior>();
            this.connectionManagerBehavior     = this.AttachedNode.Behaviors.Find <ConnectionManagerBehavior>();

            this.logger.LogTrace("(-)");
        }
        /// <summary>
        /// Processes "getblocks" message received from the peer.
        /// </summary>
        /// <param name="peer">Peer that sent the message.</param>
        /// <param name="getBlocksPayload">Payload of "getblocks" message to process.</param>
        private async Task ProcessGetBlocksAsync(INetworkPeer peer, GetBlocksPayload getBlocksPayload)
        {
            this.logger.LogTrace("({0}:'{1}',{2}:'{3}')", nameof(peer), peer.RemoteSocketEndpoint, nameof(getBlocksPayload), getBlocksPayload);

            // We only want to work with blocks that are in the store,
            // so we first get information about the store's tip.
            ChainedBlock blockStoreTip = this.chain.GetBlock(this.blockRepository.BlockHash);

            if (blockStoreTip == null)
            {
                this.logger.LogTrace("(-)[REORG]");
                return;
            }

            this.logger.LogTrace("Block store tip is '{0}'.", blockStoreTip);

            // Now we want to find the last common block between our chain and the block locator the peer sent us.
            ChainedBlock chainTip  = this.chain.Tip;
            ChainedBlock forkPoint = null;

            // Find last common block between our chain and the block locator the peer sent us.
            while (forkPoint == null)
            {
                forkPoint = this.chain.FindFork(getBlocksPayload.BlockLocators.Blocks);
                if (forkPoint == null)
                {
                    this.logger.LogTrace("(-)[NO_FORK_POINT]");
                    return;
                }

                // In case of reorg, we just try again, eventually we succeed.
                if (chainTip.FindAncestorOrSelf(forkPoint) == null)
                {
                    chainTip  = this.chain.Tip;
                    forkPoint = null;
                }
            }

            this.logger.LogTrace("Fork point is '{0}'.", forkPoint);

            // If block store is lower than the fork point, or it is on different chain, we don't have anything to contribute to this peer at this point.
            if (blockStoreTip.FindAncestorOrSelf(forkPoint) == null)
            {
                this.logger.LogTrace("(-)[FORK_OUTSIDE_STORE]");
                return;
            }

            // Now we compile a list of blocks we want to send to the peer as inventory vectors.
            // This is needed as we want to traverse the chain in forward direction.
            int          maxHeight    = Math.Min(blockStoreTip.Height, forkPoint.Height + InvPayload.MaxGetBlocksInventorySize);
            ChainedBlock lastBlock    = blockStoreTip.GetAncestor(maxHeight);
            int          headersCount = maxHeight - forkPoint.Height;

            this.logger.LogTrace("Last block to announce is '{0}', number of blocks to announce is {1}.", lastBlock, headersCount);

            ChainedBlock[] headersToAnnounce = new ChainedBlock[headersCount];
            for (int i = headersCount - 1; i >= 0; i--)
            {
                headersToAnnounce[i] = lastBlock;
                lastBlock            = lastBlock.Previous;
            }

            // Now we compile inventory payload and we also consider hash stop given by the peer.
            bool         sendContinuation      = true;
            ChainedBlock lastAddedChainedBlock = null;
            var          inv = new InvPayload();

            for (int i = 0; i < headersToAnnounce.Length; i++)
            {
                ChainedBlock chainedBlock = headersToAnnounce[i];
                if (chainedBlock.HashBlock == getBlocksPayload.HashStop)
                {
                    this.logger.LogTrace("Hash stop has been reached.");
                    break;
                }

                this.logger.LogTrace("Adding block '{0}' to the inventory.", chainedBlock);
                lastAddedChainedBlock = chainedBlock;
                inv.Inventory.Add(new InventoryVector(InventoryType.MSG_BLOCK, chainedBlock.HashBlock));
                if (chainedBlock.HashBlock == chainTip.HashBlock)
                {
                    this.logger.LogTrace("Tip of the chain has been reached.");
                    sendContinuation = false;
                }
            }

            int count = inv.Inventory.Count;

            if (count > 0)
            {
                ChainHeadersBehavior chainBehavior = peer.Behavior <ChainHeadersBehavior>();
                ChainedBlock         peerTip       = chainBehavior.PendingTip;

                int peersHeight = peerTip != null ? peerTip.Height : 0;
                if (peersHeight < lastAddedChainedBlock.Height)
                {
                    this.logger.LogTrace("Setting peer's pending tip to '{0}'.", lastAddedChainedBlock);
                    chainBehavior.SetPendingTip(lastAddedChainedBlock);

                    // Set last item of the batch (unless we are announcing the tip), which is then used
                    // when the peer sends us "getdata" message. When we detect "getdata" message for this block,
                    // we will send continuation inventory message. This will cause the peer to ask for another batch of blocks.
                    // See ProcessGetDataAsync method.
                    if (sendContinuation)
                    {
                        this.getBlocksBatchLastItemHash = lastAddedChainedBlock.HashBlock;
                    }
                }

                this.logger.LogTrace("Sending inventory with {0} block hashes.", count);
                await peer.SendMessageAsync(inv).ConfigureAwait(false);
            }
            else
            {
                this.logger.LogTrace("Nothing to send.");
            }

            this.logger.LogTrace("(-)");
        }