Skip to content

Commit

Permalink
P2P: fix UnknownCapabilityvalidation and maintainig (neo-project#3647)
Browse files Browse the repository at this point in the history
* P2P: allow to serialize UnknownCapability

Otherwise it can't be properly passed through the P2P network which makes
it impossible to use UnknownCapabilities as an extensions in the existing
networks.

Follow nspcc-dev/neo-go#3778.

Signed-off-by: Anna Shaleva <[email protected]>

* P2P: fix verification rules for NetworkAddressWithTime

Without this commit every `Addr` message containing UnknownCapability
will be considered as invalid. The desired behaviour is to include node
with UnknownCapability into the list of peers.

Follow the nspcc-dev/neo-go#3778, should be a
part of neo-project#3639.

Signed-off-by: Anna Shaleva <[email protected]>

* P2P: don't strip UnknownCapabilities from node's version

Make the behaviour compatible with
nspcc-dev/neo-go#3778.

Signed-off-by: Anna Shaleva <[email protected]>

---------

Signed-off-by: Anna Shaleva <[email protected]>
  • Loading branch information
AnnaShaleva authored Dec 29, 2024
1 parent f65c193 commit d55f0a1
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 8 deletions.
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())
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())
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());
}
}
}

0 comments on commit d55f0a1

Please sign in to comment.