From 1f845a4e29cd8353934e9c6e398b1d74322f5ffe Mon Sep 17 00:00:00 2001 From: Erik van den Brink Date: Mon, 1 Apr 2019 14:35:38 +0200 Subject: [PATCH 1/4] Add ping/pong for height --- neo/Network/P2P/Payloads/PingPayload.cs | 30 +++++++++++++++++++++++++ neo/Network/P2P/ProtocolHandler.cs | 11 ++++++++- neo/Network/P2P/RemoteNode.cs | 5 +++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 neo/Network/P2P/Payloads/PingPayload.cs diff --git a/neo/Network/P2P/Payloads/PingPayload.cs b/neo/Network/P2P/Payloads/PingPayload.cs new file mode 100644 index 0000000000..7adb4bbda9 --- /dev/null +++ b/neo/Network/P2P/Payloads/PingPayload.cs @@ -0,0 +1,30 @@ +using Neo.IO; +using System; +using System.IO; + +namespace Neo.Network.P2P.Payloads +{ + public class PingPayload : ISerializable + { + public int Size => sizeof(uint); + public uint currentHeight; + + public static PingPayload Create(uint height) + { + return new PingPayload + { + currentHeight= height + }; + } + + void ISerializable.Deserialize(BinaryReader reader) + { + currentHeight = reader.ReadUInt32(); + } + + void ISerializable.Serialize(BinaryWriter writer) + { + writer.Write(currentHeight); + } + } +} diff --git a/neo/Network/P2P/ProtocolHandler.cs b/neo/Network/P2P/ProtocolHandler.cs index a6549a417d..cb5cab4fb4 100644 --- a/neo/Network/P2P/ProtocolHandler.cs +++ b/neo/Network/P2P/ProtocolHandler.cs @@ -21,6 +21,7 @@ internal class ProtocolHandler : UntypedActor public class SetVersion { public VersionPayload Version; } public class SetVerack { } public class SetFilter { public BloomFilter Filter; } + public class SetHeight { public uint height; } private readonly NeoSystem system; private readonly HashSet knownHashes = new HashSet(); @@ -102,10 +103,12 @@ protected override void OnReceive(object message) case "verack": case "version": throw new ProtocolViolationException(); + case "ping": + OnPingMessageReceived(msg.Payload.AsSerializable()); + break; case "alert": case "merkleblock": case "notfound": - case "ping": case "pong": case "reject": default: @@ -284,6 +287,12 @@ private void OnVersionMessageReceived(VersionPayload payload) Context.Parent.Tell(new SetVersion { Version = payload }); } + private void OnPingMessageReceived(PingPayload payload) + { + Context.Parent.Tell(new SetHeight { height = payload.currentHeight }); + Context.Parent.Tell(Message.Create("pong", PingPayload.Create(Blockchain.Singleton.Height))); + } + public static Props Props(NeoSystem system) { return Akka.Actor.Props.Create(() => new ProtocolHandler(system)).WithMailbox("protocol-handler-mailbox"); diff --git a/neo/Network/P2P/RemoteNode.cs b/neo/Network/P2P/RemoteNode.cs index 9880339f73..dc7b0c816e 100644 --- a/neo/Network/P2P/RemoteNode.cs +++ b/neo/Network/P2P/RemoteNode.cs @@ -29,6 +29,7 @@ internal class Relay { public IInventory Inventory; } public IPEndPoint Listener => new IPEndPoint(Remote.Address, ListenerPort); public override int ListenerPort => Version?.Port ?? 0; public VersionPayload Version { get; private set; } + public uint currentHeight; public RemoteNode(NeoSystem system, object connection, IPEndPoint remote, IPEndPoint local) : base(connection, remote, local) @@ -63,6 +64,7 @@ private void EnqueueMessage(Message message) case "getblocks": case "getheaders": case "mempool": + case "pong": is_single = true; break; } @@ -123,6 +125,9 @@ protected override void OnReceive(object message) case ProtocolHandler.SetFilter setFilter: OnSetFilter(setFilter.Filter); break; + case ProtocolHandler.SetHeight setHeight: + currentHeight = setHeight.height; + break; } } From 3413fc0864631e86ca3a375a2b424797e9d185a0 Mon Sep 17 00:00:00 2001 From: Erik van den Brink Date: Mon, 1 Apr 2019 20:47:23 +0200 Subject: [PATCH 2/4] don't include own height --- neo/Network/P2P/Payloads/PongPayload.cs | 30 +++++++++++++++++++++++++ neo/Network/P2P/ProtocolHandler.cs | 8 +++---- neo/Network/P2P/RemoteNode.cs | 4 ---- 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 neo/Network/P2P/Payloads/PongPayload.cs diff --git a/neo/Network/P2P/Payloads/PongPayload.cs b/neo/Network/P2P/Payloads/PongPayload.cs new file mode 100644 index 0000000000..37c3590b15 --- /dev/null +++ b/neo/Network/P2P/Payloads/PongPayload.cs @@ -0,0 +1,30 @@ +using Neo.IO; +using System; +using System.IO; + +namespace Neo.Network.P2P.Payloads +{ + public class PongPayload : ISerializable + { + public int Size => sizeof(uint); + public uint currentHeight; + + public static PongPayload Create(uint height) + { + return new PongPayload + { + currentHeight= height + }; + } + + void ISerializable.Deserialize(BinaryReader reader) + { + currentHeight = reader.ReadUInt32(); + } + + void ISerializable.Serialize(BinaryWriter writer) + { + writer.Write(currentHeight); + } + } +} diff --git a/neo/Network/P2P/ProtocolHandler.cs b/neo/Network/P2P/ProtocolHandler.cs index cb5cab4fb4..9174da3dbe 100644 --- a/neo/Network/P2P/ProtocolHandler.cs +++ b/neo/Network/P2P/ProtocolHandler.cs @@ -21,7 +21,6 @@ internal class ProtocolHandler : UntypedActor public class SetVersion { public VersionPayload Version; } public class SetVerack { } public class SetFilter { public BloomFilter Filter; } - public class SetHeight { public uint height; } private readonly NeoSystem system; private readonly HashSet knownHashes = new HashSet(); @@ -104,7 +103,7 @@ protected override void OnReceive(object message) case "version": throw new ProtocolViolationException(); case "ping": - OnPingMessageReceived(msg.Payload.AsSerializable()); + OnPingMessageReceived(); break; case "alert": case "merkleblock": @@ -287,10 +286,9 @@ private void OnVersionMessageReceived(VersionPayload payload) Context.Parent.Tell(new SetVersion { Version = payload }); } - private void OnPingMessageReceived(PingPayload payload) + private void OnPingMessageReceived() { - Context.Parent.Tell(new SetHeight { height = payload.currentHeight }); - Context.Parent.Tell(Message.Create("pong", PingPayload.Create(Blockchain.Singleton.Height))); + Context.Parent.Tell(Message.Create("pong", PongPayload.Create(Blockchain.Singleton.Height))); } public static Props Props(NeoSystem system) diff --git a/neo/Network/P2P/RemoteNode.cs b/neo/Network/P2P/RemoteNode.cs index dc7b0c816e..4970e7db5b 100644 --- a/neo/Network/P2P/RemoteNode.cs +++ b/neo/Network/P2P/RemoteNode.cs @@ -29,7 +29,6 @@ internal class Relay { public IInventory Inventory; } public IPEndPoint Listener => new IPEndPoint(Remote.Address, ListenerPort); public override int ListenerPort => Version?.Port ?? 0; public VersionPayload Version { get; private set; } - public uint currentHeight; public RemoteNode(NeoSystem system, object connection, IPEndPoint remote, IPEndPoint local) : base(connection, remote, local) @@ -125,9 +124,6 @@ protected override void OnReceive(object message) case ProtocolHandler.SetFilter setFilter: OnSetFilter(setFilter.Filter); break; - case ProtocolHandler.SetHeight setHeight: - currentHeight = setHeight.height; - break; } } From 97aa688d10c169ceeedc059c27c2bd60626f02ab Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 2 Apr 2019 08:50:53 +0800 Subject: [PATCH 3/4] Save `LastBlockIndex` into `RemoteNode` --- neo/Network/P2P/Payloads/PingPayload.cs | 24 +++++++++++++++---- neo/Network/P2P/Payloads/PongPayload.cs | 30 ----------------------- neo/Network/P2P/ProtocolHandler.cs | 32 +++++++++++++++---------- neo/Network/P2P/RemoteNode.cs | 23 +++++++++++++----- 4 files changed, 55 insertions(+), 54 deletions(-) delete mode 100644 neo/Network/P2P/Payloads/PongPayload.cs diff --git a/neo/Network/P2P/Payloads/PingPayload.cs b/neo/Network/P2P/Payloads/PingPayload.cs index 7adb4bbda9..f702458b9c 100644 --- a/neo/Network/P2P/Payloads/PingPayload.cs +++ b/neo/Network/P2P/Payloads/PingPayload.cs @@ -6,25 +6,39 @@ namespace Neo.Network.P2P.Payloads { public class PingPayload : ISerializable { - public int Size => sizeof(uint); - public uint currentHeight; + public uint LastBlockIndex; + public uint Timestamp; + public uint Nonce; + + public int Size => + sizeof(uint) + //LastBlockIndex + sizeof(uint) + //Timestamp + sizeof(uint); //Nonce + public static PingPayload Create(uint height) { + Random rand = new Random(); return new PingPayload { - currentHeight= height + LastBlockIndex = height, + Timestamp = DateTime.UtcNow.ToTimestamp(), + Nonce = (uint)rand.Next() }; } void ISerializable.Deserialize(BinaryReader reader) { - currentHeight = reader.ReadUInt32(); + LastBlockIndex = reader.ReadUInt32(); + Timestamp = reader.ReadUInt32(); + Nonce = reader.ReadUInt32(); } void ISerializable.Serialize(BinaryWriter writer) { - writer.Write(currentHeight); + writer.Write(LastBlockIndex); + writer.Write(Timestamp); + writer.Write(Nonce); } } } diff --git a/neo/Network/P2P/Payloads/PongPayload.cs b/neo/Network/P2P/Payloads/PongPayload.cs deleted file mode 100644 index 37c3590b15..0000000000 --- a/neo/Network/P2P/Payloads/PongPayload.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Neo.IO; -using System; -using System.IO; - -namespace Neo.Network.P2P.Payloads -{ - public class PongPayload : ISerializable - { - public int Size => sizeof(uint); - public uint currentHeight; - - public static PongPayload Create(uint height) - { - return new PongPayload - { - currentHeight= height - }; - } - - void ISerializable.Deserialize(BinaryReader reader) - { - currentHeight = reader.ReadUInt32(); - } - - void ISerializable.Serialize(BinaryWriter writer) - { - writer.Write(currentHeight); - } - } -} diff --git a/neo/Network/P2P/ProtocolHandler.cs b/neo/Network/P2P/ProtocolHandler.cs index 9174da3dbe..c1c2337598 100644 --- a/neo/Network/P2P/ProtocolHandler.cs +++ b/neo/Network/P2P/ProtocolHandler.cs @@ -18,8 +18,6 @@ namespace Neo.Network.P2P { internal class ProtocolHandler : UntypedActor { - public class SetVersion { public VersionPayload Version; } - public class SetVerack { } public class SetFilter { public BloomFilter Filter; } private readonly NeoSystem system; @@ -95,6 +93,12 @@ protected override void OnReceive(object message) case "mempool": OnMemPoolMessageReceived(); break; + case "ping": + OnPingMessageReceived(msg.GetPayload()); + break; + case "pong": + OnPongMessageReceived(msg.GetPayload()); + break; case "tx": if (msg.Payload.Length <= Transaction.MaxTransactionSize) OnInventoryReceived(msg.GetTransaction()); @@ -102,13 +106,9 @@ protected override void OnReceive(object message) case "verack": case "version": throw new ProtocolViolationException(); - case "ping": - OnPingMessageReceived(); - break; case "alert": case "merkleblock": case "notfound": - case "pong": case "reject": default: //暂时忽略 @@ -274,21 +274,27 @@ private void OnMemPoolMessageReceived() Context.Parent.Tell(Message.Create("inv", payload)); } + private void OnPingMessageReceived(PingPayload payload) + { + Context.Parent.Tell(payload); + Context.Parent.Tell(Message.Create("pong", PingPayload.Create(Blockchain.Singleton.Height))); + } + + private void OnPongMessageReceived(PingPayload payload) + { + Context.Parent.Tell(payload); + } + private void OnVerackMessageReceived() { verack = true; - Context.Parent.Tell(new SetVerack()); + Context.Parent.Tell("verack"); } private void OnVersionMessageReceived(VersionPayload payload) { version = payload; - Context.Parent.Tell(new SetVersion { Version = payload }); - } - - private void OnPingMessageReceived() - { - Context.Parent.Tell(Message.Create("pong", PongPayload.Create(Blockchain.Singleton.Height))); + Context.Parent.Tell(payload); } public static Props Props(NeoSystem system) diff --git a/neo/Network/P2P/RemoteNode.cs b/neo/Network/P2P/RemoteNode.cs index 4970e7db5b..c15b0128be 100644 --- a/neo/Network/P2P/RemoteNode.cs +++ b/neo/Network/P2P/RemoteNode.cs @@ -29,6 +29,7 @@ internal class Relay { public IInventory Inventory; } public IPEndPoint Listener => new IPEndPoint(Remote.Address, ListenerPort); public override int ListenerPort => Version?.Port ?? 0; public VersionPayload Version { get; private set; } + public uint LastBlockIndex { get; private set; } public RemoteNode(NeoSystem system, object connection, IPEndPoint remote, IPEndPoint local) : base(connection, remote, local) @@ -63,6 +64,7 @@ private void EnqueueMessage(Message message) case "getblocks": case "getheaders": case "mempool": + case "ping": case "pong": is_single = true; break; @@ -115,18 +117,26 @@ protected override void OnReceive(object message) case Relay relay: OnRelay(relay.Inventory); break; - case ProtocolHandler.SetVersion setVersion: - OnSetVersion(setVersion.Version); + case VersionPayload payload: + OnVersionPayload(payload); break; - case ProtocolHandler.SetVerack _: - OnSetVerack(); + case "verack": + OnVerack(); break; case ProtocolHandler.SetFilter setFilter: OnSetFilter(setFilter.Filter); break; + case PingPayload payload: + OnPingPayload(payload); + break; } } + private void OnPingPayload(PingPayload payload) + { + LastBlockIndex = payload.LastBlockIndex; + } + private void OnRelay(IInventory inventory) { if (Version?.Relay != true) return; @@ -154,16 +164,17 @@ private void OnSetFilter(BloomFilter filter) bloom_filter = filter; } - private void OnSetVerack() + private void OnVerack() { verack = true; system.TaskManager.Tell(new TaskManager.Register { Version = Version }); CheckMessageQueue(); } - private void OnSetVersion(VersionPayload version) + private void OnVersionPayload(VersionPayload version) { this.Version = version; + this.LastBlockIndex = Version.StartHeight; if (version.Nonce == LocalNode.Nonce) { Disconnect(true); From e5f5827d595c75fad422cbe1ab6c8d7a6c0dbd93 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 2 Apr 2019 10:57:41 +0800 Subject: [PATCH 4/4] improve --- neo/Network/P2P/RemoteNode.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/neo/Network/P2P/RemoteNode.cs b/neo/Network/P2P/RemoteNode.cs index c15b0128be..65a384188a 100644 --- a/neo/Network/P2P/RemoteNode.cs +++ b/neo/Network/P2P/RemoteNode.cs @@ -134,7 +134,8 @@ protected override void OnReceive(object message) private void OnPingPayload(PingPayload payload) { - LastBlockIndex = payload.LastBlockIndex; + if (payload.LastBlockIndex > LastBlockIndex) + LastBlockIndex = payload.LastBlockIndex; } private void OnRelay(IInventory inventory)