/// <summary>
        /// Initializes an instance of the object for inbound network peers with already established connection.
        /// </summary>
        /// <param name="peerEndPoint">IP address and port on the side of the peer.</param>
        /// <param name="network">Specification of the network the node runs on - regtest/testnet/mainnet.</param>
        /// <param name="parameters">Various settings and requirements related to how the connections with peers are going to be established, or <c>null</c> to use default parameters.</param>
        /// <param name="client">Already connected network client.</param>
        /// <param name="dateTimeProvider">Provider of time functions.</param>
        /// <param name="networkPeerFactory">Factory for creating P2P network peers.</param>
        /// <param name="loggerFactory">Factory for creating loggers.</param>
        /// <param name="selfEndpointTracker">Tracker for endpoints known to be self.</param>
        /// <param name="onDisconnected">Callback that is invoked when peer has finished disconnecting, or <c>null</c> when no notification after the disconnection is required.</param>
        public NetworkPeer(IPEndPoint peerEndPoint,
                           Network network,
                           NetworkPeerConnectionParameters parameters,
                           TcpClient client,
                           IDateTimeProvider dateTimeProvider,
                           INetworkPeerFactory networkPeerFactory,
                           ILoggerFactory loggerFactory,
                           ISelfEndpointTracker selfEndpointTracker,
                           IAsyncProvider asyncProvider,
                           Action <INetworkPeer> onDisconnected          = null,
                           Action <IPEndPoint, Payload> onSendingMessage = null)
            : this(true, peerEndPoint, network, parameters, dateTimeProvider, loggerFactory, selfEndpointTracker, asyncProvider, onDisconnected, onSendingMessage)
        {
            this.Connection = networkPeerFactory.CreateNetworkPeerConnection(this, client, this.ProcessMessageAsync);

            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);

            this.logger.LogDebug("Connected to peer '{0}'.", this.PeerEndPoint);

            this.InitDefaultBehaviors(this.ConnectionParameters);
            this.Connection.StartReceiveMessages();
        }
        /// <summary>
        /// Initializes parts of the object that are common for both inbound and outbound peers.
        /// </summary>
        /// <param name="inbound"><c>true</c> for inbound peers, <c>false</c> for outbound peers.</param>
        /// <param name="peerEndPoint">IP address and port on the side of the peer.</param>
        /// <param name="network">Specification of the network the node runs on - regtest/testnet/mainnet.</param>
        /// <param name="parameters">Various settings and requirements related to how the connections with peers are going to be established, or <c>null</c> to use default parameters.</param>
        /// <param name="dateTimeProvider">Provider of time functions.</param>
        /// <param name="loggerFactory">Factory for creating loggers.</param>
        /// <param name="selfEndpointTracker">Tracker for endpoints known to be self.</param>
        /// <param name="onDisconnected">Callback that is invoked when peer has finished disconnecting, or <c>null</c> when no notification after the disconnection is required.</param>
        private NetworkPeer(bool inbound,
                            IPEndPoint peerEndPoint,
                            Network network,
                            NetworkPeerConnectionParameters parameters,
                            IDateTimeProvider dateTimeProvider,
                            ILoggerFactory loggerFactory,
                            ISelfEndpointTracker selfEndpointTracker,
                            IAsyncProvider asyncProvider,
                            Action <INetworkPeer> onDisconnected          = null,
                            Action <IPEndPoint, Payload> onSendingMessage = null)
        {
            this.dateTimeProvider = dateTimeProvider;

            this.preferredTransactionOptions = parameters.PreferredTransactionOptions;
            this.SupportedTransactionOptions = parameters.PreferredTransactionOptions & ~TransactionOptions.All;

            this.State                = inbound ? NetworkPeerState.Connected : NetworkPeerState.Created;
            this.Inbound              = inbound;
            this.PeerEndPoint         = peerEndPoint;
            this.RemoteSocketEndpoint = this.PeerEndPoint;

            this.Network                    = network;
            this.Behaviors                  = new List <INetworkPeerBehavior>();
            this.selfEndpointTracker        = selfEndpointTracker;
            this.asyncProvider              = asyncProvider;
            this.onDisconnectedAsyncContext = new AsyncLocal <DisconnectedExecutionAsyncContext>();

            this.ConnectionParameters = parameters ?? new NetworkPeerConnectionParameters();
            this.MyVersion            = this.ConnectionParameters.CreateVersion(this.selfEndpointTracker.MyExternalAddress, this.PeerEndPoint, network, this.dateTimeProvider.GetTimeOffset());

            this.MessageReceived  = new AsyncExecutionEvent <INetworkPeer, IncomingMessage>();
            this.StateChanged     = new AsyncExecutionEvent <INetworkPeer, NetworkPeerState>();
            this.onDisconnected   = onDisconnected;
            this.onSendingMessage = onSendingMessage;

            string dequeuerName = $"{nameof(NetworkPeer)}-{nameof(this.asyncPayloadsQueue)}-{this.PeerEndPoint.ToString()}";

            this.asyncPayloadsQueue = asyncProvider.CreateAndRunAsyncDelegateDequeuer <Payload>(dequeuerName, this.SendMessageHandledAsync);
        }
Beispiel #3
0
        /// <summary>
        /// Initializes an instance of the object for outbound network peers.
        /// </summary>
        /// <param name="peerEndPoint">IP address and port on the side of the peer.</param>
        /// <param name="network">Specification of the network the node runs on - regtest/testnet/mainnet.</param>
        /// <param name="parameters">Various settings and requirements related to how the connections with peers are going to be established, or <c>null</c> to use default parameters.</param>
        /// <param name="networkPeerFactory">Factory for creating P2P network peers.</param>
        /// <param name="dateTimeProvider">Provider of time functions.</param>
        /// <param name="loggerFactory">Factory for creating loggers.</param>
        /// <param name="selfEndpointTracker">Tracker for endpoints known to be self.</param>
        /// <param name="onDisconnected">Callback that is invoked when peer has finished disconnecting, or <c>null</c> when no notification after the disconnection is required.</param>
        public NetworkPeer(IPEndPoint peerEndPoint,
                           Network network,
                           NetworkPeerConnectionParameters parameters,
                           INetworkPeerFactory networkPeerFactory,
                           IDateTimeProvider dateTimeProvider,
                           ILoggerFactory loggerFactory,
                           ISelfEndpointTracker selfEndpointTracker,
                           IAsyncProvider asyncProvider,
                           Action <INetworkPeer> onDisconnected          = null,
                           Action <IPEndPoint, Payload> onSendingMessage = null
                           )
            : this(false, peerEndPoint, network, parameters, dateTimeProvider, loggerFactory, selfEndpointTracker, asyncProvider, onDisconnected, onSendingMessage)
        {
            var client = new TcpClient(AddressFamily.InterNetworkV6);

            client.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
            client.Client.ReceiveBufferSize = parameters.ReceiveBufferSize;
            client.Client.SendBufferSize    = parameters.SendBufferSize;

            this.Connection = networkPeerFactory.CreateNetworkPeerConnection(this, client, this.ProcessMessageAsync);

            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
        }