Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(delayedack): delayedack invariant for finalized and reverted packets #686

Merged
merged 28 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions testutil/keeper/delayedack.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@
return rollapptypes.StateInfoIndex{}, false
}

func (RollappKeeperStub) GetLatestFinalizedStateIndex(ctx sdk.Context, rollappId string) (val rollapptypes.StateInfoIndex, found bool) {
return rollapptypes.StateInfoIndex{}, false

Check warning on line 104 in testutil/keeper/delayedack.go

View check run for this annotation

Codecov / codecov/patch

testutil/keeper/delayedack.go#L103-L104

Added lines #L103 - L104 were not covered by tests
}

func (RollappKeeperStub) GetAllRollapps(ctx sdk.Context) (list []rollapptypes.Rollapp) {
return []rollapptypes.Rollapp{}

Check warning on line 108 in testutil/keeper/delayedack.go

View check run for this annotation

Codecov / codecov/patch

testutil/keeper/delayedack.go#L107-L108

Added lines #L107 - L108 were not covered by tests
}

type SequencerKeeperStub struct{}

func (SequencerKeeperStub) GetSequencer(ctx sdk.Context, sequencerAddress string) (val sequencertypes.Sequencer, found bool) {
Expand Down
2 changes: 1 addition & 1 deletion x/delayedack/keeper/fraud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
commontypes "github.com/dymensionxyz/dymension/v3/x/common/types"
)

func (suite *KeeperTestSuite) TestHandleFraud() {
func (suite *DelayedAckTestSuite) TestHandleFraud() {
keeper, ctx := suite.App.DelayedAckKeeper, suite.Ctx
rollappId := "testRollappId"
pkts := generatePackets(rollappId, 5)
Expand Down
4 changes: 2 additions & 2 deletions x/delayedack/keeper/hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

// TestAfterEpochEnd tests that the finalized of rollapp packets
// are deleted given the correct epoch identifier
func (suite *KeeperTestSuite) TestAfterEpochEnd() {
func (suite *DelayedAckTestSuite) TestAfterEpochEnd() {
tests := []struct {
name string
pendingPacketsNum int
Expand Down Expand Up @@ -83,7 +83,7 @@ func (suite *KeeperTestSuite) TestAfterEpochEnd() {
}
}

func (suite *KeeperTestSuite) TestDeletionOfRevertedPackets() {
func (suite *DelayedAckTestSuite) TestDeletionOfRevertedPackets() {
keeper, ctx := suite.App.DelayedAckKeeper, suite.Ctx

rollappId := "testRollappId"
Expand Down
108 changes: 108 additions & 0 deletions x/delayedack/keeper/invariants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package keeper

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
commontypes "github.com/dymensionxyz/dymension/v3/x/common/types"
"github.com/dymensionxyz/dymension/v3/x/delayedack/types"
)

// RegisterInvariants registers the delayedack module invariants
func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
ir.RegisterRoute(types.ModuleName, "rollapp-finalized-packet", PacketsFromFinalizedHeightsAreFinalized(k))
ir.RegisterRoute(types.ModuleName, "rollapp-reverted-packet", PacketsFromRevertedHeightsAreReverted(k))
}

// AllInvariants runs all invariants of the x/delayedack module.
func AllInvariants(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
res, stop := PacketsFromFinalizedHeightsAreFinalized(k)(ctx)
if stop {
return res, stop
}
res, stop = PacketsFromRevertedHeightsAreReverted(k)(ctx)
if stop {
return res, stop
}
return "", false
}
}

// PacketsFromFinalizedHeightsAreFinalized checks that all rollapp packets stored for a rollapp finalized height are also finalized
omritoptix marked this conversation as resolved.
Show resolved Hide resolved
func PacketsFromFinalizedHeightsAreFinalized(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
var msg string
rollapps := k.rollappKeeper.GetAllRollapps(ctx)

rollappsFinalizedHeight := make(map[string]uint64)
for _, rollapp := range rollapps {
latestFinalizedStateIndex, found := k.rollappKeeper.GetLatestFinalizedStateIndex(ctx, rollapp.RollappId)
if !found {
continue
}
latestFinalizedStateInfo, found := k.rollappKeeper.GetStateInfo(ctx, rollapp.RollappId, latestFinalizedStateIndex.Index)
if !found {
continue

Check warning on line 46 in x/delayedack/keeper/invariants.go

View check run for this annotation

Codecov / codecov/patch

x/delayedack/keeper/invariants.go#L46

Added line #L46 was not covered by tests
}
rollappsFinalizedHeight[rollapp.RollappId] = types.GetLastestFinalizedHeigtFromStateInfo(&latestFinalizedStateInfo)

}

packets := k.GetAllRollappPackets(ctx)

for _, packet := range packets {
latestFinalizedHeight := rollappsFinalizedHeight[packet.RollappId]
mtsitrin marked this conversation as resolved.
Show resolved Hide resolved
if latestFinalizedHeight == 0 {
omritoptix marked this conversation as resolved.
Show resolved Hide resolved
continue
}
if packet.ProofHeight <= latestFinalizedHeight && packet.Status != commontypes.Status_FINALIZED {
msg += fmt.Sprintf("rollapp packet for the height should be in finalized status. height=%d, rollapp=%s, status=%s\n", packet.ProofHeight, packet.RollappId, packet.Status)
return msg, true
}
}
return msg, false
}
}

// PacketsFromRevertedHeightsAreReverted checks that all rollapp packets stored for a rollapp reverted height are also reverted
func PacketsFromRevertedHeightsAreReverted(k Keeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
var msg string

rollapps := k.rollappKeeper.GetAllRollapps(ctx)

for _, rollapp := range rollapps {
latestFinalizedStateIndex, found := k.rollappKeeper.GetLatestFinalizedStateIndex(ctx, rollapp.RollappId)
if !found {
continue
}

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)
stateInfoIndex++
mtsitrin marked this conversation as resolved.
Show resolved Hide resolved
if !found {
break
}
if stateInfoToCheck.Status != commontypes.Status_REVERTED {
continue
}
// TODO (srene) explore how to GetRollappPacket by rollapp to be more efficient (https://github.com/dymensionxyz/dymension/issues/631)
for _, packet := range k.GetAllRollappPackets(ctx) {
if packet.RollappId != rollapp.RollappId {
continue

Check warning on line 95 in x/delayedack/keeper/invariants.go

View check run for this annotation

Codecov / codecov/patch

x/delayedack/keeper/invariants.go#L95

Added line #L95 was not covered by tests
}
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)
srene marked this conversation as resolved.
Show resolved Hide resolved
return msg, true
}
}

}

}
return msg, false
}
}
Loading
Loading