Skip to content
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
147 changes: 78 additions & 69 deletions src/Plugins/RpcServer/RcpServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,78 +33,87 @@ public RpcServerSettings(IConfigurationSection section)

public record RpcServersSettings
{
public uint Network { get; init; }
public IPAddress BindAddress { get; init; }
public ushort Port { get; init; }
public string SslCert { get; init; }
public string SslCertPassword { get; init; }
public string[] TrustedAuthorities { get; init; }
public int MaxConcurrentConnections { get; init; }
public int MaxRequestBodySize { get; init; }
public string RpcUser { get; init; }
public string RpcPass { get; init; }
public bool EnableCors { get; init; }
public string[] AllowOrigins { get; init; }
public int KeepAliveTimeout { get; init; }
public uint RequestHeadersTimeout { get; init; }
// In the unit of datoshi, 1 GAS = 10^8 datoshi
public long MaxGasInvoke { get; init; }
// In the unit of datoshi, 1 GAS = 10^8 datoshi
public long MaxFee { get; init; }
public int MaxIteratorResultItems { get; init; }
public int MaxStackSize { get; init; }
public string[] DisabledMethods { get; init; }
public bool SessionEnabled { get; init; }
public TimeSpan SessionExpirationTime { get; init; }
public int FindStoragePageSize { get; init; }
public uint Network { get; init; } = 5195086u;
public IPAddress BindAddress { get; init; } = IPAddress.Loopback;
public ushort Port { get; init; } = 10332;
public string SslCert { get; init; } = string.Empty;
public string SslCertPassword { get; init; } = string.Empty;
public string[] TrustedAuthorities { get; init; } = [];
public int MaxConcurrentConnections { get; init; } = 40;
public int MaxRequestBodySize { get; init; } = 5 * 1024 * 1024;
public string RpcUser { get; init; } = string.Empty;
public string RpcPass { get; init; } = string.Empty;
public bool EnableCors { get; init; } = true;
public string[] AllowOrigins { get; init; } = [];

public static RpcServersSettings Default { get; } = new RpcServersSettings
/// <summary>
/// The maximum time in seconds allowed for the keep-alive connection to be idle.
/// </summary>
public int KeepAliveTimeout { get; init; } = 60;

/// <summary>
/// The maximum time in seconds allowed for the request headers to be read.
/// </summary>
public uint RequestHeadersTimeout { get; init; } = 15;

/// <summary>
/// In the unit of datoshi, 1 GAS = 10^8 datoshi
/// </summary>
public long MaxGasInvoke { get; init; } = (long)new BigDecimal(10M, NativeContract.GAS.Decimals).Value;

/// <summary>
/// In the unit of datoshi, 1 GAS = 10^8 datoshi
/// </summary>
public long MaxFee { get; init; } = (long)new BigDecimal(0.1M, NativeContract.GAS.Decimals).Value;
public int MaxIteratorResultItems { get; init; } = 100;
public int MaxStackSize { get; init; } = ushort.MaxValue;
public string[] DisabledMethods { get; init; } = [];
public bool SessionEnabled { get; init; } = false;
public TimeSpan SessionExpirationTime { get; init; } = TimeSpan.FromSeconds(60);
public int FindStoragePageSize { get; init; } = 50;

public static RpcServersSettings Default { get; } = new();

public static RpcServersSettings Load(IConfigurationSection section)
{
Network = 5195086u,
BindAddress = IPAddress.None,
SslCert = string.Empty,
SslCertPassword = string.Empty,
MaxGasInvoke = (long)new BigDecimal(10M, NativeContract.GAS.Decimals).Value,
MaxFee = (long)new BigDecimal(0.1M, NativeContract.GAS.Decimals).Value,
TrustedAuthorities = Array.Empty<string>(),
EnableCors = true,
AllowOrigins = Array.Empty<string>(),
KeepAliveTimeout = 60,
RequestHeadersTimeout = 15,
MaxIteratorResultItems = 100,
MaxStackSize = ushort.MaxValue,
DisabledMethods = Array.Empty<string>(),
MaxConcurrentConnections = 40,
MaxRequestBodySize = 5 * 1024 * 1024,
SessionEnabled = false,
SessionExpirationTime = TimeSpan.FromSeconds(60),
FindStoragePageSize = 50
};
var @default = Default;
return new()
{
Network = section.GetValue("Network", @default.Network),
BindAddress = IPAddress.Parse(section.GetValue("BindAddress", @default.BindAddress.ToString())),
Port = section.GetValue("Port", @default.Port),
SslCert = section.GetValue("SslCert", string.Empty),
SslCertPassword = section.GetValue("SslCertPassword", string.Empty),
TrustedAuthorities = GetStrings(section, "TrustedAuthorities"),
RpcUser = section.GetValue("RpcUser", @default.RpcUser),
RpcPass = section.GetValue("RpcPass", @default.RpcPass),
EnableCors = section.GetValue(nameof(EnableCors), @default.EnableCors),
Copy link
Member

Choose a reason for hiding this comment

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

We should use nameof in a homogeneous way, but it's ok to me

AllowOrigins = GetStrings(section, "AllowOrigins"),
KeepAliveTimeout = section.GetValue(nameof(KeepAliveTimeout), @default.KeepAliveTimeout),
RequestHeadersTimeout = section.GetValue(nameof(RequestHeadersTimeout), @default.RequestHeadersTimeout),
MaxGasInvoke = (long)new BigDecimal(section.GetValue<decimal>("MaxGasInvoke", @default.MaxGasInvoke), NativeContract.GAS.Decimals).Value,
MaxFee = (long)new BigDecimal(section.GetValue<decimal>("MaxFee", @default.MaxFee), NativeContract.GAS.Decimals).Value,
MaxIteratorResultItems = section.GetValue("MaxIteratorResultItems", @default.MaxIteratorResultItems),
MaxStackSize = section.GetValue("MaxStackSize", @default.MaxStackSize),
DisabledMethods = GetStrings(section, "DisabledMethods"),
MaxConcurrentConnections = section.GetValue("MaxConcurrentConnections", @default.MaxConcurrentConnections),
MaxRequestBodySize = section.GetValue("MaxRequestBodySize", @default.MaxRequestBodySize),
SessionEnabled = section.GetValue("SessionEnabled", @default.SessionEnabled),
SessionExpirationTime = TimeSpan.FromSeconds(section.GetValue("SessionExpirationTime", (long)@default.SessionExpirationTime.TotalSeconds)),
FindStoragePageSize = section.GetValue("FindStoragePageSize", @default.FindStoragePageSize)
};
}

