public void RespondToHandShake(CancellationToken cancellation = default(CancellationToken)) { using (TraceCorrelation.Open()) { var listener = new PollMessageListener <IncomingMessage>(); using (MessageProducer.AddMessageListener(listener)) { NodeServerTrace.Information("Responding to handshake"); SendMessage(MyVersion); listener.ReceiveMessage().AssertPayload <VerAckPayload>(); SendMessage(new VerAckPayload()); _State = NodeState.HandShaked; } } }
public Chain BuildChain(ObjectStream <ChainChange> changes = null, CancellationToken cancellationToken = default(CancellationToken)) { if (changes == null) { changes = new StreamObjectStream <ChainChange>(); } var chain = new Chain(Network, changes); TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Build chain"); using (trace.Open()) { using (var pool = CreateNodeSet(3)) { int height = pool.GetNodes().Max(o => o.FullVersion.StartHeight); var listener = new PollMessageListener <IncomingMessage>(); pool.SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); using (pool.MessageProducer.AddMessageListener(listener)) { while (chain.Height != height) { var before = chain.Tip; var headers = listener.RecieveMessage(cancellationToken).Message.Payload as HeadersPayload; if (headers != null) { foreach (var header in headers.Headers) { chain.GetOrAdd(header); } if (before.HashBlock != chain.Tip.HashBlock) { NodeServerTrace.Information("Chain progress : " + chain.Height + "/" + height); pool.SendMessage(new GetHeadersPayload() { BlockLocators = chain.Tip.GetLocator() }); } } } } } } return(chain); }
public TPayload RecieveMessage <TPayload>(CancellationToken cancellationToken = default(CancellationToken)) where TPayload : Payload { var listener = new PollMessageListener <IncomingMessage>(); using (MessageProducer.AddMessageListener(listener)) { while (true) { var message = listener.RecieveMessage(cancellationToken); if (message.Message.Payload is TPayload) { return((TPayload)message.Message.Payload); } } } throw new InvalidProgramException("Bug in Node.RecieveMessage"); }
public void VersionHandshake(CancellationToken cancellationToken = default(CancellationToken)) { var listener = new PollMessageListener <IncomingMessage>(); using (MessageProducer.AddMessageListener(listener)) { using (TraceCorrelation.Open()) { var myVersion = CreateVersionPayload(); SendMessage(myVersion); var version = listener.RecieveMessage(cancellationToken).AssertPayload <VersionPayload>(); _FullVersion = version; Version = version.Version; if (version.Nonce == NodeServer.Nonce) { NodeServerTrace.ConnectionToSelfDetected(); Disconnect(); throw new InvalidOperationException("Impossible to connect to self"); } if (!version.AddressReciever.Address.Equals(ExternalEndpoint.Address)) { NodeServerTrace.Warning("Different external address detected by the node " + version.AddressReciever.Address + " instead of " + ExternalEndpoint.Address); } NodeServer.ExternalAddressDetected(version.AddressReciever.Address); if (version.Version < ProtocolVersion.MIN_PEER_PROTO_VERSION) { NodeServerTrace.Warning("Outdated version " + version.Version + " disconnecting"); Disconnect(); return; } SendMessage(new VerAckPayload()); listener.RecieveMessage(cancellationToken).AssertPayload <VerAckPayload>(); State = NodeState.HandShaked; if (NodeServer.AdvertizeMyself) { AdvertiseMyself(); } } } }