-
Notifications
You must be signed in to change notification settings - Fork 353
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rollapp): rollapp state finalization (#74)
* ignite scaffold map block_height_to_finalization_queue finalization_queue:StateInfoIndex --index finalization_height:uint --no-message --module rollapp * fix ignite command * update finalizationQueue on UpdateState * finalize states on EndBlocker * add tests * fix lint * fix lint 2
- Loading branch information
Showing
24 changed files
with
2,769 additions
and
277 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package rollapp | ||
|
||
import ( | ||
"fmt" | ||
|
||
abci "github.com/tendermint/tendermint/abci/types" | ||
|
||
"github.com/dymensionxyz/dymension/x/rollapp/keeper" | ||
"github.com/dymensionxyz/dymension/x/rollapp/types" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// BeginBlocker is called on every block. | ||
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) { | ||
} | ||
|
||
// Called every block to finalize states that their dispute period over. | ||
func EndBlocker(ctx sdk.Context, k keeper.Keeper) { | ||
// check to see if there are pending states to be finalized | ||
blockHeightToFinalizationQueue, found := k.GetBlockHeightToFinalizationQueue(ctx, uint64(ctx.BlockHeight())) | ||
|
||
if found { | ||
// finalize pending states | ||
for _, stateInfoIndex := range blockHeightToFinalizationQueue.FinalizationQueue { | ||
stateInfo, found := k.GetStateInfo(ctx, stateInfoIndex.RollappId, stateInfoIndex.Index) | ||
if !found { | ||
panic(fmt.Errorf("invariant broken: rollapp %s should have state to be finalizaed in height %d. update state index is %d \n", | ||
stateInfoIndex.RollappId, ctx.BlockHeight(), stateInfoIndex.Index)) | ||
} | ||
stateInfo.Status = types.STATE_STATUS_FINALIZED | ||
// write the new status | ||
k.SetStateInfo(ctx, stateInfo) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
x/rollapp/client/cli/query_block_height_to_finalization_queue.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package cli | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
"github.com/dymensionxyz/dymension/x/rollapp/types" | ||
"github.com/spf13/cast" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func CmdListBlockHeightToFinalizationQueue() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "list-block-height-to-finalization-queue", | ||
Short: "list all block_height_to_finalization_queue", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
clientCtx := client.GetClientContextFromCmd(cmd) | ||
|
||
pageReq, err := client.ReadPageRequest(cmd.Flags()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
queryClient := types.NewQueryClient(clientCtx) | ||
|
||
params := &types.QueryAllBlockHeightToFinalizationQueueRequest{ | ||
Pagination: pageReq, | ||
} | ||
|
||
res, err := queryClient.BlockHeightToFinalizationQueueAll(context.Background(), params) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return clientCtx.PrintProto(res) | ||
}, | ||
} | ||
|
||
flags.AddPaginationFlagsToCmd(cmd, cmd.Use) | ||
flags.AddQueryFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
func CmdShowBlockHeightToFinalizationQueue() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "show-block-height-to-finalization-queue [finalization-height]", | ||
Short: "shows a block_height_to_finalization_queue", | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) (err error) { | ||
clientCtx := client.GetClientContextFromCmd(cmd) | ||
|
||
queryClient := types.NewQueryClient(clientCtx) | ||
|
||
argFinalizationHeight, err := cast.ToUint64E(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
params := &types.QueryGetBlockHeightToFinalizationQueueRequest{ | ||
FinalizationHeight: argFinalizationHeight, | ||
} | ||
|
||
res, err := queryClient.BlockHeightToFinalizationQueue(context.Background(), params) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return clientCtx.PrintProto(res) | ||
}, | ||
} | ||
|
||
flags.AddQueryFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} |
163 changes: 163 additions & 0 deletions
163
x/rollapp/client/cli/query_block_height_to_finalization_queue_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package cli_test | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"testing" | ||
|
||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" | ||
"github.com/stretchr/testify/require" | ||
tmcli "github.com/tendermint/tendermint/libs/cli" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
|
||
"github.com/dymensionxyz/dymension/testutil/network" | ||
"github.com/dymensionxyz/dymension/testutil/nullify" | ||
"github.com/dymensionxyz/dymension/x/rollapp/client/cli" | ||
"github.com/dymensionxyz/dymension/x/rollapp/types" | ||
) | ||
|
||
// Prevent strconv unused error | ||
var _ = strconv.IntSize | ||
|
||
func networkWithBlockHeightToFinalizationQueueObjects(t *testing.T, n int) (*network.Network, []types.BlockHeightToFinalizationQueue) { | ||
t.Helper() | ||
cfg := network.DefaultConfig() | ||
state := types.GenesisState{} | ||
require.NoError(t, cfg.Codec.UnmarshalJSON(cfg.GenesisState[types.ModuleName], &state)) | ||
|
||
for i := 0; i < n; i++ { | ||
blockHeightToFinalizationQueue := types.BlockHeightToFinalizationQueue{ | ||
FinalizationHeight: uint64(i), | ||
|
||
} | ||
nullify.Fill(&blockHeightToFinalizationQueue) | ||
state.BlockHeightToFinalizationQueueList = append(state.BlockHeightToFinalizationQueueList, blockHeightToFinalizationQueue) | ||
} | ||
buf, err := cfg.Codec.MarshalJSON(&state) | ||
require.NoError(t, err) | ||
cfg.GenesisState[types.ModuleName] = buf | ||
return network.New(t, cfg), state.BlockHeightToFinalizationQueueList | ||
} | ||
|
||
func TestShowBlockHeightToFinalizationQueue(t *testing.T) { | ||
net, objs := networkWithBlockHeightToFinalizationQueueObjects(t, 2) | ||
|
||
ctx := net.Validators[0].ClientCtx | ||
common := []string{ | ||
fmt.Sprintf("--%s=json", tmcli.OutputFlag), | ||
} | ||
for _, tc := range []struct { | ||
desc string | ||
idFinalizationHeight uint64 | ||
|
||
args []string | ||
err error | ||
obj types.BlockHeightToFinalizationQueue | ||
}{ | ||
{ | ||
desc: "found", | ||
idFinalizationHeight: objs[0].FinalizationHeight, | ||
|
||
args: common, | ||
obj: objs[0], | ||
}, | ||
{ | ||
desc: "not found", | ||
idFinalizationHeight: 100000, | ||
|
||
args: common, | ||
err: status.Error(codes.NotFound, "not found"), | ||
}, | ||
} { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
args := []string{ | ||
strconv.Itoa(int(tc.idFinalizationHeight)), | ||
|
||
} | ||
args = append(args, tc.args...) | ||
out, err := clitestutil.ExecTestCLICmd(ctx, cli.CmdShowBlockHeightToFinalizationQueue(), args) | ||
if tc.err != nil { | ||
stat, ok := status.FromError(tc.err) | ||
require.True(t, ok) | ||
require.ErrorIs(t, stat.Err(), tc.err) | ||
} else { | ||
require.NoError(t, err) | ||
var resp types.QueryGetBlockHeightToFinalizationQueueResponse | ||
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) | ||
require.NotNil(t, resp.BlockHeightToFinalizationQueue) | ||
require.Equal(t, | ||
nullify.Fill(&tc.obj), | ||
nullify.Fill(&resp.BlockHeightToFinalizationQueue), | ||
) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestListBlockHeightToFinalizationQueue(t *testing.T) { | ||
net, objs := networkWithBlockHeightToFinalizationQueueObjects(t, 5) | ||
|
||
ctx := net.Validators[0].ClientCtx | ||
request := func(next []byte, offset, limit uint64, total bool) []string { | ||
args := []string{ | ||
fmt.Sprintf("--%s=json", tmcli.OutputFlag), | ||
} | ||
if next == nil { | ||
args = append(args, fmt.Sprintf("--%s=%d", flags.FlagOffset, offset)) | ||
} else { | ||
args = append(args, fmt.Sprintf("--%s=%s", flags.FlagPageKey, next)) | ||
} | ||
args = append(args, fmt.Sprintf("--%s=%d", flags.FlagLimit, limit)) | ||
if total { | ||
args = append(args, fmt.Sprintf("--%s", flags.FlagCountTotal)) | ||
} | ||
return args | ||
} | ||
t.Run("ByOffset", func(t *testing.T) { | ||
step := 2 | ||
for i := 0; i < len(objs); i += step { | ||
args := request(nil, uint64(i), uint64(step), false) | ||
out, err := clitestutil.ExecTestCLICmd(ctx, cli.CmdListBlockHeightToFinalizationQueue(), args) | ||
require.NoError(t, err) | ||
var resp types.QueryAllBlockHeightToFinalizationQueueResponse | ||
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) | ||
require.LessOrEqual(t, len(resp.BlockHeightToFinalizationQueue), step) | ||
require.Subset(t, | ||
nullify.Fill(objs), | ||
nullify.Fill(resp.BlockHeightToFinalizationQueue), | ||
) | ||
} | ||
}) | ||
t.Run("ByKey", func(t *testing.T) { | ||
step := 2 | ||
var next []byte | ||
for i := 0; i < len(objs); i += step { | ||
args := request(next, 0, uint64(step), false) | ||
out, err := clitestutil.ExecTestCLICmd(ctx, cli.CmdListBlockHeightToFinalizationQueue(), args) | ||
require.NoError(t, err) | ||
var resp types.QueryAllBlockHeightToFinalizationQueueResponse | ||
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) | ||
require.LessOrEqual(t, len(resp.BlockHeightToFinalizationQueue), step) | ||
require.Subset(t, | ||
nullify.Fill(objs), | ||
nullify.Fill(resp.BlockHeightToFinalizationQueue), | ||
) | ||
next = resp.Pagination.NextKey | ||
} | ||
}) | ||
t.Run("Total", func(t *testing.T) { | ||
args := request(nil, 0, uint64(len(objs)), true) | ||
out, err := clitestutil.ExecTestCLICmd(ctx, cli.CmdListBlockHeightToFinalizationQueue(), args) | ||
require.NoError(t, err) | ||
var resp types.QueryAllBlockHeightToFinalizationQueueResponse | ||
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) | ||
require.NoError(t, err) | ||
require.Equal(t, len(objs), int(resp.Pagination.Total)) | ||
require.ElementsMatch(t, | ||
nullify.Fill(objs), | ||
nullify.Fill(resp.BlockHeightToFinalizationQueue), | ||
) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.