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

VersionPayload optimization #755

Merged
merged 60 commits into from
May 17, 2019
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
f884a17
Udp support
shargon May 10, 2019
b8b814e
Fix unbind
shargon May 10, 2019
f7a4958
typo
shargon May 10, 2019
c5de11a
Merge branch 'master' into udp-server
vncoelho May 10, 2019
0170488
Unify GetPeers
shargon May 10, 2019
d59271a
Merge remote-tracking branch 'shargon/udp-server' into udp-server
shargon May 10, 2019
1192b3f
Clean Peer
shargon May 10, 2019
e284c37
Fix clean
shargon May 10, 2019
fe42fcd
Refactor VersionPayload
shargon May 10, 2019
5904954
Merge branch 'master' into udp-server
shargon May 10, 2019
b466f9d
Fix
shargon May 10, 2019
a1972c4
Merge remote-tracking branch 'shargon/udp-server' into udp-server
shargon May 10, 2019
3a54118
Unit test
shargon May 10, 2019
54a3087
Clean code
shargon May 10, 2019
2c4fc41
Clean line
shargon May 10, 2019
ee2c9f0
Fix ut
shargon May 10, 2019
77a0b1c
Simplify VersionPayload capabilities
shargon May 10, 2019
2215a55
Refactor VersionPayload capabilities
shargon May 11, 2019
ace3153
rename NodeConfig to ChannelsStartConfig
shargon May 11, 2019
72b82cf
Clean code
shargon May 11, 2019
2e8d558
Clean code
shargon May 11, 2019
be1b889
UPnP for Udp port
shargon May 11, 2019
765d6cf
Merge remote-tracking branch 'shargon/udp-server' into udp-server
shargon May 11, 2019
9485a03
Fx for ListennerTcpPort
shargon May 11, 2019
6d80ec1
Combine NodeCapabilities with ChannelType
shargon May 12, 2019
d0c1d7a
Merge branch 'master' into udp-server
erikzhang May 12, 2019
56d8d64
Summarize ServerCapability and remove reflection
shargon May 12, 2019
f238e46
Move Capabilities
shargon May 12, 2019
e9c9097
OnStart with ChannelsStartConfig
shargon May 12, 2019
c9447b6
Remove EndPointConfig
shargon May 12, 2019
1a86ae7
Move udp logic to ProtocolHandler
shargon May 12, 2019
766f589
Rename
shargon May 12, 2019
fd12eaf
Merge branch 'master' into udp-server
shargon May 12, 2019
c53f574
Remove Services and StartHeight from VersionPayload
shargon May 12, 2019
bb76f79
Merge remote-tracking branch 'shargon/udp-server' into udp-server
shargon May 12, 2019
f8ebcc0
Merge branch 'master' into udp-server
shargon May 13, 2019
fee3f86
Remove AcceptRelay
shargon May 13, 2019
311cd31
Clean code
shargon May 13, 2019
b55d75e
Parse message in LocalNode
shargon May 14, 2019
c8fc819
Merge branch 'master' into udp-server
shargon May 14, 2019
279babe
Merge branch 'master' into udp-server
shargon May 14, 2019
35489a8
Merge branch 'master' into udp-server
shargon May 16, 2019
32db242
Merge branch 'master' into udp-server
shargon May 16, 2019
64f6c4e
Prevent PeekChar
shargon May 16, 2019
10694fe
Fix Serialize
shargon May 16, 2019
957d52e
Merge branch 'master' into udp-server
shargon May 16, 2019
d8eaf7d
Clean code
shargon May 16, 2019
6762a8e
Merge remote-tracking branch 'shargon/udp-server' into udp-server
shargon May 16, 2019
485693e
Move `ChannelsStartConfig` into `Neo.Network.P2P`
erikzhang May 17, 2019
c425700
Merge branch 'master' into udp-server
shargon May 17, 2019
68cb16c
Optimize capabilities
erikzhang May 17, 2019
499fb92
Rename
erikzhang May 17, 2019
cefc6ae
Update NodeCapabilityType.cs
shargon May 17, 2019
e0fb9b8
Optimize `RemoteNode`
erikzhang May 17, 2019
373cf31
Remove udp
shargon May 17, 2019
6f97f55
format
erikzhang May 17, 2019
2e214cc
Remove port from `NetworkAddressWithTime`
erikzhang May 17, 2019
5830fc6
Merge branch 'master' into remove-udp
shargon May 17, 2019
cd75d0d
rename
erikzhang May 17, 2019
0b5521e
Merge branch 'master' into remove-udp
erikzhang May 17, 2019
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
21 changes: 14 additions & 7 deletions neo.UnitTests/UT_P2PMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Network.P2P;
using Neo.Network.P2P.Capabilities;
using Neo.Network.P2P.Payloads;

namespace Neo.UnitTests
Expand Down Expand Up @@ -81,12 +82,15 @@ public void Compression()
{
UserAgent = "".PadLeft(1024, '0'),
Nonce = 1,
Port = 2,
Services = VersionServices.FullNode,
StartHeight = 4,
Magic = 2,
Timestamp = 5,
Version = 6
Version = 6,
Capabilities = new NodeCapability[]
{
new ServerCapability(NodeCapabilityType.TcpServer, 25)
}
};

