Skip to content

Commit

Permalink
Merge pull request planetarium#3911 from s2quake/exp/sdk/swarm
Browse files Browse the repository at this point in the history
Add Node Service(swarm) to SDK
  • Loading branch information
s2quake authored Aug 14, 2024
2 parents 5c67f7f + 1ab0ed2 commit e40cc5f
Show file tree
Hide file tree
Showing 69 changed files with 1,830 additions and 302 deletions.
3 changes: 3 additions & 0 deletions sdk/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[*.proto]
indent_size = 2

[*.cs]

# S3903: Types should be defined in named namespaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server"/>
<Protobuf Include="Protos\*.proto" GrpcServices="Server"/>
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 5 additions & 3 deletions sdk/node/Libplanet.Node.Executable/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Libplanet.Node.Extensions;
using Microsoft.AspNetCore.Server.Kestrel.Core;

SynchronizationContext.SetSynchronizationContext(new());
var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();
Expand All @@ -23,8 +24,9 @@
// Add services to the container.
builder.Services.AddGrpc();
builder.Services.AddGrpcReflection();
builder.Services.AddLibplanetNode(builder.Configuration.GetSection("Libplanet"))
.WithSeed();
var libplanetBuilder = builder.Services.AddLibplanetNode(builder.Configuration)
.WithSeed()
.WithNode();

var app = builder.Build();
var handlerMessage = """
Expand All @@ -33,7 +35,7 @@ Communication with gRPC endpoints must be made through a gRPC client. To learn h
""";

// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGrpcServiceFromDomain(libplanetBuilder.Scopes);
app.MapGet("/", () => handlerMessage);

if (builder.Environment.IsDevelopment())
Expand Down
44 changes: 44 additions & 0 deletions sdk/node/Libplanet.Node.Executable/Protos/blockchain.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
syntax = "proto3";

option csharp_namespace = "Libplanet.Node.API";

package node;

service BlockChain {
rpc GetGenesisBlock (GetGenesisBlockRequest) returns (GetGenesisBlockReply);
rpc GetTip(Empty) returns (GetTipReply);
rpc GetBlock(GetBlockRequest) returns (GetBlockReply);
}

message Empty {
}

message GetGenesisBlockRequest {
}

message GetGenesisBlockReply {
string hash = 1;
}

message GetTipReply {
string hash = 1;
int64 height = 2;
}

message GetBlockRequest {
oneof block_identifier {
int64 height = 1;
string hash = 2;
}
}

message GetBlockReply {
string hash = 1;
int64 height = 2;
string miner = 3;
string public_key = 4;
string previous_hash = 5;
string state_root_hash = 6;
string signature = 7;
int64 protocol_version = 8;
}
38 changes: 0 additions & 38 deletions sdk/node/Libplanet.Node.Executable/Protos/greet.proto

This file was deleted.

19 changes: 19 additions & 0 deletions sdk/node/Libplanet.Node.Executable/Protos/seed.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
syntax = "proto3";

option csharp_namespace = "Libplanet.Node.API";

package node;

// The greeting service definition.
service Seed {
// Sends a greeting
rpc GetSeed(GetSeedRequest) returns (GetSeedReply);
}

message GetSeedRequest {
}

