Skip to content

Commit

Permalink
introduce: IRenderObservables
Browse files Browse the repository at this point in the history
  • Loading branch information
riemannulus committed Aug 17, 2024
1 parent e40cc5f commit 15f8eb5
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
using Libplanet.Node.Extensions;
using Libplanet.Node.Options;
using Libplanet.Node.Services;
using Libplanet.Node.Services.Renderer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;

namespace Libplanet.Node.Tests.Services;

Expand All @@ -28,6 +30,7 @@ static BlockChainService CreateBlockChainService()
storeOptions: storeOptions,
policyService: policyService,
actionLoaderProviders: [],
rendererService: Mock.Of<IRenderObservables>(),
logger: logger);
}
}
Expand All @@ -53,6 +56,7 @@ public void Create_Test()
storeOptions: storeOptions,
policyService: policyService,
actionLoaderProviders: [],
rendererService: Mock.Of<IRenderObservables>(),
logger: logger);
var blockChain = blockChainService.BlockChain;

Expand Down
1 change: 1 addition & 0 deletions sdk/node/Libplanet.Node/Libplanet.Node.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" />
<PackageReference Include="R3" Version="1.2.6" />
</ItemGroup>

<ItemGroup>
Expand Down
58 changes: 12 additions & 46 deletions sdk/node/Libplanet.Node/Services/BlockChainService.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Numerics;
using System.Security.Cryptography;
using Bencodex.Types;
using Libplanet.Action;
using Libplanet.Action.Loader;
using Libplanet.Action.Sys;
using Libplanet.Blockchain;
using Libplanet.Blockchain.Policies;
using Libplanet.Blockchain.Renderers;
using Libplanet.Common;
using Libplanet.Crypto;
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Options;
using Libplanet.Node.Services.Renderer;
using Libplanet.RocksDBStore;
using Libplanet.Store;
using Libplanet.Store.Trie;
using Libplanet.Types.Blocks;
using Libplanet.Types.Consensus;
using Libplanet.Types.Tx;
using Microsoft.Extensions.Logging;
Expand All @@ -26,69 +23,38 @@ namespace Libplanet.Node.Services;

[Singleton]
[Singleton<IBlockChainService>]
internal sealed class BlockChainService : IBlockChainService, IActionRenderer
internal sealed class BlockChainService : IBlockChainService
{
private readonly SynchronizationContext _synchronizationContext;
private readonly ILogger<BlockChainService> _logger;

Check warning on line 28 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / docs

Remove this unread private field '_logger' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)

Check warning on line 28 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / docs

Remove this unread private field '_logger' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)

Check warning on line 28 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / check-build

Remove this unread private field '_logger' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)

Check warning on line 28 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / check-build

Remove this unread private field '_logger' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)
private readonly BlockChain _blockChain;
private readonly ConcurrentDictionary<TxId, ManualResetEvent> _eventByTxId = [];
private readonly ConcurrentDictionary<IValue, Exception> _exceptionByAction = [];

public BlockChainService(
IOptions<GenesisOptions> genesisOptions,
IOptions<StoreOptions> storeOptions,
PolicyService policyService,
IEnumerable<IActionLoaderProvider> actionLoaderProviders,
IRenderObservables rendererService,
ILogger<BlockChainService> logger)
{
_synchronizationContext = SynchronizationContext.Current ?? new();
_logger = logger;
_blockChain = CreateBlockChain(
genesisOptions: genesisOptions.Value.Verify(),
storeOptions: storeOptions.Value.Verify(),
stagePolicy: policyService.StagePolicy,
renderers: [this],
renderers:
[
rendererService.RenderActionObservable,
rendererService.RenderActionErrorObservable,
rendererService.RenderBlockObservable,
rendererService.RenderBlockEndObservable,
],
actionLoaders: [.. actionLoaderProviders.Select(item => item.GetActionLoader())]);
}

public event EventHandler<BlockEventArgs>? BlockAppended;

Check warning on line 54 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / docs

The event 'BlockChainService.BlockAppended' is never used

Check warning on line 54 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / docs

The event 'BlockChainService.BlockAppended' is never used

Check warning on line 54 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / check-build

