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 all 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
113 changes: 113 additions & 0 deletions x/delayedack/keeper/invariants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
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", PacketsFinalizationCorrespondsToFinalizationHeight(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 := PacketsFinalizationCorrespondsToFinalizationHeight(k)(ctx)
if stop {
return res, stop
}
res, stop = PacketsFromRevertedHeightsAreReverted(k)(ctx)
if stop {
return res, stop
}
return "", false
}
}

// PacketsFinalizationCorrespondsToFinalizationHeight checks that all rollapp packets stored f are finalized for all heights up to finalization height, and are non-finalized for posterior heights
func PacketsFinalizationCorrespondsToFinalizationHeight(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 {
rollappsFinalizedHeight[rollapp.RollappId] = 0

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 48 in x/delayedack/keeper/invariants.go

View check run for this annotation

Codecov / codecov/patch

x/delayedack/keeper/invariants.go#L48

Added line #L48 was not covered by tests
}
rollappsFinalizedHeight[rollapp.RollappId] = latestFinalizedStateInfo.GetLatestHeight()

}

packets := k.GetAllRollappPackets(ctx)

for _, packet := range packets {
latestFinalizedHeight := rollappsFinalizedHeight[packet.RollappId]
mtsitrin marked this conversation as resolved.
Show resolved Hide resolved

if packet.ProofHeight > latestFinalizedHeight && packet.Status == commontypes.Status_FINALIZED {
msg += fmt.Sprintf("rollapp packet for the height should not be in finalized status. height=%d, rollapp=%s, status=%s\n", packet.ProofHeight, packet.RollappId, packet.Status)
return msg, true
}
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)

frozenRollappsFinalizedHeight := make(map[string]uint64)

for _, rollapp := range rollapps {
if !rollapp.Frozen {
continue
}
frozenRollappsFinalizedHeight[rollapp.RollappId] = 0

latestFinalizedStateIndex, found := k.rollappKeeper.GetLatestFinalizedStateIndex(ctx, rollapp.RollappId)
if !found {
continue

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

View check run for this annotation

Codecov / codecov/patch

x/delayedack/keeper/invariants.go#L89

Added line #L89 was not covered by tests
}
latestFinalizedStateInfo, found := k.rollappKeeper.GetStateInfo(ctx, rollapp.RollappId, latestFinalizedStateIndex.Index)
if !found {
continue

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

View check run for this annotation

Codecov / codecov/patch

x/delayedack/keeper/invariants.go#L93

Added line #L93 was not covered by tests
}
frozenRollappsFinalizedHeight[rollapp.RollappId] = latestFinalizedStateInfo.GetLatestHeight()

}

// 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) {
latestFinalizedHeight, found := frozenRollappsFinalizedHeight[packet.RollappId]
if !found {
continue
}

if packet.ProofHeight > latestFinalizedHeight && packet.Status != commontypes.Status_REVERTED {
msg += fmt.Sprintf("packet should be reverted: rollapp: %s: height: %d: status: %s", packet.RollappId, packet.ProofHeight, packet.Status)
return msg, true
}
}
return msg, false
}
}
Loading
Loading