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

[Neo Plugin RPC] update rpc node methods signatures to use explicit parameter types. #3479

Merged
merged 5 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 47 additions & 13 deletions src/Plugins/RpcServer/RpcServer.Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,23 @@ namespace Neo.Plugins.RpcServer
{
partial class RpcServer
{
[RpcMethod]
protected internal virtual JToken GetConnectionCount(JArray _params)

/// <summary>
shargon marked this conversation as resolved.
Show resolved Hide resolved
/// Gets the current number of connections to the node.
/// </summary>
/// <returns>The number of connections as a JToken.</returns>
[RpcMethodWithParams]
protected internal virtual JToken GetConnectionCount()
{
return localNode.ConnectedCount;
}

[RpcMethod]
protected internal virtual JToken GetPeers(JArray _params)
/// <summary>
/// Gets information about the peers connected to the node.
/// </summary>
/// <returns>A JObject containing information about unconnected, bad, and connected peers.</returns>
[RpcMethodWithParams]
protected internal virtual JToken GetPeers()
{
JObject json = new();
json["unconnected"] = new JArray(localNode.GetUnconnectedPeers().Select(p =>
Expand All @@ -51,9 +60,14 @@ protected internal virtual JToken GetPeers(JArray _params)
return json;
}

/// <summary>
/// Processes the result of a transaction or block relay and returns appropriate response or throws an exception.
/// </summary>
/// <param name="reason">The verification result of the relay.</param>
/// <param name="hash">The hash of the transaction or block.</param>
/// <returns>A JObject containing the hash if successful, otherwise throws an RpcException.</returns>
private static JObject GetRelayResult(VerifyResult reason, UInt256 hash)
{

switch (reason)
{
case VerifyResult.Succeed:
Expand Down Expand Up @@ -109,8 +123,12 @@ private static JObject GetRelayResult(VerifyResult reason, UInt256 hash)
}
}

[RpcMethod]
protected internal virtual JToken GetVersion(JArray _params)
/// <summary>
/// Gets version information about the node, including network, protocol, and RPC settings.
/// </summary>
/// <returns>A JObject containing detailed version and configuration information.</returns>
[RpcMethodWithParams]
protected internal virtual JToken GetVersion()
{
JObject json = new();
json["tcpport"] = localNode.ListenerTcpPort;
Expand Down Expand Up @@ -146,23 +164,39 @@ protected internal virtual JToken GetVersion(JArray _params)
return json;
}

/// <summary>
/// Removes a specified prefix from a string if it exists.
/// </summary>
/// <param name="s">The input string.</param>
/// <param name="prefix">The prefix to remove.</param>
/// <returns>The string with the prefix removed if it existed, otherwise the original string.</returns>
private static string StripPrefix(string s, string prefix)
{
return s.StartsWith(prefix) ? s.Substring(prefix.Length) : s;
}

[RpcMethod]
protected internal virtual JToken SendRawTransaction(JArray _params)
/// <summary>
/// Sends a raw transaction to the network.
/// </summary>
/// <param name="base64Tx">The base64-encoded transaction.</param>
/// <returns>A JToken containing the result of the transaction relay.</returns>
[RpcMethodWithParams]
protected internal virtual JToken SendRawTransaction(string base64Tx)
{
Transaction tx = Result.Ok_Or(() => Convert.FromBase64String(_params[0].AsString()).AsSerializable<Transaction>(), RpcError.InvalidParams.WithData($"Invalid Transaction Format: {_params[0]}"));
Transaction tx = Result.Ok_Or(() => Convert.FromBase64String(base64Tx).AsSerializable<Transaction>(), RpcError.InvalidParams.WithData($"Invalid Transaction Format: {base64Tx}"));
RelayResult reason = system.Blockchain.Ask<RelayResult>(tx).Result;
return GetRelayResult(reason.Result, tx.Hash);
}

[RpcMethod]
protected internal virtual JToken SubmitBlock(JArray _params)
/// <summary>
/// Submits a new block to the network.
/// </summary>
/// <param name="base64Block">The base64-encoded block.</param>
/// <returns>A JToken containing the result of the block submission.</returns>
[RpcMethodWithParams]
protected internal virtual JToken SubmitBlock(string base64Block)
{
Block block = Result.Ok_Or(() => Convert.FromBase64String(_params[0].AsString()).AsSerializable<Block>(), RpcError.InvalidParams.WithData($"Invalid Block Format: {_params[0]}"));
Block block = Result.Ok_Or(() => Convert.FromBase64String(base64Block).AsSerializable<Block>(), RpcError.InvalidParams.WithData($"Invalid Block Format: {base64Block}"));
RelayResult reason = system.Blockchain.Ask<RelayResult>(block).Result;
return GetRelayResult(reason.Result, block.Hash);
}
Expand Down
44 changes: 22 additions & 22 deletions tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ partial class UT_RpcServer
[TestMethod]
public void TestGetConnectionCount()
{
var result = _rpcServer.GetConnectionCount(new JArray());
var result = _rpcServer.GetConnectionCount();
result.GetType().Should().Be(typeof(JNumber));
}

Expand All @@ -44,7 +44,7 @@ public void TestGetPeers()
localNode.AddPeers(new List<IPEndPoint>() { new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 13332) });
var rpcServer = new RpcServer(neoSystem, RpcServerSettings.Default);

var result = rpcServer.GetPeers(new JArray());
var result = rpcServer.GetPeers();
Assert.IsInstanceOfType(result, typeof(JObject));
var json = (JObject)result;
json.ContainsProperty("unconnected").Should().BeTrue();
Expand All @@ -56,7 +56,7 @@ public void TestGetPeers()
[TestMethod]
public void TestGetVersion()
{
var result = _rpcServer.GetVersion(new JArray());
var result = _rpcServer.GetVersion();
Assert.IsInstanceOfType(result, typeof(JObject));

var json = (JObject)result;
Expand Down Expand Up @@ -87,7 +87,7 @@ public void TestSendRawTransaction_Normal()
var tx = TestUtils.CreateValidTx(snapshot, _wallet, _walletAccount);
var txString = Convert.ToBase64String(tx.ToArray());

var result = _rpcServer.SendRawTransaction(new JArray(txString));
var result = _rpcServer.SendRawTransaction(txString);
Assert.IsInstanceOfType(result, typeof(JObject));
Assert.IsTrue(((JObject)result).ContainsProperty("hash"));
}
Expand All @@ -96,7 +96,7 @@ public void TestSendRawTransaction_Normal()
public void TestSendRawTransaction_InvalidTransactionFormat()
{
Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray("invalid_transaction_string")),
_rpcServer.SendRawTransaction("invalid_transaction_string"),
"Should throw RpcException for invalid transaction format");
}

Expand All @@ -108,7 +108,7 @@ public void TestSendRawTransaction_InsufficientBalance()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for insufficient balance");
Assert.AreEqual(RpcError.InsufficientFunds.Code, exception.HResult);
}
Expand All @@ -121,7 +121,7 @@ public void TestSendRawTransaction_InvalidSignature()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for invalid signature");
Assert.AreEqual(RpcError.InvalidSignature.Code, exception.HResult);
}
Expand All @@ -134,7 +134,7 @@ public void TestSendRawTransaction_InvalidScript()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for invalid script");
Assert.AreEqual(RpcError.InvalidScript.Code, exception.HResult);
}
Expand All @@ -147,7 +147,7 @@ public void TestSendRawTransaction_InvalidAttribute()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for invalid attribute");
// Transaction with invalid attribute can not pass the Transaction deserialization
// and will throw invalid params exception.
Expand All @@ -162,7 +162,7 @@ public void TestSendRawTransaction_Oversized()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for invalid format transaction");
// Oversized transaction will not pass the deserialization.
Assert.AreEqual(RpcError.InvalidParams.Code, exception.HResult);
Expand All @@ -176,7 +176,7 @@ public void TestSendRawTransaction_Expired()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for expired transaction");
Assert.AreEqual(RpcError.ExpiredTransaction.Code, exception.HResult);
}
Expand All @@ -191,7 +191,7 @@ public void TestSendRawTransaction_PolicyFailed()
snapshot.Commit();

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for conflicting transaction");
Assert.AreEqual(RpcError.PolicyFailed.Code, exception.HResult);
}
Expand All @@ -205,7 +205,7 @@ public void TestSendRawTransaction_AlreadyInPool()
var txString = Convert.ToBase64String(tx.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(txString)),
_rpcServer.SendRawTransaction(txString),
"Should throw RpcException for transaction already in memory pool");
Assert.AreEqual(RpcError.AlreadyInPool.Code, exception.HResult);
}
Expand All @@ -218,7 +218,7 @@ public void TestSendRawTransaction_AlreadyInBlockchain()
TestUtils.AddTransactionToBlockchain(snapshot, tx);
snapshot.Commit();
var txString = Convert.ToBase64String(tx.ToArray());
var exception = Assert.ThrowsException<RpcException>(() => _rpcServer.SendRawTransaction(new JArray(txString)));
var exception = Assert.ThrowsException<RpcException>(() => _rpcServer.SendRawTransaction(txString));
Assert.AreEqual(RpcError.AlreadyExists.Code, exception.HResult);
}