The event 'BlockChainService.BlockAppended' is never used

Check warning on line 54 in sdk/node/Libplanet.Node/Services/BlockChainService.cs

View workflow job for this annotation

GitHub Actions / check-build

The event 'BlockChainService.BlockAppended' is never used

public BlockChain BlockChain => _blockChain;

void IRenderer.RenderBlock(Block oldTip, Block newTip)
{
}

void IActionRenderer.RenderAction(
IValue action, ICommittedActionContext context, HashDigest<SHA256> nextState)
{
}

void IActionRenderer.RenderActionError(
IValue action, ICommittedActionContext context, Exception exception)
{
_exceptionByAction.AddOrUpdate(action, exception, (_, _) => exception);
}

void IActionRenderer.RenderBlockEnd(Block oldTip, Block newTip)
{
_synchronizationContext.Post(Action, state: null);

void Action(object? state)
{
foreach (var transaction in newTip.Transactions)
{
if (_eventByTxId.TryGetValue(transaction.Id, out var manualResetEvent))
{
manualResetEvent.Set();
}
}

_logger.LogInformation("#{Height}: Block appended.", newTip.Index);
BlockAppended?.Invoke(this, new(newTip));
}
}

private static BlockChain CreateBlockChain(
GenesisOptions genesisOptions,
StoreOptions storeOptions,
Expand All @@ -104,8 +70,8 @@ private static BlockChain CreateBlockChain(
stateStore,
actionLoader);
var validators = genesisOptions.Validators.Select(PublicKey.FromHex)
.Select(item => new Validator(item, new BigInteger(1000)))
.ToArray();
.Select(item => new Validator(item, new BigInteger(1000)))
.ToArray();
var validatorSet = new ValidatorSet(validators: [.. validators]);
var nonce = 0L;
IAction[] actions =
Expand Down
13 changes: 13 additions & 0 deletions sdk/node/Libplanet.Node/Services/Renderer/IRenderObservables.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Libplanet.Node.Services.Renderer;

public interface IRenderObservables
{
public RenderActionObservable RenderActionObservable { get; }

public RenderActionErrorObservable RenderActionErrorObservable { get; }

public RenderBlockObservable RenderBlockObservable { get; }

public RenderBlockEndObservable RenderBlockEndObservable { get; }
}

Check warning on line 12 in sdk/node/Libplanet.Node/Services/Renderer/IRenderObservables.cs

View workflow job for this annotation

GitHub Actions / docs

Check warning on line 12 in sdk/node/Libplanet.Node/Services/Renderer/IRenderObservables.cs

View workflow job for this annotation

GitHub Actions / docs

Check warning on line 12 in sdk/node/Libplanet.Node/Services/Renderer/IRenderObservables.cs

View workflow job for this annotation

GitHub Actions / check-build

Check warning on line 12 in sdk/node/Libplanet.Node/Services/Renderer/IRenderObservables.cs

View workflow job for this annotation

GitHub Actions / check-build


Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Security.Cryptography;
using Bencodex.Types;
using Libplanet.Action;
using Libplanet.Blockchain.Renderers;
using Libplanet.Common;
using Libplanet.Types.Blocks;
using R3;
using Output = (
Bencodex.Types.IValue,
Libplanet.Action.ICommittedActionContext,
System.Exception);

namespace Libplanet.Node.Services.Renderer;

public class RenderActionErrorObservable : IObservable<Output>, IActionRenderer, IDisposable
{
private readonly List<IObserver<Output>> _observers = [];
private readonly BooleanDisposable _disposable = new BooleanDisposable();

public IDisposable Subscribe(IObserver<Output> observer)
{
_observers.Add(observer);
return _disposable;
}

public void RenderBlock(Block oldTip, Block newTip)
{
}

public void RenderAction(
IValue action,
ICommittedActionContext context,
HashDigest<SHA256> nextState)
{
}

public void RenderActionError(IValue action, ICommittedActionContext context, Exception exception)

Check warning on line 37 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionErrorObservable.cs

View workflow job for this annotation

GitHub Actions / docs

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

Check warning on line 37 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionErrorObservable.cs

View workflow job for this annotation

GitHub Actions / docs

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

Check warning on line 37 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionErrorObservable.cs

View workflow job for this annotation

GitHub Actions / check-build

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

Check warning on line 37 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionErrorObservable.cs

View workflow job for this annotation

GitHub Actions / check-build

Line must be no longer than 100 characters (now 102).
{
if (_disposable.IsDisposed)
{
return;
}

foreach (IObserver<Output> observer in _observers)
{
observer.OnNext((action, context, exception));
}
}

public void RenderBlockEnd(Block oldTip, Block newTip)
{
}

public void Dispose()
{
_disposable.Dispose();

foreach (IObserver<Output> observer in _observers)
{
observer.OnCompleted();
}

GC.SuppressFinalize(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Security.Cryptography;
using Bencodex.Types;
using Libplanet.Action;
using Libplanet.Blockchain.Renderers;
using Libplanet.Common;
using Libplanet.Types.Blocks;
using R3;
using Output = (
Bencodex.Types.IValue,
Libplanet.Action.ICommittedActionContext,
Libplanet.Common.HashDigest<System.Security.Cryptography.SHA256>);

namespace Libplanet.Node.Services.Renderer;

public class RenderActionObservable : IObservable<Output>, IActionRenderer, IDisposable
{
private readonly List<IObserver<Output>> _observers = [];
private readonly BooleanDisposable _disposable = new BooleanDisposable();

public IDisposable Subscribe(IObserver<Output> observer)
{
_observers.Add(observer);
return _disposable;
}

public void RenderBlock(Block oldTip, Block newTip)
{
}

public void RenderAction(
IValue action,
ICommittedActionContext context,
HashDigest<SHA256> nextState)
{
if (_disposable.IsDisposed)
{
return;
}

foreach (IObserver<Output> observer in _observers)
{
observer.OnNext((action, context, nextState));
}
}

public void RenderActionError(IValue action, ICommittedActionContext context, Exception exception)

Check warning on line 46 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionObservable.cs

View workflow job for this annotation

GitHub Actions / docs

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

Check warning on line 46 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionObservable.cs

View workflow job for this annotation

GitHub Actions / docs

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

Check warning on line 46 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionObservable.cs

View workflow job for this annotation

GitHub Actions / check-build

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

Check warning on line 46 in sdk/node/Libplanet.Node/Services/Renderer/RenderActionObservable.cs

View workflow job for this annotation

GitHub Actions / check-build

Line must be no longer than 100 characters (now 102).
{
}

public void RenderBlockEnd(Block oldTip, Block newTip)
{
}

public void Dispose()
{
_disposable.Dispose();
foreach (IObserver<Output> observer in _observers)
{
observer.OnCompleted();
}

GC.SuppressFinalize(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Security.Cryptography;
using Bencodex.Types;
using Libplanet.Action;
using Libplanet.Blockchain.Renderers;
using Libplanet.Common;
using Libplanet.Types.Blocks;
using R3;

namespace Libplanet.Node.Services.Renderer;

public class RenderBlockEndObservable : IObservable<(Block, Block)>, IActionRenderer, IDisposable
{
private readonly List<IObserver<(Block, Block)>> _observers
= new List<IObserver<(Block, Block)>>();

private readonly BooleanDisposable _disposable = new BooleanDisposable();

public IDisposable Subscribe(IObserver<(Block, Block)> observer)
{
_observers.Add(observer);
return _disposable;
}

public void RenderBlock(Block oldTip, Block newTip)
{
}

public void RenderAction(
IValue action,
ICommittedActionContext context,
HashDigest<SHA256> nextState)
{
}

public void RenderActionError(
IValue action,
ICommittedActionContext context,
Exception exception)
{
}

public void RenderBlockEnd(Block oldTip, Block newTip)
{
if (_disposable.IsDisposed)
{
return;
}

foreach (IObserver<(Block, Block)> observer in _observers)
{
observer.OnNext((oldTip, newTip));
}
}

public void Dispose()
{
_disposable.Dispose();
foreach (IObserver<(Block, Block)> observer in _observers)
{
observer.OnCompleted();
}

GC.SuppressFinalize(this);
}
}
Loading

0 comments on commit 15f8eb5

Please sign in to comment.