var msg = Message.Create(MessageCommand.Version, payload);
var buffer = msg.ToArray();

Expand All @@ -100,11 +104,14 @@ public void Compression()

payloadCopy.UserAgent.Should().Be(payload.UserAgent);
payloadCopy.Nonce.Should().Be(payload.Nonce);
payloadCopy.Port.Should().Be(payload.Port);
payloadCopy.Services.Should().Be(payload.Services);
payloadCopy.StartHeight.Should().Be(payload.StartHeight);
payloadCopy.Magic.Should().Be(payload.Magic);
payloadCopy.Timestamp.Should().Be(payload.Timestamp);
payloadCopy.Version.Should().Be(payload.Version);

payloadCopy.Capabilities.Length.Should().Be(1);
((ServerCapability)payloadCopy.Capabilities[0]).Type.Should().Be(NodeCapabilityType.TcpServer);
((ServerCapability)payloadCopy.Capabilities[0]).Port.Should().Be(25);

}
}
}
15 changes: 4 additions & 11 deletions neo/NeoSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class NeoSystem : IDisposable
public RpcServer RpcServer { get; private set; }

private readonly Store store;
private Peer.Start start_message = null;
private ChannelsStartConfig start_message = null;
private bool suspend = false;

public NeoSystem(Store store)
Expand Down Expand Up @@ -73,17 +73,10 @@ public void StartConsensus(Wallet wallet, Store consensus_store = null, bool ign
Consensus.Tell(new ConsensusService.Start { IgnoreRecoveryLogs = ignoreRecoveryLogs }, Blockchain);
}

public void StartNode(int port = 0, int wsPort = 0, int minDesiredConnections = Peer.DefaultMinDesiredConnections,
int maxConnections = Peer.DefaultMaxConnections, int maxConnectionsPerAddress = 3)
public void StartNode(ChannelsStartConfig config)
{
start_message = new Peer.Start
{
Port = port,
WsPort = wsPort,
MinDesiredConnections = minDesiredConnections,
MaxConnections = maxConnections,
MaxConnectionsPerAddress = maxConnectionsPerAddress
};
start_message = config;

if (!suspend)
{
LocalNode.Tell(start_message);
Expand Down
32 changes: 32 additions & 0 deletions neo/Network/P2P/Capabilities/FullNodeCapability.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.IO;

namespace Neo.Network.P2P.Capabilities
{
public class FullNodeCapability : NodeCapability
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This full node capability only with start height is quite strange.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FullNodeCapability means the node has full blockchain data and accept relay.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are a relay node, why you should provide a 0 or this information?

{
public uint StartHeight;

public override int Size =>
base.Size + // Type
sizeof(uint); // Start Height

/// <summary>
/// Constructor
/// </summary>
/// <param name="startHeight">Start Height</param>
public FullNodeCapability(uint startHeight = 0) : base(NodeCapabilityType.FullNode)
{
StartHeight = startHeight;
}

protected override void DeserializeWithoutType(BinaryReader reader)
{
StartHeight = reader.ReadUInt32();
}

protected override void SerializeWithoutType(BinaryWriter writer)
{
writer.Write(StartHeight);
}
}
}
65 changes: 65 additions & 0 deletions neo/Network/P2P/Capabilities/NodeCapability.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Neo.IO;
using System;
using System.IO;

namespace Neo.Network.P2P.Capabilities
{
public abstract class NodeCapability : ISerializable
{
/// <summary>
/// Type
/// </summary>
public readonly NodeCapabilityType Type;

public virtual int Size => sizeof(NodeCapabilityType); // Type

/// <summary>
/// Constructor
/// </summary>
/// <param name="type">Type</param>
protected NodeCapability(NodeCapabilityType type)
{
this.Type = type;
}

void ISerializable.Deserialize(BinaryReader reader)
{
if (reader.ReadByte() != (byte)Type)
{
throw new FormatException();
}

DeserializeWithoutType(reader);
}

public static NodeCapability DeserializeFrom(BinaryReader reader)
{
NodeCapability capability;
NodeCapabilityType type = (NodeCapabilityType)reader.ReadByte();
switch (type)
{
case NodeCapabilityType.TcpServer:
case NodeCapabilityType.WsServer:
capability = new ServerCapability(type);
break;
case NodeCapabilityType.FullNode:
capability = new FullNodeCapability();
break;
default:
throw new FormatException();
}
capability.DeserializeWithoutType(reader);
return capability;
}

protected abstract void DeserializeWithoutType(BinaryReader reader);

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write((byte)Type);
SerializeWithoutType(writer);
}

protected abstract void SerializeWithoutType(BinaryWriter writer);
}
}
12 changes: 12 additions & 0 deletions neo/Network/P2P/Capabilities/NodeCapabilityType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Neo.Network.P2P.Capabilities
{
public enum NodeCapabilityType : byte
{
//Servers
TcpServer = 0x01,
WsServer = 0x02,

//Others
FullNode = 0x10
}
}
39 changes: 39 additions & 0 deletions neo/Network/P2P/Capabilities/ServerCapability.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.IO;

namespace Neo.Network.P2P.Capabilities
{
public class ServerCapability : NodeCapability
{
public ushort Port;

public override int Size =>
base.Size + // Type
sizeof(ushort); // Port

/// <summary>
/// Constructor
/// </summary>
/// <param name="type">Channel</param>
/// <param name="port">Port</param>
public ServerCapability(NodeCapabilityType type, ushort port = 0) : base(type)
{
if (type != NodeCapabilityType.TcpServer && type != NodeCapabilityType.WsServer)
{
throw new ArgumentException(nameof(type));
}

Port = port;
}

protected override void DeserializeWithoutType(BinaryReader reader)
{
Port = reader.ReadUInt16();
}

protected override void SerializeWithoutType(BinaryWriter writer)
{
writer.Write(Port);
}
}
}
32 changes: 32 additions & 0 deletions neo/Network/P2P/ChannelsStartConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Net;

namespace Neo.Network.P2P
{
public class ChannelsStartConfig
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Tcp configuration
/// </summary>
public IPEndPoint Tcp { get; set; }

/// <summary>
/// Web socket configuration
/// </summary>
public IPEndPoint WebSocket { get; set; }

/// <summary>
/// Minimum desired connections
/// </summary>
public int MinDesiredConnections { get; set; } = Peer.DefaultMinDesiredConnections;

/// <summary>
/// Max allowed connections
/// </summary>
public int MaxConnections { get; set; } = Peer.DefaultMaxConnections;

/// <summary>
/// Max allowed connections per address
/// </summary>
public int MaxConnectionsPerAddress { get; set; } = 3;
}
}
1 change: 0 additions & 1 deletion neo/Network/P2P/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public abstract class Connection : UntypedActor

