@@ -478,12 +478,13 @@ func (ws *workingSet) process(ctx context.Context, actions []*action.SealedEnvel
478
478
}
479
479
}
480
480
var (
481
- receipts = make ([]* action.Receipt , 0 )
482
- ctxWithBlockContext = ctx
483
- blkCtx = protocol .MustGetBlockCtx (ctx )
484
- fCtx = protocol .MustGetFeatureCtx (ctx )
481
+ receipts = make ([]* action.Receipt , 0 )
482
+ ctxWithBlockContext = ctx
483
+ blkCtx = protocol .MustGetBlockCtx (ctx )
484
+ fCtx = protocol .MustGetFeatureCtx (ctx )
485
+ userActions , systemActions = ws .splitActions (actions )
485
486
)
486
- for _ , act := range actions {
487
+ for _ , act := range userActions {
487
488
if err := ws .txValidator .ValidateWithState (ctxWithBlockContext , act ); err != nil {
488
489
return err
489
490
}
@@ -511,6 +512,21 @@ func (ws *workingSet) process(ctx context.Context, actions []*action.SealedEnvel
511
512
ctxWithBlockContext = protocol .WithBlockCtx (ctx , blkCtx )
512
513
}
513
514
}
515
+ // Handle post system actions
516
+ if err := ws .validatePostSystemActions (ctxWithBlockContext , systemActions ); err != nil {
517
+ return err
518
+ }
519
+ for _ , act := range systemActions {
520
+ actionCtx , err := withActionCtx (ctxWithBlockContext , act )
521
+ if err != nil {
522
+ return err
523
+ }
524
+ receipt , err := ws .runAction (actionCtx , act )
525
+ if err != nil {
526
+ return errors .Wrap (err , "error when run action" )
527
+ }
528
+ receipts = append (receipts , receipt )
529
+ }
514
530
if fCtx .CorrectTxLogIndex {
515
531
updateReceiptIndex (receipts )
516
532
}
@@ -598,34 +614,64 @@ func (ws *workingSet) generateSystemActions(ctx context.Context) ([]action.Envel
598
614
599
615
// validateSystemActionLayout verify whether the post system actions are appended tail
600
616
func (ws * workingSet ) validateSystemActionLayout (ctx context.Context , actions []* action.SealedEnvelope ) error {
617
+ // system actions should be at the end of the action list, and they should be continuous
618
+ hitSystemAction := false
619
+ for i := range actions {
620
+ if hitSystemAction {
621
+ if ! action .IsSystemAction (actions [i ]) {
622
+ return errors .Wrapf (errInvalidSystemActionLayout , "the %d-th action should be a system action" , i )
623
+ }
624
+ continue
625
+ } else if action .IsSystemAction (actions [i ]) {
626
+ hitSystemAction = true
627
+ }
628
+ }
629
+ return nil
630
+ }
631
+
632
+ func (ws * workingSet ) validatePostSystemActions (ctx context.Context , systemActions []* action.SealedEnvelope ) error {
601
633
postSystemActions , err := ws .generateSystemActions (ctx )
602
634
if err != nil {
603
635
return err
604
636
}
605
- // system actions should be at the end of the action list, and they should be continuous
606
- expectedStartIdx := len (actions ) - len (postSystemActions )
607
- sysActCnt := 0
608
- for i := range actions {
609
- if action .IsSystemAction (actions [i ]) {
610
- if i != expectedStartIdx + sysActCnt {
611
- return errors .Wrapf (errInvalidSystemActionLayout , "the %d-th action should not be a system action" , i )
612
- }
613
- if actions [i ].Envelope .Proto ().String () != postSystemActions [sysActCnt ].Proto ().String () {
614
- return errors .Wrapf (errInvalidSystemActionLayout , "the %d-th action is not the expected system action" , i )
637
+ if len (postSystemActions ) != len (systemActions ) {
638
+ return errors .Wrapf (errInvalidSystemActionLayout , "the number of system actions is incorrect, expected %d, got %d" , len (postSystemActions ), len (systemActions ))
639
+ }
640
+ reg := protocol .MustGetRegistry (ctx )
641
+ for i , act := range systemActions {
642
+ actionCtx , err := withActionCtx (ctx , act )
643
+ if err != nil {
644
+ return err
645
+ }
646
+ for _ , p := range reg .All () {
647
+ if validator , ok := p .(protocol.ActionValidator ); ok {
648
+ if err := validator .Validate (actionCtx , act .Envelope , ws ); err != nil {
649
+ return err
650
+ }
615
651
}
616
- sysActCnt ++
617
652
}
618
- }
619
- if sysActCnt != len ( postSystemActions ) {
620
- return errors . Wrapf ( errInvalidSystemActionLayout , "the number of system actions is incorrect, expected %d, got %d" , len ( postSystemActions ), sysActCnt )
653
+ if actual , expect := act . Envelope . Proto (). String (), postSystemActions [ i ]. Proto (). String (); actual != expect {
654
+ return errors . Wrapf ( errInvalidSystemActionLayout , "the %d-th action is not the expected system action: %v, got %v" , i , expect , actual )
655
+ }
621
656
}
622
657
return nil
623
658
}
624
659
660
+ func (ws * workingSet ) splitActions (acts []* action.SealedEnvelope ) (userActions []* action.SealedEnvelope , systemActions []* action.SealedEnvelope ) {
661
+ for _ , act := range acts {
662
+ if action .IsSystemAction (act ) {
663
+ systemActions = append (systemActions , act )
664
+ } else {
665
+ userActions = append (userActions , act )
666
+ }
667
+ }
668
+ return userActions , systemActions
669
+ }
670
+
625
671
func (ws * workingSet ) pickAndRunActions (
626
672
ctx context.Context ,
627
673
ap actpool.ActPool ,
628
- postSystemActions [] * action.SealedEnvelope ,
674
+ sign func ( elp action. Envelope ) ( * action.SealedEnvelope , error ) ,
629
675
allowedBlockGasResidue uint64 ,
630
676
) ([]* action.SealedEnvelope , error ) {
631
677
err := ws .validate (ctx )
@@ -754,6 +800,18 @@ func (ws *workingSet) pickAndRunActions(
754
800
}
755
801
}
756
802
803
+ unsignedSystemActions , err := ws .generateSystemActions (ctxWithBlockContext )
804
+ if err != nil {
805
+ return nil , err
806
+ }
807
+ postSystemActions := make ([]* action.SealedEnvelope , len (unsignedSystemActions ))
808
+ for i , elp := range unsignedSystemActions {
809
+ selp , err := sign (elp )
810
+ if err != nil {
811
+ return nil , errors .Wrapf (err , "failed to sign %+v" , elp .Action ())
812
+ }
813
+ postSystemActions [i ] = selp
814
+ }
757
815
for _ , selp := range postSystemActions {
758
816
actionCtx , err := withActionCtx (ctxWithBlockContext , selp )
759
817
if err != nil {
@@ -843,10 +901,10 @@ func (ws *workingSet) ValidateBlock(ctx context.Context, blk *block.Block) error
843
901
func (ws * workingSet ) CreateBuilder (
844
902
ctx context.Context ,
845
903
ap actpool.ActPool ,
846
- postSystemActions [] * action.SealedEnvelope ,
904
+ sign func ( elp action. Envelope ) ( * action.SealedEnvelope , error ) ,
847
905
allowedBlockGasResidue uint64 ,
848
906
) (* block.Builder , error ) {
849
- actions , err := ws .pickAndRunActions (ctx , ap , postSystemActions , allowedBlockGasResidue )
907
+ actions , err := ws .pickAndRunActions (ctx , ap , sign , allowedBlockGasResidue )
850
908
if err != nil {
851
909
return nil , err
852
910
}
0 commit comments