public NodesGroup( Network network, NodeConnectionParameters connectionParameters = null, NodeRequirement requirements = null) { AllowSameGroup = false; MaximumNodeConnection = 8; _Network = network; cs = new object(); _ConnectedNodes = new NodesCollection(); _ConnectionParameters = connectionParameters ?? new NodeConnectionParameters(); _ConnectionParameters = _ConnectionParameters.Clone(); _Requirements = requirements ?? new NodeRequirement(); _Disconnect = new CancellationTokenSource(); }
public void VersionHandshake(NodeRequirement requirements, CancellationToken cancellationToken = default(CancellationToken)) { requirements = requirements ?? new NodeRequirement(); using (var listener = CreateListener() .Where(p => p.IsPayloadTypeOf(typeof(VersionPayload), typeof(RejectPayload), typeof(VerAckPayload)))) { SendMessageAsync(MyVersion); var payload = listener.ReceivePayload <Object>(cancellationToken); if (payload is RejectPayload) { throw new ProtocolException("Handshake rejected : " + ((RejectPayload)payload).Reason); } var version = (VersionPayload)payload; _PeerVersion = version; if (!version.AddressReceiver.Address.Equals(MyVersion.AddressFrom.Address)) { NodeServerTrace.Warning("Different external address detected by the node " + version.AddressReceiver.Address + " instead of " + MyVersion.AddressFrom.Address); } if (version.Version < ProtocolVersion.MIN_PEER_PROTO_VERSION) { NodeServerTrace.Warning("Outdated version " + version.Version + " disconnecting"); Disconnect("Outdated version"); return; } if (!requirements.Check(version)) { Disconnect("The peer does not support the required services requirement"); return; } SendMessageAsync(new VerAckPayload()); listener.ReceivePayload <VerAckPayload>(cancellationToken); State = NodeState.HandShaked; if (Advertize && MyVersion.AddressFrom.Address.IsRoutable(true)) { SendMessageAsync(new AddrPayload(new NetworkAddress[] { new NetworkAddress(MyVersion.AddressFrom) { Time = DateTimeOffset.UtcNow } })); } } }