diff --git a/plugins/RpcServer/RpcServer.Node.cs b/plugins/RpcServer/RpcServer.Node.cs
index 20f105d34..0d5bb7702 100644
--- a/plugins/RpcServer/RpcServer.Node.cs
+++ b/plugins/RpcServer/RpcServer.Node.cs
@@ -123,7 +123,7 @@ private static JObject GetRelayResult(VerifyResult reason, UInt256 hash)
/// "result": {
/// "tcpport": 10333, // The TCP port,
/// "nonce": 1, // The nonce,
- /// "useragent": "The user agent",
+ /// "useragent": "/Neo:3.10.2/", // Node assembly version in the existing useragent field,
/// "rpc": {
/// "maxiteratorresultitems": 100, // The maximum number of items in the iterator result,
/// "sessionenabled": false // Whether session is enabled,
@@ -152,7 +152,8 @@ protected internal virtual JToken GetVersion()
JObject json = new();
json["tcpport"] = localNode.ListenerTcpPort;
json["nonce"] = LocalNode.Nonce;
- json["useragent"] = LocalNode.UserAgent;
+ var nodeVersion = typeof(RpcServer).Assembly.GetName().Version?.ToString(3) ?? "0.0.0";
+ json["useragent"] = UserAgentWithVersion(LocalNode.UserAgent, nodeVersion);
// rpc settings
JObject rpc = new();
rpc["maxiteratorresultitems"] = settings.MaxIteratorResultItems;
@@ -183,6 +184,19 @@ protected internal virtual JToken GetVersion()
return json;
}
+ ///
+ /// Keeps the P2P useragent product name and replaces the version with .
+ /// /Neo:3.10.1/ plus 3.10.2 becomes /Neo:3.10.2/.
+ ///
+ internal static string UserAgentWithVersion(string userAgent, string version)
+ {
+ var colon = userAgent.IndexOf(':');
+ var slash = userAgent.LastIndexOf('/');
+ if (colon >= 0 && slash > colon)
+ return string.Concat(userAgent.AsSpan(0, colon + 1), version, userAgent.AsSpan(slash));
+ return $"/Neo:{version}/";
+ }
+
///
/// Removes a specified prefix from a string if it exists.
///
diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
index 8ba40aa09..961650f74 100644
--- a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
+++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
@@ -117,6 +117,17 @@ public void TestGetVersion()
Assert.IsTrue(json.ContainsProperty("tcpport"));
Assert.IsTrue(json.ContainsProperty("nonce"));
Assert.IsTrue(json.ContainsProperty("useragent"));
+ Assert.IsFalse(json.ContainsProperty("version"));
+ var nodeVersion = _rpcServer.GetType().Assembly.GetName().Version?.ToString(3) ?? "0.0.0";
+ Assert.AreEqual(RpcServer.UserAgentWithVersion(LocalNode.UserAgent, nodeVersion), json["useragent"]!.AsString());
+ Assert.Contains($":{nodeVersion}/", json["useragent"]!.AsString());
+
+ Assert.IsTrue(json.ContainsProperty("rpc"));
+ var rpc = (JObject)json["rpc"]!;
+ Assert.IsTrue(rpc.ContainsProperty("maxiteratorresultitems"));
+ Assert.IsTrue(rpc.ContainsProperty("sessionenabled"));
+ Assert.AreEqual(_rpcServerSettings.MaxIteratorResultItems, rpc["maxiteratorresultitems"]!.AsNumber());
+ Assert.AreEqual(_rpcServerSettings.SessionEnabled, rpc["sessionenabled"]!.AsBoolean());
Assert.IsTrue(json.ContainsProperty("protocol"));
var protocol = (JObject)json["protocol"];
@@ -132,6 +143,15 @@ public void TestGetVersion()
Assert.IsTrue(protocol.ContainsProperty("seedlist"));
}
+ [TestMethod]
+ public void TestUserAgentWithVersion_ReplacesVersionKeepsProduct()
+ {
+ Assert.AreEqual("/Neo:3.10.2/", RpcServer.UserAgentWithVersion("/Neo:3.10.1/", "3.10.2"));
+ Assert.AreEqual("/MyNode:3.10.2/", RpcServer.UserAgentWithVersion("/MyNode:1.0.0/", "3.10.2"));
+ Assert.AreEqual("/Neo:3.10.2/", RpcServer.UserAgentWithVersion("not-a-ua", "3.10.2"));
+ Assert.AreEqual("/Neo:3.10.2/", RpcServer.UserAgentWithVersion(string.Empty, "3.10.2"));
+ }
+
[TestMethod]
public void TestGetVersion_HardforksStructure()
{