Skip to content

Commit 07cb4a1

Browse files
authored
generate and validate system action behind (#4606)
1 parent 355e388 commit 07cb4a1

File tree

3 files changed

+93
-44
lines changed

3 files changed

+93
-44
lines changed

state/factory/statedb.go

+1-13
Original file line numberDiff line numberDiff line change
@@ -279,22 +279,10 @@ func (sdb *stateDB) Mint(
279279
if err != nil {
280280
return nil, err
281281
}
282-
postSystemActions := make([]*action.SealedEnvelope, 0)
283-
unsignedSystemActions, err := ws.generateSystemActions(ctx)
284-
if err != nil {
285-
return nil, err
286-
}
287282
sign := func(elp action.Envelope) (*action.SealedEnvelope, error) {
288283
return action.Sign(elp, pk)
289284
}
290-
for _, elp := range unsignedSystemActions {
291-
se, err := sign(elp)
292-
if err != nil {
293-
return nil, err
294-
}
295-
postSystemActions = append(postSystemActions, se)
296-
}
297-
blkBuilder, err := ws.CreateBuilder(ctx, ap, postSystemActions, sdb.cfg.Chain.AllowedBlockGasResidue)
285+
blkBuilder, err := ws.CreateBuilder(ctx, ap, sign, sdb.cfg.Chain.AllowedBlockGasResidue)
298286
if err != nil {
299287
return nil, err
300288
}

state/factory/workingset.go

+80-22
Original file line numberDiff line numberDiff line change
@@ -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
600616
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 {
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+
625671
func (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
843901
func (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
}

state/factory/workingset_test.go

+12-9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/iotexproject/iotex-core/v2/blockchain/block"
2424
"github.com/iotexproject/iotex-core/v2/blockchain/genesis"
2525
"github.com/iotexproject/iotex-core/v2/db"
26+
"github.com/iotexproject/iotex-core/v2/pkg/unit"
2627
"github.com/iotexproject/iotex-core/v2/test/identityset"
2728
"github.com/iotexproject/iotex-core/v2/testutil"
2829
)
@@ -188,7 +189,8 @@ func TestWorkingSet_ValidateBlock_SystemAction(t *testing.T) {
188189
Chain: blockchain.DefaultConfig,
189190
Genesis: genesis.TestDefault(),
190191
}
191-
cfg.Genesis.QuebecBlockHeight = 1 // enable validate system action
192+
cfg.Genesis.VanuatuBlockHeight = 1 // enable validate system action
193+
testutil.NormalizeGenesisHeights(&cfg.Genesis.Blockchain)
192194
cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100000000"
193195
registry := protocol.NewRegistry()
194196
require.NoError(account.NewProtocol(rewarding.DepositGas).Register(registry))
@@ -221,7 +223,7 @@ func TestWorkingSet_ValidateBlock_SystemAction(t *testing.T) {
221223
require.NoError(err)
222224
receiptRoot, err := hash.HexStringToHash256("f04673451e31386a8fddfcf7750665bfcf33f239f6c4919430bb11a144e1aa95")
223225
require.NoError(err)
224-
actions := []*action.SealedEnvelope{makeTransferAction(t, 1)}
226+
actions := []*action.SealedEnvelope{makeTransferAction(t, 0)}
225227
for _, f := range factories {
226228
block := makeBlock(t, hash.ZeroHash256, receiptRoot, digestHash, actions...)
227229
require.ErrorIs(f.Validate(zctx, block), errInvalidSystemActionLayout)
@@ -232,18 +234,18 @@ func TestWorkingSet_ValidateBlock_SystemAction(t *testing.T) {
232234
require.NoError(err)
233235
receiptRoot, err := hash.HexStringToHash256("f04673451e31386a8fddfcf7750665bfcf33f239f6c4919430bb11a144e1aa95")
234236
require.NoError(err)
235-
actions := []*action.SealedEnvelope{makeRewardAction(t, 28), makeTransferAction(t, 1)}
237+
actions := []*action.SealedEnvelope{makeRewardAction(t, 28), makeTransferAction(t, 0)}
236238
for _, f := range factories {
237239
block := makeBlock(t, hash.ZeroHash256, receiptRoot, digestHash, actions...)
238240
require.ErrorIs(f.Validate(zctx, block), errInvalidSystemActionLayout)
239241
}
240242
})
241243
t.Run("correct system action", func(t *testing.T) {
242-
digestHash, err := hash.HexStringToHash256("ade24a5c647b5af34c4e74fe0d8f1fa410f6fb115f8fc2d39e45ca2f895de9ca")
244+
digestHash, err := hash.HexStringToHash256("da051302d6e0b433d54225892789ce24dd634b1c17a6fa443a8a8cab27e2c586")
243245
require.NoError(err)
244-
receiptRoot, err := hash.HexStringToHash256("a59bd06fe4d2bb537895f170dec1f9213045cb13480e4941f1abdc8d13b16fae")
246+
receiptRoot, err := hash.HexStringToHash256("afd544c5cf1b4b88216504a3b08d535314470adf6e45c68f9d0bb9e5c3699948")
245247
require.NoError(err)
246-
actions := []*action.SealedEnvelope{makeTransferAction(t, 1), makeRewardAction(t, 28)}
248+
actions := []*action.SealedEnvelope{makeTransferAction(t, 0), makeRewardAction(t, 28)}
247249
for _, f := range factories {
248250
block := makeBlock(t, hash.ZeroHash256, receiptRoot, digestHash, actions...)
249251
require.ErrorIs(f.Validate(zctx, block), nil)
@@ -254,7 +256,7 @@ func TestWorkingSet_ValidateBlock_SystemAction(t *testing.T) {
254256
require.NoError(err)
255257
receiptRoot, err := hash.HexStringToHash256("a59bd06fe4d2bb537895f170dec1f9213045cb13480e4941f1abdc8d13b16fae")
256258
require.NoError(err)
257-
actions := []*action.SealedEnvelope{makeTransferAction(t, 1), makeRewardAction(t, 27)}
259+
actions := []*action.SealedEnvelope{makeTransferAction(t, 0), makeRewardAction(t, 27)}
258260
for _, f := range factories {
259261
block := makeBlock(t, hash.ZeroHash256, receiptRoot, digestHash, actions...)
260262
require.ErrorContains(f.Validate(zctx, block), "Only producer could create reward")
@@ -265,7 +267,7 @@ func TestWorkingSet_ValidateBlock_SystemAction(t *testing.T) {
265267
require.NoError(err)
266268
receiptRoot, err := hash.HexStringToHash256("a59bd06fe4d2bb537895f170dec1f9213045cb13480e4941f1abdc8d13b16fae")
267269
require.NoError(err)
268-
actions := []*action.SealedEnvelope{makeTransferAction(t, 1), makeRewardAction(t, 28), makeRewardAction(t, 28)}
270+
actions := []*action.SealedEnvelope{makeTransferAction(t, 0), makeRewardAction(t, 28), makeRewardAction(t, 28)}
269271
for _, f := range factories {
270272
block := makeBlock(t, hash.ZeroHash256, receiptRoot, digestHash, actions...)
271273
require.ErrorIs(f.Validate(zctx, block), errInvalidSystemActionLayout)
@@ -278,7 +280,7 @@ func TestWorkingSet_ValidateBlock_SystemAction(t *testing.T) {
278280
require.NoError(err)
279281
rewardAct := makeRewardAction(t, 28)
280282
rewardAct.SetNonce(2)
281-
actions := []*action.SealedEnvelope{makeTransferAction(t, 1), rewardAct}
283+
actions := []*action.SealedEnvelope{makeTransferAction(t, 0), rewardAct}
282284
for _, f := range factories {
283285
block := makeBlock(t, hash.ZeroHash256, receiptRoot, digestHash, actions...)
284286
require.ErrorIs(f.Validate(zctx, block), errInvalidSystemActionLayout)
@@ -320,6 +322,7 @@ func makeBlock(t *testing.T, prevHash hash.Hash256, receiptRoot hash.Hash256, di
320322
SetReceiptRoot(receiptRoot).
321323
SetDeltaStateDigest(digest).
322324
SetPrevBlockHash(prevHash).
325+
SetBaseFee(big.NewInt(unit.Qev)).
323326
SignAndBuild(identityset.PrivateKey(0))
324327
require.NoError(t, err)
325328
return &blk

0 commit comments

Comments
 (0)