public IPEndPoint Remote { get; }
public IPEndPoint Local { get; }
public abstract int ListenerPort { get; }

private ICancelable timer;
private readonly IActorRef tcp;
Expand Down
2 changes: 1 addition & 1 deletion neo/Network/P2P/LocalNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal class SendDirectly { public IInventory Inventory; }
public static readonly uint Nonce;
public static string UserAgent { get; set; }

private static LocalNode singleton { get; set; }
private static LocalNode singleton;
public static LocalNode Singleton
{
get
Expand Down
33 changes: 18 additions & 15 deletions neo/Network/P2P/Payloads/NetworkAddressWithTime.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Neo.IO;
using Neo.Network.P2P.Capabilities;
using System;
using System.IO;
using System.Linq;
Expand All @@ -9,40 +10,42 @@ namespace Neo.Network.P2P.Payloads
public class NetworkAddressWithTime : ISerializable
{
public uint Timestamp;
public VersionServices Services;
public IPEndPoint EndPoint;
public IPAddress Address;
public NodeCapability[] Capabilities;

public int Size => sizeof(uint) + sizeof(ulong) + 16 + sizeof(ushort);
public IPEndPoint EndPoint => new IPEndPoint(Address, Capabilities.Where(p => p.Type == NodeCapabilityType.TcpServer).Select(p => (ServerCapability)p).FirstOrDefault()?.Port ?? 0);
public int Size => sizeof(uint) + 16 + Capabilities.GetVarSize();

public static NetworkAddressWithTime Create(IPEndPoint endpoint, VersionServices services, uint timestamp)
public static NetworkAddressWithTime Create(IPAddress address, uint timestamp, params NodeCapability[] capabilities)
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
return new NetworkAddressWithTime
{
Timestamp = timestamp,
Services = services,
EndPoint = endpoint
Address = address,
Capabilities = capabilities
};
}

void ISerializable.Deserialize(BinaryReader reader)
{
Timestamp = reader.ReadUInt32();
Services = (VersionServices)reader.ReadUInt64();

// Address
byte[] data = reader.ReadBytes(16);
if (data.Length != 16) throw new FormatException();
IPAddress address = new IPAddress(data).Unmap();
data = reader.ReadBytes(2);
if (data.Length != 2) throw new FormatException();
ushort port = data.Reverse().ToArray().ToUInt16(0);
EndPoint = new IPEndPoint(address, port);
Address = new IPAddress(data).Unmap();

// Capabilities
Capabilities = new NodeCapability[reader.ReadVarInt(VersionPayload.MaxCapabilities)];
for (int x = 0, max = Capabilities.Length; x < max; x++)
Capabilities[x] = NodeCapability.DeserializeFrom(reader);
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write(Timestamp);
writer.Write((ulong)Services);
writer.Write(EndPoint.Address.MapToIPv6().GetAddressBytes());
writer.Write(BitConverter.GetBytes((ushort)EndPoint.Port).Reverse().ToArray());
writer.Write(Address.MapToIPv6().GetAddressBytes());
writer.Write(Capabilities);
}
}
}
Loading