Expand All @@ -233,7 +233,7 @@ public void TestSubmitBlock_Normal()
var block = TestUtils.CreateBlockWithValidTransactions(snapshot, _wallet, _walletAccount, 1);
var blockString = Convert.ToBase64String(block.ToArray());

var result = _rpcServer.SubmitBlock(new JArray(blockString));
var result = _rpcServer.SubmitBlock(blockString);
Assert.IsInstanceOfType(result, typeof(JObject));
Assert.IsTrue(((JObject)result).ContainsProperty("hash"));
}
Expand All @@ -244,7 +244,7 @@ public void TestSubmitBlock_InvalidBlockFormat()
string invalidBlockString = TestUtils.CreateInvalidBlockFormat();

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SubmitBlock(new JArray(invalidBlockString)),
_rpcServer.SubmitBlock(invalidBlockString),
"Should throw RpcException for invalid block format");

Assert.AreEqual(RpcError.InvalidParams.Code, exception.HResult);
Expand All @@ -261,7 +261,7 @@ public void TestSubmitBlock_AlreadyExists()
var blockString = Convert.ToBase64String(block.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SubmitBlock(new JArray(blockString)),
_rpcServer.SubmitBlock(blockString),
"Should throw RpcException when block already exists");
Assert.AreEqual(RpcError.AlreadyExists.Code, exception.HResult);
}
Expand All @@ -275,7 +275,7 @@ public void TestSubmitBlock_InvalidBlock()
var blockString = Convert.ToBase64String(block.ToArray());

