Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2P: fix UnknownCapabilityvalidation and maintainig #3647

Merged
merged 3 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Neo/Network/P2P/Capabilities/UnknownCapability.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ protected override void DeserializeWithoutType(ref MemoryReader reader)

protected override void SerializeWithoutType(BinaryWriter writer)
{
throw new InvalidOperationException("Unknown capability can't be serialized");
writer.WriteVarBytes(Data.Span);
}
}
}
5 changes: 4 additions & 1 deletion src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ void ISerializable.Deserialize(ref MemoryReader reader)
Capabilities = new NodeCapability[reader.ReadVarInt(VersionPayload.MaxCapabilities)];
for (int x = 0, max = Capabilities.Length; x < max; x++)
Capabilities[x] = NodeCapability.DeserializeFrom(ref reader);
if (Capabilities.Select(p => p.Type).Distinct().Count() != Capabilities.Length)
// Verify that no duplicating capabilities are included. Unknown capabilities are not
// taken into account but still preserved to be able to share through the network.
var capabilities = Capabilities.Where(c => c is not UnknownCapability);
if (capabilities.Select(p => p.Type).Distinct().Count() != capabilities.Count())
roman-khimov marked this conversation as resolved.
Show resolved Hide resolved
cschuchardt88 marked this conversation as resolved.
Show resolved Hide resolved
throw new FormatException();
}

Expand Down
4 changes: 2 additions & 2 deletions src/Neo/Network/P2P/Payloads/VersionPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ void ISerializable.Deserialize(ref MemoryReader reader)
Capabilities = new NodeCapability[reader.ReadVarInt(MaxCapabilities)];
for (int x = 0, max = Capabilities.Length; x < max; x++)
Capabilities[x] = NodeCapability.DeserializeFrom(ref reader);
Capabilities = Capabilities.Where(c => c is not UnknownCapability).ToArray();
if (Capabilities.Select(p => p.Type).Distinct().Count() != Capabilities.Length)
var capabilities = Capabilities.Where(c => c is not UnknownCapability);
if (capabilities.Select(p => p.Type).Distinct().Count() != capabilities.Count())
cschuchardt88 marked this conversation as resolved.
Show resolved Hide resolved
throw new FormatException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void DeserializeUnknown()
var capab = (NodeCapability)NodeCapability.DeserializeFrom(ref br);

Assert.IsTrue(capab is UnknownCapability);
Assert.ThrowsException<InvalidOperationException>(() => capab.ToArray());
CollectionAssert.AreEqual(buffer, capab.ToArray());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// modifications are permitted.

using FluentAssertions;
using FluentAssertions.Equivalency;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Extensions;
using Neo.IO;
Expand Down Expand Up @@ -40,7 +41,7 @@ public void SizeAndEndPoint_Get()
[TestMethod]
public void DeserializeAndSerialize()
{
var test = NetworkAddressWithTime.Create(IPAddress.Any, 1, new NodeCapability[] { new ServerCapability(NodeCapabilityType.TcpServer, 22) });
var test = NetworkAddressWithTime.Create(IPAddress.Any, 1, new NodeCapability[] { new ServerCapability(NodeCapabilityType.TcpServer, 22), new UnknownCapability(NodeCapabilityType.Extension0), new UnknownCapability(NodeCapabilityType.Extension0) });
var clone = test.ToArray().AsSerializable<NetworkAddressWithTime>();

CollectionAssert.AreEqual(test.Capabilities.ToByteArray(), clone.Capabilities.ToByteArray());
Expand Down
4 changes: 2 additions & 2 deletions tests/Neo.UnitTests/Network/P2P/Payloads/UT_VersionPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ public void DeserializeAndSerialize()
buf = buf.Concat(new byte[] { 0x10, 0x01, 0x00, 0x00, 0x00 }).ToArray(); // FullNode capability, 0x01 index.

clone = buf.AsSerializable<VersionPayload>();
Assert.AreEqual(2, clone.Capabilities.Length);
Assert.AreEqual(0, clone.Capabilities.OfType<UnknownCapability>().Count());
Assert.AreEqual(4, clone.Capabilities.Length);
Assert.AreEqual(2, clone.Capabilities.OfType<UnknownCapability>().Count());
}
}
}
Loading