Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
s2quake committed Aug 26, 2024
1 parent 3b344cd commit 412140f
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.40.0"/>
<PackageReference Include="Grpc.AspNetCore.Server.Reflection" Version="2.64.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
Expand All @@ -21,6 +22,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Libplanet.Crypto.Secp256k1\Libplanet.Crypto.Secp256k1.csproj" />
<ProjectReference Include="..\Libplanet.Node.Extensions\Libplanet.Node.Extensions.csproj" />
<ProjectReference Include="..\Libplanet.Node\Libplanet.Node.csproj" />
<ProjectReference Include="..\Libplanet.Node.Swagger\Libplanet.Node.Swagger.csproj" />
Expand Down
25 changes: 25 additions & 0 deletions sdk/node/Libplanet.Node.Executable/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Libplanet.Node.Options.Schema;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Serilog;
using Serilog.Events;

var builder = WebHost.CreateDefaultBuilder(args);
var assemblies = new string[]
Expand All @@ -14,6 +16,16 @@
builder.ConfigureLogging(logging =>
{
logging.AddConsole();

// Logging setting
var loggerConfig = new LoggerConfiguration();
loggerConfig = loggerConfig.MinimumLevel.Information();
loggerConfig = loggerConfig
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console();

Log.Logger = loggerConfig.CreateLogger();
});
builder.ConfigureKestrel((context, options) =>
{
Expand All @@ -26,6 +38,19 @@
});
builder.ConfigureServices((context, services) =>
{
// string pluginPath = "/Users/bin_bash_shell/Workspaces/planetarium/NineChronicles/" +
// "lib9c/Lib9c.NCActionLoader/bin/Debug/net6.0/Lib9c.NCActionLoader.dll";
// string actionLoaderType = "Lib9c.NCActionLoader.NineChroniclesActionLoader";
// string blockPolicyType = "Lib9c.NCActionLoader.NineChroniclesPolicyActionRegistry";
// IActionLoader actionLoader = PluginLoader.LoadActionLoader(pluginPath, actionLoaderType);
// IPolicyActionsRegistry policyActionRegistry =
// PluginLoader.LoadPolicyActionRegistry(pluginPath, blockPolicyType);

// Libplanet.Crypto.CryptoConfig.CryptoBackend = new Secp256k1CryptoBackend<SHA256>();

// builder.Services.AddSingleton<IActionLoader>(actionLoader);
// builder.Services.AddSingleton<IPolicyActionsRegistry>(policyActionRegistry);

services.AddGrpc();
services.AddGrpcReflection();
services.AddLibplanetNode(context.Configuration);
Expand Down
29 changes: 26 additions & 3 deletions sdk/node/Libplanet.Node.Executable/appsettings-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,19 @@
}
}
},
"Action": {
"title": "ActionOptions",
"type": "object",
"additionalProperties": false,
"properties": {
"ActionLoaderPath": {
"type": "string"
},
"ActionLoaderType": {
"type": "string"
}
}
},
"Genesis": {
"title": "GenesisOptions",
"type": "object",
Expand All @@ -1114,12 +1127,12 @@
"properties": {
"GenesisKey": {
"type": "string",
"description": "The key of the genesis block.",
"description": "The PrivateKey used to generate the genesis block. This property cannot be used with GenesisBlockPath.",
"pattern": "^[0-9a-fA-F]{64}$"
},
"Validators": {
"type": "array",
"description": "Public keys of the validators.",
"description": "Public keys of the validators. This property cannot be used with GenesisBlockPath.",
"items": {
"type": "string"
}
Expand All @@ -1131,7 +1144,7 @@
},
"GenesisBlockPath": {
"type": "string",
"description": "The path of the genesis block."
"description": "The path of the genesis block, which can be a file path or a URI.This property cannot be used with GenesisKey."
}
}
},
Expand Down Expand Up @@ -1221,6 +1234,12 @@
"type": "string",
"description": "The endpoint of the node to block sync.",
"pattern": "^$|^[0-9a-fA-F]{130}|[0-9a-fA-F]{66},\\s*(?:(?:[a-zA-Z0-9\\-\\.]+)|(?:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})):\\d{1,5}$"
},
"TrustedAppProtocolVersionSigners": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
Expand Down Expand Up @@ -1260,6 +1279,10 @@
"description": "Type 'ExplorerOptions' does not have a description.",
"$ref": "#/definitions/Explorer"
},
"Action": {
"description": "Type 'ActionOptions' does not have a description.",
"$ref": "#/definitions/Action"
},
"Genesis": {
"description": "Options for the genesis block.",
"$ref": "#/definitions/Genesis"
Expand Down
14 changes: 11 additions & 3 deletions sdk/node/Libplanet.Node.Executable/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,17 @@
},
"Swarm": {
"IsEnabled": true,
"AppProtocolVersion": "200210/AB2da648b9154F2cCcAFBD85e0Bc3d51f97330Fc/MEUCIQCBr..8VdITFe9nMTobl4akFid.s8G2zy2pBidAyRXSeAIgER77qX+eywjgyth6QYi7rQw5nK3KXO6cQ6ngUh.CyfU=/ZHU5OnRpbWVzdGFtcHUxMDoyMDI0LTA3LTMwZQ=="
"AppProtocolVersion": "200210/AB2da648b9154F2cCcAFBD85e0Bc3d51f97330Fc/MEUCIQCBr..8VdITFe9nMTobl4akFid.s8G2zy2pBidAyRXSeAIgER77qX+eywjgyth6QYi7rQw5nK3KXO6cQ6ngUh.CyfU=/ZHU5OnRpbWVzdGFtcHUxMDoyMDI0LTA3LTMwZQ==",
"BlocksyncSeedPeer": "027bd36895d68681290e570692ad3736750ceaab37be402442ffb203967f98f7b6,9c-main-tcp-seed-1.planetarium.dev:31234"
},
"Validator": {
"IsEnabled": true
"Store": {
"Type": 0,
"RootPath": "/Users/jeesu/Projects/Storage/Chain",
"StoreName": "9c-main-snapshot-slim",
"StateStoreName": "9c-main-snapshot-slim/states"
},
"Action": {
"ActionLoaderPath": "/Users/jeesu/Downloads/osx-arm64/Lib9c.dll",
"ActionLoaderType": "Nekoyume.Action.Loader.NCActionLoader"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public static ILibplanetNodeBuilder AddLibplanetNode(
.Bind(configuration.GetSection(StoreOptions.Position));
services.AddSingleton<IConfigureOptions<StoreOptions>, StoreOptionsConfigurator>();

services.AddOptions<ActionOptions>()
.Bind(configuration.GetSection(ActionOptions.Position));

services.AddOptions<SwarmOptions>()
.Bind(configuration.GetSection(SwarmOptions.Position));
services.AddSingleton<IConfigureOptions<SwarmOptions>, SwarmOptionsConfigurator>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Libplanet.Action;
using Libplanet.Action.Loader;
using Libplanet.Blockchain;
using Libplanet.Crypto;
using Libplanet.Node.Options;
Expand All @@ -20,6 +22,7 @@ public void Create_Test()
services.AddSingleton<IConfigureOptions<GenesisOptions>, GenesisOptionsConfigurator>();
services.AddOptions<StoreOptions>();
services.AddSingleton<IConfigureOptions<StoreOptions>, StoreOptionsConfigurator>();
services.AddOptions<ActionOptions>();
services.AddOptions<SwarmOptions>();
services.AddSingleton<IConfigureOptions<SwarmOptions>, SwarmOptionsConfigurator>();

Expand All @@ -28,11 +31,12 @@ public void Create_Test()
var logger = new NullLoggerFactory().CreateLogger<BlockChainService>();
var genesisOptions = serviceProvider.GetRequiredService<IOptions<GenesisOptions>>();
var storeOptions = serviceProvider.GetRequiredService<IOptions<StoreOptions>>();
var actionOptions = serviceProvider.GetRequiredService<IOptions<ActionOptions>>();
var blockChainService = new BlockChainService(
genesisOptions: genesisOptions,
storeOptions: storeOptions,
actionOptions: actionOptions,
policyService: policyService,
actionLoaderProviders: [],
logger: logger);
var blockChain = blockChainService.BlockChain;

Expand Down
31 changes: 31 additions & 0 deletions sdk/node/Libplanet.Node/Actions/PluginLoadContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Reflection;
using System.Runtime.Loader;

namespace Libplanet.Node.Actions;

public class PluginLoadContext(string pluginPath) : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver = new(pluginPath);

protected override Assembly? Load(AssemblyName assemblyName)
{
var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath is not null)
{
return LoadFromAssemblyPath(assemblyPath);
}

return null;
}

protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
var libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath is not null)
{
return LoadUnmanagedDllFromPath(libraryPath);
}

return IntPtr.Zero;
}
}
89 changes: 89 additions & 0 deletions sdk/node/Libplanet.Node/Actions/PluginLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Reflection;
using Libplanet.Action;
using Libplanet.Action.Loader;