var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SubmitBlock(new JArray(blockString)),
_rpcServer.SubmitBlock(blockString),
"Should throw RpcException for invalid block");
Assert.AreEqual(RpcError.VerificationFailed.Code, exception.HResult);
}
Expand All @@ -288,7 +288,7 @@ public void TestSubmitBlock_InvalidBlock()
public void TestSendRawTransaction_NullInput()
{
var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray((string)null)),
_rpcServer.SendRawTransaction((string)null),
"Should throw RpcException for null input");
Assert.AreEqual(RpcError.InvalidParams.Code, exception.HResult);
}
Expand All @@ -297,7 +297,7 @@ public void TestSendRawTransaction_NullInput()
public void TestSendRawTransaction_EmptyInput()
{
var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SendRawTransaction(new JArray(string.Empty)),
_rpcServer.SendRawTransaction(string.Empty),
"Should throw RpcException for empty input");
Assert.AreEqual(RpcError.InvalidParams.Code, exception.HResult);
}
Expand All @@ -306,7 +306,7 @@ public void TestSendRawTransaction_EmptyInput()
public void TestSubmitBlock_NullInput()
{
var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SubmitBlock(new JArray((string)null)),
_rpcServer.SubmitBlock((string)null),
"Should throw RpcException for null input");
Assert.AreEqual(RpcError.InvalidParams.Code, exception.HResult);
}
Expand All @@ -315,7 +315,7 @@ public void TestSubmitBlock_NullInput()
public void TestSubmitBlock_EmptyInput()
{
var exception = Assert.ThrowsException<RpcException>(() =>
_rpcServer.SubmitBlock(new JArray(string.Empty)),
_rpcServer.SubmitBlock(string.Empty),
"Should throw RpcException for empty input");
Assert.AreEqual(RpcError.InvalidParams.Code, exception.HResult);
}
Expand Down
Loading