message GetSeedReply {
string blocksync_seed = 1;
string consensus_seed = 2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Grpc.Core;
using Libplanet.Common;
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Services;
using Libplanet.Types.Blocks;

namespace Libplanet.Node.API.Services;

[Grpc]
public class BlockChainGrpcService(
IReadChainService blockChain)
: BlockChain.BlockChainBase
{
private readonly IReadChainService _blockChain = blockChain;

public override Task<GetGenesisBlockReply> GetGenesisBlock(
GetGenesisBlockRequest request,
ServerCallContext context)
{
return Task.FromResult(new GetGenesisBlockReply
{
Hash = _blockChain.Tip.Hash.ToString(),
});
}

public override Task<GetTipReply> GetTip(Empty request, ServerCallContext context)
{
return Task.FromResult(new GetTipReply
{
Hash = _blockChain.Tip.Hash.ToString(),
Height = _blockChain.Tip.Index,
});
}

public override Task<GetBlockReply> GetBlock(GetBlockRequest request, ServerCallContext context)
{
return Task.Run(GetResult);

Block GetBlock() => request.BlockIdentifierCase switch
{
GetBlockRequest.BlockIdentifierOneofCase.Hash
=> _blockChain.GetBlock(BlockHash.FromString(request.Hash)),
GetBlockRequest.BlockIdentifierOneofCase.Height
=> _blockChain.GetBlock(request.Height),
_ => throw new InvalidOperationException("Invalid block identifier."),
};

GetBlockReply GetResult()
{
var block = GetBlock();
return new GetBlockReply
{
Hash = block.Hash.ToString(),
Height = block.Index,
Miner = block.Miner.ToString(),
PublicKey = $"{block.PublicKey}",
PreviousHash = $"{block.PreviousHash}",
StateRootHash = $"{block.StateRootHash}",
Signature = $"{ByteUtil.Hex(block.Signature ?? [])}",
ProtocolVersion = block.ProtocolVersion,
};
}
}
}
45 changes: 0 additions & 45 deletions sdk/node/Libplanet.Node.Executable/Services/GreeterService.cs

This file was deleted.

28 changes: 28 additions & 0 deletions sdk/node/Libplanet.Node.Executable/Services/SeedGrpcService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Grpc.Core;
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Services;

namespace Libplanet.Node.API.Services;

[Grpc(Scope = "Seed")]
public class SeedGrpcService(
IServiceProvider serviceProvider)
: Seed.SeedBase
{
public override Task<GetSeedReply> GetSeed(GetSeedRequest request, ServerCallContext context)
{
var blocksyncSeedService = serviceProvider.GetService<IBlocksyncSeedService>();
var consensusSeedService = serviceProvider.GetService<IConsensusSeedService>();
if (blocksyncSeedService is null || consensusSeedService is null)
{
throw new RpcException(
new Status(StatusCode.Unavailable, "Seed services are not available."));
}

return Task.FromResult(new GetSeedReply
{
BlocksyncSeed = EndPointUtility.ToString(blocksyncSeedService.BoundPeer.EndPoint),
ConsensusSeed = EndPointUtility.ToString(consensusSeedService.BoundPeer.EndPoint),
});
}
}
12 changes: 0 additions & 12 deletions sdk/node/Libplanet.Node.Executable/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,5 @@
"EndpointDefaults": {
"Protocols": "Http2"
}
},
"Libplanet": {
"Store": {
"RootPath": "./.store",
"Type": "InMemory"
},
"Genesis": {
"GenesisKey": "2a15e7deaac09ce631e1faa184efadb175b6b90989cf1faed9dfc321ad1db5ac",
"Validators": [
"044640270a199ee7b17b0c905916f2ca8188c70d8f0a004f669712383d5827209c404f523a19351a1d578c8bce1a1a54b29a054e4a865a9a5ce285325e3e81c789"
]
}
}
}
6 changes: 0 additions & 6 deletions sdk/node/Libplanet.Node.Executable/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,5 @@
"EndpointDefaults": {
"Protocols": "Http2"
}
},
"Libplanet": {
"Store": {
"RootPath": "./.store",
"Type": "InMemory"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
25 changes: 4 additions & 21 deletions sdk/node/Libplanet.Node.Extensions/LibplanetServicesExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,20 @@
using Libplanet.Node.Options;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Libplanet.Node.Extensions;

public static class LibplanetServicesExtensions
{
public static ILibplanetNodeBuilder AddLibplanetNode(
this IServiceCollection services,
Action<LibplanetOption> configure)
{
services.Configure(configure);
return AddLibplanetNode(services);
}

public static ILibplanetNodeBuilder AddLibplanetNode(
this IServiceCollection services,
IConfiguration configuration)
{
services.Configure<StoreOption>(configuration.GetSection(StoreOption.Position));
SynchronizationContext.SetSynchronizationContext(SynchronizationContext.Current ?? new());
services.AddSingleton(SynchronizationContext.Current!);
services.Configure<SoloProposeOption>(configuration.GetSection(SoloProposeOption.Position));
services.Configure<GenesisOptions>(configuration.GetSection(GenesisOptions.Position));
services.Configure<SeedOptions>(
SeedOptions.BlocksyncSeed, configuration.GetSection(SeedOptions.BlocksyncSeed));
services.Configure<SeedOptions>(
SeedOptions.ConsensusSeed, configuration.GetSection(SeedOptions.ConsensusSeed));
services.AddOptionsFromDomain(configuration);

services.AddSingleton<IConfigureOptions<SeedOptions>, SeedOptionsConfigurator>();
services.AddSingleton<IConfigureNamedOptions<SeedOptions>, SeedOptionsConfigurator>();
return AddLibplanetNode(services);
return new LibplanetNodeBuilder(services, configuration);
}

private static ILibplanetNodeBuilder AddLibplanetNode(this IServiceCollection services)
=> new LibplanetNodeBuilder(services);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ public interface ILibplanetNodeBuilder
{
IServiceCollection Services { get; }

string[] Scopes { get; }

ILibplanetNodeBuilder WithSolo();

ILibplanetNodeBuilder WithSwarm();
ILibplanetNodeBuilder WithNode();

ILibplanetNodeBuilder WithValidate();

Expand Down
Loading

0 comments on commit e40cc5f

Please sign in to comment.