private void StartNodeServer() { var logs = new StringBuilder(); logs.AppendLine("Node listening on:"); foreach (NodeServerEndpoint listen in this.ConnectionSettings.Listen) { NetworkPeerConnectionParameters cloneParameters = this.Parameters.Clone(); NetworkPeerServer server = this.NetworkPeerFactory.CreateNetworkPeerServer(listen.Endpoint, this.ConnectionSettings.ExternalEndpoint); this.Servers.Add(server); cloneParameters.TemplateBehaviors.Add(new ConnectionManagerBehavior(true, this, this.loggerFactory) { Whitelisted = listen.Whitelisted }); server.InboundNetworkPeerConnectionParameters = cloneParameters; try { server.Listen(); } catch (SocketException e) { this.logger.LogCritical("Unable to listen on port {0} (you can change the port using '-port=[number]'). Error message: {1}", listen.Endpoint.Port, e.Message); throw e; } logs.Append(listen.Endpoint.Address + ":" + listen.Endpoint.Port); if (listen.Whitelisted) { logs.Append(" (whitelisted)"); } logs.AppendLine(); } this.logger.LogInformation(logs.ToString()); }
/// <summary> /// Initializes node's address manager. Loads previously known peers from the file /// or creates new peer file if it does not exist. Creates periodic task to persist changes /// in peers to disk. /// </summary> void StartAddressManager(NetworkPeerConnectionParameters connectionParameters) { var addressManagerBehaviour = new PeerAddressManagerBehaviour(this.dateTimeProvider, this.peerAddressManager, this.peerBanning, this.loggerFactory); connectionParameters.TemplateBehaviors.Add(addressManagerBehaviour); if (File.Exists(Path.Combine(this.dataFolder.AddressManagerFilePath, PeerAddressManager.PeerFileName))) { this.logger.LogInformation($"Loading peers from : {this.dataFolder.AddressManagerFilePath}."); this.peerAddressManager.LoadPeers(); } this.flushAddressManagerLoop = this.asyncProvider.CreateAndRunAsyncLoop("Periodic peer flush", token => { this.peerAddressManager.SavePeers(); return(Task.CompletedTask); }, this.nodeLifetime.ApplicationStopping, TimeSpan.FromMinutes(5.0), TimeSpan.FromMinutes(5.0)); }
/// <inheritdoc /> public override async Task InitializeAsync() { this.dbreezeSerializer.Initialize(this.chain.Network); await this.StartChainAsync().ConfigureAwait(false); NetworkPeerConnectionParameters connectionParameters = this.connectionManager.Parameters; connectionParameters.IsRelay = this.connectionManager.ConnectionSettings.RelayTxes; connectionParameters.TemplateBehaviors.Add(new PingPongBehavior()); connectionParameters.TemplateBehaviors.Add(new ConsensusManagerBehavior(this.chain, this.initialBlockDownloadState, this.consensusManager, this.peerBanning, this.loggerFactory)); connectionParameters.TemplateBehaviors.Add(new PeerBanningBehavior(this.loggerFactory, this.peerBanning, this.nodeSettings)); connectionParameters.TemplateBehaviors.Add(new BlockPullerBehavior(this.blockPuller, this.initialBlockDownloadState, this.dateTimeProvider, this.loggerFactory)); connectionParameters.TemplateBehaviors.Add(new ConnectionManagerBehavior(this.connectionManager, this.loggerFactory)); this.StartAddressManager(connectionParameters); if (this.connectionManager.ConnectionSettings.SyncTimeEnabled) { connectionParameters.TemplateBehaviors.Add(new TimeSyncBehavior(this.timeSyncBehaviorState, this.dateTimeProvider, this.loggerFactory)); } else { this.logger.LogDebug("Time synchronization with peers is disabled."); } // Block store must be initialized before consensus manager. // This may be a temporary solution until a better way is found to solve this dependency. await this.blockStore.InitializeAsync().ConfigureAwait(false); await this.consensusRules.InitializeAsync(this.chain.Tip).ConfigureAwait(false); this.consensusRules.Register(); await this.consensusManager.InitializeAsync(this.chain.Tip).ConfigureAwait(false); this.chainState.ConsensusTip = this.consensusManager.Tip; }
public ConnectionManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, Network network, INetworkPeerFactory networkPeerFactory, NodeSettings nodeSettings, INodeLifetime nodeLifetime, NetworkPeerConnectionParameters parameters, IPeerAddressManager peerAddressManager, IEnumerable <IPeerConnector> peerConnectors, IPeerDiscovery peerDiscovery, ConnectionManagerSettings connectionSettings, IVersionProvider versionProvider) { this.connectedPeers = new NetworkPeerCollection(); this.dateTimeProvider = dateTimeProvider; this.loggerFactory = loggerFactory; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.Network = network; this.NetworkPeerFactory = networkPeerFactory; this.NodeSettings = nodeSettings; this.nodeLifetime = nodeLifetime; this.peerAddressManager = peerAddressManager; this.PeerConnectors = peerConnectors; this.peerDiscovery = peerDiscovery; this.ConnectionSettings = connectionSettings; this.networkPeerDisposer = new NetworkPeerDisposer(this.loggerFactory); this.Servers = new List <NetworkPeerServer>(); this.Parameters = parameters; this.Parameters.ConnectCancellation = this.nodeLifetime.ApplicationStopping; this.versionProvider = versionProvider; this.Parameters.UserAgent = $"{this.NodeSettings.Agent}:{versionProvider.GetVersion()}"; this.Parameters.Version = this.NodeSettings.ProtocolVersion; this.downloads = new Dictionary <INetworkPeer, PerformanceSnapshot>(); }
public override async Task InitializeAsync() { // Set up our database of deposit and withdrawal transactions. Needs to happen before everything else. this.crossChainTransferStore.Initialize(); // Load the federation wallet that will be used to generate transactions. this.federationWalletManager.Start(); // Query the other chain every N seconds for deposits. Triggers signing process if deposits are found. this.maturedBlocksSyncManager.Start(); // Syncs the wallet correctly when restarting the node. i.e. deals with reorgs. this.walletSyncManager.Initialize(); // Synchronises the wallet and the transfer store. this.crossChainTransferStore.Start(); // Query our database for partially-signed transactions and send them around to be signed every N seconds. this.partialTransactionRequester.Start(); // Query our database for fully-signed transactions and broadcast them every N seconds. this.signedBroadcaster.Start(); // Check that the feature is configured correctly before going any further. this.CheckConfiguration(); // Connect the node to the other federation members. foreach (IPEndPoint federationMemberIp in this.federatedPegSettings.FederationNodeIpEndPoints) { this.connectionManager.AddNodeAddress(federationMemberIp, true); } // Respond to requests to sign transactions from other nodes. NetworkPeerConnectionParameters networkPeerConnectionParameters = this.connectionManager.Parameters; networkPeerConnectionParameters.TemplateBehaviors.Add(new PartialTransactionsBehavior(this.loggerFactory, this.federationWalletManager, this.network, this.federatedPegSettings, this.crossChainTransferStore, this.inputConsolidator)); }
/// <summary>Constructor used by <see cref="Connection.ConnectionManager"/>.</summary> protected PeerConnector( IAsyncLoopFactory asyncLoopFactory, ILogger logger, Network network, INetworkPeerFactory networkPeerFactory, INodeLifetime nodeLifeTime, NodeSettings nodeSettings, NetworkPeerConnectionParameters parameters, IPeerAddressManager peerAddressManager) { this.asyncLoopFactory = asyncLoopFactory; this.ConnectedPeers = new NetworkPeerCollection(); this.network = network; this.networkPeerFactory = networkPeerFactory; this.nodeLifetime = nodeLifeTime; this.NodeSettings = nodeSettings; this.parentParameters = parameters; this.peerAddressManager = peerAddressManager; this.CurrentParameters = this.parentParameters.Clone(); this.CurrentParameters.TemplateBehaviors.Add(new PeerConnectorBehaviour(this)); this.CurrentParameters.ConnectCancellation = this.nodeLifetime.ApplicationStopping; }
public void RequestPeerServices_PeersThatDontSupportNewServicesAreRemoved() { Mock <INetworkPeer> peer1 = this.helper.CreatePeerMock(out ExtendedBlockPullerBehavior behavior1); Mock <INetworkPeer> peer2 = this.helper.CreatePeerMock(out ExtendedBlockPullerBehavior behavior2); List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(5); this.puller.NewPeerTipClaimed(peer1.Object, headers.Last()); this.puller.NewPeerTipClaimed(peer2.Object, headers.Last()); Assert.Equal(2, this.puller.PullerBehaviorsByPeerId.Count); VersionPayload version = new NetworkPeerConnectionParameters().CreateVersion(new IPEndPoint(1, 1), new IPEndPoint(1, 1), KnownNetworks.StratisMain, new DateTimeProvider().GetTimeOffset()); version.Services = NetworkPeerServices.Network | NetworkPeerServices.NODE_WITNESS; peer1.SetupGet(x => x.PeerVersion).Returns(version); this.puller.RequestPeerServices(NetworkPeerServices.NODE_WITNESS); Assert.Equal(1, this.puller.PullerBehaviorsByPeerId.Count); }
/// <summary>Creates a peer with extended puller behavior.</summary> public Mock <INetworkPeer> CreatePeerMock(out ExtendedBlockPullerBehavior mockedBehavior, bool notSupportedVersion = false) { var peer = new Mock <INetworkPeer>(); var signals = new Blockcore.Signals.Signals(this.loggerFactory, null); var asyncProvider = new AsyncProvider(this.loggerFactory, signals, new NodeLifetime()); var connection = new NetworkPeerConnection(KnownNetworks.StratisMain, peer.Object, new TcpClient(), this.currentPeerId, (message, token) => Task.CompletedTask, new DateTimeProvider(), this.loggerFactory, new PayloadProvider(), asyncProvider); this.currentPeerId++; peer.SetupGet(networkPeer => networkPeer.Connection).Returns(connection); var connectionParameters = new NetworkPeerConnectionParameters(); VersionPayload version = connectionParameters.CreateVersion(new IPEndPoint(1, 1), new IPEndPoint(1, 1), KnownNetworks.StratisMain, new DateTimeProvider().GetTimeOffset()); if (notSupportedVersion) { version.Version = ProtocolVersion.MIN_PEER_PROTO_VERSION; } else { version.Services = NetworkPeerServices.Network; } peer.SetupGet(x => x.PeerVersion).Returns(version); peer.SetupGet(x => x.State).Returns(NetworkPeerState.HandShaked); peer.SetupGet(x => x.MessageReceived).Returns(new AsyncExecutionEvent <INetworkPeer, IncomingMessage>()); ExtendedBlockPullerBehavior behavior = this.CreateBlockPullerBehavior(); behavior.Attach(peer.Object); peer.Setup(x => x.Behavior <IBlockPullerBehavior>()).Returns(() => behavior); mockedBehavior = behavior; return(peer); }
private Mock <INetworkPeer> CreatePeerMock() { var peer = new Mock <INetworkPeer>(); var signals = new Bitcoin.Signals.Signals(this.loggerFactory, null); var asyncProvider = new AsyncProvider(this.loggerFactory, signals, new NodeLifetime()); var connection = new NetworkPeerConnection(KnownNetworks.StraxMain, peer.Object, new TcpClient(), 0, (message, token) => Task.CompletedTask, new DateTimeProvider(), this.loggerFactory, new PayloadProvider(), asyncProvider); peer.SetupGet(networkPeer => networkPeer.Connection).Returns(connection); var connectionParameters = new NetworkPeerConnectionParameters(); VersionPayload version = connectionParameters.CreateVersion(new IPEndPoint(1, 1), new IPEndPoint(1, 1), KnownNetworks.StraxMain, new DateTimeProvider().GetTimeOffset()); version.Services = NetworkPeerServices.Network; peer.SetupGet(x => x.PeerVersion).Returns(version); peer.SetupGet(x => x.State).Returns(NetworkPeerState.HandShaked); this.StateChanged = new AsyncExecutionEvent <INetworkPeer, NetworkPeerState>(); this.MessageReceived = new AsyncExecutionEvent <INetworkPeer, IncomingMessage>(); peer.Setup(x => x.StateChanged).Returns(() => this.StateChanged); peer.Setup(x => x.MessageReceived).Returns(() => this.MessageReceived); var connectionManagerBehaviorMock = new Mock <IConnectionManagerBehavior>(); connectionManagerBehaviorMock.Setup(x => x.Whitelisted).Returns(this.IsPeerWhitelisted); peer.Setup(x => x.Behavior <IConnectionManagerBehavior>()).Returns(() => connectionManagerBehaviorMock.Object); peer.SetupGet(x => x.PeerEndPoint).Returns(new IPEndPoint(1, 1)); return(peer); }
/// <inheritdoc /> public override Task InitializeAsync() { NetworkPeerConnectionParameters connectionParameters = this.connectionManager.Parameters; var defaultConsensusManagerBehavior = connectionParameters.TemplateBehaviors.FirstOrDefault(behavior => behavior is ConsensusManagerBehavior); if (defaultConsensusManagerBehavior == null) { throw new MissingServiceException(typeof(ConsensusManagerBehavior), "Missing expected ConsensusManagerBehavior."); } // Replace default ConsensusManagerBehavior with ProvenHeadersConsensusManagerBehavior // Temporary disabled in impleum until soft fork is done if (this.network.IsImpleum()) { return(Task.CompletedTask); } connectionParameters.TemplateBehaviors.Remove(defaultConsensusManagerBehavior); connectionParameters.TemplateBehaviors.Add(new ProvenHeadersConsensusManagerBehavior(this.chainIndexer, this.initialBlockDownloadState, this.consensusManager, this.peerBanning, this.loggerFactory, this.network, this.chainState, this.checkpoints, this.provenBlockHeaderStore, this.connectionManagerSettings)); connectionParameters.TemplateBehaviors.Add(new ProvenHeadersReservedSlotsBehavior(this.connectionManager, this.loggerFactory)); return(Task.CompletedTask); }
private IPeerConnector CreatePeerConnector( NetworkPeerConnectionParameters parameters, NetworkPeerServices requiredServices, Func <IPEndPoint, byte[]> peerSelector, PeerIntroductionType peerIntroductionType, int?maximumNodeConnections = 8) { this.logger.LogTrace("({0}:{1})", nameof(requiredServices), requiredServices); var nodeRequirement = new NetworkPeerRequirement { MinVersion = this.NodeSettings.ProtocolVersion, RequiredServices = requiredServices, }; var peerConnector = new PeerConnector(this.Network, this.nodeLifetime, parameters, nodeRequirement, peerSelector, this.asyncLoopFactory, this.peerAddressManager, peerIntroductionType, this.networkPeerFactory) { MaximumNodeConnections = maximumNodeConnections.Value }; this.logger.LogTrace("(-)"); return(peerConnector); }
public override Task InitializeAsync() { // Subscribe to receiving blocks and transactions. this.blockSubscriberDisposable = this.signals.SubscribeForBlocksConnected( new BlockObserver( this.walletSyncManager, this.depositExtractor, this.withdrawalExtractor, this.withdrawalReceiver, this.maturedBlockSender, this.maturedBlocksProvider, this.blockTipSender)); this.transactionSubscriberDisposable = this.signals.SubscribeForTransactions(new TransactionObserver(this.walletSyncManager)); this.crossChainTransferStore.Initialize(); this.federationWalletManager.Start(); this.walletSyncManager.Start(); this.crossChainTransferStore.Start(); this.partialTransactionRequester.Start(); this.maturedBlockRequester.Start(); // Connect the node to the other federation members. foreach (IPEndPoint federationMemberIp in this.federationGatewaySettings.FederationNodeIpEndPoints) { this.connectionManager.AddNodeAddress(federationMemberIp); } NetworkPeerConnectionParameters networkPeerConnectionParameters = this.connectionManager.Parameters; networkPeerConnectionParameters.TemplateBehaviors.Add(new PartialTransactionsBehavior(this.loggerFactory, this.federationWalletManager, this.network, this.federationGatewaySettings, this.crossChainTransferStore)); return(Task.CompletedTask); }
public void PeerConnectorDiscovery_ConnectsTo_NodeInSameNetworkGroup_WithIpRangeFilteringDisabled() { // IpRangeFiltering enabled by default, disabled explicitly. var nodeSettings = new NodeSettings(this.Network, args: new[] { "-IpRangeFiltering=false" }); var connectionManagerSettingsExisting = new ConnectionManagerSettings(nodeSettings); DataFolder peerFolder = CreateDataFolder(this); var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, peerFolder, this.extendedLoggerFactory, new SelfEndpointTracker(this.extendedLoggerFactory, connectionManagerSettingsExisting)); Mock <INetworkPeerFactory> networkPeerFactoryExisting = new Mock <INetworkPeerFactory>(); Mock <IConnectionManager> connectionManagerExisting = new Mock <IConnectionManager>(); var networkPeerParameters = new NetworkPeerConnectionParameters(); networkPeerParameters.TemplateBehaviors.Add(new ConnectionManagerBehavior(connectionManagerExisting.Object, this.extendedLoggerFactory)); connectionManagerExisting.SetupGet(np => np.Parameters).Returns(networkPeerParameters); connectionManagerExisting.SetupGet(np => np.ConnectedPeers).Returns(new NetworkPeerCollection()); var peerConnector = new PeerConnectorDiscovery(this.asyncProvider, DateTimeProvider.Default, this.extendedLoggerFactory, this.Network, networkPeerFactoryExisting.Object, this.nodeLifetime, nodeSettings, connectionManagerSettingsExisting, peerAddressManager, new SelfEndpointTracker(this.extendedLoggerFactory, connectionManagerSettingsExisting)); peerConnector.Initialize(connectionManagerExisting.Object); //Peer 1. IPAddress originalAddressPeer1 = IPAddress.Parse("::ffff:57.48.183.81"); // ipv4 var endpointPeer1 = new IPEndPoint(originalAddressPeer1, 80); peerAddressManager.AddPeer(endpointPeer1, IPAddress.Loopback); bool connectedToThisPeer = ConnectToPeer(peerAddressManager, networkPeerFactoryExisting, connectionManagerSettingsExisting, peerConnector, endpointPeer1, connectionManagerExisting); Assert.True(connectedToThisPeer); // Peer 2 has different network group to Peer 1. IPAddress addressInDifferentNetworkGroupPeer2 = IPAddress.Parse("99be:f5c5:adc2:525c:f6d7:7b30:5336:5a0f"); // ipv6 var endpointPeer2 = new IPEndPoint(addressInDifferentNetworkGroupPeer2, 80); peerAddressManager.AddPeer(endpointPeer2, IPAddress.Loopback); connectedToThisPeer = ConnectToPeer(peerAddressManager, networkPeerFactoryExisting, connectionManagerSettingsExisting, peerConnector, endpointPeer2, connectionManagerExisting); Assert.True(connectedToThisPeer); // Different network group: connects. // Peer 3 in same network group as Peer 2. IPAddress addressInSameNetworkGroupPeer3 = IPAddress.Parse("99be:f5c5:adc2:525c:db45:d36e:ce01:a394"); // ipv6 var endpointPeer3 = new IPEndPoint(addressInSameNetworkGroupPeer3, 80); peerAddressManager.AddPeer(endpointPeer3, IPAddress.Loopback); connectedToThisPeer = ConnectToPeer(peerAddressManager, networkPeerFactoryExisting, connectionManagerSettingsExisting, peerConnector, endpointPeer3, connectionManagerExisting); Assert.True(connectedToThisPeer); // Same network group: connects. // Peer 4 has different network group to Peer 1. IPAddress addressInDifferentNetworkGroupPeer4 = IPAddress.Parse("::ffff:58.48.183.81"); // ipv4 var endpointPeer4 = new IPEndPoint(addressInDifferentNetworkGroupPeer4, 80); peerAddressManager.AddPeer(endpointPeer4, IPAddress.Loopback); connectedToThisPeer = ConnectToPeer(peerAddressManager, networkPeerFactoryExisting, connectionManagerSettingsExisting, peerConnector, endpointPeer4, connectionManagerExisting); Assert.True(connectedToThisPeer); // Different network group: connects. // Peer 5 has same network group as Peer 1. IPAddress addressInSameNetworkGroupPeer5 = IPAddress.Parse("::ffff:57.48.183.82"); // ipv4 var endpointPeer5 = new IPEndPoint(addressInSameNetworkGroupPeer5, 80); peerAddressManager.AddPeer(endpointPeer5, IPAddress.Loopback); connectedToThisPeer = ConnectToPeer(peerAddressManager, networkPeerFactoryExisting, connectionManagerSettingsExisting, peerConnector, endpointPeer5, connectionManagerExisting); Assert.True(connectedToThisPeer); // Same network group: connects. }
/// <summary>Attempts to connect to a random peer.</summary> public async Task ConnectAsync(PeerAddress peerAddress) { if (this.selfEndpointTracker.IsSelf(peerAddress.Endpoint)) { this.logger.LogDebug("Connect aborted: {0} is self.", peerAddress.Endpoint); return; } if (this.IsPeerConnected(peerAddress.Endpoint)) { this.logger.LogDebug("Connect aborted: {0} is already connected.", peerAddress.Endpoint); return; } if (peerAddress.IsBanned(this.dateTimeProvider.GetUtcNow())) { this.logger.LogDebug("Connect aborted: {0} is banned until {1}.", peerAddress.Endpoint, peerAddress.BanUntil); return; } INetworkPeer peer = null; try { using (CancellationTokenSource timeoutTokenSource = CancellationTokenSource.CreateLinkedTokenSource(this.NodeLifetime.ApplicationStopping)) { this.PeerAddressManager.PeerAttempted(peerAddress.Endpoint, this.dateTimeProvider.GetUtcNow()); NetworkPeerConnectionParameters clonedConnectParameters = this.CurrentParameters.Clone(); timeoutTokenSource.CancelAfter(5000); clonedConnectParameters.ConnectCancellation = timeoutTokenSource.Token; peer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(peerAddress.Endpoint, clonedConnectParameters, this.networkPeerDisposer).ConfigureAwait(false); await peer.VersionHandshakeAsync(this.Requirements, timeoutTokenSource.Token).ConfigureAwait(false); this.AddPeer(peer); } } catch (OperationCanceledException) { if (this.NodeLifetime.ApplicationStopping.IsCancellationRequested) { this.logger.LogDebug("Peer {0} connection canceled because application is stopping.", peerAddress.Endpoint); peer?.Disconnect("Application stopping"); } else { this.logger.LogDebug("Peer {0} connection timeout.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Connection timeout"); } } catch (NBitcoin.Protocol.ProtocolException) { this.logger.LogDebug("Handshake rejected by peer '{0}'.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while handshaking"); } catch (Exception exception) { this.logger.LogDebug("Exception occurred while connecting: {0}", exception is SocketException ? exception.Message : exception.ToString()); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while connecting", exception); } }
/// <inheritdoc /> public override async Task InitializeAsync() { // TODO rewrite chain starting logic. Tips manager should be used. await this.StartChainAsync().ConfigureAwait(false); if (this.provenBlockHeaderStore != null) { // If we find at this point that proven header store is behind chain we can rewind chain (this will cause a ripple effect and rewind block store and consensus) // This problem should go away once we implement a component to keep all tips up to date // https://github.com/stratisproject/StratisBitcoinFullNode/issues/2503 ChainedHeader initializedAt = await this.provenBlockHeaderStore.InitializeAsync(this.chainIndexer.Tip); this.chainIndexer.Initialize(initializedAt); } NetworkPeerConnectionParameters connectionParameters = this.connectionManager.Parameters; connectionParameters.IsRelay = this.connectionManager.ConnectionSettings.RelayTxes; connectionParameters.TemplateBehaviors.Add(new PingPongBehavior()); connectionParameters.TemplateBehaviors.Add(new EnforcePeerVersionCheckBehavior(this.chainIndexer, this.nodeSettings, this.network, this.loggerFactory)); connectionParameters.TemplateBehaviors.Add(new ConsensusManagerBehavior(this.chainIndexer, this.initialBlockDownloadState, this.consensusManager, this.peerBanning, this.loggerFactory)); // TODO: Once a proper rate limiting strategy has been implemented, this check will be removed. if (!this.network.IsRegTest()) { connectionParameters.TemplateBehaviors.Add(new RateLimitingBehavior(this.dateTimeProvider, this.loggerFactory, this.peerBanning)); } connectionParameters.TemplateBehaviors.Add(new PeerBanningBehavior(this.loggerFactory, this.peerBanning, this.nodeSettings)); connectionParameters.TemplateBehaviors.Add(new BlockPullerBehavior(this.blockPuller, this.initialBlockDownloadState, this.dateTimeProvider, this.loggerFactory)); connectionParameters.TemplateBehaviors.Add(new ConnectionManagerBehavior(this.connectionManager, this.loggerFactory)); this.StartAddressManager(connectionParameters); if (this.connectionManager.ConnectionSettings.SyncTimeEnabled) { connectionParameters.TemplateBehaviors.Add(new TimeSyncBehavior(this.timeSyncBehaviorState, this.dateTimeProvider, this.loggerFactory)); } else { this.logger.LogDebug("Time synchronization with peers is disabled."); } // Block store must be initialized before consensus manager. // This may be a temporary solution until a better way is found to solve this dependency. this.blockStore.Initialize(); // The finalized repository needs to be initialized before the rules engine in case the // node shutdown unexpectedly and the finalized block info needs to be reset. this.finalizedBlockInfoRepository.Initialize(this.chainIndexer.Tip); this.consensusRules.Initialize(this.chainIndexer.Tip); await this.consensusManager.InitializeAsync(this.chainIndexer.Tip).ConfigureAwait(false); this.chainState.ConsensusTip = this.consensusManager.Tip; this.nodeStats.RegisterStats(sb => sb.Append(this.asyncProvider.GetStatistics(!this.nodeSettings.LogSettings.DebugArgs.Any())), StatsType.Component, this.GetType().Name, 100); // TODO: Should this always be called? ((IBlockStoreQueue)this.blockStore).ReindexChain(this.consensusManager, this.nodeLifetime.ApplicationStopping); }
public static BroadcastHub GetBroadcastHub(NetworkPeerConnectionParameters parameters) { return(GetBroadcastHub(parameters.TemplateBehaviors)); }
public NetworkPeer CreateNodeClient(NetworkPeerConnectionParameters parameters) { return(this.networkPeerFactory.CreateConnectedNetworkPeerAsync(Network.RegTest, "127.0.0.1:" + this.ports[0].ToString(), parameters).GetAwaiter().GetResult()); }
/// <summary>Attempts to connect to a random peer.</summary> internal async Task ConnectAsync(PeerAddress peerAddress) { if (this.selfEndpointTracker.IsSelf(peerAddress.Endpoint)) { this.logger.LogTrace("{0} is self. Therefore not connecting.", peerAddress.Endpoint); return; } // Connect if local, ip range filtering disabled or ip range filtering enabled and peer in a different group. if (peerAddress.Endpoint.Address.IsRoutable(false) && this.ConnectionSettings.IpRangeFiltering && this.PeerIsPartOfExistingGroup(peerAddress)) { this.logger.LogTrace("(-)[RANGE_FILTERED]"); return; } INetworkPeer peer = null; try { using (CancellationTokenSource timeoutTokenSource = CancellationTokenSource.CreateLinkedTokenSource(this.nodeLifetime.ApplicationStopping)) { this.peerAddressManager.PeerAttempted(peerAddress.Endpoint, this.dateTimeProvider.GetUtcNow()); NetworkPeerConnectionParameters clonedConnectParamaters = this.CurrentParameters.Clone(); timeoutTokenSource.CancelAfter(5000); clonedConnectParamaters.ConnectCancellation = timeoutTokenSource.Token; peer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(peerAddress.Endpoint, clonedConnectParamaters, this.networkPeerDisposer).ConfigureAwait(false); await peer.VersionHandshakeAsync(this.Requirements, timeoutTokenSource.Token).ConfigureAwait(false); this.AddPeer(peer); } } catch (OperationCanceledException) { if (this.nodeLifetime.ApplicationStopping.IsCancellationRequested) { this.logger.LogDebug("Peer {0} connection canceled because application is stopping.", peerAddress.Endpoint); peer?.Disconnect("Application stopping"); } else { this.logger.LogDebug("Peer {0} connection timeout.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Connection timeout"); } } catch (NBitcoin.Protocol.ProtocolException) { this.logger.LogDebug("Handshake rejected by peer '{0}'.", peerAddress.Endpoint); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while handshaking"); } catch (Exception exception) { this.logger.LogTrace("Exception occurred while connecting: {0}", exception.ToString()); peerAddress.SetHandshakeAttempted(this.dateTimeProvider.GetUtcNow()); peer?.Disconnect("Error while connecting", exception); } }
/// <summary> /// See <see cref="DiscoverPeers"/> /// </summary> private async Task DiscoverPeersAsync() { var peersToDiscover = new List <IPEndPoint>(); List <PeerAddress> foundPeers = this.peerAddressManager.PeerSelector.SelectPeersForDiscovery(1000).ToList(); peersToDiscover.AddRange(foundPeers.Select(p => p.Endpoint)); if (peersToDiscover.Count == 0) { // On normal circumstances the dns seeds are attempted only once per node lifetime. if (this.isSeedAndDnsAttempted) { this.logger.LogTrace("(-)[DNS_ATTEMPTED]"); return; } this.AddDNSSeedNodes(peersToDiscover); this.AddSeedNodes(peersToDiscover); this.isSeedAndDnsAttempted = true; if (peersToDiscover.Count == 0) { this.logger.LogTrace("(-)[NO_ADDRESSES]"); return; } peersToDiscover = peersToDiscover.OrderBy(a => RandomUtils.GetInt32()).ToList(); } else { // If all attempts have failed then attempt the dns seeds again. if (!this.isSeedAndDnsAttempted && foundPeers.All(peer => peer.Attempted)) { peersToDiscover.Clear(); this.AddDNSSeedNodes(peersToDiscover); this.AddSeedNodes(peersToDiscover); this.isSeedAndDnsAttempted = true; } } await peersToDiscover.ForEachAsync(5, this.nodeLifetime.ApplicationStopping, async (endPoint, cancellation) => { using (CancellationTokenSource connectTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellation)) { this.logger.LogTrace("Attempting to discover from : '{0}'", endPoint); connectTokenSource.CancelAfter(TimeSpan.FromSeconds(5)); INetworkPeer networkPeer = null; try { NetworkPeerConnectionParameters clonedParameters = this.currentParameters.Clone(); clonedParameters.ConnectCancellation = connectTokenSource.Token; PeerAddressManagerBehaviour addressManagerBehaviour = clonedParameters.TemplateBehaviors.OfType <PeerAddressManagerBehaviour>().FirstOrDefault(); clonedParameters.TemplateBehaviors.Clear(); clonedParameters.TemplateBehaviors.Add(addressManagerBehaviour); networkPeer = await this.networkPeerFactory.CreateConnectedNetworkPeerAsync(endPoint, clonedParameters).ConfigureAwait(false); await networkPeer.VersionHandshakeAsync(connectTokenSource.Token).ConfigureAwait(false); await networkPeer.SendMessageAsync(new GetAddrPayload(), connectTokenSource.Token).ConfigureAwait(false); this.peerAddressManager.PeerDiscoveredFrom(endPoint, DateTimeProvider.Default.GetUtcNow()); connectTokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)); } catch { } finally { networkPeer?.Disconnect("Discovery job done"); networkPeer?.Dispose(); } this.logger.LogTrace("Discovery from '{0}' finished", endPoint); } }).ConfigureAwait(false); }
public static PeerAddressManagerBehaviour PeerAddressManagerBehaviour( this NetworkPeerConnectionParameters parameters) { return(parameters.TemplateBehaviors.OfType <PeerAddressManagerBehaviour>().FirstOrDefault()); }
public static PeerAddressManagerBehaviour PeerAddressManagerBehaviour(this NetworkPeerConnectionParameters parameters) { return(parameters.TemplateBehaviors.Find <PeerAddressManagerBehaviour>()); }
public void CanDiscoverAndConnectToPeersOnTheNetwork() { var parameters = new NetworkPeerConnectionParameters(); var testFolder = TestDirectory.Create("CanDiscoverAndConnectToPeersOnTheNetwork"); var nodeSettings = new NodeSettings { DataDir = testFolder.FolderName }; nodeSettings.DataFolder = new DataFolder(nodeSettings); var peerAddressManager = new PeerAddressManager(nodeSettings.DataFolder); var peerAddressManagerBehaviour = new PeerAddressManagerBehaviour(new DateTimeProvider(), peerAddressManager) { PeersToDiscover = 3 }; parameters.TemplateBehaviors.Add(peerAddressManagerBehaviour); var loggerFactory = new ExtendedLoggerFactory(); loggerFactory.AddConsoleWithFilters(); var networkPeerFactory = new NetworkPeerFactory(DateTimeProvider.Default, loggerFactory); var peerConnectorDiscovery = new PeerConnectorDiscovery( new AsyncLoopFactory(loggerFactory), loggerFactory, Network.Main, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); var peerDiscovery = new PeerDiscovery( new AsyncLoopFactory(loggerFactory), loggerFactory, Network.Main, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); IConnectionManager connectionManager = new ConnectionManager( new AsyncLoopFactory(loggerFactory), new DateTimeProvider(), loggerFactory, Network.Main, networkPeerFactory, nodeSettings, new NodeLifetime(), parameters, peerAddressManager, new IPeerConnector[] { peerConnectorDiscovery }, peerDiscovery); NetworkPeerConnectionParameters cloned = parameters.Clone(); cloned.TemplateBehaviors.Add(new ConnectionManagerBehavior(false, connectionManager, loggerFactory)); peerDiscovery.DiscoverPeers(cloned); // Wait until we have discovered 3 peers. TestHelper.WaitLoop(() => peerAddressManager.Peers.Count > 3); // Wait until at least one successful connection has been made. while (true) { try { var peerOne = peerAddressManager.SelectPeerToConnectTo(); NetworkPeer node = networkPeerFactory.CreateConnectedNetworkPeer(Network.Main, peerOne, parameters); node.VersionHandshake(); node.Disconnect(); break; } catch { } } ; }