public static RpcServersSettings Load(IConfigurationSection section) => new()
private static string[] GetStrings(IConfigurationSection section, string key)
{
Network = section.GetValue("Network", Default.Network),
BindAddress = IPAddress.Parse(section.GetSection("BindAddress").Value),
Port = ushort.Parse(section.GetSection("Port").Value),
SslCert = section.GetSection("SslCert").Value,
SslCertPassword = section.GetSection("SslCertPassword").Value,
TrustedAuthorities = section.GetSection("TrustedAuthorities").GetChildren().Select(p => p.Get<string>()).ToArray(),
RpcUser = section.GetSection("RpcUser").Value,
RpcPass = section.GetSection("RpcPass").Value,
EnableCors = section.GetValue(nameof(EnableCors), Default.EnableCors),
AllowOrigins = section.GetSection(nameof(AllowOrigins)).GetChildren().Select(p => p.Get<string>()).ToArray(),
KeepAliveTimeout = section.GetValue(nameof(KeepAliveTimeout), Default.KeepAliveTimeout),
RequestHeadersTimeout = section.GetValue(nameof(RequestHeadersTimeout), Default.RequestHeadersTimeout),
MaxGasInvoke = (long)new BigDecimal(section.GetValue<decimal>("MaxGasInvoke", Default.MaxGasInvoke), NativeContract.GAS.Decimals).Value,
MaxFee = (long)new BigDecimal(section.GetValue<decimal>("MaxFee", Default.MaxFee), NativeContract.GAS.Decimals).Value,
MaxIteratorResultItems = section.GetValue("MaxIteratorResultItems", Default.MaxIteratorResultItems),
MaxStackSize = section.GetValue("MaxStackSize", Default.MaxStackSize),
DisabledMethods = section.GetSection("DisabledMethods").GetChildren().Select(p => p.Get<string>()).ToArray(),
MaxConcurrentConnections = section.GetValue("MaxConcurrentConnections", Default.MaxConcurrentConnections),
MaxRequestBodySize = section.GetValue("MaxRequestBodySize", Default.MaxRequestBodySize),
SessionEnabled = section.GetValue("SessionEnabled", Default.SessionEnabled),
SessionExpirationTime = TimeSpan.FromSeconds(section.GetValue("SessionExpirationTime", (int)Default.SessionExpirationTime.TotalSeconds)),
FindStoragePageSize = section.GetValue("FindStoragePageSize", Default.FindStoragePageSize)
};
List<string> list = [];
foreach (var child in section.GetSection(key).GetChildren())
{
var value = child.Get<string>();
if (value is null) throw new ArgumentException($"Invalid value for {key}");
list.Add(value);
}
return list.ToArray();
}
}
}
4 changes: 2 additions & 2 deletions src/Plugins/RpcServer/RpcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public RpcServer(NeoSystem system, RpcServersSettings settings)
this.system = system;
this.settings = settings;

