Skip to content

Commit

Permalink
Merge pull request #59 from s2quake/feature/evidence
Browse files Browse the repository at this point in the history
Add Evidence module
  • Loading branch information
s2quake authored Jul 22, 2024
2 parents 1fca7b6 + 9b7e353 commit b029feb
Show file tree
Hide file tree
Showing 25 changed files with 727 additions and 5 deletions.
10 changes: 7 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"console": "integratedTerminal",
"args": [
"--nodes",
"b05c8b2bc981219c2afc32725f1dd7bdfce356ac7382699cb74647ab20895e32",
"b52e619962057e397f47efcb009ce45341f84cb86f425cd081cb64f1f1c1b220,cc1f459ea12f97cc8e996cf1d6ea74c4991f38cf4b555fa26a84d1db22c4481c,c7ffc6717833a51396ec992c0804946422a4ab85ab9fd64dfde99ba25a58ffe0,07cd0cf1242dd6ddef68a865658a57bdbe6b21c98d74c80365a274297e98667d",
"--clients",
"698e1dc854bfba5c359710ded3770010aa58625c2fe6ee1765ed9d0cf99c6b0d",
"--end-point",
Expand All @@ -31,7 +31,11 @@
"args": [
"--end-point",
"127.0.0.1:5353",
"--explorer-end-point"
"--explorer-end-point",
"--private-key",
"b52e619962057e397f47efcb009ce45341f84cb86f425cd081cb64f1f1c1b220",
"--log-path",
".log/node.log"
]
},
{
Expand Down Expand Up @@ -83,4 +87,4 @@
]
}
]
}
}
14 changes: 14 additions & 0 deletions libplanet-console.sln
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibplanetConsole.Consoles.E
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibplanetConsole.Common.Tests", "test\LibplanetConsole.Common.Tests\LibplanetConsole.Common.Tests.csproj", "{65341396-A058-4577-9B70-C1DD3D146501}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibplanetConsole.Nodes.Evidence", "src\node\LibplanetConsole.Nodes.Evidence\LibplanetConsole.Nodes.Evidence.csproj", "{4C151EAE-2105-4DA1-B645-C09513EA8532}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibplanetConsole.Consoles.Evidence", "src\console\LibplanetConsole.Consoles.Evidence\LibplanetConsole.Consoles.Evidence.csproj", "{965DF40E-F3BA-45F2-A177-A3DE550C824E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -117,6 +121,14 @@ Global
{65341396-A058-4577-9B70-C1DD3D146501}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65341396-A058-4577-9B70-C1DD3D146501}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65341396-A058-4577-9B70-C1DD3D146501}.Release|Any CPU.Build.0 = Release|Any CPU
{4C151EAE-2105-4DA1-B645-C09513EA8532}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C151EAE-2105-4DA1-B645-C09513EA8532}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C151EAE-2105-4DA1-B645-C09513EA8532}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C151EAE-2105-4DA1-B645-C09513EA8532}.Release|Any CPU.Build.0 = Release|Any CPU
{965DF40E-F3BA-45F2-A177-A3DE550C824E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{965DF40E-F3BA-45F2-A177-A3DE550C824E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{965DF40E-F3BA-45F2-A177-A3DE550C824E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{965DF40E-F3BA-45F2-A177-A3DE550C824E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -142,6 +154,8 @@ Global
{FEF8E9D4-CBB7-4EFC-A5C2-2C9E91498D79} = {4A8F8EE9-769C-4C97-89BC-19D038E69998}
{AF1A0011-2795-42FD-B67B-7F1956268577} = {CAB76DA9-6E57-4422-98C6-DD2D6299F675}
{65341396-A058-4577-9B70-C1DD3D146501} = {56942891-CFBD-41E4-8881-47F455D7BEFD}
{4C151EAE-2105-4DA1-B645-C09513EA8532} = {4A8F8EE9-769C-4C97-89BC-19D038E69998}
{965DF40E-F3BA-45F2-A177-A3DE550C824E} = {CAB76DA9-6E57-4422-98C6-DD2D6299F675}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
{1778FDCB-AC26-43E4-97FE-FC4F0C427672} = {23C68389-8F13-48E7-9878-440917F70DAF}
Expand Down
8 changes: 8 additions & 0 deletions src/common/LibplanetConsole.Common/AppPrivateKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Bencodex;
using Bencodex.Types;
using Libplanet.Common;
using Libplanet.Crypto;
using LibplanetConsole.Common.Converters;
Expand All @@ -13,6 +15,7 @@ namespace LibplanetConsole.Common;
[JsonConverter(typeof(AppPrivateKeyJsonConverter))]
public sealed record class AppPrivateKey
{
private static readonly Codec _codec = new();
private readonly PrivateKey _privateKey;

public AppPrivateKey(PrivateKey privateKey) => _privateKey = privateKey;
Expand Down Expand Up @@ -106,6 +109,11 @@ public T Decrypt<T>(string text)

public byte[] Sign(object obj)
{
if (obj is IValue value)
{
return _privateKey.Sign(_codec.Encode(value));
}

var json = JsonSerializer.Serialize(obj);
var bytes = Encoding.UTF8.GetBytes(json);
return _privateKey.Sign(bytes);
Expand Down
2 changes: 1 addition & 1 deletion src/common/LibplanetConsole.Common/BlockChainUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static BlockChain CreateBlockChain(
transactions: transactions,
timestamp: DateTimeOffset.MinValue);
var policy = new BlockPolicy(
blockInterval: TimeSpan.FromMilliseconds(8),
blockInterval: TimeSpan.FromSeconds(10),
getMaxTransactionsPerBlock: _ => int.MaxValue,
getMaxTransactionsBytes: _ => long.MaxValue);
var stagePolicy = new VolatileStagePolicy();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.ComponentModel;
using System.ComponentModel.Composition;
using JSSoft.Commands;
using LibplanetConsole.Common.Extensions;

namespace LibplanetConsole.Consoles.Evidence.Commands;

[Export(typeof(ICommand))]
[CommandSummary("Provides evidence-related commands.")]
[Category("Evidence")]
[method: ImportingConstructor]
internal sealed class EvidenceCommand(INodeCollection nodes)
: CommandMethodBase
{
[CommandMethod]
public async Task NewAsync(
string nodeAddress = "", CancellationToken cancellationToken = default)
{
var node = nodes.Current ?? throw new InvalidOperationException("No node is selected.");
var evidenceContent = node.GetService<IEvidenceContent>();
var evidenceInfo = await evidenceContent.AddEvidenceAsync(cancellationToken);
await Out.WriteLineAsJsonAsync(evidenceInfo);
}

[CommandMethod]
public async Task RaiseAsync(
CancellationToken cancellationToken = default)
{
var node = nodes.Current ?? throw new InvalidOperationException("No node is selected.");
var evidenceContent = node.GetService<IEvidenceContent>();
await evidenceContent.ViolateAsync(cancellationToken);
}

[CommandMethod]
public async Task ListAsync(long height = -1, CancellationToken cancellationToken = default)
{
var node = nodes.Current ?? throw new InvalidOperationException("No node is selected.");
var evidenceContent = node.GetService<IEvidenceContent>();
var evidenceInfos = await evidenceContent.GetEvidenceAsync(height, cancellationToken);
await Out.WriteLineAsJsonAsync(evidenceInfos);
}

#if LIBPLANET_DPOS
[CommandMethod]
public async Task UnjailAsync(
CancellationToken cancellationToken = default)
{
var node = nodes.Current ?? throw new InvalidOperationException("No node is selected.");
var evidenceContent = node.GetService<IEvidenceContent>();
await evidenceContent.UnjailAsync(cancellationToken);
}
#endif // LIBPLANET_DPOS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.ComponentModel.Composition;
using LibplanetConsole.Common.Services;
using LibplanetConsole.Consoles.Services;
using LibplanetConsole.Evidence.Serializations;
using LibplanetConsole.Evidence.Services;

namespace LibplanetConsole.Consoles.Evidence;

[Export(typeof(INodeContent))]
[Export(typeof(IEvidenceContent))]
[Export(typeof(INodeContentService))]
[method: ImportingConstructor]
internal sealed class EvidenceNodeContent(INode node)
: INodeContent, IEvidenceContent, INodeContentService
{
private readonly RemoteService<IEvidenceService> _evidenceService = new();

INode INodeContent.Node => node;

string INodeContent.Name => "evidence";

IRemoteService INodeContentService.RemoteService => _evidenceService;

private IEvidenceService Service => _evidenceService.Service;

public Task<EvidenceInfo> AddEvidenceAsync(CancellationToken cancellationToken)
=> Service.AddEvidenceAsync(cancellationToken);

public Task<EvidenceInfo[]> GetEvidenceAsync(long height, CancellationToken cancellationToken)
=> Service.GetEvidenceAsync(height, cancellationToken);

public Task ViolateAsync(CancellationToken cancellationToken)
=> Service.ViolateAsync(cancellationToken);

#if LIBPLANET_DPOS
public Task UnjailAsync(CancellationToken cancellationToken)
{
var signature = node.Sign(true);
return Service.UnjailAsync(signature, cancellationToken);
}
#endif // LIBPLANET_DPOS
}
16 changes: 16 additions & 0 deletions src/console/LibplanetConsole.Consoles.Evidence/IEvidenceContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using LibplanetConsole.Evidence.Serializations;

namespace LibplanetConsole.Consoles.Evidence;

internal interface IEvidenceContent
{
Task<EvidenceInfo> AddEvidenceAsync(CancellationToken cancellationToken);

Task<EvidenceInfo[]> GetEvidenceAsync(long height, CancellationToken cancellationToken);

Task ViolateAsync(CancellationToken cancellationToken);

#if LIBPLANET_DPOS
Task UnjailAsync(CancellationToken cancellationToken);
#endif // LIBPLANET_DPOS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\LibplanetConsole.Consoles\LibplanetConsole.Consoles.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)..\..\shared\LibplanetConsole.Evidence\**\*.cs" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<ProjectReference Include="..\LibplanetConsole.Consoles\LibplanetConsole.Consoles.csproj" />
<ProjectReference Include="..\LibplanetConsole.Consoles.Examples\LibplanetConsole.Consoles.Examples.csproj" />
<ProjectReference Include="..\LibplanetConsole.Consoles.Explorer\LibplanetConsole.Consoles.Explorer.csproj" />
<ProjectReference Include="..\LibplanetConsole.Consoles.Evidence\LibplanetConsole.Consoles.Evidence.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.ComponentModel;
using System.ComponentModel.Composition;
using JSSoft.Commands;
using LibplanetConsole.Common.Extensions;

namespace LibplanetConsole.Nodes.Evidence.Commands;

[Export(typeof(ICommand))]
[CommandSummary("Provides evidence-related commands.")]
[Category("Evidence")]
[method: ImportingConstructor]
internal sealed class EvidenceCommand(INode node, IEvidenceNode evidenceNode)
: CommandMethodBase
{
public override bool IsEnabled => node.IsRunning is true;

[CommandMethod]
[CommandSummary("Adds a new evidence.")]
public async Task NewAsync(CancellationToken cancellationToken)
{
var evidenceInfo = await evidenceNode.AddEvidenceAsync(cancellationToken);
await Out.WriteLineAsJsonAsync(evidenceInfo);
}

[CommandMethod]
[CommandSummary("Raises a infraction.")]
public async Task RaiseAsync(CancellationToken cancellationToken)
{
await evidenceNode.ViolateAsync(cancellationToken);
}

[CommandMethod]
[CommandMethodStaticProperty(typeof(ListProperties))]
[CommandSummary("Gets the evidence list.")]
public async Task ListAsync(CancellationToken cancellationToken = default)
{
var height = ListProperties.Height;
var isPending = ListProperties.IsPending;
var evidenceInfos = isPending == true ?
await evidenceNode.GetPendingEvidenceAsync(cancellationToken) :
await evidenceNode.GetEvidenceAsync(height, cancellationToken);
await Out.WriteLineAsJsonAsync(evidenceInfos);
}

[CommandMethod]
[CommandMethodStaticProperty(typeof(GetProperties))]
[CommandSummary("Gets the evidence.")]
public async Task GetAsync(string evidenceId, CancellationToken cancellationToken)
{
var isPending = GetProperties.IsPending;
var evidenceInfo = isPending == true ?
await evidenceNode.GetPendingEvidenceAsync(evidenceId, cancellationToken) :
await evidenceNode.GetEvidenceAsync(evidenceId, cancellationToken);
await Out.WriteLineAsJsonAsync(evidenceInfo);
}

#if LIBPLANET_DPOS
[CommandMethod]
public async Task UnjailAsync(CancellationToken cancellationToken)
{
await evidenceNode.UnjailAsync(cancellationToken);
}
#endif // LIBPLANET_DPOS

public static class ListProperties
{
[CommandPropertyRequired(DefaultValue = -1)]
[CommandSummary("The height of the block to get the evidence. default is the tip.")]
public static long Height { get; set; }

[CommandPropertySwitch("pending", 'p')]
[CommandPropertyCondition(nameof(Height), -1, IsNot = true)]
[CommandSummary("Indicates whether to get pending evidence. " +
"if true, the height is ignored.")]
public static bool IsPending { get; set; }
}

public static class GetProperties
{
[CommandPropertySwitch("pending", 'p')]
[CommandSummary("Indicates whether to get pending evidence.")]
public static bool IsPending { get; set; }
}
}
Loading

0 comments on commit b029feb

Please sign in to comment.