Skip to content

Commit 76adc0f

Browse files
committed
Expose node ports in API
1 parent 2689105 commit 76adc0f

File tree

6 files changed

+119
-11
lines changed

6 files changed

+119
-11
lines changed

Phantasma.API/NexusAPI.cs

+17-3
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ public class NexusAPI
404404
public ITokenSwapper TokenSwapper;
405405
public Mempool Mempool;
406406
public Node Node;
407+
407408
public IEnumerable<APIEntry> Methods => _methods.Values;
408409

409410
private readonly Dictionary<string, APIEntry> _methods = new Dictionary<string, APIEntry>(StringComparer.InvariantCultureIgnoreCase);
@@ -2126,9 +2127,22 @@ public IAPIResult GetPeers()
21262127
allPeers = allPeers.Where(x => !x.Endpoint.Host.Contains("localhost"));
21272128
}
21282129

2129-
var peers = allPeers.Select(x => new PeerResult() { url = x.Endpoint.ToString(), version = x.Version, flags = x.Capabilities.ToString(), fee = x.MinimumFee.ToString(), pow = (uint)x.MinimumPoW }).ToList();
2130-
2131-
peers.Add(new PeerResult() { url = $"{Node.PublicEndpoint}", version = Node.Version, flags = Node.Capabilities.ToString(), fee = Node.MinimumFee.ToString(), pow = (uint)Node.MinimumPoW });
2130+
var peers = allPeers.Select(x => new PeerResult() {
2131+
url = x.Endpoint.ToString(),
2132+
version = x.Version,
2133+
flags = x.Capabilities.ToString(),
2134+
fee = x.MinimumFee.ToString(),
2135+
pow = (uint)x.MinimumPoW,
2136+
ports = x.Ports.Select(y => new PortResult() { name = y.Name, port = y.Port}).ToArray()
2137+
}) .ToList();
2138+
2139+
peers.Add(new PeerResult() {
2140+
url = $"{Node.PublicEndpoint}",
2141+
version = Node.Version,
2142+
flags = Node.Capabilities.ToString(),
2143+
fee = Node.MinimumFee.ToString(),
2144+
pow = (uint)Node.MinimumPoW,
2145+
ports = this.Node.AvailablePorts.Select(y => new PortResult() { name = y.Name, port = y.Port }).ToArray() });
21322146

21332147
peers.Shuffle();
21342148

Phantasma.API/Structs.cs

+12
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,15 @@ public struct ReceiptResult : IAPIResult
592592
public string script;
593593
}
594594

595+
public struct PortResult: IAPIResult
596+
{
597+
[APIDescription("Port description")]
598+
public string name;
599+
600+
[APIDescription("Port number")]
601+
public int port;
602+
}
603+
595604
public struct PeerResult: IAPIResult
596605
{
597606
[APIDescription("URL of peer")]
@@ -608,6 +617,9 @@ public struct PeerResult: IAPIResult
608617

609618
[APIDescription("Minimum proof of work required by node")]
610619
public uint pow;
620+
621+
[APIDescription("List of exposed ports")]
622+
public PortResult[] ports;
611623
}
612624

613625
public struct ValidatorResult : IAPIResult

Phantasma.P2P/Messages/ListMessage.cs

+55
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ public static ChainInfo Unserialize(BinaryReader reader)
3939
}
4040
}
4141

42+
public class PeerInfo
43+
{
44+
public string version;
45+
public PeerCaps caps;
46+
public BigInteger minimumFee;
47+
public uint minimumPow;
48+
public PeerPort[] ports;
49+
}
50+
4251
public struct BlockRange
4352
{
4453
public readonly Block[] blocks;
@@ -64,6 +73,8 @@ public class ListMessage : Message
6473
private ChainInfo[] _chains = null;
6574
public IEnumerable<ChainInfo> Chains => _chains;
6675

76+
public PeerInfo _peerInfo = null;
77+
6778
public const int MaxPeers = 255;
6879
public const int MaxChains = 128;
6980
public const int MaxTransactions = 1024; // for mempool
@@ -169,6 +180,22 @@ internal static ListMessage FromReader(Address address, string host, BinaryReade
169180
}
170181
}
171182

