@@ -26,27 +26,34 @@ namespace Libplanet.Action
26
26
public class ActionEvaluator : IActionEvaluator
27
27
{
28
28
private readonly ILogger _logger ;
29
- private readonly PolicyBlockActionGetter _policyBlockActionGetter ;
29
+ private readonly PolicyBlockActionGetter _policyBeginBlockActionGetter ;
30
+ private readonly PolicyBlockActionGetter _policyEndBlockActionGetter ;
30
31
private readonly IStateStore _stateStore ;
31
32
private readonly IActionLoader _actionLoader ;
32
33
33
34
/// <summary>
34
35
/// Creates a new <see cref="ActionEvaluator"/>.
35
36
/// </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="policyBeginBlockActionGetter">A delegator to get policy block actions to
38
+ /// evaluate at the beginning for each <see cref="IPreEvaluationBlock"/>
39
+ /// that gets evaluated.</param>
40
+ /// <param name="policyEndBlockActionGetter">A delegator to get policy block actions to
41
+ /// evaluate at the end for each <see cref="IPreEvaluationBlock"/> that gets evaluated.
42
+ /// </param>
38
43
/// <param name="stateStore">The <see cref="IStateStore"/> to use to retrieve
39
44
/// the states for a provided <see cref="HashDigest{SHA256}"/>.</param>
40
45
/// <param name="actionTypeLoader"> A <see cref="IActionLoader"/> implementation using
41
46
/// action type lookup.</param>
42
47
public ActionEvaluator (
43
- PolicyBlockActionGetter policyBlockActionGetter ,
48
+ PolicyBlockActionGetter policyBeginBlockActionGetter ,
49
+ PolicyBlockActionGetter policyEndBlockActionGetter ,
44
50
IStateStore stateStore ,
45
51
IActionLoader actionTypeLoader )
46
52
{
47
53
_logger = Log . ForContext < ActionEvaluator > ( )
48
54
. ForContext ( "Source" , nameof ( ActionEvaluator ) ) ;
49
- _policyBlockActionGetter = policyBlockActionGetter ;
55
+ _policyBeginBlockActionGetter = policyBeginBlockActionGetter ;
56
+ _policyEndBlockActionGetter = policyEndBlockActionGetter ;
50
57
_stateStore = stateStore ;
51
58
_actionLoader = actionTypeLoader ;
52
59
}
@@ -123,16 +130,29 @@ public IReadOnlyList<ICommittedActionEvaluation> Evaluate(
123
130
throw new ApplicationException ( "World cannot be mutated from modern to legacy" ) ;
124
131
}
125
132
126
- ImmutableList < ActionEvaluation > evaluations =
127
- EvaluateBlock ( block , previousState ) . ToImmutableList ( ) ;
133
+ var evaluations = ImmutableList < ActionEvaluation > . Empty ;
134
+ if ( _policyBeginBlockActionGetter ( block ) is { } beginBlockActions &&
135
+ beginBlockActions . Length > 0 )
136
+ {
137
+ evaluations = evaluations . AddRange ( EvaluatePolicyBeginBlockActions (
138
+ block , previousState
139
+ ) ) ;
140
+ previousState = evaluations . Last ( ) . OutputState ;
141
+ }
142
+
143
+ evaluations = evaluations . AddRange (
144
+ EvaluateBlock ( block , previousState ) . ToImmutableList ( )
145
+ ) ;
128
146
129
- var policyBlockAction = _policyBlockActionGetter ( block ) ;
130
- if ( policyBlockAction is { } blockAction )
147
+ if ( _policyEndBlockActionGetter ( block ) is { } endBlockActions &&
148
+ endBlockActions . Length > 0 )
131
149
{
132
150
previousState = evaluations . Count > 0
133
151
? evaluations . Last ( ) . OutputState
134
152
: previousState ;
135
- evaluations = evaluations . Add ( EvaluatePolicyBlockAction ( block , previousState ) ) ;
153
+ evaluations = evaluations . AddRange ( EvaluatePolicyEndBlockActions (
154
+ block , previousState
155
+ ) ) ;
136
156
}
137
157
138
158
var committed = ToCommittedEvaluation ( block , evaluations , baseStateRootHash ) ;
@@ -491,30 +511,50 @@ internal IEnumerable<ActionEvaluation> EvaluateTx(
491
511
/// the <see cref="IBlockPolicy.BlockAction"/> held by the instance
492
512
/// for the <paramref name="blockHeader"/>.</returns>
493
513
[ Pure ]
494
- internal ActionEvaluation EvaluatePolicyBlockAction (
514
+ internal ActionEvaluation [ ] EvaluatePolicyBeginBlockActions (
495
515
IPreEvaluationBlockHeader blockHeader ,
496
516
IWorld previousState )
497
517
{
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
- }
518
+ _logger . Information (
519
+ $ "Evaluating policy begin block actions for block #{ blockHeader . Index } " +
520
+ $ "{ ByteUtil . Hex ( blockHeader . PreEvaluationHash . ByteArray ) } ") ;
521
+
522
+ return EvaluateActions (
523
+ blockHeader : blockHeader ,
524
+ tx : null ,
525
+ previousState : previousState ,
526
+ actions : _policyBeginBlockActionGetter ( blockHeader ) ,
527
+ stateStore : _stateStore ,
528
+ logger : _logger ) . ToArray ( ) ;
529
+ }
506
530
531
+ /// <summary>
532
+ /// Evaluates the <see cref="IBlockPolicy.BlockAction"/> set by the policy when
533
+ /// this <see cref="ActionEvaluator"/> was instantiated for a given
534
+ /// <see cref="IPreEvaluationBlockHeader"/>.
535
+ /// </summary>
536
+ /// <param name="blockHeader">The header of the block to evaluate.</param>
537
+ /// <param name="previousState">The states immediately before the evaluation of
538
+ /// the <see cref="IBlockPolicy.BlockAction"/> held by the instance.</param>
539
+ /// <returns>The <see cref="ActionEvaluation"/> of evaluating
540
+ /// the <see cref="IBlockPolicy.BlockAction"/> held by the instance
541
+ /// for the <paramref name="blockHeader"/>.</returns>
542
+ [ Pure ]
543
+ internal ActionEvaluation [ ] EvaluatePolicyEndBlockActions (
544
+ IPreEvaluationBlockHeader blockHeader ,
545
+ IWorld previousState )
546
+ {
507
547
_logger . Information (
508
- $ "Evaluating policy block action for block #{ blockHeader . Index } " +
548
+ $ "Evaluating policy end block actions for block #{ blockHeader . Index } " +
509
549
$ "{ ByteUtil . Hex ( blockHeader . PreEvaluationHash . ByteArray ) } ") ;
510
550
511
551
return EvaluateActions (
512
552
blockHeader : blockHeader ,
513
553
tx : null ,
514
554
previousState : previousState ,
515
- actions : new [ ] { policyBlockAction } . ToImmutableList ( ) ,
555
+ actions : _policyEndBlockActionGetter ( blockHeader ) ,
516
556
stateStore : _stateStore ,
517
- logger : _logger ) . Single ( ) ;
557
+ logger : _logger ) . ToArray ( ) ;
518
558
}
519
559
520
560
internal IWorld PrepareInitialDelta ( HashDigest < SHA256 > ? stateRootHash )
0 commit comments