namespace Libplanet.Node.Actions;

public static class PluginLoader
{
public static IActionLoader LoadActionLoader(string relativePath, string typeName)
{
Assembly assembly = LoadPlugin(relativePath);
IEnumerable<IActionLoader> loaders = Create<IActionLoader>(assembly);
foreach (IActionLoader loader in loaders)
{
if (loader.GetType().FullName == typeName)
{
return loader;
}
}

throw new ApplicationException(
$"Can't find {typeName} in {assembly} from {assembly.Location}. " +
$"Available types: {string
.Join(",", loaders.Select(x => x.GetType().FullName))}");
}

public static IPolicyActionsRegistry LoadPolicyActionRegistry(
string relativePath,
string typeName)
{
Assembly assembly = LoadPlugin(relativePath);
IEnumerable<IPolicyActionsRegistry> policies = Create<IPolicyActionsRegistry>(assembly);
foreach (IPolicyActionsRegistry policy in policies)
{
if (policy.GetType().FullName == typeName)
{
return policy;
}
}

throw new ApplicationException(
$"Can't find {typeName} in {assembly} from {assembly.Location}. " +
$"Available types: {string
.Join(",", policies.Select(x => x.GetType().FullName))}");
}

private static IEnumerable<T> Create<T>(Assembly assembly)
where T : class
{
int count = 0;

foreach (Type type in assembly.GetTypes())

Check warning on line 52 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / check-build

Loops should be simplified using the "Where" LINQ method (https://rules.sonarsource.com/csharp/RSPEC-3267)

Check warning on line 52 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / docs

Loops should be simplified using the "Where" LINQ method (https://rules.sonarsource.com/csharp/RSPEC-3267)
{
if (typeof(T).IsAssignableFrom(type))
{
if (Activator.CreateInstance(type) is T result)

Check warning on line 56 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / check-build

Merge this if statement with the enclosing one. (https://rules.sonarsource.com/csharp/RSPEC-1066)

Check warning on line 56 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / docs

Merge this if statement with the enclosing one. (https://rules.sonarsource.com/csharp/RSPEC-1066)
{
count++;
yield return result;
}
}
}

if (count == 0)
{
string availableTypes = string.Join(",", assembly.GetTypes().Select(t => t.FullName));
throw new ApplicationException(
$"Can't find any type which implements ICommand in {assembly} from {assembly.Location}.\n" +

Check warning on line 68 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / check-build

Line must be no longer than 100 characters (now 108).

Check warning on line 68 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / docs

Line must be no longer than 100 characters (now 108).
$"Available types: {availableTypes}");
}
}

private static Assembly LoadPlugin(string relativePath)
{
// Navigate up to the solution root
// string root = Path.GetFullPath(Path.Combine(
// Path.GetDirectoryName(
// Path.GetDirectoryName(
// Path.GetDirectoryName(
// Path.GetDirectoryName(
// Path.GetDirectoryName(typeof(Program).Assembly.Location)))))));

Check warning on line 81 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / check-build

Remove this commented out code. (https://rules.sonarsource.com/csharp/RSPEC-125)

Check warning on line 81 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / docs

Remove this commented out code. (https://rules.sonarsource.com/csharp/RSPEC-125)

// string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\', Path.DirectorySeparatorChar)));

Check warning on line 83 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / check-build

Line must be no longer than 100 characters (now 129).

Check warning on line 83 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / docs

Line must be no longer than 100 characters (now 129).
string pluginLocation = relativePath;
Console.WriteLine($"Loading commands from: {pluginLocation}");
PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);
return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));

Check warning on line 87 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / check-build

Line must be no longer than 100 characters (now 116).

Check warning on line 87 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs

View workflow job for this annotation

GitHub Actions / docs

Line must be no longer than 100 characters (now 116).
}
}
28 changes: 28 additions & 0 deletions sdk/node/Libplanet.Node/Options/ActionOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Libplanet.Action;
using Libplanet.Action.Loader;
using Libplanet.Node.Actions;

namespace Libplanet.Node.Options;

[Options(Position)]
public sealed class ActionOptions : OptionsBase<ActionOptions>
{
public const string Position = "Action";

public string ActionLoaderPath { get; set; } = string.Empty;

public string ActionLoaderType { get; set; } = string.Empty;

internal IActionLoader GetActionLoader()
{
var actionLoaderPath = ActionLoaderPath;
var actionLoaderType = ActionLoaderType;
return PluginLoader.LoadActionLoader(actionLoaderPath, actionLoaderType);
}

internal IPolicyActionsRegistry GetPolicyActionsRegistry()
{
// PluginLoader.LoadPolicyActionRegistry(pluginPath, blockPolicyType);

Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs

View workflow job for this annotation

GitHub Actions / check-build

Remove this commented out code. (https://rules.sonarsource.com/csharp/RSPEC-125)

Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs

View workflow job for this annotation

GitHub Actions / check-build

Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs

View workflow job for this annotation

GitHub Actions / docs

Remove this commented out code. (https://rules.sonarsource.com/csharp/RSPEC-125)

Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs

View workflow job for this annotation

GitHub Actions / docs

return new PolicyActionsRegistry();
}
}
4 changes: 4 additions & 0 deletions sdk/node/Libplanet.Node/Options/SwarmOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ public sealed class SwarmOptions : OptionsBase<SwarmOptions>
[BoundPeer]
[Description("The endpoint of the node to block sync.")]
public string BlocksyncSeedPeer { get; set; } = string.Empty;

// 030ffa9bd579ee1503ce008394f687c182279da913bfaec12baca34e79698a7cd1
[PublicKeyArray]
public string[] TrustedAppProtocolVersionSigners { get; set; } = [];
}
Loading

0 comments on commit 412140f

Please sign in to comment.