From 30ca6733cd91be56411b8eadda8875bde2304bb5 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 25 Nov 2020 14:33:55 +0100 Subject: [PATCH 01/23] Allow plugins to send messages --- src/neo/Network/P2P/MessageCommand.cs | 2 + src/neo/Network/P2P/Payloads/PluginPayload.cs | 86 +++++++++++++++++++ .../Network/P2P/RemoteNode.ProtocolHandler.cs | 14 +++ 3 files changed, 102 insertions(+) create mode 100644 src/neo/Network/P2P/Payloads/PluginPayload.cs diff --git a/src/neo/Network/P2P/MessageCommand.cs b/src/neo/Network/P2P/MessageCommand.cs index 89c21597cf..fba87781cd 100644 --- a/src/neo/Network/P2P/MessageCommand.cs +++ b/src/neo/Network/P2P/MessageCommand.cs @@ -40,6 +40,8 @@ public enum MessageCommand : byte Block = 0x2c, [ReflectionCache(typeof(ConsensusPayload))] Consensus = 0x2d, + [ReflectionCache(typeof(PluginPayload))] + Plugin = 0x2e, Reject = 0x2f, //SPV protocol diff --git a/src/neo/Network/P2P/Payloads/PluginPayload.cs b/src/neo/Network/P2P/Payloads/PluginPayload.cs new file mode 100644 index 0000000000..2a91c485ab --- /dev/null +++ b/src/neo/Network/P2P/Payloads/PluginPayload.cs @@ -0,0 +1,86 @@ +using Neo.IO; +using Neo.Persistence; +using Neo.SmartContract; +using Neo.SmartContract.Native; +using System; +using System.IO; + +namespace Neo.Network.P2P.Payloads +{ + public class PluginPayload : IVerifiable + { + public string Plugin; + public byte MessageType; + public byte[] Data; + public Witness Witness; + + private UInt256 _hash = null; + public UInt256 Hash + { + get + { + if (_hash == null) + { + _hash = this.CalculateHash(); + } + return _hash; + } + } + + public int Size => + Plugin.GetVarSize() + //Plugin + sizeof(byte) + //MessageType + Data.GetVarSize() + //Data + 1 + Witness.Size; //Witness + + Witness[] IVerifiable.Witnesses + { + get + { + return new[] { Witness }; + } + set + { + if (value.Length != 1) throw new ArgumentException(); + Witness = value[0]; + } + } + + void ISerializable.Deserialize(BinaryReader reader) + { + ((IVerifiable)this).DeserializeUnsigned(reader); + if (reader.ReadByte() != 1) throw new FormatException(); + Witness = reader.ReadSerializable(); + } + + void IVerifiable.DeserializeUnsigned(BinaryReader reader) + { + Plugin = reader.ReadVarString(32); + MessageType = reader.ReadByte(); + Data = reader.ReadVarBytes(ushort.MaxValue); + } + + UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot) + { + return new[] { NativeContract.NEO.GetCommitteeAddress(snapshot) }; + } + + void ISerializable.Serialize(BinaryWriter writer) + { + ((IVerifiable)this).SerializeUnsigned(writer); + writer.Write((byte)1); writer.Write(Witness); + } + + void IVerifiable.SerializeUnsigned(BinaryWriter writer) + { + writer.WriteVarString(Plugin); + writer.Write(MessageType); + writer.WriteVarBytes(Data); + } + + public bool Verify(StoreView snapshot) + { + return this.VerifyWitnesses(snapshot, 0_02000000); + } + } +} diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index 8cda813e72..fc72eb3929 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -39,6 +39,12 @@ protected override UInt256 GetKeyForItem((UInt256, DateTime) item) private void OnMessage(Message msg) { + if (msg.Command == MessageCommand.Plugin) + { + var payload = (PluginPayload)msg.Payload; + if (!knownHashes.Add(payload.Hash)) return; + if (!payload.Verify(Blockchain.Singleton.GetSnapshot())) return; + } foreach (IP2PPlugin plugin in Plugin.P2PPlugins) if (!plugin.OnP2PMessage(msg)) return; @@ -107,6 +113,9 @@ private void OnMessage(Message msg) if (msg.Payload.Size <= Transaction.MaxTransactionSize) OnInventoryReceived((Transaction)msg.Payload); break; + case MessageCommand.Plugin: + OnPluginMessage(msg); + break; case MessageCommand.Verack: case MessageCommand.Version: throw new ProtocolViolationException(); @@ -119,6 +128,11 @@ private void OnMessage(Message msg) } } + private void OnPluginMessage(Message msg) + { + system.LocalNode.Tell(msg); + } + private void OnAddrMessageReceived(AddrPayload payload) { ref bool sent = ref sentCommands[(byte)MessageCommand.GetAddr]; From 4d9c61332e3c65facdef0abc6cbfdb8f75e72dfe Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 25 Nov 2020 15:58:19 +0100 Subject: [PATCH 02/23] Any role --- src/neo/Network/P2P/Payloads/PluginPayload.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/neo/Network/P2P/Payloads/PluginPayload.cs b/src/neo/Network/P2P/Payloads/PluginPayload.cs index 2a91c485ab..99170cfcbd 100644 --- a/src/neo/Network/P2P/Payloads/PluginPayload.cs +++ b/src/neo/Network/P2P/Payloads/PluginPayload.cs @@ -1,7 +1,9 @@ using Neo.IO; +using Neo.Ledger; using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; +using Neo.SmartContract.Native.Designate; using System; using System.IO; @@ -12,6 +14,7 @@ public class PluginPayload : IVerifiable public string Plugin; public byte MessageType; public byte[] Data; + public Role WitnessRole; public Witness Witness; private UInt256 _hash = null; @@ -30,6 +33,7 @@ public UInt256 Hash public int Size => Plugin.GetVarSize() + //Plugin sizeof(byte) + //MessageType + sizeof(Role) + //WitnessRole Data.GetVarSize() + //Data 1 + Witness.Size; //Witness @@ -58,11 +62,13 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader) Plugin = reader.ReadVarString(32); MessageType = reader.ReadByte(); Data = reader.ReadVarBytes(ushort.MaxValue); + WitnessRole = (Role)reader.ReadByte(); + if (!Enum.IsDefined(typeof(Role), WitnessRole)) throw new FormatException(); } UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot) { - return new[] { NativeContract.NEO.GetCommitteeAddress(snapshot) }; + return new[] { Blockchain.GetConsensusAddress(NativeContract.Designate.GetDesignatedByRole(snapshot, WitnessRole, snapshot.Height)) }; } void ISerializable.Serialize(BinaryWriter writer) @@ -76,6 +82,7 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer) writer.WriteVarString(Plugin); writer.Write(MessageType); writer.WriteVarBytes(Data); + writer.Write((byte)WitnessRole); } public bool Verify(StoreView snapshot) From ea0393c8163e89031582d3f2f0c698df03932a72 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 7 Dec 2020 10:50:53 +0100 Subject: [PATCH 03/23] Use a different enum --- src/neo/Network/P2P/Payloads/PluginPayload.cs | 27 +++++++++++++++---- .../Network/P2P/Payloads/PluginPayloadRole.cs | 10 +++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/neo/Network/P2P/Payloads/PluginPayloadRole.cs diff --git a/src/neo/Network/P2P/Payloads/PluginPayload.cs b/src/neo/Network/P2P/Payloads/PluginPayload.cs index 99170cfcbd..bf90df1efb 100644 --- a/src/neo/Network/P2P/Payloads/PluginPayload.cs +++ b/src/neo/Network/P2P/Payloads/PluginPayload.cs @@ -14,7 +14,7 @@ public class PluginPayload : IVerifiable public string Plugin; public byte MessageType; public byte[] Data; - public Role WitnessRole; + public PluginPayloadRole WitnessRole; public Witness Witness; private UInt256 _hash = null; @@ -33,7 +33,7 @@ public UInt256 Hash public int Size => Plugin.GetVarSize() + //Plugin sizeof(byte) + //MessageType - sizeof(Role) + //WitnessRole + sizeof(PluginPayloadRole) + //WitnessRole Data.GetVarSize() + //Data 1 + Witness.Size; //Witness @@ -62,13 +62,30 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader) Plugin = reader.ReadVarString(32); MessageType = reader.ReadByte(); Data = reader.ReadVarBytes(ushort.MaxValue); - WitnessRole = (Role)reader.ReadByte(); - if (!Enum.IsDefined(typeof(Role), WitnessRole)) throw new FormatException(); + WitnessRole = (PluginPayloadRole)reader.ReadByte(); + if (!Enum.IsDefined(typeof(PluginPayloadRole), WitnessRole)) throw new FormatException(); } UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot) { - return new[] { Blockchain.GetConsensusAddress(NativeContract.Designate.GetDesignatedByRole(snapshot, WitnessRole, snapshot.Height)) }; + switch (WitnessRole) + { + case PluginPayloadRole.Committee: + { + return new[] { NativeContract.NEO.GetCommitteeAddress(snapshot) }; + } + case PluginPayloadRole.Validators: + { + return new[] { Blockchain.GetConsensusAddress(NativeContract.NEO.GetNextBlockValidators(snapshot)) }; + } + case PluginPayloadRole.StateValidator: + case PluginPayloadRole.Oracle: + { + return new[] { Blockchain.GetConsensusAddress(NativeContract.Designate.GetDesignatedByRole(snapshot, (Role)WitnessRole, snapshot.Height)) }; + } + } + + throw new ArgumentException(); } void ISerializable.Serialize(BinaryWriter writer) diff --git a/src/neo/Network/P2P/Payloads/PluginPayloadRole.cs b/src/neo/Network/P2P/Payloads/PluginPayloadRole.cs new file mode 100644 index 0000000000..df9d5a9043 --- /dev/null +++ b/src/neo/Network/P2P/Payloads/PluginPayloadRole.cs @@ -0,0 +1,10 @@ +namespace Neo.Network.P2P.Payloads +{ + public enum PluginPayloadRole : byte + { + Committee = 0, + Validators = 2, + StateValidator = 4, + Oracle = 8 + } +} From e8650ad7b5ec70a2da17518a8aae9a6a9e632aae Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 21 Dec 2020 09:54:11 +0100 Subject: [PATCH 04/23] Remove enum --- src/neo/Network/P2P/Payloads/PluginPayload.cs | 27 +------------------ .../Network/P2P/Payloads/PluginPayloadRole.cs | 10 ------- 2 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 src/neo/Network/P2P/Payloads/PluginPayloadRole.cs diff --git a/src/neo/Network/P2P/Payloads/PluginPayload.cs b/src/neo/Network/P2P/Payloads/PluginPayload.cs index bf90df1efb..4ac5090d05 100644 --- a/src/neo/Network/P2P/Payloads/PluginPayload.cs +++ b/src/neo/Network/P2P/Payloads/PluginPayload.cs @@ -1,9 +1,6 @@ using Neo.IO; -using Neo.Ledger; using Neo.Persistence; using Neo.SmartContract; -using Neo.SmartContract.Native; -using Neo.SmartContract.Native.Designate; using System; using System.IO; @@ -14,7 +11,6 @@ public class PluginPayload : IVerifiable public string Plugin; public byte MessageType; public byte[] Data; - public PluginPayloadRole WitnessRole; public Witness Witness; private UInt256 _hash = null; @@ -33,7 +29,6 @@ public UInt256 Hash public int Size => Plugin.GetVarSize() + //Plugin sizeof(byte) + //MessageType - sizeof(PluginPayloadRole) + //WitnessRole Data.GetVarSize() + //Data 1 + Witness.Size; //Witness @@ -62,30 +57,11 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader) Plugin = reader.ReadVarString(32); MessageType = reader.ReadByte(); Data = reader.ReadVarBytes(ushort.MaxValue); - WitnessRole = (PluginPayloadRole)reader.ReadByte(); - if (!Enum.IsDefined(typeof(PluginPayloadRole), WitnessRole)) throw new FormatException(); } UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot) { - switch (WitnessRole) - { - case PluginPayloadRole.Committee: - { - return new[] { NativeContract.NEO.GetCommitteeAddress(snapshot) }; - } - case PluginPayloadRole.Validators: - { - return new[] { Blockchain.GetConsensusAddress(NativeContract.NEO.GetNextBlockValidators(snapshot)) }; - } - case PluginPayloadRole.StateValidator: - case PluginPayloadRole.Oracle: - { - return new[] { Blockchain.GetConsensusAddress(NativeContract.Designate.GetDesignatedByRole(snapshot, (Role)WitnessRole, snapshot.Height)) }; - } - } - - throw new ArgumentException(); + return new[] { Witness.ScriptHash }; // This address should be checked by consumer } void ISerializable.Serialize(BinaryWriter writer) @@ -99,7 +75,6 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer) writer.WriteVarString(Plugin); writer.Write(MessageType); writer.WriteVarBytes(Data); - writer.Write((byte)WitnessRole); } public bool Verify(StoreView snapshot) diff --git a/src/neo/Network/P2P/Payloads/PluginPayloadRole.cs b/src/neo/Network/P2P/Payloads/PluginPayloadRole.cs deleted file mode 100644 index df9d5a9043..0000000000 --- a/src/neo/Network/P2P/Payloads/PluginPayloadRole.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Neo.Network.P2P.Payloads -{ - public enum PluginPayloadRole : byte - { - Committee = 0, - Validators = 2, - StateValidator = 4, - Oracle = 8 - } -} From e7355d007b63a162cafaff467185c21e202cc9ec Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 21 Dec 2020 10:53:26 +0100 Subject: [PATCH 05/23] WhiteList p2p message --- src/neo/Ledger/Blockchain.cs | 16 ++++++++++++++++ .../Network/P2P/RemoteNode.ProtocolHandler.cs | 1 + 2 files changed, 17 insertions(+) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index a1be404406..f018d7f0f7 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -10,6 +10,7 @@ using Neo.Persistence; using Neo.Plugins; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM; using System; using System.Collections.Concurrent; @@ -66,6 +67,7 @@ public class RelayResult { public IInventory Inventory; public VerifyResult Resu private readonly Dictionary block_cache_unverified = new Dictionary(); internal readonly RelayCache RelayCache = new RelayCache(100); private SnapshotView currentSnapshot; + private HashSet addressWhiteList = new HashSet(); public IStore Store { get; } public ReadOnlyView View { get; } @@ -472,6 +474,7 @@ protected override void PostStop() { base.PostStop(); currentSnapshot?.Dispose(); + addressWhiteList.Clear(); } public static Props Props(NeoSystem system, IStore store) @@ -517,6 +520,19 @@ private void SendRelayResult(IInventory inventory, VerifyResult result) private void UpdateCurrentSnapshot() { Interlocked.Exchange(ref currentSnapshot, GetSnapshot())?.Dispose(); + HashSet whiteList = new HashSet + { + NativeContract.NEO.GetCommitteeAddress(currentSnapshot), + GetConsensusAddress(NativeContract.NEO.GetNextBlockValidators(currentSnapshot)), + GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height)), + GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height)) + }; + Interlocked.Exchange(ref addressWhiteList, whiteList)?.Clear(); + } + + internal bool IsWhiteListed(UInt160 address) + { + return addressWhiteList.Contains(address); } } diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index fc72eb3929..b2fc755734 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -43,6 +43,7 @@ private void OnMessage(Message msg) { var payload = (PluginPayload)msg.Payload; if (!knownHashes.Add(payload.Hash)) return; + if (!Blockchain.Singleton.IsWhiteListed(payload.Witness.ScriptHash)) return; if (!payload.Verify(Blockchain.Singleton.GetSnapshot())) return; } foreach (IP2PPlugin plugin in Plugin.P2PPlugins) From 0af78581ab91a1d8fae2563529fc62540c73e80f Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 21 Dec 2020 10:55:35 +0100 Subject: [PATCH 06/23] Clean --- src/neo/Network/P2P/Payloads/PluginPayload.cs | 2 ++ src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/neo/Network/P2P/Payloads/PluginPayload.cs b/src/neo/Network/P2P/Payloads/PluginPayload.cs index 4ac5090d05..0879179720 100644 --- a/src/neo/Network/P2P/Payloads/PluginPayload.cs +++ b/src/neo/Network/P2P/Payloads/PluginPayload.cs @@ -1,4 +1,5 @@ using Neo.IO; +using Neo.Ledger; using Neo.Persistence; using Neo.SmartContract; using System; @@ -79,6 +80,7 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer) public bool Verify(StoreView snapshot) { + if (!Blockchain.Singleton.IsWhiteListed(Witness.ScriptHash)) return false; return this.VerifyWitnesses(snapshot, 0_02000000); } } diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index b2fc755734..fc72eb3929 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -43,7 +43,6 @@ private void OnMessage(Message msg) { var payload = (PluginPayload)msg.Payload; if (!knownHashes.Add(payload.Hash)) return; - if (!Blockchain.Singleton.IsWhiteListed(payload.Witness.ScriptHash)) return; if (!payload.Verify(Blockchain.Singleton.GetSnapshot())) return; } foreach (IP2PPlugin plugin in Plugin.P2PPlugins) From 4334d6e54d88e579c6ebbf5f94ddba0ce10f7d9c Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 22 Dec 2020 12:37:09 +0100 Subject: [PATCH 07/23] Rename --- src/neo/Network/P2P/MessageCommand.cs | 4 ++-- .../{PluginPayload.cs => ExtensiblePayload.cs} | 10 +++++----- src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) rename src/neo/Network/P2P/Payloads/{PluginPayload.cs => ExtensiblePayload.cs} (90%) diff --git a/src/neo/Network/P2P/MessageCommand.cs b/src/neo/Network/P2P/MessageCommand.cs index fba87781cd..7438d90850 100644 --- a/src/neo/Network/P2P/MessageCommand.cs +++ b/src/neo/Network/P2P/MessageCommand.cs @@ -40,8 +40,8 @@ public enum MessageCommand : byte Block = 0x2c, [ReflectionCache(typeof(ConsensusPayload))] Consensus = 0x2d, - [ReflectionCache(typeof(PluginPayload))] - Plugin = 0x2e, + [ReflectionCache(typeof(ExtensiblePayload))] + Extensible = 0x2e, Reject = 0x2f, //SPV protocol diff --git a/src/neo/Network/P2P/Payloads/PluginPayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs similarity index 90% rename from src/neo/Network/P2P/Payloads/PluginPayload.cs rename to src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index 0879179720..d0fcdc13ee 100644 --- a/src/neo/Network/P2P/Payloads/PluginPayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -7,9 +7,9 @@ namespace Neo.Network.P2P.Payloads { - public class PluginPayload : IVerifiable + public class ExtensiblePayload : IVerifiable { - public string Plugin; + public string Receiver; public byte MessageType; public byte[] Data; public Witness Witness; @@ -28,7 +28,7 @@ public UInt256 Hash } public int Size => - Plugin.GetVarSize() + //Plugin + Receiver.GetVarSize() + //Receiver sizeof(byte) + //MessageType Data.GetVarSize() + //Data 1 + Witness.Size; //Witness @@ -55,7 +55,7 @@ void ISerializable.Deserialize(BinaryReader reader) void IVerifiable.DeserializeUnsigned(BinaryReader reader) { - Plugin = reader.ReadVarString(32); + Receiver = reader.ReadVarString(32); MessageType = reader.ReadByte(); Data = reader.ReadVarBytes(ushort.MaxValue); } @@ -73,7 +73,7 @@ void ISerializable.Serialize(BinaryWriter writer) void IVerifiable.SerializeUnsigned(BinaryWriter writer) { - writer.WriteVarString(Plugin); + writer.WriteVarString(Receiver); writer.Write(MessageType); writer.WriteVarBytes(Data); } diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index fc72eb3929..a568ed2ccc 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -39,9 +39,9 @@ protected override UInt256 GetKeyForItem((UInt256, DateTime) item) private void OnMessage(Message msg) { - if (msg.Command == MessageCommand.Plugin) + if (msg.Command == MessageCommand.Extensible) { - var payload = (PluginPayload)msg.Payload; + var payload = (ExtensiblePayload)msg.Payload; if (!knownHashes.Add(payload.Hash)) return; if (!payload.Verify(Blockchain.Singleton.GetSnapshot())) return; } @@ -113,7 +113,7 @@ private void OnMessage(Message msg) if (msg.Payload.Size <= Transaction.MaxTransactionSize) OnInventoryReceived((Transaction)msg.Payload); break; - case MessageCommand.Plugin: + case MessageCommand.Extensible: OnPluginMessage(msg); break; case MessageCommand.Verack: From 7960e27a98481e4dea8ef332059acfbc431779d1 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Tue, 22 Dec 2020 20:37:05 +0800 Subject: [PATCH 08/23] Rename --- src/neo/Ledger/Blockchain.cs | 14 ++++++-------- src/neo/Network/P2P/Payloads/ExtensiblePayload.cs | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index f018d7f0f7..add493f4d1 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -15,6 +15,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -67,7 +68,7 @@ public class RelayResult { public IInventory Inventory; public VerifyResult Resu private readonly Dictionary block_cache_unverified = new Dictionary(); internal readonly RelayCache RelayCache = new RelayCache(100); private SnapshotView currentSnapshot; - private HashSet addressWhiteList = new HashSet(); + private ImmutableHashSet extensibleWitnessWhiteList; public IStore Store { get; } public ReadOnlyView View { get; } @@ -474,7 +475,6 @@ protected override void PostStop() { base.PostStop(); currentSnapshot?.Dispose(); - addressWhiteList.Clear(); } public static Props Props(NeoSystem system, IStore store) @@ -520,19 +520,17 @@ private void SendRelayResult(IInventory inventory, VerifyResult result) private void UpdateCurrentSnapshot() { Interlocked.Exchange(ref currentSnapshot, GetSnapshot())?.Dispose(); - HashSet whiteList = new HashSet - { + extensibleWitnessWhiteList = ImmutableHashSet.Create( NativeContract.NEO.GetCommitteeAddress(currentSnapshot), GetConsensusAddress(NativeContract.NEO.GetNextBlockValidators(currentSnapshot)), GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height)), GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height)) - }; - Interlocked.Exchange(ref addressWhiteList, whiteList)?.Clear(); + ); } - internal bool IsWhiteListed(UInt160 address) + internal bool IsExtensibleWitnessWhiteListed(UInt160 address) { - return addressWhiteList.Contains(address); + return extensibleWitnessWhiteList.Contains(address); } } diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index d0fcdc13ee..11d0f26c7c 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -80,7 +80,7 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer) public bool Verify(StoreView snapshot) { - if (!Blockchain.Singleton.IsWhiteListed(Witness.ScriptHash)) return false; + if (!Blockchain.Singleton.IsExtensibleWitnessWhiteListed(Witness.ScriptHash)) return false; return this.VerifyWitnesses(snapshot, 0_02000000); } } From 8250aa1a965991c0af7e86e6fa2cbf5bd2d7d7de Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 24 Dec 2020 09:51:31 +0100 Subject: [PATCH 09/23] Add single validators --- src/neo/Ledger/Blockchain.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index add493f4d1..ebcf1a4d93 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -520,11 +520,16 @@ private void SendRelayResult(IInventory inventory, VerifyResult result) private void UpdateCurrentSnapshot() { Interlocked.Exchange(ref currentSnapshot, GetSnapshot())?.Dispose(); + var validators = NativeContract.NEO.GetNextBlockValidators(currentSnapshot); extensibleWitnessWhiteList = ImmutableHashSet.Create( - NativeContract.NEO.GetCommitteeAddress(currentSnapshot), - GetConsensusAddress(NativeContract.NEO.GetNextBlockValidators(currentSnapshot)), - GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height)), - GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height)) + new UInt160[] { + GetConsensusAddress(validators), + NativeContract.NEO.GetCommitteeAddress(currentSnapshot), + GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height)), + GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height)) + } + .Concat(validators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) + .ToArray() ); } From a8eca563194af917c2f3cfafe3a4c2e1964f7897 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 24 Dec 2020 09:52:59 +0100 Subject: [PATCH 10/23] Add single validators --- src/neo/Ledger/Blockchain.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index ebcf1a4d93..feff008ec0 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -521,14 +521,17 @@ private void UpdateCurrentSnapshot() { Interlocked.Exchange(ref currentSnapshot, GetSnapshot())?.Dispose(); var validators = NativeContract.NEO.GetNextBlockValidators(currentSnapshot); + var oracles = NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height); + var stateValidators = NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height); extensibleWitnessWhiteList = ImmutableHashSet.Create( new UInt160[] { - GetConsensusAddress(validators), NativeContract.NEO.GetCommitteeAddress(currentSnapshot), - GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height)), - GetConsensusAddress(NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height)) + GetConsensusAddress(validators), + GetConsensusAddress(oracles), + GetConsensusAddress(stateValidators) } .Concat(validators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) + .Concat(oracles.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) .ToArray() ); } From 9d2756a893439bdb8e3666717075c361872d6fd9 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 24 Dec 2020 09:54:49 +0100 Subject: [PATCH 11/23] Update Blockchain.cs --- src/neo/Ledger/Blockchain.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index feff008ec0..38e89728db 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -532,6 +532,7 @@ private void UpdateCurrentSnapshot() } .Concat(validators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) .Concat(oracles.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) + .Concat(stateValidators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) .ToArray() ); } From c656f3bb513a30cbbf6f0d4f9e541d7fbbe02a30 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 24 Dec 2020 10:10:25 +0100 Subject: [PATCH 12/23] IInventory --- src/neo/Ledger/Blockchain.cs | 9 +++------ src/neo/Network/P2P/Message.cs | 1 + src/neo/Network/P2P/Payloads/ExtensiblePayload.cs | 4 +++- src/neo/Network/P2P/Payloads/InventoryType.cs | 1 + src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs | 11 +++-------- src/neo/Network/P2P/RemoteNode.cs | 2 ++ src/neo/Network/P2P/TaskManager.cs | 2 +- 7 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index 38e89728db..f6e5e3a882 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -524,12 +524,9 @@ private void UpdateCurrentSnapshot() var oracles = NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height); var stateValidators = NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height); extensibleWitnessWhiteList = ImmutableHashSet.Create( - new UInt160[] { - NativeContract.NEO.GetCommitteeAddress(currentSnapshot), - GetConsensusAddress(validators), - GetConsensusAddress(oracles), - GetConsensusAddress(stateValidators) - } + new UInt160[] { NativeContract.NEO.GetCommitteeAddress(currentSnapshot), GetConsensusAddress(validators) } + .Concat(oracles.Length == 0 ? Array.Empty() : new UInt160[] { GetConsensusAddress(oracles) }) + .Concat(stateValidators.Length == 0 ? Array.Empty() : new UInt160[] { GetConsensusAddress(stateValidators) }) .Concat(validators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) .Concat(oracles.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) .Concat(stateValidators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) diff --git a/src/neo/Network/P2P/Message.cs b/src/neo/Network/P2P/Message.cs index 397ee4d033..ed0d23f883 100644 --- a/src/neo/Network/P2P/Message.cs +++ b/src/neo/Network/P2P/Message.cs @@ -39,6 +39,7 @@ public static Message Create(MessageCommand command, ISerializable payload = nul bool tryCompression = command == MessageCommand.Block || command == MessageCommand.Consensus || + command == MessageCommand.Extensible || command == MessageCommand.Transaction || command == MessageCommand.Headers || command == MessageCommand.Addr || diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index 11d0f26c7c..39f7b28461 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -7,7 +7,7 @@ namespace Neo.Network.P2P.Payloads { - public class ExtensiblePayload : IVerifiable + public class ExtensiblePayload : IInventory { public string Receiver; public byte MessageType; @@ -27,6 +27,8 @@ public UInt256 Hash } } + InventoryType IInventory.InventoryType => InventoryType.Extensible; + public int Size => Receiver.GetVarSize() + //Receiver sizeof(byte) + //MessageType diff --git a/src/neo/Network/P2P/Payloads/InventoryType.cs b/src/neo/Network/P2P/Payloads/InventoryType.cs index 0a1b831d12..33b9f2fc25 100644 --- a/src/neo/Network/P2P/Payloads/InventoryType.cs +++ b/src/neo/Network/P2P/Payloads/InventoryType.cs @@ -4,6 +4,7 @@ public enum InventoryType : byte { TX = MessageCommand.Transaction, Block = MessageCommand.Block, + Extensible = MessageCommand.Extensible, Consensus = MessageCommand.Consensus } } diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index a568ed2ccc..141c425949 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -73,6 +73,9 @@ private void OnMessage(Message msg) case MessageCommand.Consensus: OnInventoryReceived((ConsensusPayload)msg.Payload); break; + case MessageCommand.Extensible: + OnInventoryReceived((ExtensiblePayload)msg.Payload); + break; case MessageCommand.FilterAdd: OnFilterAddMessageReceived((FilterAddPayload)msg.Payload); break; @@ -113,9 +116,6 @@ private void OnMessage(Message msg) if (msg.Payload.Size <= Transaction.MaxTransactionSize) OnInventoryReceived((Transaction)msg.Payload); break; - case MessageCommand.Extensible: - OnPluginMessage(msg); - break; case MessageCommand.Verack: case MessageCommand.Version: throw new ProtocolViolationException(); @@ -128,11 +128,6 @@ private void OnMessage(Message msg) } } - private void OnPluginMessage(Message msg) - { - system.LocalNode.Tell(msg); - } - private void OnAddrMessageReceived(AddrPayload payload) { ref bool sent = ref sentCommands[(byte)MessageCommand.GetAddr]; diff --git a/src/neo/Network/P2P/RemoteNode.cs b/src/neo/Network/P2P/RemoteNode.cs index 9440584ddc..8e1343ec0b 100644 --- a/src/neo/Network/P2P/RemoteNode.cs +++ b/src/neo/Network/P2P/RemoteNode.cs @@ -87,6 +87,7 @@ private void EnqueueMessage(Message message) { case MessageCommand.Alert: case MessageCommand.Consensus: + case MessageCommand.Extensible: case MessageCommand.FilterAdd: case MessageCommand.FilterClear: case MessageCommand.FilterLoad: @@ -223,6 +224,7 @@ internal protected override bool IsHighPriority(object message) switch (msg.Command) { case MessageCommand.Consensus: + case MessageCommand.Extensible: case MessageCommand.FilterAdd: case MessageCommand.FilterClear: case MessageCommand.FilterLoad: diff --git a/src/neo/Network/P2P/TaskManager.cs b/src/neo/Network/P2P/TaskManager.cs index fb1ade45bd..688fa13cff 100644 --- a/src/neo/Network/P2P/TaskManager.cs +++ b/src/neo/Network/P2P/TaskManager.cs @@ -342,7 +342,7 @@ internal protected override bool IsHighPriority(object message) case TaskManager.RestartTasks _: return true; case TaskManager.NewTasks tasks: - if (tasks.Payload.Type == InventoryType.Block || tasks.Payload.Type == InventoryType.Consensus) + if (tasks.Payload.Type == InventoryType.Block || tasks.Payload.Type == InventoryType.Consensus || tasks.Payload.Type == InventoryType.Extensible) return true; return false; default: From 7fd40ece46d41d6209bc9596070e74697242d873 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Sun, 27 Dec 2020 22:44:30 +0800 Subject: [PATCH 13/23] Use CreateBuilder --- src/neo/Ledger/Blockchain.cs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index f6e5e3a882..e3146513ec 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -520,18 +520,24 @@ private void SendRelayResult(IInventory inventory, VerifyResult result) private void UpdateCurrentSnapshot() { Interlocked.Exchange(ref currentSnapshot, GetSnapshot())?.Dispose(); + var builder = ImmutableHashSet.CreateBuilder(); + builder.Add(NativeContract.NEO.GetCommitteeAddress(currentSnapshot)); var validators = NativeContract.NEO.GetNextBlockValidators(currentSnapshot); + builder.Add(GetConsensusAddress(validators)); + builder.UnionWith(validators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())); var oracles = NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.Oracle, currentSnapshot.Height); + if (oracles.Length > 0) + { + builder.Add(GetConsensusAddress(oracles)); + builder.UnionWith(oracles.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())); + } var stateValidators = NativeContract.RoleManagement.GetDesignatedByRole(currentSnapshot, Role.StateValidator, currentSnapshot.Height); - extensibleWitnessWhiteList = ImmutableHashSet.Create( - new UInt160[] { NativeContract.NEO.GetCommitteeAddress(currentSnapshot), GetConsensusAddress(validators) } - .Concat(oracles.Length == 0 ? Array.Empty() : new UInt160[] { GetConsensusAddress(oracles) }) - .Concat(stateValidators.Length == 0 ? Array.Empty() : new UInt160[] { GetConsensusAddress(stateValidators) }) - .Concat(validators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) - .Concat(oracles.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) - .Concat(stateValidators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())) - .ToArray() - ); + if (stateValidators.Length > 0) + { + builder.Add(GetConsensusAddress(stateValidators)); + builder.UnionWith(stateValidators.Select(u => Contract.CreateSignatureRedeemScript(u).ToScriptHash())); + } + extensibleWitnessWhiteList = builder.ToImmutable(); } internal bool IsExtensibleWitnessWhiteListed(UInt160 address) From 6c62a301ffa7184d8ceadf4697f3308abcc95b40 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 29 Dec 2020 13:07:31 +0100 Subject: [PATCH 14/23] Add Height --- .../Network/P2P/Payloads/ExtensiblePayload.cs | 9 ++++ .../P2P/Payloads/UT_ExtensiblePayload.cs | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index 39f7b28461..2fd2e49977 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -11,6 +11,8 @@ public class ExtensiblePayload : IInventory { public string Receiver; public byte MessageType; + public uint ValidBlockStart; + public uint ValidBlockEnd; public byte[] Data; public Witness Witness; @@ -32,6 +34,8 @@ public UInt256 Hash public int Size => Receiver.GetVarSize() + //Receiver sizeof(byte) + //MessageType + sizeof(uint) + //ValidBlockStart + sizeof(uint) + //ValidBlockEnd Data.GetVarSize() + //Data 1 + Witness.Size; //Witness @@ -59,6 +63,8 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader) { Receiver = reader.ReadVarString(32); MessageType = reader.ReadByte(); + ValidBlockStart = reader.ReadUInt32(); + ValidBlockEnd = reader.ReadUInt32(); Data = reader.ReadVarBytes(ushort.MaxValue); } @@ -77,11 +83,14 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer) { writer.WriteVarString(Receiver); writer.Write(MessageType); + writer.Write(ValidBlockStart); + writer.Write(ValidBlockEnd); writer.WriteVarBytes(Data); } public bool Verify(StoreView snapshot) { + if (snapshot.PersistingBlock.Index < ValidBlockStart || snapshot.PersistingBlock.Index > ValidBlockEnd) return false; if (!Blockchain.Singleton.IsExtensibleWitnessWhiteListed(Witness.ScriptHash)) return false; return this.VerifyWitnesses(snapshot, 0_02000000); } diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs new file mode 100644 index 0000000000..6988b15afe --- /dev/null +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -0,0 +1,44 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.IO; +using Neo.Network.P2P.Payloads; + +namespace Neo.UnitTests.Network.P2P.Payloads +{ + [TestClass] + public class UT_ExtensiblePayload + { + [TestMethod] + public void Size_Get() + { + var test = new ExtensiblePayload() + { + Receiver = "123", + Data = new byte[] { 1, 2, 3 }, + Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = new byte[0] } + }; + test.Size.Should().Be(23); + } + + [TestMethod] + public void DeserializeAndSerialize() + { + var test = new ExtensiblePayload() + { + Receiver = "123", + MessageType = 123, + ValidBlockEnd = 456, + ValidBlockStart = 789, + Data = new byte[] { 1, 2, 3 }, + Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = new byte[0] } + }; + var clone = test.ToArray().AsSerializable(); + + Assert.AreEqual(test.Hash, clone.Hash); + Assert.AreEqual(test.ValidBlockStart, clone.ValidBlockStart); + Assert.AreEqual(test.ValidBlockEnd, clone.ValidBlockEnd); + Assert.AreEqual(test.Receiver, clone.Receiver); + Assert.AreEqual(test.MessageType, clone.MessageType); + } + } +} From 18d3e9a2168ebe75545e07cc507c67f50ef68a7f Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Wed, 30 Dec 2020 11:23:12 +0800 Subject: [PATCH 15/23] Simplify --- src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index 141c425949..9bbb96464d 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -68,13 +68,9 @@ private void OnMessage(Message msg) OnAddrMessageReceived((AddrPayload)msg.Payload); break; case MessageCommand.Block: - OnInventoryReceived((Block)msg.Payload); - break; case MessageCommand.Consensus: - OnInventoryReceived((ConsensusPayload)msg.Payload); - break; case MessageCommand.Extensible: - OnInventoryReceived((ExtensiblePayload)msg.Payload); + OnInventoryReceived((IInventory)msg.Payload); break; case MessageCommand.FilterAdd: OnFilterAddMessageReceived((FilterAddPayload)msg.Payload); From 4d8b0a2a0ff646225d9f7b9353ea936ba59956d1 Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 30 Dec 2020 09:45:10 +0100 Subject: [PATCH 16/23] Remove MessageType --- src/neo/Network/P2P/Payloads/ExtensiblePayload.cs | 4 ---- .../Network/P2P/Payloads/UT_ExtensiblePayload.cs | 2 -- 2 files changed, 6 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index 2fd2e49977..32651be260 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -10,7 +10,6 @@ namespace Neo.Network.P2P.Payloads public class ExtensiblePayload : IInventory { public string Receiver; - public byte MessageType; public uint ValidBlockStart; public uint ValidBlockEnd; public byte[] Data; @@ -33,7 +32,6 @@ public UInt256 Hash public int Size => Receiver.GetVarSize() + //Receiver - sizeof(byte) + //MessageType sizeof(uint) + //ValidBlockStart sizeof(uint) + //ValidBlockEnd Data.GetVarSize() + //Data @@ -62,7 +60,6 @@ void ISerializable.Deserialize(BinaryReader reader) void IVerifiable.DeserializeUnsigned(BinaryReader reader) { Receiver = reader.ReadVarString(32); - MessageType = reader.ReadByte(); ValidBlockStart = reader.ReadUInt32(); ValidBlockEnd = reader.ReadUInt32(); Data = reader.ReadVarBytes(ushort.MaxValue); @@ -82,7 +79,6 @@ void ISerializable.Serialize(BinaryWriter writer) void IVerifiable.SerializeUnsigned(BinaryWriter writer) { writer.WriteVarString(Receiver); - writer.Write(MessageType); writer.Write(ValidBlockStart); writer.Write(ValidBlockEnd); writer.WriteVarBytes(Data); diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index 6988b15afe..fb91a5eaa3 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -26,7 +26,6 @@ public void DeserializeAndSerialize() var test = new ExtensiblePayload() { Receiver = "123", - MessageType = 123, ValidBlockEnd = 456, ValidBlockStart = 789, Data = new byte[] { 1, 2, 3 }, @@ -38,7 +37,6 @@ public void DeserializeAndSerialize() Assert.AreEqual(test.ValidBlockStart, clone.ValidBlockStart); Assert.AreEqual(test.ValidBlockEnd, clone.ValidBlockEnd); Assert.AreEqual(test.Receiver, clone.Receiver); - Assert.AreEqual(test.MessageType, clone.MessageType); } } } From 9c2a6f6577b4fe5852467760a6f2e5cf858620fb Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 30 Dec 2020 10:35:52 +0100 Subject: [PATCH 17/23] Update --- src/neo/Ledger/Blockchain.cs | 8 ++++++-- src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs | 6 ------ src/neo/Plugins/IP2PPlugin.cs | 1 + tests/neo.UnitTests/Plugins/UT_Plugin.cs | 6 +++++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index e3146513ec..6635167368 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -291,8 +291,12 @@ private void OnInventory(IInventory inventory, bool relay = true) Transaction transaction => OnNewTransaction(transaction), _ => OnNewInventory(inventory) }; - if (relay && result == VerifyResult.Succeed) - system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = inventory }); + if (result == VerifyResult.Succeed) + { + if (relay) system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = inventory }); + foreach (IP2PPlugin plugin in Plugin.P2PPlugins) + plugin.OnVerifiedInventory(inventory); + } SendRelayResult(inventory, result); } diff --git a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs index 9bbb96464d..48e1cb3143 100644 --- a/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -39,12 +39,6 @@ protected override UInt256 GetKeyForItem((UInt256, DateTime) item) private void OnMessage(Message msg) { - if (msg.Command == MessageCommand.Extensible) - { - var payload = (ExtensiblePayload)msg.Payload; - if (!knownHashes.Add(payload.Hash)) return; - if (!payload.Verify(Blockchain.Singleton.GetSnapshot())) return; - } foreach (IP2PPlugin plugin in Plugin.P2PPlugins) if (!plugin.OnP2PMessage(msg)) return; diff --git a/src/neo/Plugins/IP2PPlugin.cs b/src/neo/Plugins/IP2PPlugin.cs index 40c083545b..d6ba709e36 100644 --- a/src/neo/Plugins/IP2PPlugin.cs +++ b/src/neo/Plugins/IP2PPlugin.cs @@ -7,5 +7,6 @@ public interface IP2PPlugin { bool OnP2PMessage(Message message) => true; bool OnConsensusMessage(ConsensusPayload payload) => true; + void OnVerifiedInventory(IInventory inventory); } } diff --git a/tests/neo.UnitTests/Plugins/UT_Plugin.cs b/tests/neo.UnitTests/Plugins/UT_Plugin.cs index d56dcd8c15..de32a45898 100644 --- a/tests/neo.UnitTests/Plugins/UT_Plugin.cs +++ b/tests/neo.UnitTests/Plugins/UT_Plugin.cs @@ -1,5 +1,6 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Network.P2P.Payloads; using Neo.Plugins; using System; @@ -10,7 +11,10 @@ public class UT_Plugin { private static readonly object locker = new object(); - private class DummyP2PPlugin : IP2PPlugin { } + private class DummyP2PPlugin : IP2PPlugin + { + public void OnVerifiedInventory(IInventory inventory) { } + } private class dummyPersistencePlugin : IPersistencePlugin { } [TestMethod] From 48a98a5f4fa7c5ddee908a422f46a8cc0915fc4c Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 30 Dec 2020 10:38:34 +0100 Subject: [PATCH 18/23] Fix UT --- .../neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index fb91a5eaa3..747fe53552 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -17,7 +17,7 @@ public void Size_Get() Data = new byte[] { 1, 2, 3 }, Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = new byte[0] } }; - test.Size.Should().Be(23); + test.Size.Should().Be(22); } [TestMethod] From eb41546ca9d98882d1d03a2cc1d8e3779a1258f9 Mon Sep 17 00:00:00 2001 From: Shargon Date: Fri, 1 Jan 2021 11:40:36 +0100 Subject: [PATCH 19/23] Rename --- src/neo/Network/P2P/Payloads/ExtensiblePayload.cs | 8 ++++---- .../Network/P2P/Payloads/UT_ExtensiblePayload.cs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index 32651be260..fa07d8a786 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -9,7 +9,7 @@ namespace Neo.Network.P2P.Payloads { public class ExtensiblePayload : IInventory { - public string Receiver; + public string Category; public uint ValidBlockStart; public uint ValidBlockEnd; public byte[] Data; @@ -31,7 +31,7 @@ public UInt256 Hash InventoryType IInventory.InventoryType => InventoryType.Extensible; public int Size => - Receiver.GetVarSize() + //Receiver + Category.GetVarSize() + //Receiver sizeof(uint) + //ValidBlockStart sizeof(uint) + //ValidBlockEnd Data.GetVarSize() + //Data @@ -59,7 +59,7 @@ void ISerializable.Deserialize(BinaryReader reader) void IVerifiable.DeserializeUnsigned(BinaryReader reader) { - Receiver = reader.ReadVarString(32); + Category = reader.ReadVarString(32); ValidBlockStart = reader.ReadUInt32(); ValidBlockEnd = reader.ReadUInt32(); Data = reader.ReadVarBytes(ushort.MaxValue); @@ -78,7 +78,7 @@ void ISerializable.Serialize(BinaryWriter writer) void IVerifiable.SerializeUnsigned(BinaryWriter writer) { - writer.WriteVarString(Receiver); + writer.WriteVarString(Category); writer.Write(ValidBlockStart); writer.Write(ValidBlockEnd); writer.WriteVarBytes(Data); diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index 747fe53552..6822ca021c 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -13,7 +13,7 @@ public void Size_Get() { var test = new ExtensiblePayload() { - Receiver = "123", + Category = "123", Data = new byte[] { 1, 2, 3 }, Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = new byte[0] } }; @@ -25,7 +25,7 @@ public void DeserializeAndSerialize() { var test = new ExtensiblePayload() { - Receiver = "123", + Category = "123", ValidBlockEnd = 456, ValidBlockStart = 789, Data = new byte[] { 1, 2, 3 }, @@ -36,7 +36,7 @@ public void DeserializeAndSerialize() Assert.AreEqual(test.Hash, clone.Hash); Assert.AreEqual(test.ValidBlockStart, clone.ValidBlockStart); Assert.AreEqual(test.ValidBlockEnd, clone.ValidBlockEnd); - Assert.AreEqual(test.Receiver, clone.Receiver); + Assert.AreEqual(test.Category, clone.Category); } } } From 98a7316a8bf0a0ab03dfc2536d66dfa1b5db3683 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 5 Jan 2021 13:46:04 +0100 Subject: [PATCH 20/23] Add sender --- .../Network/P2P/Payloads/ExtensiblePayload.cs | 8 +++++++- .../P2P/Payloads/UT_ExtensiblePayload.cs | 17 ++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index fa07d8a786..fcd27bf1b8 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -28,10 +28,13 @@ public UInt256 Hash } } + public UInt160 Sender { get; set; } + InventoryType IInventory.InventoryType => InventoryType.Extensible; public int Size => - Category.GetVarSize() + //Receiver + UInt160.Length + //Sender + Category.GetVarSize() + //Category sizeof(uint) + //ValidBlockStart sizeof(uint) + //ValidBlockEnd Data.GetVarSize() + //Data @@ -55,10 +58,12 @@ void ISerializable.Deserialize(BinaryReader reader) ((IVerifiable)this).DeserializeUnsigned(reader); if (reader.ReadByte() != 1) throw new FormatException(); Witness = reader.ReadSerializable(); + if (Witness.ScriptHash != Sender) throw new FormatException(); } void IVerifiable.DeserializeUnsigned(BinaryReader reader) { + Sender = reader.ReadSerializable(); Category = reader.ReadVarString(32); ValidBlockStart = reader.ReadUInt32(); ValidBlockEnd = reader.ReadUInt32(); @@ -78,6 +83,7 @@ void ISerializable.Serialize(BinaryWriter writer) void IVerifiable.SerializeUnsigned(BinaryWriter writer) { + writer.Write(Sender); writer.WriteVarString(Category); writer.Write(ValidBlockStart); writer.Write(ValidBlockEnd); diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index 6822ca021c..d4259e0ac8 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -2,6 +2,8 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.IO; using Neo.Network.P2P.Payloads; +using Neo.SmartContract; +using System; namespace Neo.UnitTests.Network.P2P.Payloads { @@ -13,11 +15,12 @@ public void Size_Get() { var test = new ExtensiblePayload() { + Sender = Array.Empty().ToScriptHash(), Category = "123", Data = new byte[] { 1, 2, 3 }, - Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = new byte[0] } + Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = Array.Empty() } }; - test.Size.Should().Be(22); + test.Size.Should().Be(42); } [TestMethod] @@ -25,18 +28,26 @@ public void DeserializeAndSerialize() { var test = new ExtensiblePayload() { + Sender = Array.Empty().ToScriptHash(), Category = "123", ValidBlockEnd = 456, ValidBlockStart = 789, Data = new byte[] { 1, 2, 3 }, - Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = new byte[0] } + Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = Array.Empty() } }; var clone = test.ToArray().AsSerializable(); + Assert.AreEqual(test.Sender, clone.Witness.ScriptHash); Assert.AreEqual(test.Hash, clone.Hash); Assert.AreEqual(test.ValidBlockStart, clone.ValidBlockStart); Assert.AreEqual(test.ValidBlockEnd, clone.ValidBlockEnd); Assert.AreEqual(test.Category, clone.Category); + + // Check error + + test.Sender = UInt160.Zero; + + Assert.ThrowsException(() => test.ToArray().AsSerializable()); } } } From 0b28d17d88dbfe4b350eed2b04f8f47150fef929 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Wed, 6 Jan 2021 11:54:36 +0800 Subject: [PATCH 21/23] Update ExtensiblePayload.cs --- src/neo/Network/P2P/Payloads/ExtensiblePayload.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index fcd27bf1b8..9feb83fe05 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -12,6 +12,7 @@ public class ExtensiblePayload : IInventory public string Category; public uint ValidBlockStart; public uint ValidBlockEnd; + public UInt160 Sender; public byte[] Data; public Witness Witness; @@ -28,15 +29,13 @@ public UInt256 Hash } } - public UInt160 Sender { get; set; } - InventoryType IInventory.InventoryType => InventoryType.Extensible; public int Size => - UInt160.Length + //Sender Category.GetVarSize() + //Category sizeof(uint) + //ValidBlockStart sizeof(uint) + //ValidBlockEnd + UInt160.Length + //Sender Data.GetVarSize() + //Data 1 + Witness.Size; //Witness @@ -63,16 +62,16 @@ void ISerializable.Deserialize(BinaryReader reader) void IVerifiable.DeserializeUnsigned(BinaryReader reader) { - Sender = reader.ReadSerializable(); Category = reader.ReadVarString(32); ValidBlockStart = reader.ReadUInt32(); ValidBlockEnd = reader.ReadUInt32(); + Sender = reader.ReadSerializable(); Data = reader.ReadVarBytes(ushort.MaxValue); } UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot) { - return new[] { Witness.ScriptHash }; // This address should be checked by consumer + return new[] { Sender }; // This address should be checked by consumer } void ISerializable.Serialize(BinaryWriter writer) @@ -83,17 +82,17 @@ void ISerializable.Serialize(BinaryWriter writer) void IVerifiable.SerializeUnsigned(BinaryWriter writer) { - writer.Write(Sender); writer.WriteVarString(Category); writer.Write(ValidBlockStart); writer.Write(ValidBlockEnd); + writer.Write(Sender); writer.WriteVarBytes(Data); } public bool Verify(StoreView snapshot) { if (snapshot.PersistingBlock.Index < ValidBlockStart || snapshot.PersistingBlock.Index > ValidBlockEnd) return false; - if (!Blockchain.Singleton.IsExtensibleWitnessWhiteListed(Witness.ScriptHash)) return false; + if (!Blockchain.Singleton.IsExtensibleWitnessWhiteListed(Sender)) return false; return this.VerifyWitnesses(snapshot, 0_02000000); } } From 7f49339dd64cdb5169159cc8793392ab766162fb Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Wed, 6 Jan 2021 11:58:49 +0800 Subject: [PATCH 22/23] Check format --- src/neo/Network/P2P/Payloads/ExtensiblePayload.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs index 9feb83fe05..d7a0902e42 100644 --- a/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -57,7 +57,6 @@ void ISerializable.Deserialize(BinaryReader reader) ((IVerifiable)this).DeserializeUnsigned(reader); if (reader.ReadByte() != 1) throw new FormatException(); Witness = reader.ReadSerializable(); - if (Witness.ScriptHash != Sender) throw new FormatException(); } void IVerifiable.DeserializeUnsigned(BinaryReader reader) @@ -65,6 +64,7 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader) Category = reader.ReadVarString(32); ValidBlockStart = reader.ReadUInt32(); ValidBlockEnd = reader.ReadUInt32(); + if (ValidBlockStart > ValidBlockEnd) throw new FormatException(); Sender = reader.ReadSerializable(); Data = reader.ReadVarBytes(ushort.MaxValue); } From b6f505e2b1dfd8d20a0c999d021d2af0cdf00c7a Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Wed, 6 Jan 2021 12:01:45 +0800 Subject: [PATCH 23/23] Fix UT --- .../Network/P2P/Payloads/UT_ExtensiblePayload.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index d4259e0ac8..0fd01642b1 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -28,10 +28,10 @@ public void DeserializeAndSerialize() { var test = new ExtensiblePayload() { - Sender = Array.Empty().ToScriptHash(), Category = "123", - ValidBlockEnd = 456, - ValidBlockStart = 789, + ValidBlockStart = 456, + ValidBlockEnd = 789, + Sender = Array.Empty().ToScriptHash(), Data = new byte[] { 1, 2, 3 }, Witness = new Witness() { InvocationScript = new byte[] { 3, 5, 6 }, VerificationScript = Array.Empty() } }; @@ -42,12 +42,6 @@ public void DeserializeAndSerialize() Assert.AreEqual(test.ValidBlockStart, clone.ValidBlockStart); Assert.AreEqual(test.ValidBlockEnd, clone.ValidBlockEnd); Assert.AreEqual(test.Category, clone.Category); - - // Check error - - test.Sender = UInt160.Zero; - - Assert.ThrowsException(() => test.ToArray().AsSerializable()); } } }