From 2b6ebed0719f4d9693e9910b77ababed6051d185 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Thu, 2 Feb 2023 00:04:14 +0800 Subject: [PATCH 1/4] fix epoch 0 bug --- x/checkpointing/keeper/keeper.go | 2 +- x/monitor/keeper/keeper.go | 16 ++++++++++------ x/monitor/types/expected_keepers.go | 1 + 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index 63246c5e7..e9a7a5030 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -244,7 +244,7 @@ func (k Keeper) verifyCkptBytes(ctx sdk.Context, rawCheckpoint *txformat.RawBtcC // record verified checkpoint err = k.AfterRawCheckpointBlsSigVerified(ctx, ckpt) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to record verified checkpoint of epoch %d for monitoring: %w", ckpt.EpochNum, err) } // now the checkpoint's multi-sig is valid, if the lastcommithash is the diff --git a/x/monitor/keeper/keeper.go b/x/monitor/keeper/keeper.go index 156ebf28f..308ee45e8 100644 --- a/x/monitor/keeper/keeper.go +++ b/x/monitor/keeper/keeper.go @@ -65,18 +65,18 @@ func (k Keeper) updateBtcLightClientHeightForCheckpoint(ctx sdk.Context, ckpt *c store := ctx.KVStore(k.storeKey) ckptHashStr := ckpt.HashStr() + storeKey, err := types.GetCheckpointReportedLightClientHeightKey(ckptHashStr) + if err != nil { + return err + } + // if the checkpoint exists, meaning an earlier checkpoint with a lower btc height is already recorded // we should keep the lower btc height in the store - if store.Has([]byte(ckptHashStr)) { + if store.Has(storeKey) { k.Logger(ctx).With("module", fmt.Sprintf("checkpoint %s is already recorded", ckptHashStr)) return nil } - storeKey, err := types.GetCheckpointReportedLightClientHeightKey(ckptHashStr) - if err != nil { - return err - } - currentTipHeight := k.btcLightClientKeeper.GetTipInfo(ctx).Height store.Set(storeKey, sdk.Uint64ToBigEndian(currentTipHeight)) @@ -98,6 +98,10 @@ func (k Keeper) removeCheckpointRecord(ctx sdk.Context, ckpt *ckpttypes.RawCheck } func (k Keeper) LightclientHeightAtEpochEnd(ctx sdk.Context, epoch uint64) (uint64, error) { + if epoch == 0 { + return k.btcLightClientKeeper.GetBaseBTCHeader(ctx).Height, nil + } + store := ctx.KVStore(k.storeKey) btcHeightBytes := store.Get(types.GetEpochEndLightClientHeightKey(epoch)) diff --git a/x/monitor/types/expected_keepers.go b/x/monitor/types/expected_keepers.go index 6777fbff5..6f3566003 100644 --- a/x/monitor/types/expected_keepers.go +++ b/x/monitor/types/expected_keepers.go @@ -20,4 +20,5 @@ type BankKeeper interface { type BTCLightClientKeeper interface { GetTipInfo(ctx sdk.Context) *lc.BTCHeaderInfo + GetBaseBTCHeader(ctx sdk.Context) *lc.BTCHeaderInfo } From 4a98378cf726c5edd672227ed3445ff1daf7dcfe Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Thu, 2 Feb 2023 11:01:46 +0800 Subject: [PATCH 2/4] add ended epoch btc height testing --- testutil/keeper/monitor.go | 56 ++++++++++++ x/monitor/keeper/grpc_query_params.go | 7 ++ x/monitor/keeper/grpc_query_test.go | 127 ++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 testutil/keeper/monitor.go create mode 100644 x/monitor/keeper/grpc_query_test.go diff --git a/testutil/keeper/monitor.go b/testutil/keeper/monitor.go new file mode 100644 index 000000000..8a48a9af0 --- /dev/null +++ b/testutil/keeper/monitor.go @@ -0,0 +1,56 @@ +package keeper + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + typesparams "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" + + "github.com/babylonchain/babylon/x/monitor/keeper" + "github.com/babylonchain/babylon/x/monitor/types" +) + +func MonitorKeeper(t testing.TB, lck types.BTCLightClientKeeper) (*keeper.Keeper, sdk.Context) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + registry := codectypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(registry) + + paramsSubspace := typesparams.NewSubspace( + cdc, + nil, + storeKey, + memStoreKey, + "MonitorParams", + ) + + k := keeper.NewKeeper( + cdc, + storeKey, + memStoreKey, + paramsSubspace, + lck, + ) + + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + + // Initialize params + k.SetParams(ctx, types.DefaultParams()) + + return &k, ctx +} diff --git a/x/monitor/keeper/grpc_query_params.go b/x/monitor/keeper/grpc_query_params.go index 4cf229c7a..9ba4a1b00 100644 --- a/x/monitor/keeper/grpc_query_params.go +++ b/x/monitor/keeper/grpc_query_params.go @@ -9,6 +9,13 @@ import ( "google.golang.org/grpc/status" ) +// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper +type Querier struct { + Keeper +} + +var _ types.QueryServer = Querier{} + func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") diff --git a/x/monitor/keeper/grpc_query_test.go b/x/monitor/keeper/grpc_query_test.go new file mode 100644 index 000000000..d1fe9c3fc --- /dev/null +++ b/x/monitor/keeper/grpc_query_test.go @@ -0,0 +1,127 @@ +package keeper_test + +import ( + "github.com/babylonchain/babylon/testutil/datagen" + btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonchain/babylon/x/epoching/testepoching" + monitorkeeper "github.com/babylonchain/babylon/x/monitor/keeper" + "github.com/babylonchain/babylon/x/monitor/types" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/stretchr/testify/require" + "math/rand" + "testing" +) + +func FuzzQueryEndedEpochBtcHeight(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + rand.Seed(seed) + // a genesis validator is generated for setup + helper := testepoching.NewHelper(t) + lck := helper.App.BTCLightClientKeeper + mk := helper.App.MonitorKeeper + ek := helper.EpochingKeeper + querier := monitorkeeper.Querier{Keeper: mk} + queryHelper := baseapp.NewQueryServerTestHelper(helper.Ctx, helper.App.InterfaceRegistry()) + types.RegisterQueryServer(queryHelper, querier) + queryClient := types.NewQueryClient(queryHelper) + + // BeginBlock of block 1, and thus entering epoch 1 + ctx := helper.BeginBlock() + epoch := ek.GetEpoch(ctx) + require.Equal(t, uint64(1), epoch.EpochNumber) + + // Insert header tree + tree := datagen.NewBTCHeaderTree() + root := lck.GetBaseBTCHeader(ctx) + tree.Add(root, nil) + tree.GenRandomBTCHeaderTree(1, 10, root, func(header *btclightclienttypes.BTCHeaderInfo) bool { + err := lck.InsertHeader(ctx, header.Header) + require.NoError(t, err) + return true + }) + + // EndBlock of block 1 + ctx = helper.EndBlock() + + // go to BeginBlock of block 11, and thus entering epoch 2 + for i := uint64(0); i < ek.GetParams(ctx).EpochInterval; i++ { + ctx = helper.GenAndApplyEmptyBlock() + } + epoch = ek.GetEpoch(ctx) + require.Equal(t, uint64(2), epoch.EpochNumber) + + // query epoch 0 ended BTC light client height, should return base height + req := types.QueryEndedEpochBtcHeightRequest{ + EpochNum: 0, + } + resp, err := queryClient.EndedEpochBtcHeight(ctx, &req) + require.NoError(t, err) + require.Equal(t, lck.GetBaseBTCHeader(ctx).Height, resp.BtcLightClientHeight) + + // query epoch 1 ended BTC light client height, should return tip height + req = types.QueryEndedEpochBtcHeightRequest{ + EpochNum: 1, + } + resp, err = queryClient.EndedEpochBtcHeight(ctx, &req) + require.NoError(t, err) + require.Equal(t, lck.GetTipInfo(ctx).Height, resp.BtcLightClientHeight) + }) +} + +func FuzzQueryEndedEpochBtcHeight(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + rand.Seed(seed) + // a genesis validator is generated for setup + helper := testepoching.NewHelper(t) + lck := helper.App.BTCLightClientKeeper + mk := helper.App.MonitorKeeper + ek := helper.EpochingKeeper + querier := monitorkeeper.Querier{Keeper: mk} + queryHelper := baseapp.NewQueryServerTestHelper(helper.Ctx, helper.App.InterfaceRegistry()) + types.RegisterQueryServer(queryHelper, querier) + queryClient := types.NewQueryClient(queryHelper) + + // BeginBlock of block 1, and thus entering epoch 1 + ctx := helper.BeginBlock() + epoch := ek.GetEpoch(ctx) + require.Equal(t, uint64(1), epoch.EpochNumber) + + // Insert header tree + tree := datagen.NewBTCHeaderTree() + root := lck.GetBaseBTCHeader(ctx) + tree.Add(root, nil) + tree.GenRandomBTCHeaderTree(1, 10, root, func(header *btclightclienttypes.BTCHeaderInfo) bool { + err := lck.InsertHeader(ctx, header.Header) + require.NoError(t, err) + return true + }) + + // EndBlock of block 1 + ctx = helper.EndBlock() + + // go to BeginBlock of block 11, and thus entering epoch 2 + for i := uint64(0); i < ek.GetParams(ctx).EpochInterval; i++ { + ctx = helper.GenAndApplyEmptyBlock() + } + epoch = ek.GetEpoch(ctx) + require.Equal(t, uint64(2), epoch.EpochNumber) + + // query epoch 0 ended BTC light client height, should return base height + req := types.QueryEndedEpochBtcHeightRequest{ + EpochNum: 0, + } + resp, err := queryClient.EndedEpochBtcHeight(ctx, &req) + require.NoError(t, err) + require.Equal(t, lck.GetBaseBTCHeader(ctx).Height, resp.BtcLightClientHeight) + + // query epoch 1 ended BTC light client height, should return tip height + req = types.QueryEndedEpochBtcHeightRequest{ + EpochNum: 1, + } + resp, err = queryClient.EndedEpochBtcHeight(ctx, &req) + require.NoError(t, err) + require.Equal(t, lck.GetTipInfo(ctx).Height, resp.BtcLightClientHeight) + }) +} From 6c76dd7a502391c25607b4d0273b2c4149efcb17 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Thu, 2 Feb 2023 14:57:54 +0800 Subject: [PATCH 3/4] add fuzz test for reported checkpoint query --- app/app.go | 7 +-- x/checkpointing/keeper/keeper.go | 10 ++++- x/checkpointing/types/hooks.go | 4 +- x/monitor/keeper/grpc_query_test.go | 67 +++++++++++++++++++++-------- x/monitor/keeper/hooks.go | 3 +- 5 files changed, 66 insertions(+), 25 deletions(-) diff --git a/app/app.go b/app/app.go index c964260b7..ca0bc07dd 100644 --- a/app/app.go +++ b/app/app.go @@ -507,10 +507,11 @@ func NewBabylonApp( app.GetSubspace(checkpointingtypes.ModuleName), privSigner.ClientCtx, ) - app.CheckpointingKeeper = *checkpointingKeeper.SetHooks( - checkpointingtypes.NewMultiCheckpointingHooks(app.EpochingKeeper.Hooks(), app.ZoneConciergeKeeper.Hooks()), + checkpointingKeeper.SetHooks( + checkpointingtypes.NewMultiCheckpointingHooks(app.EpochingKeeper.Hooks(), app.ZoneConciergeKeeper.Hooks(), app.MonitorKeeper.Hooks()), ) - app.ZoneConciergeKeeper.SetCheckpointingKeeper(app.CheckpointingKeeper) + app.CheckpointingKeeper = checkpointingKeeper + app.ZoneConciergeKeeper.SetCheckpointingKeeper(checkpointingKeeper) // TODO for now use mocks, as soon as Checkpoining and lightClient will have correct interfaces // change to correct implementations diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index e9a7a5030..69c0e0647 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -3,7 +3,6 @@ package keeper import ( "errors" "fmt" - txformat "github.com/babylonchain/babylon/btctxformatter" "github.com/babylonchain/babylon/crypto/bls12381" @@ -210,6 +209,11 @@ func (k Keeper) verifyCkptBytes(ctx sdk.Context, rawCheckpoint *txformat.RawBtcC // can skip the checks if it is identical with the local checkpoint that is not accumulating if ckptWithMeta.Ckpt.Equal(ckpt) && ckptWithMeta.Status != types.Accumulating { + // record verified checkpoint + err = k.AfterRawCheckpointBlsSigVerified(ctx, ckpt) + if err != nil { + return nil, fmt.Errorf("failed to record verified checkpoint of epoch %d for monitoring: %w", ckpt.EpochNum, err) + } return ckptWithMeta, nil } @@ -270,6 +274,10 @@ func (k Keeper) verifyCkptBytes(ctx sdk.Context, rawCheckpoint *txformat.RawBtcC return nil, types.ErrConflictingCheckpoint } +func (k *Keeper) SetEpochingKeeper(ek types.EpochingKeeper) { + k.epochingKeeper = ek +} + // SetCheckpointSubmitted sets the status of a checkpoint to SUBMITTED, // and records the associated state update in lifecycle func (k Keeper) SetCheckpointSubmitted(ctx sdk.Context, epoch uint64) { diff --git a/x/checkpointing/types/hooks.go b/x/checkpointing/types/hooks.go index d003f59eb..50a97c406 100644 --- a/x/checkpointing/types/hooks.go +++ b/x/checkpointing/types/hooks.go @@ -49,7 +49,9 @@ func (h MultiCheckpointingHooks) AfterRawCheckpointFinalized(ctx sdk.Context, ep func (h MultiCheckpointingHooks) AfterRawCheckpointBlsSigVerified(ctx sdk.Context, ckpt *RawCheckpoint) error { for i := range h { - return h[i].AfterRawCheckpointBlsSigVerified(ctx, ckpt) + if err := h[i].AfterRawCheckpointBlsSigVerified(ctx, ckpt); err != nil { + return err + } } return nil } diff --git a/x/monitor/keeper/grpc_query_test.go b/x/monitor/keeper/grpc_query_test.go index d1fe9c3fc..44dc9ee11 100644 --- a/x/monitor/keeper/grpc_query_test.go +++ b/x/monitor/keeper/grpc_query_test.go @@ -1,12 +1,17 @@ package keeper_test import ( + "github.com/babylonchain/babylon/btctxformatter" "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/mocks" btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" + ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" "github.com/babylonchain/babylon/x/epoching/testepoching" + types2 "github.com/babylonchain/babylon/x/epoching/types" monitorkeeper "github.com/babylonchain/babylon/x/monitor/keeper" "github.com/babylonchain/babylon/x/monitor/types" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "math/rand" "testing" @@ -69,15 +74,20 @@ func FuzzQueryEndedEpochBtcHeight(f *testing.F) { }) } -func FuzzQueryEndedEpochBtcHeight(f *testing.F) { +func FuzzQueryReportedCheckpointBtcHeight(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) // a genesis validator is generated for setup helper := testepoching.NewHelper(t) + ctl := gomock.NewController(t) + defer ctl.Finish() lck := helper.App.BTCLightClientKeeper mk := helper.App.MonitorKeeper ek := helper.EpochingKeeper + ck := helper.App.CheckpointingKeeper + mockEk := mocks.NewMockEpochingKeeper(ctl) + ck.SetEpochingKeeper(mockEk) querier := monitorkeeper.Querier{Keeper: mk} queryHelper := baseapp.NewQueryServerTestHelper(helper.Ctx, helper.App.InterfaceRegistry()) types.RegisterQueryServer(queryHelper, querier) @@ -98,30 +108,51 @@ func FuzzQueryEndedEpochBtcHeight(f *testing.F) { return true }) - // EndBlock of block 1 - ctx = helper.EndBlock() - - // go to BeginBlock of block 11, and thus entering epoch 2 - for i := uint64(0); i < ek.GetParams(ctx).EpochInterval; i++ { - ctx = helper.GenAndApplyEmptyBlock() + // Add checkpoint + valBlsSet, privKeys := datagen.GenerateValidatorSetWithBLSPrivKeys(int(datagen.RandomIntOtherThan(0, 10))) + valSet := make([]types2.Validator, len(valBlsSet.ValSet)) + for i, val := range valBlsSet.ValSet { + valSet[i] = types2.Validator{ + Addr: []byte(val.ValidatorAddress), + Power: int64(val.VotingPower), + } + err := ck.CreateRegistration(ctx, val.BlsPubKey, []byte(val.ValidatorAddress)) + require.NoError(t, err) } - epoch = ek.GetEpoch(ctx) - require.Equal(t, uint64(2), epoch.EpochNumber) + mockCkptWithMeta := &ckpttypes.RawCheckpointWithMeta{Ckpt: datagen.GenerateLegitimateRawCheckpoint(privKeys)} + mockEk.EXPECT().GetValidatorSet(gomock.Any(), gomock.Eq(mockCkptWithMeta.Ckpt.EpochNum)).Return(valSet).AnyTimes() + // make sure voting power is always sufficient + mockEk.EXPECT().GetTotalVotingPower(gomock.Any(), gomock.Eq(mockCkptWithMeta.Ckpt.EpochNum)).Return(int64(0)).AnyTimes() + err := ck.AddRawCheckpoint( + ctx, + mockCkptWithMeta, + ) + require.NoError(t, err) - // query epoch 0 ended BTC light client height, should return base height - req := types.QueryEndedEpochBtcHeightRequest{ - EpochNum: 0, + // Verify checkpoint + btcCkpt := btctxformatter.RawBtcCheckpoint{ + Epoch: mockCkptWithMeta.Ckpt.EpochNum, + LastCommitHash: *mockCkptWithMeta.Ckpt.LastCommitHash, + BitMap: mockCkptWithMeta.Ckpt.Bitmap, + SubmitterAddress: datagen.GenRandomByteArray(btctxformatter.AddressLength), + BlsSig: *mockCkptWithMeta.Ckpt.BlsMultiSig, } - resp, err := queryClient.EndedEpochBtcHeight(ctx, &req) + err = ck.VerifyCheckpoint(ctx, btcCkpt) require.NoError(t, err) - require.Equal(t, lck.GetBaseBTCHeader(ctx).Height, resp.BtcLightClientHeight) - // query epoch 1 ended BTC light client height, should return tip height - req = types.QueryEndedEpochBtcHeightRequest{ - EpochNum: 1, + // query reported checkpoint BTC light client height + req := types.QueryReportedCheckpointBtcHeightRequest{ + CkptHash: mockCkptWithMeta.Ckpt.HashStr(), } - resp, err = queryClient.EndedEpochBtcHeight(ctx, &req) + resp, err := queryClient.ReportedCheckpointBtcHeight(ctx, &req) require.NoError(t, err) require.Equal(t, lck.GetTipInfo(ctx).Height, resp.BtcLightClientHeight) + + // query not reported checkpoint BTC light client height, should expect an ErrCheckpointNotReported + req = types.QueryReportedCheckpointBtcHeightRequest{ + CkptHash: datagen.GenRandomHexStr(32), + } + _, err = queryClient.ReportedCheckpointBtcHeight(ctx, &req) + require.ErrorIs(t, err, types.ErrCheckpointNotReported) }) } diff --git a/x/monitor/keeper/hooks.go b/x/monitor/keeper/hooks.go index 91bd8437d..49a24e0e7 100644 --- a/x/monitor/keeper/hooks.go +++ b/x/monitor/keeper/hooks.go @@ -16,8 +16,7 @@ type Hooks struct { k Keeper } -var _ HandledHooks = Hooks{} - +// Create new distribution hooks func (k Keeper) Hooks() Hooks { return Hooks{k} } func (h Hooks) AfterEpochBegins(ctx sdk.Context, epoch uint64) {} From acadde2977b235682d24de8eeaa58b1c30b5f551 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Thu, 2 Feb 2023 15:52:30 +0800 Subject: [PATCH 4/4] address comments --- app/app.go | 5 ++-- testutil/keeper/monitor.go | 56 -------------------------------------- x/checkpointing/abci.go | 2 +- 3 files changed, 3 insertions(+), 60 deletions(-) delete mode 100644 testutil/keeper/monitor.go diff --git a/app/app.go b/app/app.go index ca0bc07dd..6790210f7 100644 --- a/app/app.go +++ b/app/app.go @@ -507,11 +507,10 @@ func NewBabylonApp( app.GetSubspace(checkpointingtypes.ModuleName), privSigner.ClientCtx, ) - checkpointingKeeper.SetHooks( + app.CheckpointingKeeper = *checkpointingKeeper.SetHooks( checkpointingtypes.NewMultiCheckpointingHooks(app.EpochingKeeper.Hooks(), app.ZoneConciergeKeeper.Hooks(), app.MonitorKeeper.Hooks()), ) - app.CheckpointingKeeper = checkpointingKeeper - app.ZoneConciergeKeeper.SetCheckpointingKeeper(checkpointingKeeper) + app.ZoneConciergeKeeper.SetCheckpointingKeeper(app.CheckpointingKeeper) // TODO for now use mocks, as soon as Checkpoining and lightClient will have correct interfaces // change to correct implementations diff --git a/testutil/keeper/monitor.go b/testutil/keeper/monitor.go deleted file mode 100644 index 8a48a9af0..000000000 --- a/testutil/keeper/monitor.go +++ /dev/null @@ -1,56 +0,0 @@ -package keeper - -import ( - "testing" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/store" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - typesparams "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmdb "github.com/tendermint/tm-db" - - "github.com/babylonchain/babylon/x/monitor/keeper" - "github.com/babylonchain/babylon/x/monitor/types" -) - -func MonitorKeeper(t testing.TB, lck types.BTCLightClientKeeper) (*keeper.Keeper, sdk.Context) { - storeKey := sdk.NewKVStoreKey(types.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - - db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) - require.NoError(t, stateStore.LoadLatestVersion()) - - registry := codectypes.NewInterfaceRegistry() - cdc := codec.NewProtoCodec(registry) - - paramsSubspace := typesparams.NewSubspace( - cdc, - nil, - storeKey, - memStoreKey, - "MonitorParams", - ) - - k := keeper.NewKeeper( - cdc, - storeKey, - memStoreKey, - paramsSubspace, - lck, - ) - - ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) - - // Initialize params - k.SetParams(ctx, types.DefaultParams()) - - return &k, ctx -} diff --git a/x/checkpointing/abci.go b/x/checkpointing/abci.go index feba0e8d0..c7348f161 100644 --- a/x/checkpointing/abci.go +++ b/x/checkpointing/abci.go @@ -26,7 +26,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper, req abci.RequestBeginBlock) if epoch.IsFirstBlock(ctx) { err := k.InitValidatorBLSSet(ctx) if err != nil { - panic(fmt.Errorf("failed to store validator BLS set")) + panic(fmt.Errorf("failed to store validator BLS set: %w", err)) } } if epoch.IsSecondBlock(ctx) {