_rpcUser = settings.RpcUser is not null ? Encoding.UTF8.GetBytes(settings.RpcUser) : [];
_rpcPass = settings.RpcPass is not null ? Encoding.UTF8.GetBytes(settings.RpcPass) : [];
_rpcUser = string.IsNullOrEmpty(settings.RpcUser) ? [] : Encoding.UTF8.GetBytes(settings.RpcUser);
_rpcPass = string.IsNullOrEmpty(settings.RpcPass) ? [] : Encoding.UTF8.GetBytes(settings.RpcPass);

var addressVersion = system.Settings.AddressVersion;
ParameterConverter.RegisterConversion<SignersAndWitnesses>(token => token.ToSignersAndWitnesses(addressVersion));
Expand Down
43 changes: 40 additions & 3 deletions tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// modifications are permitted.

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Json;
using Neo.Persistence.Providers;
Expand All @@ -21,6 +22,7 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

Expand All @@ -37,9 +39,6 @@ public partial class UT_RpcServer
private readonly NEP6Wallet _wallet = TestUtils.GenerateTestWallet("123");
private WalletAccount _walletAccount;

const byte NativePrefixAccount = 20;
const byte NativePrefixTotalSupply = 11;

[TestInitialize]
public void TestSetup()
{
Expand Down Expand Up @@ -280,5 +279,43 @@ public async Task TestRegisterMethods()
Assert.AreEqual("mock", responseJson["result"].AsString());
Assert.AreEqual(200, context.Response.StatusCode);
}

[TestMethod]
public void TestRpcServerSettings_Load()
{
var config = new ConfigurationBuilder()
.AddJsonFile("RpcServer.json")
.Build()
.GetSection("PluginConfiguration")
.GetSection("Servers")
.GetChildren()
.First();

var settings = RpcServersSettings.Load(config);
Assert.AreEqual(860833102u, settings.Network);
Assert.AreEqual(10332, settings.Port);
Assert.AreEqual(IPAddress.Parse("127.0.0.1"), settings.BindAddress);
Assert.AreEqual(string.Empty, settings.SslCert);
Assert.AreEqual(string.Empty, settings.SslCertPassword);
Assert.AreEqual(0, settings.TrustedAuthorities.Length);
Assert.AreEqual(string.Empty, settings.RpcUser);
Assert.AreEqual(string.Empty, settings.RpcPass);
Assert.AreEqual(true, settings.EnableCors);
Assert.AreEqual(20_00000000, settings.MaxGasInvoke);
Assert.AreEqual(TimeSpan.FromSeconds(60), settings.SessionExpirationTime);
Assert.AreEqual(false, settings.SessionEnabled);
Assert.AreEqual(true, settings.EnableCors);
Assert.AreEqual(0, settings.AllowOrigins.Length);
Assert.AreEqual(60, settings.KeepAliveTimeout);
Assert.AreEqual(15u, settings.RequestHeadersTimeout);
Assert.AreEqual(1000_0000, settings.MaxFee); // 0.1 * 10^8
Assert.AreEqual(100, settings.MaxIteratorResultItems);
Assert.AreEqual(65535, settings.MaxStackSize);
Assert.AreEqual(1, settings.DisabledMethods.Length);
Assert.AreEqual("openwallet", settings.DisabledMethods[0]);
Assert.AreEqual(40, settings.MaxConcurrentConnections);
Assert.AreEqual(5 * 1024 * 1024, settings.MaxRequestBodySize);
Assert.AreEqual(50, settings.FindStoragePageSize);
}
}
}
Loading