183+
if (kind.HasFlag(RequestKind.Info))
184+
{
185+
var version = reader.ReadVarString();
186+
var caps = (PeerCaps)reader.ReadInt32();
187+
var minimumFee = reader.ReadBigInteger();
188+
var minimumPow = (int)reader.ReadVarInt();
189+
var portCount = (int)reader.ReadVarInt();
190+
var ports = new PeerPort[portCount];
191+
for (int i=0; i<portCount; i++)
192+
{
193+
var portName = reader.ReadVarString();
194+
var portNumber = (int)reader.ReadVarInt();
195+
ports[i] = new PeerPort(portName, portNumber);
196+
}
197+
}
198+
172199
return result;
173200
}
174201

@@ -233,6 +260,20 @@ protected override void OnSerialize(BinaryWriter writer)
233260
}
234261
}
235262
}
263+
264+
if (Kind.HasFlag(RequestKind.Info))
265+
{
266+
writer.WriteVarString(_peerInfo.version);
267+
writer.Write((int)_peerInfo.caps);
268+
writer.WriteBigInteger(_peerInfo.minimumFee);
269+
writer.WriteVarInt(_peerInfo.minimumPow);
270+
writer.WriteVarInt(_peerInfo.ports.Length);
271+
foreach (var entry in _peerInfo.ports)
272+
{
273+
writer.WriteVarString(entry.Name);
274+
writer.WriteVarInt(entry.Port);
275+
}
276+
}
236277
}
237278

238279
public override IEnumerable<string> GetDescription()
@@ -312,5 +353,19 @@ public void AddBlockRange(Chain chain, BigInteger startHeight, uint count)
312353

313354
AddBlockRange(chain.Name, blocks.ToArray(), transactions);
314355
}
356+
357+
public void SetInfo(string version, PeerCaps caps, BigInteger minimumFee, uint minimumPow, IEnumerable<PeerPort> ports)
358+
{
359+
var info = new PeerInfo()
360+
{
361+
version = version,
362+
caps = caps,
363+
minimumFee = minimumFee,
364+
minimumPow = minimumPow,
365+
ports = ports.ToArray()
366+
};
367+
368+
this._peerInfo = info;
369+
}
315370
}
316371
}

Phantasma.P2P/Messages/RequestMessage.cs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public enum RequestKind
1717
Mempool = 0x4,
1818
Blocks = 0x8,
1919
Transactions = 0x16,
20+
Info = 0x32,
2021
}
2122

2223
public struct RequestRange

Phantasma.P2P/Node.cs

+19-8
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public sealed partial class Node : Runnable
7878

7979
public readonly string Version;
8080

81-
public readonly int Port;
81+
public readonly int SyncPort;
8282
public readonly string Host;
8383
public readonly string PublicEndpoint;
8484
public readonly PeerCaps Capabilities;
@@ -113,11 +113,13 @@ public sealed partial class Node : Runnable
113113

114114
private DateTime _lastRequestTime = DateTime.UtcNow;
115115

116+
public readonly PeerPort[] AvailablePorts;
117+
116118
public bool IsFullySynced { get; private set; }
117119

118120
public string ProxyURL = null;
119121

