From 5338daa5e2b226719549bd6b5fec13f7dfc85ba1 Mon Sep 17 00:00:00 2001 From: Sergi Rene Date: Mon, 18 Mar 2024 16:19:17 +0100 Subject: [PATCH] revert invariant improved --- testutil/keeper/delayedack.go | 3 + x/delayedack/keeper/invariants.go | 47 +++---- x/delayedack/keeper/invariants_test.go | 119 ++++++++++++++++++ x/delayedack/types/expected_keepers.go | 1 + .../block_height_to_finalization_queue.go | 1 + 5 files changed, 144 insertions(+), 27 deletions(-) diff --git a/testutil/keeper/delayedack.go b/testutil/keeper/delayedack.go index f1a7cde84..7bea7f8f6 100644 --- a/testutil/keeper/delayedack.go +++ b/testutil/keeper/delayedack.go @@ -103,6 +103,9 @@ func (RollappKeeperStub) GetLatestStateInfoIndex(ctx sdk.Context, rollappId stri func (RollappKeeperStub) GetLatestFinalizedStateIndex(ctx sdk.Context, rollappId string) (val rollapptypes.StateInfoIndex, found bool) { return rollapptypes.StateInfoIndex{}, false } +func (RollappKeeperStub) GetAllRollapps(ctx sdk.Context) (list []rollapptypes.Rollapp) { + return []rollapptypes.Rollapp{} +} type SequencerKeeperStub struct{} diff --git a/x/delayedack/keeper/invariants.go b/x/delayedack/keeper/invariants.go index 58663e98e..1bd83bc13 100644 --- a/x/delayedack/keeper/invariants.go +++ b/x/delayedack/keeper/invariants.go @@ -40,7 +40,6 @@ func RollappFinalizedPackets(k Keeper) sdk.Invariant { packets := k.GetAllRollappPackets(ctx) for _, packet := range packets { - latestFinalizedStateIndex, found := k.rollappKeeper.GetLatestFinalizedStateIndex(ctx, packet.RollappId) if !found { msg += fmt.Sprintf("unable to find latest finalized state index for rollapp %s\n", packet.RollappId) @@ -69,42 +68,36 @@ func RollappRevertedPackets(k Keeper) sdk.Invariant { msg string ) - packets := k.GetAllRollappPackets(ctx) - - for _, packet := range packets { + rollapps := k.rollappKeeper.GetAllRollapps(ctx) - latestFinalizedStateIndex, found := k.rollappKeeper.GetLatestFinalizedStateIndex(ctx, packet.RollappId) - if !found { - msg += fmt.Sprintf("unable to find latest finalized state index for rollapp %s\n", packet.RollappId) - broken = true - } - latestFinalizedStateInfo, found := k.rollappKeeper.GetStateInfo(ctx, packet.RollappId, latestFinalizedStateIndex.Index) + for _, rollapp := range rollapps { + latestFinalizedStateIndex, found := k.rollappKeeper.GetLatestFinalizedStateIndex(ctx, rollapp.RollappId) if !found { - msg += fmt.Sprintf("unable to find latest finalized state info for rollapp %s\n", packet.RollappId) - broken = true + continue } - latestFinalizedHeight := latestFinalizedStateInfo.StartHeight + latestFinalizedStateInfo.NumBlocks - 1 - if packet.ProofHeight > latestFinalizedHeight { - stateInfoIndex := latestFinalizedStateIndex.Index + 1 - for { - stateInfoToCheck, found := k.rollappKeeper.GetStateInfo(ctx, packet.RollappId, stateInfoIndex) - if found { - if stateInfoToCheck.Status == commontypes.Status_REVERTED { - if stateInfoToCheck.StartHeight >= packet.ProofHeight && stateInfoToCheck.StartHeight+stateInfoToCheck.NumBlocks < packet.ProofHeight { - if packet.Status != commontypes.Status_REVERTED { - msg += fmt.Sprintf("rollapp packet for height %d from rollapp %s should be in finalized status, but is in %s status\n", packet.ProofHeight, packet.RollappId, packet.Status) + + stateInfoIndex := latestFinalizedStateIndex.Index + 1 + //Checking that all packets after the latest finalized height, that belong to a reverted state info, are also in reverted state + for { + stateInfoToCheck, found := k.rollappKeeper.GetStateInfo(ctx, rollapp.RollappId, stateInfoIndex) + if found { + if stateInfoToCheck.Status == commontypes.Status_REVERTED { + //TODO (srene) add GetRollappPacketByRollap to be more efficient + for _, packet := range k.GetAllRollappPackets(ctx) { + if packet.RollappId == rollapp.RollappId { + if packet.ProofHeight >= stateInfoToCheck.StartHeight && packet.ProofHeight < stateInfoToCheck.StartHeight+stateInfoToCheck.NumBlocks && packet.Status != commontypes.Status_REVERTED { + msg += fmt.Sprintf("rollapp packet for height %d from rollapp %s should be in reverted status, but is in %s status\n", packet.ProofHeight, packet.RollappId, packet.Status) broken = true - break } } } - } else { - break } - stateInfoIndex++ + } else { + break } - + stateInfoIndex++ } + } return msg, broken } diff --git a/x/delayedack/keeper/invariants_test.go b/x/delayedack/keeper/invariants_test.go index f040cdfb5..283367d27 100644 --- a/x/delayedack/keeper/invariants_test.go +++ b/x/delayedack/keeper/invariants_test.go @@ -70,7 +70,126 @@ func (suite *DelayedAckTestSuite) TestInvariants() { //progress finalization queue suite.App.RollappKeeper.FinalizeQueue(suite.Ctx) + //test fraud + for rollapp := range seqPerRollapp { + err := suite.App.DelayedAckKeeper.HandleFraud(ctx, rollapp) + suite.Require().Nil(err) + break + } + // check invariant msg, bool := keeper.AllInvariants(suite.App.DelayedAckKeeper)(suite.Ctx) suite.Require().False(bool, msg) } + +/*func (suite *RollappTestSuite) TestRollappFinalizedStateInvariant() { + suite.SetupTest() + ctx := suite.Ctx + rollapp1, rollapp2, rollapp3 := "rollapp1", "rollapp2", "rollapp3" + cases := []struct { + name string + rollappId string + stateInfo *types.StateInfo + latestFinalizedStateInfo types.StateInfo + latestStateInfoIndex types.StateInfo + expectedIsBroken bool + }{ + { + "successful invariant check", + "rollapp1", + &types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp1, + Index: 1, + }, + Status: commontypes.Status_FINALIZED, + }, + types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp1, + Index: 2, + }, + Status: commontypes.Status_FINALIZED, + }, + types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp1, + Index: 3, + }, + Status: commontypes.Status_PENDING, + }, + false, + }, + { + "failed invariant check - state not found", + rollapp2, + nil, + types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp2, + Index: 2, + }, + Status: commontypes.Status_FINALIZED, + }, + types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp2, + Index: 3, + }, + Status: commontypes.Status_PENDING, + }, + true, + }, + { + "failed invariant check - state not finalized", + rollapp3, + &types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp3, + Index: 1, + }, + Status: commontypes.Status_PENDING, + }, + types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp3, + Index: 2, + }, + Status: commontypes.Status_FINALIZED, + }, + types.StateInfo{ + StateInfoIndex: types.StateInfoIndex{ + RollappId: rollapp3, + Index: 3, + }, + Status: commontypes.Status_PENDING, + }, + true, + }, + } + for _, tc := range cases { + suite.Run(tc.name, func() { + // create rollapp + suite.CreateRollappWithName(tc.rollappId) + // update state infos + if tc.stateInfo != nil { + suite.App.RollappKeeper.SetStateInfo(ctx, *tc.stateInfo) + } + // update latest finalized state info + suite.App.RollappKeeper.SetStateInfo(ctx, tc.latestFinalizedStateInfo) + suite.App.RollappKeeper.SetLatestFinalizedStateIndex(ctx, types.StateInfoIndex{ + RollappId: tc.rollappId, + Index: tc.latestFinalizedStateInfo.GetIndex().Index, + }) + // update latest state info index + suite.App.RollappKeeper.SetStateInfo(ctx, tc.latestStateInfoIndex) + suite.App.RollappKeeper.SetLatestStateInfoIndex(ctx, types.StateInfoIndex{ + RollappId: tc.rollappId, + Index: tc.latestStateInfoIndex.GetIndex().Index, + }) + // check invariant + _, isBroken := keeper.RollappFinalizedStateInvariant(suite.App.RollappKeeper)(ctx) + suite.Require().Equal(tc.expectedIsBroken, isBroken) + }) + } +}*/ diff --git a/x/delayedack/types/expected_keepers.go b/x/delayedack/types/expected_keepers.go index cc261ebcd..56968c67a 100644 --- a/x/delayedack/types/expected_keepers.go +++ b/x/delayedack/types/expected_keepers.go @@ -37,6 +37,7 @@ type RollappKeeper interface { StateInfo(ctx context.Context, req *rollapptypes.QueryGetStateInfoRequest) (*rollapptypes.QueryGetStateInfoResponse, error) GetLatestStateInfoIndex(ctx sdk.Context, rollappId string) (val rollapptypes.StateInfoIndex, found bool) GetLatestFinalizedStateIndex(ctx sdk.Context, rollappId string) (val types.StateInfoIndex, found bool) + GetAllRollapps(ctx sdk.Context) (list []types.Rollapp) } type SequencerKeeper interface { diff --git a/x/rollapp/keeper/block_height_to_finalization_queue.go b/x/rollapp/keeper/block_height_to_finalization_queue.go index b46226895..77ec36e7d 100644 --- a/x/rollapp/keeper/block_height_to_finalization_queue.go +++ b/x/rollapp/keeper/block_height_to_finalization_queue.go @@ -18,6 +18,7 @@ func (k Keeper) FinalizeQueue(ctx sdk.Context) { pendingFinalizationQueue := k.GetAllFinalizationQueueUntilHeight(ctx, finalizationHeight) for _, blockHeightToFinalizationQueue := range pendingFinalizationQueue { + // finalize pending states var failedToFinalizeQueue []types.StateInfoIndex for _, stateInfoIndex := range blockHeightToFinalizationQueue.FinalizationQueue {