From 509f890f261f79e578dfb0abe26964fad0898b26 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Thu, 4 Apr 2024 20:09:51 +0100 Subject: [PATCH 01/14] event manager initial implementation --- app/keepers/keepers.go | 11 +- app/keepers/keys.go | 2 + app/upgrades.go | 5 + app/upgrades/types.go | 1 + x/eventmanager/keeper/conditions.go | 60 ++ x/eventmanager/keeper/events.go | 94 +++ x/eventmanager/keeper/grpc_query.go | 50 ++ x/eventmanager/keeper/grpc_query_test.go | 39 ++ x/eventmanager/keeper/keeper.go | 58 ++ x/eventmanager/keeper/keeper_test.go | 208 ++++++ x/eventmanager/module.go | 178 +++++ x/eventmanager/types/callbacks.go | 12 + x/eventmanager/types/codec.go | 25 + x/eventmanager/types/fields.go | 67 ++ x/eventmanager/types/genesis.go | 12 + x/eventmanager/types/genesis.pb.go | 818 +++++++++++++++++++++++ x/eventmanager/types/keys.go | 36 + x/eventmanager/types/query.pb.go | 723 ++++++++++++++++++++ x/eventmanager/types/query.pb.gw.go | 207 ++++++ x/interchainstaking/keeper/events.go | 59 ++ 20 files changed, 2662 insertions(+), 3 deletions(-) create mode 100644 x/eventmanager/keeper/conditions.go create mode 100644 x/eventmanager/keeper/events.go create mode 100644 x/eventmanager/keeper/grpc_query.go create mode 100644 x/eventmanager/keeper/grpc_query_test.go create mode 100644 x/eventmanager/keeper/keeper.go create mode 100644 x/eventmanager/keeper/keeper_test.go create mode 100644 x/eventmanager/module.go create mode 100644 x/eventmanager/types/callbacks.go create mode 100644 x/eventmanager/types/codec.go create mode 100644 x/eventmanager/types/fields.go create mode 100644 x/eventmanager/types/genesis.go create mode 100644 x/eventmanager/types/genesis.pb.go create mode 100644 x/eventmanager/types/keys.go create mode 100644 x/eventmanager/types/query.pb.go create mode 100644 x/eventmanager/types/query.pb.gw.go create mode 100644 x/interchainstaking/keeper/events.go diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index b19a59308..e32330f7c 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -67,6 +67,8 @@ import ( claimsmanagertypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" epochskeeper "github.com/quicksilver-zone/quicksilver/x/epochs/keeper" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + emkeeper "github.com/quicksilver-zone/quicksilver/x/eventmanager/keeper" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" interchainquerykeeper "github.com/quicksilver-zone/quicksilver/x/interchainquery/keeper" interchainquerytypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking" @@ -110,6 +112,7 @@ type AppKeepers struct { ClaimsManagerKeeper claimsmanagerkeeper.Keeper InterchainstakingKeeper *interchainstakingkeeper.Keeper InterchainQueryKeeper interchainquerykeeper.Keeper + EventManagerKeeper emkeeper.Keeper ParticipationRewardsKeeper *participationrewardskeeper.Keeper AirdropKeeper *airdropkeeper.Keeper SupplyKeeper supplykeeper.Keeper @@ -376,8 +379,7 @@ func (appKeepers *AppKeepers) InitKeepers( // claimsmanagerModule := claimsmanager.NewAppModule(appCodec, appKeepers.ClaimsManagerKeeper) appKeepers.InterchainQueryKeeper = interchainquerykeeper.NewKeeper(appCodec, appKeepers.keys[interchainquerytypes.StoreKey], appKeepers.IBCKeeper) - - // interchainQueryModule := interchainquery.NewAppModule(appCodec, appKeepers.InterchainQueryKeeper) + appKeepers.EventManagerKeeper = emkeeper.NewKeeper(appCodec, appKeepers.keys[emtypes.StoreKey]) appKeepers.InterchainstakingKeeper = interchainstakingkeeper.NewKeeper( appCodec, @@ -417,7 +419,9 @@ func (appKeepers *AppKeepers) InitKeepers( panic(err) } - // participationrewardsModule := participationrewards.NewAppModule(appCodec, appKeepers.ParticipationRewardsKeeper) + if err := appKeepers.EventManagerKeeper.SetCallbackHandler(interchainstakingtypes.ModuleName, appKeepers.InterchainstakingKeeper.EventCallbackHandler()); err != nil { + panic(err) + } if err := appKeepers.InterchainQueryKeeper.SetCallbackHandler(participationrewardstypes.ModuleName, appKeepers.ParticipationRewardsKeeper.CallbackHandler()); err != nil { panic(err) @@ -534,6 +538,7 @@ func (*AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *cod paramsKeeper.Subspace(minttypes.ModuleName) paramsKeeper.Subspace(interchainstakingtypes.ModuleName) paramsKeeper.Subspace(interchainquerytypes.ModuleName) + paramsKeeper.Subspace(emtypes.ModuleName) paramsKeeper.Subspace(participationrewardstypes.ModuleName) paramsKeeper.Subspace(airdroptypes.ModuleName) diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 56d3e5a70..ba3240dfd 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -26,6 +26,7 @@ import ( airdroptypes "github.com/quicksilver-zone/quicksilver/x/airdrop/types" claimsmanagertypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" interchainquerytypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" interchainstakingtypes "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" minttypes "github.com/quicksilver-zone/quicksilver/x/mint/types" @@ -61,6 +62,7 @@ func KVStoreKeys() []string { epochstypes.StoreKey, interchainstakingtypes.StoreKey, interchainquerytypes.StoreKey, + emtypes.StoreKey, participationrewardstypes.StoreKey, airdroptypes.StoreKey, supplytypes.StoreKey, diff --git a/app/upgrades.go b/app/upgrades.go index ebff9126d..031e15841 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -13,6 +13,7 @@ import ( v6 "github.com/cosmos/ibc-go/v6/testing/simapp/upgrades/v6" // nolint:revive "github.com/quicksilver-zone/quicksilver/app/upgrades" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" supplytypes "github.com/quicksilver-zone/quicksilver/x/supply/types" ) @@ -76,6 +77,10 @@ func (app *Quicksilver) setUpgradeStoreLoaders() { storeUpgrades = &storetypes.StoreUpgrades{ Deleted: []string{wasmModuleName, tfModuleName}, } + case upgrades.V010700UpgradeName: + storeUpgrades = &storetypes.StoreUpgrades{ + Added: []string{emtypes.ModuleName}, + } default: // no-op } diff --git a/app/upgrades/types.go b/app/upgrades/types.go index 7fe437dba..8c1d14910 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -43,6 +43,7 @@ const ( V010504UpgradeName = "v1.5.4" V010505UpgradeName = "v1.5.5" V010601UpgradeName = "v1.6.1" + V010700UpgradeName = "v1.7.0" ) // Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal diff --git a/x/eventmanager/keeper/conditions.go b/x/eventmanager/keeper/conditions.go new file mode 100644 index 000000000..f618ab589 --- /dev/null +++ b/x/eventmanager/keeper/conditions.go @@ -0,0 +1,60 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" +) + +type ConditionI interface { + Resolve(ctx sdk.Context, k *Keeper) bool +} + +// type ConditionExistsAny struct { +// Fields []types.KV +// negate bool +// } + +// func (c ConditionExistsAny) Resolve(ctx sdk.Context, k *Keeper) bool { +// out := false +// k.IterateEvents(ctx, func(index int64, event types.Event) (stop bool) { +// if event.ResolveAnyFieldValues(c.Fields) { +// out := +// } +// } +// return negate ^ out +// } + +type ConditionExistsAll struct { + Fields []types.FieldValue + Negate bool +} + +func (c ConditionExistsAll) Resolve(ctx sdk.Context, k *Keeper) bool { + out := false + k.IteratePrefixedEvents(ctx, nil, func(index int64, event types.Event) (stop bool) { + if event.ResolveAllFieldValues(c.Fields) { + out = true + return true + } + return false + }) + return c.Negate != out +} + +type ConditionAnd struct { + Condition1 ConditionI + Condition2 ConditionI +} + +func (c ConditionAnd) Resolve(ctx sdk.Context, k *Keeper) bool { + return c.Condition1.Resolve(ctx, k) && c.Condition2.Resolve(ctx, k) +} + +type ConditionOr struct { + Condition1 ConditionI + Condition2 ConditionI +} + +func (c ConditionOr) Resolve(ctx sdk.Context, k *Keeper) bool { + return c.Condition1.Resolve(ctx, k) || c.Condition2.Resolve(ctx, k) +} diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go new file mode 100644 index 000000000..615bcff18 --- /dev/null +++ b/x/eventmanager/keeper/events.go @@ -0,0 +1,94 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" +) + +// ---------------------------------------------------------------- + +func GenerateEventKey(module, chainId, id string) []byte { + return []byte(module + chainId + id) +} + +// GetEvent returns event. +func (k Keeper) GetEvent(ctx sdk.Context, module, chainId, id string) (types.Event, bool) { + event := types.Event{} + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) + bz := store.Get(GenerateEventKey(module, chainId, id)) + if len(bz) == 0 { + return event, false + } + k.cdc.MustUnmarshal(bz, &event) + return event, true +} + +// SetEvent set event. +func (k Keeper) SetEvent(ctx sdk.Context, event types.Event) { + key := GenerateEventKey(event.Module, event.ChainId, event.Identifier) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) + bz := k.cdc.MustMarshal(&event) + store.Set(key, bz) +} + +// DeleteEvent delete event. +func (k Keeper) DeleteEvent(ctx sdk.Context, module, chainId, id string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) + store.Delete(GenerateEventKey(module, chainId, id)) +} + +// IterateEvents iterate through queries. +func (k Keeper) IteratePrefixedEvents(ctx sdk.Context, prefixBytes []byte, fn func(index int64, event types.Event) (stop bool)) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) + iterator := sdk.KVStorePrefixIterator(store, prefixBytes) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + event := types.Event{} + k.cdc.MustUnmarshal(iterator.Value(), &event) + stop := fn(i, event) + + if stop { + break + } + i++ + } +} + +func (k Keeper) IterateModuleEvents(ctx sdk.Context, module string, fn func(index int64, event types.Event) (stop bool)) { + k.IteratePrefixedEvents(ctx, []byte(module), fn) +} + +func (k Keeper) IterateModuleChainEvents(ctx sdk.Context, module string, chainId string, fn func(index int64, event types.Event) (stop bool)) { + k.IteratePrefixedEvents(ctx, []byte(module+chainId), fn) +} + +// AllEvents returns every eventInfo in the store. +func (k Keeper) AllEvents(ctx sdk.Context) []types.Event { + queries := []types.Event{} + k.IteratePrefixedEvents(ctx, nil, func(_ int64, eventInfo types.Event) (stop bool) { + queries = append(queries, eventInfo) + return false + }) + return queries +} + +func (k Keeper) MarkCompleted(ctx sdk.Context, module string, chainID string, identifier string) { + k.DeleteEvent(ctx, module, chainID, identifier) + k.Trigger(ctx, module, chainID) +} + +func (k Keeper) Trigger(ctx sdk.Context, module string, chainID string) { + k.IterateModuleChainEvents(ctx, module, chainID, func(_ int64, e types.Event) (stop bool) { + if e.EventStatus == types.EventStatusPending { + err := k.Call(ctx, e.Module, e.Callback, e.Payload) + if err != nil { + k.Logger(ctx).Error("unable to execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) + } + } + return false + }) +} diff --git a/x/eventmanager/keeper/grpc_query.go b/x/eventmanager/keeper/grpc_query.go new file mode 100644 index 000000000..efe70b178 --- /dev/null +++ b/x/eventmanager/keeper/grpc_query.go @@ -0,0 +1,50 @@ +package keeper + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + + "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" +) + +var _ types.QuerySrvrServer = Keeper{} + +// Queries returns information about registered zones. +func (k Keeper) Queries(c context.Context, req *types.QueryRequestsRequest) (*types.QueryRequestsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(c) + + var queries []types.Query + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixQuery) + + pageRes, err := query.FilteredPaginate(store, req.Pagination, func(_, value []byte, accumulate bool) (bool, error) { + var query types.Query + if err := k.cdc.Unmarshal(value, &query); err != nil { + return false, err + } + + if query.ChainId == req.ChainId && (query.LastEmission.IsNil() || query.LastEmission.IsZero() || query.LastEmission.GTE(query.LastHeight)) { + queries = append(queries, query) + return true, nil + } + + return false, nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryRequestsResponse{ + Queries: queries, + Pagination: pageRes, + }, nil +} diff --git a/x/eventmanager/keeper/grpc_query_test.go b/x/eventmanager/keeper/grpc_query_test.go new file mode 100644 index 000000000..2261da547 --- /dev/null +++ b/x/eventmanager/keeper/grpc_query_test.go @@ -0,0 +1,39 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + icqtypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" +) + +func (suite *KeeperTestSuite) TestQueries() { + bondedQuery := stakingtypes.QueryValidatorsRequest{Status: stakingtypes.BondStatusBonded} + bz, err := bondedQuery.Marshal() + suite.NoError(err) + + query := suite.GetSimApp(suite.chainA).InterchainQueryKeeper.NewQuery( + "", + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(200), + "", + 0, + ) + + // set the query + suite.GetSimApp(suite.chainA).InterchainQueryKeeper.SetQuery(suite.chainA.GetContext(), *query) + + icqsrvSrv := icqtypes.QuerySrvrServer(suite.GetSimApp(suite.chainA).InterchainQueryKeeper) + + res, err := icqsrvSrv.Queries(sdk.WrapSDKContext(suite.chainA.GetContext()), &icqtypes.QueryRequestsRequest{ChainId: suite.chainB.ChainID}) + suite.NoError(err) + suite.Len(res.Queries, 1) + suite.Equal(suite.path.EndpointB.ConnectionID, res.Queries[0].ConnectionId) + suite.Equal(suite.chainB.ChainID, res.Queries[0].ChainId) + suite.Equal("cosmos.staking.v1beta1.Query/Validators", res.Queries[0].QueryType) + suite.Equal(sdk.NewInt(200), res.Queries[0].Period) + suite.Equal("", res.Queries[0].CallbackId) +} diff --git a/x/eventmanager/keeper/keeper.go b/x/eventmanager/keeper/keeper.go new file mode 100644 index 000000000..3f93872a6 --- /dev/null +++ b/x/eventmanager/keeper/keeper.go @@ -0,0 +1,58 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" +) + +// Keeper of this module maintains collections of registered zones. +type Keeper struct { + cdc codec.Codec + storeKey storetypes.StoreKey + callbacks map[string]types.EventCallbacks +} + +// NewKeeper returns a new instance of zones Keeper. +func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey) Keeper { + + return Keeper{ + cdc: cdc, + storeKey: storeKey, + callbacks: make(map[string]types.EventCallbacks), + } +} + +func (k *Keeper) SetCallbackHandler(module string, handler types.EventCallbacks) error { + _, found := k.callbacks[module] + if found { + return fmt.Errorf("callback handler already set for %s", module) + } + k.callbacks[module] = handler.RegisterCallbacks() + return nil +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +func (k Keeper) Call(ctx sdk.Context, moduleName string, callbackID string, payload []byte) error { + + module, found := k.callbacks[moduleName] + if !found { + return fmt.Errorf("bad module %s", moduleName) + } + if module.Has(callbackID) { + // we have executed a callback; only a single callback is expected per request, so break here. + return module.Call(ctx, callbackID, payload) + } + + return fmt.Errorf("callback %s not found for module %s", callbackID, moduleName) +} diff --git a/x/eventmanager/keeper/keeper_test.go b/x/eventmanager/keeper/keeper_test.go new file mode 100644 index 000000000..cf4e40bbe --- /dev/null +++ b/x/eventmanager/keeper/keeper_test.go @@ -0,0 +1,208 @@ +package keeper_test + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/suite" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + ibctesting "github.com/cosmos/ibc-go/v5/testing" + + "github.com/quicksilver-zone/quicksilver/app" + "github.com/quicksilver-zone/quicksilver/x/interchainquery/keeper" + icqtypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" +) + +const TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + +func init() { + ibctesting.DefaultTestingAppInit = app.SetupTestingApp +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +type KeeperTestSuite struct { + suite.Suite + + coordinator *ibctesting.Coordinator + + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain + path *ibctesting.Path +} + +func (suite *KeeperTestSuite) GetSimApp(chain *ibctesting.TestChain) *app.Quicksilver { + quicksilver, ok := chain.App.(*app.Quicksilver) + if !ok { + panic("not quicksilver app") + } + + return quicksilver +} + +func (suite *KeeperTestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) + + suite.path = newSimAppPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(suite.path) +} + +func (suite *KeeperTestSuite) TestMakeRequest() { + bondedQuery := stakingtypes.QueryValidatorsRequest{Status: stakingtypes.BondStatusBonded} + bz, err := bondedQuery.Marshal() + suite.NoError(err) + + suite.GetSimApp(suite.chainA).InterchainQueryKeeper.MakeRequest( + suite.chainA.GetContext(), + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(200), + "", + "", + 0, + ) + + id := keeper.GenerateQueryHash(suite.path.EndpointB.ConnectionID, suite.chainB.ChainID, "cosmos.staking.v1beta1.Query/Validators", bz, "", "") + query, found := suite.GetSimApp(suite.chainA).InterchainQueryKeeper.GetQuery(suite.chainA.GetContext(), id) + suite.True(found) + suite.Equal(suite.path.EndpointB.ConnectionID, query.ConnectionId) + suite.Equal(suite.chainB.ChainID, query.ChainId) + suite.Equal("cosmos.staking.v1beta1.Query/Validators", query.QueryType) + suite.Equal(sdk.NewInt(200), query.Period) + suite.Equal("", query.CallbackId) + + suite.GetSimApp(suite.chainA).InterchainQueryKeeper.MakeRequest( + suite.chainA.GetContext(), + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(200), + "", + "", + 0, + ) +} + +func (suite *KeeperTestSuite) TestSubmitQueryResponse() { + bondedQuery := stakingtypes.QueryValidatorsRequest{Status: stakingtypes.BondStatusBonded} + bz, err := bondedQuery.Marshal() + suite.NoError(err) + + qvr := stakingtypes.QueryValidatorsResponse{ + Validators: suite.GetSimApp(suite.chainB).StakingKeeper.GetBondedValidatorsByPower(suite.chainB.GetContext()), + } + + tests := []struct { + query *icqtypes.Query + setQuery bool + expectError error + }{ + { + suite.GetSimApp(suite.chainA).InterchainQueryKeeper. + NewQuery( + "", + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(200), + "", + 0, + ), + true, + nil, + }, + { + suite.GetSimApp(suite.chainA).InterchainQueryKeeper. + NewQuery( + "", + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(200), + "", + 10, + ), + true, + nil, + }, + { + suite.GetSimApp(suite.chainA).InterchainQueryKeeper. + NewQuery( + "", + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(-200), + "", + 0, + ), + true, + nil, + }, + { + suite.GetSimApp(suite.chainA).InterchainQueryKeeper. + NewQuery( + "", + suite.path.EndpointB.ConnectionID, + suite.chainB.ChainID, + "cosmos.staking.v1beta1.Query/Validators", + bz, + sdk.NewInt(100), + "", + 0, + ), + false, + nil, + }, + } + + for _, tc := range tests { + // set the query + if tc.setQuery { + suite.GetSimApp(suite.chainA).InterchainQueryKeeper.SetQuery(suite.chainA.GetContext(), *tc.query) + } + + icqmsgSrv := keeper.NewMsgServerImpl(suite.GetSimApp(suite.chainA).InterchainQueryKeeper) + + qmsg := icqtypes.MsgSubmitQueryResponse{ + ChainId: suite.chainB.ChainID, + QueryId: keeper.GenerateQueryHash(tc.query.ConnectionId, tc.query.ChainId, tc.query.QueryType, bz, "", ""), + Result: suite.GetSimApp(suite.chainB).AppCodec().MustMarshalJSON(&qvr), + Height: suite.chainB.CurrentHeader.Height, + FromAddress: TestOwnerAddress, + } + + _, err = icqmsgSrv.SubmitQueryResponse(sdk.WrapSDKContext(suite.chainA.GetContext()), &qmsg) + suite.Equal(tc.expectError, err) + } +} + +func newSimAppPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort + + return path +} + +func (suite *KeeperTestSuite) TestLatestHeight() { + height := rand.Uint64() + chainID := "test" + + suite.GetSimApp(suite.chainA).InterchainQueryKeeper.SetLatestHeight(suite.chainA.GetContext(), chainID, height) + got := suite.GetSimApp(suite.chainA).InterchainQueryKeeper.GetLatestHeight(suite.chainA.GetContext(), chainID) + suite.Require().Equal(height, got) +} diff --git a/x/eventmanager/module.go b/x/eventmanager/module.go new file mode 100644 index 000000000..ed6fb6262 --- /dev/null +++ b/x/eventmanager/module.go @@ -0,0 +1,178 @@ +package interchainquery + +import ( + "context" + "encoding/json" + "math/rand" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/quicksilver-zone/quicksilver/x/interchainquery/keeper" + "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" +) + +var ( + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModule = AppModule{} + _ module.AppModuleSimulation = AppModule{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct { + cdc codec.Codec +} + +// NewAppModuleBasic return a new AppModuleBasic. +func NewAppModuleBasic(cdc codec.Codec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the capability module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers a legacy amino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { +} + +// RegisterInterfaces registers the module's interface types. +func (AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { +} + +// DefaultGenesis returns the capability module's default genesis state. +func (AppModuleBasic) DefaultGenesis(_ codec.JSONCodec) json.RawMessage { + return nil +} + +// ValidateGenesis performs genesis state validation for the capability module. +func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, _ json.RawMessage) error { + return nil +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + err := types.RegisterQuerySrvrHandlerClient(context.Background(), mux, types.NewQuerySrvrClient(clientCtx)) + if err != nil { + panic(err) + } +} + +// GetTxCmd returns the capability module's root tx command. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper +} + +// NewAppModule return a new AppModule. +func NewAppModule(cdc codec.Codec, k keeper.Keeper) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: k, + } +} + +// Name returns the capability module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the capability module's message routing key. +func (AppModule) Route() sdk.Route { + return sdk.Route{} +} + +// QuerierRoute returns the capability module's query routing key. +func (AppModule) QuerierRoute() string { return types.QuerierRoute } + +// LegacyQuerierHandler returns the capability module's Querier. +func (AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterQuerySrvrServer(cfg.QueryServer(), am.keeper) +} + +// RegisterInvariants registers the capability module's invariants. +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the capability module's genesis initialization It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return nil +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. +func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { +} + +// EndBlock executes all ABCI EndBlock logic respective to the capability module. It +// returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// ___________________________________________________________________________ + +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the pool-incentives module. +func (AppModule) GenerateGenesisState(_ *module.SimulationState) { +} + +// ProposalContents doesn't return any content functions for governance proposals. +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { + return nil +} + +// RandomizedParams creates randomized pool-incentives param changes for the simulator. +func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { + return nil +} + +// RegisterStoreDecoder registers a decoder for supply module's types. +func (AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { +} + +// WeightedOperations returns the all the gov module operations with their respective weights. +func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil // TODO add operations +} diff --git a/x/eventmanager/types/callbacks.go b/x/eventmanager/types/callbacks.go new file mode 100644 index 000000000..df8b15b44 --- /dev/null +++ b/x/eventmanager/types/callbacks.go @@ -0,0 +1,12 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type EventCallbacks interface { + AddCallback(id string, fn interface{}) EventCallbacks + RegisterCallbacks() EventCallbacks + Call(ctx sdk.Context, id string, args []byte) error + Has(id string) bool +} diff --git a/x/eventmanager/types/codec.go b/x/eventmanager/types/codec.go new file mode 100644 index 000000000..0836bbdad --- /dev/null +++ b/x/eventmanager/types/codec.go @@ -0,0 +1,25 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewAminoCodec(amino) +) + +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { +} + +func RegisterInterfaces(registry types.InterfaceRegistry) { +} + +func init() { + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + sdk.RegisterLegacyAminoCodec(amino) +} diff --git a/x/eventmanager/types/fields.go b/x/eventmanager/types/fields.go new file mode 100644 index 000000000..322fdd1f0 --- /dev/null +++ b/x/eventmanager/types/fields.go @@ -0,0 +1,67 @@ +package types + +import ( + "strconv" + "strings" +) + +type FieldValue struct { + Field string + Value string + Negate bool +} + +func (e Event) ResolveAllFieldValues(fvs []FieldValue) bool { + for _, fv := range fvs { + if !e.resolveFieldValue(fv) { + return false + } + } + return true +} + +func (e Event) ResolveAnyFieldValues(fvs []FieldValue) bool { + for _, fv := range fvs { + if e.resolveFieldValue(fv) { + return true + } + } + return false +} + +func (e Event) resolveFieldValue(fv FieldValue) bool { + + if strings.ToLower(fv.Field) == "eventtype" { + v, err := strconv.ParseInt(fv.Value, 10, 32) + if err != nil { + return fv.Negate + } + if v == int64(e.EventType) { + return !fv.Negate + } + return fv.Negate + } + + if strings.ToLower(fv.Field) == "eventstatus" { + v, err := strconv.ParseInt(fv.Value, 10, 32) + if err != nil { + return fv.Negate + } + if v == int64(e.EventType) { + return !fv.Negate + } + return fv.Negate + } + + if strings.ToLower(fv.Field) == "module" && fv.Value == e.Module { + return !fv.Negate + } + if strings.ToLower(fv.Field) == "identifier" && fv.Value == e.Identifier { + return !fv.Negate + } + if strings.ToLower(fv.Field) == "chainid" && fv.Value == e.ChainId { + return !fv.Negate + } + + return fv.Negate +} diff --git a/x/eventmanager/types/genesis.go b/x/eventmanager/types/genesis.go new file mode 100644 index 000000000..15e83fd5d --- /dev/null +++ b/x/eventmanager/types/genesis.go @@ -0,0 +1,12 @@ +package types + +// DefaultGenesisState returns the default Capability genesis state. +func DefaultGenesisState() *GenesisState { + return &GenesisState{} +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (GenesisState) Validate() error { + return nil +} diff --git a/x/eventmanager/types/genesis.pb.go b/x/eventmanager/types/genesis.pb.go new file mode 100644 index 000000000..8f5b71584 --- /dev/null +++ b/x/eventmanager/types/genesis.pb.go @@ -0,0 +1,818 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: quicksilver/eventmanager/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Event struct { + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + EventType int32 `protobuf:"varint,2,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` + Identifier string `protobuf:"bytes,3,opt,name=identifier,proto3" json:"identifier,omitempty"` + EventStatus int32 `protobuf:"varint,4,opt,name=event_status,json=eventStatus,proto3" json:"event_status,omitempty"` + Module string `protobuf:"bytes,5,opt,name=module,proto3" json:"module,omitempty"` + Callback string `protobuf:"bytes,6,opt,name=callback,proto3" json:"callback,omitempty"` + Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"` + ExecuteCondition []byte `protobuf:"bytes,8,opt,name=execute_condition,json=executeCondition,proto3" json:"execute_condition,omitempty"` + EmittedHeight int64 `protobuf:"varint,9,opt,name=emitted_height,json=emittedHeight,proto3" json:"emitted_height,omitempty"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{0} +} +func (m *Event) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Event.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Event) XXX_Merge(src proto.Message) { + xxx_messageInfo_Event.Merge(m, src) +} +func (m *Event) XXX_Size() int { + return m.Size() +} +func (m *Event) XXX_DiscardUnknown() { + xxx_messageInfo_Event.DiscardUnknown(m) +} + +var xxx_messageInfo_Event proto.InternalMessageInfo + +func (m *Event) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +func (m *Event) GetEventType() int32 { + if m != nil { + return m.EventType + } + return 0 +} + +func (m *Event) GetIdentifier() string { + if m != nil { + return m.Identifier + } + return "" +} + +func (m *Event) GetEventStatus() int32 { + if m != nil { + return m.EventStatus + } + return 0 +} + +func (m *Event) GetModule() string { + if m != nil { + return m.Module + } + return "" +} + +func (m *Event) GetCallback() string { + if m != nil { + return m.Callback + } + return "" +} + +func (m *Event) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *Event) GetExecuteCondition() []byte { + if m != nil { + return m.ExecuteCondition + } + return nil +} + +func (m *Event) GetEmittedHeight() int64 { + if m != nil { + return m.EmittedHeight + } + return 0 +} + +// GenesisState defines the eventmanager module's genesis state. +type GenesisState struct { +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{1} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Event)(nil), "quicksilver.eventmanager.v1.Event") + proto.RegisterType((*GenesisState)(nil), "quicksilver.eventmanager.v1.GenesisState") +} + +func init() { + proto.RegisterFile("quicksilver/eventmanager/v1/genesis.proto", fileDescriptor_74127b30ab787dbd) +} + +var fileDescriptor_74127b30ab787dbd = []byte{ + // 390 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0xcd, 0x6e, 0xd4, 0x30, + 0x14, 0x85, 0xc7, 0x2d, 0xf3, 0x67, 0x86, 0x0a, 0x2c, 0x84, 0xcc, 0x20, 0x4c, 0xa8, 0x84, 0x14, + 0x84, 0x88, 0x55, 0xb1, 0x65, 0x05, 0x42, 0xc0, 0x36, 0x20, 0x16, 0x6c, 0x22, 0x27, 0xbe, 0x75, + 0xac, 0x26, 0x76, 0x48, 0x9c, 0xa8, 0xc3, 0x53, 0xf0, 0x14, 0x3c, 0x0b, 0xcb, 0x2e, 0x59, 0xa2, + 0x99, 0x17, 0x41, 0x71, 0x52, 0x14, 0xba, 0xcb, 0xf9, 0xce, 0x39, 0xc9, 0xd5, 0xbd, 0xc1, 0xcf, + 0xbf, 0xb5, 0x3a, 0xbb, 0x68, 0x74, 0xd1, 0x41, 0xcd, 0xa1, 0x03, 0xe3, 0x4a, 0x61, 0x84, 0x82, + 0x9a, 0x77, 0x67, 0x5c, 0x81, 0x81, 0x46, 0x37, 0x51, 0x55, 0x5b, 0x67, 0xc9, 0xa3, 0x49, 0x34, + 0x9a, 0x46, 0xa3, 0xee, 0x6c, 0x7b, 0x5f, 0x59, 0x65, 0x7d, 0x8e, 0xf7, 0x4f, 0x43, 0x65, 0xcb, + 0x94, 0xb5, 0xaa, 0x00, 0xee, 0x55, 0xda, 0x9e, 0x73, 0xd9, 0xd6, 0xc2, 0x69, 0x6b, 0x46, 0xff, + 0xc9, 0x4d, 0xdf, 0xe9, 0x12, 0x1a, 0x27, 0xca, 0x6a, 0x08, 0x9c, 0xfe, 0x3c, 0xc2, 0xf3, 0x77, + 0xfd, 0xa7, 0xc8, 0x43, 0xbc, 0xca, 0x72, 0xa1, 0x4d, 0xa2, 0x25, 0x45, 0x01, 0x0a, 0xd7, 0xf1, + 0xd2, 0xeb, 0x8f, 0x92, 0x3c, 0xc6, 0xd8, 0x8f, 0x93, 0xb8, 0x5d, 0x05, 0xf4, 0x28, 0x40, 0xe1, + 0x3c, 0x5e, 0x7b, 0xf2, 0x79, 0x57, 0x01, 0x61, 0x18, 0x6b, 0x09, 0xc6, 0xe9, 0x73, 0x0d, 0x35, + 0x3d, 0xf6, 0xdd, 0x09, 0x21, 0x4f, 0xf1, 0x66, 0xa8, 0x37, 0x4e, 0xb8, 0xb6, 0xa1, 0xb7, 0xfc, + 0x0b, 0x6e, 0x7b, 0xf6, 0xc9, 0x23, 0xf2, 0x00, 0x2f, 0x4a, 0x2b, 0xdb, 0x02, 0xe8, 0xdc, 0xd7, + 0x47, 0x45, 0xb6, 0x78, 0x95, 0x89, 0xa2, 0x48, 0x45, 0x76, 0x41, 0x17, 0xde, 0xf9, 0xa7, 0x09, + 0xc5, 0xcb, 0x4a, 0xec, 0x0a, 0x2b, 0x24, 0x5d, 0x06, 0x28, 0xdc, 0xc4, 0xd7, 0x92, 0xbc, 0xc0, + 0xf7, 0xe0, 0x12, 0xb2, 0xd6, 0x41, 0x92, 0x59, 0x23, 0x75, 0xbf, 0x10, 0xba, 0xf2, 0x99, 0xbb, + 0xa3, 0xf1, 0xf6, 0x9a, 0x93, 0x67, 0xf8, 0x04, 0x4a, 0xed, 0x1c, 0xc8, 0x24, 0x07, 0xad, 0x72, + 0x47, 0xd7, 0x01, 0x0a, 0x8f, 0xe3, 0x3b, 0x23, 0xfd, 0xe0, 0xe1, 0xe9, 0x09, 0xde, 0xbc, 0x1f, + 0xae, 0xd5, 0x8f, 0x0c, 0x6f, 0xbe, 0xfc, 0xda, 0x33, 0x74, 0xb5, 0x67, 0xe8, 0xcf, 0x9e, 0xa1, + 0x1f, 0x07, 0x36, 0xbb, 0x3a, 0xb0, 0xd9, 0xef, 0x03, 0x9b, 0x7d, 0x7d, 0xad, 0xb4, 0xcb, 0xdb, + 0x34, 0xca, 0x6c, 0xc9, 0x27, 0x17, 0x7d, 0xf9, 0xdd, 0x1a, 0x98, 0x02, 0x7e, 0xf9, 0xff, 0xff, + 0xd0, 0x2f, 0xb7, 0x49, 0x17, 0xfe, 0x2e, 0xaf, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x64, 0x4b, + 0x05, 0x58, 0x38, 0x02, 0x00, 0x00, +} + +func (m *Event) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Event) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Event) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.EmittedHeight != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.EmittedHeight)) + i-- + dAtA[i] = 0x48 + } + if len(m.ExecuteCondition) > 0 { + i -= len(m.ExecuteCondition) + copy(dAtA[i:], m.ExecuteCondition) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ExecuteCondition))) + i-- + dAtA[i] = 0x42 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x3a + } + if len(m.Callback) > 0 { + i -= len(m.Callback) + copy(dAtA[i:], m.Callback) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Callback))) + i-- + dAtA[i] = 0x32 + } + if len(m.Module) > 0 { + i -= len(m.Module) + copy(dAtA[i:], m.Module) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Module))) + i-- + dAtA[i] = 0x2a + } + if m.EventStatus != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.EventStatus)) + i-- + dAtA[i] = 0x20 + } + if len(m.Identifier) > 0 { + i -= len(m.Identifier) + copy(dAtA[i:], m.Identifier) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Identifier))) + i-- + dAtA[i] = 0x1a + } + if m.EventType != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.EventType)) + i-- + dAtA[i] = 0x10 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Event) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.EventType != 0 { + n += 1 + sovGenesis(uint64(m.EventType)) + } + l = len(m.Identifier) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.EventStatus != 0 { + n += 1 + sovGenesis(uint64(m.EventStatus)) + } + l = len(m.Module) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Callback) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.ExecuteCondition) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.EmittedHeight != 0 { + n += 1 + sovGenesis(uint64(m.EmittedHeight)) + } + return n +} + +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Event) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Event: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EventType", wireType) + } + m.EventType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EventType |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EventStatus", wireType) + } + m.EventStatus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EventStatus |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Module", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Module = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Callback", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Callback = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecuteCondition", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExecuteCondition = append(m.ExecuteCondition[:0], dAtA[iNdEx:postIndex]...) + if m.ExecuteCondition == nil { + m.ExecuteCondition = []byte{} + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EmittedHeight", wireType) + } + m.EmittedHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EmittedHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/eventmanager/types/keys.go b/x/eventmanager/types/keys.go new file mode 100644 index 000000000..43a881df6 --- /dev/null +++ b/x/eventmanager/types/keys.go @@ -0,0 +1,36 @@ +package types + +const ( + // ModuleName defines the module name. + ModuleName = "eventmanager" + + // StoreKey defines the primary module store key. + StoreKey = ModuleName + + // RouterKey is the message route for interchainquery. + RouterKey = ModuleName + + // QuerierRoute defines the module's query routing key. + QuerierRoute = ModuleName +) + +const ( + EventStatusUnspecified = 0 + EventStatusActive = 1 + EventStatusPending = 2 +) + +const ( + EventTypeUnspecified = 0x00 + EventTypeICQQueryRewards = 0x01 + EventTypeICQQueryDelegations = 0x02 + EventTypeICQAccountBalances = 0x03 + EventTypeICQAccountBalance = 0x04 + EventTypeICAWithdrawRewards = 0x05 + EventTypeICADelegate = 0x06 + EventTypeICAUnbond = 0x07 +) + +var ( + KeyPrefixEvent = []byte{0x01} +) diff --git a/x/eventmanager/types/query.pb.go b/x/eventmanager/types/query.pb.go new file mode 100644 index 000000000..053d01497 --- /dev/null +++ b/x/eventmanager/types/query.pb.go @@ -0,0 +1,723 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: quicksilver/eventmanager/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type QueryEventsRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` + ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (m *QueryEventsRequest) Reset() { *m = QueryEventsRequest{} } +func (m *QueryEventsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryEventsRequest) ProtoMessage() {} +func (*QueryEventsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e5e5a2821b1a7196, []int{0} +} +func (m *QueryEventsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryEventsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryEventsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryEventsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryEventsRequest.Merge(m, src) +} +func (m *QueryEventsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryEventsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryEventsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryEventsRequest proto.InternalMessageInfo + +func (m *QueryEventsRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +func (m *QueryEventsRequest) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +type QueryEventsResponse struct { + Events []Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryEventsResponse) Reset() { *m = QueryEventsResponse{} } +func (m *QueryEventsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryEventsResponse) ProtoMessage() {} +func (*QueryEventsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e5e5a2821b1a7196, []int{1} +} +func (m *QueryEventsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryEventsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryEventsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryEventsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryEventsResponse.Merge(m, src) +} +func (m *QueryEventsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryEventsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryEventsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryEventsResponse proto.InternalMessageInfo + +func (m *QueryEventsResponse) GetEvents() []Event { + if m != nil { + return m.Events + } + return nil +} + +func (m *QueryEventsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +func init() { + proto.RegisterType((*QueryEventsRequest)(nil), "quicksilver.eventmanager.v1.QueryEventsRequest") + proto.RegisterType((*QueryEventsResponse)(nil), "quicksilver.eventmanager.v1.QueryEventsResponse") +} + +func init() { + proto.RegisterFile("quicksilver/eventmanager/v1/query.proto", fileDescriptor_e5e5a2821b1a7196) +} + +var fileDescriptor_e5e5a2821b1a7196 = []byte{ + // 401 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xb1, 0xae, 0xd3, 0x30, + 0x14, 0x86, 0xe3, 0x02, 0x05, 0x7c, 0x37, 0xc3, 0x50, 0x0a, 0x0a, 0x55, 0x06, 0x6e, 0x41, 0xc2, + 0xbe, 0x29, 0x12, 0x13, 0x03, 0xba, 0x12, 0x20, 0x36, 0xc8, 0xc0, 0xc0, 0x82, 0x9c, 0xf4, 0xc8, + 0xb5, 0x68, 0xed, 0x34, 0x76, 0x02, 0x05, 0xb1, 0xf0, 0x04, 0x48, 0xbc, 0x00, 0x12, 0x33, 0xef, + 0xd1, 0xb1, 0x12, 0x0b, 0x13, 0x42, 0x2d, 0x0f, 0x82, 0x62, 0x07, 0x91, 0x08, 0x29, 0xb0, 0x9d, + 0xc4, 0xff, 0x7f, 0xfe, 0xef, 0x1c, 0x1b, 0x1f, 0xaf, 0x4b, 0x99, 0xbd, 0x34, 0x72, 0x59, 0x41, + 0xc1, 0xa0, 0x02, 0x65, 0x57, 0x5c, 0x71, 0x01, 0x05, 0xab, 0x62, 0xb6, 0x2e, 0xa1, 0xd8, 0xd0, + 0xbc, 0xd0, 0x56, 0x93, 0xab, 0x2d, 0x21, 0x6d, 0x0b, 0x69, 0x15, 0x8f, 0x6f, 0x65, 0xda, 0xac, + 0xb4, 0x61, 0x29, 0x37, 0xe0, 0x5d, 0xac, 0x8a, 0x53, 0xb0, 0x3c, 0x66, 0x39, 0x17, 0x52, 0x71, + 0x2b, 0xb5, 0xf2, 0x8d, 0xc6, 0x97, 0x85, 0x16, 0xda, 0x95, 0xac, 0xae, 0x9a, 0xbf, 0xd7, 0x84, + 0xd6, 0x62, 0x09, 0x8c, 0xe7, 0x92, 0x71, 0xa5, 0xb4, 0x75, 0x16, 0xd3, 0x9c, 0xde, 0xec, 0xa3, + 0x14, 0xa0, 0xc0, 0xc8, 0x46, 0x1a, 0xbd, 0xc2, 0xe4, 0x69, 0x0d, 0xf0, 0xa0, 0x56, 0x99, 0x04, + 0xd6, 0x25, 0x18, 0x4b, 0x1e, 0x62, 0xfc, 0x07, 0x64, 0x84, 0x26, 0x68, 0x7a, 0x34, 0xbb, 0x41, + 0x3d, 0x35, 0xad, 0xa9, 0xa9, 0x9f, 0xb5, 0xa1, 0xa6, 0x4f, 0xb8, 0x80, 0xc6, 0x9b, 0xb4, 0x9c, + 0xe4, 0x0a, 0xbe, 0x90, 0x2d, 0xb8, 0x54, 0x2f, 0xe4, 0x7c, 0x34, 0x98, 0xa0, 0xe9, 0xc5, 0xe4, + 0xbc, 0xfb, 0x7e, 0x3c, 0x8f, 0x3e, 0x21, 0x7c, 0xa9, 0x93, 0x6c, 0x72, 0xad, 0x0c, 0x90, 0xfb, + 0x78, 0xe8, 0x88, 0xcd, 0x08, 0x4d, 0xce, 0x4c, 0x8f, 0x66, 0x11, 0xed, 0xd9, 0x24, 0x75, 0xe6, + 0xd3, 0xb3, 0xdb, 0xef, 0xd7, 0x83, 0xa4, 0xf1, 0x91, 0x47, 0x1d, 0xf8, 0x81, 0x83, 0x3f, 0xfe, + 0x27, 0xbc, 0x8f, 0x6f, 0xd3, 0xcf, 0xbe, 0x20, 0x7c, 0xce, 0x21, 0x92, 0xcf, 0x08, 0x0f, 0x3d, + 0x27, 0x61, 0xbd, 0x3c, 0x7f, 0xef, 0x72, 0x7c, 0xf2, 0xff, 0x06, 0xcf, 0x10, 0xdd, 0x7d, 0xff, + 0xf5, 0xe7, 0xc7, 0xc1, 0x09, 0xa1, 0xac, 0xef, 0x1e, 0xfd, 0xb4, 0xec, 0xed, 0xef, 0x05, 0xbf, + 0x3b, 0x7d, 0xb6, 0xdd, 0x87, 0x68, 0xb7, 0x0f, 0xd1, 0x8f, 0x7d, 0x88, 0x3e, 0x1c, 0xc2, 0x60, + 0x77, 0x08, 0x83, 0x6f, 0x87, 0x30, 0x78, 0x7e, 0x4f, 0x48, 0xbb, 0x28, 0x53, 0x9a, 0xe9, 0x55, + 0xbb, 0xe7, 0xed, 0x37, 0x5a, 0x41, 0x27, 0xe4, 0x75, 0x37, 0xc6, 0x6e, 0x72, 0x30, 0xe9, 0xd0, + 0x3d, 0x95, 0x3b, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x7a, 0xce, 0x8a, 0xaa, 0xfd, 0x02, 0x00, + 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Events query events + Events(ctx context.Context, in *QueryEventsRequest, opts ...grpc.CallOption) (*QueryEventsResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Events(ctx context.Context, in *QueryEventsRequest, opts ...grpc.CallOption) (*QueryEventsResponse, error) { + out := new(QueryEventsResponse) + err := c.cc.Invoke(ctx, "/quicksilver.eventmanager.v1.Query/Events", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Events query events + Events(context.Context, *QueryEventsRequest) (*QueryEventsResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Events(ctx context.Context, req *QueryEventsRequest) (*QueryEventsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Events not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Events_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryEventsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Events(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/quicksilver.eventmanager.v1.Query/Events", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Events(ctx, req.(*QueryEventsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "quicksilver.eventmanager.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Events", + Handler: _Query_Events_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "quicksilver/eventmanager/v1/query.proto", +} + +func (m *QueryEventsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryEventsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryEventsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x12 + } + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryEventsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryEventsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryEventsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryEventsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryEventsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryEventsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryEventsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryEventsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryEventsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryEventsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryEventsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/eventmanager/types/query.pb.gw.go b/x/eventmanager/types/query.pb.gw.go new file mode 100644 index 000000000..ba7f6f95c --- /dev/null +++ b/x/eventmanager/types/query.pb.gw.go @@ -0,0 +1,207 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: quicksilver/eventmanager/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +var ( + filter_Query_Events_0 = &utilities.DoubleArray{Encoding: map[string]int{"chain_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_Events_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryEventsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Events_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Events(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Events_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryEventsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Events_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Events(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Events_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Events_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Events_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Events_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Events_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Events_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Events_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"quicksilver", "eventmanager", "v1", "events", "chain_id"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_Events_0 = runtime.ForwardResponseMessage +) diff --git a/x/interchainstaking/keeper/events.go b/x/interchainstaking/keeper/events.go new file mode 100644 index 000000000..8b120d1e9 --- /dev/null +++ b/x/interchainstaking/keeper/events.go @@ -0,0 +1,59 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" +) + +// ___________________________________________________________________________________________________ + +type EventCallback func(*Keeper, sdk.Context, []byte) error + +// Callbacks wrapper struct for interchainstaking keeper. +type EventCallbacks struct { + k *Keeper + callbacks map[string]EventCallback +} + +var _ emtypes.EventCallbacks = EventCallbacks{} + +func (k *Keeper) EventCallbackHandler() EventCallbacks { + return EventCallbacks{k, make(map[string]EventCallback)} +} + +// Call calls callback handler. +func (c EventCallbacks) Call(ctx sdk.Context, id string, args []byte) error { + if !c.Has(id) { + return fmt.Errorf("callback %s not found", id) + } + return c.callbacks[id](c.k, ctx, args) +} + +func (c EventCallbacks) Has(id string) bool { + _, found := c.callbacks[id] + return found +} + +func (c EventCallbacks) AddCallback(id string, fn interface{}) emtypes.EventCallbacks { + c.callbacks[id], _ = fn.(EventCallback) + return c +} + +func (c EventCallbacks) RegisterCallbacks() emtypes.EventCallbacks { + a := c. + AddCallback("valset", EventCallback(TestCallback)) + + return a.(EventCallbacks) +} + +// ----------------------------------- +// Callback Handlers +// ----------------------------------- + +func TestCallback(k *Keeper, ctx sdk.Context, args []byte) error { + k.Logger(ctx).Error("TEST CALLBACK") + return nil +} From 31546c3d32cef0c50667066a3c32c8c441bda843 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Fri, 5 Apr 2024 13:02:02 +0100 Subject: [PATCH 02/14] wip --- app/keepers/keepers.go | 1 + .../quicksilver/eventmanager/v1/genesis.proto | 23 ++++++++++++++++ proto/quicksilver/eventmanager/v1/query.proto | 27 +++++++++++++++++++ x/eventmanager/keeper/conditions.go | 1 + x/eventmanager/keeper/events.go | 20 ++++++++++++++ x/interchainstaking/keeper/keeper.go | 3 +++ x/interchainstaking/types/expected_keepers.go | 5 ++++ 7 files changed, 80 insertions(+) create mode 100644 proto/quicksilver/eventmanager/v1/genesis.proto create mode 100644 proto/quicksilver/eventmanager/v1/query.proto diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index e32330f7c..3d64a7b6f 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -392,6 +392,7 @@ func (appKeepers *AppKeepers) InitKeepers( appKeepers.IBCKeeper, appKeepers.TransferKeeper, appKeepers.ClaimsManagerKeeper, + appKeepers.EventManagerKeeper, appKeepers.GetSubspace(interchainstakingtypes.ModuleName), ) diff --git a/proto/quicksilver/eventmanager/v1/genesis.proto b/proto/quicksilver/eventmanager/v1/genesis.proto new file mode 100644 index 000000000..67f973a55 --- /dev/null +++ b/proto/quicksilver/eventmanager/v1/genesis.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package quicksilver.eventmanager.v1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/quicksilver-zone/quicksilver/x/eventmanager/types"; + +message Event { + string chain_id = 1; + int32 event_type = 2; + string identifier = 3; + int32 event_status = 4; + string module = 5; + string callback = 6; + bytes payload = 7; + bytes execute_condition = 8; + int64 emitted_height = 9; +} + +// GenesisState defines the eventmanager module's genesis state. +message GenesisState {} diff --git a/proto/quicksilver/eventmanager/v1/query.proto b/proto/quicksilver/eventmanager/v1/query.proto new file mode 100644 index 000000000..aa39ba0d2 --- /dev/null +++ b/proto/quicksilver/eventmanager/v1/query.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package quicksilver.eventmanager.v1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "quicksilver/eventmanager/v1/genesis.proto"; + +option go_package = "github.com/quicksilver-zone/quicksilver/x/eventmanager/types"; + +// Query defines the gRPC querier service. +service Query { + // Events query events + rpc Events(QueryEventsRequest) returns (QueryEventsResponse) { + option (google.api.http).get = "/quicksilver/eventmanager/v1/events/{chain_id}"; + } +} + +message QueryEventsRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; + string chain_id = 2; +} + +message QueryEventsResponse { + repeated Event events = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/x/eventmanager/keeper/conditions.go b/x/eventmanager/keeper/conditions.go index f618ab589..d7d9f3fb6 100644 --- a/x/eventmanager/keeper/conditions.go +++ b/x/eventmanager/keeper/conditions.go @@ -7,6 +7,7 @@ import ( type ConditionI interface { Resolve(ctx sdk.Context, k *Keeper) bool + Marshal(ctx sdk.Context) []byte } // type ConditionExistsAny struct { diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go index 615bcff18..5e534c8d5 100644 --- a/x/eventmanager/keeper/events.go +++ b/x/eventmanager/keeper/events.go @@ -92,3 +92,23 @@ func (k Keeper) Trigger(ctx sdk.Context, module string, chainID string) { return false }) } + +func (k Keeper) AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, status int32, condition ConditionI, payload []byte) error { + conditionBytes := []byte{} + if condition != nil { + conditionBytes = condition.Marshal() + } + + event := types.Event{ + ChainId: chainID, + Module: module, + Identifier: identifier, + Callback: callback, + Payload: payload, + EventStatus: status, + ExecuteCondition: conditionBytes, + EmittedHeight: ctx.BlockHeight(), + } + + k.SetEvent(ctx, event) +} diff --git a/x/interchainstaking/keeper/keeper.go b/x/interchainstaking/keeper/keeper.go index 49d664323..172856633 100644 --- a/x/interchainstaking/keeper/keeper.go +++ b/x/interchainstaking/keeper/keeper.go @@ -57,6 +57,7 @@ type Keeper struct { TransferKeeper ibctransferkeeper.Keeper ClaimsManagerKeeper types.ClaimsManagerKeeper EpochsKeeper types.EpochsKeeper + EventManagerKeeper types.EventManagerKeeper Ir codectypes.InterfaceRegistry hooks types.IcsHooks paramStore paramtypes.Subspace @@ -76,6 +77,7 @@ func NewKeeper( ibcKeeper *ibckeeper.Keeper, transferKeeper ibctransferkeeper.Keeper, claimsManagerKeeper types.ClaimsManagerKeeper, + eventManagerKeeper types.EventManagerKeeper, ps paramtypes.Subspace, ) *Keeper { if addr := accountKeeper.GetModuleAddress(types.ModuleName); addr == nil { @@ -105,6 +107,7 @@ func NewKeeper( IBCKeeper: ibcKeeper, TransferKeeper: transferKeeper, ClaimsManagerKeeper: claimsManagerKeeper, + EventManagerKeeper: eventManagerKeeper, hooks: nil, txSubmit: ProdSubmitTx, paramStore: ps, diff --git a/x/interchainstaking/types/expected_keepers.go b/x/interchainstaking/types/expected_keepers.go index 691154777..8a5645e40 100644 --- a/x/interchainstaking/types/expected_keepers.go +++ b/x/interchainstaking/types/expected_keepers.go @@ -9,6 +9,7 @@ import ( claimsmanagertypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + emkeeper "github.com/quicksilver-zone/quicksilver/x/eventmanager/keeper" ) // ChannelKeeper defines the expected IBC channel keeper. @@ -59,3 +60,7 @@ type ClaimsManagerKeeper interface { type EpochsKeeper interface { GetEpochInfo(ctx sdk.Context, identifier string) epochstypes.EpochInfo } + +type EventManagerKeeper interface { + AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, payload []byte, status int32, condtion emkeeper.ConditionI) error +} From 4e177ef336d5b67cecd724d46bd53ded02759a60 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Fri, 5 Apr 2024 21:42:28 +0100 Subject: [PATCH 03/14] move conditions to proto --- .../quicksilver/eventmanager/v1/genesis.proto | 32 +- x/eventmanager/keeper/conditions.go | 61 - x/eventmanager/keeper/events.go | 23 +- x/eventmanager/keeper/events_test.go | 127 ++ x/eventmanager/keeper/keeper_test.go | 151 -- x/eventmanager/module.go | 1 + x/eventmanager/types/conditions.go | 60 + x/eventmanager/types/fields.go | 23 +- x/eventmanager/types/genesis.pb.go | 1539 +++++++++++++++-- x/eventmanager/types/keys.go | 30 +- x/interchainstaking/keeper/redemptions.go | 11 + x/interchainstaking/types/expected_keepers.go | 4 +- 12 files changed, 1643 insertions(+), 419 deletions(-) delete mode 100644 x/eventmanager/keeper/conditions.go create mode 100644 x/eventmanager/keeper/events_test.go create mode 100644 x/eventmanager/types/conditions.go diff --git a/proto/quicksilver/eventmanager/v1/genesis.proto b/proto/quicksilver/eventmanager/v1/genesis.proto index 67f973a55..30d6f45a3 100644 --- a/proto/quicksilver/eventmanager/v1/genesis.proto +++ b/proto/quicksilver/eventmanager/v1/genesis.proto @@ -1,9 +1,9 @@ syntax = "proto3"; package quicksilver.eventmanager.v1; +import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; option go_package = "github.com/quicksilver-zone/quicksilver/x/eventmanager/types"; @@ -15,9 +15,35 @@ message Event { string module = 5; string callback = 6; bytes payload = 7; - bytes execute_condition = 8; + google.protobuf.Any execute_condition = 8 [(cosmos_proto.accepts_interface) = "quicksilver.interchainstaking.ConditionI"]; int64 emitted_height = 9; } // GenesisState defines the eventmanager module's genesis state. message GenesisState {} + +message FieldValue { + string field = 1; + string value = 2; + bool negate = 3; +} + +message ConditionAny { + repeated FieldValue fields = 1; + bool negate = 2; +} + +message ConditionAll { + repeated FieldValue fields = 1; + bool negate = 2; +} + +message ConditionAnd { + google.protobuf.Any condition1 = 1 [(cosmos_proto.accepts_interface) = "quicksilver.interchainstaking.ConditionI"]; + google.protobuf.Any condition2 = 2 [(cosmos_proto.accepts_interface) = "quicksilver.interchainstaking.ConditionI"]; +} + +message ConditionOr { + google.protobuf.Any condition1 = 1 [(cosmos_proto.accepts_interface) = "quicksilver.interchainstaking.ConditionI"]; + google.protobuf.Any condition2 = 2 [(cosmos_proto.accepts_interface) = "quicksilver.interchainstaking.ConditionI"]; +} diff --git a/x/eventmanager/keeper/conditions.go b/x/eventmanager/keeper/conditions.go deleted file mode 100644 index d7d9f3fb6..000000000 --- a/x/eventmanager/keeper/conditions.go +++ /dev/null @@ -1,61 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" -) - -type ConditionI interface { - Resolve(ctx sdk.Context, k *Keeper) bool - Marshal(ctx sdk.Context) []byte -} - -// type ConditionExistsAny struct { -// Fields []types.KV -// negate bool -// } - -// func (c ConditionExistsAny) Resolve(ctx sdk.Context, k *Keeper) bool { -// out := false -// k.IterateEvents(ctx, func(index int64, event types.Event) (stop bool) { -// if event.ResolveAnyFieldValues(c.Fields) { -// out := -// } -// } -// return negate ^ out -// } - -type ConditionExistsAll struct { - Fields []types.FieldValue - Negate bool -} - -func (c ConditionExistsAll) Resolve(ctx sdk.Context, k *Keeper) bool { - out := false - k.IteratePrefixedEvents(ctx, nil, func(index int64, event types.Event) (stop bool) { - if event.ResolveAllFieldValues(c.Fields) { - out = true - return true - } - return false - }) - return c.Negate != out -} - -type ConditionAnd struct { - Condition1 ConditionI - Condition2 ConditionI -} - -func (c ConditionAnd) Resolve(ctx sdk.Context, k *Keeper) bool { - return c.Condition1.Resolve(ctx, k) && c.Condition2.Resolve(ctx, k) -} - -type ConditionOr struct { - Condition1 ConditionI - Condition2 ConditionI -} - -func (c ConditionOr) Resolve(ctx sdk.Context, k *Keeper) bool { - return c.Condition1.Resolve(ctx, k) || c.Condition2.Resolve(ctx, k) -} diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go index 5e534c8d5..2395d9b20 100644 --- a/x/eventmanager/keeper/events.go +++ b/x/eventmanager/keeper/events.go @@ -1,6 +1,9 @@ package keeper import ( + "fmt" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -86,27 +89,37 @@ func (k Keeper) Trigger(ctx sdk.Context, module string, chainID string) { if e.EventStatus == types.EventStatusPending { err := k.Call(ctx, e.Module, e.Callback, e.Payload) if err != nil { + fmt.Println("omfg", "errr", err.Error()) k.Logger(ctx).Error("unable to execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) } + e.EventStatus = types.EventStatusActive + k.SetEvent(ctx, e) } return false }) } -func (k Keeper) AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, status int32, condition ConditionI, payload []byte) error { - conditionBytes := []byte{} - if condition != nil { - conditionBytes = condition.Marshal() +func (k Keeper) AddEvent(ctx sdk.Context, + module, chainID, identifier, callback string, + eventType, status int32, + condition types.ConditionI, + payload []byte, +) { + + conditionAny, err := codectypes.NewAnyWithValue(condition) + if err != nil { + panic(err) } event := types.Event{ ChainId: chainID, Module: module, Identifier: identifier, + EventType: eventType, Callback: callback, Payload: payload, EventStatus: status, - ExecuteCondition: conditionBytes, + ExecuteCondition: conditionAny, EmittedHeight: ctx.BlockHeight(), } diff --git a/x/eventmanager/keeper/events_test.go b/x/eventmanager/keeper/events_test.go new file mode 100644 index 000000000..69566301c --- /dev/null +++ b/x/eventmanager/keeper/events_test.go @@ -0,0 +1,127 @@ +package keeper_test + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/quicksilver-zone/quicksilver/x/eventmanager/keeper" + "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" +) + +var GLOBAL_VAR = 0 + +// ___________________________________________________________________________________________________ + +type EventCallback func(*keeper.Keeper, sdk.Context, []byte) error + +// Callbacks wrapper struct for interchainstaking keeper. +type EventCallbacks struct { + k *keeper.Keeper + callbacks map[string]EventCallback +} + +var _ types.EventCallbacks = EventCallbacks{} + +// Call calls callback handler. +func (c EventCallbacks) Call(ctx sdk.Context, id string, args []byte) error { + if !c.Has(id) { + return fmt.Errorf("callback %s not found", id) + } + return c.callbacks[id](c.k, ctx, args) +} + +func (c EventCallbacks) Has(id string) bool { + _, found := c.callbacks[id] + return found +} + +func (c EventCallbacks) AddCallback(id string, fn interface{}) types.EventCallbacks { + c.callbacks[id], _ = fn.(EventCallback) + return c +} + +func (c EventCallbacks) RegisterCallbacks() types.EventCallbacks { + a := c. + AddCallback("testCallback", EventCallback(testCallback)) + + return a.(EventCallbacks) +} + +// ----------------------------------- +// Callback Handlers +// ----------------------------------- + +func testCallback(k *keeper.Keeper, ctx sdk.Context, args []byte) error { + GLOBAL_VAR = 12345 + return nil +} + +// tests + +func (suite *KeeperTestSuite) TestEventLifecycle() { + app := suite.GetSimApp(suite.chainA) + ctx := suite.chainA.GetContext() + + callbackHandler := EventCallbacks{&app.EventManagerKeeper, make(map[string]EventCallback, 0)} + + app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) + + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test", "testCallback", types.EventTypeICADelegate, types.EventStatusPending, nil, nil) + + events := app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(1, len(events)) + + GLOBAL_VAR = 0 + + app.EventManagerKeeper.Trigger(ctx, types.ModuleName, suite.chainB.ChainID) + + event, found := app.EventManagerKeeper.GetEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + + suite.True(found) + suite.Equal(12345, GLOBAL_VAR) + + suite.Equal(event.EventStatus, types.EventStatusActive) + + app.EventManagerKeeper.DeleteEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + + events = app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(0, len(events)) +} + +func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { + app := suite.GetSimApp(suite.chainA) + ctx := suite.chainA.GetContext() + + callbackHandler := EventCallbacks{&app.EventManagerKeeper, make(map[string]EventCallback, 0)} + + app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) + + condition := &types.ConditionAll{Fields: []*types.FieldValue{{Field: types.FieldModule, Value: types.ModuleName, Negate: true}}, Negate: false} + + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test", "testCallback", types.EventTypeICADelegate, types.EventStatusPending, condition, nil) + + events := app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(1, len(events)) + + GLOBAL_VAR = 0 + + app.EventManagerKeeper.Trigger(ctx, types.ModuleName, suite.chainB.ChainID) + + event, found := app.EventManagerKeeper.GetEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + + fmt.Println(event) + suite.True(found) + suite.Equal(12345, GLOBAL_VAR) + + suite.Equal(event.EventStatus, types.EventStatusActive) + + app.EventManagerKeeper.DeleteEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + + events = app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(0, len(events)) +} diff --git a/x/eventmanager/keeper/keeper_test.go b/x/eventmanager/keeper/keeper_test.go index cf4e40bbe..8bee4e9f2 100644 --- a/x/eventmanager/keeper/keeper_test.go +++ b/x/eventmanager/keeper/keeper_test.go @@ -1,19 +1,13 @@ package keeper_test import ( - "math/rand" "testing" "github.com/stretchr/testify/suite" - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibctesting "github.com/cosmos/ibc-go/v5/testing" "github.com/quicksilver-zone/quicksilver/app" - "github.com/quicksilver-zone/quicksilver/x/interchainquery/keeper" - icqtypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" ) const TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" @@ -54,142 +48,6 @@ func (suite *KeeperTestSuite) SetupTest() { suite.coordinator.SetupConnections(suite.path) } -func (suite *KeeperTestSuite) TestMakeRequest() { - bondedQuery := stakingtypes.QueryValidatorsRequest{Status: stakingtypes.BondStatusBonded} - bz, err := bondedQuery.Marshal() - suite.NoError(err) - - suite.GetSimApp(suite.chainA).InterchainQueryKeeper.MakeRequest( - suite.chainA.GetContext(), - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(200), - "", - "", - 0, - ) - - id := keeper.GenerateQueryHash(suite.path.EndpointB.ConnectionID, suite.chainB.ChainID, "cosmos.staking.v1beta1.Query/Validators", bz, "", "") - query, found := suite.GetSimApp(suite.chainA).InterchainQueryKeeper.GetQuery(suite.chainA.GetContext(), id) - suite.True(found) - suite.Equal(suite.path.EndpointB.ConnectionID, query.ConnectionId) - suite.Equal(suite.chainB.ChainID, query.ChainId) - suite.Equal("cosmos.staking.v1beta1.Query/Validators", query.QueryType) - suite.Equal(sdk.NewInt(200), query.Period) - suite.Equal("", query.CallbackId) - - suite.GetSimApp(suite.chainA).InterchainQueryKeeper.MakeRequest( - suite.chainA.GetContext(), - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(200), - "", - "", - 0, - ) -} - -func (suite *KeeperTestSuite) TestSubmitQueryResponse() { - bondedQuery := stakingtypes.QueryValidatorsRequest{Status: stakingtypes.BondStatusBonded} - bz, err := bondedQuery.Marshal() - suite.NoError(err) - - qvr := stakingtypes.QueryValidatorsResponse{ - Validators: suite.GetSimApp(suite.chainB).StakingKeeper.GetBondedValidatorsByPower(suite.chainB.GetContext()), - } - - tests := []struct { - query *icqtypes.Query - setQuery bool - expectError error - }{ - { - suite.GetSimApp(suite.chainA).InterchainQueryKeeper. - NewQuery( - "", - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(200), - "", - 0, - ), - true, - nil, - }, - { - suite.GetSimApp(suite.chainA).InterchainQueryKeeper. - NewQuery( - "", - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(200), - "", - 10, - ), - true, - nil, - }, - { - suite.GetSimApp(suite.chainA).InterchainQueryKeeper. - NewQuery( - "", - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(-200), - "", - 0, - ), - true, - nil, - }, - { - suite.GetSimApp(suite.chainA).InterchainQueryKeeper. - NewQuery( - "", - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(100), - "", - 0, - ), - false, - nil, - }, - } - - for _, tc := range tests { - // set the query - if tc.setQuery { - suite.GetSimApp(suite.chainA).InterchainQueryKeeper.SetQuery(suite.chainA.GetContext(), *tc.query) - } - - icqmsgSrv := keeper.NewMsgServerImpl(suite.GetSimApp(suite.chainA).InterchainQueryKeeper) - - qmsg := icqtypes.MsgSubmitQueryResponse{ - ChainId: suite.chainB.ChainID, - QueryId: keeper.GenerateQueryHash(tc.query.ConnectionId, tc.query.ChainId, tc.query.QueryType, bz, "", ""), - Result: suite.GetSimApp(suite.chainB).AppCodec().MustMarshalJSON(&qvr), - Height: suite.chainB.CurrentHeader.Height, - FromAddress: TestOwnerAddress, - } - - _, err = icqmsgSrv.SubmitQueryResponse(sdk.WrapSDKContext(suite.chainA.GetContext()), &qmsg) - suite.Equal(tc.expectError, err) - } -} - func newSimAppPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort @@ -197,12 +55,3 @@ func newSimAppPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { return path } - -func (suite *KeeperTestSuite) TestLatestHeight() { - height := rand.Uint64() - chainID := "test" - - suite.GetSimApp(suite.chainA).InterchainQueryKeeper.SetLatestHeight(suite.chainA.GetContext(), chainID, height) - got := suite.GetSimApp(suite.chainA).InterchainQueryKeeper.GetLatestHeight(suite.chainA.GetContext(), chainID) - suite.Require().Equal(height, got) -} diff --git a/x/eventmanager/module.go b/x/eventmanager/module.go index ed6fb6262..4371fe538 100644 --- a/x/eventmanager/module.go +++ b/x/eventmanager/module.go @@ -47,6 +47,7 @@ func (AppModuleBasic) Name() string { // RegisterLegacyAminoCodec registers a legacy amino codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) } // RegisterInterfaces registers the module's interface types. diff --git a/x/eventmanager/types/conditions.go b/x/eventmanager/types/conditions.go new file mode 100644 index 000000000..61e463947 --- /dev/null +++ b/x/eventmanager/types/conditions.go @@ -0,0 +1,60 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/gogo/protobuf/proto" +) + +type EMKeeper interface { + IteratePrefixedEvents(sdk.Context, []byte, func(int64, Event) (stop bool)) +} + +type ConditionI interface { + proto.Message + Resolve(ctx sdk.Context, k EMKeeper) bool +} + +// type ConditionExistsAny struct { +// Fields []types.KV +// negate bool +// } + +// func (c ConditionExistsAny) Resolve(ctx sdk.Context, k *Keeper) bool { +// out := false +// k.IterateEvents(ctx, func(index int64, event types.Event) (stop bool) { +// if event.ResolveAnyFieldValues(c.Fields) { +// out := +// } +// } +// return negate ^ out +// } + +func (c ConditionAll) Resolve(ctx sdk.Context, k EMKeeper) bool { + out := false + k.IteratePrefixedEvents(ctx, nil, func(index int64, event Event) (stop bool) { + if event.ResolveAllFieldValues(c.Fields) { + out = true + return true + } + return false + }) + return c.Negate != out +} + +func (c ConditionAnd) Resolve(ctx sdk.Context, k EMKeeper) bool { + var condition1 ConditionI + var condition2 ConditionI + _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) + _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) + + return condition1.Resolve(ctx, k) && condition2.Resolve(ctx, k) +} + +func (c ConditionOr) Resolve(ctx sdk.Context, k EMKeeper) bool { + var condition1 ConditionI + var condition2 ConditionI + _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) + _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) + + return condition1.Resolve(ctx, k) || condition2.Resolve(ctx, k) +} diff --git a/x/eventmanager/types/fields.go b/x/eventmanager/types/fields.go index 322fdd1f0..7ad05f743 100644 --- a/x/eventmanager/types/fields.go +++ b/x/eventmanager/types/fields.go @@ -2,16 +2,9 @@ package types import ( "strconv" - "strings" ) -type FieldValue struct { - Field string - Value string - Negate bool -} - -func (e Event) ResolveAllFieldValues(fvs []FieldValue) bool { +func (e Event) ResolveAllFieldValues(fvs []*FieldValue) bool { for _, fv := range fvs { if !e.resolveFieldValue(fv) { return false @@ -20,7 +13,7 @@ func (e Event) ResolveAllFieldValues(fvs []FieldValue) bool { return true } -func (e Event) ResolveAnyFieldValues(fvs []FieldValue) bool { +func (e Event) ResolveAnyFieldValues(fvs []*FieldValue) bool { for _, fv := range fvs { if e.resolveFieldValue(fv) { return true @@ -29,9 +22,9 @@ func (e Event) ResolveAnyFieldValues(fvs []FieldValue) bool { return false } -func (e Event) resolveFieldValue(fv FieldValue) bool { +func (e Event) resolveFieldValue(fv *FieldValue) bool { - if strings.ToLower(fv.Field) == "eventtype" { + if fv.Field == FieldEventType { v, err := strconv.ParseInt(fv.Value, 10, 32) if err != nil { return fv.Negate @@ -42,7 +35,7 @@ func (e Event) resolveFieldValue(fv FieldValue) bool { return fv.Negate } - if strings.ToLower(fv.Field) == "eventstatus" { + if fv.Field == FieldEventStatus { v, err := strconv.ParseInt(fv.Value, 10, 32) if err != nil { return fv.Negate @@ -53,13 +46,13 @@ func (e Event) resolveFieldValue(fv FieldValue) bool { return fv.Negate } - if strings.ToLower(fv.Field) == "module" && fv.Value == e.Module { + if fv.Field == FieldModule && fv.Value == e.Module { return !fv.Negate } - if strings.ToLower(fv.Field) == "identifier" && fv.Value == e.Identifier { + if fv.Field == FieldIdentifier && fv.Value == e.Identifier { return !fv.Negate } - if strings.ToLower(fv.Field) == "chainid" && fv.Value == e.ChainId { + if fv.Field == FieldChainID && fv.Value == e.ChainId { return !fv.Negate } diff --git a/x/eventmanager/types/genesis.pb.go b/x/eventmanager/types/genesis.pb.go index 8f5b71584..bda6a1d86 100644 --- a/x/eventmanager/types/genesis.pb.go +++ b/x/eventmanager/types/genesis.pb.go @@ -5,10 +5,10 @@ package types import ( fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/gogo/protobuf/proto" - _ "google.golang.org/protobuf/types/known/durationpb" - _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" @@ -26,15 +26,15 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Event struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - EventType int32 `protobuf:"varint,2,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` - Identifier string `protobuf:"bytes,3,opt,name=identifier,proto3" json:"identifier,omitempty"` - EventStatus int32 `protobuf:"varint,4,opt,name=event_status,json=eventStatus,proto3" json:"event_status,omitempty"` - Module string `protobuf:"bytes,5,opt,name=module,proto3" json:"module,omitempty"` - Callback string `protobuf:"bytes,6,opt,name=callback,proto3" json:"callback,omitempty"` - Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"` - ExecuteCondition []byte `protobuf:"bytes,8,opt,name=execute_condition,json=executeCondition,proto3" json:"execute_condition,omitempty"` - EmittedHeight int64 `protobuf:"varint,9,opt,name=emitted_height,json=emittedHeight,proto3" json:"emitted_height,omitempty"` + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + EventType int32 `protobuf:"varint,2,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` + Identifier string `protobuf:"bytes,3,opt,name=identifier,proto3" json:"identifier,omitempty"` + EventStatus int32 `protobuf:"varint,4,opt,name=event_status,json=eventStatus,proto3" json:"event_status,omitempty"` + Module string `protobuf:"bytes,5,opt,name=module,proto3" json:"module,omitempty"` + Callback string `protobuf:"bytes,6,opt,name=callback,proto3" json:"callback,omitempty"` + Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"` + ExecuteCondition *types.Any `protobuf:"bytes,8,opt,name=execute_condition,json=executeCondition,proto3" json:"execute_condition,omitempty"` + EmittedHeight int64 `protobuf:"varint,9,opt,name=emitted_height,json=emittedHeight,proto3" json:"emitted_height,omitempty"` } func (m *Event) Reset() { *m = Event{} } @@ -119,7 +119,7 @@ func (m *Event) GetPayload() []byte { return nil } -func (m *Event) GetExecuteCondition() []byte { +func (m *Event) GetExecuteCondition() *types.Any { if m != nil { return m.ExecuteCondition } @@ -170,9 +170,282 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo +type FieldValue struct { + Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Negate bool `protobuf:"varint,3,opt,name=negate,proto3" json:"negate,omitempty"` +} + +func (m *FieldValue) Reset() { *m = FieldValue{} } +func (m *FieldValue) String() string { return proto.CompactTextString(m) } +func (*FieldValue) ProtoMessage() {} +func (*FieldValue) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{2} +} +func (m *FieldValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FieldValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FieldValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *FieldValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldValue.Merge(m, src) +} +func (m *FieldValue) XXX_Size() int { + return m.Size() +} +func (m *FieldValue) XXX_DiscardUnknown() { + xxx_messageInfo_FieldValue.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldValue proto.InternalMessageInfo + +func (m *FieldValue) GetField() string { + if m != nil { + return m.Field + } + return "" +} + +func (m *FieldValue) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *FieldValue) GetNegate() bool { + if m != nil { + return m.Negate + } + return false +} + +type ConditionAny struct { + Fields []*FieldValue `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` + Negate bool `protobuf:"varint,2,opt,name=negate,proto3" json:"negate,omitempty"` +} + +func (m *ConditionAny) Reset() { *m = ConditionAny{} } +func (m *ConditionAny) String() string { return proto.CompactTextString(m) } +func (*ConditionAny) ProtoMessage() {} +func (*ConditionAny) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{3} +} +func (m *ConditionAny) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConditionAny) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConditionAny.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConditionAny) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConditionAny.Merge(m, src) +} +func (m *ConditionAny) XXX_Size() int { + return m.Size() +} +func (m *ConditionAny) XXX_DiscardUnknown() { + xxx_messageInfo_ConditionAny.DiscardUnknown(m) +} + +var xxx_messageInfo_ConditionAny proto.InternalMessageInfo + +func (m *ConditionAny) GetFields() []*FieldValue { + if m != nil { + return m.Fields + } + return nil +} + +func (m *ConditionAny) GetNegate() bool { + if m != nil { + return m.Negate + } + return false +} + +type ConditionAll struct { + Fields []*FieldValue `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` + Negate bool `protobuf:"varint,2,opt,name=negate,proto3" json:"negate,omitempty"` +} + +func (m *ConditionAll) Reset() { *m = ConditionAll{} } +func (m *ConditionAll) String() string { return proto.CompactTextString(m) } +func (*ConditionAll) ProtoMessage() {} +func (*ConditionAll) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{4} +} +func (m *ConditionAll) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConditionAll) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConditionAll.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConditionAll) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConditionAll.Merge(m, src) +} +func (m *ConditionAll) XXX_Size() int { + return m.Size() +} +func (m *ConditionAll) XXX_DiscardUnknown() { + xxx_messageInfo_ConditionAll.DiscardUnknown(m) +} + +var xxx_messageInfo_ConditionAll proto.InternalMessageInfo + +func (m *ConditionAll) GetFields() []*FieldValue { + if m != nil { + return m.Fields + } + return nil +} + +func (m *ConditionAll) GetNegate() bool { + if m != nil { + return m.Negate + } + return false +} + +type ConditionAnd struct { + Condition1 *types.Any `protobuf:"bytes,1,opt,name=condition1,proto3" json:"condition1,omitempty"` + Condition2 *types.Any `protobuf:"bytes,2,opt,name=condition2,proto3" json:"condition2,omitempty"` +} + +func (m *ConditionAnd) Reset() { *m = ConditionAnd{} } +func (m *ConditionAnd) String() string { return proto.CompactTextString(m) } +func (*ConditionAnd) ProtoMessage() {} +func (*ConditionAnd) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{5} +} +func (m *ConditionAnd) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConditionAnd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConditionAnd.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConditionAnd) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConditionAnd.Merge(m, src) +} +func (m *ConditionAnd) XXX_Size() int { + return m.Size() +} +func (m *ConditionAnd) XXX_DiscardUnknown() { + xxx_messageInfo_ConditionAnd.DiscardUnknown(m) +} + +var xxx_messageInfo_ConditionAnd proto.InternalMessageInfo + +func (m *ConditionAnd) GetCondition1() *types.Any { + if m != nil { + return m.Condition1 + } + return nil +} + +func (m *ConditionAnd) GetCondition2() *types.Any { + if m != nil { + return m.Condition2 + } + return nil +} + +type ConditionOr struct { + Condition1 *types.Any `protobuf:"bytes,1,opt,name=condition1,proto3" json:"condition1,omitempty"` + Condition2 *types.Any `protobuf:"bytes,2,opt,name=condition2,proto3" json:"condition2,omitempty"` +} + +func (m *ConditionOr) Reset() { *m = ConditionOr{} } +func (m *ConditionOr) String() string { return proto.CompactTextString(m) } +func (*ConditionOr) ProtoMessage() {} +func (*ConditionOr) Descriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{6} +} +func (m *ConditionOr) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConditionOr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConditionOr.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConditionOr) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConditionOr.Merge(m, src) +} +func (m *ConditionOr) XXX_Size() int { + return m.Size() +} +func (m *ConditionOr) XXX_DiscardUnknown() { + xxx_messageInfo_ConditionOr.DiscardUnknown(m) +} + +var xxx_messageInfo_ConditionOr proto.InternalMessageInfo + +func (m *ConditionOr) GetCondition1() *types.Any { + if m != nil { + return m.Condition1 + } + return nil +} + +func (m *ConditionOr) GetCondition2() *types.Any { + if m != nil { + return m.Condition2 + } + return nil +} + func init() { proto.RegisterType((*Event)(nil), "quicksilver.eventmanager.v1.Event") proto.RegisterType((*GenesisState)(nil), "quicksilver.eventmanager.v1.GenesisState") + proto.RegisterType((*FieldValue)(nil), "quicksilver.eventmanager.v1.FieldValue") + proto.RegisterType((*ConditionAny)(nil), "quicksilver.eventmanager.v1.ConditionAny") + proto.RegisterType((*ConditionAll)(nil), "quicksilver.eventmanager.v1.ConditionAll") + proto.RegisterType((*ConditionAnd)(nil), "quicksilver.eventmanager.v1.ConditionAnd") + proto.RegisterType((*ConditionOr)(nil), "quicksilver.eventmanager.v1.ConditionOr") } func init() { @@ -180,32 +453,42 @@ func init() { } var fileDescriptor_74127b30ab787dbd = []byte{ - // 390 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0xcd, 0x6e, 0xd4, 0x30, - 0x14, 0x85, 0xc7, 0x2d, 0xf3, 0x67, 0x86, 0x0a, 0x2c, 0x84, 0xcc, 0x20, 0x4c, 0xa8, 0x84, 0x14, - 0x84, 0x88, 0x55, 0xb1, 0x65, 0x05, 0x42, 0xc0, 0x36, 0x20, 0x16, 0x6c, 0x22, 0x27, 0xbe, 0x75, - 0xac, 0x26, 0x76, 0x48, 0x9c, 0xa8, 0xc3, 0x53, 0xf0, 0x14, 0x3c, 0x0b, 0xcb, 0x2e, 0x59, 0xa2, - 0x99, 0x17, 0x41, 0x71, 0x52, 0x14, 0xba, 0xcb, 0xf9, 0xce, 0x39, 0xc9, 0xd5, 0xbd, 0xc1, 0xcf, - 0xbf, 0xb5, 0x3a, 0xbb, 0x68, 0x74, 0xd1, 0x41, 0xcd, 0xa1, 0x03, 0xe3, 0x4a, 0x61, 0x84, 0x82, - 0x9a, 0x77, 0x67, 0x5c, 0x81, 0x81, 0x46, 0x37, 0x51, 0x55, 0x5b, 0x67, 0xc9, 0xa3, 0x49, 0x34, - 0x9a, 0x46, 0xa3, 0xee, 0x6c, 0x7b, 0x5f, 0x59, 0x65, 0x7d, 0x8e, 0xf7, 0x4f, 0x43, 0x65, 0xcb, - 0x94, 0xb5, 0xaa, 0x00, 0xee, 0x55, 0xda, 0x9e, 0x73, 0xd9, 0xd6, 0xc2, 0x69, 0x6b, 0x46, 0xff, - 0xc9, 0x4d, 0xdf, 0xe9, 0x12, 0x1a, 0x27, 0xca, 0x6a, 0x08, 0x9c, 0xfe, 0x3c, 0xc2, 0xf3, 0x77, - 0xfd, 0xa7, 0xc8, 0x43, 0xbc, 0xca, 0x72, 0xa1, 0x4d, 0xa2, 0x25, 0x45, 0x01, 0x0a, 0xd7, 0xf1, - 0xd2, 0xeb, 0x8f, 0x92, 0x3c, 0xc6, 0xd8, 0x8f, 0x93, 0xb8, 0x5d, 0x05, 0xf4, 0x28, 0x40, 0xe1, - 0x3c, 0x5e, 0x7b, 0xf2, 0x79, 0x57, 0x01, 0x61, 0x18, 0x6b, 0x09, 0xc6, 0xe9, 0x73, 0x0d, 0x35, - 0x3d, 0xf6, 0xdd, 0x09, 0x21, 0x4f, 0xf1, 0x66, 0xa8, 0x37, 0x4e, 0xb8, 0xb6, 0xa1, 0xb7, 0xfc, - 0x0b, 0x6e, 0x7b, 0xf6, 0xc9, 0x23, 0xf2, 0x00, 0x2f, 0x4a, 0x2b, 0xdb, 0x02, 0xe8, 0xdc, 0xd7, - 0x47, 0x45, 0xb6, 0x78, 0x95, 0x89, 0xa2, 0x48, 0x45, 0x76, 0x41, 0x17, 0xde, 0xf9, 0xa7, 0x09, - 0xc5, 0xcb, 0x4a, 0xec, 0x0a, 0x2b, 0x24, 0x5d, 0x06, 0x28, 0xdc, 0xc4, 0xd7, 0x92, 0xbc, 0xc0, - 0xf7, 0xe0, 0x12, 0xb2, 0xd6, 0x41, 0x92, 0x59, 0x23, 0x75, 0xbf, 0x10, 0xba, 0xf2, 0x99, 0xbb, - 0xa3, 0xf1, 0xf6, 0x9a, 0x93, 0x67, 0xf8, 0x04, 0x4a, 0xed, 0x1c, 0xc8, 0x24, 0x07, 0xad, 0x72, - 0x47, 0xd7, 0x01, 0x0a, 0x8f, 0xe3, 0x3b, 0x23, 0xfd, 0xe0, 0xe1, 0xe9, 0x09, 0xde, 0xbc, 0x1f, - 0xae, 0xd5, 0x8f, 0x0c, 0x6f, 0xbe, 0xfc, 0xda, 0x33, 0x74, 0xb5, 0x67, 0xe8, 0xcf, 0x9e, 0xa1, - 0x1f, 0x07, 0x36, 0xbb, 0x3a, 0xb0, 0xd9, 0xef, 0x03, 0x9b, 0x7d, 0x7d, 0xad, 0xb4, 0xcb, 0xdb, - 0x34, 0xca, 0x6c, 0xc9, 0x27, 0x17, 0x7d, 0xf9, 0xdd, 0x1a, 0x98, 0x02, 0x7e, 0xf9, 0xff, 0xff, - 0xd0, 0x2f, 0xb7, 0x49, 0x17, 0xfe, 0x2e, 0xaf, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x64, 0x4b, - 0x05, 0x58, 0x38, 0x02, 0x00, 0x00, + // 549 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x54, 0xbd, 0x8e, 0xd3, 0x40, + 0x10, 0xce, 0x26, 0xe4, 0x6f, 0x13, 0x4e, 0xb0, 0x8a, 0x90, 0x13, 0x84, 0x65, 0x22, 0x21, 0x8c, + 0xc4, 0xd9, 0x4a, 0x68, 0x91, 0xd0, 0x1d, 0xe2, 0xe7, 0x2a, 0x90, 0x41, 0x57, 0xd0, 0x44, 0x1b, + 0x7b, 0xb2, 0x59, 0xc5, 0xd9, 0x0d, 0xf6, 0x3a, 0x3a, 0xf3, 0x14, 0x3c, 0x0c, 0x0f, 0x81, 0xa8, + 0xae, 0x01, 0x51, 0xa2, 0xa4, 0xe3, 0x29, 0x90, 0xd7, 0x4e, 0x70, 0x0a, 0xa8, 0x8e, 0x86, 0xce, + 0xdf, 0x37, 0x33, 0xdf, 0xcc, 0x7c, 0x63, 0x2d, 0x7e, 0xf0, 0x3e, 0xe1, 0xfe, 0x22, 0xe6, 0xe1, + 0x1a, 0x22, 0x17, 0xd6, 0x20, 0xd4, 0x92, 0x0a, 0xca, 0x20, 0x72, 0xd7, 0x23, 0x97, 0x81, 0x80, + 0x98, 0xc7, 0xce, 0x2a, 0x92, 0x4a, 0x92, 0xdb, 0xa5, 0x54, 0xa7, 0x9c, 0xea, 0xac, 0x47, 0x83, + 0xbe, 0x2f, 0xe3, 0xa5, 0x8c, 0x27, 0x3a, 0xd5, 0xcd, 0x41, 0x5e, 0x37, 0xe8, 0x31, 0xc9, 0x64, + 0xce, 0x67, 0x5f, 0x05, 0xdb, 0x67, 0x52, 0xb2, 0x10, 0x5c, 0x8d, 0xa6, 0xc9, 0xcc, 0xa5, 0x22, + 0xcd, 0x43, 0xc3, 0x9f, 0x55, 0x5c, 0x7f, 0x96, 0xe9, 0x93, 0x3e, 0x6e, 0xf9, 0x73, 0xca, 0xc5, + 0x84, 0x07, 0x06, 0xb2, 0x90, 0xdd, 0xf6, 0x9a, 0x1a, 0x9f, 0x05, 0xe4, 0x0e, 0xc6, 0x7a, 0x86, + 0x89, 0x4a, 0x57, 0x60, 0x54, 0x2d, 0x64, 0xd7, 0xbd, 0xb6, 0x66, 0xde, 0xa6, 0x2b, 0x20, 0x26, + 0xc6, 0x3c, 0x00, 0xa1, 0xf8, 0x8c, 0x43, 0x64, 0xd4, 0x74, 0x6d, 0x89, 0x21, 0x77, 0x71, 0x37, + 0x2f, 0x8f, 0x15, 0x55, 0x49, 0x6c, 0x5c, 0xd3, 0x02, 0x1d, 0xcd, 0xbd, 0xd1, 0x14, 0xb9, 0x85, + 0x1b, 0x4b, 0x19, 0x24, 0x21, 0x18, 0x75, 0x5d, 0x5e, 0x20, 0x32, 0xc0, 0x2d, 0x9f, 0x86, 0xe1, + 0x94, 0xfa, 0x0b, 0xa3, 0xa1, 0x23, 0x7b, 0x4c, 0x0c, 0xdc, 0x5c, 0xd1, 0x34, 0x94, 0x34, 0x30, + 0x9a, 0x16, 0xb2, 0xbb, 0xde, 0x0e, 0x12, 0x89, 0x6f, 0xc2, 0x05, 0xf8, 0x89, 0x82, 0x89, 0x2f, + 0x45, 0xc0, 0x15, 0x97, 0xc2, 0x68, 0x59, 0xc8, 0xee, 0x8c, 0x7b, 0x4e, 0xee, 0x85, 0xb3, 0xf3, + 0xc2, 0x39, 0x11, 0xe9, 0xe9, 0xc3, 0x2f, 0x9f, 0x8e, 0xed, 0xb2, 0xe5, 0x5c, 0x28, 0x88, 0xf4, + 0xfa, 0xb1, 0xa2, 0x0b, 0x2e, 0x98, 0xf3, 0x74, 0x27, 0x74, 0xe6, 0xdd, 0x28, 0xc4, 0xf7, 0x14, + 0xb9, 0x87, 0x8f, 0x60, 0xc9, 0x95, 0x82, 0x60, 0x32, 0x07, 0xce, 0xe6, 0xca, 0x68, 0x5b, 0xc8, + 0xae, 0x79, 0xd7, 0x0b, 0xf6, 0xa5, 0x26, 0x87, 0x47, 0xb8, 0xfb, 0x22, 0x3f, 0x73, 0xb6, 0x36, + 0x0c, 0x5f, 0x63, 0xfc, 0x9c, 0x43, 0x18, 0x9c, 0xd3, 0x30, 0x01, 0xd2, 0xc3, 0xf5, 0x59, 0x86, + 0x0a, 0xf7, 0x73, 0x90, 0xb1, 0xeb, 0x2c, 0xac, 0x6d, 0x6f, 0x7b, 0x39, 0xc8, 0xfc, 0x12, 0xc0, + 0xa8, 0x02, 0x6d, 0x77, 0xcb, 0x2b, 0xd0, 0x90, 0xe1, 0xee, 0x7e, 0xaa, 0x13, 0x91, 0x92, 0x27, + 0xb8, 0xa1, 0x65, 0x62, 0x03, 0x59, 0x35, 0xbb, 0x33, 0xbe, 0xef, 0xfc, 0xe5, 0xc7, 0x72, 0x7e, + 0x0f, 0xe3, 0x15, 0x65, 0xa5, 0x46, 0xd5, 0x3f, 0x37, 0x0a, 0xc3, 0x7f, 0xd7, 0xe8, 0x1b, 0x3a, + 0x58, 0x29, 0x20, 0x53, 0x8c, 0xf7, 0x47, 0x1d, 0x69, 0xaf, 0xae, 0xe6, 0xaa, 0x25, 0xd5, 0x83, + 0x1e, 0x63, 0x3d, 0xd0, 0x55, 0xf7, 0x18, 0x0f, 0xbf, 0x22, 0xdc, 0xd9, 0x87, 0x5e, 0x45, 0xff, + 0xcb, 0x5e, 0xa7, 0xe7, 0x9f, 0x37, 0x26, 0xba, 0xdc, 0x98, 0xe8, 0xc7, 0xc6, 0x44, 0x1f, 0xb7, + 0x66, 0xe5, 0x72, 0x6b, 0x56, 0xbe, 0x6f, 0xcd, 0xca, 0xbb, 0xc7, 0x8c, 0xab, 0x79, 0x32, 0x75, + 0x7c, 0xb9, 0x74, 0x4b, 0xd2, 0xc7, 0x1f, 0xa4, 0x80, 0x32, 0xe1, 0x5e, 0x1c, 0xbe, 0x8e, 0xd9, + 0xab, 0x13, 0x4f, 0x1b, 0x7a, 0xbe, 0x47, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x91, 0x6f, + 0x19, 0x46, 0x05, 0x00, 0x00, } func (m *Event) Marshal() (dAtA []byte, err error) { @@ -233,10 +516,15 @@ func (m *Event) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x48 } - if len(m.ExecuteCondition) > 0 { - i -= len(m.ExecuteCondition) - copy(dAtA[i:], m.ExecuteCondition) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.ExecuteCondition))) + if m.ExecuteCondition != nil { + { + size, err := m.ExecuteCondition.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0x42 } @@ -311,73 +599,398 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *FieldValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Event) Size() (n int) { - if m == nil { - return 0 - } + +func (m *FieldValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FieldValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - if m.EventType != 0 { - n += 1 + sovGenesis(uint64(m.EventType)) - } - l = len(m.Identifier) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - if m.EventStatus != 0 { - n += 1 + sovGenesis(uint64(m.EventStatus)) - } - l = len(m.Module) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Callback) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Payload) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if m.Negate { + i-- + if m.Negate { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 } - l = len(m.ExecuteCondition) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x12 } - if m.EmittedHeight != 0 { - n += 1 + sovGenesis(uint64(m.EmittedHeight)) + if len(m.Field) > 0 { + i -= len(m.Field) + copy(dAtA[i:], m.Field) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Field))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *GenesisState) Size() (n int) { - if m == nil { - return 0 +func (m *ConditionAny) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 +func (m *ConditionAny) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + +func (m *ConditionAny) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Negate { + i-- + if m.Negate { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.Fields) > 0 { + for iNdEx := len(m.Fields) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Fields[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ConditionAll) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConditionAll) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConditionAll) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Negate { + i-- + if m.Negate { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.Fields) > 0 { + for iNdEx := len(m.Fields) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Fields[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ConditionAnd) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConditionAnd) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConditionAnd) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Condition2 != nil { + { + size, err := m.Condition2.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Condition1 != nil { + { + size, err := m.Condition1.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ConditionOr) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConditionOr) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConditionOr) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Condition2 != nil { + { + size, err := m.Condition2.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Condition1 != nil { + { + size, err := m.Condition1.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Event) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.EventType != 0 { + n += 1 + sovGenesis(uint64(m.EventType)) + } + l = len(m.Identifier) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.EventStatus != 0 { + n += 1 + sovGenesis(uint64(m.EventStatus)) + } + l = len(m.Module) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Callback) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.ExecuteCondition != nil { + l = m.ExecuteCondition.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.EmittedHeight != 0 { + n += 1 + sovGenesis(uint64(m.EmittedHeight)) + } + return n +} + +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *FieldValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Field) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.Negate { + n += 2 + } + return n +} + +func (m *ConditionAny) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Fields) > 0 { + for _, e := range m.Fields { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if m.Negate { + n += 2 + } + return n +} + +func (m *ConditionAll) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Fields) > 0 { + for _, e := range m.Fields { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if m.Negate { + n += 2 + } + return n +} + +func (m *ConditionAnd) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Condition1 != nil { + l = m.Condition1.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.Condition2 != nil { + l = m.Condition2.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *ConditionOr) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Condition1 != nil { + l = m.Condition1.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.Condition2 != nil { + l = m.Condition2.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } func (m *Event) Unmarshal(dAtA []byte) error { l := len(dAtA) @@ -459,11 +1072,449 @@ func (m *Event) Unmarshal(dAtA []byte) error { break } } - case 3: + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EventStatus", wireType) + } + m.EventStatus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EventStatus |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Module", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Module = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Callback", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Callback = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecuteCondition", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ExecuteCondition == nil { + m.ExecuteCondition = &types.Any{} + } + if err := m.ExecuteCondition.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EmittedHeight", wireType) + } + m.EmittedHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EmittedHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FieldValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FieldValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FieldValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Field = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Negate", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Negate = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConditionAny) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConditionAny: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConditionAny: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Fields", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -473,29 +1524,31 @@ func (m *Event) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.Identifier = string(dAtA[iNdEx:postIndex]) + m.Fields = append(m.Fields, &FieldValue{}) + if err := m.Fields[len(m.Fields)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: + case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EventStatus", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Negate", wireType) } - m.EventStatus = 0 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -505,16 +1558,67 @@ func (m *Event) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.EventStatus |= int32(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - case 5: + m.Negate = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConditionAll) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConditionAll: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConditionAll: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Module", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Fields", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -524,29 +1628,31 @@ func (m *Event) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.Module = string(dAtA[iNdEx:postIndex]) + m.Fields = append(m.Fields, &FieldValue{}) + if err := m.Fields[len(m.Fields)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Callback", wireType) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Negate", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -556,29 +1662,67 @@ func (m *Event) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis + m.Negate = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + intStringLen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthGenesis } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.Callback = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConditionAnd) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConditionAnd: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConditionAnd: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Condition1", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -588,31 +1732,33 @@ func (m *Event) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) - if m.Payload == nil { - m.Payload = []byte{} + if m.Condition1 == nil { + m.Condition1 = &types.Any{} + } + if err := m.Condition1.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex - case 8: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecuteCondition", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Condition2", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -622,45 +1768,28 @@ func (m *Event) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - m.ExecuteCondition = append(m.ExecuteCondition[:0], dAtA[iNdEx:postIndex]...) - if m.ExecuteCondition == nil { - m.ExecuteCondition = []byte{} - } - iNdEx = postIndex - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EmittedHeight", wireType) + if m.Condition2 == nil { + m.Condition2 = &types.Any{} } - m.EmittedHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.EmittedHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } + if err := m.Condition2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -682,7 +1811,7 @@ func (m *Event) Unmarshal(dAtA []byte) error { } return nil } -func (m *GenesisState) Unmarshal(dAtA []byte) error { +func (m *ConditionOr) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -705,12 +1834,84 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + return fmt.Errorf("proto: ConditionOr: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConditionOr: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Condition1", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Condition1 == nil { + m.Condition1 = &types.Any{} + } + if err := m.Condition1.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Condition2", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Condition2 == nil { + m.Condition2 = &types.Any{} + } + if err := m.Condition2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/eventmanager/types/keys.go b/x/eventmanager/types/keys.go index 43a881df6..e518f3545 100644 --- a/x/eventmanager/types/keys.go +++ b/x/eventmanager/types/keys.go @@ -15,20 +15,24 @@ const ( ) const ( - EventStatusUnspecified = 0 - EventStatusActive = 1 - EventStatusPending = 2 -) + EventStatusUnspecified = int32(0) + EventStatusActive = int32(1) + EventStatusPending = int32(2) -const ( - EventTypeUnspecified = 0x00 - EventTypeICQQueryRewards = 0x01 - EventTypeICQQueryDelegations = 0x02 - EventTypeICQAccountBalances = 0x03 - EventTypeICQAccountBalance = 0x04 - EventTypeICAWithdrawRewards = 0x05 - EventTypeICADelegate = 0x06 - EventTypeICAUnbond = 0x07 + EventTypeUnspecified = int32(0x00) + EventTypeICQQueryRewards = int32(0x01) + EventTypeICQQueryDelegations = int32(0x02) + EventTypeICQAccountBalances = int32(0x03) + EventTypeICQAccountBalance = int32(0x04) + EventTypeICAWithdrawRewards = int32(0x05) + EventTypeICADelegate = int32(0x06) + EventTypeICAUnbond = int32(0x07) + + FieldEventType = "eventtype" + FieldModule = "module" + FieldEventStatus = "eventstatus" + FieldChainID = "chainid" + FieldIdentifier = "identifier" ) var ( diff --git a/x/interchainstaking/keeper/redemptions.go b/x/interchainstaking/keeper/redemptions.go index 871c7145b..d54b6e6b4 100644 --- a/x/interchainstaking/keeper/redemptions.go +++ b/x/interchainstaking/keeper/redemptions.go @@ -13,6 +13,7 @@ import ( "github.com/quicksilver-zone/quicksilver/utils" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" ) @@ -237,6 +238,16 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch for _, valoper := range utils.Keys(coinsOutPerValidator) { if !coinsOutPerValidator[valoper].Amount.IsZero() { msgs = append(msgs, &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: coinsOutPerValidator[valoper]}) + k.EventManagerKeeper.AddEvent(ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("%s/%s", types.EpochWithdrawalMemo(epoch), valoper), + "unbondAck", + emtypes.EventTypeICAUnbond, + emtypes.EventStatusActive, + nil, + nil, + ) } } diff --git a/x/interchainstaking/types/expected_keepers.go b/x/interchainstaking/types/expected_keepers.go index 8a5645e40..c8805d995 100644 --- a/x/interchainstaking/types/expected_keepers.go +++ b/x/interchainstaking/types/expected_keepers.go @@ -9,7 +9,7 @@ import ( claimsmanagertypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" - emkeeper "github.com/quicksilver-zone/quicksilver/x/eventmanager/keeper" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" ) // ChannelKeeper defines the expected IBC channel keeper. @@ -62,5 +62,5 @@ type EpochsKeeper interface { } type EventManagerKeeper interface { - AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, payload []byte, status int32, condtion emkeeper.ConditionI) error + AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, eventType, status int32, condtion emtypes.ConditionI, payload []byte) } From 8b0cb614ca78457056b3d1bc3b830103f423f6bb Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Sat, 6 Apr 2024 00:07:11 +0100 Subject: [PATCH 04/14] working em with tests --- app/modules.go | 10 +- .../quicksilver/eventmanager/v1/genesis.proto | 11 +- x/eventmanager/keeper/events.go | 27 +-- x/eventmanager/keeper/events_test.go | 90 +++++++++- x/eventmanager/keeper/keeper.go | 4 + x/eventmanager/module.go | 18 +- x/eventmanager/types/codec.go | 2 + x/eventmanager/types/conditions.go | 106 ++++++++++-- x/eventmanager/types/fields.go | 104 ++++++++---- x/eventmanager/types/genesis.pb.go | 154 +++++++++++++----- x/eventmanager/types/keys.go | 1 + x/interchainstaking/keeper/redemptions.go | 9 +- 12 files changed, 426 insertions(+), 110 deletions(-) diff --git a/app/modules.go b/app/modules.go index da72dbb27..ec3bb2b37 100644 --- a/app/modules.go +++ b/app/modules.go @@ -55,6 +55,8 @@ import ( claimsmanagertypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" "github.com/quicksilver-zone/quicksilver/x/epochs" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + "github.com/quicksilver-zone/quicksilver/x/eventmanager" + eventmanagertypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" "github.com/quicksilver-zone/quicksilver/x/interchainquery" interchainquerytypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking" @@ -107,6 +109,7 @@ var ( participationrewards.AppModuleBasic{}, airdrop.AppModuleBasic{}, supply.AppModuleBasic{}, + eventmanager.AppModuleBasic{}, ) // module account permissions. @@ -169,6 +172,7 @@ func appModules( epochs.NewAppModule(appCodec, app.EpochsKeeper), interchainstaking.NewAppModule(appCodec, app.InterchainstakingKeeper), interchainquery.NewAppModule(appCodec, app.InterchainQueryKeeper), + eventmanager.NewAppModule(appCodec, app.EventManagerKeeper), participationrewards.NewAppModule(appCodec, app.ParticipationRewardsKeeper), airdrop.NewAppModule(appCodec, app.AirdropKeeper), supply.NewAppModule(appCodec, app.SupplyKeeper), @@ -207,6 +211,7 @@ func simulationModules( epochs.NewAppModule(appCodec, app.EpochsKeeper), interchainstaking.NewAppModule(appCodec, app.InterchainstakingKeeper), interchainquery.NewAppModule(appCodec, app.InterchainQueryKeeper), + eventmanager.NewAppModule(appCodec, app.EventManagerKeeper), participationrewards.NewAppModule(appCodec, app.ParticipationRewardsKeeper), airdrop.NewAppModule(appCodec, app.AirdropKeeper), // supply.NewAppModule(appCodec, app.SupplyKeeper), @@ -237,7 +242,8 @@ func orderBeginBlockers() []string { stakingtypes.ModuleName, ibchost.ModuleName, interchainstakingtypes.ModuleName, - interchainquerytypes.ModuleName, // check ordering here. + interchainquerytypes.ModuleName, + eventmanagertypes.ModuleName, // no-op modules ibctransfertypes.ModuleName, icatypes.ModuleName, @@ -297,6 +303,7 @@ func orderEndBlockers() []string { participationrewardstypes.ModuleName, airdroptypes.ModuleName, supplytypes.ModuleName, + eventmanagertypes.ModuleName, // currently no-op. } } @@ -339,6 +346,7 @@ func orderInitBlockers() []string { participationrewardstypes.ModuleName, airdroptypes.ModuleName, supplytypes.ModuleName, + eventmanagertypes.ModuleName, // NOTE: crisis module must go at the end to check for invariants on each module crisistypes.ModuleName, } diff --git a/proto/quicksilver/eventmanager/v1/genesis.proto b/proto/quicksilver/eventmanager/v1/genesis.proto index 30d6f45a3..5e9d22b75 100644 --- a/proto/quicksilver/eventmanager/v1/genesis.proto +++ b/proto/quicksilver/eventmanager/v1/genesis.proto @@ -22,10 +22,19 @@ message Event { // GenesisState defines the eventmanager module's genesis state. message GenesisState {} +enum FieldOperator { + UNSPECIFIED = 0; + EQUAL = 1; + CONTAINS = 2; + BEGINSWITH = 3; + ENDSWITH = 4; +} + message FieldValue { string field = 1; string value = 2; - bool negate = 3; + FieldOperator operator = 3; + bool negate = 4; } message ConditionAny { diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go index 2395d9b20..bc32cbd1c 100644 --- a/x/eventmanager/keeper/events.go +++ b/x/eventmanager/keeper/events.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -87,13 +85,18 @@ func (k Keeper) MarkCompleted(ctx sdk.Context, module string, chainID string, id func (k Keeper) Trigger(ctx sdk.Context, module string, chainID string) { k.IterateModuleChainEvents(ctx, module, chainID, func(_ int64, e types.Event) (stop bool) { if e.EventStatus == types.EventStatusPending { - err := k.Call(ctx, e.Module, e.Callback, e.Payload) + res, err := e.CanExecute(ctx, &k) if err != nil { - fmt.Println("omfg", "errr", err.Error()) - k.Logger(ctx).Error("unable to execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) + k.Logger(ctx).Error("unable to determine if event can execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) + } + if res { + err := k.Call(ctx, e.Module, e.Callback, e.Payload) + if err != nil { + k.Logger(ctx).Error("unable to execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) + } + e.EventStatus = types.EventStatusActive + k.SetEvent(ctx, e) } - e.EventStatus = types.EventStatusActive - k.SetEvent(ctx, e) } return false }) @@ -106,9 +109,13 @@ func (k Keeper) AddEvent(ctx sdk.Context, payload []byte, ) { - conditionAny, err := codectypes.NewAnyWithValue(condition) - if err != nil { - panic(err) + var err error + var conditionAny *codectypes.Any + if condition != nil { + conditionAny, err = codectypes.NewAnyWithValue(condition) + if err != nil { + panic(err) + } } event := types.Event{ diff --git a/x/eventmanager/keeper/events_test.go b/x/eventmanager/keeper/events_test.go index 69566301c..19f6ce233 100644 --- a/x/eventmanager/keeper/events_test.go +++ b/x/eventmanager/keeper/events_test.go @@ -43,7 +43,8 @@ func (c EventCallbacks) AddCallback(id string, fn interface{}) types.EventCallba func (c EventCallbacks) RegisterCallbacks() types.EventCallbacks { a := c. - AddCallback("testCallback", EventCallback(testCallback)) + AddCallback("testCallback", EventCallback(testCallback)). + AddCallback("testCallbackWithArgs", EventCallback(testCallbackWithArgs)) return a.(EventCallbacks) } @@ -57,6 +58,11 @@ func testCallback(k *keeper.Keeper, ctx sdk.Context, args []byte) error { return nil } +func testCallbackWithArgs(k *keeper.Keeper, ctx sdk.Context, args []byte) error { + GLOBAL_VAR = int(args[0]) + return nil +} + // tests func (suite *KeeperTestSuite) TestEventLifecycle() { @@ -99,27 +105,101 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) - condition := &types.ConditionAll{Fields: []*types.FieldValue{{Field: types.FieldModule, Value: types.ModuleName, Negate: true}}, Negate: false} + condition, err := types.NewConditionAll(ctx, []*types.FieldValue{ + {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, + {Field: types.FieldEventStatus, Value: fmt.Sprintf("%d", types.EventStatusActive), Operator: types.FieldOperator_EQUAL, Negate: false}, + }, true) + + suite.NoError(err) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test1", "", types.EventTypeICAUnbond, types.EventStatusActive, nil, nil) app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test", "testCallback", types.EventTypeICADelegate, types.EventStatusPending, condition, nil) events := app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(1, len(events)) + suite.Equal(2, len(events)) GLOBAL_VAR = 0 - app.EventManagerKeeper.Trigger(ctx, types.ModuleName, suite.chainB.ChainID) + // martCompleted doesn't require an explicit callback + app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test1") event, found := app.EventManagerKeeper.GetEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + events = app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(1, len(events)) + fmt.Println(event) suite.True(found) suite.Equal(12345, GLOBAL_VAR) suite.Equal(event.EventStatus, types.EventStatusActive) - app.EventManagerKeeper.DeleteEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test") + + events = app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(0, len(events)) +} + +func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { + app := suite.GetSimApp(suite.chainA) + ctx := suite.chainA.GetContext() + + callbackHandler := EventCallbacks{&app.EventManagerKeeper, make(map[string]EventCallback, 0)} + + app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) + + condition1, err := types.NewConditionAll(ctx, []*types.FieldValue{ + {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, + {Field: types.FieldEventType, Value: fmt.Sprintf("%d", types.EventTypeICAUnbond), Operator: types.FieldOperator_EQUAL, Negate: false}, + }, true) + suite.NoError(err) + + condition2, err := types.NewConditionAll(ctx, []*types.FieldValue{ + {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, + {Field: types.FieldEventType, Value: fmt.Sprintf("%d", types.EventTypeICADelegate), Operator: types.FieldOperator_EQUAL, Negate: false}, + }, true) + suite.NoError(err) + + conditionAnd, err := types.NewConditionAnd(ctx, condition1, condition2) + suite.NoError(err) + + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test1", "", types.EventTypeICAUnbond, types.EventStatusActive, nil, nil) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test", "testCallbackWithArgs", types.EventTypeICADelegate, types.EventStatusPending, condition1, []byte{0x01}) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test2", "testCallbackWithArgs", types.EventTypeICAWithdrawRewards, types.EventStatusPending, conditionAnd, []byte{0x02}) + + events := app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(3, len(events)) + + GLOBAL_VAR = 0 + + // markCompleted doesn't require an explicit callback + app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test1") + + event, found := app.EventManagerKeeper.GetEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") + suite.True(found) + + events = app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(2, len(events)) + + fmt.Println(event) + suite.Equal(1, GLOBAL_VAR) + + suite.Equal(event.EventStatus, types.EventStatusActive) + + app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test") + + suite.Equal(2, GLOBAL_VAR) + + events = app.EventManagerKeeper.AllEvents(ctx) + + suite.Equal(1, len(events)) + + app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test2") events = app.EventManagerKeeper.AllEvents(ctx) diff --git a/x/eventmanager/keeper/keeper.go b/x/eventmanager/keeper/keeper.go index 3f93872a6..67c497874 100644 --- a/x/eventmanager/keeper/keeper.go +++ b/x/eventmanager/keeper/keeper.go @@ -29,6 +29,10 @@ func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey) Keeper { } } +func (k *Keeper) GetCodec() codec.Codec { + return k.cdc +} + func (k *Keeper) SetCallbackHandler(module string, handler types.EventCallbacks) error { _, found := k.callbacks[module] if found { diff --git a/x/eventmanager/module.go b/x/eventmanager/module.go index 4371fe538..5e38100c1 100644 --- a/x/eventmanager/module.go +++ b/x/eventmanager/module.go @@ -1,7 +1,6 @@ -package interchainquery +package eventmanager import ( - "context" "encoding/json" "math/rand" @@ -16,8 +15,8 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/quicksilver-zone/quicksilver/x/interchainquery/keeper" - "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" + "github.com/quicksilver-zone/quicksilver/x/eventmanager/keeper" + "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" ) var ( @@ -52,6 +51,7 @@ func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { // RegisterInterfaces registers the module's interface types. func (AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) } // DefaultGenesis returns the capability module's default genesis state. @@ -66,10 +66,10 @@ func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConf // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - err := types.RegisterQuerySrvrHandlerClient(context.Background(), mux, types.NewQuerySrvrClient(clientCtx)) - if err != nil { - panic(err) - } + // err := types.RegisterQuerySrvrHandlerClient(context.Background(), mux, types.NewQuerySrvrClient(clientCtx)) + // if err != nil { + // panic(err) + // } } // GetTxCmd returns the capability module's root tx command. @@ -121,7 +121,7 @@ func (AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterQuerySrvrServer(cfg.QueryServer(), am.keeper) + //types.RegisterQuerySrvrServer(cfg.QueryServer(), am.keeper) } // RegisterInvariants registers the capability module's invariants. diff --git a/x/eventmanager/types/codec.go b/x/eventmanager/types/codec.go index 0836bbdad..159d3bff0 100644 --- a/x/eventmanager/types/codec.go +++ b/x/eventmanager/types/codec.go @@ -16,6 +16,8 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { } func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterInterface("quicksilver.eventmanager.v1.ConditionI", (*ConditionI)(nil)) + registry.RegisterImplementations((*ConditionI)(nil), &ConditionAll{}, &ConditionAnd{} /*&ConditionAny{},*/, &ConditionOr{}) } func init() { diff --git a/x/eventmanager/types/conditions.go b/x/eventmanager/types/conditions.go index 61e463947..1a2ce3df9 100644 --- a/x/eventmanager/types/conditions.go +++ b/x/eventmanager/types/conditions.go @@ -1,17 +1,22 @@ package types import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/proto" ) type EMKeeper interface { IteratePrefixedEvents(sdk.Context, []byte, func(int64, Event) (stop bool)) + GetCodec() codec.Codec } type ConditionI interface { proto.Message - Resolve(ctx sdk.Context, k EMKeeper) bool + Resolve(ctx sdk.Context, k EMKeeper) (bool, error) } // type ConditionExistsAny struct { @@ -29,32 +34,109 @@ type ConditionI interface { // return negate ^ out // } -func (c ConditionAll) Resolve(ctx sdk.Context, k EMKeeper) bool { +func (c ConditionAll) Resolve(ctx sdk.Context, k EMKeeper) (bool, error) { out := false + var err error k.IteratePrefixedEvents(ctx, nil, func(index int64, event Event) (stop bool) { - if event.ResolveAllFieldValues(c.Fields) { + res, err := event.ResolveAllFieldValues(c.Fields) + if err != nil { + return true + } + if res { out = true return true } return false }) - return c.Negate != out + return c.Negate != out, err } -func (c ConditionAnd) Resolve(ctx sdk.Context, k EMKeeper) bool { +func NewConditionAll(ctx sdk.Context, fields []*FieldValue, negate bool) (*ConditionAll, error) { + return &ConditionAll{fields, negate}, nil +} + +func (c ConditionAnd) Resolve(ctx sdk.Context, k EMKeeper) (bool, error) { var condition1 ConditionI var condition2 ConditionI - _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) - _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) + err := k.GetCodec().UnpackAny(c.Condition1, &condition1) + if err != nil { + return false, err + } + err = k.GetCodec().UnpackAny(c.Condition2, &condition2) + if err != nil { + return false, err + } + + res1, err := condition1.Resolve(ctx, k) + if err != nil { + return false, err + } + res2, err := condition2.Resolve(ctx, k) + if err != nil { + return false, err + } + return res1 && res2, nil +} - return condition1.Resolve(ctx, k) && condition2.Resolve(ctx, k) +func NewConditionAnd(ctx sdk.Context, condition1, condition2 ConditionI) (*ConditionAnd, error) { + anyc1, err := codectypes.NewAnyWithValue(condition1) + if err != nil { + return nil, err + } + anyc2, err := codectypes.NewAnyWithValue(condition2) + if err != nil { + return nil, err + } + return &ConditionAnd{anyc1, anyc2}, nil } -func (c ConditionOr) Resolve(ctx sdk.Context, k EMKeeper) bool { +func (c ConditionOr) Resolve(ctx sdk.Context, k EMKeeper) (bool, error) { var condition1 ConditionI var condition2 ConditionI - _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) - _ = ModuleCdc.UnpackAny(c.Condition1, &condition1) + err := k.GetCodec().UnpackAny(c.Condition1, &condition1) + if err != nil { + return false, err + } + err = k.GetCodec().UnpackAny(c.Condition2, &condition2) + if err != nil { + return false, err + } + + res1, err := condition1.Resolve(ctx, k) + if err != nil { + return false, err + } + res2, err := condition2.Resolve(ctx, k) + if err != nil { + return false, err + } + return res1 || res2, nil +} + +func NewConditionOr(ctx sdk.Context, condition1, condition2 ConditionI) (*ConditionOr, error) { + anyc1, err := codectypes.NewAnyWithValue(condition1) + if err != nil { + return nil, err + } + anyc2, err := codectypes.NewAnyWithValue(condition2) + if err != nil { + return nil, err + } + return &ConditionOr{anyc1, anyc2}, nil +} + +// CanExecute determines whether a +func (e *Event) CanExecute(ctx sdk.Context, k EMKeeper) (bool, error) { + fmt.Print(e.ExecuteCondition) + if e.ExecuteCondition == nil { + return true, nil + } + var condition ConditionI + err := k.GetCodec().UnpackAny(e.ExecuteCondition, &condition) + if err != nil { + return false, err + } + fmt.Print(condition) - return condition1.Resolve(ctx, k) || condition2.Resolve(ctx, k) + return condition.Resolve(ctx, k) } diff --git a/x/eventmanager/types/fields.go b/x/eventmanager/types/fields.go index 7ad05f743..802637189 100644 --- a/x/eventmanager/types/fields.go +++ b/x/eventmanager/types/fields.go @@ -1,60 +1,106 @@ package types import ( + fmt "fmt" "strconv" + "strings" ) -func (e Event) ResolveAllFieldValues(fvs []*FieldValue) bool { +func (e Event) ResolveAllFieldValues(fvs []*FieldValue) (bool, error) { for _, fv := range fvs { - if !e.resolveFieldValue(fv) { - return false + res, err := e.resolveFieldValue(fv) + if err != nil { + return false, err + } + if !res { + return false, nil } } - return true + // return true if none of the conditions failed. + return true, nil } -func (e Event) ResolveAnyFieldValues(fvs []*FieldValue) bool { +func (e Event) ResolveAnyFieldValues(fvs []*FieldValue) (bool, error) { for _, fv := range fvs { - if e.resolveFieldValue(fv) { - return true + res, err := e.resolveFieldValue(fv) + if err != nil { + return false, err + } + if res { + return true, nil } } - return false + // return false if none of the conditons passed. + return false, nil } -func (e Event) resolveFieldValue(fv *FieldValue) bool { +func (e Event) resolveFieldValue(fv *FieldValue) (bool, error) { - if fv.Field == FieldEventType { + switch { + case fv.Field == FieldEventType: + if fv.Operator != FieldOperator_EQUAL { + return false, fmt.Errorf("bad operator %d for field %s", fv.Operator, fv.Field) + } v, err := strconv.ParseInt(fv.Value, 10, 32) if err != nil { - return fv.Negate + return fv.Negate, err } if v == int64(e.EventType) { - return !fv.Negate + return !fv.Negate, nil + } + return fv.Negate, nil + case fv.Field == FieldEventStatus: + if fv.Operator != FieldOperator_EQUAL { + return false, fmt.Errorf("bad operator %d for field %s", fv.Operator, fv.Field) } - return fv.Negate - } - - if fv.Field == FieldEventStatus { v, err := strconv.ParseInt(fv.Value, 10, 32) if err != nil { - return fv.Negate + return fv.Negate, err } if v == int64(e.EventType) { - return !fv.Negate + return !fv.Negate, nil } - return fv.Negate + return fv.Negate, nil + case fv.Field == FieldModule: + res, err := compare(fv.Operator, fv.Value, e.Module) + if err != nil { + return false, nil + } + return res != fv.Negate, nil + case fv.Field == FieldIdentifier: + res, err := compare(fv.Operator, fv.Value, e.Identifier) + if err != nil { + return false, nil + } + return res != fv.Negate, nil + case fv.Field == FieldChainID: + res, err := compare(fv.Operator, fv.Value, e.ChainId) + if err != nil { + return false, nil + } + return res != fv.Negate, nil + case fv.Field == FieldCallback: + res, err := compare(fv.Operator, fv.Value, e.ChainId) + if err != nil { + return false, nil + } + return res != fv.Negate, nil } - if fv.Field == FieldModule && fv.Value == e.Module { - return !fv.Negate - } - if fv.Field == FieldIdentifier && fv.Value == e.Identifier { - return !fv.Negate - } - if fv.Field == FieldChainID && fv.Value == e.ChainId { - return !fv.Negate - } + return fv.Negate, nil +} - return fv.Negate +func compare(operator FieldOperator, testValue, value string) (bool, error) { + switch operator { + case FieldOperator_EQUAL: + return testValue == value, nil + case FieldOperator_CONTAINS: + return strings.Contains(value, testValue), nil + case FieldOperator_BEGINSWITH: + return strings.HasPrefix(value, testValue), nil + case FieldOperator_ENDSWITH: + return strings.HasSuffix(value, testValue), nil + default: + return false, fmt.Errorf("unrecognised operator %d", operator) + } } diff --git a/x/eventmanager/types/genesis.pb.go b/x/eventmanager/types/genesis.pb.go index bda6a1d86..d41a240a1 100644 --- a/x/eventmanager/types/genesis.pb.go +++ b/x/eventmanager/types/genesis.pb.go @@ -25,6 +25,40 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type FieldOperator int32 + +const ( + FieldOperator_UNSPECIFIED FieldOperator = 0 + FieldOperator_EQUAL FieldOperator = 1 + FieldOperator_CONTAINS FieldOperator = 2 + FieldOperator_BEGINSWITH FieldOperator = 3 + FieldOperator_ENDSWITH FieldOperator = 4 +) + +var FieldOperator_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "EQUAL", + 2: "CONTAINS", + 3: "BEGINSWITH", + 4: "ENDSWITH", +} + +var FieldOperator_value = map[string]int32{ + "UNSPECIFIED": 0, + "EQUAL": 1, + "CONTAINS": 2, + "BEGINSWITH": 3, + "ENDSWITH": 4, +} + +func (x FieldOperator) String() string { + return proto.EnumName(FieldOperator_name, int32(x)) +} + +func (FieldOperator) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_74127b30ab787dbd, []int{0} +} + type Event struct { ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` EventType int32 `protobuf:"varint,2,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` @@ -171,9 +205,10 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo type FieldValue struct { - Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - Negate bool `protobuf:"varint,3,opt,name=negate,proto3" json:"negate,omitempty"` + Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Operator FieldOperator `protobuf:"varint,3,opt,name=operator,proto3,enum=quicksilver.eventmanager.v1.FieldOperator" json:"operator,omitempty"` + Negate bool `protobuf:"varint,4,opt,name=negate,proto3" json:"negate,omitempty"` } func (m *FieldValue) Reset() { *m = FieldValue{} } @@ -223,6 +258,13 @@ func (m *FieldValue) GetValue() string { return "" } +func (m *FieldValue) GetOperator() FieldOperator { + if m != nil { + return m.Operator + } + return FieldOperator_UNSPECIFIED +} + func (m *FieldValue) GetNegate() bool { if m != nil { return m.Negate @@ -439,6 +481,7 @@ func (m *ConditionOr) GetCondition2() *types.Any { } func init() { + proto.RegisterEnum("quicksilver.eventmanager.v1.FieldOperator", FieldOperator_name, FieldOperator_value) proto.RegisterType((*Event)(nil), "quicksilver.eventmanager.v1.Event") proto.RegisterType((*GenesisState)(nil), "quicksilver.eventmanager.v1.GenesisState") proto.RegisterType((*FieldValue)(nil), "quicksilver.eventmanager.v1.FieldValue") @@ -453,42 +496,48 @@ func init() { } var fileDescriptor_74127b30ab787dbd = []byte{ - // 549 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x54, 0xbd, 0x8e, 0xd3, 0x40, - 0x10, 0xce, 0x26, 0xe4, 0x6f, 0x13, 0x4e, 0xb0, 0x8a, 0x90, 0x13, 0x84, 0x65, 0x22, 0x21, 0x8c, - 0xc4, 0xd9, 0x4a, 0x68, 0x91, 0xd0, 0x1d, 0xe2, 0xe7, 0x2a, 0x90, 0x41, 0x57, 0xd0, 0x44, 0x1b, - 0x7b, 0xb2, 0x59, 0xc5, 0xd9, 0x0d, 0xf6, 0x3a, 0x3a, 0xf3, 0x14, 0x3c, 0x0c, 0x0f, 0x81, 0xa8, - 0xae, 0x01, 0x51, 0xa2, 0xa4, 0xe3, 0x29, 0x90, 0xd7, 0x4e, 0x70, 0x0a, 0xa8, 0x8e, 0x86, 0xce, - 0xdf, 0x37, 0x33, 0xdf, 0xcc, 0x7c, 0x63, 0x2d, 0x7e, 0xf0, 0x3e, 0xe1, 0xfe, 0x22, 0xe6, 0xe1, - 0x1a, 0x22, 0x17, 0xd6, 0x20, 0xd4, 0x92, 0x0a, 0xca, 0x20, 0x72, 0xd7, 0x23, 0x97, 0x81, 0x80, - 0x98, 0xc7, 0xce, 0x2a, 0x92, 0x4a, 0x92, 0xdb, 0xa5, 0x54, 0xa7, 0x9c, 0xea, 0xac, 0x47, 0x83, - 0xbe, 0x2f, 0xe3, 0xa5, 0x8c, 0x27, 0x3a, 0xd5, 0xcd, 0x41, 0x5e, 0x37, 0xe8, 0x31, 0xc9, 0x64, - 0xce, 0x67, 0x5f, 0x05, 0xdb, 0x67, 0x52, 0xb2, 0x10, 0x5c, 0x8d, 0xa6, 0xc9, 0xcc, 0xa5, 0x22, - 0xcd, 0x43, 0xc3, 0x9f, 0x55, 0x5c, 0x7f, 0x96, 0xe9, 0x93, 0x3e, 0x6e, 0xf9, 0x73, 0xca, 0xc5, - 0x84, 0x07, 0x06, 0xb2, 0x90, 0xdd, 0xf6, 0x9a, 0x1a, 0x9f, 0x05, 0xe4, 0x0e, 0xc6, 0x7a, 0x86, - 0x89, 0x4a, 0x57, 0x60, 0x54, 0x2d, 0x64, 0xd7, 0xbd, 0xb6, 0x66, 0xde, 0xa6, 0x2b, 0x20, 0x26, - 0xc6, 0x3c, 0x00, 0xa1, 0xf8, 0x8c, 0x43, 0x64, 0xd4, 0x74, 0x6d, 0x89, 0x21, 0x77, 0x71, 0x37, - 0x2f, 0x8f, 0x15, 0x55, 0x49, 0x6c, 0x5c, 0xd3, 0x02, 0x1d, 0xcd, 0xbd, 0xd1, 0x14, 0xb9, 0x85, - 0x1b, 0x4b, 0x19, 0x24, 0x21, 0x18, 0x75, 0x5d, 0x5e, 0x20, 0x32, 0xc0, 0x2d, 0x9f, 0x86, 0xe1, - 0x94, 0xfa, 0x0b, 0xa3, 0xa1, 0x23, 0x7b, 0x4c, 0x0c, 0xdc, 0x5c, 0xd1, 0x34, 0x94, 0x34, 0x30, - 0x9a, 0x16, 0xb2, 0xbb, 0xde, 0x0e, 0x12, 0x89, 0x6f, 0xc2, 0x05, 0xf8, 0x89, 0x82, 0x89, 0x2f, - 0x45, 0xc0, 0x15, 0x97, 0xc2, 0x68, 0x59, 0xc8, 0xee, 0x8c, 0x7b, 0x4e, 0xee, 0x85, 0xb3, 0xf3, - 0xc2, 0x39, 0x11, 0xe9, 0xe9, 0xc3, 0x2f, 0x9f, 0x8e, 0xed, 0xb2, 0xe5, 0x5c, 0x28, 0x88, 0xf4, - 0xfa, 0xb1, 0xa2, 0x0b, 0x2e, 0x98, 0xf3, 0x74, 0x27, 0x74, 0xe6, 0xdd, 0x28, 0xc4, 0xf7, 0x14, - 0xb9, 0x87, 0x8f, 0x60, 0xc9, 0x95, 0x82, 0x60, 0x32, 0x07, 0xce, 0xe6, 0xca, 0x68, 0x5b, 0xc8, - 0xae, 0x79, 0xd7, 0x0b, 0xf6, 0xa5, 0x26, 0x87, 0x47, 0xb8, 0xfb, 0x22, 0x3f, 0x73, 0xb6, 0x36, - 0x0c, 0x5f, 0x63, 0xfc, 0x9c, 0x43, 0x18, 0x9c, 0xd3, 0x30, 0x01, 0xd2, 0xc3, 0xf5, 0x59, 0x86, - 0x0a, 0xf7, 0x73, 0x90, 0xb1, 0xeb, 0x2c, 0xac, 0x6d, 0x6f, 0x7b, 0x39, 0xc8, 0xfc, 0x12, 0xc0, - 0xa8, 0x02, 0x6d, 0x77, 0xcb, 0x2b, 0xd0, 0x90, 0xe1, 0xee, 0x7e, 0xaa, 0x13, 0x91, 0x92, 0x27, - 0xb8, 0xa1, 0x65, 0x62, 0x03, 0x59, 0x35, 0xbb, 0x33, 0xbe, 0xef, 0xfc, 0xe5, 0xc7, 0x72, 0x7e, - 0x0f, 0xe3, 0x15, 0x65, 0xa5, 0x46, 0xd5, 0x3f, 0x37, 0x0a, 0xc3, 0x7f, 0xd7, 0xe8, 0x1b, 0x3a, - 0x58, 0x29, 0x20, 0x53, 0x8c, 0xf7, 0x47, 0x1d, 0x69, 0xaf, 0xae, 0xe6, 0xaa, 0x25, 0xd5, 0x83, - 0x1e, 0x63, 0x3d, 0xd0, 0x55, 0xf7, 0x18, 0x0f, 0xbf, 0x22, 0xdc, 0xd9, 0x87, 0x5e, 0x45, 0xff, - 0xcb, 0x5e, 0xa7, 0xe7, 0x9f, 0x37, 0x26, 0xba, 0xdc, 0x98, 0xe8, 0xc7, 0xc6, 0x44, 0x1f, 0xb7, - 0x66, 0xe5, 0x72, 0x6b, 0x56, 0xbe, 0x6f, 0xcd, 0xca, 0xbb, 0xc7, 0x8c, 0xab, 0x79, 0x32, 0x75, - 0x7c, 0xb9, 0x74, 0x4b, 0xd2, 0xc7, 0x1f, 0xa4, 0x80, 0x32, 0xe1, 0x5e, 0x1c, 0xbe, 0x8e, 0xd9, - 0xab, 0x13, 0x4f, 0x1b, 0x7a, 0xbe, 0x47, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x91, 0x6f, - 0x19, 0x46, 0x05, 0x00, 0x00, + // 645 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x54, 0xcd, 0x6e, 0xd3, 0x4c, + 0x14, 0xcd, 0x24, 0x4d, 0x9a, 0xdc, 0xa4, 0xf9, 0xf2, 0x8d, 0x2a, 0xe4, 0x16, 0x61, 0x85, 0x48, + 0x08, 0x53, 0x51, 0x5b, 0x0d, 0x5b, 0x24, 0x94, 0xb6, 0x69, 0x6b, 0x09, 0xa5, 0xe0, 0xf4, 0x47, + 0x62, 0x13, 0x39, 0xf6, 0xd4, 0x19, 0xd5, 0x99, 0x09, 0xf6, 0x38, 0x6a, 0x78, 0x0a, 0x96, 0x3c, + 0x08, 0x0f, 0x81, 0x58, 0x75, 0x03, 0x62, 0x89, 0xda, 0x1d, 0x4f, 0x81, 0x3c, 0x76, 0x22, 0x67, + 0x01, 0x6c, 0xca, 0x86, 0x9d, 0xcf, 0xb9, 0x73, 0xef, 0x99, 0x73, 0x7c, 0x35, 0xf0, 0xe4, 0x6d, + 0x44, 0x9d, 0xcb, 0x90, 0xfa, 0x53, 0x12, 0x18, 0x64, 0x4a, 0x98, 0x18, 0xdb, 0xcc, 0xf6, 0x48, + 0x60, 0x4c, 0x77, 0x0c, 0x8f, 0x30, 0x12, 0xd2, 0x50, 0x9f, 0x04, 0x5c, 0x70, 0x7c, 0x3f, 0x73, + 0x54, 0xcf, 0x1e, 0xd5, 0xa7, 0x3b, 0x9b, 0x1b, 0x0e, 0x0f, 0xc7, 0x3c, 0x1c, 0xc8, 0xa3, 0x46, + 0x02, 0x92, 0xbe, 0xcd, 0x75, 0x8f, 0x7b, 0x3c, 0xe1, 0xe3, 0xaf, 0x94, 0xdd, 0xf0, 0x38, 0xf7, + 0x7c, 0x62, 0x48, 0x34, 0x8c, 0x2e, 0x0c, 0x9b, 0xcd, 0x92, 0x52, 0xeb, 0x47, 0x1e, 0x8a, 0xdd, + 0x78, 0x3e, 0xde, 0x80, 0xb2, 0x33, 0xb2, 0x29, 0x1b, 0x50, 0x57, 0x41, 0x4d, 0xa4, 0x55, 0xac, + 0x55, 0x89, 0x4d, 0x17, 0x3f, 0x00, 0x90, 0x77, 0x18, 0x88, 0xd9, 0x84, 0x28, 0xf9, 0x26, 0xd2, + 0x8a, 0x56, 0x45, 0x32, 0x27, 0xb3, 0x09, 0xc1, 0x2a, 0x00, 0x75, 0x09, 0x13, 0xf4, 0x82, 0x92, + 0x40, 0x29, 0xc8, 0xde, 0x0c, 0x83, 0x1f, 0x42, 0x2d, 0x69, 0x0f, 0x85, 0x2d, 0xa2, 0x50, 0x59, + 0x91, 0x03, 0xaa, 0x92, 0xeb, 0x4b, 0x0a, 0xdf, 0x83, 0xd2, 0x98, 0xbb, 0x91, 0x4f, 0x94, 0xa2, + 0x6c, 0x4f, 0x11, 0xde, 0x84, 0xb2, 0x63, 0xfb, 0xfe, 0xd0, 0x76, 0x2e, 0x95, 0x92, 0xac, 0x2c, + 0x30, 0x56, 0x60, 0x75, 0x62, 0xcf, 0x7c, 0x6e, 0xbb, 0xca, 0x6a, 0x13, 0x69, 0x35, 0x6b, 0x0e, + 0x31, 0x87, 0xff, 0xc9, 0x15, 0x71, 0x22, 0x41, 0x06, 0x0e, 0x67, 0x2e, 0x15, 0x94, 0x33, 0xa5, + 0xdc, 0x44, 0x5a, 0xb5, 0xbd, 0xae, 0x27, 0x59, 0xe8, 0xf3, 0x2c, 0xf4, 0x0e, 0x9b, 0xed, 0x3e, + 0xfd, 0xfc, 0x71, 0x5b, 0xcb, 0x46, 0x4e, 0x99, 0x20, 0x81, 0xb4, 0x1f, 0x0a, 0xfb, 0x92, 0x32, + 0x4f, 0xdf, 0x9b, 0x0f, 0x32, 0xad, 0x46, 0x3a, 0x7c, 0x41, 0xe1, 0x47, 0x50, 0x27, 0x63, 0x2a, + 0x04, 0x71, 0x07, 0x23, 0x42, 0xbd, 0x91, 0x50, 0x2a, 0x4d, 0xa4, 0x15, 0xac, 0xb5, 0x94, 0x3d, + 0x92, 0x64, 0xab, 0x0e, 0xb5, 0xc3, 0xe4, 0x37, 0xc7, 0xb6, 0x49, 0xeb, 0x03, 0x02, 0x38, 0xa0, + 0xc4, 0x77, 0xcf, 0x6c, 0x3f, 0x22, 0x78, 0x1d, 0x8a, 0x17, 0x31, 0x4a, 0xe3, 0x4f, 0x40, 0xcc, + 0x4e, 0xe3, 0xb2, 0xcc, 0xbd, 0x62, 0x25, 0x00, 0x1f, 0x40, 0x99, 0x4f, 0x48, 0x60, 0x0b, 0x9e, + 0x24, 0x5e, 0x6f, 0x6f, 0xe9, 0xbf, 0xd9, 0x19, 0x5d, 0xca, 0x1c, 0xa7, 0x1d, 0xd6, 0xa2, 0x37, + 0x0e, 0x9e, 0x11, 0xcf, 0x16, 0x44, 0xfe, 0x95, 0xb2, 0x95, 0xa2, 0x96, 0x07, 0xb5, 0x85, 0xbd, + 0x0e, 0x9b, 0xe1, 0x17, 0x50, 0x92, 0xd7, 0x09, 0x15, 0xd4, 0x2c, 0x68, 0xd5, 0xf6, 0xe3, 0x3f, + 0xab, 0x49, 0x53, 0x56, 0xda, 0x96, 0x11, 0xca, 0xff, 0x5a, 0xc8, 0xf7, 0xff, 0x9e, 0xd0, 0x57, + 0xb4, 0x64, 0xc9, 0xc5, 0x43, 0x80, 0xc5, 0x76, 0xec, 0xc8, 0xcc, 0xef, 0x66, 0x3d, 0x32, 0x53, + 0x97, 0x34, 0xda, 0xf2, 0x42, 0x77, 0xad, 0xd1, 0x6e, 0x7d, 0x41, 0x50, 0x5d, 0x94, 0x8e, 0x83, + 0x7f, 0xc5, 0xd7, 0xd6, 0x39, 0xac, 0x2d, 0x6d, 0x2d, 0xfe, 0x0f, 0xaa, 0xa7, 0xbd, 0xfe, 0xab, + 0xee, 0x9e, 0x79, 0x60, 0x76, 0xf7, 0x1b, 0x39, 0x5c, 0x81, 0x62, 0xf7, 0xf5, 0x69, 0xe7, 0x65, + 0x03, 0xe1, 0x1a, 0x94, 0xf7, 0x8e, 0x7b, 0x27, 0x1d, 0xb3, 0xd7, 0x6f, 0xe4, 0x71, 0x1d, 0x60, + 0xb7, 0x7b, 0x68, 0xf6, 0xfa, 0xe7, 0xe6, 0xc9, 0x51, 0xa3, 0x10, 0x57, 0xbb, 0xbd, 0xfd, 0x04, + 0xad, 0xec, 0x9e, 0x7d, 0xba, 0x51, 0xd1, 0xf5, 0x8d, 0x8a, 0xbe, 0xdf, 0xa8, 0xe8, 0xfd, 0xad, + 0x9a, 0xbb, 0xbe, 0x55, 0x73, 0xdf, 0x6e, 0xd5, 0xdc, 0x9b, 0xe7, 0x1e, 0x15, 0xa3, 0x68, 0xa8, + 0x3b, 0x7c, 0x6c, 0x64, 0xee, 0xbc, 0xfd, 0x8e, 0x33, 0x92, 0x25, 0x8c, 0xab, 0xe5, 0xf7, 0x3b, + 0x7e, 0x17, 0xc3, 0x61, 0x49, 0x1a, 0x7f, 0xf6, 0x33, 0x00, 0x00, 0xff, 0xff, 0x47, 0xaf, 0xe5, + 0x26, 0xe8, 0x05, 0x00, 0x00, } func (m *Event) Marshal() (dAtA []byte, err error) { @@ -627,6 +676,11 @@ func (m *FieldValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0 } i-- + dAtA[i] = 0x20 + } + if m.Operator != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Operator)) + i-- dAtA[i] = 0x18 } if len(m.Value) > 0 { @@ -910,6 +964,9 @@ func (m *FieldValue) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } + if m.Operator != 0 { + n += 1 + sovGenesis(uint64(m.Operator)) + } if m.Negate { n += 2 } @@ -1441,6 +1498,25 @@ func (m *FieldValue) Unmarshal(dAtA []byte) error { m.Value = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) + } + m.Operator = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Operator |= FieldOperator(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Negate", wireType) } diff --git a/x/eventmanager/types/keys.go b/x/eventmanager/types/keys.go index e518f3545..d68f8c75f 100644 --- a/x/eventmanager/types/keys.go +++ b/x/eventmanager/types/keys.go @@ -33,6 +33,7 @@ const ( FieldEventStatus = "eventstatus" FieldChainID = "chainid" FieldIdentifier = "identifier" + FieldCallback = "callback" ) var ( diff --git a/x/interchainstaking/keeper/redemptions.go b/x/interchainstaking/keeper/redemptions.go index d54b6e6b4..f1766dfbc 100644 --- a/x/interchainstaking/keeper/redemptions.go +++ b/x/interchainstaking/keeper/redemptions.go @@ -238,6 +238,7 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch for _, valoper := range utils.Keys(coinsOutPerValidator) { if !coinsOutPerValidator[valoper].Amount.IsZero() { msgs = append(msgs, &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: coinsOutPerValidator[valoper]}) + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, zone.ChainId, @@ -265,10 +266,10 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch } } - if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), uint32(len(msgs)), "trigger unbonding messages"); err != nil { - return err - } - k.SetZone(ctx, zone) + // if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), uint32(len(msgs)), "trigger unbonding messages"); err != nil { + // return err + // } + //k.SetZone(ctx, zone) return nil } From cbf486a405a38bdd1ad90d2f963dc1a3979a3372 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 10 Apr 2024 23:29:29 +0100 Subject: [PATCH 05/14] eventmanager integration --- x/eventmanager/keeper/events.go | 4 + x/eventmanager/keeper/events_test.go | 2 - x/eventmanager/keeper/grpc_query.go | 24 +-- x/eventmanager/keeper/grpc_query_test.go | 39 ----- x/eventmanager/module.go | 11 +- x/eventmanager/types/conditions.go | 5 - x/eventmanager/types/fields.go | 29 ++++ x/interchainstaking/keeper/callbacks.go | 50 +++---- x/interchainstaking/keeper/delegation.go | 19 ++- x/interchainstaking/keeper/events.go | 49 ++++++- x/interchainstaking/keeper/hooks.go | 137 +++++++++++++++--- .../keeper/ibc_packet_handlers.go | 31 ++-- x/interchainstaking/types/expected_keepers.go | 1 + 13 files changed, 265 insertions(+), 136 deletions(-) delete mode 100644 x/eventmanager/keeper/grpc_query_test.go diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go index bc32cbd1c..14785fd75 100644 --- a/x/eventmanager/keeper/events.go +++ b/x/eventmanager/keeper/events.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -78,6 +80,7 @@ func (k Keeper) AllEvents(ctx sdk.Context) []types.Event { } func (k Keeper) MarkCompleted(ctx sdk.Context, module string, chainID string, identifier string) { + k.Logger(ctx).Info(fmt.Sprintf("marking event %s/%s/%s as complete!", module, chainID, identifier)) k.DeleteEvent(ctx, module, chainID, identifier) k.Trigger(ctx, module, chainID) } @@ -90,6 +93,7 @@ func (k Keeper) Trigger(ctx sdk.Context, module string, chainID string) { k.Logger(ctx).Error("unable to determine if event can execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) } if res { + k.Logger(ctx).Info(fmt.Sprintf("triggered event callback %s for event %s (%s)", e.Callback, e.Identifier, e.ChainId)) err := k.Call(ctx, e.Module, e.Callback, e.Payload) if err != nil { k.Logger(ctx).Error("unable to execute callback", "module", e.Module, "id", e.Identifier, "callback", e.Callback, "error", err) diff --git a/x/eventmanager/keeper/events_test.go b/x/eventmanager/keeper/events_test.go index 19f6ce233..4d53e2f52 100644 --- a/x/eventmanager/keeper/events_test.go +++ b/x/eventmanager/keeper/events_test.go @@ -130,7 +130,6 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { suite.Equal(1, len(events)) - fmt.Println(event) suite.True(found) suite.Equal(12345, GLOBAL_VAR) @@ -186,7 +185,6 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { suite.Equal(2, len(events)) - fmt.Println(event) suite.Equal(1, GLOBAL_VAR) suite.Equal(event.EventStatus, types.EventStatusActive) diff --git a/x/eventmanager/keeper/grpc_query.go b/x/eventmanager/keeper/grpc_query.go index efe70b178..725d5a35e 100644 --- a/x/eventmanager/keeper/grpc_query.go +++ b/x/eventmanager/keeper/grpc_query.go @@ -10,30 +10,30 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" + "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" ) -var _ types.QuerySrvrServer = Keeper{} +var _ types.QueryServer = Keeper{} -// Queries returns information about registered zones. -func (k Keeper) Queries(c context.Context, req *types.QueryRequestsRequest) (*types.QueryRequestsResponse, error) { +// Events returns information about registered zones. +func (k Keeper) Events(c context.Context, req *types.QueryEventsRequest) (*types.QueryEventsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } ctx := sdk.UnwrapSDKContext(c) - var queries []types.Query - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixQuery) + var events []types.Event + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) pageRes, err := query.FilteredPaginate(store, req.Pagination, func(_, value []byte, accumulate bool) (bool, error) { - var query types.Query - if err := k.cdc.Unmarshal(value, &query); err != nil { + var event types.Event + if err := k.cdc.Unmarshal(value, &event); err != nil { return false, err } - if query.ChainId == req.ChainId && (query.LastEmission.IsNil() || query.LastEmission.IsZero() || query.LastEmission.GTE(query.LastHeight)) { - queries = append(queries, query) + if event.ChainId == req.ChainId { + events = append(events, event) return true, nil } @@ -43,8 +43,8 @@ func (k Keeper) Queries(c context.Context, req *types.QueryRequestsRequest) (*ty return nil, status.Error(codes.Internal, err.Error()) } - return &types.QueryRequestsResponse{ - Queries: queries, + return &types.QueryEventsResponse{ + Events: events, Pagination: pageRes, }, nil } diff --git a/x/eventmanager/keeper/grpc_query_test.go b/x/eventmanager/keeper/grpc_query_test.go deleted file mode 100644 index 2261da547..000000000 --- a/x/eventmanager/keeper/grpc_query_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package keeper_test - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - icqtypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" -) - -func (suite *KeeperTestSuite) TestQueries() { - bondedQuery := stakingtypes.QueryValidatorsRequest{Status: stakingtypes.BondStatusBonded} - bz, err := bondedQuery.Marshal() - suite.NoError(err) - - query := suite.GetSimApp(suite.chainA).InterchainQueryKeeper.NewQuery( - "", - suite.path.EndpointB.ConnectionID, - suite.chainB.ChainID, - "cosmos.staking.v1beta1.Query/Validators", - bz, - sdk.NewInt(200), - "", - 0, - ) - - // set the query - suite.GetSimApp(suite.chainA).InterchainQueryKeeper.SetQuery(suite.chainA.GetContext(), *query) - - icqsrvSrv := icqtypes.QuerySrvrServer(suite.GetSimApp(suite.chainA).InterchainQueryKeeper) - - res, err := icqsrvSrv.Queries(sdk.WrapSDKContext(suite.chainA.GetContext()), &icqtypes.QueryRequestsRequest{ChainId: suite.chainB.ChainID}) - suite.NoError(err) - suite.Len(res.Queries, 1) - suite.Equal(suite.path.EndpointB.ConnectionID, res.Queries[0].ConnectionId) - suite.Equal(suite.chainB.ChainID, res.Queries[0].ChainId) - suite.Equal("cosmos.staking.v1beta1.Query/Validators", res.Queries[0].QueryType) - suite.Equal(sdk.NewInt(200), res.Queries[0].Period) - suite.Equal("", res.Queries[0].CallbackId) -} diff --git a/x/eventmanager/module.go b/x/eventmanager/module.go index 5e38100c1..368b123ef 100644 --- a/x/eventmanager/module.go +++ b/x/eventmanager/module.go @@ -1,6 +1,7 @@ package eventmanager import ( + "context" "encoding/json" "math/rand" @@ -66,10 +67,10 @@ func (AppModuleBasic) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConf // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - // err := types.RegisterQuerySrvrHandlerClient(context.Background(), mux, types.NewQuerySrvrClient(clientCtx)) - // if err != nil { - // panic(err) - // } + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } } // GetTxCmd returns the capability module's root tx command. @@ -121,7 +122,7 @@ func (AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { - //types.RegisterQuerySrvrServer(cfg.QueryServer(), am.keeper) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) } // RegisterInvariants registers the capability module's invariants. diff --git a/x/eventmanager/types/conditions.go b/x/eventmanager/types/conditions.go index 1a2ce3df9..8d326e12b 100644 --- a/x/eventmanager/types/conditions.go +++ b/x/eventmanager/types/conditions.go @@ -1,8 +1,6 @@ package types import ( - "fmt" - "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -127,7 +125,6 @@ func NewConditionOr(ctx sdk.Context, condition1, condition2 ConditionI) (*Condit // CanExecute determines whether a func (e *Event) CanExecute(ctx sdk.Context, k EMKeeper) (bool, error) { - fmt.Print(e.ExecuteCondition) if e.ExecuteCondition == nil { return true, nil } @@ -136,7 +133,5 @@ func (e *Event) CanExecute(ctx sdk.Context, k EMKeeper) (bool, error) { if err != nil { return false, err } - fmt.Print(condition) - return condition.Resolve(ctx, k) } diff --git a/x/eventmanager/types/fields.go b/x/eventmanager/types/fields.go index 802637189..7a7ca3469 100644 --- a/x/eventmanager/types/fields.go +++ b/x/eventmanager/types/fields.go @@ -104,3 +104,32 @@ func compare(operator FieldOperator, testValue, value string) (bool, error) { return false, fmt.Errorf("unrecognised operator %d", operator) } } + +func NewFieldValues(fields ...*FieldValue) []*FieldValue { + return fields +} + +func FieldEqual(field, value string) *FieldValue { + return NewFieldValue(field, value, FieldOperator_EQUAL, false) +} + +func FieldNotEqual(field, value string) *FieldValue { + return NewFieldValue(field, value, FieldOperator_EQUAL, true) +} + +func FieldBegins(field, value string) *FieldValue { + return NewFieldValue(field, value, FieldOperator_BEGINSWITH, false) +} + +func FieldEnds(field, value string) *FieldValue { + return NewFieldValue(field, value, FieldOperator_ENDSWITH, false) +} + +func NewFieldValue(field, value string, operator FieldOperator, negate bool) *FieldValue { + return &FieldValue{ + field, + value, + operator, + negate, + } +} diff --git a/x/interchainstaking/keeper/callbacks.go b/x/interchainstaking/keeper/callbacks.go index f6159f28e..6ca90fe71 100644 --- a/x/interchainstaking/keeper/callbacks.go +++ b/x/interchainstaking/keeper/callbacks.go @@ -29,6 +29,7 @@ import ( "github.com/quicksilver-zone/quicksilver/utils" "github.com/quicksilver-zone/quicksilver/utils/addressutils" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" icqtypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" ) @@ -68,7 +69,7 @@ func (c Callbacks) AddCallback(id string, fn interface{}) icqtypes.QueryCallback } func (c Callbacks) RegisterCallbacks() icqtypes.QueryCallbacks { - a := c. + return c. AddCallback("valset", Callback(ValsetCallback)). AddCallback("validator", Callback(ValidatorCallback)). AddCallback("rewards", Callback(RewardsCallback)). @@ -85,8 +86,6 @@ func (c Callbacks) RegisterCallbacks() icqtypes.QueryCallbacks { AddCallback("delegationaccountbalance", Callback(DelegationAccountBalanceCallback)). AddCallback("delegationaccountbalances", Callback(DelegationAccountBalancesCallback)). AddCallback("signinginfo", Callback(SigningInfoCallback)) - - return a.(Callbacks) } // ----------------------------------- @@ -124,19 +123,13 @@ func RewardsCallback(k *Keeper, ctx sdk.Context, args []byte, query icqtypes.Que return err } - // decrement waitgroup as we have received back the query - // (initially incremented in AfterEpochEnd) - if err = zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "rewards callback"); err != nil { - // given that there _could_ be a backlog of message, we don't want to bail here, else they will remain undeliverable. - k.Logger(ctx).Error(err.Error()) - } - - k.Logger(ctx).Debug("QueryDelegationRewards callback", "wg", zone.GetWithdrawalWaitgroup(), "delegatorAddress", rewardsQuery.DelegatorAddress, "zone", query.ChainId) + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, "query_rewards_epoch") return k.WithdrawDelegationRewardsForResponse(ctx, &zone, rewardsQuery.DelegatorAddress, args) } func DelegationsEpochCallback(k *Keeper, ctx sdk.Context, args []byte, query icqtypes.Query) error { + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, "query_delegations_epoch") return delegationsCallback(k, ctx, args, query, true) } @@ -601,6 +594,7 @@ func DelegationAccountBalanceCallback(k *Keeper, ctx sdk.Context, args []byte, q if !found { return fmt.Errorf("no registered zone for chain id: %s", query.GetChainId()) } + // strip the BalancesPrefix from the request key, as AddressFromBalancesStore expects this to be removed // by the prefixIterator. query.Request is a value that Quicksilver always sets, and is not user generated, // but lets us be safe here :) @@ -614,6 +608,9 @@ func DelegationAccountBalanceCallback(k *Keeper, ctx sdk.Context, args []byte, q return err } + identifier := fmt.Sprintf("query_delegationaccountbalance_epoch/%s", denom) + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, identifier) + coin, err := bankkeeper.UnmarshalBalanceCompat(k.cdc, args, denom) if err != nil { return err @@ -640,10 +637,6 @@ func DelegationAccountBalanceCallback(k *Keeper, ctx sdk.Context, args []byte, q } k.Logger(ctx).Info("Received balance response for denom", "denom", coin.Denom) - if err = zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "delegationaccountbalance callback"); err != nil { - // given that there _could_ be a backlog of message, we don't want to bail here, else they will remain undeliverable. - k.Logger(ctx).Error(err.Error()) - } // set the zone amount. balance := zone.DelegationAddress.Balance @@ -663,12 +656,6 @@ func DelegationAccountBalanceCallback(k *Keeper, ctx sdk.Context, args []byte, q // if token is not valid for staking, then send to withdrawal account. if valid, _ := zone.ValidateCoinsForZone(sdk.NewCoins(coin), k.GetValidatorAddressesAsMap(ctx, zone.ChainId)); !valid { k.Logger(ctx).Info("token is not a valid staking token, so sending to withdrawal account for disbursal", "chain", zone.ChainId, "assets", coin) - if zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("triggering redemption rate calc in lieu of delegation flush") - if err := k.TriggerRedemptionRate(ctx, &zone); err != nil { - return err - } - } return k.SendToWithdrawal(ctx, &zone, zone.DelegationAddress, sdk.NewCoins(coin)) } @@ -683,10 +670,7 @@ func DelegationAccountBalancesCallback(k *Keeper, ctx sdk.Context, args []byte, result := banktypes.QueryAllBalancesResponse{} k.cdc.MustUnmarshal(args, &result) - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "delegationaccountbalances callback"); err != nil { - // given that there _could_ be a backlog of message, we don't want to bail here, else they will remain undeliverable. - k.Logger(ctx).Error(err.Error()) - } + k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, "query_delegationaccountbalances_epoch") addressBytes, err := addressutils.AccAddressFromBech32(zone.DelegationAddress.Address, zone.AccountPrefix) if err != nil { @@ -710,10 +694,18 @@ func DelegationAccountBalancesCallback(k *Keeper, ctx sdk.Context, args []byte, 0, ) - if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, fmt.Sprintf("delegation account balance for %s", coin.Denom)); err != nil { - return err - } - k.Logger(ctx).Info("Emitting balance request for denom", "denom", coin.Denom, "waitgroup", zone.GetWithdrawalWaitgroup()) + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + query.ChainId, + fmt.Sprintf("query_delegationaccountbalance_epoch/%s", coin.Denom), + "", + emtypes.EventTypeICQAccountBalance, + emtypes.EventStatusActive, + nil, + nil, + ) + } k.SetZone(ctx, &zone) diff --git a/x/interchainstaking/keeper/delegation.go b/x/interchainstaking/keeper/delegation.go index 2548401fd..56dbe7ee4 100644 --- a/x/interchainstaking/keeper/delegation.go +++ b/x/interchainstaking/keeper/delegation.go @@ -13,6 +13,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/quicksilver-zone/quicksilver/utils" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" lsmstakingtypes "github.com/quicksilver-zone/quicksilver/x/lsmtypes" ) @@ -262,23 +263,27 @@ func (k *Keeper) WithdrawDelegationRewardsForResponse(ctx sdk.Context, zone *typ k.Logger(ctx).Info("Withdraw rewards", "delegator", delegator, "validator", del.ValidatorAddress, "amount", del.Reward) msgs = append(msgs, &distrtypes.MsgWithdrawDelegatorReward{DelegatorAddress: delegator, ValidatorAddress: del.ValidatorAddress}) + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("%s/%s", "withdraw_rewards_epoch", del.ValidatorAddress), + "", + emtypes.EventTypeICAWithdrawRewards, + emtypes.EventStatusActive, + nil, + nil, + ) } } if len(msgs) == 0 { - // always setZone here because calling method update waitgroup. - k.SetZone(ctx, zone) return nil } // increment withdrawal waitgroup for every withdrawal msg sent // this allows us to track individual msg responses and ensure all // responses have been received and handled... // HandleWithdrawRewards contains the opposing decrement. - if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), uint32(len(msgs)), "WithdrawDelegationRewardsForResponse"); err != nil { - return err - } - k.SetZone(ctx, zone) - k.Logger(ctx).Info("Received WithdrawDelegationRewardsForResponse acknowledgement", "wg", zone.GetWithdrawalWaitgroup(), "address", delegator) return k.SubmitTx(ctx, msgs, zone.DelegationAddress, "", zone.MessagesPerTx) } diff --git a/x/interchainstaking/keeper/events.go b/x/interchainstaking/keeper/events.go index 8b120d1e9..6655a95d3 100644 --- a/x/interchainstaking/keeper/events.go +++ b/x/interchainstaking/keeper/events.go @@ -1,11 +1,13 @@ package keeper import ( + "encoding/json" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" + "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" ) // ___________________________________________________________________________________________________ @@ -43,17 +45,52 @@ func (c EventCallbacks) AddCallback(id string, fn interface{}) emtypes.EventCall } func (c EventCallbacks) RegisterCallbacks() emtypes.EventCallbacks { - a := c. - AddCallback("valset", EventCallback(TestCallback)) - - return a.(EventCallbacks) + return c. + AddCallback(ICQEmitDelegatorDelegations, EventCallback(EmitDelegatorDelegations)). + AddCallback(TriggerCalculateRedemptionRate, EventCallback(CalculateRedemptionRate)) } +const ( + ICQEmitDelegatorDelegations = "ICQEmitDelegatorDelegations" + TriggerCalculateRedemptionRate = "CalculateRedemptionRate" +) + // ----------------------------------- // Callback Handlers // ----------------------------------- -func TestCallback(k *Keeper, ctx sdk.Context, args []byte) error { - k.Logger(ctx).Error("TEST CALLBACK") +type DelegatorDelegationsParams struct { + ChainID string + ConnectionID string + Request []byte +} + +func EmitDelegatorDelegations(k *Keeper, ctx sdk.Context, args []byte) error { + + var params DelegatorDelegationsParams + err := json.Unmarshal(args, ¶ms) + if err != nil { + return err + } + + k.ICQKeeper.MakeRequest( + ctx, + params.ConnectionID, + params.ChainID, + "cosmos.staking.v1beta1.Query/DelegatorDelegations", + params.Request, + sdk.NewInt(-1), + types.ModuleName, + "delegations_epoch", + 0, + ) return nil } + +func CalculateRedemptionRate(k *Keeper, ctx sdk.Context, args []byte) error { + zone, found := k.GetZone(ctx, string(args)) + if !found { + return fmt.Errorf("unable to find zone %s", args) + } + return k.TriggerRedemptionRate(ctx, &zone) +} diff --git a/x/interchainstaking/keeper/hooks.go b/x/interchainstaking/keeper/hooks.go index d7c2eded9..7212300d9 100644 --- a/x/interchainstaking/keeper/hooks.go +++ b/x/interchainstaking/keeper/hooks.go @@ -1,6 +1,8 @@ package keeper import ( + "encoding/json" + "fmt" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -10,6 +12,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" ) @@ -146,19 +149,61 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNum delegationQuery := stakingtypes.QueryDelegatorDelegationsRequest{DelegatorAddr: zone.DelegationAddress.Address, Pagination: &query.PageRequest{Limit: uint64(len(vals))}} bz := k.cdc.MustMarshal(&delegationQuery) - k.ICQKeeper.MakeRequest( + delegationParams := DelegatorDelegationsParams{ + ChainID: zone.ChainId, + ConnectionID: zone.ConnectionId, + Request: bz, + } + + delegationPayload, err := json.Marshal(&delegationParams) + if err != nil { + panic(err) + } + delegationCondition1, err := emtypes.NewConditionAll(ctx, + emtypes.NewFieldValues( + emtypes.FieldEqual(emtypes.FieldChainID, zone.ChainId), + emtypes.FieldEqual(emtypes.FieldModule, types.ModuleName), + emtypes.FieldEqual(emtypes.FieldEventType, fmt.Sprintf("%d", emtypes.EventTypeICAUnbond)), + emtypes.FieldBegins(emtypes.FieldIdentifier, types.EpochWithdrawalMemo(epochNumber)), + ), + true, + ) + if err != nil { + panic(err) + } + delegationCondition2, err := emtypes.NewConditionAll(ctx, + emtypes.NewFieldValues( + emtypes.FieldEqual(emtypes.FieldChainID, zone.ChainId), + emtypes.FieldEqual(emtypes.FieldModule, types.ModuleName), + emtypes.FieldEqual(emtypes.FieldEventType, fmt.Sprintf("%d", emtypes.EventTypeICADelegate)), + emtypes.FieldBegins(emtypes.FieldIdentifier, fmt.Sprintf("batch/%d", epochNumber)), + ), + true, + ) + if err != nil { + panic(err) + } + + delegationCondition, err := emtypes.NewConditionAnd( ctx, - zone.ConnectionId, - zone.ChainId, - "cosmos.staking.v1beta1.Query/DelegatorDelegations", - bz, - sdk.NewInt(-1), - types.ModuleName, - "delegations_epoch", - 0, + delegationCondition1, + delegationCondition2, ) + if err != nil { + panic(err) + } - _ = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, "delegations trigger") + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + "query_delegations_epoch", + ICQEmitDelegatorDelegations, + emtypes.EventTypeICQQueryDelegations, + emtypes.EventStatusPending, + delegationCondition, + delegationPayload, + ) balancesQuery := banktypes.QueryAllBalancesRequest{Address: zone.DelegationAddress.Address} bz = k.cdc.MustMarshal(&balancesQuery) @@ -173,8 +218,18 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNum "delegationaccountbalances", 0, ) - // increment waitgroup; decremented in delegationaccountbalance callback - _ = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, "delegationaccountbalances trigger") + + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + "query_delegationaccountbalances_epoch", + "", + emtypes.EventTypeICQAccountBalances, + emtypes.EventStatusActive, + nil, + nil, + ) rewardsQuery := distrtypes.QueryDelegationTotalRewardsRequest{DelegatorAddress: zone.DelegationAddress.Address} bz = k.cdc.MustMarshal(&rewardsQuery) @@ -191,12 +246,60 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNum 0, ) - // increment the WithdrawalWaitgroup - // this allows us to track the response for every protocol delegator - // WithdrawalWaitgroup is decremented in RewardsCallback - _ = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, "rewards trigger") + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + "query_rewards_epoch", + "", + emtypes.EventTypeICQQueryRewards, + emtypes.EventStatusActive, + nil, + nil, + ) + + rrCondition1, err := emtypes.NewConditionAll(ctx, + emtypes.NewFieldValues( + emtypes.FieldEqual(emtypes.FieldChainID, zone.ChainId), + emtypes.FieldEqual(emtypes.FieldModule, types.ModuleName), + emtypes.FieldEqual(emtypes.FieldEventType, fmt.Sprintf("%d", emtypes.EventTypeICAWithdrawRewards)), + ), + true, + ) + if err != nil { + panic(err) + } + rrCondition2, err := emtypes.NewConditionAll(ctx, + emtypes.NewFieldValues( + emtypes.FieldEqual(emtypes.FieldChainID, zone.ChainId), + emtypes.FieldEqual(emtypes.FieldModule, types.ModuleName), + emtypes.FieldEqual(emtypes.FieldEventType, fmt.Sprintf("%d", emtypes.EventTypeICQQueryDelegations)), + ), + true, + ) + if err != nil { + panic(err) + } + rrCondition, err := emtypes.NewConditionAnd(ctx, rrCondition1, rrCondition2) + if err != nil { + panic(err) + } + rrConditionAnd, err := emtypes.NewConditionAnd(ctx, rrCondition, delegationCondition) + if err != nil { + panic(err) + } - k.SetZone(ctx, zone) + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + "trigger_rr", + TriggerCalculateRedemptionRate, + emtypes.EventTypeICQQueryRewards, + emtypes.EventStatusPending, + rrConditionAnd, + []byte(zone.ChainId), + ) return false }) diff --git a/x/interchainstaking/keeper/ibc_packet_handlers.go b/x/interchainstaking/keeper/ibc_packet_handlers.go index b57ee0b32..4ca2ecc90 100644 --- a/x/interchainstaking/keeper/ibc_packet_handlers.go +++ b/x/interchainstaking/keeper/ibc_packet_handlers.go @@ -29,6 +29,7 @@ import ( "github.com/quicksilver-zone/quicksilver/utils" "github.com/quicksilver-zone/quicksilver/utils/addressutils" cmtypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" querytypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" lsmstakingtypes "github.com/quicksilver-zone/quicksilver/x/lsmtypes" @@ -1388,21 +1389,9 @@ func (k *Keeper) HandleWithdrawRewards(ctx sdk.Context, msg sdk.Msg, connectionI // operates outside the delegator set, its purpose is to track validator // performance only. if withdrawalMsg.DelegatorAddress != zone.PerformanceAddress.Address { - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "handle withdraw rewards"); err != nil { - k.Logger(ctx).Error(err.Error()) - return nil - // return nil here so we don't reject the incoming tx, but log the error and don't trigger RR update for repeated zero. - } - k.SetZone(ctx, zone) - } - k.Logger(ctx).Info("Received MsgWithdrawDelegatorReward acknowledgement", "wg", zone.GetWithdrawalWaitgroup(), "delegator", withdrawalMsg.DelegatorAddress) - switch zone.GetWithdrawalWaitgroup() == 0 { - case true: - k.Logger(ctx).Info("triggering redemption rate calc after rewards withdrawal") - return k.TriggerRedemptionRate(ctx, zone) - default: - return nil + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("%s/%s", "withdraw_rewards_epoch", withdrawalMsg.ValidatorAddress)) } + return nil } func (k *Keeper) TriggerRedemptionRate(ctx sdk.Context, zone *types.Zone) error { @@ -1425,10 +1414,24 @@ func (k *Keeper) TriggerRedemptionRate(ctx sdk.Context, zone *types.Zone) error "distributerewards", 0, ) + + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + "query_withdrawal_balance", + "", + emtypes.EventTypeICQAccountBalances, + emtypes.EventStatusActive, + nil, + nil, + ) + return nil } func DistributeRewardsFromWithdrawAccount(k *Keeper, ctx sdk.Context, args []byte, query querytypes.Query) error { + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, "query_withdrawal_balance") zone, found := k.GetZone(ctx, query.ChainId) if !found { return fmt.Errorf("unable to find zone for %s", query.ChainId) diff --git a/x/interchainstaking/types/expected_keepers.go b/x/interchainstaking/types/expected_keepers.go index c8805d995..d1c12302b 100644 --- a/x/interchainstaking/types/expected_keepers.go +++ b/x/interchainstaking/types/expected_keepers.go @@ -63,4 +63,5 @@ type EpochsKeeper interface { type EventManagerKeeper interface { AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, eventType, status int32, condtion emtypes.ConditionI, payload []byte) + MarkCompleted(ctx sdk.Context, module string, chainID string, identifier string) } From 05787e992a666e56aaecf72a03e87716af976b83 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Mon, 15 Apr 2024 14:32:04 +0100 Subject: [PATCH 06/14] wip --- x/eventmanager/types/keys.go | 11 +- x/interchainstaking/keeper/callbacks.go | 2 +- x/interchainstaking/keeper/callbacks_test.go | 10 - x/interchainstaking/keeper/delegation.go | 55 +++--- x/interchainstaking/keeper/delegation_test.go | 2 +- x/interchainstaking/keeper/hooks.go | 6 +- .../keeper/ibc_packet_handlers.go | 172 ++++++------------ .../keeper/ibc_packet_handlers_test.go | 27 --- x/interchainstaking/keeper/redemptions.go | 13 +- x/interchainstaking/types/zones.go | 27 --- x/interchainstaking/types/zones_test.go | 14 -- 11 files changed, 105 insertions(+), 234 deletions(-) diff --git a/x/eventmanager/types/keys.go b/x/eventmanager/types/keys.go index d68f8c75f..9c516332c 100644 --- a/x/eventmanager/types/keys.go +++ b/x/eventmanager/types/keys.go @@ -22,11 +22,12 @@ const ( EventTypeUnspecified = int32(0x00) EventTypeICQQueryRewards = int32(0x01) EventTypeICQQueryDelegations = int32(0x02) - EventTypeICQAccountBalances = int32(0x03) - EventTypeICQAccountBalance = int32(0x04) - EventTypeICAWithdrawRewards = int32(0x05) - EventTypeICADelegate = int32(0x06) - EventTypeICAUnbond = int32(0x07) + EventTypeICQQueryDelegation = int32(0x03) + EventTypeICQAccountBalances = int32(0x04) + EventTypeICQAccountBalance = int32(0x05) + EventTypeICAWithdrawRewards = int32(0x06) + EventTypeICADelegate = int32(0x07) + EventTypeICAUnbond = int32(0x08) FieldEventType = "eventtype" FieldModule = "module" diff --git a/x/interchainstaking/keeper/callbacks.go b/x/interchainstaking/keeper/callbacks.go index 6ca90fe71..57e0356c4 100644 --- a/x/interchainstaking/keeper/callbacks.go +++ b/x/interchainstaking/keeper/callbacks.go @@ -670,7 +670,7 @@ func DelegationAccountBalancesCallback(k *Keeper, ctx sdk.Context, args []byte, result := banktypes.QueryAllBalancesResponse{} k.cdc.MustUnmarshal(args, &result) - k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, "query_delegationaccountbalances_epoch") + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, "query_delegationaccountbalances_epoch") addressBytes, err := addressutils.AccAddressFromBech32(zone.DelegationAddress.Address, zone.AccountPrefix) if err != nil { diff --git a/x/interchainstaking/keeper/callbacks_test.go b/x/interchainstaking/keeper/callbacks_test.go index 26c013b5a..04bb8af54 100644 --- a/x/interchainstaking/keeper/callbacks_test.go +++ b/x/interchainstaking/keeper/callbacks_test.go @@ -753,7 +753,6 @@ func (suite *KeeperTestSuite) TestHandleRewardsCallbackNonDelegator() { ctx := suite.chainA.GetContext() zone, _ := quicksilver.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.NoError(zone.IncrementWithdrawalWaitgroup(quicksilver.Logger(), 1, "test rewards callback handler")) quicksilver.InterchainstakingKeeper.SetZone(ctx, &zone) user := addressutils.GenerateAccAddressForTest() @@ -789,7 +788,6 @@ func (suite *KeeperTestSuite) TestHandleRewardsCallbackEmptyResponse() { ctx := suite.chainA.GetContext() zone, _ := quicksilver.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.NoError(zone.IncrementWithdrawalWaitgroup(quicksilver.Logger(), 1, "test rewards callback handler")) quicksilver.InterchainstakingKeeper.SetZone(ctx, &zone) @@ -819,9 +817,6 @@ func (suite *KeeperTestSuite) TestHandleValideRewardsCallback() { ctx := suite.chainA.GetContext() zone, _ := quicksilver.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.NoError(zone.IncrementWithdrawalWaitgroup(quicksilver.Logger(), 1, "test rewards callback handler")) - - quicksilver.InterchainstakingKeeper.SetZone(ctx, &zone) queryReq := distrtypes.QueryDelegationTotalRewardsRequest{ DelegatorAddress: zone.DelegationAddress.Address, @@ -2564,7 +2559,6 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalancesCallback() { ctx := suite.chainA.GetContext() zone, _ := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - zone.SetWithdrawalWaitgroup(app.Logger(), 1, "init") zone.DelegationAddress.Balance = t.PreviousBalance app.InterchainstakingKeeper.SetZone(ctx, &zone) @@ -2618,7 +2612,6 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallbackDenomMismatch( ctx := suite.chainA.GetContext() zone, _ := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - zone.SetWithdrawalWaitgroup(app.Logger(), 2, "init") zone.DelegationAddress.Balance = sdk.NewCoins(sdk.NewCoin("uatom", sdkmath.NewInt(500_000_000))) app.InterchainstakingKeeper.SetZone(ctx, &zone) @@ -2692,7 +2685,6 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallback() { ctx := suite.chainA.GetContext() zone, _ := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - zone.SetWithdrawalWaitgroup(app.Logger(), 2, "init") zone.DelegationAddress.Balance = sdk.NewCoins(sdk.NewCoin("uatom", sdkmath.NewInt(500_000_000))) app.InterchainstakingKeeper.SetZone(ctx, &zone) @@ -2727,7 +2719,6 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallbackLSM() { valOper := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID)[0] denom := valOper + "/1" - zone.SetWithdrawalWaitgroup(app.Logger(), 2, "init") zone.DelegationAddress.Balance = sdk.NewCoins(sdk.NewCoin("uatom", sdkmath.NewInt(500))) app.InterchainstakingKeeper.SetZone(ctx, &zone) @@ -2766,7 +2757,6 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallbackLSMBadZone() { valOper := addressutils.GenerateAddressForTestWithPrefix("quickvaloper") denom := valOper + "/1" - zone.SetWithdrawalWaitgroup(app.Logger(), 2, "init") zone.DelegationAddress.Balance = sdk.NewCoins(sdk.NewCoin("uatom", sdkmath.NewInt(500))) app.InterchainstakingKeeper.SetZone(ctx, &zone) diff --git a/x/interchainstaking/keeper/delegation.go b/x/interchainstaking/keeper/delegation.go index 56dbe7ee4..2629e4ea6 100644 --- a/x/interchainstaking/keeper/delegation.go +++ b/x/interchainstaking/keeper/delegation.go @@ -1,8 +1,10 @@ package keeper import ( + "crypto/sha256" "errors" "fmt" + "strings" sdkmath "cosmossdk.io/math" @@ -192,24 +194,49 @@ func (k *Keeper) IterateDelegatorDelegations(ctx sdk.Context, chainID string, de } } -func (*Keeper) PrepareDelegationMessagesForCoins(zone *types.Zone, allocations map[string]sdkmath.Int, isFlush bool) []sdk.Msg { +func (k *Keeper) PrepareDelegationMessagesForCoins(ctx sdk.Context, zone *types.Zone, allocations map[string]sdkmath.Int, isFlush bool) []sdk.Msg { var msgs []sdk.Msg for _, valoper := range utils.Keys(allocations) { if allocations[valoper].IsPositive() { if allocations[valoper].GTE(zone.DustThreshold) || isFlush { - msgs = append(msgs, &stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: sdk.NewCoin(zone.BaseDenom, allocations[valoper])}) + msg := &stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: sdk.NewCoin(zone.BaseDenom, allocations[valoper])} + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("delegation/%s/%x", valoper, sha256.Sum256(msg.GetSignBytes())), + "", + emtypes.EventTypeICADelegate, + emtypes.EventStatusActive, + nil, + nil, + ) + msgs = append(msgs, msg) } } } return msgs } -func (*Keeper) PrepareDelegationMessagesForShares(zone *types.Zone, coins sdk.Coins) []sdk.Msg { +func (k *Keeper) PrepareDelegationMessagesForShares(ctx sdk.Context, zone *types.Zone, coins sdk.Coins) []sdk.Msg { var msgs []sdk.Msg for _, coin := range coins.Sort() { if coin.IsPositive() { // no min amount here. - msgs = append(msgs, &lsmstakingtypes.MsgRedeemTokensForShares{DelegatorAddress: zone.DelegationAddress.Address, Amount: coin}) + valoper := strings.Split(coin.Denom, "/")[0] + msg := &lsmstakingtypes.MsgRedeemTokensForShares{DelegatorAddress: zone.DelegationAddress.Address, Amount: coin} + msgs = append(msgs, msg) + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("delegation/%s/%x", valoper, sha256.Sum256(msg.GetSignBytes())), + "", + emtypes.EventTypeICADelegate, + emtypes.EventStatusActive, + nil, + nil, + ) } } return msgs @@ -334,13 +361,6 @@ func (k *Keeper) FlushOutstandingDelegations(ctx sdk.Context, zone *types.Zone, if hasNeg || coinsToFlush.IsZero() { k.Logger(ctx).Info("delegate account balance negative, or nothing to flush, setting outdated receipts") k.SetReceiptsCompleted(ctx, zone.ChainId, exclusionTime, ctx.BlockTime(), delAddrBalance.Denom) - if zone.GetWithdrawalWaitgroup() == 0 { - // we won't be sending any messages when we exit here; so if WG==0, then trigger RR update - k.Logger(ctx).Info("triggering redemption rate calc in lieu of delegation flush (non-positive coins)") - if err := k.TriggerRedemptionRate(ctx, zone); err != nil { - return err - } - } return nil } @@ -352,21 +372,10 @@ func (k *Keeper) FlushOutstandingDelegations(ctx sdk.Context, zone *types.Zone, ToAddress: "", Amount: coinsToFlush, } - numMsgs, err := k.handleSendToDelegate(ctx, zone, &sendMsg, fmt.Sprintf("batch/%d", exclusionTime.Unix())) + err := k.handleSendToDelegate(ctx, zone, &sendMsg, fmt.Sprintf("batch/%d", exclusionTime.Unix())) if err != nil { return err } - if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), uint32(numMsgs), "sending flush messages"); err != nil { - return err - } - - // if we didn't send any messages (thus no acks will happen), and WG==0, then trigger RR update - if numMsgs == 0 && zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("triggering redemption rate calc in lieu of delegation flush (no messages to send)") - if err := k.TriggerRedemptionRate(ctx, zone); err != nil { - return err - } - } k.SetZone(ctx, zone) return nil diff --git a/x/interchainstaking/keeper/delegation_test.go b/x/interchainstaking/keeper/delegation_test.go index 4ad5a0248..4befd4a3e 100644 --- a/x/interchainstaking/keeper/delegation_test.go +++ b/x/interchainstaking/keeper/delegation_test.go @@ -625,7 +625,7 @@ func (suite *KeeperTestSuite) TestFlushOutstandingDelegations() { if test.mockAck { allocations, err := quicksilver.InterchainstakingKeeper.DeterminePlanForDelegation(ctx, &zone, test.expectedDelegation) suite.NoError(err) - msgs = append(msgs, quicksilver.InterchainstakingKeeper.PrepareDelegationMessagesForCoins(&zone, allocations, true)...) + msgs = append(msgs, quicksilver.InterchainstakingKeeper.PrepareDelegationMessagesForCoins(ctx, &zone, allocations, true)...) } err := quicksilver.InterchainstakingKeeper.FlushOutstandingDelegations(ctx, &zone, test.delAddrBalance) diff --git a/x/interchainstaking/keeper/hooks.go b/x/interchainstaking/keeper/hooks.go index 7212300d9..10e181132 100644 --- a/x/interchainstaking/keeper/hooks.go +++ b/x/interchainstaking/keeper/hooks.go @@ -104,10 +104,6 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNum return false }) - if zone.GetWithdrawalWaitgroup() > 0 { - zone.SetWithdrawalWaitgroup(k.Logger(ctx), 0, "epoch waitgroup was unexpected > 0") - } - if err := k.HandleQueuedUnbondings(ctx, zone, epochNumber); err != nil { // we can and need not panic here; logging the error is sufficient. // an error here is not expected, but also not terminal. @@ -176,7 +172,7 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNum emtypes.FieldEqual(emtypes.FieldChainID, zone.ChainId), emtypes.FieldEqual(emtypes.FieldModule, types.ModuleName), emtypes.FieldEqual(emtypes.FieldEventType, fmt.Sprintf("%d", emtypes.EventTypeICADelegate)), - emtypes.FieldBegins(emtypes.FieldIdentifier, fmt.Sprintf("batch/%d", epochNumber)), + emtypes.FieldBegins(emtypes.FieldIdentifier, "delegation"), // should this be all delegations, or just from this epoch? ), true, ) diff --git a/x/interchainstaking/keeper/ibc_packet_handlers.go b/x/interchainstaking/keeper/ibc_packet_handlers.go index 4ca2ecc90..afcfd5b84 100644 --- a/x/interchainstaking/keeper/ibc_packet_handlers.go +++ b/x/interchainstaking/keeper/ibc_packet_handlers.go @@ -1,6 +1,7 @@ package keeper import ( + "crypto/sha256" "errors" "fmt" "reflect" @@ -393,8 +394,7 @@ func (k *Keeper) HandleCompleteSend(ctx sdk.Context, msg sdk.Msg, memo string, c case zone.IsDelegateAddress(sMsg.ToAddress) && zone.IsDepositAddress(sMsg.FromAddress): k.Logger(ctx).Info("delegate account received tokens from deposit account; delegating deposit", "amount", sMsg.Amount, "memo", memo) - _, err := k.handleSendToDelegate(ctx, zone, sMsg, memo) - return err + return k.handleSendToDelegate(ctx, zone, sMsg, memo) case zone.IsDelegateAddress(sMsg.FromAddress): k.Logger(ctx).Info("delegate account send tokens; handling withdrawal", "amount", sMsg.Amount, "memo", memo) @@ -412,27 +412,26 @@ func (k *Keeper) HandleCompleteSend(ctx sdk.Context, msg sdk.Msg, memo string, c } func (k *Keeper) handleRewardsDelegation(ctx sdk.Context, zone types.Zone, msg *banktypes.MsgSend) error { - _, err := k.handleSendToDelegate(ctx, &zone, msg, "rewards") - return err + return k.handleSendToDelegate(ctx, &zone, msg, "rewards") } -func (k *Keeper) handleSendToDelegate(ctx sdk.Context, zone *types.Zone, msg *banktypes.MsgSend, memo string) (int, error) { +func (k *Keeper) handleSendToDelegate(ctx sdk.Context, zone *types.Zone, msg *banktypes.MsgSend, memo string) error { var msgs []sdk.Msg for _, coin := range msg.Amount { if coin.Denom == zone.BaseDenom { allocations, err := k.DeterminePlanForDelegation(ctx, zone, msg.Amount) if err != nil { - return 0, err + return err } - msgs = append(msgs, k.PrepareDelegationMessagesForCoins(zone, allocations, isBatchOrRewards(memo))...) + msgs = append(msgs, k.PrepareDelegationMessagesForCoins(ctx, zone, allocations, isBatchOrRewards(memo))...) } else { - msgs = append(msgs, k.PrepareDelegationMessagesForShares(zone, msg.Amount)...) + msgs = append(msgs, k.PrepareDelegationMessagesForShares(ctx, zone, msg.Amount)...) } } k.Logger(ctx).Info("messages to send", "messages", msgs) - return len(msgs), k.SubmitTx(ctx, msgs, zone.DelegationAddress, memo, zone.MessagesPerTx) + return k.SubmitTx(ctx, msgs, zone.DelegationAddress, memo, zone.MessagesPerTx) } func isBatchOrRewards(memo string) bool { @@ -766,10 +765,8 @@ func (k *Keeper) HandleUndelegate(ctx sdk.Context, msg sdk.Msg, completion time. return fmt.Errorf("zone for delegate account %s not found", undelegateMsg.DelegatorAddress) } - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "unbonding message ack"); err != nil { - // given that there _could_ be a backlog of message, we don't want to bail here, else they will remain undeliverable. - k.Logger(ctx).Error(err.Error()) - } + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("unbond/%s/%s", undelegateMsg.ValidatorAddress, sha256.Sum256(undelegateMsg.GetSignBytes()))) + ubr, found := k.GetUnbondingRecord(ctx, zone.ChainId, undelegateMsg.ValidatorAddress, epochNumber) if !found { return fmt.Errorf("unbonding record for %s not found for epoch %d", undelegateMsg.ValidatorAddress, epochNumber) @@ -816,10 +813,17 @@ func (k *Keeper) HandleUndelegate(ctx sdk.Context, msg sdk.Msg, completion time. 0, ) - if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, "unbonding message ack emit delegation_epoch query"); err != nil { - return err - } - k.SetZone(ctx, zone) + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("query_delegation/%s", undelegateMsg.ValidatorAddress), + "", + emtypes.EventTypeICQQueryDelegation, + emtypes.EventStatusActive, + nil, + nil, + ) return nil } @@ -901,6 +905,9 @@ func (k *Keeper) HandleFailedUndelegate(ctx sdk.Context, msg sdk.Msg, memo strin if !found { return fmt.Errorf("zone for delegate account %s not found", undelegateMsg.DelegatorAddress) } + + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("unbond/%s/%s", undelegateMsg.ValidatorAddress, sha256.Sum256(undelegateMsg.GetSignBytes()))) + ubr, found := k.GetUnbondingRecord(ctx, zone.ChainId, undelegateMsg.ValidatorAddress, epochNumber) if !found { return fmt.Errorf("cannot find unbonding record for %s/%s/%d", zone.ChainId, undelegateMsg.ValidatorAddress, epochNumber) @@ -992,6 +999,9 @@ func (k *Keeper) HandleRedeemTokens(ctx sdk.Context, msg sdk.Msg, amount sdk.Coi return fmt.Errorf("zone for delegate account %s not found", redeemMsg.DelegatorAddress) } + valoper := strings.Split(redeemMsg.Amount.Denom, "/")[0] + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s/%x", valoper, sha256.Sum256(redeemMsg.GetSignBytes()))) + switch { case strings.HasPrefix(memo, "batch"): k.Logger(ctx).Debug("batch delegation", "memo", memo, "tx", redeemMsg) @@ -1008,12 +1018,6 @@ func (k *Keeper) HandleRedeemTokens(ctx sdk.Context, msg sdk.Msg, amount sdk.Coi } zone.DelegationAddress.Balance = balance k.SetZone(ctx, zone) - if zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("Triggering redemption rate calc after delegation flush") - if err = k.TriggerRedemptionRate(ctx, zone); err != nil { - return err - } - } default: receipt, found := k.GetReceipt(ctx, zone.ChainId, memo) @@ -1044,26 +1048,9 @@ func (k *Keeper) HandleFailedRedeemTokens(ctx sdk.Context, msg sdk.Msg, memo str return fmt.Errorf("unable to find zone for address %s", redeemMsg.DelegatorAddress) } - switch { - case strings.HasPrefix(memo, "batch"): - k.Logger(ctx).Error("batch token redemption failed", "memo", memo, "tx", redeemMsg) - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), uint32(1), "batch token redemption failure ack"); err != nil { - k.Logger(ctx).Error(err.Error()) - return nil - // return nil here so we don't reject the incoming tx, but log the error and don't trigger RR update for repeated zero. - } - k.Logger(ctx).Info("Decremented waitgroup after failed batch token redemption", "wg", zone.GetWithdrawalWaitgroup()) - k.SetZone(ctx, zone) - if zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("Triggering redemption rate calc after delegation flush") - if err := k.TriggerRedemptionRate(ctx, zone); err != nil { - return err - } - } + valoper := strings.Split(redeemMsg.Amount.Denom, "/")[0] + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s/%x", valoper, sha256.Sum256(redeemMsg.GetSignBytes()))) - default: - // no-op - } return nil } @@ -1083,6 +1070,8 @@ func (k *Keeper) HandleDelegate(ctx sdk.Context, msg sdk.Msg, memo string) error } return fmt.Errorf("unable to find zone for address %s", delegateMsg.DelegatorAddress) } + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s/%x", delegateMsg.ValidatorAddress, sha256.Sum256(delegateMsg.GetSignBytes()))) + switch { case memo == "rewards": case strings.HasPrefix(memo, "batch"): @@ -1099,18 +1088,7 @@ func (k *Keeper) HandleDelegate(ctx sdk.Context, msg sdk.Msg, memo string) error return nil } zone.DelegationAddress.Balance = balance - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), uint32(1), "batch/reward delegation success ack"); err != nil { - k.Logger(ctx).Error(err.Error()) - return nil - // return nil here so we don't reject the incoming tx, but log the error and don't trigger RR update for repeated zero. - } k.SetZone(ctx, zone) - if zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("Triggering redemption rate calc after delegation flush") - if err := k.TriggerRedemptionRate(ctx, zone); err != nil { - return err - } - } default: receipt, found := k.GetReceipt(ctx, zone.ChainId, memo) if !found { @@ -1142,25 +1120,8 @@ func (k *Keeper) HandleFailedDelegate(ctx sdk.Context, msg sdk.Msg, memo string) return fmt.Errorf("unable to find zone for address %s", delegateMsg.DelegatorAddress) } - switch { - case strings.HasPrefix(memo, "batch"): - k.Logger(ctx).Error("batch delegation failed", "memo", memo, "tx", delegateMsg) - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "batch delegation failed ack"); err != nil { - k.Logger(ctx).Error(err.Error()) - return nil - // return nil here so we don't reject the incoming tx, but log the error and don't trigger RR update for repeated zero. - } - k.SetZone(ctx, zone) - if zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("Triggering redemption rate calc after delegation flush") - if err := k.TriggerRedemptionRate(ctx, zone); err != nil { - return err - } - } + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s/%x", delegateMsg.ValidatorAddress, sha256.Sum256(delegateMsg.GetSignBytes()))) - default: - // no-op - } return nil } @@ -1236,14 +1197,7 @@ func (k *Keeper) UpdateDelegationRecordsForAddress(ctx sdk.Context, zone types.Z delMap[del.ValidatorAddress] = del } - cb := "delegation" - if isEpoch { - if err := zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "delegations_epoch callback succeeded"); err != nil { - k.Logger(ctx).Error(err.Error()) - // don't return here, catch and squash err. - } - cb = "delegation_epoch" - } + k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, "query_delegations_epoch") for _, delegationRecord := range response.DelegationResponses { @@ -1265,15 +1219,21 @@ func (k *Keeper) UpdateDelegationRecordsForAddress(ctx sdk.Context, zone types.Z data, sdk.NewInt(-1), types.ModuleName, - cb, + "delegation", 0, ) - if isEpoch { - err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, fmt.Sprintf("delegation callback emit %s query", cb)) - if err != nil { - return err - } - } + + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("delegation_query/%s", delegationRecord.Delegation.ValidatorAddress), + "", + emtypes.EventTypeICQQueryDelegation, + emtypes.EventStatusActive, + nil, // TODO: maybe delegation/valoper? + nil, + ) } if ok { @@ -1298,19 +1258,21 @@ func (k *Keeper) UpdateDelegationRecordsForAddress(ctx sdk.Context, zone types.Z data, sdk.NewInt(-1), types.ModuleName, - cb, + "delegation", 0, ) - if isEpoch { - err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), 1, fmt.Sprintf("delegations callback emit %s query", cb)) - if err != nil { - return err - } - } - } - if isEpoch { - k.SetZone(ctx, &zone) + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + zone.ChainId, + fmt.Sprintf("delegation_query/%s", existingValAddr), + "", + emtypes.EventTypeICQQueryDelegation, + emtypes.EventStatusActive, + nil, // TODO: maybe delegation/valoper? + nil, + ) } return nil @@ -1348,24 +1310,8 @@ func (k *Keeper) UpdateDelegationRecordForAddress( return err } - if isEpoch { - err = zone.DecrementWithdrawalWaitgroup(k.Logger(ctx), 1, "delegation_epoch success") - if err != nil { - k.Logger(ctx).Error(err.Error()) - // return nil here as to not fail the ack, but don't trigger RR multiple times. - return nil - } - - k.SetZone(ctx, zone) + k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, fmt.Sprintf("delegation_query/%s", validatorAddress)) - if zone.GetWithdrawalWaitgroup() == 0 { - k.Logger(ctx).Info("Triggering redemption rate upgrade after delegation updates") - err = k.TriggerRedemptionRate(ctx, zone) - if err != nil { - return err - } - } - } return nil } diff --git a/x/interchainstaking/keeper/ibc_packet_handlers_test.go b/x/interchainstaking/keeper/ibc_packet_handlers_test.go index 18482e60b..28a15bed9 100644 --- a/x/interchainstaking/keeper/ibc_packet_handlers_test.go +++ b/x/interchainstaking/keeper/ibc_packet_handlers_test.go @@ -893,7 +893,6 @@ func (suite *KeeperTestSuite) TestHandleWithdrawRewards() { { name: "try to decrement when waitgroup = 0", setup: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) { - zone.SetWithdrawalWaitgroup(quicksilver.Logger(), 0, "init") quicksilver.InterchainstakingKeeper.SetZone(ctx, zone) }, checks: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) {}, @@ -909,8 +908,6 @@ func (suite *KeeperTestSuite) TestHandleWithdrawRewards() { { name: "valid case with balances != 0", setup: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) { - zone.SetWithdrawalWaitgroup(quicksilver.Logger(), 1, "init") - balances := sdk.NewCoins( sdk.NewCoin( zone.BaseDenom, @@ -933,7 +930,6 @@ func (suite *KeeperTestSuite) TestHandleWithdrawRewards() { { name: "valid case trigger redemption rate and check if delegatorAddress == performanceAddress", setup: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) { - zone.SetWithdrawalWaitgroup(quicksilver.Logger(), 1, "init") quicksilver.InterchainstakingKeeper.SetZone(ctx, zone) }, checks: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) { @@ -953,8 +949,6 @@ func (suite *KeeperTestSuite) TestHandleWithdrawRewards() { { name: "valid case trigger redemption rate and without checking if delegatorAddress == performanceAddress", setup: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) { - zone.SetWithdrawalWaitgroup(quicksilver.Logger(), 0, "init") - quicksilver.InterchainstakingKeeper.SetZone(ctx, zone) }, checks: func(ctx sdk.Context, quicksilver *app.Quicksilver, zone *types.Zone) {}, msg: func(zone *types.Zone) sdk.Msg { @@ -3001,7 +2995,6 @@ func (suite *KeeperTestSuite) TestReceiveAckForWithdrawReward() { if !found { suite.Fail("unable to retrieve zone for test") } - zone.SetWithdrawalWaitgroup(quicksilver.Logger(), 1, "init") quicksilver.InterchainstakingKeeper.SetZone(ctx, &zone) withdrawReward := &distrtypes.MsgWithdrawDelegatorReward{ @@ -4830,9 +4823,6 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_Batch_OK() { zone, found := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) suite.True(found) - zone.SetWithdrawalWaitgroup(app.Logger(), 100, "init") - app.InterchainstakingKeeper.SetZone(ctx, &zone) - vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} var msgMsg sdk.Msg = &msg @@ -4854,9 +4844,6 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_PerfAddress_OK() { zone, found := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) suite.True(found) - zone.SetWithdrawalWaitgroup(app.Logger(), 100, "init") - app.InterchainstakingKeeper.SetZone(ctx, &zone) - vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: zone.PerformanceAddress.Address, ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} var msgMsg sdk.Msg = &msg @@ -4879,9 +4866,6 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_NotBatch_OK() { zone, found := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) suite.True(found) - zone.SetWithdrawalWaitgroup(app.Logger(), 100, "init") - app.InterchainstakingKeeper.SetZone(ctx, &zone) - vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} var msgMsg sdk.Msg = &msg @@ -4904,8 +4888,6 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_BatchTriggerRR_OK() { zone, found := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) suite.True(found) - zone.SetWithdrawalWaitgroup(app.Logger(), 1, "init") - app.InterchainstakingKeeper.SetZone(ctx, &zone) preQueries := app.InterchainQueryKeeper.AllQueries(ctx) vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) @@ -4948,12 +4930,6 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_BadAddr_Fail() { app := suite.GetQuicksilverApp(suite.chainA) ctx := suite.chainA.GetContext() - zone, found := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.True(found) - - zone.SetWithdrawalWaitgroup(app.Logger(), 100, "init") - app.InterchainstakingKeeper.SetZone(ctx, &zone) - vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: addressutils.GenerateAddressForTestWithPrefix("cosmos"), ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} var msgMsg sdk.Msg = &msg @@ -4971,9 +4947,6 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_BadMsg_Fail() { zone, found := app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) suite.True(found) - zone.SetWithdrawalWaitgroup(app.Logger(), 100, "init") - app.InterchainstakingKeeper.SetZone(ctx, &zone) - vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgBeginRedelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorSrcAddress: vals[0], ValidatorDstAddress: vals[1], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} var msgMsg sdk.Msg = &msg diff --git a/x/interchainstaking/keeper/redemptions.go b/x/interchainstaking/keeper/redemptions.go index f1766dfbc..986367cdd 100644 --- a/x/interchainstaking/keeper/redemptions.go +++ b/x/interchainstaking/keeper/redemptions.go @@ -1,6 +1,7 @@ package keeper import ( + "crypto/sha256" "errors" "fmt" "sort" @@ -237,13 +238,14 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch var msgs []sdk.Msg for _, valoper := range utils.Keys(coinsOutPerValidator) { if !coinsOutPerValidator[valoper].Amount.IsZero() { - msgs = append(msgs, &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: coinsOutPerValidator[valoper]}) + msg := &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: coinsOutPerValidator[valoper]} + msgs = append(msgs, msg) k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, zone.ChainId, - fmt.Sprintf("%s/%s", types.EpochWithdrawalMemo(epoch), valoper), - "unbondAck", + fmt.Sprintf("unbond/%s/%s", valoper, sha256.Sum256(msg.GetSignBytes())), + "", emtypes.EventTypeICAUnbond, emtypes.EventStatusActive, nil, @@ -266,11 +268,6 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch } } - // if err = zone.IncrementWithdrawalWaitgroup(k.Logger(ctx), uint32(len(msgs)), "trigger unbonding messages"); err != nil { - // return err - // } - //k.SetZone(ctx, zone) - return nil } diff --git a/x/interchainstaking/types/zones.go b/x/interchainstaking/types/zones.go index 162d52388..f3a4c1b16 100644 --- a/x/interchainstaking/types/zones.go +++ b/x/interchainstaking/types/zones.go @@ -6,8 +6,6 @@ import ( "fmt" "strings" - "github.com/tendermint/tendermint/libs/log" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/quicksilver-zone/quicksilver/utils/addressutils" @@ -43,31 +41,6 @@ func (z *Zone) GetDelegationAccount() (*ICAAccount, error) { return z.DelegationAddress, nil } -func (z *Zone) SetWithdrawalWaitgroup(logger log.Logger, num uint32, reason string) { - logger.Info("setting withdrawal waitgroup", "zone", z.ChainId, "existing", z.WithdrawalWaitgroup, "new", num, "reason", reason) - z.WithdrawalWaitgroup = num -} - -func (z *Zone) DecrementWithdrawalWaitgroup(logger log.Logger, num uint32, reason string) error { - if z.WithdrawalWaitgroup-num > z.WithdrawalWaitgroup { // underflow - logger.Error("error decrementing withdrawal waitgroup: uint32 underflow ", "zone", z.ChainId, "existing", z.WithdrawalWaitgroup, "decrement", num, "reason", reason) - return errors.New("unable to decrement the withdrawal waitgroup below 0") - } - logger.Info("decrementing withdrawal waitgroup", "zone", z.ChainId, "existing", z.WithdrawalWaitgroup, "decrement", num, "new", z.WithdrawalWaitgroup-num, "reason", reason) - z.WithdrawalWaitgroup -= num - return nil -} - -func (z *Zone) IncrementWithdrawalWaitgroup(logger log.Logger, num uint32, reason string) error { - if z.WithdrawalWaitgroup+num < z.WithdrawalWaitgroup { // overflow - logger.Error("error incrementing withdrawal waitgroup: uint32 overflow ", "zone", z.ChainId, "existing", z.WithdrawalWaitgroup, "increment", num, "reason", reason) - return errors.New("unable to increment the withdrawal waitgroup above 4294967295") - } - logger.Info("incrementing withdrawal waitgroup", "zone", z.ChainId, "existing", z.WithdrawalWaitgroup, "increment", num, "new", z.WithdrawalWaitgroup+num, "reason", reason) - z.WithdrawalWaitgroup += num - return nil -} - // ValidateCoinsForZone checks whether an inbound denomination is valid for this zone. // valid coins comprise: // - non-lsm: staking denom only (z.BaseDenom) diff --git a/x/interchainstaking/types/zones_test.go b/x/interchainstaking/types/zones_test.go index 85e0690e1..b69a6cee9 100644 --- a/x/interchainstaking/types/zones_test.go +++ b/x/interchainstaking/types/zones_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -39,19 +38,6 @@ func TestGetDelegationAccount(t *testing.T) { require.Nil(t, acc2) } -func TestDecrementWithdrawalWg(t *testing.T) { - testlog := log.NewNopLogger() - zone := types.Zone{WithdrawalWaitgroup: 0} - oldWg := zone.GetWithdrawalWaitgroup() - require.NoError(t, zone.IncrementWithdrawalWaitgroup(testlog, 1, "test increment")) - firstWg := zone.GetWithdrawalWaitgroup() - require.Equal(t, oldWg+1, firstWg) - require.NoError(t, zone.DecrementWithdrawalWaitgroup(testlog, 1, "test decrement")) - secondWg := zone.GetWithdrawalWaitgroup() - require.Equal(t, firstWg-1, secondWg) - require.Error(t, zone.DecrementWithdrawalWaitgroup(testlog, 1, "test decrement error")) -} - func TestValidateCoinsForZone(t *testing.T) { zone := types.Zone{ConnectionId: "connection-0", ChainId: "cosmoshub-4", AccountPrefix: "cosmos", LocalDenom: "uqatom", BaseDenom: "uatom", Is_118: true} valAddresses := map[string]bool{ From 3cc8271ad619c2fe44c28e5a5cf7f8143d9f763a Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 17 Apr 2024 19:42:24 +0100 Subject: [PATCH 07/14] working ics em integration --- x/interchainstaking/keeper/keeper.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/interchainstaking/keeper/keeper.go b/x/interchainstaking/keeper/keeper.go index 172856633..f2d9f2ad8 100644 --- a/x/interchainstaking/keeper/keeper.go +++ b/x/interchainstaking/keeper/keeper.go @@ -701,6 +701,7 @@ func (k *Keeper) UpdateRedemptionRate(ctx sdk.Context, zone *types.Zone, epochRe zone.LastRedemptionRate = zone.RedemptionRate zone.RedemptionRate = ratio k.SetZone(ctx, zone) + k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, zone.ChainId, "trigger_rr") } func (k *Keeper) OverrideRedemptionRateNoCap(ctx sdk.Context, zone *types.Zone) { From 49848a810d0606b33a1b2fc75ecf09e04115fa5f Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Tue, 23 Apr 2024 13:23:51 +0100 Subject: [PATCH 08/14] wip pr --- app/keepers/keepers.go | 4 + docker-compose.yml | 26 +-- scripts/simple-test.sh | 6 - x/eventmanager/keeper/events.go | 17 +- x/eventmanager/keeper/events_test.go | 27 +-- x/eventmanager/keeper/keeper.go | 2 - x/eventmanager/keeper/keeper_test.go | 2 +- x/eventmanager/types/codec.go | 2 +- x/eventmanager/types/conditions.go | 3 +- x/eventmanager/types/fields.go | 3 +- x/eventmanager/types/keys.go | 10 +- x/interchainstaking/keeper/events.go | 1 - x/interchainstaking/keeper/validators.go | 10 + x/participationrewards/keeper/allocations.go | 76 +++++++ x/participationrewards/keeper/callbacks.go | 2 + x/participationrewards/keeper/distribution.go | 26 +-- x/participationrewards/keeper/events.go | 93 +++++++++ x/participationrewards/keeper/hooks.go | 76 ++++--- x/participationrewards/keeper/keeper.go | 7 +- .../keeper/rewards_validatorSelection.go | 99 ++++----- .../keeper/rewards_validatorSelection_test.go | 116 ++++------- .../keeper/submodule_liquid.go | 3 +- .../keeper/submodule_osmosis.go | 14 ++ x/participationrewards/types/allocations.go | 43 ---- .../types/allocations_test.go | 190 ------------------ .../types/expected_keepers.go | 8 + x/participationrewards/types/keys.go | 7 +- .../types/participationrewards.go | 17 +- 28 files changed, 425 insertions(+), 465 deletions(-) create mode 100644 x/participationrewards/keeper/allocations.go create mode 100644 x/participationrewards/keeper/events.go delete mode 100644 x/participationrewards/types/allocations.go delete mode 100644 x/participationrewards/types/allocations_test.go diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 3d64a7b6f..b87f61728 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -411,6 +411,7 @@ func (appKeepers *AppKeepers) InitKeepers( &appKeepers.InterchainQueryKeeper, appKeepers.InterchainstakingKeeper, appKeepers.ClaimsManagerKeeper, + appKeepers.EventManagerKeeper, authtypes.FeeCollectorName, proofOpsFn, selfProofOpsFn, @@ -428,6 +429,9 @@ func (appKeepers *AppKeepers) InitKeepers( panic(err) } + if err := appKeepers.EventManagerKeeper.SetCallbackHandler(participationrewardstypes.ModuleName, appKeepers.ParticipationRewardsKeeper.EventCallbackHandler()); err != nil { + panic(err) + } // Quicksilver Keepers appKeepers.EpochsKeeper = epochskeeper.NewKeeper(appCodec, appKeepers.keys[epochstypes.StoreKey]) appKeepers.ParticipationRewardsKeeper.SetEpochsKeeper(appKeepers.EpochsKeeper) diff --git a/docker-compose.yml b/docker-compose.yml index 1d0175d4f..c805454f6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -98,7 +98,7 @@ services: - osmosisd - start hermes: - image: informalsystems/hermes:v1.8.0 + image: informalsystems/hermes:v1.8.2 hostname: hermes volumes: - ./data/hermes:/home/hermes/.hermes @@ -121,19 +121,19 @@ services: - icq-relayer - run restart: always - relayer: - image: quicksilverzone/relayer:v2.3.0 - build: - context: . - dockerfile: Dockerfile.relayer - volumes: - - ./data/rly:/rly/.relayer - command: - - rly - - start - - demo + #relayer: + # image: quicksilverzone/relayer:v2.3.0 + # build: + # context: . + # dockerfile: Dockerfile.relayer + # volumes: + # - ./data/rly:/rly/.relayer + # command: + # - rly + # - start + # - demo #- -p #- events #- -b #- "100" - restart: always + # restart: always diff --git a/scripts/simple-test.sh b/scripts/simple-test.sh index 8144bf1f5..40313b2d2 100755 --- a/scripts/simple-test.sh +++ b/scripts/simple-test.sh @@ -61,12 +61,6 @@ $HERMES_RUN create channel --a-chain $CHAINID_0 --b-chain $CHAINID_1 --a-port tr #$HERMES_RUN create channel --port-a transfer --port-b transfer $CHAINID_0 connection-0 echo "Tranfer channel created" docker-compose up --force-recreate -d hermes -RLY_ADDRESS_3=$($RLY_RUN keys show qstest-1 testkey) -RLY_ADDRESS_4=$($RLY_RUN keys show lstest-1 testkey) -$QS1_EXEC tx bank send val1 $RLY_ADDRESS_3 1000uqck --chain-id $CHAINID_0 -y --keyring-backend=test -$TZ1_1_EXEC tx bank send val2 $RLY_ADDRESS_4 1000uatom --chain-id $CHAINID_1 -y --keyring-backend=test - -docker-compose up --force-recreate -d relayer rm -rf ./icq/keys echo "Launch and configure interchain query daemon" diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go index 14785fd75..958ed39ca 100644 --- a/x/eventmanager/keeper/events.go +++ b/x/eventmanager/keeper/events.go @@ -12,15 +12,15 @@ import ( // ---------------------------------------------------------------- -func GenerateEventKey(module, chainId, id string) []byte { - return []byte(module + chainId + id) +func GenerateEventKey(module, chainID, id string) []byte { + return []byte(module + chainID + id) } // GetEvent returns event. -func (k Keeper) GetEvent(ctx sdk.Context, module, chainId, id string) (types.Event, bool) { +func (k Keeper) GetEvent(ctx sdk.Context, module, chainID, id string) (types.Event, bool) { event := types.Event{} store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) - bz := store.Get(GenerateEventKey(module, chainId, id)) + bz := store.Get(GenerateEventKey(module, chainID, id)) if len(bz) == 0 { return event, false } @@ -37,9 +37,9 @@ func (k Keeper) SetEvent(ctx sdk.Context, event types.Event) { } // DeleteEvent delete event. -func (k Keeper) DeleteEvent(ctx sdk.Context, module, chainId, id string) { +func (k Keeper) DeleteEvent(ctx sdk.Context, module, chainID, id string) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvent) - store.Delete(GenerateEventKey(module, chainId, id)) + store.Delete(GenerateEventKey(module, chainID, id)) } // IterateEvents iterate through queries. @@ -65,8 +65,8 @@ func (k Keeper) IterateModuleEvents(ctx sdk.Context, module string, fn func(inde k.IteratePrefixedEvents(ctx, []byte(module), fn) } -func (k Keeper) IterateModuleChainEvents(ctx sdk.Context, module string, chainId string, fn func(index int64, event types.Event) (stop bool)) { - k.IteratePrefixedEvents(ctx, []byte(module+chainId), fn) +func (k Keeper) IterateModuleChainEvents(ctx sdk.Context, module string, chainID string, fn func(index int64, event types.Event) (stop bool)) { + k.IteratePrefixedEvents(ctx, []byte(module+chainID), fn) } // AllEvents returns every eventInfo in the store. @@ -112,7 +112,6 @@ func (k Keeper) AddEvent(ctx sdk.Context, condition types.ConditionI, payload []byte, ) { - var err error var conditionAny *codectypes.Any if condition != nil { diff --git a/x/eventmanager/keeper/events_test.go b/x/eventmanager/keeper/events_test.go index 4d53e2f52..1151a4d01 100644 --- a/x/eventmanager/keeper/events_test.go +++ b/x/eventmanager/keeper/events_test.go @@ -9,7 +9,7 @@ import ( "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" ) -var GLOBAL_VAR = 0 +var GlobalVar = 0 // ___________________________________________________________________________________________________ @@ -54,12 +54,12 @@ func (c EventCallbacks) RegisterCallbacks() types.EventCallbacks { // ----------------------------------- func testCallback(k *keeper.Keeper, ctx sdk.Context, args []byte) error { - GLOBAL_VAR = 12345 + GlobalVar = 12345 return nil } func testCallbackWithArgs(k *keeper.Keeper, ctx sdk.Context, args []byte) error { - GLOBAL_VAR = int(args[0]) + GlobalVar = int(args[0]) return nil } @@ -71,7 +71,7 @@ func (suite *KeeperTestSuite) TestEventLifecycle() { callbackHandler := EventCallbacks{&app.EventManagerKeeper, make(map[string]EventCallback, 0)} - app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) + suite.NoError(app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler)) app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test", "testCallback", types.EventTypeICADelegate, types.EventStatusPending, nil, nil) @@ -79,14 +79,14 @@ func (suite *KeeperTestSuite) TestEventLifecycle() { suite.Equal(1, len(events)) - GLOBAL_VAR = 0 + GlobalVar = 0 app.EventManagerKeeper.Trigger(ctx, types.ModuleName, suite.chainB.ChainID) event, found := app.EventManagerKeeper.GetEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") suite.True(found) - suite.Equal(12345, GLOBAL_VAR) + suite.Equal(12345, GlobalVar) suite.Equal(event.EventStatus, types.EventStatusActive) @@ -103,7 +103,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { callbackHandler := EventCallbacks{&app.EventManagerKeeper, make(map[string]EventCallback, 0)} - app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) + suite.NoError(app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler)) condition, err := types.NewConditionAll(ctx, []*types.FieldValue{ {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, @@ -119,7 +119,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { suite.Equal(2, len(events)) - GLOBAL_VAR = 0 + GlobalVar = 0 // martCompleted doesn't require an explicit callback app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test1") @@ -131,7 +131,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { suite.Equal(1, len(events)) suite.True(found) - suite.Equal(12345, GLOBAL_VAR) + suite.Equal(12345, GlobalVar) suite.Equal(event.EventStatus, types.EventStatusActive) @@ -148,7 +148,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { callbackHandler := EventCallbacks{&app.EventManagerKeeper, make(map[string]EventCallback, 0)} - app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler) + suite.NoError(app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler)) condition1, err := types.NewConditionAll(ctx, []*types.FieldValue{ {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, @@ -171,9 +171,10 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { events := app.EventManagerKeeper.AllEvents(ctx) + fmt.Println(events) suite.Equal(3, len(events)) - GLOBAL_VAR = 0 + GlobalVar = 0 // markCompleted doesn't require an explicit callback app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test1") @@ -185,13 +186,13 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { suite.Equal(2, len(events)) - suite.Equal(1, GLOBAL_VAR) + suite.Equal(1, GlobalVar) suite.Equal(event.EventStatus, types.EventStatusActive) app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test") - suite.Equal(2, GLOBAL_VAR) + suite.Equal(2, GlobalVar) events = app.EventManagerKeeper.AllEvents(ctx) diff --git a/x/eventmanager/keeper/keeper.go b/x/eventmanager/keeper/keeper.go index 67c497874..7fa546bfa 100644 --- a/x/eventmanager/keeper/keeper.go +++ b/x/eventmanager/keeper/keeper.go @@ -21,7 +21,6 @@ type Keeper struct { // NewKeeper returns a new instance of zones Keeper. func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey) Keeper { - return Keeper{ cdc: cdc, storeKey: storeKey, @@ -48,7 +47,6 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { } func (k Keeper) Call(ctx sdk.Context, moduleName string, callbackID string, payload []byte) error { - module, found := k.callbacks[moduleName] if !found { return fmt.Errorf("bad module %s", moduleName) diff --git a/x/eventmanager/keeper/keeper_test.go b/x/eventmanager/keeper/keeper_test.go index 8bee4e9f2..ba7ca66ad 100644 --- a/x/eventmanager/keeper/keeper_test.go +++ b/x/eventmanager/keeper/keeper_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/suite" - ibctesting "github.com/cosmos/ibc-go/v5/testing" + ibctesting "github.com/cosmos/ibc-go/v6/testing" "github.com/quicksilver-zone/quicksilver/app" ) diff --git a/x/eventmanager/types/codec.go b/x/eventmanager/types/codec.go index 159d3bff0..1c42ecb14 100644 --- a/x/eventmanager/types/codec.go +++ b/x/eventmanager/types/codec.go @@ -17,7 +17,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterInterface("quicksilver.eventmanager.v1.ConditionI", (*ConditionI)(nil)) - registry.RegisterImplementations((*ConditionI)(nil), &ConditionAll{}, &ConditionAnd{} /*&ConditionAny{},*/, &ConditionOr{}) + registry.RegisterImplementations((*ConditionI)(nil), &ConditionAll{}, &ConditionAnd{}, &ConditionOr{}) } func init() { diff --git a/x/eventmanager/types/conditions.go b/x/eventmanager/types/conditions.go index 8d326e12b..92211ad57 100644 --- a/x/eventmanager/types/conditions.go +++ b/x/eventmanager/types/conditions.go @@ -1,10 +1,11 @@ package types import ( + "github.com/gogo/protobuf/proto" + "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/gogo/protobuf/proto" ) type EMKeeper interface { diff --git a/x/eventmanager/types/fields.go b/x/eventmanager/types/fields.go index 7a7ca3469..ceb48f22d 100644 --- a/x/eventmanager/types/fields.go +++ b/x/eventmanager/types/fields.go @@ -1,7 +1,7 @@ package types import ( - fmt "fmt" + "fmt" "strconv" "strings" ) @@ -35,7 +35,6 @@ func (e Event) ResolveAnyFieldValues(fvs []*FieldValue) (bool, error) { } func (e Event) resolveFieldValue(fv *FieldValue) (bool, error) { - switch { case fv.Field == FieldEventType: if fv.Operator != FieldOperator_EQUAL { diff --git a/x/eventmanager/types/keys.go b/x/eventmanager/types/keys.go index 9c516332c..405f428a3 100644 --- a/x/eventmanager/types/keys.go +++ b/x/eventmanager/types/keys.go @@ -28,6 +28,12 @@ const ( EventTypeICAWithdrawRewards = int32(0x06) EventTypeICADelegate = int32(0x07) EventTypeICAUnbond = int32(0x08) + EventTypeICQGetLatestBlock = int32(0x09) + EventTypeICQOsmosisPool = int32(0x0a) + EventTypeSubmodules = int32(0x0b) + EventTypeCalculateTvls = int32(0x0c) + EventTypeDistributeRewards = int32(0x0d) + FieldEventType = "eventtype" FieldModule = "module" @@ -37,6 +43,4 @@ const ( FieldCallback = "callback" ) -var ( - KeyPrefixEvent = []byte{0x01} -) +var KeyPrefixEvent = []byte{0x01} diff --git a/x/interchainstaking/keeper/events.go b/x/interchainstaking/keeper/events.go index 6655a95d3..c2b1b1bd1 100644 --- a/x/interchainstaking/keeper/events.go +++ b/x/interchainstaking/keeper/events.go @@ -66,7 +66,6 @@ type DelegatorDelegationsParams struct { } func EmitDelegatorDelegations(k *Keeper, ctx sdk.Context, args []byte) error { - var params DelegatorDelegationsParams err := json.Unmarshal(args, ¶ms) if err != nil { diff --git a/x/interchainstaking/keeper/validators.go b/x/interchainstaking/keeper/validators.go index ba3c20843..785f3fb67 100644 --- a/x/interchainstaking/keeper/validators.go +++ b/x/interchainstaking/keeper/validators.go @@ -18,6 +18,16 @@ func (k Keeper) GetValidators(ctx sdk.Context, chainID string) []types.Validator return validators } +// GetValidators returns validators by chainID. +func (k Keeper) GetValidatorsAsMap(ctx sdk.Context, chainID string) map[string]types.Validator { + validators := map[string]types.Validator{} + k.IterateValidators(ctx, chainID, func(_ int64, validator types.Validator) (stop bool) { + validators[validator.ValoperAddress] = validator + return false + }) + return validators +} + // GetValidatorAddresses returns a slice of validator addresses by chainID. func (k Keeper) GetValidatorAddresses(ctx sdk.Context, chainID string) []string { validators := []string{} diff --git a/x/participationrewards/keeper/allocations.go b/x/participationrewards/keeper/allocations.go new file mode 100644 index 000000000..7ea97392c --- /dev/null +++ b/x/participationrewards/keeper/allocations.go @@ -0,0 +1,76 @@ +package keeper + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" +) + +// GetHoldingAllocation returns sdk.Coin allocated to the given identifier. +func (k *Keeper) GetHoldingAllocation(ctx sdk.Context, chainID string) sdk.Coin { + value := sdk.Coin{} + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixHoldingAllocation) + bz := store.Get([]byte(chainID)) + if len(bz) == 0 { + return value + } + + k.cdc.MustUnmarshal(bz, &value) + return value +} + +// SetHoldingAllocation sets sdk.Coin allocated as the given identifier. +func (k Keeper) SetHoldingAllocation(ctx sdk.Context, chainID string, value sdk.Coin) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixHoldingAllocation) + bz := k.cdc.MustMarshal(&value) + store.Set([]byte(chainID), bz) +} + +// GetValidatorAllocation returns sdk.Coin allocated to the given identifier. +func (k *Keeper) GetValidatorAllocation(ctx sdk.Context, chainID string) sdk.Coin { + value := sdk.Coin{} + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixValidatorAllocation) + bz := store.Get([]byte(chainID)) + if len(bz) == 0 { + return value + } + + k.cdc.MustUnmarshal(bz, &value) + return value +} + +// SetValidatorAllocation sets sdk.Coin allocated as the given identifier. +func (k Keeper) SetValidatorAllocation(ctx sdk.Context, chainID string, value sdk.Coin) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixValidatorAllocation) + bz := k.cdc.MustMarshal(&value) + store.Set([]byte(chainID), bz) +} + +func (k Keeper) DetermineAllocations(ctx sdk.Context, moduleBalance sdk.Coin, proportions types.DistributionProportions) error { + if moduleBalance.IsNil() || moduleBalance.IsZero() { + return types.ErrNothingToAllocate + } + + if sum := proportions.Total(); !sum.Equal(sdk.OneDec()) { + return fmt.Errorf("%w: got %v", types.ErrInvalidTotalProportions, sum) + } + + // split participation rewards allocations + validatorAllocation := sdk.NewDecFromInt(moduleBalance.Amount).Mul(proportions.ValidatorSelectionAllocation).TruncateInt() + holdingAllocation := sdk.NewDecFromInt(moduleBalance.Amount).Mul(proportions.HoldingsAllocation).TruncateInt() + + // use sum to check total distribution to collect and allocate dust + sum := validatorAllocation.Add(holdingAllocation) + dust := moduleBalance.Amount.Sub(sum) + + // Add dust to validator choice allocation (favors decentralization) + validatorAllocation = validatorAllocation.Add(dust) + + k.SetHoldingAllocation(ctx, types.ModuleName, sdk.NewCoin(moduleBalance.Denom, holdingAllocation)) + k.SetValidatorAllocation(ctx, types.ModuleName, sdk.NewCoin(moduleBalance.Denom, validatorAllocation)) + + return nil +} diff --git a/x/participationrewards/keeper/callbacks.go b/x/participationrewards/keeper/callbacks.go index 0dfec4458..fb0d26650 100644 --- a/x/participationrewards/keeper/callbacks.go +++ b/x/participationrewards/keeper/callbacks.go @@ -139,6 +139,8 @@ func OsmosisPoolUpdateCallback(ctx sdk.Context, k *Keeper, response []byte, quer } poolID := sdk.BigEndianToUint64(query.Request[1:]) + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", fmt.Sprintf("submodule/osmosispool/%d", poolID)) + data, ok := k.GetProtocolData(ctx, types.ProtocolDataTypeOsmosisPool, fmt.Sprintf("%d", poolID)) if !ok { return fmt.Errorf("unable to find protocol data for osmosispools/%d", poolID) diff --git a/x/participationrewards/keeper/distribution.go b/x/participationrewards/keeper/distribution.go index dbacf0fd1..f72c09054 100644 --- a/x/participationrewards/keeper/distribution.go +++ b/x/participationrewards/keeper/distribution.go @@ -181,22 +181,18 @@ func (k *Keeper) CalcTokenValues(ctx sdk.Context) (TokenValues, error) { // AllocateZoneRewards executes zone based rewards allocation. This entails // rewards that are proportionally distributed to zones based on the tvl for // each zone relative to the tvl of the QS protocol. -func (k *Keeper) AllocateZoneRewards(ctx sdk.Context, tvs TokenValues, allocation types.RewardsAllocation) error { - k.Logger(ctx).Info("allocateZoneRewards", "token values", tvs, "allocation", allocation) +func (k *Keeper) AllocateZoneRewards(ctx sdk.Context, tvs TokenValues) error { + // <<--- move to callback - if err := k.SetZoneAllocations(ctx, tvs, allocation); err != nil { - return err - } - - k.AllocateValidatorSelectionRewards(ctx) - - return k.AllocateHoldingsRewards(ctx) + return k.AllocateHoldingsRewards(ctx) // << -- move to callback } // SetZoneAllocations returns the proportional zone rewards allocations as a // map indexed by the zone id. -func (k *Keeper) SetZoneAllocations(ctx sdk.Context, tvs TokenValues, allocation types.RewardsAllocation) error { - k.Logger(ctx).Info("setZoneAllocations", "allocation", allocation) +func (k *Keeper) SetZoneAllocations(ctx sdk.Context, tvs TokenValues) error { + holdingAllocation := k.GetHoldingAllocation(ctx, types.ModuleName) + validatorAllocation := k.GetValidatorAllocation(ctx, types.ModuleName) + k.Logger(ctx).Info("setZoneAllocations", "holdingAllocation", holdingAllocation, "validatorAllocation", validatorAllocation) otvl := sdk.ZeroDec() // pass 1: iterate zones - set tvl & calc overall tvl @@ -225,15 +221,13 @@ func (k *Keeper) SetZoneAllocations(ctx sdk.Context, tvs TokenValues, allocation // pass 2: iterate zones - calc zone tvl proportion & set allocations k.icsKeeper.IterateZones(ctx, func(index int64, zone *icstypes.Zone) (stop bool) { if zone.Tvl.IsNil() { - zone.Tvl = sdk.ZeroDec() + return false } zp := zone.Tvl.Quo(otvl) k.Logger(ctx).Info("zone proportion", "zone", zone.ChainId, "proportion", zp) - - zone.ValidatorSelectionAllocation = sdk.NewDecFromInt(allocation.ValidatorSelection).Mul(zp).TruncateInt().Uint64() - zone.HoldingsAllocation = sdk.NewDecFromInt(allocation.Holdings).Mul(zp).TruncateInt().Uint64() - k.icsKeeper.SetZone(ctx, zone) + k.SetValidatorAllocation(ctx, zone.ChainId, sdk.NewCoin(validatorAllocation.Denom, sdk.NewDecFromInt(validatorAllocation.Amount).Mul(zp).TruncateInt())) + k.SetHoldingAllocation(ctx, zone.ChainId, sdk.NewCoin(holdingAllocation.Denom, sdk.NewDecFromInt(holdingAllocation.Amount).Mul(zp).TruncateInt())) return false }) diff --git a/x/participationrewards/keeper/events.go b/x/participationrewards/keeper/events.go new file mode 100644 index 000000000..70d0d2cb9 --- /dev/null +++ b/x/participationrewards/keeper/events.go @@ -0,0 +1,93 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" + "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" +) + +// ___________________________________________________________________________________________________ + +type EventCallback func(*Keeper, sdk.Context, []byte) error + +// Callbacks wrapper struct for interchainstaking keeper. +type EventCallbacks struct { + k *Keeper + callbacks map[string]EventCallback +} + +var _ emtypes.EventCallbacks = EventCallbacks{} + +func (k *Keeper) EventCallbackHandler() EventCallbacks { + return EventCallbacks{k, make(map[string]EventCallback)} +} + +// Call calls callback handler. +func (c EventCallbacks) Call(ctx sdk.Context, id string, args []byte) error { + if !c.Has(id) { + return fmt.Errorf("callback %s not found", id) + } + return c.callbacks[id](c.k, ctx, args) +} + +func (c EventCallbacks) Has(id string) bool { + _, found := c.callbacks[id] + return found +} + +func (c EventCallbacks) AddCallback(id string, fn interface{}) emtypes.EventCallbacks { + c.callbacks[id], _ = fn.(EventCallback) + return c +} + +func (c EventCallbacks) RegisterCallbacks() emtypes.EventCallbacks { + return c. + AddCallback(CalculateValues, EventCallback(CalculateTokenValues)). + AddCallback(Submodules, EventCallback(SubmoduleHooks)). + AddCallback(DistributeRewards, EventCallback(DistributeParticipationRewards)) +} + +const ( + CalculateValues = "CalculateValues" + Submodules = "Submodules" + DistributeRewards = "DistributeRewards" +) + +// ----------------------------------- +// Callback Handlers +// ----------------------------------- + +func CalculateTokenValues(k *Keeper, ctx sdk.Context, args []byte) error { + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", "calc_tokens") + + tvs, err := k.CalcTokenValues(ctx) + if err != nil { + return err + } + + err = k.SetZoneAllocations(ctx, tvs) + if err != nil { + return err + } + + k.QueryValidatorDelegationPerformance(ctx) + + return nil +} + +func SubmoduleHooks(k *Keeper, ctx sdk.Context, args []byte) error { + for _, sub := range k.PrSubmodules { + sub.Hooks(ctx, k) + + } + return nil +} + +func DistributeParticipationRewards(k *Keeper, ctx sdk.Context, args []byte) error { + // calculate, based on latest token values + // allocation based on calculations + return nil +} diff --git a/x/participationrewards/keeper/hooks.go b/x/participationrewards/keeper/hooks.go index 6fae26d7e..96b94bf06 100644 --- a/x/participationrewards/keeper/hooks.go +++ b/x/participationrewards/keeper/hooks.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" icstypes "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" ) @@ -44,29 +45,45 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ int64) SetEpochBlockCallbackID, 0, ) + + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, connectionData.ChainID, "get_epoch_height", "", emtypes.EventTypeICQGetLatestBlock, emtypes.EventStatusActive, nil, nil) return false }) + condition, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "get_epoch_height", emtypes.FieldOperator_EQUAL, true)), false) + if err != nil { + panic(err) + } + + // add event to ensure submodule hooks are called when the get_epoch_height calls have returned. + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "submodules", Submodules, emtypes.EventTypeSubmodules, emtypes.EventStatusPending, condition, nil) + k.Logger(ctx).Info("setting self connection data...") - err := k.UpdateSelfConnectionData(ctx) + err = k.UpdateSelfConnectionData(ctx) if err != nil { panic(err) } - k.Logger(ctx).Info("distribute participation rewards...") + condition2, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "submodule", emtypes.FieldOperator_BEGINSWITH, true)), false) + if err != nil { + panic(err) + } - allocation, err := types.GetRewardsAllocations( - k.GetModuleBalance(ctx), - k.GetParams(ctx).DistributionProportions, - ) + conditionAnd, err := emtypes.NewConditionAnd(ctx, condition, condition2) if err != nil { - k.Logger(ctx).Error(err.Error()) + panic(err) } + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "calc_tokens", CalculateValues, emtypes.EventTypeCalculateTvls, emtypes.EventStatusPending, conditionAnd, nil) - k.Logger(ctx).Info("Triggering submodule hooks") - for _, sub := range k.PrSubmodules { - sub.Hooks(ctx, k) + condition3, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "calc_tokens", emtypes.FieldOperator_EQUAL, true)), false) + if err != nil { + panic(err) + } + conditionAnd2, err := emtypes.NewConditionAnd(ctx, conditionAnd, condition3) + if err != nil { + panic(err) } + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "distribute_rewards", DistributeRewards, emtypes.EventTypeDistributeRewards, emtypes.EventStatusPending, conditionAnd2, nil) // ensure we archive claims before we return! k.icsKeeper.IterateZones(ctx, func(index int64, zone *icstypes.Zone) (stop bool) { @@ -74,23 +91,36 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ int64) return false }) - tvs, err := k.CalcTokenValues(ctx) - if err != nil { - k.Logger(ctx).Error("unable to calculate token values", "error", err.Error()) - return nil - } + // ascertain validator scores... - if allocation == nil { - // if allocation is unset, then return early to avoid panic - k.Logger(ctx).Error("nil allocation") - return nil - } + // tvs, err := k.CalcTokenValues(ctx) + // if err != nil { + // k.Logger(ctx).Error("unable to calculate token values", "error", err.Error()) + // return nil + // } - if err := k.AllocateZoneRewards(ctx, tvs, *allocation); err != nil { - k.Logger(ctx).Error("unable to allocate: tvl is zero", "error", err.Error()) - return nil + // if allocation == nil { + // // if allocation is unset, then return early to avoid panic + // k.Logger(ctx).Error("nil allocation") + // return nil + // } + + k.Logger(ctx).Info("distribute participation rewards...") + + err = k.DetermineAllocations( + ctx, + k.GetModuleBalance(ctx), + k.GetParams(ctx).DistributionProportions, + ) + if err != nil { + k.Logger(ctx).Error(err.Error()) } + // if err := k.AllocateZoneRewards(ctx, tvs, *allocation); err != nil { // split into calculate a + // k.Logger(ctx).Error("unable to allocate: tvl is zero", "error", err.Error()) + // return nil + // } + // TODO: remove 'lockup' allocation logic. // if !allocation.Lockup.IsZero() { // // at genesis lockup will be disabled, and enabled when ICS is used. diff --git a/x/participationrewards/keeper/keeper.go b/x/participationrewards/keeper/keeper.go index f9e54268a..7ed3c6470 100644 --- a/x/participationrewards/keeper/keeper.go +++ b/x/participationrewards/keeper/keeper.go @@ -51,6 +51,7 @@ type Keeper struct { icsKeeper types.InterchainStakingKeeper epochsKeeper epochskeeper.Keeper ClaimsManagerKeeper types.ClaimsManagerKeeper + EventManagerKeeper types.EventManagerKeeper feeCollectorName string PrSubmodules map[cmtypes.ClaimType]Submodule @@ -71,6 +72,7 @@ func NewKeeper( icqk types.InterchainQueryKeeper, icsk types.InterchainStakingKeeper, cmk types.ClaimsManagerKeeper, + emk types.EventManagerKeeper, feeCollectorName string, proofValidationFn utils.ProofOpsFn, selfProofValidationFn utils.SelfProofOpsFn, @@ -95,6 +97,7 @@ func NewKeeper( IcqKeeper: icqk, icsKeeper: icsk, ClaimsManagerKeeper: cmk, + EventManagerKeeper: emk, feeCollectorName: feeCollectorName, PrSubmodules: LoadSubmodules(), ValidateProofOps: proofValidationFn, @@ -159,14 +162,14 @@ func (k *Keeper) UpdateSelfConnectionData(ctx sdk.Context) error { return nil } -func (k *Keeper) GetModuleBalance(ctx sdk.Context) sdkmath.Int { +func (k *Keeper) GetModuleBalance(ctx sdk.Context) sdk.Coin { denom := k.stakingKeeper.BondDenom(ctx) moduleAddress := k.accountKeeper.GetModuleAddress(types.ModuleName) moduleBalance := k.bankKeeper.GetBalance(ctx, moduleAddress, denom) k.Logger(ctx).Info("module account", "address", moduleAddress, "balance", moduleBalance) - return moduleBalance.Amount + return moduleBalance } func LoadSubmodules() map[cmtypes.ClaimType]Submodule { diff --git a/x/participationrewards/keeper/rewards_validatorSelection.go b/x/participationrewards/keeper/rewards_validatorSelection.go index 66e6ce24a..852d70106 100644 --- a/x/participationrewards/keeper/rewards_validatorSelection.go +++ b/x/participationrewards/keeper/rewards_validatorSelection.go @@ -4,18 +4,23 @@ import ( "errors" "fmt" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/quicksilver-zone/quicksilver/utils" + "github.com/quicksilver-zone/quicksilver/utils/addressutils" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" icstypes "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" ) -// AllocateValidatorSelectionRewards utilizes IBC to query the performance +// QueryValidatorDelegationPerformance utilizes IBC to query the performance // rewards account for each zone to determine validator performance and // corresponding rewards allocations. Each zone's response is dealt with // individually in a callback. -func (k Keeper) AllocateValidatorSelectionRewards(ctx sdk.Context) { +func (k Keeper) QueryValidatorDelegationPerformance(ctx sdk.Context) { k.icsKeeper.IterateZones(ctx, func(_ int64, zone *icstypes.Zone) (stop bool) { if zone.PerformanceAddress != nil { k.Logger(ctx).Info("zones", "chain_id", zone.ChainId, "performance address", zone.PerformanceAddress.Address) @@ -35,6 +40,8 @@ func (k Keeper) AllocateValidatorSelectionRewards(ctx sdk.Context) { ValidatorSelectionRewardsCallbackID, 0, ) + + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, zone.ChainId, "validator_performance", "", emtypes.EventTypeICQQueryDelegations, emtypes.EventStatusActive, nil, nil) } return false }) @@ -56,14 +63,14 @@ func (k Keeper) getZoneScores( zs := types.ZoneScore{ ZoneID: zone.ChainId, TotalVotingPower: sdk.NewInt(0), - ValidatorScores: make(map[string]*types.Validator), + ValidatorScores: make(map[string]*types.ValidatorScore), } if err := k.CalcDistributionScores(ctx, zone, &zs); err != nil { return nil, err } - if err := k.CalcOverallScores(ctx, zone, delegatorRewards, &zs); err != nil { + if err := k.CalcPerformanceScores(ctx, zone, delegatorRewards, &zs); err != nil { return nil, err } @@ -81,30 +88,15 @@ func (k Keeper) CalcDistributionScores(ctx sdk.Context, zone icstypes.Zone, zs * return fmt.Errorf("zone %v has no validators", zone.ChainId) } - // calculate total voting power - // and determine min/max voting power for zone - max := sdk.NewInt(0) - min := sdk.NewInt(999999999999999999) + vps := map[string]math.Int{} for _, zoneVal := range zoneValidators { val := zoneVal if val.VotingPower.IsNegative() { - return fmt.Errorf("unexpected negative voting power for %s", val.ValoperAddress) + continue } // compute zone total voting power zs.TotalVotingPower = zs.TotalVotingPower.Add(val.VotingPower) - if _, exists := zs.ValidatorScores[val.ValoperAddress]; !exists { - zs.ValidatorScores[val.ValoperAddress] = &types.Validator{Validator: &val} - } - - // Set max/min - if max.LT(val.VotingPower) { - max = val.VotingPower - k.Logger(ctx).Info("new power max", "max", max, "validator", val.ValoperAddress) - } - if min.GT(val.VotingPower) { - min = val.VotingPower - k.Logger(ctx).Info("new power min", "min", min, "validator", val.ValoperAddress) - } + vps[val.ValoperAddress] = val.VotingPower } k.Logger(ctx).Info("zone voting power", "zone", zone.ChainId, "total voting power", zs.TotalVotingPower) @@ -116,31 +108,22 @@ func (k Keeper) CalcDistributionScores(ctx sdk.Context, zone icstypes.Zone, zs * } // calculate power percentage and normalized distribution scores - maxp := sdk.NewDecFromInt(max).Quo(sdk.NewDecFromInt(zs.TotalVotingPower)) - minp := sdk.NewDecFromInt(min).Quo(sdk.NewDecFromInt(zs.TotalVotingPower)) - for _, vs := range zs.ValidatorScores { - // calculate power percentage - vs.PowerPercentage = sdk.NewDecFromInt(vs.VotingPower).Quo(sdk.NewDecFromInt(zs.TotalVotingPower)) - - // calculate normalized distribution score - vs.DistributionScore = sdk.NewDec(1).Sub( - vs.PowerPercentage.Sub(minp).Mul( - sdk.NewDec(1).Quo(maxp), - ), - ) + for _, valoper := range utils.Keys[math.Int](vps) { + vpPercent := sdk.NewDecFromInt(vps[valoper]).Quo(sdk.NewDecFromInt(zs.TotalVotingPower)) + zs.ValidatorScores[valoper] = &types.ValidatorScore{DistributionScore: sdk.NewDec(1).Quo(vpPercent)} k.Logger(ctx).Debug( "validator score", - "validator", vs.ValoperAddress, - "power percentage", vs.PowerPercentage, - "distribution score", vs.DistributionScore, + "validator", valoper, + "power percentage", vpPercent, + "distribution score", zs.ValidatorScores[valoper].DistributionScore, ) } return nil } -// CalcOverallScores calculates the overall validator scores for the given zone +// CalcPerformanceScores calculates he overall validator scores for the given zone // based on the combination of performance score and distribution score. // // The performance score is first calculated based on validator rewards earned @@ -152,7 +135,7 @@ func (k Keeper) CalcDistributionScores(ctx sdk.Context, zone icstypes.Zone, zs * // // On completion a msg is submitted to withdraw the zone performance rewards, // resetting zone performance scoring for the next epoch. -func (k Keeper) CalcOverallScores( +func (k Keeper) CalcPerformanceScores( ctx sdk.Context, zone icstypes.Zone, delegatorRewards distrtypes.QueryDelegationTotalRewardsResponse, @@ -180,8 +163,9 @@ func (k Keeper) CalcOverallScores( "expected", expected, ) + maxScore := sdk.ZeroDec() + msgs := make([]sdk.Msg, 0) - limit := sdk.NewDec(1.0) for _, reward := range rewards { vs, exists := zs.ValidatorScores[reward.ValidatorAddress] if !exists { @@ -189,23 +173,31 @@ func (k Keeper) CalcOverallScores( continue } - vs.PerformanceScore = reward.Reward.AmountOf(zone.BaseDenom).Quo(expected) - if vs.PerformanceScore.GT(limit) { - vs.PerformanceScore = limit + rootScore := reward.Reward.AmountOf(zone.BaseDenom).Quo(expected) + vs.PerformanceScore = rootScore.Mul(rootScore) + if vs.PerformanceScore.GT(maxScore) { + maxScore = vs.PerformanceScore } - k.Logger(ctx).Info("performance score", "validator", vs.ValoperAddress, "performance", vs.PerformanceScore) + } - // calculate and set overall score - vs.Score = vs.DistributionScore.Mul(vs.PerformanceScore) - k.Logger(ctx).Info("overall score", "validator", vs.ValoperAddress, "overall", vs.Score) - if err := k.icsKeeper.SetValidator(ctx, zone.ChainId, *(vs.Validator)); err != nil { - k.Logger(ctx).Error("unable to set score for validator", "validator", vs.ValoperAddress) + for _, reward := range rewards { + vs := zs.ValidatorScores[reward.ValidatorAddress] + vs.PerformanceScore = vs.PerformanceScore.Quo(maxScore) + k.Logger(ctx).Info("overall score", "validator", reward.ValidatorAddress, "distribution", vs.DistributionScore, "performance", vs.PerformanceScore, "total", vs.TotalScore()) + val, found := k.icsKeeper.GetValidator(ctx, zone.ChainId, addressutils.MustValAddressFromBech32(reward.ValidatorAddress, "")) + if !found { + k.Logger(ctx).Error("unable to find validator", "validator", reward.ValidatorAddress) + } else { + val.Score = vs.TotalScore() + if err := k.icsKeeper.SetValidator(ctx, zone.ChainId, val); err != nil { + k.Logger(ctx).Error("unable to set score for validator", "validator", reward.ValidatorAddress) + } } // prepare validator performance withdrawal msg msg := &distrtypes.MsgWithdrawDelegatorReward{ DelegatorAddress: zone.PerformanceAddress.GetAddress(), - ValidatorAddress: vs.ValoperAddress, + ValidatorAddress: reward.ValidatorAddress, } msgs = append(msgs, msg) } @@ -218,9 +210,6 @@ func (k Keeper) CalcOverallScores( } } - // update zone with validator scores - k.icsKeeper.SetZone(ctx, &zone) - return nil } @@ -249,8 +238,8 @@ func (k Keeper) CalcUserValidatorSelectionAllocations( // calc overall user score score := sdk.ZeroDec() if vs, exists := zs.ValidatorScores[intent.ValoperAddress]; exists { - if !vs.Score.IsNil() { - score = intent.Weight.Mul(vs.Score) + if !vs.TotalScore().IsNil() { + score = intent.Weight.Mul(vs.TotalScore()) } } k.Logger(ctx).Info("user score for validator", "user", di.GetDelegator(), "validator", intent.GetValoperAddress(), "score", score) diff --git a/x/participationrewards/keeper/rewards_validatorSelection_test.go b/x/participationrewards/keeper/rewards_validatorSelection_test.go index 6937edda8..8c9e81c6b 100644 --- a/x/participationrewards/keeper/rewards_validatorSelection_test.go +++ b/x/participationrewards/keeper/rewards_validatorSelection_test.go @@ -21,7 +21,7 @@ func (suite *KeeperTestSuite) TestCalcUserValidatorSelectionAllocations() { tests := []struct { name string malleate func(sdk.Context, *app.Quicksilver) - validatorScores func(sdk.Context, *app.Quicksilver, string) map[string]*types.Validator + validatorScores func(sdk.Context, *app.Quicksilver, string) map[string]*types.ValidatorScore want func(denom string) []types.UserAllocation }{ { @@ -35,7 +35,7 @@ func (suite *KeeperTestSuite) TestCalcUserValidatorSelectionAllocations() { zone.ValidatorSelectionAllocation = 0 appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(context sdk.Context, quicksilver *app.Quicksilver, s string) map[string]*types.Validator { + validatorScores: func(context sdk.Context, quicksilver *app.Quicksilver, s string) map[string]*types.ValidatorScore { return nil }, want: func(denom string) []types.UserAllocation { return []types.UserAllocation{} }, @@ -59,16 +59,14 @@ func (suite *KeeperTestSuite) TestCalcUserValidatorSelectionAllocations() { appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) validators := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) for i := range validators { validators[i].Score = sdk.NewDec(1) - validatorScores[validators[i].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[validators[i].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &validators[i], } } return validatorScores @@ -92,17 +90,15 @@ func (suite *KeeperTestSuite) TestCalcUserValidatorSelectionAllocations() { appA.InterchainstakingKeeper.SetDelegatorIntent(ctx, &zone, icstypes.DelegatorIntent{Delegator: user1.String(), Intents: validatorIntents}, true) appA.InterchainstakingKeeper.SetDelegatorIntent(ctx, &zone, icstypes.DelegatorIntent{Delegator: user2.String(), Intents: validatorIntents}, true) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) validators := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) for i := range validators { validators[i].Score = sdk.NewDec(1) - validatorScores[validators[i].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[validators[i].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &validators[i], } } return validatorScores @@ -138,17 +134,15 @@ func (suite *KeeperTestSuite) TestCalcUserValidatorSelectionAllocations() { appA.InterchainstakingKeeper.SetDelegatorIntent(ctx, &zone, icstypes.DelegatorIntent{Delegator: user1.String(), Intents: validatorIntentsA}, true) appA.InterchainstakingKeeper.SetDelegatorIntent(ctx, &zone, icstypes.DelegatorIntent{Delegator: user2.String(), Intents: validatorIntentsB}, true) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) validators := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) for i := range validators { validators[i].Score = sdk.NewDec(1) - validatorScores[validators[i].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[validators[i].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &validators[i], } } return validatorScores @@ -184,17 +178,15 @@ func (suite *KeeperTestSuite) TestCalcUserValidatorSelectionAllocations() { appA.InterchainstakingKeeper.SetDelegatorIntent(ctx, &zone, icstypes.DelegatorIntent{Delegator: user1.String(), Intents: validatorIntentsA}, true) appA.InterchainstakingKeeper.SetDelegatorIntent(ctx, &zone, icstypes.DelegatorIntent{Delegator: user2.String(), Intents: validatorIntentsB}, true) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) validators := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) for i := range validators { validators[i].Score = sdk.NewDec(1) - validatorScores[validators[i].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[validators[i].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &validators[i], } } return validatorScores @@ -253,7 +245,7 @@ func (suite *KeeperTestSuite) TestCalcDistributionScores() { tests := []struct { name string malleate func(sdk.Context, *app.Quicksilver) - validatorScores func(sdk.Context, *app.Quicksilver, string) map[string]*types.Validator + validatorScores func(sdk.Context, *app.Quicksilver, string) map[string]*types.ValidatorScore verify func(sdk.Context, *app.Quicksilver, types.ZoneScore) wantErr bool }{ @@ -274,7 +266,7 @@ func (suite *KeeperTestSuite) TestCalcDistributionScores() { appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { return nil }, verify: func(context sdk.Context, quicksilver *app.Quicksilver, score types.ZoneScore) { @@ -300,17 +292,15 @@ func (suite *KeeperTestSuite) TestCalcDistributionScores() { appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) validators := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) for i := range validators { validators[i].Score = sdk.NewDec(1) - validatorScores[validators[i].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[validators[i].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &validators[i], } } return validatorScores @@ -337,30 +327,24 @@ func (suite *KeeperTestSuite) TestCalcDistributionScores() { appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) vals := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) (&vals[0]).VotingPower = sdk.NewInt(10) - validatorScores[vals[0].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[vals[0].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &vals[0], } (&vals[1]).VotingPower = sdk.NewInt(20) - validatorScores[vals[1].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[vals[1].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &vals[1], } (&vals[2]).VotingPower = sdk.NewInt(30) - validatorScores[vals[2].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[vals[2].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &vals[2], } return validatorScores }, @@ -369,10 +353,6 @@ func (suite *KeeperTestSuite) TestCalcDistributionScores() { validators := appA.InterchainstakingKeeper.GetValidators(ctx, zs.ZoneID) - suite.Equal(strings.TrimRight(zs.ValidatorScores[validators[0].ValoperAddress].PowerPercentage.String(), "0"), "0.1") - suite.Equal(strings.TrimRight(zs.ValidatorScores[validators[1].ValoperAddress].PowerPercentage.String(), "0"), "0.2") - suite.Equal(strings.TrimRight(zs.ValidatorScores[validators[2].ValoperAddress].PowerPercentage.String(), "0"), "0.3") - suite.Equal(zs.ValidatorScores[validators[0].ValoperAddress].DistributionScore, sdk.NewDec(1)) suite.Equal(strings.TrimRight(zs.ValidatorScores[validators[1].ValoperAddress].DistributionScore.String(), "0"), "0.75") suite.Equal(strings.TrimRight(zs.ValidatorScores[validators[2].ValoperAddress].DistributionScore.String(), "0"), "0.5") @@ -421,7 +401,7 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { tests := []struct { name string malleate func(sdk.Context, *app.Quicksilver) - validatorScores func(sdk.Context, *app.Quicksilver, string) map[string]*types.Validator + validatorScores func(sdk.Context, *app.Quicksilver, string) map[string]*types.ValidatorScore delegatorRewards func(sdk.Context, *app.Quicksilver, string) distributiontypes.QueryDelegationTotalRewardsResponse verify func(types.ZoneScore, []distributiontypes.DelegationDelegatorReward, []icstypes.Validator) wantErr bool @@ -430,7 +410,7 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { name: "nil delegation rewards", malleate: func(context sdk.Context, quicksilver *app.Quicksilver) { }, - validatorScores: func(context sdk.Context, quicksilver *app.Quicksilver, s string) map[string]*types.Validator { + validatorScores: func(context sdk.Context, quicksilver *app.Quicksilver, s string) map[string]*types.ValidatorScore { return nil }, delegatorRewards: func(_ sdk.Context, _ *app.Quicksilver, _ string) distributiontypes.QueryDelegationTotalRewardsResponse { @@ -444,7 +424,7 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { name: "zero total rewards", malleate: func(context sdk.Context, quicksilver *app.Quicksilver) { }, - validatorScores: func(context sdk.Context, quicksilver *app.Quicksilver, s string) map[string]*types.Validator { + validatorScores: func(context sdk.Context, quicksilver *app.Quicksilver, s string) map[string]*types.ValidatorScore { return nil }, delegatorRewards: func(ctx sdk.Context, appA *app.Quicksilver, chainID string) distributiontypes.QueryDelegationTotalRewardsResponse { @@ -467,15 +447,13 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) val := appA.InterchainstakingKeeper.GetValidators(ctx, chainId)[1] - validatorScores[val.ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[val.ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(3), PerformanceScore: sdk.NewDec(619), - Validator: &val, } return validatorScores @@ -492,8 +470,8 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { verify: func(zs types.ZoneScore, delegatorRewards []distributiontypes.DelegationDelegatorReward, validators []icstypes.Validator) { suite.True(zs.ValidatorScores[delegatorRewards[0].ValidatorAddress] == nil) suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].PerformanceScore, sdk.NewDec(1)) - suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].Score, sdk.NewDec(3)) - suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].Score, validators[1].Score) + suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].TotalScore(), sdk.NewDec(3)) + suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].TotalScore(), validators[1].Score) }, }, { @@ -507,27 +485,21 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { appA.InterchainstakingKeeper.SetZone(ctx, &zone) }, - validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.Validator { - validatorScores := make(map[string]*types.Validator) + validatorScores: func(ctx sdk.Context, appA *app.Quicksilver, chainId string) map[string]*types.ValidatorScore { + validatorScores := make(map[string]*types.ValidatorScore) vals := appA.InterchainstakingKeeper.GetValidators(ctx, chainId) - validatorScores[vals[0].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[vals[0].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(1), PerformanceScore: sdk.NewDec(1), - Validator: &vals[0], } - validatorScores[vals[1].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[vals[1].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(5), PerformanceScore: sdk.NewDec(1), - Validator: &vals[1], } - validatorScores[vals[2].ValoperAddress] = &types.Validator{ - PowerPercentage: sdk.NewDec(1), + validatorScores[vals[2].ValoperAddress] = &types.ValidatorScore{ DistributionScore: sdk.NewDec(7), PerformanceScore: sdk.NewDec(1), - Validator: &vals[2], } return validatorScores }, @@ -542,16 +514,16 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { }, verify: func(zs types.ZoneScore, delegatorRewards []distributiontypes.DelegationDelegatorReward, validators []icstypes.Validator) { suite.Equal(strings.TrimRight(zs.ValidatorScores[delegatorRewards[0].ValidatorAddress].PerformanceScore.String(), "0"), "0.5") - suite.Equal(strings.TrimRight(zs.ValidatorScores[delegatorRewards[0].ValidatorAddress].Score.String(), "0"), "0.5") - suite.Equal(zs.ValidatorScores[delegatorRewards[0].ValidatorAddress].Score, validators[0].Score) + suite.Equal(strings.TrimRight(zs.ValidatorScores[delegatorRewards[0].ValidatorAddress].TotalScore().String(), "0"), "0.5") + suite.Equal(zs.ValidatorScores[delegatorRewards[0].ValidatorAddress].TotalScore(), validators[0].Score) suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].PerformanceScore, sdk.NewDec(1)) - suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].Score, sdk.NewDec(5)) - suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].Score, validators[1].Score) + suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].TotalScore(), sdk.NewDec(5)) + suite.Equal(zs.ValidatorScores[delegatorRewards[1].ValidatorAddress].TotalScore(), validators[1].Score) suite.Equal(zs.ValidatorScores[delegatorRewards[2].ValidatorAddress].PerformanceScore, sdk.NewDec(1)) - suite.Equal(zs.ValidatorScores[delegatorRewards[2].ValidatorAddress].Score, sdk.NewDec(7)) - suite.Equal(zs.ValidatorScores[delegatorRewards[2].ValidatorAddress].Score, validators[2].Score) + suite.Equal(zs.ValidatorScores[delegatorRewards[2].ValidatorAddress].TotalScore(), sdk.NewDec(7)) + suite.Equal(zs.ValidatorScores[delegatorRewards[2].ValidatorAddress].TotalScore(), validators[2].Score) }, }, } @@ -587,7 +559,7 @@ func (suite *KeeperTestSuite) TestCalcOverallScores() { delegatorRewards := tt.delegatorRewards(ctx, appA, zone.ChainId) - err := appA.ParticipationRewardsKeeper.CalcOverallScores(ctx, zone, delegatorRewards, &zs) + err := appA.ParticipationRewardsKeeper.CalcPerformanceScores(ctx, zone, delegatorRewards, &zs) suite.Equal(err != nil, tt.wantErr) tt.verify(zs, delegatorRewards.Rewards, appA.InterchainstakingKeeper.GetValidators(ctx, zone.ChainId)) diff --git a/x/participationrewards/keeper/submodule_liquid.go b/x/participationrewards/keeper/submodule_liquid.go index a0d345f0d..4f8c6bc72 100644 --- a/x/participationrewards/keeper/submodule_liquid.go +++ b/x/participationrewards/keeper/submodule_liquid.go @@ -18,8 +18,7 @@ type LiquidTokensModule struct{} var _ Submodule = &LiquidTokensModule{} -func (*LiquidTokensModule) Hooks(_ sdk.Context, _ *Keeper) { -} +func (*LiquidTokensModule) Hooks(_ sdk.Context, _ *Keeper) {} func (*LiquidTokensModule) ValidateClaim(ctx sdk.Context, k *Keeper, msg *types.MsgSubmitClaim) (math.Int, error) { // message diff --git a/x/participationrewards/keeper/submodule_osmosis.go b/x/participationrewards/keeper/submodule_osmosis.go index df36fa4b1..28f8c7abd 100644 --- a/x/participationrewards/keeper/submodule_osmosis.go +++ b/x/participationrewards/keeper/submodule_osmosis.go @@ -17,6 +17,7 @@ import ( osmosistypes "github.com/quicksilver-zone/quicksilver/third-party-chains/osmosis-types" osmolockup "github.com/quicksilver-zone/quicksilver/third-party-chains/osmosis-types/lockup" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" ) @@ -69,6 +70,19 @@ func (m *OsmosisModule) Hooks(ctx sdk.Context, k *Keeper) { OsmosisPoolUpdateCallbackID, 0, ) // query pool data + + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + "", + fmt.Sprintf("submodule/osmosispool/%d", pool.PoolID), + "", + emtypes.EventTypeICQOsmosisPool, + emtypes.EventStatusActive, + nil, + nil, + ) + return false }) } diff --git a/x/participationrewards/types/allocations.go b/x/participationrewards/types/allocations.go deleted file mode 100644 index 4e6810fcf..000000000 --- a/x/participationrewards/types/allocations.go +++ /dev/null @@ -1,43 +0,0 @@ -package types - -import ( - "fmt" - - "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type RewardsAllocation struct { - ValidatorSelection math.Int - Holdings math.Int - Lockup math.Int -} - -// GetRewardsAllocations returns an instance of rewardsAllocation with values -// set according to the given moduleBalance and distribution proportions. -func GetRewardsAllocations(moduleBalance math.Int, proportions DistributionProportions) (*RewardsAllocation, error) { - if moduleBalance.IsNil() || moduleBalance.IsZero() { - return nil, ErrNothingToAllocate - } - - if sum := proportions.Total(); !sum.Equal(sdk.OneDec()) { - return nil, fmt.Errorf("%w: got %v", ErrInvalidTotalProportions, sum) - } - - var allocation RewardsAllocation - - // split participation rewards allocations - allocation.ValidatorSelection = sdk.NewDecFromInt(moduleBalance).Mul(proportions.ValidatorSelectionAllocation).TruncateInt() - allocation.Holdings = sdk.NewDecFromInt(moduleBalance).Mul(proportions.HoldingsAllocation).TruncateInt() - allocation.Lockup = sdk.NewDecFromInt(moduleBalance).Mul(proportions.LockupAllocation).TruncateInt() - - // use sum to check total distribution to collect and allocate dust - sum := allocation.Lockup.Add(allocation.ValidatorSelection).Add(allocation.Holdings) - dust := moduleBalance.Sub(sum) - - // Add dust to validator choice allocation (favors decentralization) - allocation.ValidatorSelection = allocation.ValidatorSelection.Add(dust) - - return &allocation, nil -} diff --git a/x/participationrewards/types/allocations_test.go b/x/participationrewards/types/allocations_test.go deleted file mode 100644 index 525a11be0..000000000 --- a/x/participationrewards/types/allocations_test.go +++ /dev/null @@ -1,190 +0,0 @@ -package types_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" -) - -func TestGetRewardsAllocations(t *testing.T) { - type args struct { - moduleBalance math.Int - proportions types.DistributionProportions - } - tests := []struct { - name string - args args - want *types.RewardsAllocation - wantErr string - }{ - { - "empty_params", - args{}, - nil, - "balance is zero, nothing to allocate", - }, - { - "invalid_no_balance", - args{ - sdk.NewInt(0), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.34"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.33"), - LockupAllocation: sdk.MustNewDecFromStr("0.33"), - }, - }, - nil, - "balance is zero, nothing to allocate", - }, - { - "invalid_proportions_gt", - args{ - sdk.NewInt(1000000000), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.5"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.5"), - LockupAllocation: sdk.MustNewDecFromStr("0.5"), - }, - }, - nil, - "total distribution proportions must be 1.0: got 1.50", - }, - { - "invalid_proportions_lt", - args{ - sdk.NewInt(1000000000), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.3"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.3"), - LockupAllocation: sdk.MustNewDecFromStr("0.3"), - }, - }, - nil, - "total distribution proportions must be 1.0: got 0.90", - }, - { - "valid", - args{ - sdk.NewInt(1000000000), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.34"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.33"), - LockupAllocation: sdk.MustNewDecFromStr("0.33"), - }, - }, - &types.RewardsAllocation{ - ValidatorSelection: sdk.NewInt(340000000), - Holdings: sdk.NewInt(330000000), - Lockup: sdk.NewInt(330000000), - }, - "", - }, - { - "valid", - args{ - sdk.NewInt(1000000000), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.5"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.25"), - LockupAllocation: sdk.MustNewDecFromStr("0.25"), - }, - }, - &types.RewardsAllocation{ - ValidatorSelection: sdk.NewInt(500000000), - Holdings: sdk.NewInt(250000000), - Lockup: sdk.NewInt(250000000), - }, - "", - }, - { - "valid", - args{ - sdk.NewInt(1000000000), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.6"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.4"), - LockupAllocation: sdk.MustNewDecFromStr("0"), - }, - }, - &types.RewardsAllocation{ - ValidatorSelection: sdk.NewInt(600000000), - Holdings: sdk.NewInt(400000000), - Lockup: sdk.NewInt(0), - }, - "", - }, - { - "valid", - args{ - sdk.NewInt(164133471813), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.34"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.33"), - LockupAllocation: sdk.MustNewDecFromStr("0.33"), - }, - }, - &types.RewardsAllocation{ - ValidatorSelection: sdk.NewInt(55805380417), - Holdings: sdk.NewInt(54164045698), - Lockup: sdk.NewInt(54164045698), - }, - "", - }, - { - "valid", - args{ - sdk.NewInt(164133471813), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.5"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.25"), - LockupAllocation: sdk.MustNewDecFromStr("0.25"), - }, - }, - &types.RewardsAllocation{ - ValidatorSelection: sdk.NewInt(82066735907), - Holdings: sdk.NewInt(41033367953), - Lockup: sdk.NewInt(41033367953), - }, - "", - }, - { - "valid", - args{ - sdk.NewInt(164133471813), - types.DistributionProportions{ - ValidatorSelectionAllocation: sdk.MustNewDecFromStr("0.6"), - HoldingsAllocation: sdk.MustNewDecFromStr("0.4"), - LockupAllocation: sdk.MustNewDecFromStr("0"), - }, - }, - &types.RewardsAllocation{ - ValidatorSelection: sdk.NewInt(98480083088), - Holdings: sdk.NewInt(65653388725), - Lockup: sdk.NewInt(0), - }, - "", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := types.GetRewardsAllocations(tt.args.moduleBalance, tt.args.proportions) - if tt.wantErr != "" { - require.Error(t, err) - require.Nil(t, got) - require.Contains(t, err.Error(), tt.wantErr) - t.Logf("Error: %v", err) - return - } - - require.NoError(t, err) - require.NotNil(t, got) - require.Equal(t, tt.want, got) - }) - } -} diff --git a/x/participationrewards/types/expected_keepers.go b/x/participationrewards/types/expected_keepers.go index e118bfdf3..142fa435d 100644 --- a/x/participationrewards/types/expected_keepers.go +++ b/x/participationrewards/types/expected_keepers.go @@ -9,6 +9,7 @@ import ( ibctmtypes "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint/types" claimsmanagertypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" interchainquerytypes "github.com/quicksilver-zone/quicksilver/x/interchainquery/types" interchainstakingtypes "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" ) @@ -75,5 +76,12 @@ type InterchainStakingKeeper interface { GetDelegationsInProcess(ctx sdk.Context, chainID string) sdkmath.Int IterateDelegatorIntents(ctx sdk.Context, zone *interchainstakingtypes.Zone, snapshot bool, fn func(index int64, intent interchainstakingtypes.DelegatorIntent) (stop bool)) GetValidators(ctx sdk.Context, chainID string) []interchainstakingtypes.Validator + GetValidatorsAsMap(ctx sdk.Context, chainID string) map[string]interchainstakingtypes.Validator SetValidator(ctx sdk.Context, chainID string, val interchainstakingtypes.Validator) error + GetValidator(ctx sdk.Context, chainID string, address []byte) (interchainstakingtypes.Validator, bool) +} + +type EventManagerKeeper interface { + AddEvent(ctx sdk.Context, module, chainID, identifier, callback string, eventType, status int32, condtion emtypes.ConditionI, payload []byte) + MarkCompleted(ctx sdk.Context, module string, chainID string, identifier string) } diff --git a/x/participationrewards/types/keys.go b/x/participationrewards/types/keys.go index 4ca7adf24..d4d09854b 100644 --- a/x/participationrewards/types/keys.go +++ b/x/participationrewards/types/keys.go @@ -22,7 +22,12 @@ const ( ProofTypeLPFarm = "lpfarm" ) -var KeyPrefixProtocolData = []byte{0x00} +var ( + KeyPrefixProtocolData = []byte{0x00} + KeyPrefixHoldingAllocation = []byte{0x01} + KeyPrefixValidatorAllocation = []byte{0x02} + KeyPrefixValues = []byte{0x03} +) func GetProtocolDataKey(pdType ProtocolDataType, key []byte) []byte { return append(sdk.Uint64ToBigEndian(uint64(pdType)), key...) diff --git a/x/participationrewards/types/participationrewards.go b/x/participationrewards/types/participationrewards.go index c23b67d52..26c4bae50 100644 --- a/x/participationrewards/types/participationrewards.go +++ b/x/participationrewards/types/participationrewards.go @@ -9,8 +9,6 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - - icstypes "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" ) const ( @@ -135,18 +133,19 @@ type UserAllocation struct { type ZoneScore struct { ZoneID string // chainID TotalVotingPower math.Int - ValidatorScores map[string]*Validator + ValidatorScores map[string]*ValidatorScore } -// Validator is an internal struct to track transient state for the calculation -// of zone scores. It contains all relevant Validator scoring metrics with a -// pointer reference to the actual Validator (embedded). -type Validator struct { - PowerPercentage sdk.Dec +// ValidatorScore is an internal struct to track transient state for the calculation +// of zone scores. It contains all relevant ValidatorScore scoring metrics with a +// pointer reference to the actual ValidatorScore (embedded). +type ValidatorScore struct { PerformanceScore sdk.Dec DistributionScore sdk.Dec +} - *icstypes.Validator +func (v *ValidatorScore) TotalScore() sdk.Dec { + return v.PerformanceScore.Add(v.DistributionScore) } // UserScore is an internal struct to track transient state for rewards From 141a01f6952400748b6a8c4794f509ffc5e448b0 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 24 Apr 2024 23:24:32 +0100 Subject: [PATCH 09/14] finish participation rewards integration with em --- x/eventmanager/types/keys.go | 34 ++++++----- x/participationrewards/keeper/callbacks.go | 9 +++ .../keeper/submodule_umee.go | 61 ++++++++++++++++++- 3 files changed, 87 insertions(+), 17 deletions(-) diff --git a/x/eventmanager/types/keys.go b/x/eventmanager/types/keys.go index 405f428a3..19e0e58d1 100644 --- a/x/eventmanager/types/keys.go +++ b/x/eventmanager/types/keys.go @@ -19,21 +19,25 @@ const ( EventStatusActive = int32(1) EventStatusPending = int32(2) - EventTypeUnspecified = int32(0x00) - EventTypeICQQueryRewards = int32(0x01) - EventTypeICQQueryDelegations = int32(0x02) - EventTypeICQQueryDelegation = int32(0x03) - EventTypeICQAccountBalances = int32(0x04) - EventTypeICQAccountBalance = int32(0x05) - EventTypeICAWithdrawRewards = int32(0x06) - EventTypeICADelegate = int32(0x07) - EventTypeICAUnbond = int32(0x08) - EventTypeICQGetLatestBlock = int32(0x09) - EventTypeICQOsmosisPool = int32(0x0a) - EventTypeSubmodules = int32(0x0b) - EventTypeCalculateTvls = int32(0x0c) - EventTypeDistributeRewards = int32(0x0d) - + EventTypeUnspecified = int32(0x00) + EventTypeICQQueryRewards = int32(0x01) + EventTypeICQQueryDelegations = int32(0x02) + EventTypeICQQueryDelegation = int32(0x03) + EventTypeICQAccountBalances = int32(0x04) + EventTypeICQAccountBalance = int32(0x05) + EventTypeICAWithdrawRewards = int32(0x06) + EventTypeICADelegate = int32(0x07) + EventTypeICAUnbond = int32(0x08) + EventTypeICQGetLatestBlock = int32(0x09) + EventTypeICQOsmosisPool = int32(0x0a) + EventTypeSubmodules = int32(0x0b) + EventTypeCalculateTvls = int32(0x0c) + EventTypeDistributeRewards = int32(0x0d) + EventTypeICQUmeeUTokenSupply = int32(0x0e) + EventTypeICQUmeeInterestScalar = int32(0x0f) + EventTypeICQUmeeLeverageBalance = int32(0x10) + EventTypeICQUmeeReserves = int32(0x11) + EventTypeICQUmeeTotalBorrows = int32(0x12) FieldEventType = "eventtype" FieldModule = "module" diff --git a/x/participationrewards/keeper/callbacks.go b/x/participationrewards/keeper/callbacks.go index fb0d26650..21822ff7c 100644 --- a/x/participationrewards/keeper/callbacks.go +++ b/x/participationrewards/keeper/callbacks.go @@ -228,6 +228,8 @@ func UmeeReservesUpdateCallback(ctx sdk.Context, k *Keeper, response []byte, que if !ok { return fmt.Errorf("unable to find protocol data for umeereserves/%s", denom) } + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", fmt.Sprintf("submodule/umeereserves/%s", denom)) + ireserves, err := types.UnmarshalProtocolData(types.ProtocolDataTypeUmeeReserves, data.Data) if err != nil { return err @@ -261,6 +263,8 @@ func UmeeTotalBorrowsUpdateCallback(ctx sdk.Context, k *Keeper, response []byte, } denom := umeetypes.DenomFromKey(query.Request, umeetypes.KeyPrefixAdjustedTotalBorrow) + + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", fmt.Sprintf("submodule/umeetotalborrows/%s", denom)) data, ok := k.GetProtocolData(ctx, types.ProtocolDataTypeUmeeTotalBorrows, denom) if !ok { return fmt.Errorf("unable to find protocol data for umee-types total borrows/%s", denom) @@ -298,6 +302,7 @@ func UmeeInterestScalarUpdateCallback(ctx sdk.Context, k *Keeper, response []byt } denom := umeetypes.DenomFromKey(query.Request, umeetypes.KeyPrefixInterestScalar) + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", fmt.Sprintf("submodule/umeeinterestscalar/%s", denom)) data, ok := k.GetProtocolData(ctx, types.ProtocolDataTypeUmeeInterestScalar, denom) if !ok { return fmt.Errorf("unable to find protocol data for interestscalar/%s", denom) @@ -335,6 +340,7 @@ func UmeeUTokenSupplyUpdateCallback(ctx sdk.Context, k *Keeper, response []byte, } denom := umeetypes.DenomFromKey(query.Request, umeetypes.KeyPrefixUtokenSupply) + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", fmt.Sprintf("submodule/umeeutokensupply/%s", denom)) data, ok := k.GetProtocolData(ctx, types.ProtocolDataTypeUmeeUTokenSupply, denom) if !ok { return fmt.Errorf("unable to find protocol data for umee-types utoken supply/%s", denom) @@ -373,6 +379,8 @@ func UmeeLeverageModuleBalanceUpdateCallback(ctx sdk.Context, k *Keeper, respons return err } + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, "", fmt.Sprintf("submodule/umeeleveragebalance/%s", denom)) + balanceCoin, err := bankkeeper.UnmarshalBalanceCompat(k.cdc, response, denom) if err != nil { return err @@ -407,6 +415,7 @@ func UmeeLeverageModuleBalanceUpdateCallback(ctx sdk.Context, k *Keeper, respons // SetEpochBlockCallback records the block height of the registered zone at the epoch boundary. func SetEpochBlockCallback(ctx sdk.Context, k *Keeper, args []byte, query icqtypes.Query) error { + defer k.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, query.ChainId, "get_epoch_height") data, ok := k.GetProtocolData(ctx, types.ProtocolDataTypeConnection, query.ChainId) if !ok { return fmt.Errorf("unable to find protocol data for connection/%s", query.ChainId) diff --git a/x/participationrewards/keeper/submodule_umee.go b/x/participationrewards/keeper/submodule_umee.go index 218880c23..dd5fb43fa 100644 --- a/x/participationrewards/keeper/submodule_umee.go +++ b/x/participationrewards/keeper/submodule_umee.go @@ -16,6 +16,7 @@ import ( leveragetypes "github.com/quicksilver-zone/quicksilver/third-party-chains/umee-types/leverage/types" "github.com/quicksilver-zone/quicksilver/utils" cmtypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" icstypes "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" ) @@ -70,8 +71,21 @@ func (UmeeModule) Hooks(ctx sdk.Context, k *Keeper) { UmeeReservesUpdateCallbackID, 0, ) // query reserve data + + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + "", + fmt.Sprintf("submodule/umeereserves/%s", reserves.Denom), + "", + emtypes.EventTypeICQUmeeReserves, + emtypes.EventStatusActive, + nil, + nil, + ) return false }) + // umee-types interest scalar update k.IteratePrefixedProtocolDatas(ctx, types.GetPrefixProtocolDataKey(types.ProtocolDataTypeUmeeInterestScalar), func(idx int64, _ []byte, data types.ProtocolData) bool { iinterest, err := types.UnmarshalProtocolData(types.ProtocolDataTypeUmeeInterestScalar, data.Data) @@ -92,7 +106,17 @@ func (UmeeModule) Hooks(ctx sdk.Context, k *Keeper) { UmeeInterestScalarUpdateCallbackID, 0, ) // query interest data - + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + "", + fmt.Sprintf("submodule/umeeinterestscalar/%s", interest.Denom), + "", + emtypes.EventTypeICQUmeeInterestScalar, + emtypes.EventStatusActive, + nil, + nil, + ) return false }) // umee-types utoken supply update @@ -115,6 +139,17 @@ func (UmeeModule) Hooks(ctx sdk.Context, k *Keeper) { UmeeUTokenSupplyUpdateCallbackID, 0, ) // query utoken supply + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + "", + fmt.Sprintf("submodule/umeeutokensupply/%s", supply.Denom), + "", + emtypes.EventTypeICQUmeeUTokenSupply, + emtypes.EventStatusActive, + nil, + nil, + ) return false }) @@ -141,6 +176,18 @@ func (UmeeModule) Hooks(ctx sdk.Context, k *Keeper) { 0, ) // query leverage module balance + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + "", + fmt.Sprintf("submodule/umeeleveragebalance/%s", balance.Denom), + "", + emtypes.EventTypeICQUmeeLeverageBalance, + emtypes.EventStatusActive, + nil, + nil, + ) + return false }) // umee-types total borrowed update @@ -163,7 +210,17 @@ func (UmeeModule) Hooks(ctx sdk.Context, k *Keeper) { UmeeTotalBorrowsUpdateCallbackID, 0, ) // query leverage module balance - + k.EventManagerKeeper.AddEvent( + ctx, + types.ModuleName, + "", + fmt.Sprintf("submodule/umeetotalborrows/%s", borrows.Denom), + "", + emtypes.EventTypeICQUmeeTotalBorrows, + emtypes.EventStatusActive, + nil, + nil, + ) return false }) } From e35b29c8051b0f82a69d2d50faa0bd5710620862 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 1 May 2024 19:25:15 +0100 Subject: [PATCH 10/14] fix b0rked merge --- app/keepers/keepers.go | 1 + 1 file changed, 1 insertion(+) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index b87f61728..cf6b95a44 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -432,6 +432,7 @@ func (appKeepers *AppKeepers) InitKeepers( if err := appKeepers.EventManagerKeeper.SetCallbackHandler(participationrewardstypes.ModuleName, appKeepers.ParticipationRewardsKeeper.EventCallbackHandler()); err != nil { panic(err) } + // Quicksilver Keepers appKeepers.EpochsKeeper = epochskeeper.NewKeeper(appCodec, appKeepers.keys[epochstypes.StoreKey]) appKeepers.ParticipationRewardsKeeper.SetEpochsKeeper(appKeepers.EpochsKeeper) From 175b37c37b1eaf2aedeb004f363f625ce90e333e Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 1 May 2024 19:25:35 +0100 Subject: [PATCH 11/14] fix ibc version; fix tests --- x/eventmanager/keeper/events_test.go | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/x/eventmanager/keeper/events_test.go b/x/eventmanager/keeper/events_test.go index 1151a4d01..c12b248f6 100644 --- a/x/eventmanager/keeper/events_test.go +++ b/x/eventmanager/keeper/events_test.go @@ -73,11 +73,13 @@ func (suite *KeeperTestSuite) TestEventLifecycle() { suite.NoError(app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler)) + preEvents := len(app.EventManagerKeeper.AllEvents(ctx)) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test", "testCallback", types.EventTypeICADelegate, types.EventStatusPending, nil, nil) events := app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(1, len(events)) + suite.Equal(preEvents+1, len(events)) GlobalVar = 0 @@ -94,7 +96,7 @@ func (suite *KeeperTestSuite) TestEventLifecycle() { events = app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(0, len(events)) + suite.Equal(preEvents, len(events)) } func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { @@ -105,6 +107,8 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { suite.NoError(app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler)) + preEvents := len(app.EventManagerKeeper.AllEvents(ctx)) + condition, err := types.NewConditionAll(ctx, []*types.FieldValue{ {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, {Field: types.FieldEventStatus, Value: fmt.Sprintf("%d", types.EventStatusActive), Operator: types.FieldOperator_EQUAL, Negate: false}, @@ -117,18 +121,18 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { events := app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(2, len(events)) + suite.Equal(preEvents+2, len(events)) GlobalVar = 0 - // martCompleted doesn't require an explicit callback + // markCompleted doesn't require an explicit callback app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test1") event, found := app.EventManagerKeeper.GetEvent(ctx, types.ModuleName, suite.chainB.ChainID, "test") events = app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(1, len(events)) + suite.Equal(preEvents+1, len(events)) suite.True(found) suite.Equal(12345, GlobalVar) @@ -139,7 +143,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition() { events = app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(0, len(events)) + suite.Equal(preEvents, len(events)) } func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { @@ -150,6 +154,8 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { suite.NoError(app.EventManagerKeeper.SetCallbackHandler(types.ModuleName, callbackHandler)) + preEvents := len(app.EventManagerKeeper.AllEvents(ctx)) + condition1, err := types.NewConditionAll(ctx, []*types.FieldValue{ {Field: types.FieldModule, Value: types.ModuleName, Operator: types.FieldOperator_EQUAL, Negate: false}, {Field: types.FieldEventType, Value: fmt.Sprintf("%d", types.EventTypeICAUnbond), Operator: types.FieldOperator_EQUAL, Negate: false}, @@ -172,7 +178,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { events := app.EventManagerKeeper.AllEvents(ctx) fmt.Println(events) - suite.Equal(3, len(events)) + suite.Equal(preEvents+3, len(events)) GlobalVar = 0 @@ -184,7 +190,7 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { events = app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(2, len(events)) + suite.Equal(preEvents+2, len(events)) suite.Equal(1, GlobalVar) @@ -196,11 +202,11 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { events = app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(1, len(events)) + suite.Equal(preEvents+1, len(events)) app.EventManagerKeeper.MarkCompleted(ctx, types.ModuleName, suite.chainB.ChainID, "test2") events = app.EventManagerKeeper.AllEvents(ctx) - suite.Equal(0, len(events)) + suite.Equal(preEvents, len(events)) } From 790e85cf7fade45d53158810cb12b5d09d3b321c Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 8 May 2024 14:47:17 +0100 Subject: [PATCH 12/14] fixy fixy --- x/eventmanager/keeper/events_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/eventmanager/keeper/events_test.go b/x/eventmanager/keeper/events_test.go index c12b248f6..ce8ad639d 100644 --- a/x/eventmanager/keeper/events_test.go +++ b/x/eventmanager/keeper/events_test.go @@ -177,7 +177,6 @@ func (suite *KeeperTestSuite) TestEventLifecycleWithCondition2() { events := app.EventManagerKeeper.AllEvents(ctx) - fmt.Println(events) suite.Equal(preEvents+3, len(events)) GlobalVar = 0 From d5b343d0bf4a29b17a148c5abfa570b81f7bde5d Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Mon, 13 May 2024 19:37:02 +0100 Subject: [PATCH 13/14] fix some tests WIP --- x/eventmanager/keeper/events.go | 17 ++- x/interchainstaking/keeper/callbacks_test.go | 106 ++++++++++-------- .../keeper/ibc_packet_handlers_test.go | 29 +++-- 3 files changed, 93 insertions(+), 59 deletions(-) diff --git a/x/eventmanager/keeper/events.go b/x/eventmanager/keeper/events.go index 958ed39ca..458777fc4 100644 --- a/x/eventmanager/keeper/events.go +++ b/x/eventmanager/keeper/events.go @@ -28,6 +28,17 @@ func (k Keeper) GetEvent(ctx sdk.Context, module, chainID, id string) (types.Eve return event, true } +func (k Keeper) GetEvents(ctx sdk.Context, module, chainID, prefix string) ([]types.Event, int) { + events := make([]types.Event, 0) + + k.IteratePrefixedEvents(ctx, []byte(module+chainID+prefix), func(index int64, event types.Event) (stop bool) { + events = append(events, event) + return false + }) + + return events, len(events) +} + // SetEvent set event. func (k Keeper) SetEvent(ctx sdk.Context, event types.Event) { key := GenerateEventKey(event.Module, event.ChainId, event.Identifier) @@ -71,12 +82,12 @@ func (k Keeper) IterateModuleChainEvents(ctx sdk.Context, module string, chainID // AllEvents returns every eventInfo in the store. func (k Keeper) AllEvents(ctx sdk.Context) []types.Event { - queries := []types.Event{} + events := []types.Event{} k.IteratePrefixedEvents(ctx, nil, func(_ int64, eventInfo types.Event) (stop bool) { - queries = append(queries, eventInfo) + events = append(events, eventInfo) return false }) - return queries + return events } func (k Keeper) MarkCompleted(ctx sdk.Context, module string, chainID string, identifier string) { diff --git a/x/interchainstaking/keeper/callbacks_test.go b/x/interchainstaking/keeper/callbacks_test.go index 04bb8af54..61cb57d88 100644 --- a/x/interchainstaking/keeper/callbacks_test.go +++ b/x/interchainstaking/keeper/callbacks_test.go @@ -2492,60 +2492,52 @@ func (suite *KeeperTestSuite) TestDepositLsmTxCallbackFailOnNonMatchingValidator func (suite *KeeperTestSuite) TestDelegationAccountBalancesCallback() { tcs := []struct { - Name string - PreviousBalance sdk.Coins - IncomingBalance sdk.Coins - ExpectedQueryCount int - ExpectedWaitgroup uint32 + Name string + PreviousBalance sdk.Coins + IncomingBalance sdk.Coins + ExpectedCount int }{ { - Name: "initial nil, incoming uqck", - PreviousBalance: sdk.NewCoins(), - IncomingBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - ExpectedQueryCount: 1, // uqck - ExpectedWaitgroup: 1, + Name: "initial nil, incoming uqck", + PreviousBalance: sdk.NewCoins(), + IncomingBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + ExpectedCount: 1, // uqck }, { - Name: "initial uqck, incoming uqck", - PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - IncomingBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - ExpectedQueryCount: 1, // uqck - ExpectedWaitgroup: 1, + Name: "initial uqck, incoming uqck", + PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + IncomingBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + ExpectedCount: 1, // uqck }, { - Name: "initial uqck, incoming lsm", - PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - IncomingBalance: sdk.NewCoins(sdk.NewCoin(addressutils.GenerateAddressForTestWithPrefix("cosmosvaloper")+"/1", sdk.NewInt(1))), - ExpectedQueryCount: 2, // uqck - ExpectedWaitgroup: 2, + Name: "initial uqck, incoming lsm", + PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + IncomingBalance: sdk.NewCoins(sdk.NewCoin(addressutils.GenerateAddressForTestWithPrefix("cosmosvaloper")+"/1", sdk.NewInt(1))), + ExpectedCount: 2, // uqck + lsm share }, { - Name: "initial uqck, incoming lsm + qck", - PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - IncomingBalance: sdk.NewCoins(sdk.NewCoin(addressutils.GenerateAddressForTestWithPrefix("cosmosvaloper")+"/1", sdk.NewInt(1)), sdk.NewCoin("uqck", sdk.NewInt(1))), - ExpectedQueryCount: 2, // uqck - ExpectedWaitgroup: 2, + Name: "initial uqck, incoming lsm + qck", + PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + IncomingBalance: sdk.NewCoins(sdk.NewCoin(addressutils.GenerateAddressForTestWithPrefix("cosmosvaloper")+"/1", sdk.NewInt(1)), sdk.NewCoin("uqck", sdk.NewInt(1))), + ExpectedCount: 2, // uqck + lsm share }, { - Name: "initial lsm, incoming uqck", - PreviousBalance: sdk.NewCoins(sdk.NewCoin(addressutils.GenerateAddressForTestWithPrefix("cosmosvaloper")+"/1", sdk.NewInt(1))), - IncomingBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - ExpectedQueryCount: 2, // uqck - ExpectedWaitgroup: 2, + Name: "initial lsm, incoming uqck", + PreviousBalance: sdk.NewCoins(sdk.NewCoin(addressutils.GenerateAddressForTestWithPrefix("cosmosvaloper")+"/1", sdk.NewInt(1))), + IncomingBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + ExpectedCount: 2, // uqck + lsm share }, { - Name: "initial uqck, incoming nil", - PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), - IncomingBalance: sdk.NewCoins(), - ExpectedQueryCount: 1, // uqck - ExpectedWaitgroup: 1, + Name: "initial uqck, incoming nil", + PreviousBalance: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(1))), + IncomingBalance: sdk.NewCoins(), + ExpectedCount: 1, // uqck }, { - Name: "initial nil, incoming nil", - PreviousBalance: sdk.NewCoins(), - IncomingBalance: sdk.NewCoins(), - ExpectedQueryCount: 0, // uqck - ExpectedWaitgroup: 0, + Name: "initial nil, incoming nil", + PreviousBalance: sdk.NewCoins(), + IncomingBalance: sdk.NewCoins(), + ExpectedCount: 0, }, } @@ -2576,8 +2568,9 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalancesCallback() { suite.Require().NoError(err) // refetch zone - zone, _ = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.Require().Equal(t.ExpectedWaitgroup, zone.GetWithdrawalWaitgroup()) + + _, count := app.EventManagerKeeper.GetEvents(ctx, icstypes.ModuleName, suite.chainB.ChainID, "query_delegationaccountbalance_epoch/") + suite.Equal(t.ExpectedCount, count) _, addr, err := bech32.DecodeAndConvert(zone.DelegationAddress.Address) suite.Require().NoError(err) @@ -2701,7 +2694,16 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallback() { ctx = suite.chainA.GetContext() zone, _ = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.Equal(uint32(5), zone.GetWithdrawalWaitgroup()) // initial 2 is reduced to 1, but incremented by 4 (4x delegation messages) == 5 + + _, found := app.EventManagerKeeper.GetEvent(ctx, icstypes.ModuleName, zone.ChainId, "query_delegationaccountbalance_epoch/uatom") + + suite.False(found) + + for _, valoperAddress := range app.InterchainstakingKeeper.GetValidatorAddresses(ctx, zone.ChainId) { + _, count := app.EventManagerKeeper.GetEvents(ctx, icstypes.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s", valoperAddress)) + suite.Equal(1, count) + } + suite.Equal(sdk.NewInt(500_000_000), zone.DelegationAddress.Balance.AmountOf("uatom")) }) } @@ -2735,7 +2737,14 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallbackLSM() { ctx = suite.chainA.GetContext() zone, _ = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.Equal(uint32(2), zone.GetWithdrawalWaitgroup()) // initial 2 is reduced to 1, but incremented by 1 (1x redeem token messages) == 2 + + _, found := app.EventManagerKeeper.GetEvent(ctx, icstypes.ModuleName, zone.ChainId, "query_delegationaccountbalance_epoch/uatom") + + suite.False(found) + + _, count := app.EventManagerKeeper.GetEvents(ctx, icstypes.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s", valOper)) + suite.Equal(1, count) + suite.Equal(sdk.NewInt(500), zone.DelegationAddress.Balance.AmountOf("uatom")) suite.Equal(sdk.NewInt(10), zone.DelegationAddress.Balance.AmountOf(denom)) }) @@ -2773,7 +2782,14 @@ func (suite *KeeperTestSuite) TestDelegationAccountBalanceCallbackLSMBadZone() { ctx = suite.chainA.GetContext() zone, _ = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.Equal(uint32(1), zone.GetWithdrawalWaitgroup()) // initial 2 is reduced to 1, and not incremented (no wg increment for sendToWithdrawal) + + _, found := app.EventManagerKeeper.GetEvent(ctx, icstypes.ModuleName, zone.ChainId, "query_delegationaccountbalance_epoch/uatom") + + suite.False(found) + + _, count := app.EventManagerKeeper.GetEvents(ctx, icstypes.ModuleName, zone.ChainId, fmt.Sprintf("delegation/%s", valOper)) + suite.Equal(0, count) + suite.Equal(sdk.NewInt(500), zone.DelegationAddress.Balance.AmountOf("uatom")) suite.Equal(sdk.NewInt(10), zone.DelegationAddress.Balance.AmountOf(denom)) suite.Equal(1, len(txk.Txs)) diff --git a/x/interchainstaking/keeper/ibc_packet_handlers_test.go b/x/interchainstaking/keeper/ibc_packet_handlers_test.go index 28a15bed9..295913999 100644 --- a/x/interchainstaking/keeper/ibc_packet_handlers_test.go +++ b/x/interchainstaking/keeper/ibc_packet_handlers_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "context" + "crypto/sha256" "errors" "fmt" "testing" @@ -31,6 +32,7 @@ import ( "github.com/quicksilver-zone/quicksilver/utils/addressutils" "github.com/quicksilver-zone/quicksilver/utils/randomutils" cmtypes "github.com/quicksilver-zone/quicksilver/x/claimsmanager/types" + emtypes "github.com/quicksilver-zone/quicksilver/x/eventmanager/types" "github.com/quicksilver-zone/quicksilver/x/interchainstaking/types" lsmstakingtypes "github.com/quicksilver-zone/quicksilver/x/lsmtypes" ) @@ -4825,13 +4827,15 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_Batch_OK() { vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} + hash := sha256.Sum256(msg.GetSignBytes()) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, fmt.Sprintf("delegation/%s/%x", msg.ValidatorAddress, hash), "", emtypes.EventTypeICADelegate, emtypes.EventStatusActive, nil, nil) + var msgMsg sdk.Msg = &msg err := app.InterchainstakingKeeper.HandleFailedDelegate(ctx, msgMsg, "batch/12345678") suite.NoError(err) - zone, found = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.True(found) - suite.Equal(uint32(99), zone.GetWithdrawalWaitgroup()) + _, count := app.EventManagerKeeper.GetEvents(ctx, types.ModuleName, suite.chainB.ChainID, fmt.Sprintf("delegation/%s/%x", msg.ValidatorAddress, hash)) + suite.Equal(0, count) } func (suite *KeeperTestSuite) TestHandleFailedDelegate_PerfAddress_OK() { @@ -4846,14 +4850,16 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_PerfAddress_OK() { vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: zone.PerformanceAddress.Address, ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} + + hash := sha256.Sum256(msg.GetSignBytes()) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, fmt.Sprintf("delegation/%s/%x", msg.ValidatorAddress, hash), "", emtypes.EventTypeICADelegate, emtypes.EventStatusActive, nil, nil) + var msgMsg sdk.Msg = &msg err := app.InterchainstakingKeeper.HandleFailedDelegate(ctx, msgMsg, "batch/12345678") suite.NoError(err) - zone, found = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.True(found) - // delegator was perf address, no change in waitgroup - suite.Equal(uint32(100), zone.GetWithdrawalWaitgroup()) + _, count := app.EventManagerKeeper.GetEvents(ctx, types.ModuleName, suite.chainB.ChainID, fmt.Sprintf("delegation/%s/%x", msg.ValidatorAddress, hash)) + suite.Equal(1, count) // performance delegation callback does not delete event (no event would be created in the first place) } func (suite *KeeperTestSuite) TestHandleFailedDelegate_NotBatch_OK() { @@ -4868,14 +4874,15 @@ func (suite *KeeperTestSuite) TestHandleFailedDelegate_NotBatch_OK() { vals := app.InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID) msg := stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: vals[0], Amount: sdk.NewCoin("uatom", sdk.NewInt(100))} + hash := sha256.Sum256(msg.GetSignBytes()) + app.EventManagerKeeper.AddEvent(ctx, types.ModuleName, suite.chainB.ChainID, fmt.Sprintf("delegation/%s/%x", msg.ValidatorAddress, hash), "", emtypes.EventTypeICADelegate, emtypes.EventStatusActive, nil, nil) + var msgMsg sdk.Msg = &msg err := app.InterchainstakingKeeper.HandleFailedDelegate(ctx, msgMsg, randomutils.GenerateRandomHashAsHex(32)) suite.NoError(err) - zone, found = app.InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID) - suite.True(found) - // memo was not a batch id, so don't decrement withdrawal wg - suite.Equal(uint32(100), zone.GetWithdrawalWaitgroup()) + _, count := app.EventManagerKeeper.GetEvents(ctx, types.ModuleName, suite.chainB.ChainID, fmt.Sprintf("delegation/%s/%x", msg.ValidatorAddress, hash)) + suite.Equal(0, count) } func (suite *KeeperTestSuite) TestHandleFailedDelegate_BatchTriggerRR_OK() { From 58c54c1375bdd2b1bd74904ed5bc238b5f4e72c7 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Wed, 22 May 2024 16:00:13 +0100 Subject: [PATCH 14/14] handle validator perf delegations per zone, to save iterating through zones again --- x/participationrewards/keeper/distribution.go | 9 -- x/participationrewards/keeper/events.go | 6 +- x/participationrewards/keeper/hooks.go | 92 +++++++++---------- .../keeper/rewards_validatorSelection.go | 46 +++++----- 4 files changed, 63 insertions(+), 90 deletions(-) diff --git a/x/participationrewards/keeper/distribution.go b/x/participationrewards/keeper/distribution.go index f72c09054..888a295fe 100644 --- a/x/participationrewards/keeper/distribution.go +++ b/x/participationrewards/keeper/distribution.go @@ -178,15 +178,6 @@ func (k *Keeper) CalcTokenValues(ctx sdk.Context) (TokenValues, error) { return tvs, nil } -// AllocateZoneRewards executes zone based rewards allocation. This entails -// rewards that are proportionally distributed to zones based on the tvl for -// each zone relative to the tvl of the QS protocol. -func (k *Keeper) AllocateZoneRewards(ctx sdk.Context, tvs TokenValues) error { - // <<--- move to callback - - return k.AllocateHoldingsRewards(ctx) // << -- move to callback -} - // SetZoneAllocations returns the proportional zone rewards allocations as a // map indexed by the zone id. func (k *Keeper) SetZoneAllocations(ctx sdk.Context, tvs TokenValues) error { diff --git a/x/participationrewards/keeper/events.go b/x/participationrewards/keeper/events.go index 70d0d2cb9..bef34a200 100644 --- a/x/participationrewards/keeper/events.go +++ b/x/participationrewards/keeper/events.go @@ -73,21 +73,17 @@ func CalculateTokenValues(k *Keeper, ctx sdk.Context, args []byte) error { return err } - k.QueryValidatorDelegationPerformance(ctx) - return nil } func SubmoduleHooks(k *Keeper, ctx sdk.Context, args []byte) error { for _, sub := range k.PrSubmodules { sub.Hooks(ctx, k) - } return nil } func DistributeParticipationRewards(k *Keeper, ctx sdk.Context, args []byte) error { - // calculate, based on latest token values - // allocation based on calculations + k.AllocateHoldingsRewards(ctx) return nil } diff --git a/x/participationrewards/keeper/hooks.go b/x/participationrewards/keeper/hooks.go index 96b94bf06..64036de61 100644 --- a/x/participationrewards/keeper/hooks.go +++ b/x/participationrewards/keeper/hooks.go @@ -28,6 +28,7 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ int64) iConnectionData, err := types.UnmarshalProtocolData(types.ProtocolDataTypeConnection, data.Data) if err != nil { k.Logger(ctx).Error("Error unmarshalling protocol data") + return false } connectionData, _ := iConnectionData.(*types.ConnectionProtocolData) if connectionData.ChainID == ctx.ChainID() { @@ -50,85 +51,74 @@ func (k *Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ int64) return false }) - condition, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "get_epoch_height", emtypes.FieldOperator_EQUAL, true)), false) + k.icsKeeper.IterateZones(ctx, func(index int64, zone *icstypes.Zone) (stop bool) { + // ensure we archive claims before we return! + k.ClaimsManagerKeeper.ArchiveAndGarbageCollectClaims(ctx, zone.ChainId) + // send validator performance query + k.QueryValidatorDelegationPerformance(ctx, zone) + return false + }) + + k.Logger(ctx).Info("setting self connection data...") + err := k.UpdateSelfConnectionData(ctx) if err != nil { panic(err) } - // add event to ensure submodule hooks are called when the get_epoch_height calls have returned. - k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "submodules", Submodules, emtypes.EventTypeSubmodules, emtypes.EventStatusPending, condition, nil) + k.Logger(ctx).Info("allocate participation rewards...") - k.Logger(ctx).Info("setting self connection data...") - err = k.UpdateSelfConnectionData(ctx) + // determine allocations splits the balance of the module between holding/usage and validatorSelection rewards. + err = k.DetermineAllocations( + ctx, + k.GetModuleBalance(ctx), + k.GetParams(ctx).DistributionProportions, + ) if err != nil { - panic(err) + k.Logger(ctx).Error(err.Error()) } - condition2, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "submodule", emtypes.FieldOperator_BEGINSWITH, true)), false) + conditionGetEpochHeight, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "get_epoch_height", emtypes.FieldOperator_EQUAL, true)), false) if err != nil { panic(err) } - conditionAnd, err := emtypes.NewConditionAnd(ctx, condition, condition2) + conditionValidatorPerformance, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "validator_performance", emtypes.FieldOperator_EQUAL, true)), false) if err != nil { panic(err) } - k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "calc_tokens", CalculateValues, emtypes.EventTypeCalculateTvls, emtypes.EventStatusPending, conditionAnd, nil) - condition3, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "calc_tokens", emtypes.FieldOperator_EQUAL, true)), false) + conditionSubmodulePre, err := emtypes.NewConditionAnd(ctx, conditionGetEpochHeight, conditionValidatorPerformance) if err != nil { panic(err) } - conditionAnd2, err := emtypes.NewConditionAnd(ctx, conditionAnd, condition3) + + // add event to ensure submodule hooks are called when the validator_performance and get_epoch_height calls have returned. + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "submodules", Submodules, emtypes.EventTypeSubmodules, emtypes.EventStatusPending, conditionSubmodulePre, nil) + + conditionSubmoduleComplete, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "submodule", emtypes.FieldOperator_BEGINSWITH, true)), false) if err != nil { panic(err) } - k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "distribute_rewards", DistributeRewards, emtypes.EventTypeDistributeRewards, emtypes.EventStatusPending, conditionAnd2, nil) - - // ensure we archive claims before we return! - k.icsKeeper.IterateZones(ctx, func(index int64, zone *icstypes.Zone) (stop bool) { - k.ClaimsManagerKeeper.ArchiveAndGarbageCollectClaims(ctx, zone.ChainId) - return false - }) - - // ascertain validator scores... - - // tvs, err := k.CalcTokenValues(ctx) - // if err != nil { - // k.Logger(ctx).Error("unable to calculate token values", "error", err.Error()) - // return nil - // } - // if allocation == nil { - // // if allocation is unset, then return early to avoid panic - // k.Logger(ctx).Error("nil allocation") - // return nil - // } - - k.Logger(ctx).Info("distribute participation rewards...") + conditionCalcTokensPre, err := emtypes.NewConditionAnd(ctx, conditionSubmodulePre, conditionSubmoduleComplete) + if err != nil { + panic(err) + } + // add calc_tokens event to be triggered on satisfaction of all submodule*, validator_performance, and get_epoch_height calls events. + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "calc_tokens", CalculateValues, emtypes.EventTypeCalculateTvls, emtypes.EventStatusPending, conditionCalcTokensPre, nil) - err = k.DetermineAllocations( - ctx, - k.GetModuleBalance(ctx), - k.GetParams(ctx).DistributionProportions, - ) + conditionCalcTokensComplete, err := emtypes.NewConditionAll(ctx, emtypes.NewFieldValues(emtypes.NewFieldValue(emtypes.FieldIdentifier, "calc_tokens", emtypes.FieldOperator_EQUAL, true)), false) if err != nil { - k.Logger(ctx).Error(err.Error()) + panic(err) + } + conditionDistributeRewardsPre, err := emtypes.NewConditionAnd(ctx, conditionCalcTokensPre, conditionCalcTokensComplete) + if err != nil { + panic(err) } - // if err := k.AllocateZoneRewards(ctx, tvs, *allocation); err != nil { // split into calculate a - // k.Logger(ctx).Error("unable to allocate: tvl is zero", "error", err.Error()) - // return nil - // } + // add distribute_rewards event to trigger on completion of get_epoch_height, validator_performance, submodule* and calc_token events. + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, "", "distribute_rewards", DistributeRewards, emtypes.EventTypeDistributeRewards, emtypes.EventStatusPending, conditionDistributeRewardsPre, nil) - // TODO: remove 'lockup' allocation logic. - // if !allocation.Lockup.IsZero() { - // // at genesis lockup will be disabled, and enabled when ICS is used. - // if err := k.AllocateLockupRewards(ctx, allocation.Lockup); err != nil { - // k.Logger(ctx).Error(err.Error()) - // return err - // } - // } return nil } diff --git a/x/participationrewards/keeper/rewards_validatorSelection.go b/x/participationrewards/keeper/rewards_validatorSelection.go index 852d70106..d21d5644e 100644 --- a/x/participationrewards/keeper/rewards_validatorSelection.go +++ b/x/participationrewards/keeper/rewards_validatorSelection.go @@ -20,31 +20,27 @@ import ( // rewards account for each zone to determine validator performance and // corresponding rewards allocations. Each zone's response is dealt with // individually in a callback. -func (k Keeper) QueryValidatorDelegationPerformance(ctx sdk.Context) { - k.icsKeeper.IterateZones(ctx, func(_ int64, zone *icstypes.Zone) (stop bool) { - if zone.PerformanceAddress != nil { - k.Logger(ctx).Info("zones", "chain_id", zone.ChainId, "performance address", zone.PerformanceAddress.Address) - - // obtain zone performance account rewards - rewardsQuery := distrtypes.QueryDelegationTotalRewardsRequest{DelegatorAddress: zone.PerformanceAddress.Address} - bz := k.cdc.MustMarshal(&rewardsQuery) - - k.IcqKeeper.MakeRequest( - ctx, - zone.ConnectionId, - zone.ChainId, - "cosmos.distribution.v1beta1.Query/DelegationTotalRewards", - bz, - sdk.NewInt(-1), - types.ModuleName, - ValidatorSelectionRewardsCallbackID, - 0, - ) - - k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, zone.ChainId, "validator_performance", "", emtypes.EventTypeICQQueryDelegations, emtypes.EventStatusActive, nil, nil) - } - return false - }) +func (k Keeper) QueryValidatorDelegationPerformance(ctx sdk.Context, zone *icstypes.Zone) { + if zone.PerformanceAddress != nil { + k.Logger(ctx).Info("zones", "chain_id", zone.ChainId, "performance address", zone.PerformanceAddress.Address) + + // obtain zone performance account rewards + rewardsQuery := distrtypes.QueryDelegationTotalRewardsRequest{DelegatorAddress: zone.PerformanceAddress.Address} + bz := k.cdc.MustMarshal(&rewardsQuery) + + k.IcqKeeper.MakeRequest( + ctx, + zone.ConnectionId, + zone.ChainId, + "cosmos.distribution.v1beta1.Query/DelegationTotalRewards", + bz, + sdk.NewInt(-1), + types.ModuleName, + ValidatorSelectionRewardsCallbackID, + 0, + ) + k.EventManagerKeeper.AddEvent(ctx, types.ModuleName, zone.ChainId, "validator_performance", "", emtypes.EventTypeICQQueryDelegations, emtypes.EventStatusActive, nil, nil) + } } // getZoneScores returns an instance of zoneScore containing the calculated