Skip to content

Commit e025295

Browse files
authored
Merge pull request #3701 from s2quake/exp/dpos
Introduce Begin / End block action
2 parents 96970ec + 523d937 commit e025295

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+681
-179
lines changed

CHANGES.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
11
Libplanet changelog
22
===================
33

4+
Version DPoS
5+
-------------
6+
7+
### Deprecated APIs
8+
9+
### Backward-incompatible API changes
10+
11+
- (Libplanet) Removed `IBlockPolicy.BlockAction` property. [[#3701]]
12+
- (Libplanet) Added `IBlockPolicy.BeginBlockActions`. property. [[#3701]]
13+
- (Libplanet) Added `IBlockPolicy.EndBlockActions`. property. [[#3701]]
14+
- (Libplanet) `BlockPolicy` constructor requires `beginBlockActions` and
15+
`endBlockActions` parameters instead of the `blockAction` parameter.
16+
[[#3701]]
17+
- (Libplanet.Action) Renamed `PolicyBlockActionGetter` delegate to
18+
`PolicyBlockActionGetter` and changed return type to
19+
`ImmutableArray<IAction>`. [[#3701]]
20+
- (Libplanet.Action) `ActionEvaluator` constructor requires
21+
`policyBeginBlockActionGetter` and `policyEndBlockActionGetter`
22+
parameters instead of the `policyBlockActionGetter` parameter. [[#3701]]
23+
24+
### Backward-incompatible network protocol changes
25+
26+
### Backward-incompatible storage format changes
27+
28+
### Added APIs
29+
30+
### Behavioral changes
31+
32+
### Bug fixes
33+
34+
### Dependencies
35+
36+
### CLI tools
37+
38+
[#3701]: https://github.com/planetarium/libplanet/pull/3701
39+
40+
441
Version 4.1.0
542
-------------
643

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Bencodex.Types;
2+
using Libplanet.Action.State;
3+
using Libplanet.Crypto;
4+
5+
namespace Libplanet.Action.Tests.Common
6+
{
7+
public sealed class UpdateValueAction : IAction
8+
{
9+
public static readonly Address ValueAddress =
10+
new Address("0000000000000000000000000000000000000123");
11+
12+
public UpdateValueAction()
13+
{
14+
}
15+
16+
public UpdateValueAction(int increment)
17+
{
18+
Increment = increment;
19+
}
20+
21+
public int Increment { get; set; }
22+
23+
public IValue PlainValue => Bencodex.Types.Dictionary.Empty
24+
.Add("value", new Bencodex.Types.Integer(Increment));
25+
26+
public void LoadPlainValue(IValue plainValue)
27+
{
28+
Increment = (int)(Bencodex.Types.Integer)((Dictionary)plainValue)["value"];
29+
}
30+
31+
public IWorld Execute(IActionContext ctx)
32+
{
33+
IWorld states = ctx.PreviousState;
34+
IAccount account = states.GetAccount(ReservedAddresses.LegacyAccount);
35+
int value = 0;
36+
int increment = Increment;
37+
38+
if (account.GetState(ValueAddress) is Integer integer)
39+
{
40+
value = (int)integer.Value + increment;
41+
}
42+
43+
account = account.SetState(ValueAddress, new Integer(value));
44+
return states.SetAccount(ReservedAddresses.LegacyAccount, account);
45+
}
46+
}
47+
}

Libplanet.Action/ActionEvaluator.cs

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,37 @@ namespace Libplanet.Action
2626
public class ActionEvaluator : IActionEvaluator
2727
{
2828
private readonly ILogger _logger;
29-
private readonly PolicyBlockActionGetter _policyBlockActionGetter;
29+
private readonly PolicyBlockActionsGetter _policyBeginBlockActionsGetter;
30+
private readonly PolicyBlockActionsGetter _policyEndBlockActionsGetter;
3031
private readonly IStateStore _stateStore;
3132
private readonly IActionLoader _actionLoader;
3233

3334
/// <summary>
3435
/// Creates a new <see cref="ActionEvaluator"/>.
3536
/// </summary>
36-
/// <param name="policyBlockActionGetter">A delegator to get policy block action to evaluate
37-
/// at the end for each <see cref="IPreEvaluationBlock"/> that gets evaluated.</param>
37+
/// <param name="policyBeginBlockActionsGetter">A delegator to get policy block actions to
38+
/// evaluate at the beginning for each <see cref="IPreEvaluationBlock"/>
39+
/// that gets evaluated.
40+
/// Note the order of the returned list determines the execution order.
41+
/// </param>
42+
/// <param name="policyEndBlockActionsGetter">A delegator to get policy block actions to
43+
/// evaluate at the end for each <see cref="IPreEvaluationBlock"/> that gets evaluated.
44+
/// Note the order of the returned list determines the execution order.
45+
/// </param>
3846
/// <param name="stateStore">The <see cref="IStateStore"/> to use to retrieve
3947
/// the states for a provided <see cref="HashDigest{SHA256}"/>.</param>
4048
/// <param name="actionTypeLoader"> A <see cref="IActionLoader"/> implementation using
4149
/// action type lookup.</param>
4250
public ActionEvaluator(
43-
PolicyBlockActionGetter policyBlockActionGetter,
51+
PolicyBlockActionsGetter policyBeginBlockActionsGetter,
52+
PolicyBlockActionsGetter policyEndBlockActionsGetter,
4453
IStateStore stateStore,
4554
IActionLoader actionTypeLoader)
4655
{
4756
_logger = Log.ForContext<ActionEvaluator>()
4857
.ForContext("Source", nameof(ActionEvaluator));
49-
_policyBlockActionGetter = policyBlockActionGetter;
58+
_policyBeginBlockActionsGetter = policyBeginBlockActionsGetter;
59+
_policyEndBlockActionsGetter = policyEndBlockActionsGetter;
5060
_stateStore = stateStore;
5161
_actionLoader = actionTypeLoader;
5262
}
@@ -123,16 +133,29 @@ public IReadOnlyList<ICommittedActionEvaluation> Evaluate(
123133
throw new ApplicationException("World cannot be mutated from modern to legacy");
124134
}
125135

126-
ImmutableList<ActionEvaluation> evaluations =
127-
EvaluateBlock(block, previousState).ToImmutableList();
136+
var evaluations = ImmutableList<ActionEvaluation>.Empty;
137+
if (_policyBeginBlockActionsGetter(block) is { } beginBlockActions &&
138+
beginBlockActions.Length > 0)
139+
{
140+
evaluations = evaluations.AddRange(EvaluatePolicyBeginBlockActions(
141+
block, previousState
142+
));
143+
previousState = evaluations.Last().OutputState;
144+
}
145+
146+
evaluations = evaluations.AddRange(
147+
EvaluateBlock(block, previousState).ToImmutableList()
148+
);
128149

129-
var policyBlockAction = _policyBlockActionGetter(block);
130-
if (policyBlockAction is { } blockAction)
150+
if (_policyEndBlockActionsGetter(block) is { } endBlockActions &&
151+
endBlockActions.Length > 0)
131152
{
132153
previousState = evaluations.Count > 0
133154
? evaluations.Last().OutputState
134155
: previousState;
135-
evaluations = evaluations.Add(EvaluatePolicyBlockAction(block, previousState));
156+
evaluations = evaluations.AddRange(EvaluatePolicyEndBlockActions(
157+
block, previousState
158+
));
136159
}
137160

138161
var committed = ToCommittedEvaluation(block, evaluations, baseStateRootHash);
@@ -491,30 +514,50 @@ internal IEnumerable<ActionEvaluation> EvaluateTx(
491514
/// the <see cref="IBlockPolicy.BlockAction"/> held by the instance
492515
/// for the <paramref name="blockHeader"/>.</returns>
493516
[Pure]
494-
internal ActionEvaluation EvaluatePolicyBlockAction(
517+
internal ActionEvaluation[] EvaluatePolicyBeginBlockActions(
495518
IPreEvaluationBlockHeader blockHeader,
496519
IWorld previousState)
497520
{
498-
var policyBlockAction = _policyBlockActionGetter(blockHeader);
499-
if (policyBlockAction is null)
500-
{
501-
var message =
502-
"To evaluate policy block action, " +
503-
"policyBlockAction must not be null.";
504-
throw new InvalidOperationException(message);
505-
}
521+
_logger.Information(
522+
$"Evaluating policy begin block actions for block #{blockHeader.Index} " +
523+
$"{ByteUtil.Hex(blockHeader.PreEvaluationHash.ByteArray)}");
524+
525+
return EvaluateActions(
526+
blockHeader: blockHeader,
527+
tx: null,
528+
previousState: previousState,
529+
actions: _policyBeginBlockActionsGetter(blockHeader),
530+
stateStore: _stateStore,
531+
logger: _logger).ToArray();
532+
}
506533

534+
/// <summary>
535+
/// Evaluates the <see cref="IBlockPolicy.BlockAction"/> set by the policy when
536+
/// this <see cref="ActionEvaluator"/> was instantiated for a given
537+
/// <see cref="IPreEvaluationBlockHeader"/>.
538+
/// </summary>
539+
/// <param name="blockHeader">The header of the block to evaluate.</param>
540+
/// <param name="previousState">The states immediately before the evaluation of
541+
/// the <see cref="IBlockPolicy.BlockAction"/> held by the instance.</param>
542+
/// <returns>The <see cref="ActionEvaluation"/> of evaluating
543+
/// the <see cref="IBlockPolicy.BlockAction"/> held by the instance
544+
/// for the <paramref name="blockHeader"/>.</returns>
545+
[Pure]
546+
internal ActionEvaluation[] EvaluatePolicyEndBlockActions(
547+
IPreEvaluationBlockHeader blockHeader,
548+
IWorld previousState)
549+
{
507550
_logger.Information(
508-
$"Evaluating policy block action for block #{blockHeader.Index} " +
551+
$"Evaluating policy end block actions for block #{blockHeader.Index} " +
509552
$"{ByteUtil.Hex(blockHeader.PreEvaluationHash.ByteArray)}");
510553

511554
return EvaluateActions(
512555
blockHeader: blockHeader,
513556
tx: null,
514557
previousState: previousState,
515-
actions: new[] { policyBlockAction }.ToImmutableList(),
558+
actions: _policyEndBlockActionsGetter(blockHeader),
516559
stateStore: _stateStore,
517-
logger: _logger).Single();
560+
logger: _logger).ToArray();
518561
}
519562

520563
internal IWorld PrepareInitialDelta(HashDigest<SHA256>? stateRootHash)

Libplanet.Action/PolicyBlockActionGetter.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Collections.Immutable;
2+
using Libplanet.Types.Blocks;
3+
4+
namespace Libplanet.Action
5+
{
6+
public delegate ImmutableArray<IAction> PolicyBlockActionsGetter(
7+
IPreEvaluationBlockHeader blockHeader
8+
);
9+
}

Libplanet.Benchmarks/AppendBlock.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Libplanet.Types.Blocks;
99
using Libplanet.Tests;
1010
using Libplanet.Tests.Store;
11+
using System.Collections.Immutable;
1112

1213
namespace Libplanet.Benchmarks
1314
{
@@ -29,7 +30,8 @@ public AppendBlock()
2930
fx.StateStore,
3031
fx.GenesisBlock,
3132
new ActionEvaluator(
32-
policyBlockActionGetter: _ => null,
33+
policyBeginBlockActionsGetter: _ => ImmutableArray<IAction>.Empty,
34+
policyEndBlockActionsGetter: _ => ImmutableArray<IAction>.Empty,
3335
stateStore: fx.StateStore,
3436
actionTypeLoader: new SingleActionLoader(typeof(DumbAction))));
3537
_privateKey = new PrivateKey();

Libplanet.Benchmarks/BlockChain.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Immutable;
12
using BenchmarkDotNet.Attributes;
23
using Libplanet.Action;
34
using Libplanet.Action.Loader;
@@ -35,7 +36,8 @@ public void SetupChain()
3536
_fx.StateStore,
3637
_fx.GenesisBlock,
3738
new ActionEvaluator(
38-
policyBlockActionGetter: _ => null,
39+
policyBeginBlockActionsGetter: _ => ImmutableArray<IAction>.Empty,
40+
policyEndBlockActionsGetter: _ => ImmutableArray<IAction>.Empty,
3941
stateStore: _fx.StateStore,
4042
actionTypeLoader: new SingleActionLoader(typeof(DumbAction))));
4143
var key = new PrivateKey();

Libplanet.Benchmarks/ProposeBlock.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Libplanet.Types.Blocks;
99
using Libplanet.Tests;
1010
using Libplanet.Tests.Store;
11+
using System.Collections.Immutable;
1112

1213
namespace Libplanet.Benchmarks
1314
{
@@ -28,7 +29,8 @@ public ProposeBlock()
2829
fx.StateStore,
2930
fx.GenesisBlock,
3031
new ActionEvaluator(
31-
policyBlockActionGetter: _ => null,
32+
policyBeginBlockActionsGetter: _ => ImmutableArray<IAction>.Empty,
33+
policyEndBlockActionsGetter: _ => ImmutableArray<IAction>.Empty,
3234
stateStore: fx.StateStore,
3335
actionTypeLoader: new SingleActionLoader(typeof(DumbAction))));
3436
_privateKey = new PrivateKey();

Libplanet.Explorer.Executable/Program.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ If omitted (default) explorer only the local blockchain store.")]
200200
options.GetGenesisBlock(policy),
201201
blockChainStates,
202202
new ActionEvaluator(
203-
_ => policy.BlockAction,
203+
_ => policy.BeginBlockActions,
204+
_ => policy.EndBlockActions,
204205
stateStore,
205206
new SingleActionLoader(typeof(NullAction))));
206207
Startup.PreloadedSingleton = false;
@@ -341,7 +342,8 @@ private static IStore LoadStore(Options options)
341342
private static BlockPolicy LoadBlockPolicy(Options options)
342343
{
343344
return new BlockPolicy(
344-
blockAction: null,
345+
beginBlockActions: ImmutableArray<IAction>.Empty,
346+
endBlockActions: ImmutableArray<IAction>.Empty,
345347
blockInterval: TimeSpan.FromMilliseconds(options.BlockIntervalMilliseconds),
346348
getMaxTransactionsBytes: i => i > 0
347349
? options.MaxTransactionsBytes
@@ -384,7 +386,9 @@ public DumbBlockPolicy(BlockPolicy blockPolicy)
384386
_impl = blockPolicy;
385387
}
386388

387-
public IAction BlockAction => _impl.BlockAction;
389+
public ImmutableArray<IAction> BeginBlockActions => _impl.BeginBlockActions;
390+
391+
public ImmutableArray<IAction> EndBlockActions => _impl.EndBlockActions;
388392

389393
public int GetMinTransactionsPerBlock(long index) =>
390394
_impl.GetMinTransactionsPerBlock(index);

Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ public GeneratedBlockChainFixture(
7171
getMaxTransactionsPerBlock: _ => int.MaxValue,
7272
getMaxTransactionsBytes: _ => long.MaxValue);
7373
var actionEvaluator = new ActionEvaluator(
74-
_ => policy.BlockAction,
74+
_ => policy.BeginBlockActions,
75+
_ => policy.EndBlockActions,
7576
stateStore,
7677
TypedActionLoader.Create(typeof(SimpleAction).Assembly, typeof(SimpleAction)));
7778
Block genesisBlock = BlockChain.ProposeGenesisBlock(

0 commit comments

Comments
 (0)