@@ -478,12 +478,13 @@ func (ws *workingSet) process(ctx context.Context, actions []*action.SealedEnvel
478478 }
479479 }
480480 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 )
485486 )
486- for _ , act := range actions {
487+ for _ , act := range userActions {
487488 if err := ws .txValidator .ValidateWithState (ctxWithBlockContext , act ); err != nil {
488489 return err
489490 }
@@ -511,6 +512,21 @@ func (ws *workingSet) process(ctx context.Context, actions []*action.SealedEnvel
511512 ctxWithBlockContext = protocol .WithBlockCtx (ctx , blkCtx )
512513 }
513514 }
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+ }
514530 if fCtx .CorrectTxLogIndex {
515531 updateReceiptIndex (receipts )
516532 }
@@ -598,34 +614,64 @@ func (ws *workingSet) generateSystemActions(ctx context.Context) ([]action.Envel
598614
599615// validateSystemActionLayout verify whether the post system actions are appended tail
600616func (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 {
601633 postSystemActions , err := ws .generateSystemActions (ctx )
602634 if err != nil {
603635 return err
604636 }
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+ }
615651 }
616- sysActCnt ++
617652 }
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+ }
621656 }
622657 return nil
623658}
624659
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+
625671func (ws * workingSet ) pickAndRunActions (
626672 ctx context.Context ,
627673 ap actpool.ActPool ,
628- postSystemActions [] * action.SealedEnvelope ,
674+ sign func ( elp action. Envelope ) ( * action.SealedEnvelope , error ) ,
629675 allowedBlockGasResidue uint64 ,
630676) ([]* action.SealedEnvelope , error ) {
631677 err := ws .validate (ctx )
@@ -754,6 +800,18 @@ func (ws *workingSet) pickAndRunActions(
754800 }
755801 }
756802
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+ }
757815 for _ , selp := range postSystemActions {
758816 actionCtx , err := withActionCtx (ctxWithBlockContext , selp )
759817 if err != nil {
@@ -843,10 +901,10 @@ func (ws *workingSet) ValidateBlock(ctx context.Context, blk *block.Block) error
843901func (ws * workingSet ) CreateBuilder (
844902 ctx context.Context ,
845903 ap actpool.ActPool ,
846- postSystemActions [] * action.SealedEnvelope ,
904+ sign func ( elp action. Envelope ) ( * action.SealedEnvelope , error ) ,
847905 allowedBlockGasResidue uint64 ,
848906) (* block.Builder , error ) {
849- actions , err := ws .pickAndRunActions (ctx , ap , postSystemActions , allowedBlockGasResidue )
907+ actions , err := ws .pickAndRunActions (ctx , ap , sign , allowedBlockGasResidue )
850908 if err != nil {
851909 return nil , err
852910 }
0 commit comments