120-
public Node(string version, Nexus nexus, Mempool mempool, PhantasmaKeys keys, string publicHost, int port, PeerCaps caps, IEnumerable<string> seeds, Logger log)
122+
public Node(string version, Nexus nexus, Mempool mempool, PhantasmaKeys keys, string publicHost, IEnumerable<PeerPort> availablePorts, PeerCaps caps, IEnumerable<string> seeds, Logger log)
121123
{
122124
if (mempool != null)
123125
{
@@ -129,11 +131,15 @@ public Node(string version, Nexus nexus, Mempool mempool, PhantasmaKeys keys, st
129131
Throw.If(caps.HasFlag(PeerCaps.Mempool), "mempool included in caps but mempool instance is null");
130132
}
131133

134+
var syncPort = availablePorts.FirstOrDefault(x => x.Name.Equals("sync", StringComparison.OrdinalIgnoreCase)).Port;
135+
Throw.If(syncPort <= 0, "missing sync port");
136+
132137
this.Logger = Logger.Init(log);
133138

134139
this.Version = version;
135140
this.Nexus = nexus;
136-
this.Port = port;
141+
this.SyncPort = syncPort;
142+
this.AvailablePorts = availablePorts.ToArray();
137143
this.Keys = keys;
138144
this.Capabilities = caps;
139145

@@ -157,7 +163,7 @@ public Node(string version, Nexus nexus, Mempool mempool, PhantasmaKeys keys, st
157163
Throw.If(publicHost.Contains(":"), "invalid host, protocol or port number should not be included");
158164
this.Host = publicHost;
159165

160-
this.PublicEndpoint = $"tcp:{publicHost}:{port}";
166+
this.PublicEndpoint = $"tcp:{publicHost}:{syncPort}";
161167

162168
if (this.Capabilities.HasFlag(PeerCaps.Sync))
163169
{
@@ -166,7 +172,7 @@ public Node(string version, Nexus nexus, Mempool mempool, PhantasmaKeys keys, st
166172
// TODO this is a security issue, later change this to be configurable and default to localhost
167173
var bindAddress = IPAddress.Any;
168174

169-
listener = new TcpListener(bindAddress, port);
175+
listener = new TcpListener(bindAddress, syncPort);
170176

171177
if (seeds.Any())
172178
{
@@ -220,7 +226,7 @@ public bool ParseEndpoint(string src, out PeerProtocol protocol, out IPAddress i
220226
}
221227
else
222228
{
223-
port = this.Port;
229+
port = this.SyncPort;
224230
}
225231

226232
if (!IPAddress.TryParse(src, out ipAddress))
@@ -326,7 +332,7 @@ protected override void OnStart()
326332
{
327333
if (this.Capabilities.HasFlag(PeerCaps.Sync))
328334
{
329-
Logger.Message($"Phantasma node listening on port {Port}, using address: {Address}");
335+
Logger.Message($"Phantasma node listening on port {SyncPort}, using address: {Address}");
330336

331337
listener.Start();
332338
}
@@ -465,7 +471,7 @@ private void HandleConnection(Socket socket)
465471
var peer = new TCPPeer(socket);
466472

467473
// this initial message is not only used to fetch chains but also to verify identity of peers
468-
var requestKind = RequestKind.Chains | RequestKind.Peers;
474+
var requestKind = RequestKind.Chains | RequestKind.Peers | RequestKind.Info;
469475
if (Capabilities.HasFlag(PeerCaps.Mempool))
470476
{
471477
requestKind |= RequestKind.Mempool;
@@ -688,6 +694,11 @@ private Message HandleMessage(Peer peer, Message msg)
688694
answer.SetPeers(this.Peers.Where(x => x != peer).Select(x => x.Endpoint.ToString()));
689695
}
690696

697+
if (request.Kind.HasFlag(RequestKind.Info))
698+
{
699+
answer.SetInfo(this.Version, this.Capabilities, this.MinimumFee, this.MinimumPoW, this.AvailablePorts);
700+
}
701+
691702
if (request.Kind.HasFlag(RequestKind.Chains))
692703
{
693704
var chainList = Nexus.GetChains(Nexus.RootStorage);

Phantasma.P2P/Peer.cs

+15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Phantasma.Domain;
44
using Phantasma.Numerics;
55
using System;
6+
using System.Collections.Generic;
67

78
namespace Phantasma.Network.P2P
89
{
@@ -20,6 +21,18 @@ public enum PeerCaps
2021
REST = 0x40,
2122
}
2223

24+
public struct PeerPort
25+
{
26+
public readonly string Name;
27+
public readonly int Port;
28+
29+
public PeerPort(string name, int port)
30+
{
31+
Name = name;
32+
Port = port;
33+
}
34+
}
35+
2336
public abstract class Peer
2437
{
2538
public Address Address { get; private set; }
@@ -33,6 +46,8 @@ public abstract class Peer
3346
public BigInteger MinimumFee { get; set; }
3447
public int MinimumPoW { get; set; }
3548

49+
public List<PeerPort> Ports { get; set; }
50+
3651
public abstract void Send(Message msg);
3752
public abstract Message Receive();
3853

0 commit comments

Comments
 (0)