Skip to content

Commit

Permalink
Fix enode parsing (#4886)
Browse files Browse the repository at this point in the history
* draft

* fix

* refactoring

* cosmetic
  • Loading branch information
marcindsobczak authored Nov 10, 2022
1 parent ec6a176 commit 0934dd2
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 7 deletions.
41 changes: 34 additions & 7 deletions src/Nethermind/Nethermind.Config/Enode.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) 2021 Demerzel Solutions Limited
// This file is part of the Nethermind library.
//
//
// The Nethermind library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// The Nethermind library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
//
// You should have received a copy of the GNU Lesser General Public License
// along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

Expand All @@ -28,11 +28,12 @@ public class Enode : IEnode
{
private readonly PublicKey _nodeKey;

public Enode(PublicKey nodeKey, IPAddress hostIp, int port)
public Enode(PublicKey nodeKey, IPAddress hostIp, int port, int? discoveryPort = null)
{
_nodeKey = nodeKey;
HostIp = hostIp;
Port = port;
DiscoveryPort = discoveryPort ?? port;
}

public Enode(string enodeString)
Expand All @@ -47,12 +48,35 @@ ArgumentException GetPortException(string hostName) =>
string[] enodeParts2 = enodeParts[1].Split('@');
_nodeKey = new PublicKey(enodeParts2[0].TrimStart('/'));
string host = enodeParts2[1];
if (enodeParts.Length <= 2 || !int.TryParse(enodeParts[2], out int port))

if (enodeParts.Length != 3)
{
throw GetPortException(host);
}

string[] portParts = enodeParts[2].Split("?discport=");

switch (portParts.Length)
{
case 1:
if (int.TryParse(portParts[0], out int port))
{
Port = port;
DiscoveryPort = port;
}
else throw GetPortException(host);
break;
case 2:
if (int.TryParse(portParts[0], out int listeningPort) && int.TryParse(portParts[1], out int discoveryPort))
{
Port = listeningPort;
DiscoveryPort = discoveryPort;
}
else throw GetPortException(host);
break;
default:
throw GetPortException(host);
}
Port = port;

try
{
Expand Down Expand Up @@ -84,7 +108,10 @@ ArgumentException GetPortException(string hostName) =>
public Address Address => _nodeKey.Address;
public IPAddress HostIp { get; }
public int Port { get; }
public string Info => $"enode://{_nodeKey.ToString(false)}@{HostIp}:{Port}";
public int DiscoveryPort { get; }
public string Info => DiscoveryPort == Port
? $"enode://{_nodeKey.ToString(false)}@{HostIp}:{Port}"
: $"enode://{_nodeKey.ToString(false)}@{HostIp}:{Port}?discport={DiscoveryPort}";

public override string ToString() => Info;
}
Expand Down
70 changes: 70 additions & 0 deletions src/Nethermind/Nethermind.Network.Test/PeerManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ public async Task Can_start_and_stop()
private const string enode4String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@some.url:434";

private const string enode5String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@52.141.78.53";

private const string enode6String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@52.141.78.53:12345";

private const string enode7String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@52.141.78.53:12345?discport=6789";

private const string enode8String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@52.141.78.53:12345?somethingwrong=6789";

private const string enode9String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@52.141.78.53:12345?discport=6789?discport=67899";

private const string enode10String =
"enode://3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333b@52.141.78.53:12345:discport=6789";

[Test, Retry(10)]
public async Task Will_connect_to_a_candidate_node()
{
Expand Down Expand Up @@ -126,6 +144,58 @@ public void Will_return_exception_in_dns()
});
}

[Test]
public void Will_return_exception_when_there_is_no_port()
{
Assert.Throws<ArgumentException>(delegate
{
Enode unused = new(enode5String);
});
}

[Test]
public void Will_parse_ports_correctly_when_there_are_two_different_ports()
{
Enode enode = new(enode6String);
enode.Port.Should().Be(12345);
enode.DiscoveryPort.Should().Be(12345);
}

[Test]
public void Will_parse_port_correctly_when_there_is_only_one()
{
Enode enode = new(enode7String);
enode.Port.Should().Be(12345);
enode.DiscoveryPort.Should().Be(6789);
}

[Test]
public void Will_return_exception_on_wrong_ports_part()
{
Assert.Throws<ArgumentException>(delegate
{
Enode unused = new(enode8String);
});
}

[Test]
public void Will_return_exception_on_duplicated_discovery_port_part()
{
Assert.Throws<ArgumentException>(delegate
{
Enode unused = new(enode9String);
});
}

[Test]
public void Will_return_exception_on_wrong_form_of_discovery_port_part()
{
Assert.Throws<ArgumentException>(delegate
{
Enode unused = new(enode10String);
});
}

[Test]
public async Task Will_accept_static_connection()
{
Expand Down

0 comments on commit 0934dd2

Please sign in to comment.