From 4e50842f46bc2e03ba76b458009fd50af7521227 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 7 Feb 2024 17:31:44 +0200 Subject: [PATCH 01/64] CNS-866: make pool methods support all denoms --- x/rewards/keeper/grpc_query_block_reward.go | 2 +- x/rewards/keeper/grpc_query_pools.go | 8 +++---- x/rewards/keeper/helpers_test.go | 2 +- x/rewards/keeper/pool.go | 8 +++---- x/rewards/keeper/pool_test.go | 24 ++++++++++----------- x/rewards/keeper/providers.go | 2 +- x/rewards/keeper/providers_test.go | 12 +++++------ x/rewards/keeper/rewards.go | 12 +++++------ 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/x/rewards/keeper/grpc_query_block_reward.go b/x/rewards/keeper/grpc_query_block_reward.go index fdb5b61934..b00516edb9 100644 --- a/x/rewards/keeper/grpc_query_block_reward.go +++ b/x/rewards/keeper/grpc_query_block_reward.go @@ -23,7 +23,7 @@ func (k Keeper) BlockReward(goCtx context.Context, req *types.QueryBlockRewardRe blocksToNextTimerExpiry := k.BlocksToNextTimerExpiry(ctx) // get validator block pool balance - blockPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName) + blockPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx)) if blocksToNextTimerExpiry == 0 { return nil, utils.LavaFormatWarning("blocksToNextTimerExpiry is zero", fmt.Errorf("critical: Attempt to divide by zero"), utils.LogAttr("blocksToNextTimerExpiry", blocksToNextTimerExpiry), diff --git a/x/rewards/keeper/grpc_query_pools.go b/x/rewards/keeper/grpc_query_pools.go index acf521b94e..de14e08aa5 100644 --- a/x/rewards/keeper/grpc_query_pools.go +++ b/x/rewards/keeper/grpc_query_pools.go @@ -19,19 +19,19 @@ func (k Keeper) Pools(goCtx context.Context, req *types.QueryPoolsRequest) (*typ pools := []types.PoolInfo{ { Name: string(types.ValidatorsRewardsDistributionPoolName), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName)), + Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx))), }, { Name: string(types.ValidatorsRewardsAllocationPoolName), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ValidatorsRewardsAllocationPoolName)), + Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ValidatorsRewardsAllocationPoolName, k.stakingKeeper.BondDenom(ctx))), }, { Name: string(types.ProviderRewardsDistributionPool), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool)), + Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool, k.stakingKeeper.BondDenom(ctx))), }, { Name: string(types.ProvidersRewardsAllocationPool), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ProvidersRewardsAllocationPool)), + Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ProvidersRewardsAllocationPool, k.stakingKeeper.BondDenom(ctx))), }, } diff --git a/x/rewards/keeper/helpers_test.go b/x/rewards/keeper/helpers_test.go index a0b5f3b793..0b34692451 100644 --- a/x/rewards/keeper/helpers_test.go +++ b/x/rewards/keeper/helpers_test.go @@ -39,7 +39,7 @@ func newTester(t *testing.T, addValidator bool) *tester { } ts.plan = common.CreateMockPlan() - monthlyProvidersPool := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardsTypes.ProviderRewardsDistributionPool) + monthlyProvidersPool := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardsTypes.ProviderRewardsDistributionPool, ts.BondDenom()) ts.plan.Price.Amount = monthlyProvidersPool.QuoRaw(5).AddRaw(5) ts.plan.PlanPolicy.EpochCuLimit = monthlyProvidersPool.Uint64() * 5 ts.plan.PlanPolicy.TotalCuLimit = monthlyProvidersPool.Uint64() * 5 diff --git a/x/rewards/keeper/pool.go b/x/rewards/keeper/pool.go index 5797a4f66d..01b1ba8252 100644 --- a/x/rewards/keeper/pool.go +++ b/x/rewards/keeper/pool.go @@ -8,19 +8,19 @@ import ( ) // TotalPoolTokens gets the total tokens supply from a pool -func (k Keeper) TotalPoolTokens(ctx sdk.Context, pool types.Pool) math.Int { +func (k Keeper) TotalPoolTokens(ctx sdk.Context, pool types.Pool, denom string) math.Int { poolAddr := k.accountKeeper.GetModuleAddress(string(pool)) - return k.bankKeeper.GetBalance(ctx, poolAddr, k.stakingKeeper.BondDenom(ctx)).Amount + return k.bankKeeper.GetBalance(ctx, poolAddr, denom).Amount } // BurnPoolTokens removes coins from a pool module account -func (k Keeper) BurnPoolTokens(ctx sdk.Context, pool types.Pool, amt math.Int) error { +func (k Keeper) BurnPoolTokens(ctx sdk.Context, pool types.Pool, amt math.Int, denom string) error { if !amt.IsPositive() { // skip as no coins need to be burned return nil } - coins := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), amt)) + coins := sdk.NewCoins(sdk.NewCoin(denom, amt)) return k.bankKeeper.BurnCoins(ctx, string(pool), coins) } diff --git a/x/rewards/keeper/pool_test.go b/x/rewards/keeper/pool_test.go index 26c5f826a6..f3656aa49e 100644 --- a/x/rewards/keeper/pool_test.go +++ b/x/rewards/keeper/pool_test.go @@ -78,7 +78,7 @@ func TestRewardsModuleSetup(t *testing.T) { func TestBurnRateParam(t *testing.T) { ts := newTester(t, true) lifetime := int64(types.RewardsAllocationPoolsLifetime) - allocPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName).Int64() + allocPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()).Int64() // advance a month to trigger monthly pool refill callback // to see why these 3 are called, see general note 2 @@ -90,7 +90,7 @@ func TestBurnRateParam(t *testing.T) { // default burn rate = 1, distribution pool's old balance should be wiped // current balance should be exactly the expected monthly quota minus block reward expectedMonthlyQuota := allocPoolBalance / (lifetime - 1) - distPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName).Int64() + distPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() require.Equal(t, expectedMonthlyQuota, distPoolBalance) // change the burn rate param to be zero @@ -105,12 +105,12 @@ func TestBurnRateParam(t *testing.T) { resp, err = ts.QueryRewardsPools() require.NoError(t, err) ts.AdvanceBlock(time.Duration(resp.TimeToRefill) * time.Second) - prevDistPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName).Int64() + prevDistPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() testkeeper.EndBlock(ts.Ctx, ts.Keepers) // burn rate = 0, distribution pool's old balance should not be wiped // current balance should be previous balance (minus block reward) plus new quota - distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName).Int64() + distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() require.Equal(t, prevDistPoolBalance+expectedMonthlyQuota, distPoolBalance) } @@ -125,11 +125,11 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { // calc expectedMonthlyQuota. Check that it was subtracted from the allocation pool and added // to the distribution pool (its balance should be the monthly quota minus the fee collector's balance) expectedMonthlyQuota := allocationPoolBalance / lifetime - currentAllocPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName) + currentAllocPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) require.Equal(t, expectedMonthlyQuota, allocationPoolBalance-currentAllocPoolBalance.Int64()) feeCollectorBalance := ts.GetBalance(ts.feeCollector()) - currentDistPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName) + currentDistPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) require.Equal(t, expectedMonthlyQuota, feeCollectorBalance+currentDistPoolBalance.Int64()) // check the monthly quota is as expected with advancement of months @@ -141,7 +141,7 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { monthsLeft := ts.Keepers.Rewards.AllocationPoolMonthsLeft(ts.Ctx) prevAllocPoolBalance := currentAllocPoolBalance - currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName) + currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) var monthlyQuota int64 if monthsLeft != 0 { @@ -160,7 +160,7 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { ts.AdvanceMonths(1) ts.AdvanceBlock() testkeeper.EndBlock(ts.Ctx, ts.Keepers) - currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName) + currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) require.True(t, currentAllocPoolBalance.IsZero()) // advance another month to distribute the last quota to the fee collector @@ -174,7 +174,7 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { ts.AdvanceBlock() testkeeper.EndBlock(ts.Ctx, ts.Keepers) - currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName) + currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) require.True(t, currentAllocPoolBalance.IsZero()) currentFeeCollectorBalance := ts.GetBalance(ts.feeCollector()) @@ -212,7 +212,7 @@ func TestValidatorBlockRewards(t *testing.T) { res, err := ts.QueryRewardsBlockReward() require.NoError(t, err) blockReward := res.Reward.Amount - distPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName) + distPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) blocksToNextExpiry := ts.Keepers.Rewards.BlocksToNextTimerExpiry(ts.Ctx) bondedTargetFactor := sdk.OneDec().MulInt(blockReward).MulInt64(blocksToNextExpiry).QuoInt(distPoolBalance).TruncateInt() require.True(t, bondedTargetFactor.Equal(expectedBondedTargetFactor)) @@ -228,7 +228,7 @@ func TestValidatorBlockRewards(t *testing.T) { blockReward = res.Reward.Amount // transfer half of the total distribution pool balance to the allocation pool - distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName) + distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) err = ts.Keepers.BankKeeper.SendCoinsFromModuleToModule( ts.Ctx, string(types.ValidatorsRewardsDistributionPoolName), @@ -263,7 +263,7 @@ func TestValidatorBlockRewards(t *testing.T) { require.NoError(t, err) blockReward = res.Reward.Amount bondedTargetFactor = ts.Keepers.Rewards.BondedTargetFactor(ts.Ctx).TruncateInt() - distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName) + distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) blocksToNextExpiry = bondedTargetFactor.Mul(distPoolBalance).Quo(blockReward).Int64() require.Equal(t, refBlocksToExpiry, blocksToNextExpiry) } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 3f9d160a18..6abec4d264 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -30,7 +30,7 @@ func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adju // Distribute bonus rewards to providers across all chains based on performance func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { details := map[string]string{} - total := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool) + total := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool, k.stakingKeeper.BondDenom(ctx)) totalRewarded := sdk.ZeroInt() // specs emissions from the total reward pool base on stake specs := k.specEmissionParts(ctx) diff --git a/x/rewards/keeper/providers_test.go b/x/rewards/keeper/providers_test.go index 175824c95b..5e889e227d 100644 --- a/x/rewards/keeper/providers_test.go +++ b/x/rewards/keeper/providers_test.go @@ -124,7 +124,7 @@ func TestSpecAllocationProvidersRewards(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool) + distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") @@ -172,7 +172,7 @@ func TestProvidersDiminishingRewards(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool) + distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") @@ -280,7 +280,7 @@ func Test2SpecsZeroShares(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool) + distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") @@ -414,7 +414,7 @@ func TestBonusRewards3Providers(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool) + distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res1, err := ts.QueryDualstakingDelegatorRewards(providerAcc1.Addr.String(), "", "") @@ -596,7 +596,7 @@ func TestBonusRewardsEquall5Providers(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool) + distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() for _, providerAcc := range providerAccs { @@ -663,7 +663,7 @@ func TestBonusRewards5Providers(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool) + distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() // distribution pool divided between all providers (5) equally (they served the same amount of CU in total) diff --git a/x/rewards/keeper/rewards.go b/x/rewards/keeper/rewards.go index 00fdee330e..4d696b42e3 100644 --- a/x/rewards/keeper/rewards.go +++ b/x/rewards/keeper/rewards.go @@ -20,7 +20,7 @@ func (k Keeper) DistributeBlockReward(ctx sdk.Context) { blocksToNextTimerExpiry := k.BlocksToNextTimerExpiry(ctx) // get validator distribution pool balance - distributionPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName) + distributionPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx)) if blocksToNextTimerExpiry == 0 { utils.LavaFormatWarning("blocksToNextTimerExpiry is zero", fmt.Errorf("critical: Attempt to divide by zero"), @@ -84,8 +84,8 @@ func (k Keeper) RefillRewardsPools(ctx sdk.Context, _ []byte, data []byte) { nextMonth := utils.NextMonth(ctx.BlockTime()).UTC() k.refillRewardsPoolTS.AddTimerByBlockTime(ctx, uint64(nextMonth.Unix()), []byte(types.RefillRewardsPoolTimerName), monthsLeftBytes) - valDistPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName).Int64() - providerDistPoolBalance := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool).Int64() + valDistPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx)).Int64() + providerDistPoolBalance := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool, k.stakingKeeper.BondDenom(ctx)).Int64() nextRefillBlock := k.blocksToNextTimerExpiry(ctx, nextMonth.Unix()-ctx.BlockTime().UTC().Unix()) + ctx.BlockHeight() details := map[string]string{ "allocation_pool_remaining_lifetime": strconv.FormatUint(monthsLeft, 10), @@ -101,8 +101,8 @@ func (k Keeper) RefillRewardsPools(ctx sdk.Context, _ []byte, data []byte) { func (k Keeper) refillDistributionPool(ctx sdk.Context, monthsLeft uint64, allocationPool types.Pool, distributionPool types.Pool, burnRate sdkmath.LegacyDec) { // burn remaining tokens in the distribution pool - tokensToBurn := burnRate.MulInt(k.TotalPoolTokens(ctx, distributionPool)).TruncateInt() - err := k.BurnPoolTokens(ctx, distributionPool, tokensToBurn) + tokensToBurn := burnRate.MulInt(k.TotalPoolTokens(ctx, distributionPool, k.stakingKeeper.BondDenom(ctx))).TruncateInt() + err := k.BurnPoolTokens(ctx, distributionPool, tokensToBurn, k.stakingKeeper.BondDenom(ctx)) if err != nil { utils.LavaFormatError("critical - could not burn distribution pool tokens", err, utils.Attribute{Key: "distribution_pool", Value: string(distributionPool)}, @@ -111,7 +111,7 @@ func (k Keeper) refillDistributionPool(ctx sdk.Context, monthsLeft uint64, alloc } // transfer the new monthly quota (if allocation pool is expired, rewards=0) - allocPoolBalance := k.TotalPoolTokens(ctx, allocationPool) + allocPoolBalance := k.TotalPoolTokens(ctx, allocationPool, k.stakingKeeper.BondDenom(ctx)) if monthsLeft != 0 && !allocPoolBalance.IsZero() { monthlyQuota := sdk.Coin{Denom: k.stakingKeeper.BondDenom(ctx), Amount: allocPoolBalance.QuoRaw(int64(monthsLeft))} From c0d1cd99b40322afe8a4a4e39b1737fee59aa478 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 7 Feb 2024 18:49:46 +0200 Subject: [PATCH 02/64] CNS-868: scaffold map iprpc subscriptions --- proto/lavanet/lava/rewards/genesis.proto | 1 + x/rewards/genesis.go | 6 +- x/rewards/keeper/iprpc_data.go | 41 +++ x/rewards/keeper/iprpc_data_test.go | 51 ++++ x/rewards/types/genesis.go | 15 +- x/rewards/types/genesis.pb.go | 101 +++++-- x/rewards/types/genesis_test.go | 11 + x/rewards/types/iprpc.pb.go | 319 +++++++++++++++++++++++ x/rewards/types/keys.go | 3 + 9 files changed, 522 insertions(+), 26 deletions(-) create mode 100644 x/rewards/keeper/iprpc_data.go create mode 100644 x/rewards/keeper/iprpc_data_test.go create mode 100644 x/rewards/types/iprpc.pb.go diff --git a/proto/lavanet/lava/rewards/genesis.proto b/proto/lavanet/lava/rewards/genesis.proto index d18d83e2fc..b29f69bc59 100644 --- a/proto/lavanet/lava/rewards/genesis.proto +++ b/proto/lavanet/lava/rewards/genesis.proto @@ -14,5 +14,6 @@ message GenesisState { Params params = 1 [(gogoproto.nullable) = false]; lavanet.lava.timerstore.GenesisState refillRewardsTS = 2 [(gogoproto.nullable) = false]; repeated BasePayGenesis base_pays = 3 [(gogoproto.nullable) = false]; + repeated string iprpc_subscriptions = 4 [(gogoproto.nullable) = false]; // this line is used by starport scaffolding # genesis/proto/state } \ No newline at end of file diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index 81934f3d5b..fada13f0c2 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -19,6 +19,10 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) if len(genState.RefillRewardsTS.TimeEntries) == 0 { k.RefillRewardsPools(ctx, nil, nil) } + + for _, sub := range genState.IprpcSubscriptions { + k.SetIprpcSubscription(ctx, sub) + } } // ExportGenesis returns the capability module's exported genesis. @@ -27,7 +31,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.Params = k.GetParams(ctx) genesis.RefillRewardsTS = k.ExportRewardsRefillTS(ctx) genesis.BasePays = k.GetAllBasePay(ctx) - + genesis.IprpcSubscriptions = k.GetAllIprpcSubscription(ctx) // this line is used by starport scaffolding # genesis/module/export return genesis diff --git a/x/rewards/keeper/iprpc_data.go b/x/rewards/keeper/iprpc_data.go new file mode 100644 index 0000000000..e81fa17b06 --- /dev/null +++ b/x/rewards/keeper/iprpc_data.go @@ -0,0 +1,41 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/rewards/types" +) + +// SetIprpcSubscription set a subscription in the IprpcSubscription store +func (k Keeper) SetIprpcSubscription(ctx sdk.Context, address string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcSubscriptionPrefix)) + store.Set([]byte(address), []byte{}) +} + +// IsIprpcSubscription checks whether a subscription is IPRPC eligible subscription +func (k Keeper) IsIprpcSubscription(ctx sdk.Context, address string) bool { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcSubscriptionPrefix)) + b := store.Get([]byte(address)) + return b != nil +} + +// RemoveIprpcSubscription removes a subscription from the IprpcSubscription store +func (k Keeper) RemoveIprpcSubscription(ctx sdk.Context, address string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcSubscriptionPrefix)) + store.Delete([]byte(address)) +} + +// GetAllIprpcSubscription returns all subscription from the IprpcSubscription store +func (k Keeper) GetAllIprpcSubscription(ctx sdk.Context) []string { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcSubscriptionPrefix)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + list := []string{} + for ; iterator.Valid(); iterator.Next() { + list = append(list, string(iterator.Key())) + } + + return list +} diff --git a/x/rewards/keeper/iprpc_data_test.go b/x/rewards/keeper/iprpc_data_test.go new file mode 100644 index 0000000000..bc2435d9d1 --- /dev/null +++ b/x/rewards/keeper/iprpc_data_test.go @@ -0,0 +1,51 @@ +package keeper_test + +import ( + "strconv" + "testing" + + keepertest "github.com/lavanet/lava/testutil/keeper" + "github.com/lavanet/lava/testutil/nullify" + "github.com/lavanet/lava/x/rewards/keeper" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +// Prevent strconv unused error +var _ = strconv.IntSize + +func createNIprpcSubscriptions(keeper *keeper.Keeper, ctx sdk.Context, n int) []string { + items := make([]string, n) + for i := range items { + items[i] = strconv.Itoa(i) + keeper.SetIprpcSubscription(ctx, items[i]) + } + return items +} + +func TestIprpcSubscriptionsGet(t *testing.T) { + keeper, ctx := keepertest.RewardsKeeper(t) + items := createNIprpcSubscriptions(keeper, ctx, 10) + for _, item := range items { + require.True(t, keeper.IsIprpcSubscription(ctx, item)) + } +} + +func TestIprpcSubscriptionsRemove(t *testing.T) { + keeper, ctx := keepertest.RewardsKeeper(t) + items := createNIprpcSubscriptions(keeper, ctx, 10) + for _, item := range items { + keeper.RemoveIprpcSubscription(ctx, item) + require.False(t, keeper.IsIprpcSubscription(ctx, item)) + } +} + +func TestIprpcSubscriptionsGetAll(t *testing.T) { + keeper, ctx := keepertest.RewardsKeeper(t) + items := createNIprpcSubscriptions(keeper, ctx, 10) + require.ElementsMatch(t, + nullify.Fill(items), + nullify.Fill(keeper.GetAllIprpcSubscription(ctx)), + ) +} diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index cb790d62c0..4d6584f7bc 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -3,6 +3,7 @@ package types import ( fmt "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/lavanet/lava/x/timerstore/types" ) @@ -15,9 +16,10 @@ const DefaultIndex uint64 = 1 func DefaultGenesis() *GenesisState { return &GenesisState{ // this line is used by starport scaffolding # genesis/types/default - Params: DefaultParams(), - RefillRewardsTS: *types.DefaultGenesis(), - BasePays: []BasePayGenesis{}, + Params: DefaultParams(), + RefillRewardsTS: *types.DefaultGenesis(), + BasePays: []BasePayGenesis{}, + IprpcSubscriptions: []string{}, } } @@ -31,5 +33,12 @@ func (gs GenesisState) Validate() error { at all times. amount of timers found: %v`, len(timeEntries)) } + for _, sub := range gs.IprpcSubscriptions { + _, err := sdk.AccAddressFromBech32(sub) + if err != nil { + return fmt.Errorf("invalid subscription address. err: %s", err.Error()) + } + } + return gs.Params.Validate() } diff --git a/x/rewards/types/genesis.pb.go b/x/rewards/types/genesis.pb.go index 85de155d9f..3ae410863b 100644 --- a/x/rewards/types/genesis.pb.go +++ b/x/rewards/types/genesis.pb.go @@ -26,9 +26,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the rewards module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - RefillRewardsTS types.GenesisState `protobuf:"bytes,2,opt,name=refillRewardsTS,proto3" json:"refillRewardsTS"` - BasePays []BasePayGenesis `protobuf:"bytes,3,rep,name=base_pays,json=basePays,proto3" json:"base_pays"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + RefillRewardsTS types.GenesisState `protobuf:"bytes,2,opt,name=refillRewardsTS,proto3" json:"refillRewardsTS"` + BasePays []BasePayGenesis `protobuf:"bytes,3,rep,name=base_pays,json=basePays,proto3" json:"base_pays"` + IprpcSubscriptions []string `protobuf:"bytes,4,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -85,6 +86,13 @@ func (m *GenesisState) GetBasePays() []BasePayGenesis { return nil } +func (m *GenesisState) GetIprpcSubscriptions() []string { + if m != nil { + return m.IprpcSubscriptions + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "lavanet.lava.rewards.GenesisState") } @@ -94,25 +102,27 @@ func init() { } var fileDescriptor_02c24f4df31ca14e = []byte{ - // 287 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xca, 0x49, 0x2c, 0x4b, - 0xcc, 0x4b, 0x2d, 0xd1, 0x07, 0xd1, 0xfa, 0x45, 0xa9, 0xe5, 0x89, 0x45, 0x29, 0xc5, 0xfa, 0xe9, - 0xa9, 0x79, 0xa9, 0xc5, 0x99, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x22, 0x50, 0x35, - 0x7a, 0x20, 0x5a, 0x0f, 0xaa, 0x46, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xac, 0x40, 0x1f, 0xc4, - 0x82, 0xa8, 0x95, 0x52, 0xc4, 0x6a, 0x5e, 0x41, 0x62, 0x51, 0x62, 0x2e, 0xd4, 0x38, 0x29, 0x65, - 0xac, 0x4a, 0x92, 0x12, 0x8b, 0x53, 0xe3, 0x0b, 0x12, 0x2b, 0xb1, 0x2a, 0x2a, 0xc9, 0xcc, 0x4d, - 0x2d, 0x2a, 0x2e, 0xc9, 0x2f, 0x4a, 0x85, 0x30, 0x21, 0x8a, 0x94, 0x5e, 0x31, 0x72, 0xf1, 0xb8, - 0x43, 0x9c, 0x1a, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0x64, 0xc5, 0xc5, 0x06, 0xb1, 0x4a, 0x82, 0x51, - 0x81, 0x51, 0x83, 0xdb, 0x48, 0x46, 0x0f, 0x9b, 0xd3, 0xf5, 0x02, 0xc0, 0x6a, 0x9c, 0x58, 0x4e, - 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x10, 0x0a, 0xe5, 0xe2, 0x2f, 0x4a, 0x4d, 0xcb, 0xcc, 0xc9, - 0x09, 0x82, 0xa8, 0x0a, 0x09, 0x96, 0x60, 0x02, 0x1b, 0xa2, 0x8a, 0x6a, 0x08, 0xc2, 0x2d, 0x7a, - 0xc8, 0x76, 0x43, 0x4d, 0x43, 0x37, 0x43, 0xc8, 0x9d, 0x8b, 0x13, 0xe6, 0xb5, 0x62, 0x09, 0x66, - 0x05, 0x66, 0x0d, 0x6e, 0x23, 0x15, 0xec, 0xae, 0x72, 0x4a, 0x2c, 0x4e, 0x0d, 0x48, 0xac, 0x84, - 0x1a, 0x0a, 0x35, 0x8f, 0x23, 0x09, 0x22, 0x5a, 0xec, 0xe4, 0x78, 0xe2, 0x91, 0x1c, 0xe3, 0x85, - 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, - 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xea, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, - 0xfa, 0x28, 0xc1, 0x56, 0x01, 0x0f, 0xdd, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0x70, 0xb0, - 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x63, 0x4e, 0xb8, 0x2a, 0xf5, 0x01, 0x00, 0x00, + // 320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x41, 0x4f, 0xc2, 0x30, + 0x14, 0xc7, 0x37, 0x20, 0x44, 0x8a, 0x89, 0x49, 0xe5, 0xb0, 0x10, 0x53, 0x11, 0x35, 0x72, 0xea, + 0x12, 0x8c, 0x17, 0x6f, 0x72, 0xe1, 0x4a, 0x40, 0x2f, 0x5e, 0x48, 0x87, 0x75, 0x36, 0x01, 0xda, + 0xf4, 0x15, 0x75, 0xdf, 0xc2, 0xaf, 0xe0, 0xb7, 0xe1, 0xc8, 0xd1, 0x93, 0x31, 0xdb, 0x17, 0x31, + 0x5b, 0xab, 0x82, 0xd9, 0xe9, 0xbd, 0x6c, 0xbf, 0xfe, 0xde, 0xbf, 0xaf, 0xa8, 0x3b, 0x67, 0xcf, + 0x6c, 0xc9, 0x4d, 0x98, 0xd7, 0x50, 0xf3, 0x17, 0xa6, 0x1f, 0x20, 0x8c, 0xf9, 0x92, 0x83, 0x00, + 0xaa, 0xb4, 0x34, 0x12, 0xb7, 0x1c, 0x43, 0xf3, 0x4a, 0x1d, 0xd3, 0x6e, 0xc5, 0x32, 0x96, 0x05, + 0x10, 0xe6, 0x9d, 0x65, 0xdb, 0x27, 0xa5, 0x3e, 0xc5, 0x34, 0x5b, 0x38, 0x5d, 0xfb, 0xb4, 0x14, + 0x89, 0x18, 0xf0, 0xa9, 0x62, 0x49, 0x29, 0x64, 0xc4, 0x82, 0x6b, 0x30, 0x52, 0x73, 0xdb, 0x5a, + 0xa8, 0xfb, 0x5e, 0x41, 0xfb, 0x43, 0x1b, 0x75, 0x62, 0x98, 0xe1, 0xf8, 0x1a, 0xd5, 0xed, 0xa8, + 0xc0, 0xef, 0xf8, 0xbd, 0x66, 0xff, 0x88, 0x96, 0x45, 0xa7, 0xa3, 0x82, 0x19, 0xd4, 0xd6, 0x9f, + 0xc7, 0xde, 0xd8, 0x9d, 0xc0, 0x77, 0xe8, 0x40, 0xf3, 0x47, 0x31, 0x9f, 0x8f, 0x2d, 0x75, 0x3b, + 0x09, 0x2a, 0x85, 0xe4, 0x7c, 0x57, 0xf2, 0x97, 0x85, 0x6e, 0xcf, 0x76, 0xb6, 0xff, 0x0e, 0x3c, + 0x44, 0x8d, 0x9f, 0xab, 0x41, 0x50, 0xed, 0x54, 0x7b, 0xcd, 0xfe, 0x59, 0x79, 0xaa, 0x01, 0x03, + 0x3e, 0x62, 0x89, 0x93, 0x3a, 0xdf, 0x5e, 0x64, 0xbf, 0x02, 0xbe, 0x42, 0x87, 0x42, 0x69, 0x35, + 0x9b, 0xc2, 0x2a, 0x82, 0x99, 0x16, 0xca, 0x08, 0xb9, 0x84, 0xa0, 0xd6, 0xa9, 0xf6, 0x1a, 0x0e, + 0xc6, 0x05, 0x30, 0xd9, 0xfe, 0x3f, 0xb8, 0x59, 0xa7, 0xc4, 0xdf, 0xa4, 0xc4, 0xff, 0x4a, 0x89, + 0xff, 0x96, 0x11, 0x6f, 0x93, 0x11, 0xef, 0x23, 0x23, 0xde, 0xfd, 0x45, 0x2c, 0xcc, 0xd3, 0x2a, + 0xa2, 0x33, 0xb9, 0x08, 0x77, 0xb6, 0xfd, 0xfa, 0xfb, 0x28, 0x26, 0x51, 0x1c, 0xa2, 0x7a, 0xb1, + 0xed, 0xcb, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0c, 0xae, 0x1d, 0x49, 0x2c, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -135,6 +145,15 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.IprpcSubscriptions) > 0 { + for iNdEx := len(m.IprpcSubscriptions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.IprpcSubscriptions[iNdEx]) + copy(dAtA[i:], m.IprpcSubscriptions[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.IprpcSubscriptions[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } if len(m.BasePays) > 0 { for iNdEx := len(m.BasePays) - 1; iNdEx >= 0; iNdEx-- { { @@ -199,6 +218,12 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.IprpcSubscriptions) > 0 { + for _, s := range m.IprpcSubscriptions { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -337,6 +362,38 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcSubscriptions", 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.IprpcSubscriptions = append(m.IprpcSubscriptions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/rewards/types/genesis_test.go b/x/rewards/types/genesis_test.go index 31e2769423..c3698d7823 100644 --- a/x/rewards/types/genesis_test.go +++ b/x/rewards/types/genesis_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/lavanet/lava/x/rewards/types" + timerstore "github.com/lavanet/lava/x/timerstore/types" "github.com/stretchr/testify/require" ) @@ -18,6 +19,16 @@ func TestGenesisState_Validate(t *testing.T) { genState: types.DefaultGenesis(), valid: true, }, + { + desc: "invalid iprpc subscriptions", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + RefillRewardsTS: *timerstore.DefaultGenesis(), + BasePays: []types.BasePayGenesis{}, + IprpcSubscriptions: []string{"invalidAddress"}, + }, + valid: false, + }, // this line is used by starport scaffolding # types/genesis/testcase } { t.Run(tc.desc, func(t *testing.T) { diff --git a/x/rewards/types/iprpc.pb.go b/x/rewards/types/iprpc.pb.go new file mode 100644 index 0000000000..ec5fb38716 --- /dev/null +++ b/x/rewards/types/iprpc.pb.go @@ -0,0 +1,319 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: lavanet/lava/rewards/iprpc.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + 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 IprpcSubscription struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *IprpcSubscription) Reset() { *m = IprpcSubscription{} } +func (m *IprpcSubscription) String() string { return proto.CompactTextString(m) } +func (*IprpcSubscription) ProtoMessage() {} +func (*IprpcSubscription) Descriptor() ([]byte, []int) { + return fileDescriptor_1293618a311573f7, []int{0} +} +func (m *IprpcSubscription) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IprpcSubscription) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IprpcSubscription.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 *IprpcSubscription) XXX_Merge(src proto.Message) { + xxx_messageInfo_IprpcSubscription.Merge(m, src) +} +func (m *IprpcSubscription) XXX_Size() int { + return m.Size() +} +func (m *IprpcSubscription) XXX_DiscardUnknown() { + xxx_messageInfo_IprpcSubscription.DiscardUnknown(m) +} + +var xxx_messageInfo_IprpcSubscription proto.InternalMessageInfo + +func (m *IprpcSubscription) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func init() { + proto.RegisterType((*IprpcSubscription)(nil), "lavanet.lava.rewards.IprpcSubscription") +} + +func init() { proto.RegisterFile("lavanet/lava/rewards/iprpc.proto", fileDescriptor_1293618a311573f7) } + +var fileDescriptor_1293618a311573f7 = []byte{ + // 201 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc8, 0x49, 0x2c, 0x4b, + 0xcc, 0x4b, 0x2d, 0xd1, 0x07, 0xd1, 0xfa, 0x45, 0xa9, 0xe5, 0x89, 0x45, 0x29, 0xc5, 0xfa, 0x99, + 0x05, 0x45, 0x05, 0xc9, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x22, 0x50, 0x15, 0x7a, 0x20, + 0x5a, 0x0f, 0xaa, 0x42, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xac, 0x40, 0x1f, 0xc4, 0x82, 0xa8, + 0x95, 0x92, 0x4b, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0x2c, 0x4e, 0xd5, 0x2f, 0x33, + 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0xce, 0xcf, 0xcc, 0x83, 0xc8, 0x2b, 0xe9, 0x72, 0x09, + 0x7a, 0x82, 0x8c, 0x0e, 0x2e, 0x4d, 0x2a, 0x4e, 0x2e, 0xca, 0x2c, 0x28, 0xc9, 0xcc, 0xcf, 0x13, + 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x96, 0x60, 0x54, 0x60, 0xd4, 0xe0, + 0x0c, 0x82, 0x71, 0x9d, 0x1c, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, + 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, + 0x3d, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xc5, 0x07, 0x15, 0x70, + 0x3f, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x2d, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, + 0xff, 0xb8, 0x17, 0xb1, 0xdd, 0xe8, 0x00, 0x00, 0x00, +} + +func (m *IprpcSubscription) 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 *IprpcSubscription) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IprpcSubscription) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintIprpc(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintIprpc(dAtA []byte, offset int, v uint64) int { + offset -= sovIprpc(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *IprpcSubscription) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovIprpc(uint64(l)) + } + return n +} + +func sovIprpc(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozIprpc(x uint64) (n int) { + return sovIprpc(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *IprpcSubscription) 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 ErrIntOverflowIprpc + } + 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: IprpcSubscription: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IprpcSubscription: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIprpc + } + 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 ErrInvalidLengthIprpc + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIprpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIprpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthIprpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipIprpc(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, ErrIntOverflowIprpc + } + 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, ErrIntOverflowIprpc + } + 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, ErrIntOverflowIprpc + } + 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, ErrInvalidLengthIprpc + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupIprpc + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthIprpc + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthIprpc = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowIprpc = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupIprpc = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/rewards/types/keys.go b/x/rewards/types/keys.go index ac8f682afb..5e3bb8e9f6 100644 --- a/x/rewards/types/keys.go +++ b/x/rewards/types/keys.go @@ -18,6 +18,9 @@ const ( // prefix for the CU tracker timer store MonthlyRewardsTSPrefix = "monthly-rewards-ts" + + // prefix for IPRPC eligible subscriptions + IprpcSubscriptionPrefix = "iprpc-subscription" ) func KeyPrefix(p string) []byte { From 426a2c8b33b65a6aa629c992058f97e7074aeb14 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 7 Feb 2024 19:23:55 +0200 Subject: [PATCH 03/64] CNS-868: scaffold single min iprpc cost --- proto/lavanet/lava/rewards/genesis.proto | 2 + x/rewards/genesis.go | 1 + x/rewards/keeper/iprpc_data.go | 20 ++ x/rewards/keeper/iprpc_data_test.go | 17 ++ x/rewards/types/genesis.go | 10 + x/rewards/types/genesis.pb.go | 100 +++++-- x/rewards/types/genesis_test.go | 6 +- x/rewards/types/iprpc.pb.go | 319 ----------------------- x/rewards/types/keys.go | 3 + 9 files changed, 135 insertions(+), 343 deletions(-) delete mode 100644 x/rewards/types/iprpc.pb.go diff --git a/proto/lavanet/lava/rewards/genesis.proto b/proto/lavanet/lava/rewards/genesis.proto index b29f69bc59..8a28f3f2fb 100644 --- a/proto/lavanet/lava/rewards/genesis.proto +++ b/proto/lavanet/lava/rewards/genesis.proto @@ -5,6 +5,7 @@ import "gogoproto/gogo.proto"; import "lavanet/lava/rewards/params.proto"; import "lavanet/lava/rewards/base_pay.proto"; import "lavanet/lava/timerstore/timer.proto"; +import "cosmos/base/v1beta1/coin.proto"; // this line is used by starport scaffolding # genesis/proto/import option go_package = "github.com/lavanet/lava/x/rewards/types"; @@ -15,5 +16,6 @@ message GenesisState { lavanet.lava.timerstore.GenesisState refillRewardsTS = 2 [(gogoproto.nullable) = false]; repeated BasePayGenesis base_pays = 3 [(gogoproto.nullable) = false]; repeated string iprpc_subscriptions = 4 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin min_iprpc_cost = 5 [(gogoproto.nullable) = false]; // this line is used by starport scaffolding # genesis/proto/state } \ No newline at end of file diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index fada13f0c2..3eb9454a48 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -32,6 +32,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.RefillRewardsTS = k.ExportRewardsRefillTS(ctx) genesis.BasePays = k.GetAllBasePay(ctx) genesis.IprpcSubscriptions = k.GetAllIprpcSubscription(ctx) + genesis.MinIprpcCost = k.GetMinIprpcCost(ctx) // this line is used by starport scaffolding # genesis/module/export return genesis diff --git a/x/rewards/keeper/iprpc_data.go b/x/rewards/keeper/iprpc_data.go index e81fa17b06..fd0152cbbc 100644 --- a/x/rewards/keeper/iprpc_data.go +++ b/x/rewards/keeper/iprpc_data.go @@ -6,6 +6,26 @@ import ( "github.com/lavanet/lava/x/rewards/types" ) +/********************** Min IPRPC Cost **********************/ + +// SetMinIprpcCost sets the min iprpc cost +func (k Keeper) SetMinIprpcCost(ctx sdk.Context, cost sdk.Coin) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.MinIprpcCostPrefix)) + b := k.cdc.MustMarshal(&cost) + store.Set([]byte{0}, b) +} + +// GetMinIprpcCost gets the min iprpc cost +func (k Keeper) GetMinIprpcCost(ctx sdk.Context) sdk.Coin { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.MinIprpcCostPrefix)) + b := store.Get([]byte{0}) + var cost sdk.Coin + k.cdc.MustUnmarshal(b, &cost) + return cost +} + +/********************** IPRPC Subscription **********************/ + // SetIprpcSubscription set a subscription in the IprpcSubscription store func (k Keeper) SetIprpcSubscription(ctx sdk.Context, address string) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcSubscriptionPrefix)) diff --git a/x/rewards/keeper/iprpc_data_test.go b/x/rewards/keeper/iprpc_data_test.go index bc2435d9d1..b295c6c9a8 100644 --- a/x/rewards/keeper/iprpc_data_test.go +++ b/x/rewards/keeper/iprpc_data_test.go @@ -4,6 +4,7 @@ import ( "strconv" "testing" + "cosmossdk.io/math" keepertest "github.com/lavanet/lava/testutil/keeper" "github.com/lavanet/lava/testutil/nullify" "github.com/lavanet/lava/x/rewards/keeper" @@ -15,6 +16,22 @@ import ( // Prevent strconv unused error var _ = strconv.IntSize +func createTestMinIprpcCost(keeper *keeper.Keeper, ctx sdk.Context) sdk.Coin { + item := sdk.NewCoin("denom", math.OneInt()) + keeper.SetMinIprpcCost(ctx, item) + return item +} + +func TestMinIprpcCostGet(t *testing.T) { + keeper, ctx := keepertest.RewardsKeeper(t) + item := createTestMinIprpcCost(keeper, ctx) + rst := keeper.GetMinIprpcCost(ctx) + require.Equal(t, + nullify.Fill(&item), + nullify.Fill(&rst), + ) +} + func createNIprpcSubscriptions(keeper *keeper.Keeper, ctx sdk.Context, n int) []string { items := make([]string, n) for i := range items { diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index 4d6584f7bc..609f7f4a84 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -4,6 +4,7 @@ import ( fmt "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + commontypes "github.com/lavanet/lava/common/types" "github.com/lavanet/lava/x/timerstore/types" ) @@ -20,6 +21,7 @@ func DefaultGenesis() *GenesisState { RefillRewardsTS: *types.DefaultGenesis(), BasePays: []BasePayGenesis{}, IprpcSubscriptions: []string{}, + MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, sdk.ZeroInt()), } } @@ -40,5 +42,13 @@ func (gs GenesisState) Validate() error { } } + if gs.MinIprpcCost.Denom != DefaultGenesis().MinIprpcCost.Denom { + return fmt.Errorf("invalid min iprpc cost denom. MinIprpcCost: %s", gs.MinIprpcCost.String()) + } + + if gs.MinIprpcCost.Amount.IsNegative() { + return fmt.Errorf("negative min iprpc cost. MinIprpcCost: %s", gs.MinIprpcCost.String()) + } + return gs.Params.Validate() } diff --git a/x/rewards/types/genesis.pb.go b/x/rewards/types/genesis.pb.go index 3ae410863b..41183b0591 100644 --- a/x/rewards/types/genesis.pb.go +++ b/x/rewards/types/genesis.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + types1 "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" types "github.com/lavanet/lava/x/timerstore/types" @@ -30,6 +31,7 @@ type GenesisState struct { RefillRewardsTS types.GenesisState `protobuf:"bytes,2,opt,name=refillRewardsTS,proto3" json:"refillRewardsTS"` BasePays []BasePayGenesis `protobuf:"bytes,3,rep,name=base_pays,json=basePays,proto3" json:"base_pays"` IprpcSubscriptions []string `protobuf:"bytes,4,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` + MinIprpcCost types1.Coin `protobuf:"bytes,5,opt,name=min_iprpc_cost,json=minIprpcCost,proto3" json:"min_iprpc_cost"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -93,6 +95,13 @@ func (m *GenesisState) GetIprpcSubscriptions() []string { return nil } +func (m *GenesisState) GetMinIprpcCost() types1.Coin { + if m != nil { + return m.MinIprpcCost + } + return types1.Coin{} +} + func init() { proto.RegisterType((*GenesisState)(nil), "lavanet.lava.rewards.GenesisState") } @@ -102,27 +111,31 @@ func init() { } var fileDescriptor_02c24f4df31ca14e = []byte{ - // 320 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x41, 0x4f, 0xc2, 0x30, - 0x14, 0xc7, 0x37, 0x20, 0x44, 0x8a, 0x89, 0x49, 0xe5, 0xb0, 0x10, 0x53, 0x11, 0x35, 0x72, 0xea, - 0x12, 0x8c, 0x17, 0x6f, 0x72, 0xe1, 0x4a, 0x40, 0x2f, 0x5e, 0x48, 0x87, 0x75, 0x36, 0x01, 0xda, - 0xf4, 0x15, 0x75, 0xdf, 0xc2, 0xaf, 0xe0, 0xb7, 0xe1, 0xc8, 0xd1, 0x93, 0x31, 0xdb, 0x17, 0x31, - 0x5b, 0xab, 0x82, 0xd9, 0xe9, 0xbd, 0x6c, 0xbf, 0xfe, 0xde, 0xbf, 0xaf, 0xa8, 0x3b, 0x67, 0xcf, - 0x6c, 0xc9, 0x4d, 0x98, 0xd7, 0x50, 0xf3, 0x17, 0xa6, 0x1f, 0x20, 0x8c, 0xf9, 0x92, 0x83, 0x00, - 0xaa, 0xb4, 0x34, 0x12, 0xb7, 0x1c, 0x43, 0xf3, 0x4a, 0x1d, 0xd3, 0x6e, 0xc5, 0x32, 0x96, 0x05, - 0x10, 0xe6, 0x9d, 0x65, 0xdb, 0x27, 0xa5, 0x3e, 0xc5, 0x34, 0x5b, 0x38, 0x5d, 0xfb, 0xb4, 0x14, - 0x89, 0x18, 0xf0, 0xa9, 0x62, 0x49, 0x29, 0x64, 0xc4, 0x82, 0x6b, 0x30, 0x52, 0x73, 0xdb, 0x5a, - 0xa8, 0xfb, 0x5e, 0x41, 0xfb, 0x43, 0x1b, 0x75, 0x62, 0x98, 0xe1, 0xf8, 0x1a, 0xd5, 0xed, 0xa8, - 0xc0, 0xef, 0xf8, 0xbd, 0x66, 0xff, 0x88, 0x96, 0x45, 0xa7, 0xa3, 0x82, 0x19, 0xd4, 0xd6, 0x9f, - 0xc7, 0xde, 0xd8, 0x9d, 0xc0, 0x77, 0xe8, 0x40, 0xf3, 0x47, 0x31, 0x9f, 0x8f, 0x2d, 0x75, 0x3b, - 0x09, 0x2a, 0x85, 0xe4, 0x7c, 0x57, 0xf2, 0x97, 0x85, 0x6e, 0xcf, 0x76, 0xb6, 0xff, 0x0e, 0x3c, - 0x44, 0x8d, 0x9f, 0xab, 0x41, 0x50, 0xed, 0x54, 0x7b, 0xcd, 0xfe, 0x59, 0x79, 0xaa, 0x01, 0x03, - 0x3e, 0x62, 0x89, 0x93, 0x3a, 0xdf, 0x5e, 0x64, 0xbf, 0x02, 0xbe, 0x42, 0x87, 0x42, 0x69, 0x35, - 0x9b, 0xc2, 0x2a, 0x82, 0x99, 0x16, 0xca, 0x08, 0xb9, 0x84, 0xa0, 0xd6, 0xa9, 0xf6, 0x1a, 0x0e, - 0xc6, 0x05, 0x30, 0xd9, 0xfe, 0x3f, 0xb8, 0x59, 0xa7, 0xc4, 0xdf, 0xa4, 0xc4, 0xff, 0x4a, 0x89, - 0xff, 0x96, 0x11, 0x6f, 0x93, 0x11, 0xef, 0x23, 0x23, 0xde, 0xfd, 0x45, 0x2c, 0xcc, 0xd3, 0x2a, - 0xa2, 0x33, 0xb9, 0x08, 0x77, 0xb6, 0xfd, 0xfa, 0xfb, 0x28, 0x26, 0x51, 0x1c, 0xa2, 0x7a, 0xb1, - 0xed, 0xcb, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0c, 0xae, 0x1d, 0x49, 0x2c, 0x02, 0x00, 0x00, + // 378 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x41, 0x4f, 0x22, 0x31, + 0x14, 0xc7, 0x67, 0x80, 0x25, 0xcb, 0x40, 0x76, 0x93, 0x59, 0x0e, 0xb3, 0xc4, 0x8c, 0x88, 0x1a, + 0x39, 0x75, 0x02, 0xc6, 0x8b, 0x37, 0x21, 0x86, 0x78, 0x23, 0xa0, 0x17, 0x2f, 0xa4, 0x33, 0xd6, + 0xb1, 0x09, 0xd3, 0x36, 0x7d, 0x05, 0xe5, 0x5b, 0xf8, 0xb1, 0x38, 0x72, 0xf4, 0x64, 0x0c, 0x5c, + 0xfc, 0x18, 0x66, 0xa6, 0x55, 0xc1, 0xcc, 0xa9, 0x4d, 0xfb, 0x7b, 0xbf, 0xbe, 0x7f, 0x9f, 0xd3, + 0x9a, 0xe2, 0x39, 0x66, 0x44, 0x05, 0xe9, 0x1a, 0x48, 0xf2, 0x88, 0xe5, 0x1d, 0x04, 0x31, 0x61, + 0x04, 0x28, 0x20, 0x21, 0xb9, 0xe2, 0x6e, 0xdd, 0x30, 0x28, 0x5d, 0x91, 0x61, 0x1a, 0xf5, 0x98, + 0xc7, 0x3c, 0x03, 0x82, 0x74, 0xa7, 0xd9, 0xc6, 0x41, 0xae, 0x4f, 0x60, 0x89, 0x13, 0xa3, 0x6b, + 0x1c, 0xe6, 0x22, 0x21, 0x06, 0x32, 0x11, 0x78, 0x91, 0x0b, 0x29, 0x9a, 0x10, 0x09, 0x8a, 0x4b, + 0xa2, 0xb7, 0x06, 0xf2, 0x23, 0x0e, 0x09, 0xd7, 0xb5, 0xc1, 0xbc, 0x13, 0x12, 0x85, 0x3b, 0x41, + 0xc4, 0x29, 0xd3, 0xf7, 0xad, 0xf7, 0x82, 0x53, 0x1b, 0xe8, 0x28, 0x63, 0x85, 0x15, 0x71, 0xcf, + 0x9d, 0xb2, 0x6e, 0xc5, 0xb3, 0x9b, 0x76, 0xbb, 0xda, 0xdd, 0x43, 0x79, 0xd1, 0xd0, 0x30, 0x63, + 0x7a, 0xa5, 0xe5, 0xeb, 0xbe, 0x35, 0x32, 0x15, 0xee, 0x8d, 0xf3, 0x57, 0x92, 0x7b, 0x3a, 0x9d, + 0x8e, 0x34, 0x75, 0x3d, 0xf6, 0x0a, 0x99, 0xe4, 0x78, 0x57, 0xf2, 0xdd, 0x2b, 0xda, 0x7e, 0xdb, + 0xd8, 0x7e, 0x3a, 0xdc, 0x81, 0x53, 0xf9, 0x8c, 0x0e, 0x5e, 0xb1, 0x59, 0x6c, 0x57, 0xbb, 0x47, + 0xf9, 0x5d, 0xf5, 0x30, 0x90, 0x21, 0x5e, 0x18, 0xa9, 0xf1, 0xfd, 0x0e, 0xf5, 0x29, 0xb8, 0x67, + 0xce, 0x3f, 0x2a, 0xa4, 0x88, 0x26, 0x30, 0x0b, 0x21, 0x92, 0x54, 0x28, 0xca, 0x19, 0x78, 0xa5, + 0x66, 0xb1, 0x5d, 0x31, 0xb0, 0x9b, 0x01, 0xe3, 0xed, 0x7b, 0xf7, 0xd2, 0xf9, 0x93, 0x50, 0x36, + 0xd1, 0xa5, 0x11, 0x07, 0xe5, 0xfd, 0xca, 0x52, 0xfd, 0x47, 0xfa, 0x73, 0x51, 0xfa, 0x00, 0x32, + 0x9f, 0x8b, 0xfa, 0x9c, 0x32, 0x23, 0xab, 0x25, 0x94, 0x5d, 0xa5, 0x55, 0x7d, 0x0e, 0xaa, 0x77, + 0xb1, 0x5c, 0xfb, 0xf6, 0x6a, 0xed, 0xdb, 0x6f, 0x6b, 0xdf, 0x7e, 0xde, 0xf8, 0xd6, 0x6a, 0xe3, + 0x5b, 0x2f, 0x1b, 0xdf, 0xba, 0x3d, 0x89, 0xa9, 0x7a, 0x98, 0x85, 0x28, 0xe2, 0x49, 0xb0, 0x33, + 0xd4, 0xa7, 0xaf, 0xd9, 0xab, 0x85, 0x20, 0x10, 0x96, 0xb3, 0xa1, 0x9d, 0x7e, 0x04, 0x00, 0x00, + 0xff, 0xff, 0xb8, 0x60, 0xc4, 0x73, 0x93, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -145,6 +158,16 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.MinIprpcCost.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a if len(m.IprpcSubscriptions) > 0 { for iNdEx := len(m.IprpcSubscriptions) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.IprpcSubscriptions[iNdEx]) @@ -224,6 +247,8 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + l = m.MinIprpcCost.Size() + n += 1 + l + sovGenesis(uint64(l)) return n } @@ -394,6 +419,39 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } m.IprpcSubscriptions = append(m.IprpcSubscriptions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinIprpcCost", 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 err := m.MinIprpcCost.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/rewards/types/genesis_test.go b/x/rewards/types/genesis_test.go index c3698d7823..6cd11ddc4a 100644 --- a/x/rewards/types/genesis_test.go +++ b/x/rewards/types/genesis_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/lavanet/lava/x/rewards/types" - timerstore "github.com/lavanet/lava/x/timerstore/types" "github.com/stretchr/testify/require" ) @@ -23,9 +22,10 @@ func TestGenesisState_Validate(t *testing.T) { desc: "invalid iprpc subscriptions", genState: &types.GenesisState{ Params: types.DefaultParams(), - RefillRewardsTS: *timerstore.DefaultGenesis(), - BasePays: []types.BasePayGenesis{}, + RefillRewardsTS: types.DefaultGenesis().RefillRewardsTS, + BasePays: types.DefaultGenesis().BasePays, IprpcSubscriptions: []string{"invalidAddress"}, + MinIprpcCost: types.DefaultGenesis().MinIprpcCost, }, valid: false, }, diff --git a/x/rewards/types/iprpc.pb.go b/x/rewards/types/iprpc.pb.go deleted file mode 100644 index ec5fb38716..0000000000 --- a/x/rewards/types/iprpc.pb.go +++ /dev/null @@ -1,319 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: lavanet/lava/rewards/iprpc.proto - -package types - -import ( - fmt "fmt" - _ "github.com/cosmos/cosmos-sdk/types" - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" - 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 IprpcSubscription struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` -} - -func (m *IprpcSubscription) Reset() { *m = IprpcSubscription{} } -func (m *IprpcSubscription) String() string { return proto.CompactTextString(m) } -func (*IprpcSubscription) ProtoMessage() {} -func (*IprpcSubscription) Descriptor() ([]byte, []int) { - return fileDescriptor_1293618a311573f7, []int{0} -} -func (m *IprpcSubscription) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *IprpcSubscription) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_IprpcSubscription.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 *IprpcSubscription) XXX_Merge(src proto.Message) { - xxx_messageInfo_IprpcSubscription.Merge(m, src) -} -func (m *IprpcSubscription) XXX_Size() int { - return m.Size() -} -func (m *IprpcSubscription) XXX_DiscardUnknown() { - xxx_messageInfo_IprpcSubscription.DiscardUnknown(m) -} - -var xxx_messageInfo_IprpcSubscription proto.InternalMessageInfo - -func (m *IprpcSubscription) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func init() { - proto.RegisterType((*IprpcSubscription)(nil), "lavanet.lava.rewards.IprpcSubscription") -} - -func init() { proto.RegisterFile("lavanet/lava/rewards/iprpc.proto", fileDescriptor_1293618a311573f7) } - -var fileDescriptor_1293618a311573f7 = []byte{ - // 201 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc8, 0x49, 0x2c, 0x4b, - 0xcc, 0x4b, 0x2d, 0xd1, 0x07, 0xd1, 0xfa, 0x45, 0xa9, 0xe5, 0x89, 0x45, 0x29, 0xc5, 0xfa, 0x99, - 0x05, 0x45, 0x05, 0xc9, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x22, 0x50, 0x15, 0x7a, 0x20, - 0x5a, 0x0f, 0xaa, 0x42, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xac, 0x40, 0x1f, 0xc4, 0x82, 0xa8, - 0x95, 0x92, 0x4b, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0x2c, 0x4e, 0xd5, 0x2f, 0x33, - 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0xce, 0xcf, 0xcc, 0x83, 0xc8, 0x2b, 0xe9, 0x72, 0x09, - 0x7a, 0x82, 0x8c, 0x0e, 0x2e, 0x4d, 0x2a, 0x4e, 0x2e, 0xca, 0x2c, 0x28, 0xc9, 0xcc, 0xcf, 0x13, - 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x96, 0x60, 0x54, 0x60, 0xd4, 0xe0, - 0x0c, 0x82, 0x71, 0x9d, 0x1c, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, - 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, - 0x3d, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xc5, 0x07, 0x15, 0x70, - 0x3f, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x2d, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, - 0xff, 0xb8, 0x17, 0xb1, 0xdd, 0xe8, 0x00, 0x00, 0x00, -} - -func (m *IprpcSubscription) 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 *IprpcSubscription) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *IprpcSubscription) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Address) > 0 { - i -= len(m.Address) - copy(dAtA[i:], m.Address) - i = encodeVarintIprpc(dAtA, i, uint64(len(m.Address))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintIprpc(dAtA []byte, offset int, v uint64) int { - offset -= sovIprpc(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *IprpcSubscription) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Address) - if l > 0 { - n += 1 + l + sovIprpc(uint64(l)) - } - return n -} - -func sovIprpc(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozIprpc(x uint64) (n int) { - return sovIprpc(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *IprpcSubscription) 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 ErrIntOverflowIprpc - } - 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: IprpcSubscription: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: IprpcSubscription: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowIprpc - } - 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 ErrInvalidLengthIprpc - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthIprpc - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Address = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipIprpc(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthIprpc - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipIprpc(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, ErrIntOverflowIprpc - } - 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, ErrIntOverflowIprpc - } - 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, ErrIntOverflowIprpc - } - 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, ErrInvalidLengthIprpc - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupIprpc - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthIprpc - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthIprpc = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowIprpc = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupIprpc = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/rewards/types/keys.go b/x/rewards/types/keys.go index 5e3bb8e9f6..89f06bb3e6 100644 --- a/x/rewards/types/keys.go +++ b/x/rewards/types/keys.go @@ -21,6 +21,9 @@ const ( // prefix for IPRPC eligible subscriptions IprpcSubscriptionPrefix = "iprpc-subscription" + + // prefix for min IPRPC cost + MinIprpcCostPrefix = "min-iprpc-cost" ) func KeyPrefix(p string) []byte { From d5f74ed2225be1010c5a4deab2e5353fe21c0ad8 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 8 Feb 2024 12:00:43 +0200 Subject: [PATCH 04/64] CNS-868: scaffold query show iprpc data --- proto/lavanet/lava/rewards/genesis.proto | 2 +- proto/lavanet/lava/rewards/query.proto | 14 + scripts/cli_test.sh | 1 + testutil/common/tester.go | 5 + x/rewards/client/cli/query.go | 1 + x/rewards/client/cli/query_show_iprpc_data.go | 41 ++ .../keeper/grpc_query_show_iprpc_data.go | 23 + x/rewards/types/genesis.pb.go | 50 +- x/rewards/types/query.pb.go | 468 ++++++++++++++++-- x/rewards/types/query.pb.gw.go | 65 +++ 10 files changed, 606 insertions(+), 64 deletions(-) create mode 100644 x/rewards/client/cli/query_show_iprpc_data.go create mode 100644 x/rewards/keeper/grpc_query_show_iprpc_data.go diff --git a/proto/lavanet/lava/rewards/genesis.proto b/proto/lavanet/lava/rewards/genesis.proto index 8a28f3f2fb..7803a498f7 100644 --- a/proto/lavanet/lava/rewards/genesis.proto +++ b/proto/lavanet/lava/rewards/genesis.proto @@ -15,7 +15,7 @@ message GenesisState { Params params = 1 [(gogoproto.nullable) = false]; lavanet.lava.timerstore.GenesisState refillRewardsTS = 2 [(gogoproto.nullable) = false]; repeated BasePayGenesis base_pays = 3 [(gogoproto.nullable) = false]; - repeated string iprpc_subscriptions = 4 [(gogoproto.nullable) = false]; + repeated string iprpc_subscriptions = 4; cosmos.base.v1beta1.Coin min_iprpc_cost = 5 [(gogoproto.nullable) = false]; // this line is used by starport scaffolding # genesis/proto/state } \ No newline at end of file diff --git a/proto/lavanet/lava/rewards/query.proto b/proto/lavanet/lava/rewards/query.proto index 403fe9a15f..305b4acc0e 100644 --- a/proto/lavanet/lava/rewards/query.proto +++ b/proto/lavanet/lava/rewards/query.proto @@ -26,6 +26,11 @@ service Query { rpc BlockReward(QueryBlockRewardRequest) returns (QueryBlockRewardResponse) { option (google.api.http).get = "/lavanet/lava/rewards/block_reward"; } + + // ShowIprpcData queries for the iprpc data + rpc ShowIprpcData(QueryShowIprpcDataRequest) returns (QueryShowIprpcDataResponse) { + option (google.api.http).get = "/lavanet/lava/rewards/show_iprpc_data"; + } // this line is used by starport scaffolding # 2 } @@ -63,4 +68,13 @@ message QueryBlockRewardResponse { cosmos.base.v1beta1.Coin reward = 1 [(gogoproto.nullable) = false]; } +// QueryShowIprpcDataRequest is request type for the Query/ShowIprpcData RPC method. +message QueryShowIprpcDataRequest {} + +// QueryShowIprpcDataResponse is response type for the Query/ShowIprpcData RPC method. +message QueryShowIprpcDataResponse { + cosmos.base.v1beta1.Coin min_cost = 1 [(gogoproto.nullable) = false]; + repeated string iprpc_subscriptions = 2; +} + // this line is used by starport scaffolding # 3 \ No newline at end of file diff --git a/scripts/cli_test.sh b/scripts/cli_test.sh index 40c5ecac35..212e2db1b9 100755 --- a/scripts/cli_test.sh +++ b/scripts/cli_test.sh @@ -182,6 +182,7 @@ trace lavad q fixationstore versions entry subs-fs $(lavad keys show alice -a) 1 echo "Testing rewards q commands" trace lavad q rewards pools >/dev/null trace lavad q rewards block-reward >/dev/null +trace lavad q rewards show-iprpc-data > /dev/null echo "Testing events command" trace lavad test events 30 10 --event lava_relay_payment --from alice --timeout 1s >/dev/null diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 359e77e570..3eef5f3638 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -854,6 +854,11 @@ func (ts *Tester) QueryRewardsBlockReward() (*rewardstypes.QueryBlockRewardRespo return ts.Keepers.Rewards.BlockReward(ts.GoCtx, msg) } +func (ts *Tester) QueryShowIprpcData() (*rewardstypes.QueryShowIprpcDataResponse, error) { + msg := &rewardstypes.QueryShowIprpcDataRequest{} + return ts.Keepers.Rewards.ShowIprpcData(ts.GoCtx, msg) +} + // block/epoch helpers func (ts *Tester) BlockHeight() uint64 { diff --git a/x/rewards/client/cli/query.go b/x/rewards/client/cli/query.go index b04b2b63c7..c109ab1701 100644 --- a/x/rewards/client/cli/query.go +++ b/x/rewards/client/cli/query.go @@ -27,6 +27,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdQueryParams()) cmd.AddCommand(CmdQueryPools()) cmd.AddCommand(CmdQueryBlockReward()) + cmd.AddCommand(CmdQueryShowIprpcData()) // this line is used by starport scaffolding # 1 return cmd diff --git a/x/rewards/client/cli/query_show_iprpc_data.go b/x/rewards/client/cli/query_show_iprpc_data.go new file mode 100644 index 0000000000..4448e42323 --- /dev/null +++ b/x/rewards/client/cli/query_show_iprpc_data.go @@ -0,0 +1,41 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/lavanet/lava/x/rewards/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdQueryShowIprpcData() *cobra.Command { + cmd := &cobra.Command{ + Use: "show-iprpc-data", + Short: "Query for IPRPC data: min cost and IPRPC eligible subscriptions", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryShowIprpcDataRequest{} + + res, err := queryClient.ShowIprpcData(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/rewards/keeper/grpc_query_show_iprpc_data.go b/x/rewards/keeper/grpc_query_show_iprpc_data.go new file mode 100644 index 0000000000..84444c1679 --- /dev/null +++ b/x/rewards/keeper/grpc_query_show_iprpc_data.go @@ -0,0 +1,23 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/rewards/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k Keeper) ShowIprpcData(goCtx context.Context, req *types.QueryShowIprpcDataRequest) (*types.QueryShowIprpcDataResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + cost := k.GetMinIprpcCost(ctx) + subs := k.GetAllIprpcSubscription(ctx) + + return &types.QueryShowIprpcDataResponse{MinCost: cost, IprpcSubscriptions: subs}, nil +} diff --git a/x/rewards/types/genesis.pb.go b/x/rewards/types/genesis.pb.go index 41183b0591..98e5a8712b 100644 --- a/x/rewards/types/genesis.pb.go +++ b/x/rewards/types/genesis.pb.go @@ -111,31 +111,31 @@ func init() { } var fileDescriptor_02c24f4df31ca14e = []byte{ - // 378 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x41, 0x4f, 0x22, 0x31, - 0x14, 0xc7, 0x67, 0x80, 0x25, 0xcb, 0x40, 0x76, 0x93, 0x59, 0x0e, 0xb3, 0xc4, 0x8c, 0x88, 0x1a, - 0x39, 0x75, 0x02, 0xc6, 0x8b, 0x37, 0x21, 0x86, 0x78, 0x23, 0xa0, 0x17, 0x2f, 0xa4, 0x33, 0xd6, - 0xb1, 0x09, 0xd3, 0x36, 0x7d, 0x05, 0xe5, 0x5b, 0xf8, 0xb1, 0x38, 0x72, 0xf4, 0x64, 0x0c, 0x5c, - 0xfc, 0x18, 0x66, 0xa6, 0x55, 0xc1, 0xcc, 0xa9, 0x4d, 0xfb, 0x7b, 0xbf, 0xbe, 0x7f, 0x9f, 0xd3, - 0x9a, 0xe2, 0x39, 0x66, 0x44, 0x05, 0xe9, 0x1a, 0x48, 0xf2, 0x88, 0xe5, 0x1d, 0x04, 0x31, 0x61, - 0x04, 0x28, 0x20, 0x21, 0xb9, 0xe2, 0x6e, 0xdd, 0x30, 0x28, 0x5d, 0x91, 0x61, 0x1a, 0xf5, 0x98, - 0xc7, 0x3c, 0x03, 0x82, 0x74, 0xa7, 0xd9, 0xc6, 0x41, 0xae, 0x4f, 0x60, 0x89, 0x13, 0xa3, 0x6b, - 0x1c, 0xe6, 0x22, 0x21, 0x06, 0x32, 0x11, 0x78, 0x91, 0x0b, 0x29, 0x9a, 0x10, 0x09, 0x8a, 0x4b, - 0xa2, 0xb7, 0x06, 0xf2, 0x23, 0x0e, 0x09, 0xd7, 0xb5, 0xc1, 0xbc, 0x13, 0x12, 0x85, 0x3b, 0x41, - 0xc4, 0x29, 0xd3, 0xf7, 0xad, 0xf7, 0x82, 0x53, 0x1b, 0xe8, 0x28, 0x63, 0x85, 0x15, 0x71, 0xcf, - 0x9d, 0xb2, 0x6e, 0xc5, 0xb3, 0x9b, 0x76, 0xbb, 0xda, 0xdd, 0x43, 0x79, 0xd1, 0xd0, 0x30, 0x63, - 0x7a, 0xa5, 0xe5, 0xeb, 0xbe, 0x35, 0x32, 0x15, 0xee, 0x8d, 0xf3, 0x57, 0x92, 0x7b, 0x3a, 0x9d, - 0x8e, 0x34, 0x75, 0x3d, 0xf6, 0x0a, 0x99, 0xe4, 0x78, 0x57, 0xf2, 0xdd, 0x2b, 0xda, 0x7e, 0xdb, - 0xd8, 0x7e, 0x3a, 0xdc, 0x81, 0x53, 0xf9, 0x8c, 0x0e, 0x5e, 0xb1, 0x59, 0x6c, 0x57, 0xbb, 0x47, - 0xf9, 0x5d, 0xf5, 0x30, 0x90, 0x21, 0x5e, 0x18, 0xa9, 0xf1, 0xfd, 0x0e, 0xf5, 0x29, 0xb8, 0x67, - 0xce, 0x3f, 0x2a, 0xa4, 0x88, 0x26, 0x30, 0x0b, 0x21, 0x92, 0x54, 0x28, 0xca, 0x19, 0x78, 0xa5, - 0x66, 0xb1, 0x5d, 0x31, 0xb0, 0x9b, 0x01, 0xe3, 0xed, 0x7b, 0xf7, 0xd2, 0xf9, 0x93, 0x50, 0x36, - 0xd1, 0xa5, 0x11, 0x07, 0xe5, 0xfd, 0xca, 0x52, 0xfd, 0x47, 0xfa, 0x73, 0x51, 0xfa, 0x00, 0x32, - 0x9f, 0x8b, 0xfa, 0x9c, 0x32, 0x23, 0xab, 0x25, 0x94, 0x5d, 0xa5, 0x55, 0x7d, 0x0e, 0xaa, 0x77, - 0xb1, 0x5c, 0xfb, 0xf6, 0x6a, 0xed, 0xdb, 0x6f, 0x6b, 0xdf, 0x7e, 0xde, 0xf8, 0xd6, 0x6a, 0xe3, - 0x5b, 0x2f, 0x1b, 0xdf, 0xba, 0x3d, 0x89, 0xa9, 0x7a, 0x98, 0x85, 0x28, 0xe2, 0x49, 0xb0, 0x33, - 0xd4, 0xa7, 0xaf, 0xd9, 0xab, 0x85, 0x20, 0x10, 0x96, 0xb3, 0xa1, 0x9d, 0x7e, 0x04, 0x00, 0x00, - 0xff, 0xff, 0xb8, 0x60, 0xc4, 0x73, 0x93, 0x02, 0x00, 0x00, + // 375 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x4f, 0x4f, 0xe2, 0x40, + 0x14, 0xc0, 0x5b, 0x60, 0xc9, 0x52, 0xc8, 0x6e, 0xd2, 0xe5, 0xd0, 0x25, 0xa6, 0x22, 0x6a, 0xe4, + 0x34, 0x13, 0xf0, 0xe6, 0x4d, 0x88, 0x21, 0xde, 0x08, 0xe8, 0xc5, 0x0b, 0x99, 0xd6, 0xb1, 0x4e, + 0x42, 0x3b, 0x93, 0x79, 0x03, 0xca, 0xb7, 0xf0, 0x63, 0x71, 0xe4, 0xe8, 0xc9, 0x98, 0xf2, 0x45, + 0x4c, 0x3b, 0xa3, 0x82, 0xe9, 0x69, 0x26, 0xf3, 0x7e, 0xef, 0x37, 0xef, 0x8f, 0xd3, 0x99, 0x93, + 0x25, 0x49, 0xa8, 0xc2, 0xd9, 0x89, 0x25, 0x7d, 0x22, 0xf2, 0x1e, 0x70, 0x44, 0x13, 0x0a, 0x0c, + 0x90, 0x90, 0x5c, 0x71, 0xb7, 0x69, 0x18, 0x94, 0x9d, 0xc8, 0x30, 0xad, 0x66, 0xc4, 0x23, 0x9e, + 0x03, 0x38, 0xbb, 0x69, 0xb6, 0x75, 0x54, 0xe8, 0x13, 0x44, 0x92, 0xd8, 0xe8, 0x5a, 0xc7, 0x85, + 0x48, 0x40, 0x80, 0xce, 0x04, 0x59, 0x15, 0x42, 0x8a, 0xc5, 0x54, 0x82, 0xe2, 0x92, 0xea, 0xab, + 0x81, 0xfc, 0x90, 0x43, 0xcc, 0x75, 0x2e, 0x5e, 0xf6, 0x02, 0xaa, 0x48, 0x0f, 0x87, 0x9c, 0x25, + 0x3a, 0xde, 0x49, 0x4b, 0x4e, 0x63, 0xa4, 0x5b, 0x99, 0x2a, 0xa2, 0xa8, 0x7b, 0xe1, 0x54, 0x75, + 0x29, 0x9e, 0xdd, 0xb6, 0xbb, 0xf5, 0xfe, 0x01, 0x2a, 0x6a, 0x0d, 0x8d, 0x73, 0x66, 0x50, 0x59, + 0xbf, 0x1d, 0x5a, 0x13, 0x93, 0xe1, 0xde, 0x3a, 0x7f, 0x25, 0x7d, 0x60, 0xf3, 0xf9, 0x44, 0x53, + 0x37, 0x53, 0xaf, 0x94, 0x4b, 0x4e, 0xf7, 0x25, 0xdf, 0xb5, 0xa2, 0xdd, 0xbf, 0x8d, 0xed, 0xa7, + 0xc3, 0x1d, 0x39, 0xb5, 0xcf, 0xd6, 0xc1, 0x2b, 0xb7, 0xcb, 0xdd, 0x7a, 0xff, 0xa4, 0xb8, 0xaa, + 0x01, 0x01, 0x3a, 0x26, 0x2b, 0x23, 0x35, 0xbe, 0xdf, 0x81, 0x7e, 0x05, 0x17, 0x3b, 0xff, 0x98, + 0x90, 0x22, 0x9c, 0xc1, 0x22, 0x80, 0x50, 0x32, 0xa1, 0x18, 0x4f, 0xc0, 0xab, 0xb4, 0xcb, 0xdd, + 0xda, 0xc4, 0xcd, 0x43, 0xd3, 0xdd, 0x88, 0x7b, 0xe5, 0xfc, 0x89, 0x59, 0x32, 0xd3, 0x49, 0x21, + 0x07, 0xe5, 0xfd, 0xca, 0xfb, 0xf9, 0x8f, 0xf4, 0x58, 0x51, 0xa6, 0x46, 0x66, 0xac, 0x68, 0xc8, + 0x59, 0x62, 0xfe, 0x6c, 0xc4, 0x2c, 0xb9, 0xce, 0xb2, 0x86, 0x1c, 0xd4, 0xe0, 0x72, 0x9d, 0xfa, + 0xf6, 0x26, 0xf5, 0xed, 0xf7, 0xd4, 0xb7, 0x5f, 0xb6, 0xbe, 0xb5, 0xd9, 0xfa, 0xd6, 0xeb, 0xd6, + 0xb7, 0xee, 0xce, 0x22, 0xa6, 0x1e, 0x17, 0x01, 0x0a, 0x79, 0x8c, 0xf7, 0xd6, 0xf9, 0xfc, 0xb5, + 0x75, 0xb5, 0x12, 0x14, 0x82, 0x6a, 0xbe, 0xae, 0xf3, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x17, + 0x08, 0xb2, 0x20, 0x8d, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/rewards/types/query.pb.go b/x/rewards/types/query.pb.go index 2203cbaad5..d51e38f015 100644 --- a/x/rewards/types/query.pb.go +++ b/x/rewards/types/query.pb.go @@ -355,6 +355,96 @@ func (m *QueryBlockRewardResponse) GetReward() types.Coin { return types.Coin{} } +// QueryShowIprpcDataRequest is request type for the Query/ShowIprpcData RPC method. +type QueryShowIprpcDataRequest struct { +} + +func (m *QueryShowIprpcDataRequest) Reset() { *m = QueryShowIprpcDataRequest{} } +func (m *QueryShowIprpcDataRequest) String() string { return proto.CompactTextString(m) } +func (*QueryShowIprpcDataRequest) ProtoMessage() {} +func (*QueryShowIprpcDataRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_15bce9a904340007, []int{7} +} +func (m *QueryShowIprpcDataRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryShowIprpcDataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryShowIprpcDataRequest.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 *QueryShowIprpcDataRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryShowIprpcDataRequest.Merge(m, src) +} +func (m *QueryShowIprpcDataRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryShowIprpcDataRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryShowIprpcDataRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryShowIprpcDataRequest proto.InternalMessageInfo + +// QueryShowIprpcDataResponse is response type for the Query/ShowIprpcData RPC method. +type QueryShowIprpcDataResponse struct { + MinCost types.Coin `protobuf:"bytes,1,opt,name=min_cost,json=minCost,proto3" json:"min_cost"` + IprpcSubscriptions []string `protobuf:"bytes,2,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` +} + +func (m *QueryShowIprpcDataResponse) Reset() { *m = QueryShowIprpcDataResponse{} } +func (m *QueryShowIprpcDataResponse) String() string { return proto.CompactTextString(m) } +func (*QueryShowIprpcDataResponse) ProtoMessage() {} +func (*QueryShowIprpcDataResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_15bce9a904340007, []int{8} +} +func (m *QueryShowIprpcDataResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryShowIprpcDataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryShowIprpcDataResponse.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 *QueryShowIprpcDataResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryShowIprpcDataResponse.Merge(m, src) +} +func (m *QueryShowIprpcDataResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryShowIprpcDataResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryShowIprpcDataResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryShowIprpcDataResponse proto.InternalMessageInfo + +func (m *QueryShowIprpcDataResponse) GetMinCost() types.Coin { + if m != nil { + return m.MinCost + } + return types.Coin{} +} + +func (m *QueryShowIprpcDataResponse) GetIprpcSubscriptions() []string { + if m != nil { + return m.IprpcSubscriptions + } + return nil +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "lavanet.lava.rewards.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "lavanet.lava.rewards.QueryParamsResponse") @@ -363,49 +453,57 @@ func init() { proto.RegisterType((*QueryPoolsResponse)(nil), "lavanet.lava.rewards.QueryPoolsResponse") proto.RegisterType((*QueryBlockRewardRequest)(nil), "lavanet.lava.rewards.QueryBlockRewardRequest") proto.RegisterType((*QueryBlockRewardResponse)(nil), "lavanet.lava.rewards.QueryBlockRewardResponse") + proto.RegisterType((*QueryShowIprpcDataRequest)(nil), "lavanet.lava.rewards.QueryShowIprpcDataRequest") + proto.RegisterType((*QueryShowIprpcDataResponse)(nil), "lavanet.lava.rewards.QueryShowIprpcDataResponse") } func init() { proto.RegisterFile("lavanet/lava/rewards/query.proto", fileDescriptor_15bce9a904340007) } var fileDescriptor_15bce9a904340007 = []byte{ - // 584 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4d, 0x6e, 0xd3, 0x40, - 0x14, 0x8e, 0x9b, 0x26, 0xc0, 0x04, 0x21, 0x31, 0x8d, 0x54, 0xd7, 0x0d, 0x26, 0x98, 0x48, 0x0d, - 0x95, 0xb0, 0xd5, 0xb0, 0x40, 0x80, 0x58, 0x10, 0x56, 0x48, 0x20, 0x51, 0xc3, 0x06, 0x36, 0xd6, - 0xd8, 0x9d, 0xb8, 0x16, 0xf6, 0x8c, 0xeb, 0x99, 0x14, 0xba, 0x42, 0x82, 0x0b, 0x20, 0xb1, 0xe1, - 0x0a, 0xdc, 0xa4, 0xcb, 0x4a, 0x6c, 0x58, 0x21, 0x94, 0x70, 0x02, 0x4e, 0x80, 0xfc, 0x66, 0x12, - 0x52, 0x25, 0x4d, 0xbb, 0xb2, 0x3d, 0xf3, 0xbd, 0xef, 0xe7, 0xbd, 0x27, 0xa3, 0x76, 0x4a, 0x0e, - 0x09, 0xa3, 0xd2, 0x2b, 0x9f, 0x5e, 0x41, 0xdf, 0x93, 0x62, 0x4f, 0x78, 0x07, 0x43, 0x5a, 0x1c, - 0xb9, 0x79, 0xc1, 0x25, 0xc7, 0x4d, 0x8d, 0x70, 0xcb, 0xa7, 0xab, 0x11, 0x56, 0x33, 0xe6, 0x31, - 0x07, 0x80, 0x57, 0xbe, 0x29, 0xac, 0xd5, 0x8a, 0x39, 0x8f, 0x53, 0xea, 0x91, 0x3c, 0xf1, 0x08, - 0x63, 0x5c, 0x12, 0x99, 0x70, 0x26, 0xf4, 0xed, 0x76, 0xc4, 0x45, 0xc6, 0x85, 0x17, 0x12, 0x41, - 0x95, 0x84, 0x77, 0xb8, 0x13, 0x52, 0x49, 0x76, 0xbc, 0x9c, 0xc4, 0x09, 0x03, 0xb0, 0xc6, 0xde, - 0x5a, 0xe8, 0x2b, 0x27, 0x05, 0xc9, 0x26, 0x74, 0xf6, 0x2c, 0xdd, 0x84, 0x28, 0xe2, 0x89, 0xa6, - 0x70, 0x9a, 0x08, 0xef, 0x96, 0x22, 0x2f, 0xa1, 0xc8, 0xa7, 0x07, 0x43, 0x2a, 0xa4, 0xb3, 0x8b, - 0xd6, 0x4e, 0x9d, 0x8a, 0x9c, 0x33, 0x41, 0xf1, 0x43, 0x54, 0x57, 0xe4, 0xa6, 0xd1, 0x36, 0xba, - 0x8d, 0x5e, 0xcb, 0x5d, 0x14, 0xdb, 0x55, 0x55, 0xfd, 0xd5, 0xe3, 0x5f, 0x37, 0x2b, 0xbe, 0xae, - 0x70, 0xd6, 0xd0, 0x75, 0x45, 0xc9, 0x79, 0x3a, 0xd5, 0x79, 0x83, 0x2e, 0x97, 0xdf, 0xcf, 0xd8, - 0x80, 0x63, 0x8c, 0x56, 0x19, 0xc9, 0x28, 0x50, 0x5f, 0xf1, 0xe1, 0x1d, 0x3f, 0x40, 0x97, 0x42, - 0x92, 0x12, 0x16, 0x51, 0x73, 0x05, 0x14, 0x37, 0x5c, 0x95, 0xc7, 0x2d, 0xf3, 0xb8, 0x3a, 0x8f, - 0xfb, 0x94, 0x27, 0x4c, 0xcb, 0x4d, 0xf0, 0xce, 0x5f, 0x63, 0x92, 0x4c, 0x09, 0x4e, 0x23, 0xd4, - 0xf2, 0xf2, 0xc0, 0x34, 0xda, 0xd5, 0x6e, 0xa3, 0x67, 0x9f, 0x91, 0x40, 0x9b, 0xd2, 0xa4, 0xaa, - 0x04, 0x77, 0xd0, 0x35, 0x99, 0x64, 0x34, 0x90, 0x3c, 0x28, 0xe8, 0x20, 0x49, 0x53, 0x30, 0x55, - 0xf5, 0xaf, 0x96, 0xa7, 0xaf, 0xb9, 0x0f, 0x67, 0xf8, 0x11, 0xb2, 0xa8, 0x90, 0x49, 0x46, 0x24, - 0xdd, 0x0b, 0xc2, 0x94, 0x47, 0xef, 0xc4, 0x4c, 0x45, 0x15, 0x2a, 0xd6, 0xa7, 0x88, 0x3e, 0x00, - 0xa6, 0xc5, 0x8f, 0xd1, 0x26, 0x49, 0x53, 0x1e, 0xc1, 0x94, 0x83, 0x52, 0x36, 0xc8, 0x38, 0x93, - 0xfb, 0x22, 0x48, 0xe9, 0x40, 0x9a, 0xab, 0x50, 0x6d, 0xfe, 0x87, 0x94, 0x46, 0x5f, 0x00, 0xe0, - 0x39, 0x1d, 0x48, 0x67, 0x03, 0xad, 0x43, 0x66, 0x60, 0xf5, 0x21, 0xcc, 0xa4, 0xd5, 0xaf, 0x90, - 0x39, 0x7f, 0xa5, 0x9b, 0x72, 0x1f, 0xd5, 0x55, 0x72, 0x3d, 0xd7, 0x73, 0xbb, 0xac, 0xe1, 0xbd, - 0xef, 0x55, 0x54, 0x03, 0x56, 0xfc, 0xd9, 0x40, 0x75, 0x35, 0x77, 0xdc, 0x5d, 0xdc, 0xd3, 0xf9, - 0x35, 0xb3, 0xee, 0x5c, 0x00, 0xa9, 0x2c, 0x3a, 0x9d, 0x4f, 0x3f, 0xfe, 0x7c, 0x5d, 0xb1, 0x71, - 0xcb, 0x5b, 0xb2, 0xf3, 0xf8, 0x23, 0xaa, 0xc1, 0xb8, 0xf1, 0xd6, 0x32, 0xe6, 0x99, 0x0d, 0xb4, - 0xba, 0xe7, 0x03, 0xb5, 0x83, 0xdb, 0xe0, 0xe0, 0x06, 0xde, 0x3c, 0xc3, 0x01, 0xe8, 0x7e, 0x33, - 0x50, 0x63, 0xa6, 0xc3, 0xf8, 0xee, 0x12, 0xfa, 0xf9, 0x21, 0x59, 0xee, 0x45, 0xe1, 0xda, 0xd3, - 0x36, 0x78, 0xea, 0x60, 0x67, 0xb1, 0x27, 0xd8, 0xbe, 0x40, 0x7d, 0xf5, 0x9f, 0x1c, 0x8f, 0x6c, - 0xe3, 0x64, 0x64, 0x1b, 0xbf, 0x47, 0xb6, 0xf1, 0x65, 0x6c, 0x57, 0x4e, 0xc6, 0x76, 0xe5, 0xe7, - 0xd8, 0xae, 0xbc, 0xdd, 0x8a, 0x13, 0xb9, 0x3f, 0x0c, 0xdd, 0x88, 0x67, 0xa7, 0x79, 0x3e, 0x4c, - 0x99, 0xe4, 0x51, 0x4e, 0x45, 0x58, 0x87, 0x7f, 0xc6, 0xbd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x79, 0x4e, 0x97, 0x29, 0x10, 0x05, 0x00, 0x00, + // 688 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4f, 0x4f, 0xd4, 0x40, + 0x14, 0xdf, 0xb2, 0xcb, 0x02, 0x83, 0x9a, 0x38, 0x90, 0x50, 0x0a, 0xd6, 0xb5, 0x62, 0x58, 0x49, + 0x68, 0x05, 0x0f, 0x46, 0x8d, 0x07, 0xc1, 0x0b, 0x89, 0x26, 0x52, 0xbc, 0xe8, 0xa5, 0x99, 0x96, + 0xd9, 0xdd, 0xc6, 0xb6, 0xaf, 0x74, 0x66, 0x41, 0x4e, 0x26, 0x7a, 0xf2, 0x66, 0xe2, 0xc5, 0xab, + 0xdf, 0x86, 0x8b, 0x09, 0x89, 0x17, 0x4f, 0xc6, 0x80, 0x9f, 0xc0, 0x4f, 0x60, 0xfa, 0x3a, 0xbb, + 0x2e, 0xa1, 0x2c, 0x7b, 0x6a, 0x3b, 0xf3, 0x7b, 0xbf, 0x3f, 0x33, 0xef, 0x95, 0x34, 0x22, 0xb6, + 0xcf, 0x12, 0x2e, 0x9d, 0xfc, 0xe9, 0x64, 0xfc, 0x80, 0x65, 0xbb, 0xc2, 0xd9, 0xeb, 0xf2, 0xec, + 0xd0, 0x4e, 0x33, 0x90, 0x40, 0x67, 0x15, 0xc2, 0xce, 0x9f, 0xb6, 0x42, 0x18, 0xb3, 0x6d, 0x68, + 0x03, 0x02, 0x9c, 0xfc, 0xad, 0xc0, 0x1a, 0x8b, 0x6d, 0x80, 0x76, 0xc4, 0x1d, 0x96, 0x86, 0x0e, + 0x4b, 0x12, 0x90, 0x4c, 0x86, 0x90, 0x08, 0xb5, 0xbb, 0x12, 0x80, 0x88, 0x41, 0x38, 0x3e, 0x13, + 0xbc, 0x90, 0x70, 0xf6, 0xd7, 0x7c, 0x2e, 0xd9, 0x9a, 0x93, 0xb2, 0x76, 0x98, 0x20, 0x58, 0x61, + 0x6f, 0x95, 0xfa, 0x4a, 0x59, 0xc6, 0xe2, 0x1e, 0x9d, 0x39, 0x48, 0xd7, 0x23, 0x0a, 0x20, 0x54, + 0x14, 0xd6, 0x2c, 0xa1, 0xdb, 0xb9, 0xc8, 0x4b, 0x2c, 0x72, 0xf9, 0x5e, 0x97, 0x0b, 0x69, 0x6d, + 0x93, 0x99, 0x33, 0xab, 0x22, 0x85, 0x44, 0x70, 0xfa, 0x88, 0xd4, 0x0b, 0x72, 0x5d, 0x6b, 0x68, + 0xcd, 0xe9, 0xf5, 0x45, 0xbb, 0x2c, 0xb6, 0x5d, 0x54, 0x6d, 0xd4, 0x8e, 0x7e, 0xdd, 0xac, 0xb8, + 0xaa, 0xc2, 0x9a, 0x21, 0xd7, 0x0b, 0x4a, 0x80, 0xa8, 0xaf, 0xf3, 0x9a, 0x4c, 0xe6, 0xdf, 0x5b, + 0x49, 0x0b, 0x28, 0x25, 0xb5, 0x84, 0xc5, 0x1c, 0xa9, 0xa7, 0x5c, 0x7c, 0xa7, 0x0f, 0xc9, 0x84, + 0xcf, 0x22, 0x96, 0x04, 0x5c, 0x1f, 0x43, 0xc5, 0x79, 0xbb, 0xc8, 0x63, 0xe7, 0x79, 0x6c, 0x95, + 0xc7, 0xde, 0x84, 0x30, 0x51, 0x72, 0x3d, 0xbc, 0xf5, 0x57, 0xeb, 0x25, 0x2b, 0x04, 0xfb, 0x11, + 0xc6, 0xd3, 0x7c, 0x41, 0xd7, 0x1a, 0xd5, 0xe6, 0xf4, 0xba, 0x79, 0x41, 0x02, 0x65, 0x4a, 0x91, + 0x16, 0x25, 0x74, 0x89, 0x5c, 0x93, 0x61, 0xcc, 0x3d, 0x09, 0x5e, 0xc6, 0x5b, 0x61, 0x14, 0xa1, + 0xa9, 0xaa, 0x7b, 0x25, 0x5f, 0x7d, 0x05, 0x2e, 0xae, 0xd1, 0xc7, 0xc4, 0xe0, 0x42, 0x86, 0x31, + 0x93, 0x7c, 0xd7, 0xf3, 0x23, 0x08, 0xde, 0x8a, 0x81, 0x8a, 0x2a, 0x56, 0xcc, 0xf5, 0x11, 0x1b, + 0x08, 0xe8, 0x17, 0x3f, 0x21, 0x0b, 0x2c, 0x8a, 0x20, 0xc0, 0x5b, 0xf6, 0x72, 0x59, 0x2f, 0x86, + 0x44, 0x76, 0x84, 0x17, 0xf1, 0x96, 0xd4, 0x6b, 0x58, 0xad, 0xff, 0x87, 0xe4, 0x46, 0x5f, 0x20, + 0xe0, 0x39, 0x6f, 0x49, 0x6b, 0x9e, 0xcc, 0x61, 0x66, 0x64, 0x75, 0x31, 0x4c, 0xef, 0xa8, 0x77, + 0x88, 0x7e, 0x7e, 0x4b, 0x1d, 0xca, 0x03, 0x52, 0x2f, 0x92, 0xab, 0x7b, 0xbd, 0xf4, 0x94, 0x15, + 0xdc, 0x5a, 0x20, 0xf3, 0x48, 0xba, 0xd3, 0x81, 0x83, 0xad, 0x34, 0x4b, 0x83, 0x67, 0x4c, 0xb2, + 0x9e, 0xe2, 0x27, 0x8d, 0x18, 0x65, 0xbb, 0xfd, 0x9b, 0x98, 0x8c, 0xc3, 0xc4, 0x0b, 0x40, 0xc8, + 0x51, 0x65, 0x27, 0xe2, 0x30, 0xd9, 0x04, 0x21, 0xa9, 0x43, 0x66, 0xc2, 0x9c, 0xd0, 0x13, 0x5d, + 0x5f, 0x04, 0x59, 0x98, 0xe2, 0x04, 0xe9, 0x63, 0x8d, 0x6a, 0x73, 0xca, 0xa5, 0xb8, 0xb5, 0x33, + 0xb8, 0xb3, 0xfe, 0xbd, 0x46, 0xc6, 0xd1, 0x0b, 0xfd, 0xa8, 0x91, 0x7a, 0xd1, 0xa0, 0xb4, 0x59, + 0x7e, 0xf9, 0xe7, 0xe7, 0xc1, 0xb8, 0x3b, 0x02, 0xb2, 0x88, 0x65, 0x2d, 0x7d, 0xf8, 0xf1, 0xe7, + 0xcb, 0x98, 0x49, 0x17, 0x9d, 0x21, 0xc3, 0x49, 0xdf, 0x93, 0x71, 0xec, 0x4b, 0xba, 0x3c, 0x8c, + 0x79, 0x60, 0x54, 0x8c, 0xe6, 0xe5, 0x40, 0xe5, 0xe0, 0x36, 0x3a, 0xb8, 0x41, 0x17, 0x2e, 0x70, + 0x80, 0xba, 0x5f, 0x35, 0x32, 0x3d, 0xd0, 0x0a, 0x74, 0x75, 0x08, 0xfd, 0xf9, 0x6e, 0x32, 0xec, + 0x51, 0xe1, 0xca, 0xd3, 0x0a, 0x7a, 0x5a, 0xa2, 0x56, 0xb9, 0x27, 0x1c, 0x13, 0xaf, 0xf8, 0xa2, + 0xdf, 0x34, 0x72, 0xf5, 0x4c, 0xcb, 0x50, 0x67, 0x88, 0x5a, 0x59, 0xeb, 0x19, 0xf7, 0x46, 0x2f, + 0x50, 0x06, 0x57, 0xd1, 0xe0, 0x32, 0xbd, 0x53, 0x6e, 0x50, 0x74, 0xe0, 0xc0, 0x2b, 0x5a, 0x6e, + 0x97, 0x49, 0xb6, 0xf1, 0xf4, 0xe8, 0xc4, 0xd4, 0x8e, 0x4f, 0x4c, 0xed, 0xf7, 0x89, 0xa9, 0x7d, + 0x3e, 0x35, 0x2b, 0xc7, 0xa7, 0x66, 0xe5, 0xe7, 0xa9, 0x59, 0x79, 0xb3, 0xdc, 0x0e, 0x65, 0xa7, + 0xeb, 0xdb, 0x01, 0xc4, 0x67, 0xa9, 0xde, 0xf5, 0xc9, 0xe4, 0x61, 0xca, 0x85, 0x5f, 0xc7, 0x1f, + 0xf0, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x15, 0xaa, 0x4c, 0x5d, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -426,6 +524,8 @@ type QueryClient interface { Pools(ctx context.Context, in *QueryPoolsRequest, opts ...grpc.CallOption) (*QueryPoolsResponse, error) // BlockReward queries for the validators reward for proposing a block BlockReward(ctx context.Context, in *QueryBlockRewardRequest, opts ...grpc.CallOption) (*QueryBlockRewardResponse, error) + // ShowIprpcData queries for the iprpc data + ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataRequest, opts ...grpc.CallOption) (*QueryShowIprpcDataResponse, error) } type queryClient struct { @@ -463,6 +563,15 @@ func (c *queryClient) BlockReward(ctx context.Context, in *QueryBlockRewardReque return out, nil } +func (c *queryClient) ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataRequest, opts ...grpc.CallOption) (*QueryShowIprpcDataResponse, error) { + out := new(QueryShowIprpcDataResponse) + err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Query/ShowIprpcData", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Parameters queries the parameters of the module. @@ -471,6 +580,8 @@ type QueryServer interface { Pools(context.Context, *QueryPoolsRequest) (*QueryPoolsResponse, error) // BlockReward queries for the validators reward for proposing a block BlockReward(context.Context, *QueryBlockRewardRequest) (*QueryBlockRewardResponse, error) + // ShowIprpcData queries for the iprpc data + ShowIprpcData(context.Context, *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -486,6 +597,9 @@ func (*UnimplementedQueryServer) Pools(ctx context.Context, req *QueryPoolsReque func (*UnimplementedQueryServer) BlockReward(ctx context.Context, req *QueryBlockRewardRequest) (*QueryBlockRewardResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method BlockReward not implemented") } +func (*UnimplementedQueryServer) ShowIprpcData(ctx context.Context, req *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShowIprpcData not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -545,6 +659,24 @@ func _Query_BlockReward_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Query_ShowIprpcData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryShowIprpcDataRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ShowIprpcData(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/lavanet.lava.rewards.Query/ShowIprpcData", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ShowIprpcData(ctx, req.(*QueryShowIprpcDataRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "lavanet.lava.rewards.Query", HandlerType: (*QueryServer)(nil), @@ -561,6 +693,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "BlockReward", Handler: _Query_BlockReward_Handler, }, + { + MethodName: "ShowIprpcData", + Handler: _Query_ShowIprpcData_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "lavanet/lava/rewards/query.proto", @@ -793,6 +929,71 @@ func (m *QueryBlockRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *QueryShowIprpcDataRequest) 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 *QueryShowIprpcDataRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryShowIprpcDataRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryShowIprpcDataResponse) 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 *QueryShowIprpcDataResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryShowIprpcDataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.IprpcSubscriptions) > 0 { + for iNdEx := len(m.IprpcSubscriptions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.IprpcSubscriptions[iNdEx]) + copy(dAtA[i:], m.IprpcSubscriptions[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.IprpcSubscriptions[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.MinCost.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 @@ -892,6 +1093,32 @@ func (m *QueryBlockRewardResponse) Size() (n int) { return n } +func (m *QueryShowIprpcDataRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryShowIprpcDataResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.MinCost.Size() + n += 1 + l + sovQuery(uint64(l)) + if len(m.IprpcSubscriptions) > 0 { + for _, s := range m.IprpcSubscriptions { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1470,6 +1697,171 @@ func (m *QueryBlockRewardResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryShowIprpcDataRequest) 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: QueryShowIprpcDataRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryShowIprpcDataRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryShowIprpcDataResponse) 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: QueryShowIprpcDataResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryShowIprpcDataResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinCost", 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 err := m.MinCost.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcSubscriptions", 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.IprpcSubscriptions = append(m.IprpcSubscriptions, 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 skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/rewards/types/query.pb.gw.go b/x/rewards/types/query.pb.gw.go index 1ff3ce8a27..946b59839e 100644 --- a/x/rewards/types/query.pb.gw.go +++ b/x/rewards/types/query.pb.gw.go @@ -87,6 +87,24 @@ func local_request_Query_BlockReward_0(ctx context.Context, marshaler runtime.Ma } +func request_Query_ShowIprpcData_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryShowIprpcDataRequest + var metadata runtime.ServerMetadata + + msg, err := client.ShowIprpcData(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ShowIprpcData_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryShowIprpcDataRequest + var metadata runtime.ServerMetadata + + msg, err := server.ShowIprpcData(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. @@ -162,6 +180,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ShowIprpcData_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_ShowIprpcData_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_ShowIprpcData_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -263,6 +304,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ShowIprpcData_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_ShowIprpcData_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_ShowIprpcData_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -272,6 +333,8 @@ var ( pattern_Query_Pools_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "pools"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_BlockReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "block_reward"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_ShowIprpcData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "show_iprpc_data"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -280,4 +343,6 @@ var ( forward_Query_Pools_0 = runtime.ForwardResponseMessage forward_Query_BlockReward_0 = runtime.ForwardResponseMessage + + forward_Query_ShowIprpcData_0 = runtime.ForwardResponseMessage ) From a93e64b7d92d332cec4ab7ee7f9a9609fdacb5e5 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 8 Feb 2024 17:31:04 +0200 Subject: [PATCH 05/64] CNS-868: scaffold tx set iprpc data --- app/app.go | 1 + proto/lavanet/lava/rewards/tx.proto | 13 + x/rewards/keeper/iprpc_data.go | 19 + x/rewards/keeper/keeper.go | 6 + x/rewards/keeper/msg_server_set_iprpc_data.go | 37 ++ x/rewards/types/codec.go | 6 +- x/rewards/types/message_set_iprpc_data.go | 56 ++ .../types/message_set_iprpc_data_test.go | 57 ++ x/rewards/types/tx.pb.go | 583 +++++++++++++++++- x/rewards/types/types.go | 4 + 10 files changed, 769 insertions(+), 13 deletions(-) create mode 100644 x/rewards/keeper/msg_server_set_iprpc_data.go create mode 100644 x/rewards/types/message_set_iprpc_data.go create mode 100644 x/rewards/types/message_set_iprpc_data_test.go diff --git a/app/app.go b/app/app.go index 1862b916b2..aef0fdfabe 100644 --- a/app/app.go +++ b/app/app.go @@ -524,6 +524,7 @@ func New( app.DistrKeeper, authtypes.FeeCollectorName, app.TimerStoreKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) rewardsModule := rewardsmodule.NewAppModule(appCodec, app.RewardsKeeper, app.AccountKeeper, app.BankKeeper) diff --git a/proto/lavanet/lava/rewards/tx.proto b/proto/lavanet/lava/rewards/tx.proto index b5baaf8951..c89345cef4 100644 --- a/proto/lavanet/lava/rewards/tx.proto +++ b/proto/lavanet/lava/rewards/tx.proto @@ -1,13 +1,26 @@ syntax = "proto3"; package lavanet.lava.rewards; +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; + // this line is used by starport scaffolding # proto/tx/import option go_package = "github.com/lavanet/lava/x/rewards/types"; // Msg defines the Msg service. service Msg { + rpc SetIprpcData(MsgSetIprpcData) returns (MsgSetIprpcDataResponse); // this line is used by starport scaffolding # proto/tx/rpc } +message MsgSetIprpcData { + string authority = 1; + cosmos.base.v1beta1.Coin min_iprpc_cost = 2 [(gogoproto.nullable) = false]; + repeated string iprpc_subscriptions = 3; +} + +message MsgSetIprpcDataResponse { +} + // this line is used by starport scaffolding # proto/tx/message \ No newline at end of file diff --git a/x/rewards/keeper/iprpc_data.go b/x/rewards/keeper/iprpc_data.go index fd0152cbbc..45e28c6b5d 100644 --- a/x/rewards/keeper/iprpc_data.go +++ b/x/rewards/keeper/iprpc_data.go @@ -1,11 +1,30 @@ package keeper import ( + "fmt" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/utils" "github.com/lavanet/lava/x/rewards/types" ) +func (k Keeper) SetIprpcData(ctx sdk.Context, cost sdk.Coin, subs []string) error { + if cost.Denom != k.stakingKeeper.BondDenom(ctx) { + return utils.LavaFormatWarning("min iprpc cost must be in acceptable denom", fmt.Errorf("invalid cost"), + utils.LogAttr("cost", cost.String()), + utils.LogAttr("acceptable_denom", k.stakingKeeper.BondDenom(ctx)), + ) + } + k.SetMinIprpcCost(ctx, cost) + + for _, sub := range subs { + k.SetIprpcSubscription(ctx, sub) + } + + return nil +} + /********************** Min IPRPC Cost **********************/ // SetMinIprpcCost sets the min iprpc cost diff --git a/x/rewards/keeper/keeper.go b/x/rewards/keeper/keeper.go index 8875fc3090..2b3334e001 100644 --- a/x/rewards/keeper/keeper.go +++ b/x/rewards/keeper/keeper.go @@ -37,6 +37,10 @@ type ( // the timer subkey holds the block in which the timer will expire (not exact) // the timer data holds the number of months left for the allocation pools (until all funds are gone) refillRewardsPoolTS timerstoretypes.TimerStore + + // the address capable of executing a MsgSetIprpcData message. Typically, this + // should be the x/gov module account. + authority string } ) @@ -55,6 +59,7 @@ func NewKeeper( distributionKeeper types.DistributionKeeper, feeCollectorName string, timerStoreKeeper types.TimerStoreKeeper, + authority string, ) *Keeper { // set KeyTable if it has not already been set if !ps.HasKeyTable() { @@ -77,6 +82,7 @@ func NewKeeper( distributionKeeper: distributionKeeper, feeCollectorName: feeCollectorName, + authority: authority, } refillRewardsPoolTimerCallback := func(ctx sdk.Context, subkey, data []byte) { diff --git a/x/rewards/keeper/msg_server_set_iprpc_data.go b/x/rewards/keeper/msg_server_set_iprpc_data.go new file mode 100644 index 0000000000..9e587db914 --- /dev/null +++ b/x/rewards/keeper/msg_server_set_iprpc_data.go @@ -0,0 +1,37 @@ +package keeper + +import ( + "context" + "strings" + + sdkerrors "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/lavanet/lava/utils" + "github.com/lavanet/lava/x/rewards/types" +) + +func (k msgServer) SetIprpcData(goCtx context.Context, msg *types.MsgSetIprpcData) (*types.MsgSetIprpcDataResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + err := msg.ValidateBasic() + if err != nil { + return &types.MsgSetIprpcDataResponse{}, err + } + + if msg.Authority != k.authority { + sdkerrors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) + } + + err = k.Keeper.SetIprpcData(ctx, msg.MinIprpcCost, msg.IprpcSubscriptions) + if err == nil { + logger := k.Keeper.Logger(ctx) + details := map[string]string{ + "min_cost": msg.MinIprpcCost.String(), + "subscriptions": strings.Join(msg.IprpcSubscriptions, ","), + } + utils.LogLavaEvent(ctx, logger, types.SetIprpcDataEventName, details, "Set IPRPC Data") + } + + return &types.MsgSetIprpcDataResponse{}, err +} diff --git a/x/rewards/types/codec.go b/x/rewards/types/codec.go index 8883bdf684..4a3fc0d903 100644 --- a/x/rewards/types/codec.go +++ b/x/rewards/types/codec.go @@ -3,18 +3,22 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" // this line is used by starport scaffolding # 1 "github.com/cosmos/cosmos-sdk/types/msgservice" ) func RegisterCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgSetIprpcData{}, "rewards/MsgSetIprpcData", nil) // this line is used by starport scaffolding # 2 } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { // this line is used by starport scaffolding # 3 - + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgSetIprpcData{}, + ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/rewards/types/message_set_iprpc_data.go b/x/rewards/types/message_set_iprpc_data.go new file mode 100644 index 0000000000..d7c0cc75ac --- /dev/null +++ b/x/rewards/types/message_set_iprpc_data.go @@ -0,0 +1,56 @@ +package types + +import ( + "fmt" + + sdkerrors "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const TypeMsgSetIprpcData = "set_iprpc_data" + +var _ sdk.Msg = &MsgSetIprpcData{} + +func NewMsgSetIprpcData(authority string, cost sdk.Coin, subs []string) *MsgSetIprpcData { + return &MsgSetIprpcData{ + Authority: authority, + MinIprpcCost: cost, + IprpcSubscriptions: subs, + } +} + +func (msg *MsgSetIprpcData) Route() string { + return RouterKey +} + +func (msg *MsgSetIprpcData) Type() string { + return TypeMsgSetIprpcData +} + +func (msg *MsgSetIprpcData) GetSigners() []sdk.AccAddress { + authority, _ := sdk.AccAddressFromBech32(msg.Authority) + return []sdk.AccAddress{authority} +} + +func (msg *MsgSetIprpcData) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgSetIprpcData) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil { + return sdkerrors.Wrap(err, "invalid authority address") + } + + if !msg.MinIprpcCost.IsValid() { + return sdkerrors.Wrap(fmt.Errorf("invalid min iprpc cost; invalid denom or negative amount. coin: %s", msg.MinIprpcCost.String()), "") + } + + for _, sub := range msg.IprpcSubscriptions { + if _, err := sdk.AccAddressFromBech32(sub); err != nil { + return sdkerrors.Wrap(err, "invalid subscription address") + } + } + + return nil +} diff --git a/x/rewards/types/message_set_iprpc_data_test.go b/x/rewards/types/message_set_iprpc_data_test.go new file mode 100644 index 0000000000..9e67c77dfb --- /dev/null +++ b/x/rewards/types/message_set_iprpc_data_test.go @@ -0,0 +1,57 @@ +package types + +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + commontypes "github.com/lavanet/lava/common/types" + "github.com/lavanet/lava/testutil/sample" + "github.com/stretchr/testify/require" +) + +func TestSetIprpcData_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg MsgSetIprpcData + valid bool + }{ + { + name: "invalid authority address", + msg: MsgSetIprpcData{ + Authority: "invalid_address", + MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, math.ZeroInt()), + IprpcSubscriptions: []string{sample.AccAddress()}, + }, + valid: false, + }, + { + name: "invalid subscription address", + msg: MsgSetIprpcData{ + Authority: sample.AccAddress(), + MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, math.ZeroInt()), + IprpcSubscriptions: []string{sample.AccAddress(), "invalid_address"}, + }, + valid: false, + }, + { + name: "valid message", + msg: MsgSetIprpcData{ + Authority: sample.AccAddress(), + MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, math.ZeroInt()), + IprpcSubscriptions: []string{sample.AccAddress()}, + }, + valid: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.msg.ValidateBasic() + if tt.valid { + require.NoError(t, err) + return + } + require.Error(t, err) + }) + } +} diff --git a/x/rewards/types/tx.pb.go b/x/rewards/types/tx.pb.go index e1bcba1cd9..e0886a5318 100644 --- a/x/rewards/types/tx.pb.go +++ b/x/rewards/types/tx.pb.go @@ -6,10 +6,16 @@ package types import ( context "context" fmt "fmt" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" 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. @@ -23,18 +29,132 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type MsgSetIprpcData struct { + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + MinIprpcCost types.Coin `protobuf:"bytes,2,opt,name=min_iprpc_cost,json=minIprpcCost,proto3" json:"min_iprpc_cost"` + IprpcSubscriptions []string `protobuf:"bytes,3,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` +} + +func (m *MsgSetIprpcData) Reset() { *m = MsgSetIprpcData{} } +func (m *MsgSetIprpcData) String() string { return proto.CompactTextString(m) } +func (*MsgSetIprpcData) ProtoMessage() {} +func (*MsgSetIprpcData) Descriptor() ([]byte, []int) { + return fileDescriptor_6a4c66e189226d78, []int{0} +} +func (m *MsgSetIprpcData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetIprpcData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetIprpcData.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 *MsgSetIprpcData) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetIprpcData.Merge(m, src) +} +func (m *MsgSetIprpcData) XXX_Size() int { + return m.Size() +} +func (m *MsgSetIprpcData) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetIprpcData.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetIprpcData proto.InternalMessageInfo + +func (m *MsgSetIprpcData) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgSetIprpcData) GetMinIprpcCost() types.Coin { + if m != nil { + return m.MinIprpcCost + } + return types.Coin{} +} + +func (m *MsgSetIprpcData) GetIprpcSubscriptions() []string { + if m != nil { + return m.IprpcSubscriptions + } + return nil +} + +type MsgSetIprpcDataResponse struct { +} + +func (m *MsgSetIprpcDataResponse) Reset() { *m = MsgSetIprpcDataResponse{} } +func (m *MsgSetIprpcDataResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetIprpcDataResponse) ProtoMessage() {} +func (*MsgSetIprpcDataResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6a4c66e189226d78, []int{1} +} +func (m *MsgSetIprpcDataResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetIprpcDataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetIprpcDataResponse.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 *MsgSetIprpcDataResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetIprpcDataResponse.Merge(m, src) +} +func (m *MsgSetIprpcDataResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetIprpcDataResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetIprpcDataResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetIprpcDataResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgSetIprpcData)(nil), "lavanet.lava.rewards.MsgSetIprpcData") + proto.RegisterType((*MsgSetIprpcDataResponse)(nil), "lavanet.lava.rewards.MsgSetIprpcDataResponse") +} + func init() { proto.RegisterFile("lavanet/lava/rewards/tx.proto", fileDescriptor_6a4c66e189226d78) } var fileDescriptor_6a4c66e189226d78 = []byte{ - // 124 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcd, 0x49, 0x2c, 0x4b, - 0xcc, 0x4b, 0x2d, 0xd1, 0x07, 0xd1, 0xfa, 0x45, 0xa9, 0xe5, 0x89, 0x45, 0x29, 0xc5, 0xfa, 0x25, - 0x15, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x22, 0x50, 0x69, 0x3d, 0x10, 0xad, 0x07, 0x95, - 0x36, 0x62, 0xe5, 0x62, 0xf6, 0x2d, 0x4e, 0x77, 0x72, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, - 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, - 0x63, 0x39, 0x86, 0x28, 0xf5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, - 0x14, 0x0b, 0x2a, 0x10, 0x56, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0xad, 0x31, 0x06, 0x04, - 0x00, 0x00, 0xff, 0xff, 0xfd, 0xa8, 0xea, 0x9f, 0x87, 0x00, 0x00, 0x00, + // 326 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xcf, 0x4e, 0x3a, 0x31, + 0x10, 0xc7, 0xb7, 0x3f, 0x7e, 0x31, 0xa1, 0x12, 0x4d, 0x56, 0x12, 0x81, 0x68, 0x25, 0x24, 0x46, + 0x2e, 0xb6, 0x01, 0x9f, 0x40, 0xd0, 0x83, 0x07, 0x2e, 0xcb, 0xcd, 0x0b, 0xe9, 0x2e, 0xcd, 0xd2, + 0xe8, 0x76, 0x36, 0x3b, 0x05, 0xe1, 0x2d, 0x7c, 0x0b, 0x5f, 0x85, 0x23, 0x47, 0x4f, 0xc6, 0xc0, + 0x8b, 0x98, 0xfd, 0x63, 0x10, 0xe2, 0xc1, 0xd3, 0x4c, 0xe6, 0x3b, 0x9d, 0xf9, 0x74, 0xbe, 0xf4, + 0xfc, 0x59, 0xce, 0xa4, 0x51, 0x56, 0xa4, 0x51, 0x24, 0xea, 0x45, 0x26, 0x63, 0x14, 0x76, 0xce, + 0xe3, 0x04, 0x2c, 0xb8, 0xd5, 0x42, 0xe6, 0x69, 0xe4, 0x85, 0xdc, 0x60, 0x01, 0x60, 0x04, 0x28, + 0x7c, 0x89, 0x4a, 0xcc, 0x3a, 0xbe, 0xb2, 0xb2, 0x23, 0x02, 0xd0, 0x26, 0x7f, 0xd5, 0xa8, 0x86, + 0x10, 0x42, 0x96, 0x8a, 0x34, 0xcb, 0xab, 0xad, 0x37, 0x42, 0x8f, 0x07, 0x18, 0x0e, 0x95, 0x7d, + 0x88, 0x93, 0x38, 0xb8, 0x93, 0x56, 0xba, 0x67, 0xb4, 0x2c, 0xa7, 0x76, 0x02, 0x89, 0xb6, 0x8b, + 0x1a, 0x69, 0x92, 0x76, 0xd9, 0xdb, 0x16, 0xdc, 0x7b, 0x7a, 0x14, 0x69, 0x33, 0xd2, 0x69, 0xfb, + 0x28, 0x00, 0xb4, 0xb5, 0x7f, 0x4d, 0xd2, 0x3e, 0xec, 0xd6, 0x79, 0x0e, 0xc0, 0x53, 0x00, 0x5e, + 0x00, 0xf0, 0x3e, 0x68, 0xd3, 0xfb, 0xbf, 0xfc, 0xb8, 0x70, 0xbc, 0x4a, 0xa4, 0x4d, 0xb6, 0xa4, + 0x0f, 0x68, 0x5d, 0x41, 0x4f, 0xf2, 0x11, 0x38, 0xf5, 0x31, 0x48, 0x74, 0x6c, 0x35, 0x18, 0xac, + 0x95, 0x9a, 0xa5, 0x76, 0xd9, 0x73, 0x33, 0x69, 0xf8, 0x53, 0x69, 0xd5, 0xe9, 0xe9, 0x1e, 0xa8, + 0xa7, 0x30, 0x06, 0x83, 0xaa, 0xfb, 0x44, 0x4b, 0x03, 0x0c, 0xdd, 0x31, 0xad, 0xec, 0xfc, 0xe3, + 0x92, 0xff, 0x76, 0x28, 0xbe, 0x37, 0xa5, 0x71, 0xfd, 0xa7, 0xb6, 0xef, 0x65, 0xbd, 0xdb, 0xe5, + 0x9a, 0x91, 0xd5, 0x9a, 0x91, 0xcf, 0x35, 0x23, 0xaf, 0x1b, 0xe6, 0xac, 0x36, 0xcc, 0x79, 0xdf, + 0x30, 0xe7, 0xf1, 0x2a, 0xd4, 0x76, 0x32, 0xf5, 0x79, 0x00, 0x91, 0xd8, 0x71, 0x70, 0xbe, 0xf5, + 0x70, 0x11, 0x2b, 0xf4, 0x0f, 0xb2, 0xdb, 0xdf, 0x7c, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7e, 0xc1, + 0x85, 0x7c, 0xe8, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -49,6 +169,7 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { + SetIprpcData(ctx context.Context, in *MsgSetIprpcData, opts ...grpc.CallOption) (*MsgSetIprpcDataResponse, error) } type msgClient struct { @@ -59,22 +180,460 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { return &msgClient{cc} } +func (c *msgClient) SetIprpcData(ctx context.Context, in *MsgSetIprpcData, opts ...grpc.CallOption) (*MsgSetIprpcDataResponse, error) { + out := new(MsgSetIprpcDataResponse) + err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Msg/SetIprpcData", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { + SetIprpcData(context.Context, *MsgSetIprpcData) (*MsgSetIprpcDataResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. type UnimplementedMsgServer struct { } +func (*UnimplementedMsgServer) SetIprpcData(ctx context.Context, req *MsgSetIprpcData) (*MsgSetIprpcDataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetIprpcData not implemented") +} + func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) } +func _Msg_SetIprpcData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetIprpcData) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetIprpcData(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/lavanet.lava.rewards.Msg/SetIprpcData", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetIprpcData(ctx, req.(*MsgSetIprpcData)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "lavanet.lava.rewards.Msg", HandlerType: (*MsgServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{}, - Metadata: "lavanet/lava/rewards/tx.proto", + Methods: []grpc.MethodDesc{ + { + MethodName: "SetIprpcData", + Handler: _Msg_SetIprpcData_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "lavanet/lava/rewards/tx.proto", +} + +func (m *MsgSetIprpcData) 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 *MsgSetIprpcData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetIprpcData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.IprpcSubscriptions) > 0 { + for iNdEx := len(m.IprpcSubscriptions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.IprpcSubscriptions[iNdEx]) + copy(dAtA[i:], m.IprpcSubscriptions[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.IprpcSubscriptions[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + { + size, err := m.MinIprpcCost.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSetIprpcDataResponse) 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 *MsgSetIprpcDataResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetIprpcDataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil } + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgSetIprpcData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.MinIprpcCost.Size() + n += 1 + l + sovTx(uint64(l)) + if len(m.IprpcSubscriptions) > 0 { + for _, s := range m.IprpcSubscriptions { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgSetIprpcDataResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgSetIprpcData) 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 ErrIntOverflowTx + } + 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: MsgSetIprpcData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetIprpcData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinIprpcCost", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MinIprpcCost.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcSubscriptions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IprpcSubscriptions = append(m.IprpcSubscriptions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSetIprpcDataResponse) 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 ErrIntOverflowTx + } + 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: MsgSetIprpcDataResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetIprpcDataResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/rewards/types/types.go b/x/rewards/types/types.go index 23c24e8207..936ac2e2bd 100644 --- a/x/rewards/types/types.go +++ b/x/rewards/types/types.go @@ -42,3 +42,7 @@ const ( RefillRewardsPoolTimerPrefix = "refill-rewards-pool-ts" RefillRewardsPoolTimerName = "refill-rewards-timer" ) + +const ( + SetIprpcDataEventName = "set-iprpc-data" +) From 95542cb665170c7c277afe1b6ffc401bc521ba94 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 8 Feb 2024 18:59:15 +0200 Subject: [PATCH 06/64] CNS-868: fix msg server to return error on bad authority --- x/rewards/keeper/msg_server_set_iprpc_data.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/rewards/keeper/msg_server_set_iprpc_data.go b/x/rewards/keeper/msg_server_set_iprpc_data.go index 9e587db914..05fb12e02e 100644 --- a/x/rewards/keeper/msg_server_set_iprpc_data.go +++ b/x/rewards/keeper/msg_server_set_iprpc_data.go @@ -20,7 +20,7 @@ func (k msgServer) SetIprpcData(goCtx context.Context, msg *types.MsgSetIprpcDat } if msg.Authority != k.authority { - sdkerrors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) + return &types.MsgSetIprpcDataResponse{}, sdkerrors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) } err = k.Keeper.SetIprpcData(ctx, msg.MinIprpcCost, msg.IprpcSubscriptions) From 6e2a2ec3f5f4c98eb2c4462c312ecb07f3f2d813 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 8 Feb 2024 19:00:31 +0200 Subject: [PATCH 07/64] CNS-868: tx proposal cli to automatically make proposal --- app/app.go | 2 + x/rewards/client/cli/tx.go | 124 ++++++++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/app/app.go b/app/app.go index aef0fdfabe..9379090aa1 100644 --- a/app/app.go +++ b/app/app.go @@ -138,6 +138,7 @@ import ( protocolmodulekeeper "github.com/lavanet/lava/x/protocol/keeper" protocolmoduletypes "github.com/lavanet/lava/x/protocol/types" rewardsmodule "github.com/lavanet/lava/x/rewards" + rewardsmoduleclient "github.com/lavanet/lava/x/rewards/client/cli" rewardsmodulekeeper "github.com/lavanet/lava/x/rewards/keeper" rewardsmoduletypes "github.com/lavanet/lava/x/rewards/types" specmodule "github.com/lavanet/lava/x/spec" @@ -198,6 +199,7 @@ func getGovProposalHandlers() []govclient.ProposalHandler { plansmoduleclient.PlansAddProposalHandler, plansmoduleclient.PlansDelProposalHandler, pairingmoduleclient.PairingUnstakeProposal, + rewardsmoduleclient.SetIprpcDataProposalHandler, // this line is used by starport scaffolding # stargate/app/govProposalHandler ) diff --git a/x/rewards/client/cli/tx.go b/x/rewards/client/cli/tx.go index db6b07d84a..e23fd2206c 100644 --- a/x/rewards/client/cli/tx.go +++ b/x/rewards/client/cli/tx.go @@ -1,21 +1,36 @@ package cli import ( + "context" "fmt" "time" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" // "github.com/cosmos/cosmos-sdk/client/flags" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govclient "github.com/cosmos/cosmos-sdk/x/gov/client" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + "github.com/lavanet/lava/utils/slices" "github.com/lavanet/lava/x/rewards/types" ) var DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) const ( - flagPacketTimeoutTimestamp = "packet-timeout-timestamp" - listSeparator = "," + flagPacketTimeoutTimestamp = "packet-timeout-timestamp" + listSeparator = "," + expeditedFlagName = "expedited" + minIprpcCostFlagName = "min-cost" + addIprpcSubscriptionsFlagName = "add-subscriptions" + removeIprpcSubscriptionsFlagName = "remove-subscriptions" ) // GetTxCmd returns the transaction commands for this module @@ -32,3 +47,106 @@ func GetTxCmd() *cobra.Command { return cmd } + +// SetIprpcDataProposalHandler is the param change proposal handler. +var SetIprpcDataProposalHandler = govclient.NewProposalHandler(NewSubmitSetIprpcDataProposalTxCmd) + +// NewSubmitSetIprpcDataProposalTxCmd returns a CLI command handler for creating +// a set-iprpc-data proposal governance transaction. +func NewSubmitSetIprpcDataProposalTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-iprpc-data --min-cost 0ulava --add-subscriptions addr1,addr2 --remove-subscriptions addr3,addr4", + Args: cobra.ExactArgs(1), + Short: "Submit a set IPRPC data proposal", + Long: strings.TrimSpace( + fmt.Sprintf(`Submit a set IPRPC data proposal along with an initial deposit. +The proposal details (IPRPC data to set) are supplied via optional flags. To set the minimum IPRPC cost, use the --min-cost flag. +To add IPRPC eligible subscriptions use the --add-subscriptions flag. To remove IPRPC eligible subscriptions use the --remove-subscriptions flag. +Optionally, you can make the proposal expedited using the --expedited flag. +Example: +$ %s tx gov submit-legacy-proposal set-iprpc-data --min-cost 0ulava --add-subscriptions addr1,addr2 --remove-subscriptions addr3,addr4 +`, + version.AppName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + from := clientCtx.GetFromAddress() + + isExpedited, err := cmd.Flags().GetBool(expeditedFlagName) + if err != nil { + return err + } + + // get min cost + costStr, err := cmd.Flags().GetString(minIprpcCostFlagName) + if err != nil { + return err + } + cost, err := sdk.ParseCoinNormalized(costStr) + if err != nil { + return err + } + + // get current iprpc subscriptions + q := types.NewQueryClient(clientCtx) + res, err := q.ShowIprpcData(context.Background(), &types.QueryShowIprpcDataRequest{}) + if err != nil { + return err + } + subs := res.IprpcSubscriptions + + // add from msg + subsToAdd, err := cmd.Flags().GetStringSlice(addIprpcSubscriptionsFlagName) + if err != nil { + return err + } + subs = append(subs, subsToAdd...) + + // remove duplicates + iprpcSubs := []string{} + unique := map[string]bool{} + for _, sub := range subs { + if !unique[sub] { + unique[sub] = true + iprpcSubs = append(iprpcSubs, sub) + } + } + + // remove from msg + subsToRemove, err := cmd.Flags().GetStringSlice(removeIprpcSubscriptionsFlagName) + if err != nil { + return err + } + for _, sub := range subsToRemove { + iprpcSubs, _ = slices.Remove(iprpcSubs, sub) + } + + deposit, err := sdk.ParseCoinsNormalized(args[0]) + if err != nil { + return err + } + + msg := types.MsgSetIprpcData{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + IprpcSubscriptions: iprpcSubs, + MinIprpcCost: cost, + } + + submitPropMsg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{&msg}, deposit, from.String(), "", "Set IPRPC data", "Set IPRPC data", isExpedited) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), submitPropMsg) + }, + } + cmd.Flags().String(minIprpcCostFlagName, "0ulava", "set minimum iprpc cost") + cmd.Flags().StringSlice(addIprpcSubscriptionsFlagName, []string{}, "add iprpc eligible subscriptions") + cmd.Flags().StringSlice(removeIprpcSubscriptionsFlagName, []string{}, "remove iprpc eligible subscriptions") + cmd.Flags().Bool(expeditedFlagName, false, "set to true to make the spec proposal expedited") + return cmd +} From 5e7d39e5a63d4f06e4538465fe33bcba926f67fe Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 11 Feb 2024 11:17:53 +0200 Subject: [PATCH 08/64] CNS-868: unit test --- testutil/common/tester.go | 5 +++ testutil/keeper/keepers_init.go | 2 +- testutil/keeper/rewards.go | 1 + x/rewards/keeper/iprpc_data_test.go | 56 +++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 3eef5f3638..b664e151ac 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -610,6 +610,11 @@ func (ts *Tester) TxPairingUnfreezeProvider(addr, chainID string) (*pairingtypes return ts.Servers.PairingServer.UnfreezeProvider(ts.GoCtx, msg) } +func (ts *Tester) TxRewardsSetIprpcDataProposal(ctx sdk.Context, authority string, cost sdk.Coin, subs []string) (*rewardstypes.MsgSetIprpcDataResponse, error) { + msg := rewardstypes.NewMsgSetIprpcData(authority, cost, subs) + return ts.Servers.RewardsServer.SetIprpcData(sdk.WrapSDKContext(ctx), msg) +} + // TxCreateValidator: implement 'tx staking createvalidator' and bond its tokens func (ts *Tester) TxCreateValidator(validator sigs.Account, amount math.Int) { consensusPowerTokens := ts.Keepers.StakingKeeper.TokensFromConsensusPower(ts.Ctx, 1) diff --git a/testutil/keeper/keepers_init.go b/testutil/keeper/keepers_init.go index 48aa35acc9..f3cc18733f 100644 --- a/testutil/keeper/keepers_init.go +++ b/testutil/keeper/keepers_init.go @@ -257,7 +257,7 @@ func InitAllKeepers(t testing.TB) (*Servers, *Keepers, context.Context) { ks.Projects = *projectskeeper.NewKeeper(cdc, projectsStoreKey, projectsMemStoreKey, projectsparamsSubspace, ks.Epochstorage, ks.FixationStoreKeeper) ks.Protocol = *protocolkeeper.NewKeeper(cdc, protocolStoreKey, protocolMemStoreKey, protocolparamsSubspace) ks.Downtime = downtimekeeper.NewKeeper(cdc, downtimeKey, downtimeParamsSubspace, ks.Epochstorage) - ks.Rewards = *rewardskeeper.NewKeeper(cdc, rewardsStoreKey, rewardsMemStoreKey, rewardsparamsSubspace, ks.BankKeeper, ks.AccountKeeper, ks.Spec, ks.Epochstorage, ks.Downtime, ks.StakingKeeper, ks.Dualstaking, ks.Distribution, authtypes.FeeCollectorName, ks.TimerStoreKeeper) + ks.Rewards = *rewardskeeper.NewKeeper(cdc, rewardsStoreKey, rewardsMemStoreKey, rewardsparamsSubspace, ks.BankKeeper, ks.AccountKeeper, ks.Spec, ks.Epochstorage, ks.Downtime, ks.StakingKeeper, ks.Dualstaking, ks.Distribution, authtypes.FeeCollectorName, ks.TimerStoreKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String()) ks.Subscription = *subscriptionkeeper.NewKeeper(cdc, subscriptionStoreKey, subscriptionMemStoreKey, subscriptionparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, &ks.Epochstorage, ks.Projects, ks.Plans, ks.Dualstaking, ks.Rewards, ks.FixationStoreKeeper, ks.TimerStoreKeeper, ks.StakingKeeper) ks.Pairing = *pairingkeeper.NewKeeper(cdc, pairingStoreKey, pairingMemStoreKey, pairingparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, ks.Spec, &ks.Epochstorage, ks.Projects, ks.Subscription, ks.Plans, ks.Downtime, ks.Dualstaking, &ks.StakingKeeper, ks.FixationStoreKeeper, ks.TimerStoreKeeper) ks.ParamsKeeper = paramsKeeper diff --git a/testutil/keeper/rewards.go b/testutil/keeper/rewards.go index c3d1dbf0ed..dcaf8a43d5 100644 --- a/testutil/keeper/rewards.go +++ b/testutil/keeper/rewards.go @@ -93,6 +93,7 @@ func RewardsKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { distributionKeeper, authtypes.FeeCollectorName, timerstorekeeper.NewKeeper(cdc), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) // Initialize params diff --git a/x/rewards/keeper/iprpc_data_test.go b/x/rewards/keeper/iprpc_data_test.go index b295c6c9a8..330cb09879 100644 --- a/x/rewards/keeper/iprpc_data_test.go +++ b/x/rewards/keeper/iprpc_data_test.go @@ -11,6 +11,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/lavanet/lava/testutil/common" + "github.com/lavanet/lava/testutil/sample" ) // Prevent strconv unused error @@ -66,3 +71,54 @@ func TestIprpcSubscriptionsGetAll(t *testing.T) { nullify.Fill(keeper.GetAllIprpcSubscription(ctx)), ) } + +// TestIprpcDataValidation tests that IPRPC data's validation works as expected +func TestIprpcDataValidation(t *testing.T) { + ts := newTester(t, true) + _, val := ts.GetAccount(common.VALIDATOR, 0) + + template := []struct { + name string + authority string + cost sdk.Coin + subs []string + success bool + }{ + { + name: "valid data", + authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + cost: sdk.NewCoin(ts.TokenDenom(), math.OneInt()), + subs: []string{sample.AccAddress()}, + success: true, + }, + { + name: "invalid auth", + authority: val, + cost: sdk.NewCoin(ts.TokenDenom(), math.OneInt()), + subs: []string{sample.AccAddress()}, + success: false, + }, + { + name: "invalid subs", + authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + cost: sdk.NewCoin(ts.TokenDenom(), math.OneInt()), + subs: []string{sample.AccAddress(), "invalid_addr"}, + success: false, + }, + } + + for _, tt := range template { + t.Run(tt.name, func(t *testing.T) { + _, err := ts.TxRewardsSetIprpcDataProposal(ts.Ctx, tt.authority, tt.cost, tt.subs) + if tt.success { + require.NoError(t, err) + res, err := ts.QueryShowIprpcData() + require.NoError(t, err) + require.True(t, tt.cost.IsEqual(res.MinCost)) + require.Equal(t, tt.subs, res.IprpcSubscriptions) + } else { + require.Error(t, err) + } + }) + } +} From 09b6c2124a51a9374e701cc4ef3643500e8627a4 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 11 Feb 2024 11:41:39 +0200 Subject: [PATCH 09/64] CNS-868: fix lint --- x/rewards/client/cli/tx.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x/rewards/client/cli/tx.go b/x/rewards/client/cli/tx.go index e23fd2206c..e34b4d5bf0 100644 --- a/x/rewards/client/cli/tx.go +++ b/x/rewards/client/cli/tx.go @@ -3,15 +3,13 @@ package cli import ( "context" "fmt" + "strings" "time" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/spf13/cobra" - // "github.com/cosmos/cosmos-sdk/client/flags" - "strings" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" From 43db988c0fb36f1212acbc9a82e7239a495475a0 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 11 Feb 2024 12:32:54 +0200 Subject: [PATCH 10/64] CNS-868: another lint fix --- protocol/rpcprovider/rewardserver/badger_db.go | 1 - 1 file changed, 1 deletion(-) diff --git a/protocol/rpcprovider/rewardserver/badger_db.go b/protocol/rpcprovider/rewardserver/badger_db.go index 93678135b9..9acd640114 100644 --- a/protocol/rpcprovider/rewardserver/badger_db.go +++ b/protocol/rpcprovider/rewardserver/badger_db.go @@ -85,7 +85,6 @@ func (mdb *BadgerDB) FindOne(key string) (one []byte, err error) { return nil }) - if err != nil { return nil, err } From 02745cf27455ee78e0fed060543d5a942c15e322 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 11 Feb 2024 14:05:13 +0200 Subject: [PATCH 11/64] CNS-870: define iprpc pool --- x/rewards/types/types.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/x/rewards/types/types.go b/x/rewards/types/types.go index 936ac2e2bd..7e3473777a 100644 --- a/x/rewards/types/types.go +++ b/x/rewards/types/types.go @@ -43,6 +43,15 @@ const ( RefillRewardsPoolTimerName = "refill-rewards-timer" ) +// IPRPC Pool: +// IPRPC (Incentivized Providers RPC) pool is meant to hold bonus rewards for providers that +// provide service on specific specs. The rewards from this pool are distributed on a monthly +// basis +const ( + IprpcPoolName Pool = "iprpc_pool" + IprpcPoolEmissionEventName string = "iprpc_pool_emmission" +) + const ( SetIprpcDataEventName = "set-iprpc-data" ) From 2982f86775f7e87290422c1cd536413575c02279 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 11 Feb 2024 16:01:59 +0200 Subject: [PATCH 12/64] CNS-870: scaffold list iprpc reward --- proto/lavanet/lava/rewards/base_pay.proto | 2 + proto/lavanet/lava/rewards/genesis.proto | 3 + proto/lavanet/lava/rewards/iprpc.proto | 17 + x/rewards/genesis.go | 7 + x/rewards/genesis_test.go | 42 ++ x/rewards/keeper/iprpc_reward.go | 106 ++++ x/rewards/types/base_pay.pb.go | 80 ++- x/rewards/types/genesis.go | 11 + x/rewards/types/genesis.pb.go | 150 +++++- x/rewards/types/genesis_test.go | 1 + x/rewards/types/iprpc.pb.go | 603 ++++++++++++++++++++++ x/rewards/types/keys.go | 6 + 12 files changed, 981 insertions(+), 47 deletions(-) create mode 100644 proto/lavanet/lava/rewards/iprpc.proto create mode 100644 x/rewards/genesis_test.go create mode 100644 x/rewards/keeper/iprpc_reward.go create mode 100644 x/rewards/types/iprpc.pb.go diff --git a/proto/lavanet/lava/rewards/base_pay.proto b/proto/lavanet/lava/rewards/base_pay.proto index b8248fb705..cff62cd438 100644 --- a/proto/lavanet/lava/rewards/base_pay.proto +++ b/proto/lavanet/lava/rewards/base_pay.proto @@ -20,6 +20,8 @@ message BasePay { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + + uint64 iprpc_cu = 3; } // aggregated rewards for the provider through out the month diff --git a/proto/lavanet/lava/rewards/genesis.proto b/proto/lavanet/lava/rewards/genesis.proto index 7803a498f7..34d02ca9c3 100644 --- a/proto/lavanet/lava/rewards/genesis.proto +++ b/proto/lavanet/lava/rewards/genesis.proto @@ -4,6 +4,7 @@ package lavanet.lava.rewards; import "gogoproto/gogo.proto"; import "lavanet/lava/rewards/params.proto"; import "lavanet/lava/rewards/base_pay.proto"; +import "lavanet/lava/rewards/iprpc.proto"; import "lavanet/lava/timerstore/timer.proto"; import "cosmos/base/v1beta1/coin.proto"; // this line is used by starport scaffolding # genesis/proto/import @@ -17,5 +18,7 @@ message GenesisState { repeated BasePayGenesis base_pays = 3 [(gogoproto.nullable) = false]; repeated string iprpc_subscriptions = 4; cosmos.base.v1beta1.Coin min_iprpc_cost = 5 [(gogoproto.nullable) = false]; + repeated IprpcReward iprpc_rewards = 6 [(gogoproto.nullable) = false]; + uint64 iprpc_rewards_count = 7; // this line is used by starport scaffolding # genesis/proto/state } \ No newline at end of file diff --git a/proto/lavanet/lava/rewards/iprpc.proto b/proto/lavanet/lava/rewards/iprpc.proto new file mode 100644 index 0000000000..8f3f644463 --- /dev/null +++ b/proto/lavanet/lava/rewards/iprpc.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package lavanet.lava.rewards; + +option go_package = "github.com/lavanet/lava/x/rewards/types"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// list object that holds the +message IprpcReward { + uint64 id = 1; + repeated Specfund spec_funds = 2 [(gogoproto.nullable) = false]; +} + +message Specfund { + string spec = 1; + repeated cosmos.base.v1beta1.Coin fund = 2 [(gogoproto.nullable) = false]; +} \ No newline at end of file diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index 3eb9454a48..e14b873de6 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -23,6 +23,11 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) for _, sub := range genState.IprpcSubscriptions { k.SetIprpcSubscription(ctx, sub) } + + for _, iprpcReward := range genState.IprpcRewards { + k.SetIprpcReward(ctx, iprpcReward) + } + k.SetIprpcRewardCount(ctx, genState.IprpcRewardsCount) } // ExportGenesis returns the capability module's exported genesis. @@ -33,6 +38,8 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.BasePays = k.GetAllBasePay(ctx) genesis.IprpcSubscriptions = k.GetAllIprpcSubscription(ctx) genesis.MinIprpcCost = k.GetMinIprpcCost(ctx) + genesis.IprpcRewards = k.GetAllIprpcReward(ctx) + genesis.IprpcRewardsCount = k.GetIprpcRewardCount(ctx) // this line is used by starport scaffolding # genesis/module/export return genesis diff --git a/x/rewards/genesis_test.go b/x/rewards/genesis_test.go new file mode 100644 index 0000000000..23c3bcb4e8 --- /dev/null +++ b/x/rewards/genesis_test.go @@ -0,0 +1,42 @@ +package rewards + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + testkeeper "github.com/lavanet/lava/testutil/keeper" + "github.com/lavanet/lava/testutil/nullify" + "github.com/lavanet/lava/x/rewards/types" + "github.com/stretchr/testify/require" +) + +func TestGenesis(t *testing.T) { + genesisState := types.GenesisState{ + Params: types.DefaultParams(), + + IprpcRewards: []types.IprpcReward{ + { + Id: 0, + }, + { + Id: 1, + }, + }, + IprpcRewardsCount: 2, + // this line is used by starport scaffolding # genesis/test/state + } + + _, keepers, goCtx := testkeeper.InitAllKeepers(t) + ctx := sdk.UnwrapSDKContext(goCtx) + k := keepers.Rewards + InitGenesis(ctx, k, genesisState) + got := ExportGenesis(ctx, k) + require.NotNil(t, got) + + nullify.Fill(&genesisState) + nullify.Fill(got) + + require.ElementsMatch(t, genesisState.IprpcRewards, got.IprpcRewards) + require.Equal(t, genesisState.IprpcRewardsCount, got.IprpcRewardsCount) + // this line is used by starport scaffolding # genesis/test/assert +} diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go new file mode 100644 index 0000000000..d2bcfce160 --- /dev/null +++ b/x/rewards/keeper/iprpc_reward.go @@ -0,0 +1,106 @@ +package keeper + +import ( + "encoding/binary" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/rewards/types" +) + +// GetIprpcRewardCount get the total number of IprpcReward +func (k Keeper) GetIprpcRewardCount(ctx sdk.Context) uint64 { + store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{}) + byteKey := types.KeyPrefix(types.IprpcRewardsCountPrefix) + bz := store.Get(byteKey) + + // Count doesn't exist: no element + if bz == nil { + return 0 + } + + // Parse bytes + return binary.BigEndian.Uint64(bz) +} + +// SetIprpcRewardCount set the total number of IprpcReward +func (k Keeper) SetIprpcRewardCount(ctx sdk.Context, count uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{}) + byteKey := types.KeyPrefix(types.IprpcRewardsCountPrefix) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, count) + store.Set(byteKey, bz) +} + +// AppendIprpcReward appends a IprpcReward in the store with a new id and update the count +func (k Keeper) AppendIprpcReward( + ctx sdk.Context, + IprpcReward types.IprpcReward, +) uint64 { + // Create the IprpcReward + count := k.GetIprpcRewardCount(ctx) + + // Set the ID of the appended value + IprpcReward.Id = count + + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) + appendedValue := k.cdc.MustMarshal(&IprpcReward) + store.Set(GetIprpcRewardIDBytes(IprpcReward.Id), appendedValue) + + // Update IprpcReward count + k.SetIprpcRewardCount(ctx, count+1) + + return count +} + +// SetIprpcReward set a specific IprpcReward in the store +func (k Keeper) SetIprpcReward(ctx sdk.Context, IprpcReward types.IprpcReward) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) + b := k.cdc.MustMarshal(&IprpcReward) + store.Set(GetIprpcRewardIDBytes(IprpcReward.Id), b) +} + +// GetIprpcReward returns a IprpcReward from its id +func (k Keeper) GetIprpcReward(ctx sdk.Context, id uint64) (val types.IprpcReward, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) + b := store.Get(GetIprpcRewardIDBytes(id)) + if b == nil { + return val, false + } + k.cdc.MustUnmarshal(b, &val) + return val, true +} + +// RemoveIprpcReward removes a IprpcReward from the store +func (k Keeper) RemoveIprpcReward(ctx sdk.Context, id uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) + store.Delete(GetIprpcRewardIDBytes(id)) +} + +// GetAllIprpcReward returns all IprpcReward +func (k Keeper) GetAllIprpcReward(ctx sdk.Context) (list []types.IprpcReward) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.IprpcReward + k.cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +// GetIprpcRewardIDBytes returns the byte representation of the ID +func GetIprpcRewardIDBytes(id uint64) []byte { + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, id) + return bz +} + +// GetIprpcRewardIDFromBytes returns ID in uint64 format from a byte array +func GetIprpcRewardIDFromBytes(bz []byte) uint64 { + return binary.BigEndian.Uint64(bz) +} diff --git a/x/rewards/types/base_pay.pb.go b/x/rewards/types/base_pay.pb.go index 8087c20283..e5ef1b4193 100644 --- a/x/rewards/types/base_pay.pb.go +++ b/x/rewards/types/base_pay.pb.go @@ -31,6 +31,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type BasePay struct { Total github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=total,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total"` TotalAdjusted github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=totalAdjusted,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"totalAdjusted"` + IprpcCu uint64 `protobuf:"varint,3,opt,name=iprpc_cu,json=iprpcCu,proto3" json:"iprpc_cu,omitempty"` } func (m *BasePay) Reset() { *m = BasePay{} } @@ -66,6 +67,13 @@ func (m *BasePay) XXX_DiscardUnknown() { var xxx_messageInfo_BasePay proto.InternalMessageInfo +func (m *BasePay) GetIprpcCu() uint64 { + if m != nil { + return m.IprpcCu + } + return 0 +} + // aggregated rewards for the provider through out the month type BasePayGenesis struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` @@ -129,28 +137,29 @@ func init() { } var fileDescriptor_a2fb0eb917a4ee4e = []byte{ - // 329 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xce, 0x49, 0x2c, 0x4b, - 0xcc, 0x4b, 0x2d, 0xd1, 0x07, 0xd1, 0xfa, 0x45, 0xa9, 0xe5, 0x89, 0x45, 0x29, 0xc5, 0xfa, 0x49, - 0x89, 0xc5, 0xa9, 0xf1, 0x05, 0x89, 0x95, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x22, 0x50, - 0x45, 0x7a, 0x20, 0x5a, 0x0f, 0xaa, 0x48, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xac, 0x40, 0x1f, - 0xc4, 0x82, 0xa8, 0x95, 0x92, 0x4b, 0xce, 0x2f, 0xce, 0xcd, 0x87, 0x18, 0xa1, 0x5f, 0x66, 0x98, - 0x94, 0x5a, 0x92, 0x68, 0xa8, 0x9f, 0x9c, 0x9f, 0x99, 0x07, 0x95, 0x97, 0x84, 0xc8, 0xc7, 0x43, - 0x34, 0x42, 0x38, 0x50, 0x29, 0xc1, 0xc4, 0xdc, 0xcc, 0xbc, 0x7c, 0x7d, 0x30, 0x09, 0x11, 0x52, - 0xda, 0xcc, 0xc8, 0xc5, 0xee, 0x94, 0x58, 0x9c, 0x1a, 0x90, 0x58, 0x29, 0x14, 0xc4, 0xc5, 0x5a, - 0x92, 0x5f, 0x92, 0x98, 0x23, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe9, 0x64, 0x73, 0xe2, 0x9e, 0x3c, - 0xc3, 0xad, 0x7b, 0xf2, 0x6a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0x50, - 0xe3, 0xa0, 0x94, 0x6e, 0x71, 0x4a, 0xb6, 0x7e, 0x49, 0x65, 0x41, 0x6a, 0xb1, 0x9e, 0x67, 0x5e, - 0xc9, 0xa5, 0x2d, 0xba, 0x5c, 0x50, 0xdb, 0x3c, 0xf3, 0x4a, 0x82, 0x20, 0x46, 0x09, 0x85, 0x70, - 0xf1, 0x82, 0x19, 0x8e, 0x29, 0x59, 0xa5, 0xc5, 0x25, 0xa9, 0x29, 0x12, 0x4c, 0x60, 0xb3, 0xf5, - 0x48, 0x30, 0xdb, 0x25, 0x35, 0x39, 0x08, 0xd5, 0x10, 0xa5, 0x34, 0x2e, 0x3e, 0xa8, 0xa3, 0xdd, - 0x53, 0xf3, 0x52, 0x8b, 0x33, 0x8b, 0x85, 0x44, 0xb8, 0x58, 0x33, 0xf3, 0x52, 0x52, 0x2b, 0x20, - 0x6e, 0x0f, 0x82, 0x70, 0x84, 0xec, 0xb8, 0x38, 0x60, 0x21, 0x0d, 0xb6, 0x98, 0xdb, 0x48, 0x56, - 0x0f, 0x5b, 0x50, 0xeb, 0x41, 0x4d, 0x73, 0x62, 0x01, 0xb9, 0x2b, 0x88, 0x3d, 0x09, 0xca, 0x75, - 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, - 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x75, 0x24, 0x87, 0xa3, 0xc4, - 0x70, 0x05, 0x3c, 0x8e, 0xc1, 0xae, 0x4f, 0x62, 0x03, 0x87, 0xb3, 0x31, 0x20, 0x00, 0x00, 0xff, - 0xff, 0x65, 0x93, 0x8f, 0x17, 0x08, 0x02, 0x00, 0x00, + // 349 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x51, 0xc1, 0x4e, 0x02, 0x31, + 0x14, 0xdc, 0x2a, 0x08, 0xd6, 0x68, 0xe2, 0x86, 0x03, 0x90, 0x58, 0x08, 0x26, 0xca, 0x85, 0x36, + 0xe8, 0xd5, 0x98, 0x80, 0x26, 0x86, 0x9b, 0xd9, 0x78, 0xf2, 0x42, 0xba, 0xbb, 0x15, 0x57, 0xa1, + 0xdd, 0x6c, 0xbb, 0x08, 0x7f, 0xe1, 0xc7, 0xf8, 0x11, 0x9c, 0x0c, 0xf1, 0x64, 0x3c, 0x10, 0x03, + 0x3f, 0x62, 0xb6, 0xad, 0x46, 0x12, 0x2f, 0x5e, 0xfa, 0xde, 0xf4, 0x4d, 0xa7, 0x6f, 0x32, 0xf0, + 0x70, 0x48, 0xc7, 0x94, 0x33, 0x45, 0xb2, 0x4a, 0x12, 0xf6, 0x44, 0x93, 0x50, 0x12, 0x9f, 0x4a, + 0xd6, 0x8f, 0xe9, 0x14, 0xc7, 0x89, 0x50, 0xc2, 0x2d, 0x59, 0x12, 0xce, 0x2a, 0xb6, 0xa4, 0x6a, + 0x69, 0x20, 0x06, 0x42, 0x13, 0x48, 0xd6, 0x19, 0x6e, 0x15, 0x05, 0x42, 0x8e, 0x84, 0x91, 0x20, + 0xe3, 0xb6, 0xcf, 0x14, 0x6d, 0x93, 0x40, 0x44, 0xdc, 0xce, 0x2b, 0x66, 0xde, 0x37, 0x0f, 0x0d, + 0xb0, 0xa3, 0x7d, 0x3a, 0x8a, 0xb8, 0x20, 0xfa, 0x34, 0x57, 0x8d, 0x57, 0x00, 0x0b, 0x5d, 0x2a, + 0xd9, 0x35, 0x9d, 0xba, 0x1e, 0xcc, 0x2b, 0xa1, 0xe8, 0xb0, 0x0c, 0xea, 0xa0, 0xb9, 0xdd, 0x3d, + 0x9b, 0x2d, 0x6a, 0xce, 0xc7, 0xa2, 0x76, 0x34, 0x88, 0xd4, 0x7d, 0xea, 0xe3, 0x40, 0x8c, 0xac, + 0x9c, 0x2d, 0x2d, 0x19, 0x3e, 0x12, 0x35, 0x8d, 0x99, 0xc4, 0x3d, 0xae, 0xde, 0x5e, 0x5a, 0xd0, + 0xfe, 0xd6, 0xe3, 0xca, 0x33, 0x52, 0xee, 0x0d, 0xdc, 0xd5, 0x4d, 0x27, 0x7c, 0x48, 0xa5, 0x62, + 0x61, 0x79, 0x43, 0x6b, 0xe3, 0x7f, 0x68, 0x5f, 0xb2, 0xc0, 0x5b, 0x17, 0x71, 0x2b, 0xb0, 0x18, + 0xc5, 0x49, 0x1c, 0xf4, 0x83, 0xb4, 0xbc, 0x59, 0x07, 0xcd, 0x9c, 0x57, 0xd0, 0xf8, 0x22, 0x6d, + 0xdc, 0xc1, 0x3d, 0xeb, 0xe7, 0x8a, 0x71, 0x26, 0x23, 0xe9, 0x96, 0x60, 0x3e, 0xe2, 0x21, 0x9b, + 0x18, 0x5b, 0x9e, 0x01, 0xee, 0x39, 0x2c, 0x7e, 0x87, 0xa0, 0x77, 0xda, 0x39, 0x39, 0xc0, 0x7f, + 0xa5, 0x80, 0xad, 0x5a, 0x37, 0x97, 0xad, 0xec, 0x15, 0x7c, 0x0b, 0x3b, 0xb3, 0x25, 0x02, 0xf3, + 0x25, 0x02, 0x9f, 0x4b, 0x04, 0x9e, 0x57, 0xc8, 0x99, 0xaf, 0x90, 0xf3, 0xbe, 0x42, 0xce, 0xed, + 0xf1, 0x2f, 0x4f, 0x6b, 0xe1, 0x4f, 0x7e, 0xe2, 0xd7, 0xc6, 0xfc, 0x2d, 0x1d, 0xc1, 0xe9, 0x57, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x24, 0x2a, 0x65, 0x23, 0x02, 0x00, 0x00, } func (m *BasePay) Marshal() (dAtA []byte, err error) { @@ -173,6 +182,11 @@ func (m *BasePay) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.IprpcCu != 0 { + i = encodeVarintBasePay(dAtA, i, uint64(m.IprpcCu)) + i-- + dAtA[i] = 0x18 + } { size := m.TotalAdjusted.Size() i -= size @@ -257,6 +271,9 @@ func (m *BasePay) Size() (n int) { n += 1 + l + sovBasePay(uint64(l)) l = m.TotalAdjusted.Size() n += 1 + l + sovBasePay(uint64(l)) + if m.IprpcCu != 0 { + n += 1 + sovBasePay(uint64(m.IprpcCu)) + } return n } @@ -378,6 +395,25 @@ func (m *BasePay) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcCu", wireType) + } + m.IprpcCu = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBasePay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IprpcCu |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipBasePay(dAtA[iNdEx:]) diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index 609f7f4a84..d3ec2e073f 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -22,6 +22,7 @@ func DefaultGenesis() *GenesisState { BasePays: []BasePayGenesis{}, IprpcSubscriptions: []string{}, MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, sdk.ZeroInt()), + IprpcRewards: []IprpcReward{{SpecFunds: []Specfund{}}}, } } @@ -50,5 +51,15 @@ func (gs GenesisState) Validate() error { return fmt.Errorf("negative min iprpc cost. MinIprpcCost: %s", gs.MinIprpcCost.String()) } + for _, iprpcReward := range gs.IprpcRewards { + for _, specFund := range iprpcReward.SpecFunds { + for _, coin := range specFund.Fund { + if !coin.IsValid() { + return fmt.Errorf("invalid iprpc reward fund. invalid coin: %s", coin.String()) + } + } + } + } + return gs.Params.Validate() } diff --git a/x/rewards/types/genesis.pb.go b/x/rewards/types/genesis.pb.go index 98e5a8712b..b6399f4224 100644 --- a/x/rewards/types/genesis.pb.go +++ b/x/rewards/types/genesis.pb.go @@ -32,6 +32,8 @@ type GenesisState struct { BasePays []BasePayGenesis `protobuf:"bytes,3,rep,name=base_pays,json=basePays,proto3" json:"base_pays"` IprpcSubscriptions []string `protobuf:"bytes,4,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` MinIprpcCost types1.Coin `protobuf:"bytes,5,opt,name=min_iprpc_cost,json=minIprpcCost,proto3" json:"min_iprpc_cost"` + IprpcRewards []IprpcReward `protobuf:"bytes,6,rep,name=iprpc_rewards,json=iprpcRewards,proto3" json:"iprpc_rewards"` + IprpcRewardsCount uint64 `protobuf:"varint,7,opt,name=iprpc_rewards_count,json=iprpcRewardsCount,proto3" json:"iprpc_rewards_count,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -102,6 +104,20 @@ func (m *GenesisState) GetMinIprpcCost() types1.Coin { return types1.Coin{} } +func (m *GenesisState) GetIprpcRewards() []IprpcReward { + if m != nil { + return m.IprpcRewards + } + return nil +} + +func (m *GenesisState) GetIprpcRewardsCount() uint64 { + if m != nil { + return m.IprpcRewardsCount + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "lavanet.lava.rewards.GenesisState") } @@ -111,31 +127,34 @@ func init() { } var fileDescriptor_02c24f4df31ca14e = []byte{ - // 375 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x4f, 0x4f, 0xe2, 0x40, - 0x14, 0xc0, 0x5b, 0x60, 0xc9, 0x52, 0xc8, 0x6e, 0xd2, 0xe5, 0xd0, 0x25, 0xa6, 0x22, 0x6a, 0xe4, - 0x34, 0x13, 0xf0, 0xe6, 0x4d, 0x88, 0x21, 0xde, 0x08, 0xe8, 0xc5, 0x0b, 0x99, 0xd6, 0xb1, 0x4e, - 0x42, 0x3b, 0x93, 0x79, 0x03, 0xca, 0xb7, 0xf0, 0x63, 0x71, 0xe4, 0xe8, 0xc9, 0x98, 0xf2, 0x45, - 0x4c, 0x3b, 0xa3, 0x82, 0xe9, 0x69, 0x26, 0xf3, 0x7e, 0xef, 0x37, 0xef, 0x8f, 0xd3, 0x99, 0x93, - 0x25, 0x49, 0xa8, 0xc2, 0xd9, 0x89, 0x25, 0x7d, 0x22, 0xf2, 0x1e, 0x70, 0x44, 0x13, 0x0a, 0x0c, - 0x90, 0x90, 0x5c, 0x71, 0xb7, 0x69, 0x18, 0x94, 0x9d, 0xc8, 0x30, 0xad, 0x66, 0xc4, 0x23, 0x9e, - 0x03, 0x38, 0xbb, 0x69, 0xb6, 0x75, 0x54, 0xe8, 0x13, 0x44, 0x92, 0xd8, 0xe8, 0x5a, 0xc7, 0x85, - 0x48, 0x40, 0x80, 0xce, 0x04, 0x59, 0x15, 0x42, 0x8a, 0xc5, 0x54, 0x82, 0xe2, 0x92, 0xea, 0xab, - 0x81, 0xfc, 0x90, 0x43, 0xcc, 0x75, 0x2e, 0x5e, 0xf6, 0x02, 0xaa, 0x48, 0x0f, 0x87, 0x9c, 0x25, - 0x3a, 0xde, 0x49, 0x4b, 0x4e, 0x63, 0xa4, 0x5b, 0x99, 0x2a, 0xa2, 0xa8, 0x7b, 0xe1, 0x54, 0x75, - 0x29, 0x9e, 0xdd, 0xb6, 0xbb, 0xf5, 0xfe, 0x01, 0x2a, 0x6a, 0x0d, 0x8d, 0x73, 0x66, 0x50, 0x59, - 0xbf, 0x1d, 0x5a, 0x13, 0x93, 0xe1, 0xde, 0x3a, 0x7f, 0x25, 0x7d, 0x60, 0xf3, 0xf9, 0x44, 0x53, - 0x37, 0x53, 0xaf, 0x94, 0x4b, 0x4e, 0xf7, 0x25, 0xdf, 0xb5, 0xa2, 0xdd, 0xbf, 0x8d, 0xed, 0xa7, - 0xc3, 0x1d, 0x39, 0xb5, 0xcf, 0xd6, 0xc1, 0x2b, 0xb7, 0xcb, 0xdd, 0x7a, 0xff, 0xa4, 0xb8, 0xaa, - 0x01, 0x01, 0x3a, 0x26, 0x2b, 0x23, 0x35, 0xbe, 0xdf, 0x81, 0x7e, 0x05, 0x17, 0x3b, 0xff, 0x98, - 0x90, 0x22, 0x9c, 0xc1, 0x22, 0x80, 0x50, 0x32, 0xa1, 0x18, 0x4f, 0xc0, 0xab, 0xb4, 0xcb, 0xdd, - 0xda, 0xc4, 0xcd, 0x43, 0xd3, 0xdd, 0x88, 0x7b, 0xe5, 0xfc, 0x89, 0x59, 0x32, 0xd3, 0x49, 0x21, - 0x07, 0xe5, 0xfd, 0xca, 0xfb, 0xf9, 0x8f, 0xf4, 0x58, 0x51, 0xa6, 0x46, 0x66, 0xac, 0x68, 0xc8, - 0x59, 0x62, 0xfe, 0x6c, 0xc4, 0x2c, 0xb9, 0xce, 0xb2, 0x86, 0x1c, 0xd4, 0xe0, 0x72, 0x9d, 0xfa, - 0xf6, 0x26, 0xf5, 0xed, 0xf7, 0xd4, 0xb7, 0x5f, 0xb6, 0xbe, 0xb5, 0xd9, 0xfa, 0xd6, 0xeb, 0xd6, - 0xb7, 0xee, 0xce, 0x22, 0xa6, 0x1e, 0x17, 0x01, 0x0a, 0x79, 0x8c, 0xf7, 0xd6, 0xf9, 0xfc, 0xb5, - 0x75, 0xb5, 0x12, 0x14, 0x82, 0x6a, 0xbe, 0xae, 0xf3, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x17, - 0x08, 0xb2, 0x20, 0x8d, 0x02, 0x00, 0x00, + // 428 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0x13, 0x52, 0x0a, 0xf3, 0x06, 0x08, 0xb3, 0x43, 0xa8, 0x50, 0xc8, 0x06, 0x88, 0x9c, + 0x6c, 0x6d, 0xdc, 0xb8, 0xd1, 0x0a, 0x4d, 0x48, 0x1c, 0xa6, 0x14, 0x2e, 0x5c, 0x22, 0x27, 0x98, + 0x60, 0xa9, 0xb1, 0x23, 0x3f, 0x77, 0xd0, 0x6f, 0xc1, 0xc7, 0xda, 0xb1, 0x47, 0x4e, 0xa8, 0x6a, + 0xbf, 0x08, 0x8a, 0xed, 0xd2, 0x16, 0xe5, 0x64, 0xcb, 0xef, 0xff, 0xff, 0xf9, 0xfd, 0x9f, 0x1e, + 0x3a, 0x9f, 0xb1, 0x1b, 0x26, 0xb9, 0xa1, 0xdd, 0x49, 0x35, 0xff, 0xc1, 0xf4, 0x57, 0xa0, 0x35, + 0x97, 0x1c, 0x04, 0x90, 0x56, 0x2b, 0xa3, 0xf0, 0xa9, 0xd7, 0x90, 0xee, 0x24, 0x5e, 0x33, 0x3a, + 0xad, 0x55, 0xad, 0xac, 0x80, 0x76, 0x37, 0xa7, 0x1d, 0x9d, 0xf5, 0xf2, 0x5a, 0xa6, 0x59, 0xe3, + 0x71, 0xa3, 0x17, 0xbd, 0x92, 0x92, 0x01, 0x2f, 0x5a, 0xb6, 0xf0, 0xa2, 0xb4, 0x57, 0x24, 0x5a, + 0xdd, 0x56, 0xbd, 0x18, 0x23, 0x1a, 0xae, 0xc1, 0x28, 0xcd, 0xdd, 0xd5, 0x8b, 0x92, 0x4a, 0x41, + 0xa3, 0x1c, 0x9d, 0xde, 0x5c, 0x94, 0xdc, 0xb0, 0x0b, 0x5a, 0x29, 0x21, 0x5d, 0xfd, 0x7c, 0x15, + 0xa1, 0x93, 0x2b, 0x17, 0x76, 0x6a, 0x98, 0xe1, 0xf8, 0x2d, 0x1a, 0xba, 0x66, 0xe3, 0x30, 0x0d, + 0xb3, 0xe3, 0xcb, 0x67, 0xa4, 0x2f, 0x3c, 0xb9, 0xb6, 0x9a, 0xf1, 0xe0, 0xf6, 0xcf, 0xf3, 0x20, + 0xf7, 0x0e, 0xfc, 0x19, 0x3d, 0xd2, 0xfc, 0x9b, 0x98, 0xcd, 0x72, 0xa7, 0xfa, 0x34, 0x8d, 0xef, + 0x58, 0xc8, 0xab, 0x43, 0xc8, 0xae, 0x57, 0xb2, 0xff, 0xb7, 0xa7, 0xfd, 0xcf, 0xc0, 0x57, 0xe8, + 0x68, 0x3b, 0x1c, 0x88, 0xa3, 0x34, 0xca, 0x8e, 0x2f, 0x5f, 0xf6, 0x77, 0x35, 0x66, 0xc0, 0xaf, + 0xd9, 0xc2, 0x43, 0x3d, 0xef, 0x7e, 0xe9, 0x5e, 0x01, 0x53, 0xf4, 0xc4, 0x0e, 0xb0, 0x80, 0x79, + 0x09, 0x95, 0x16, 0xad, 0x11, 0x4a, 0x42, 0x3c, 0x48, 0xa3, 0xec, 0x28, 0xc7, 0xb6, 0x34, 0xdd, + 0xaf, 0xe0, 0xf7, 0xe8, 0x61, 0x23, 0x64, 0xe1, 0x4c, 0x95, 0x02, 0x13, 0xdf, 0xb5, 0x79, 0x9e, + 0x12, 0x37, 0x56, 0xd2, 0xa1, 0x89, 0x1f, 0x2b, 0x99, 0x28, 0x21, 0xfd, 0x9f, 0x27, 0x8d, 0x90, + 0x1f, 0x3a, 0xd7, 0x44, 0x81, 0xc1, 0x1f, 0xd1, 0x03, 0x87, 0xf0, 0x7d, 0xc6, 0x43, 0x1b, 0xe2, + 0xac, 0x3f, 0x84, 0xf5, 0xb9, 0xf4, 0x5b, 0x9a, 0xd8, 0x3d, 0x01, 0x26, 0xdb, 0x14, 0xde, 0x50, + 0x54, 0x6a, 0x2e, 0x4d, 0x7c, 0x2f, 0x0d, 0xb3, 0x41, 0xfe, 0x78, 0x5f, 0x3a, 0xe9, 0x0a, 0xe3, + 0x77, 0xb7, 0xeb, 0x24, 0x5c, 0xae, 0x93, 0x70, 0xb5, 0x4e, 0xc2, 0x5f, 0x9b, 0x24, 0x58, 0x6e, + 0x92, 0xe0, 0xf7, 0x26, 0x09, 0xbe, 0xbc, 0xae, 0x85, 0xf9, 0x3e, 0x2f, 0x49, 0xa5, 0x1a, 0x7a, + 0xb0, 0x4c, 0x3f, 0xff, 0x2d, 0x9c, 0x59, 0xb4, 0x1c, 0xca, 0xa1, 0x5d, 0x96, 0x37, 0x7f, 0x03, + 0x00, 0x00, 0xff, 0xff, 0x38, 0x36, 0xec, 0x19, 0x2d, 0x03, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -158,6 +177,25 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.IprpcRewardsCount != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.IprpcRewardsCount)) + i-- + dAtA[i] = 0x38 + } + if len(m.IprpcRewards) > 0 { + for iNdEx := len(m.IprpcRewards) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IprpcRewards[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } { size, err := m.MinIprpcCost.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -249,6 +287,15 @@ func (m *GenesisState) Size() (n int) { } l = m.MinIprpcCost.Size() n += 1 + l + sovGenesis(uint64(l)) + if len(m.IprpcRewards) > 0 { + for _, e := range m.IprpcRewards { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if m.IprpcRewardsCount != 0 { + n += 1 + sovGenesis(uint64(m.IprpcRewardsCount)) + } return n } @@ -452,6 +499,59 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcRewards", 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 + } + m.IprpcRewards = append(m.IprpcRewards, IprpcReward{}) + if err := m.IprpcRewards[len(m.IprpcRewards)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcRewardsCount", wireType) + } + m.IprpcRewardsCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IprpcRewardsCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/rewards/types/genesis_test.go b/x/rewards/types/genesis_test.go index 6cd11ddc4a..faadd5ac5f 100644 --- a/x/rewards/types/genesis_test.go +++ b/x/rewards/types/genesis_test.go @@ -26,6 +26,7 @@ func TestGenesisState_Validate(t *testing.T) { BasePays: types.DefaultGenesis().BasePays, IprpcSubscriptions: []string{"invalidAddress"}, MinIprpcCost: types.DefaultGenesis().MinIprpcCost, + IprpcRewards: types.DefaultGenesis().IprpcRewards, }, valid: false, }, diff --git a/x/rewards/types/iprpc.pb.go b/x/rewards/types/iprpc.pb.go new file mode 100644 index 0000000000..eeef70a024 --- /dev/null +++ b/x/rewards/types/iprpc.pb.go @@ -0,0 +1,603 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: lavanet/lava/rewards/iprpc.proto + +package types + +import ( + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + 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 + +// list object that holds the +type IprpcReward struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + SpecFunds []Specfund `protobuf:"bytes,2,rep,name=spec_funds,json=specFunds,proto3" json:"spec_funds"` +} + +func (m *IprpcReward) Reset() { *m = IprpcReward{} } +func (m *IprpcReward) String() string { return proto.CompactTextString(m) } +func (*IprpcReward) ProtoMessage() {} +func (*IprpcReward) Descriptor() ([]byte, []int) { + return fileDescriptor_1293618a311573f7, []int{0} +} +func (m *IprpcReward) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IprpcReward) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IprpcReward.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 *IprpcReward) XXX_Merge(src proto.Message) { + xxx_messageInfo_IprpcReward.Merge(m, src) +} +func (m *IprpcReward) XXX_Size() int { + return m.Size() +} +func (m *IprpcReward) XXX_DiscardUnknown() { + xxx_messageInfo_IprpcReward.DiscardUnknown(m) +} + +var xxx_messageInfo_IprpcReward proto.InternalMessageInfo + +func (m *IprpcReward) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *IprpcReward) GetSpecFunds() []Specfund { + if m != nil { + return m.SpecFunds + } + return nil +} + +type Specfund struct { + Spec string `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + Fund []types.Coin `protobuf:"bytes,2,rep,name=fund,proto3" json:"fund"` +} + +func (m *Specfund) Reset() { *m = Specfund{} } +func (m *Specfund) String() string { return proto.CompactTextString(m) } +func (*Specfund) ProtoMessage() {} +func (*Specfund) Descriptor() ([]byte, []int) { + return fileDescriptor_1293618a311573f7, []int{1} +} +func (m *Specfund) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Specfund) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Specfund.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 *Specfund) XXX_Merge(src proto.Message) { + xxx_messageInfo_Specfund.Merge(m, src) +} +func (m *Specfund) XXX_Size() int { + return m.Size() +} +func (m *Specfund) XXX_DiscardUnknown() { + xxx_messageInfo_Specfund.DiscardUnknown(m) +} + +var xxx_messageInfo_Specfund proto.InternalMessageInfo + +func (m *Specfund) GetSpec() string { + if m != nil { + return m.Spec + } + return "" +} + +func (m *Specfund) GetFund() []types.Coin { + if m != nil { + return m.Fund + } + return nil +} + +func init() { + proto.RegisterType((*IprpcReward)(nil), "lavanet.lava.rewards.IprpcReward") + proto.RegisterType((*Specfund)(nil), "lavanet.lava.rewards.Specfund") +} + +func init() { proto.RegisterFile("lavanet/lava/rewards/iprpc.proto", fileDescriptor_1293618a311573f7) } + +var fileDescriptor_1293618a311573f7 = []byte{ + // 277 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4a, 0xc3, 0x40, + 0x10, 0x86, 0x93, 0x1a, 0xc4, 0x6e, 0xc1, 0xc3, 0xd2, 0x43, 0xed, 0x61, 0x0d, 0xbd, 0xd8, 0xd3, + 0x2c, 0xb5, 0x4f, 0x60, 0x0b, 0x82, 0xd7, 0xf4, 0xe6, 0x45, 0x92, 0xcd, 0x1a, 0x17, 0x6c, 0x76, + 0xc9, 0x6e, 0xab, 0xbe, 0x85, 0x8f, 0xd5, 0x63, 0x8f, 0x9e, 0x44, 0x92, 0x17, 0x91, 0xd9, 0xac, + 0x82, 0xe0, 0x69, 0x06, 0xfe, 0x6f, 0xfe, 0xf9, 0xf9, 0x49, 0xfa, 0x9c, 0xef, 0xf3, 0x5a, 0x3a, + 0x8e, 0x93, 0x37, 0xf2, 0x25, 0x6f, 0x4a, 0xcb, 0x95, 0x69, 0x8c, 0x00, 0xd3, 0x68, 0xa7, 0xe9, + 0x38, 0x10, 0x80, 0x13, 0x02, 0x31, 0x1d, 0x57, 0xba, 0xd2, 0x1e, 0xe0, 0xb8, 0xf5, 0xec, 0x94, + 0x09, 0x6d, 0xb7, 0xda, 0xf2, 0x22, 0xb7, 0x92, 0xef, 0x17, 0x85, 0x74, 0xf9, 0x82, 0x0b, 0xad, + 0xea, 0x5e, 0x9f, 0x15, 0x64, 0x74, 0x87, 0xd6, 0x99, 0x77, 0xa1, 0xe7, 0x64, 0xa0, 0xca, 0x49, + 0x9c, 0xc6, 0xf3, 0x24, 0x1b, 0xa8, 0x92, 0xae, 0x09, 0xb1, 0x46, 0x8a, 0x87, 0xc7, 0x5d, 0x5d, + 0xda, 0xc9, 0x20, 0x3d, 0x99, 0x8f, 0xae, 0x19, 0xfc, 0xf7, 0x1f, 0x36, 0x46, 0x0a, 0xc4, 0x56, + 0xc9, 0xe1, 0xf3, 0x32, 0xca, 0x86, 0x78, 0x77, 0x8b, 0x67, 0xb3, 0x0d, 0x39, 0xfb, 0x11, 0x29, + 0x25, 0x09, 0x0a, 0xfe, 0xc5, 0x30, 0xf3, 0x3b, 0x5d, 0x92, 0x04, 0xb5, 0x60, 0x7f, 0x01, 0x7d, + 0x64, 0xc0, 0xc8, 0x10, 0x22, 0xc3, 0x5a, 0xab, 0x3a, 0x38, 0x7b, 0x78, 0x75, 0x73, 0x68, 0x59, + 0x7c, 0x6c, 0x59, 0xfc, 0xd5, 0xb2, 0xf8, 0xbd, 0x63, 0xd1, 0xb1, 0x63, 0xd1, 0x47, 0xc7, 0xa2, + 0xfb, 0xab, 0x4a, 0xb9, 0xa7, 0x5d, 0x01, 0x42, 0x6f, 0xf9, 0x9f, 0x2e, 0x5f, 0x7f, 0xdb, 0x74, + 0x6f, 0x46, 0xda, 0xe2, 0xd4, 0x57, 0xb0, 0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x08, 0xfc, 0xb5, + 0xc2, 0x72, 0x01, 0x00, 0x00, +} + +func (m *IprpcReward) 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 *IprpcReward) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IprpcReward) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SpecFunds) > 0 { + for iNdEx := len(m.SpecFunds) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SpecFunds[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIprpc(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Id != 0 { + i = encodeVarintIprpc(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Specfund) 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 *Specfund) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Specfund) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Fund) > 0 { + for iNdEx := len(m.Fund) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Fund[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIprpc(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Spec) > 0 { + i -= len(m.Spec) + copy(dAtA[i:], m.Spec) + i = encodeVarintIprpc(dAtA, i, uint64(len(m.Spec))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintIprpc(dAtA []byte, offset int, v uint64) int { + offset -= sovIprpc(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *IprpcReward) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovIprpc(uint64(m.Id)) + } + if len(m.SpecFunds) > 0 { + for _, e := range m.SpecFunds { + l = e.Size() + n += 1 + l + sovIprpc(uint64(l)) + } + } + return n +} + +func (m *Specfund) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Spec) + if l > 0 { + n += 1 + l + sovIprpc(uint64(l)) + } + if len(m.Fund) > 0 { + for _, e := range m.Fund { + l = e.Size() + n += 1 + l + sovIprpc(uint64(l)) + } + } + return n +} + +func sovIprpc(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozIprpc(x uint64) (n int) { + return sovIprpc(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *IprpcReward) 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 ErrIntOverflowIprpc + } + 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: IprpcReward: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IprpcReward: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIprpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpecFunds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIprpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIprpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIprpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpecFunds = append(m.SpecFunds, Specfund{}) + if err := m.SpecFunds[len(m.SpecFunds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIprpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthIprpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Specfund) 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 ErrIntOverflowIprpc + } + 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: Specfund: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Specfund: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIprpc + } + 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 ErrInvalidLengthIprpc + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIprpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Spec = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Fund", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIprpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIprpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIprpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Fund = append(m.Fund, types.Coin{}) + if err := m.Fund[len(m.Fund)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIprpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthIprpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipIprpc(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, ErrIntOverflowIprpc + } + 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, ErrIntOverflowIprpc + } + 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, ErrIntOverflowIprpc + } + 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, ErrInvalidLengthIprpc + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupIprpc + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthIprpc + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthIprpc = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowIprpc = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupIprpc = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/rewards/types/keys.go b/x/rewards/types/keys.go index 89f06bb3e6..4e984f80b6 100644 --- a/x/rewards/types/keys.go +++ b/x/rewards/types/keys.go @@ -24,6 +24,12 @@ const ( // prefix for min IPRPC cost MinIprpcCostPrefix = "min-iprpc-cost" + + // prefix for IPRPC reward element + IprpcRewardPrefix = "iprpc-reward" + + // prefix for IPRPC rewards count + IprpcRewardsCountPrefix = "iprpc-rewards-count" ) func KeyPrefix(p string) []byte { From 4911a1336e27e62d421ac6d5d73fe2950bf623d3 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 11 Feb 2024 18:43:37 +0200 Subject: [PATCH 13/64] CNS-870: count iprpc cu --- x/rewards/keeper/providers.go | 6 +++++- x/subscription/keeper/cu_tracker.go | 2 +- x/subscription/types/expected_keepers.go | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 6abec4d264..f719e95469 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -12,7 +12,7 @@ import ( const DAY_SECONDS = 60 * 60 * 24 -func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int) { +func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int, sub string, cu uint64) { index := types.BasePayIndex{Provider: provider, ChainID: chainid} basepay, found := k.getBasePay(ctx, index) adjustedPay := adjustment.MulInt(rewards) @@ -24,6 +24,10 @@ func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adju basepay.TotalAdjusted = basepay.TotalAdjusted.Add(adjustedPay) } + if k.IsIprpcSubscription(ctx, sub) { + basepay.IprpcCu += cu + } + k.setBasePay(ctx, index, basepay) } diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index 9e8f1f88aa..bf7b4bc194 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -189,7 +189,7 @@ func (k Keeper) RewardAndResetCuTracker(ctx sdk.Context, cuTrackerTimerKeyBytes totalTokenRewarded = totalTokenRewarded.Add(totalMonthlyReward) // aggregate the reward for the provider - k.rewardsKeeper.AggregateRewards(ctx, provider, chainID, providerAdjustment, totalMonthlyReward) + k.rewardsKeeper.AggregateRewards(ctx, provider, chainID, providerAdjustment, totalMonthlyReward, sub, trackedCu) // Transfer some of the total monthly reward to validators contribution and community pool totalMonthlyReward, err = k.rewardsKeeper.ContributeToValidatorsAndCommunityPool(ctx, totalMonthlyReward, types.ModuleName) diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index 28c26e3b00..d6a81b47c9 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -64,7 +64,7 @@ type DualStakingKeeper interface { } type RewardsKeeper interface { - AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int) + AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int, sub string, cu uint64) MaxRewardBoost(ctx sdk.Context) (res uint64) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward math.Int, senderModule string) (updatedReward math.Int, err error) FundCommunityPoolFromModule(ctx sdk.Context, amount math.Int, senderModule string) error From a3317ac84184dae5f14f2c894bf8cb7711277be8 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Tue, 13 Feb 2024 12:03:48 +0200 Subject: [PATCH 14/64] CNS-870: implemented iprpc pool --- app/app.go | 1 + proto/lavanet/lava/pairing/debug_query.proto | 8 +- proto/lavanet/lava/rewards/iprpc.proto | 5 +- proto/lavanet/lava/rewards/query.proto | 5 +- scripts/init_chain.sh | 1 + x/dualstaking/keeper/delegator_reward.go | 70 +++--- x/pairing/client/cli/query_debug_query.go | 16 +- x/pairing/keeper/delegator_rewards_test.go | 8 +- .../grpc_query_provider_monthly_payout.go | 6 +- x/pairing/types/debug_query.pb.go | 216 ++++++++++++------ x/pairing/types/expected_keepers.go | 2 +- x/rewards/genesis_test.go | 6 +- x/rewards/keeper/grpc_query_block_reward.go | 3 +- x/rewards/keeper/grpc_query_pools.go | 12 +- x/rewards/keeper/helpers_test.go | 17 +- x/rewards/keeper/iprpc_reward.go | 25 ++ x/rewards/keeper/pool.go | 4 +- x/rewards/keeper/pool_test.go | 29 ++- x/rewards/keeper/providers.go | 120 ++++++++-- x/rewards/keeper/providers_test.go | 12 +- x/rewards/keeper/rewards.go | 17 +- x/rewards/types/expected_keepers.go | 3 +- x/rewards/types/genesis.go | 2 +- x/rewards/types/iprpc.pb.go | 46 ++-- x/rewards/types/keys.go | 2 +- x/rewards/types/query.pb.go | 130 ++++++----- x/rewards/types/types.go | 11 +- x/subscription/keeper/cu_tracker.go | 16 +- x/subscription/types/expected_keepers.go | 6 +- 29 files changed, 512 insertions(+), 287 deletions(-) diff --git a/app/app.go b/app/app.go index 9379090aa1..18dbe2a360 100644 --- a/app/app.go +++ b/app/app.go @@ -265,6 +265,7 @@ var ( string(rewardsmoduletypes.ProviderRewardsDistributionPool): {authtypes.Burner, authtypes.Staking}, string(rewardsmoduletypes.ProvidersRewardsAllocationPool): {authtypes.Minter, authtypes.Staking}, dualstakingmoduletypes.ModuleName: {authtypes.Burner, authtypes.Staking}, + string(rewardsmoduletypes.IprpcPoolName): nil, // this line is used by starport scaffolding # stargate/app/maccPerms } ) diff --git a/proto/lavanet/lava/pairing/debug_query.proto b/proto/lavanet/lava/pairing/debug_query.proto index fc5075d2f5..c8acbe60cb 100644 --- a/proto/lavanet/lava/pairing/debug_query.proto +++ b/proto/lavanet/lava/pairing/debug_query.proto @@ -13,10 +13,10 @@ import "lavanet/lava/projects/project.proto"; message QueryDebugQueryResponse { uint64 block_reward = 1; - uint64 val_dist_pool_balance = 2; - uint64 val_alloc_pool_balance = 3; - uint64 provider_dist_pool_balance = 4; - uint64 provider_alloc_pool_balance = 5; + string val_dist_pool_balance = 2; + string val_alloc_pool_balance = 3; + string provider_dist_pool_balance = 4; + string provider_alloc_pool_balance = 5; uint64 provider_full_reward = 6; uint64 provider_reward_no_bonus = 7; uint64 block = 8; diff --git a/proto/lavanet/lava/rewards/iprpc.proto b/proto/lavanet/lava/rewards/iprpc.proto index 8f3f644463..749fd1cb54 100644 --- a/proto/lavanet/lava/rewards/iprpc.proto +++ b/proto/lavanet/lava/rewards/iprpc.proto @@ -13,5 +13,8 @@ message IprpcReward { message Specfund { string spec = 1; - repeated cosmos.base.v1beta1.Coin fund = 2 [(gogoproto.nullable) = false]; + repeated cosmos.base.v1beta1.Coin fund = 2 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; } \ No newline at end of file diff --git a/proto/lavanet/lava/rewards/query.proto b/proto/lavanet/lava/rewards/query.proto index 305b4acc0e..dd0ec78fe3 100644 --- a/proto/lavanet/lava/rewards/query.proto +++ b/proto/lavanet/lava/rewards/query.proto @@ -48,7 +48,10 @@ message QueryPoolsRequest {} message PoolInfo { string name = 1; // pool name - cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false]; // pool balance + repeated cosmos.base.v1beta1.Coin balance = 2 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; // pool balance (all types of tokens) } // QueryPoolsResponse is response type for the Query/Pools RPC method. diff --git a/scripts/init_chain.sh b/scripts/init_chain.sh index da4c53ea5b..3fa6f9741c 100755 --- a/scripts/init_chain.sh +++ b/scripts/init_chain.sh @@ -113,6 +113,7 @@ if [ "$1" == "debug" ]; then else lavad add-genesis-account providers_rewards_allocation_pool 30000000000000ulava --module-account fi +lavad add-genesis-account iprpc_pool 0ulava --module-account lavad gentx alice 10000000000000ulava --chain-id $chainID lavad collect-gentxs lavad start --pruning=nothing \ No newline at end of file diff --git a/x/dualstaking/keeper/delegator_reward.go b/x/dualstaking/keeper/delegator_reward.go index 3812e3f493..99a82a68a1 100644 --- a/x/dualstaking/keeper/delegator_reward.go +++ b/x/dualstaking/keeper/delegator_reward.go @@ -82,18 +82,20 @@ func (k Keeper) GetAllDelegatorReward(ctx sdk.Context) (list []types.DelegatorRe // CalcRewards calculates the provider reward and the total reward for delegators // providerReward = totalReward * ((effectiveDelegations*commission + providerStake) / effectiveStake) // delegatorsReward = totalReward - providerReward -func (k Keeper) CalcRewards(stakeEntry epochstoragetypes.StakeEntry, totalReward math.Int, delegations []types.Delegation) (providerReward math.Int, delegatorsReward math.Int) { +func (k Keeper) CalcRewards(stakeEntry epochstoragetypes.StakeEntry, totalReward sdk.Coin, delegations []types.Delegation) (providerReward sdk.Coin, delegatorsReward sdk.Coin) { + zeroCoin := sdk.NewCoin(totalReward.Denom, math.ZeroInt()) effectiveDelegations, effectiveStake := k.CalcEffectiveDelegationsAndStake(stakeEntry, delegations) // Sanity check - effectiveStake != 0 if effectiveStake.IsZero() { - return math.ZeroInt(), math.ZeroInt() + return zeroCoin, zeroCoin } - providerReward = totalReward.Mul(stakeEntry.Stake.Amount).Quo(effectiveStake) - rawDelegatorsReward := totalReward.Mul(effectiveDelegations).Quo(effectiveStake) - providerCommission := rawDelegatorsReward.MulRaw(int64(stakeEntry.DelegateCommission)).QuoRaw(100) - providerReward = providerReward.Add(providerCommission) + providerRewardAmount := totalReward.Amount.Mul(stakeEntry.Stake.Amount).Quo(effectiveStake) + rawDelegatorsRewardAmount := totalReward.Amount.Mul(effectiveDelegations).Quo(effectiveStake) + providerCommission := rawDelegatorsRewardAmount.MulRaw(int64(stakeEntry.DelegateCommission)).QuoRaw(100) + providerRewardAmount = providerRewardAmount.Add(providerCommission) + providerReward = sdk.NewCoin(totalReward.Denom, providerRewardAmount) return providerReward, totalReward.Sub(providerReward) } @@ -163,36 +165,38 @@ func (k Keeper) ClaimRewards(ctx sdk.Context, delegator string, provider string) // RewardProvidersAndDelegators is the main function handling provider rewards with delegations // it returns the provider reward amount and updates the delegatorReward map with the reward portion for each delegator -func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward math.Int, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward math.Int, claimableRewards math.Int, err error) { +func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, claimableRewards sdk.Coin, err error) { block := uint64(ctx.BlockHeight()) + zeroCoin := sdk.NewCoin(totalReward.Denom, math.ZeroInt()) epoch, _, err := k.epochstorageKeeper.GetEpochStartForBlock(ctx, block) if err != nil { - return math.ZeroInt(), math.ZeroInt(), utils.LavaFormatError(types.ErrCalculatingProviderReward.Error(), err, + return zeroCoin, zeroCoin, utils.LavaFormatError(types.ErrCalculatingProviderReward.Error(), err, utils.Attribute{Key: "block", Value: block}, ) } stakeEntry, err := k.epochstorageKeeper.GetStakeEntryForProviderEpoch(ctx, chainID, providerAddr, epoch) if err != nil { - return math.ZeroInt(), math.ZeroInt(), err + return zeroCoin, zeroCoin, err } delegations, err := k.GetProviderDelegators(ctx, providerAddr.String(), epoch) if err != nil { - return math.ZeroInt(), math.ZeroInt(), utils.LavaFormatError("cannot get provider's delegators", err) + return zeroCoin, zeroCoin, utils.LavaFormatError("cannot get provider's delegators", err) } claimableRewards = totalReward // make sure this is post boost when rewards pool is introduced contributorAddresses, contributorPart := k.specKeeper.GetContributorReward(ctx, chainID) contributorsNum := int64(len(contributorAddresses)) if contributorsNum != 0 && contributorPart.GT(math.LegacyZeroDec()) { - contributorReward := totalReward.MulRaw(contributorPart.MulInt64(spectypes.ContributorPrecision).RoundInt64()).QuoRaw(spectypes.ContributorPrecision) + contributorRewardAmount := totalReward.Amount.MulRaw(contributorPart.MulInt64(spectypes.ContributorPrecision).RoundInt64()).QuoRaw(spectypes.ContributorPrecision) // make sure to round it down for the integers division - contributorReward = contributorReward.QuoRaw(contributorsNum).MulRaw(contributorsNum) + contributorRewardAmount = contributorRewardAmount.QuoRaw(contributorsNum).MulRaw(contributorsNum) + contributorReward := sdk.NewCoin(totalReward.Denom, contributorRewardAmount) claimableRewards = totalReward.Sub(contributorReward) if !calcOnlyContributer { err = k.PayContributors(ctx, senderModule, contributorAddresses, contributorReward, chainID) if err != nil { - return math.ZeroInt(), math.ZeroInt(), err + return zeroCoin, zeroCoin, err } } } @@ -202,13 +206,13 @@ func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.A return d.ChainID == chainID && d.IsFirstMonthPassed(ctx.BlockTime().UTC().Unix()) && d.Delegator != d.Provider }) - providerReward, delegatorsReward := k.CalcRewards(*stakeEntry, claimableRewards, relevantDelegations) + providerRewardAmount, delegatorsReward := k.CalcRewards(*stakeEntry, claimableRewards, relevantDelegations) - leftoverRewards := k.updateDelegatorsReward(ctx, stakeEntry.DelegateTotal.Amount, relevantDelegations, totalReward, delegatorsReward, senderModule, calcOnlyDelegators) - fullProviderReward := providerReward.Add(leftoverRewards) + leftoverRewards := k.updateDelegatorsReward(ctx, stakeEntry.DelegateTotal.Amount, relevantDelegations, delegatorsReward, senderModule, calcOnlyDelegators) + fullProviderReward := providerRewardAmount.Add(leftoverRewards) if !calcOnlyProvider { - if fullProviderReward.GT(math.ZeroInt()) { + if fullProviderReward.Amount.GT(math.ZeroInt()) { k.rewardDelegator(ctx, types.Delegation{Provider: providerAddr.String(), ChainID: chainID, Delegator: providerAddr.String()}, fullProviderReward, senderModule) } } @@ -217,23 +221,24 @@ func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.A } // updateDelegatorsReward updates the delegator rewards map -func (k Keeper) updateDelegatorsReward(ctx sdk.Context, totalDelegations math.Int, delegations []types.Delegation, totalReward math.Int, delegatorsReward math.Int, senderModule string, calcOnly bool) (leftoverRewards math.Int) { - usedDelegatorRewards := math.ZeroInt() // the delegator rewards are calculated using int division, so there might be leftovers +func (k Keeper) updateDelegatorsReward(ctx sdk.Context, totalDelegations math.Int, delegations []types.Delegation, delegatorsReward sdk.Coin, senderModule string, calcOnly bool) (leftoverRewards sdk.Coin) { + usedDelegatorRewards := sdk.NewCoin(delegatorsReward.Denom, math.ZeroInt()) // the delegator rewards are calculated using int division, so there might be leftovers for _, delegation := range delegations { - delegatorRewardAmount := k.CalcDelegatorReward(delegatorsReward, totalDelegations, delegation) + delegatorRewardAmount := k.CalcDelegatorReward(delegatorsReward.Amount, totalDelegations, delegation) + delegatorReward := sdk.NewCoin(delegatorsReward.Denom, delegatorRewardAmount) if !calcOnly { - k.rewardDelegator(ctx, delegation, delegatorRewardAmount, senderModule) + k.rewardDelegator(ctx, delegation, delegatorReward, senderModule) } - usedDelegatorRewards = usedDelegatorRewards.Add(delegatorRewardAmount) + usedDelegatorRewards = usedDelegatorRewards.Add(delegatorReward) } return delegatorsReward.Sub(usedDelegatorRewards) } -func (k Keeper) rewardDelegator(ctx sdk.Context, delegation types.Delegation, amount math.Int, senderModule string) { +func (k Keeper) rewardDelegator(ctx sdk.Context, delegation types.Delegation, amount sdk.Coin, senderModule string) { if amount.IsZero() { return } @@ -244,25 +249,25 @@ func (k Keeper) rewardDelegator(ctx sdk.Context, delegation types.Delegation, am delegatorReward.Provider = delegation.Provider delegatorReward.Delegator = delegation.Delegator delegatorReward.ChainId = delegation.ChainID - delegatorReward.Amount = sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), amount) + delegatorReward.Amount = amount } else { - delegatorReward.Amount = delegatorReward.Amount.AddAmount(amount) + delegatorReward.Amount = delegatorReward.Amount.Add(amount) } k.SetDelegatorReward(ctx, delegatorReward) - err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, senderModule, types.ModuleName, sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), amount))) + err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, senderModule, types.ModuleName, sdk.NewCoins(amount)) if err != nil { utils.LavaFormatError("failed to send rewards to module", err, utils.LogAttr("sender", senderModule), utils.LogAttr("amount", amount.String())) } } -func (k Keeper) PayContributors(ctx sdk.Context, senderModule string, contributorAddresses []sdk.AccAddress, contributorReward math.Int, specId string) error { +func (k Keeper) PayContributors(ctx sdk.Context, senderModule string, contributorAddresses []sdk.AccAddress, contributorReward sdk.Coin, specId string) error { if len(contributorAddresses) == 0 { // do not return this error since we don;t want to bail utils.LavaFormatError("contributor addresses for pay are empty", nil) return nil } - rewardPerContributor := contributorReward.QuoRaw(int64(len(contributorAddresses))) - rewardCoins := sdk.Coins{sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), rewardPerContributor)} + rewardPerContributor := contributorReward.Amount.QuoRaw(int64(len(contributorAddresses))) + rewardCoins := sdk.Coins{sdk.NewCoin(contributorReward.Denom, rewardPerContributor)} details := map[string]string{ "rewardCoins": rewardCoins.String(), "specId": specId, @@ -270,17 +275,18 @@ func (k Keeper) PayContributors(ctx sdk.Context, senderModule string, contributo leftRewards := contributorReward for i, contributorAddress := range contributorAddresses { details["address."+strconv.Itoa(i)] = contributorAddress.String() - if leftRewards.LT(rewardCoins.AmountOf(k.stakingKeeper.BondDenom(ctx))) { + rewardCoin := sdk.NewCoin(contributorReward.Denom, rewardCoins.AmountOf(contributorReward.Denom)) + if leftRewards.IsLT(rewardCoin) { return utils.LavaFormatError("trying to pay contributors more than their allowed amount", nil, utils.LogAttr("rewardCoins", rewardCoins.String()), utils.LogAttr("contributorReward", contributorReward.String()), utils.LogAttr("leftRewards", leftRewards.String())) } - leftRewards = leftRewards.Sub(rewardCoins.AmountOf(k.stakingKeeper.BondDenom(ctx))) + leftRewards = leftRewards.Sub(rewardCoin) err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, senderModule, contributorAddress, rewardCoins) if err != nil { return err } } utils.LogLavaEvent(ctx, k.Logger(ctx), types.ContributorRewardEventName, details, "contributors rewards given") - if leftRewards.GT(math.ZeroInt()) { + if leftRewards.Amount.GT(math.ZeroInt()) { utils.LavaFormatError("leftover rewards", nil, utils.LogAttr("rewardCoins", rewardCoins.String()), utils.LogAttr("contributorReward", contributorReward.String()), utils.LogAttr("leftRewards", leftRewards.String())) // we don;t want to bail on this return nil diff --git a/x/pairing/client/cli/query_debug_query.go b/x/pairing/client/cli/query_debug_query.go index 52835dce4a..4e582b971a 100644 --- a/x/pairing/client/cli/query_debug_query.go +++ b/x/pairing/client/cli/query_debug_query.go @@ -71,13 +71,13 @@ func CmdDebugQuery() *cobra.Command { for _, pool := range resPools.Pools { switch pool.Name { case string(rewardstypes.ValidatorsRewardsAllocationPoolName): - info.ValAllocPoolBalance = pool.Balance.Amount.Uint64() + info.ValAllocPoolBalance = pool.Balance.String() case string(rewardstypes.ValidatorsRewardsDistributionPoolName): - info.ValDistPoolBalance = pool.Balance.Amount.Uint64() + info.ValDistPoolBalance = pool.Balance.String() case string(rewardstypes.ProvidersRewardsAllocationPool): - info.ProviderAllocPoolBalance = pool.Balance.Amount.Uint64() + info.ProviderAllocPoolBalance = pool.Balance.String() case string(rewardstypes.ProviderRewardsDistributionPool): - info.ProviderDistPoolBalance = pool.Balance.Amount.Uint64() + info.ProviderDistPoolBalance = pool.Balance.String() } } @@ -132,10 +132,10 @@ func CmdDebugQuery() *cobra.Command { strToPrint := strings.Join([]string{ strconv.FormatUint(info.Block, 10), strconv.FormatUint(info.BlockReward, 10), - strconv.FormatUint(info.ValAllocPoolBalance, 10), - strconv.FormatUint(info.ValDistPoolBalance, 10), - strconv.FormatUint(info.ProviderAllocPoolBalance, 10), - strconv.FormatUint(info.ProviderDistPoolBalance, 10), + info.ValAllocPoolBalance, + info.ValDistPoolBalance, + info.ProviderAllocPoolBalance, + info.ProviderDistPoolBalance, strconv.FormatUint(info.MonthsLeft, 10), strconv.FormatUint(info.ProviderFullReward, 10), strconv.FormatUint(info.ProviderRewardNoBonus, 10), diff --git a/x/pairing/keeper/delegator_rewards_test.go b/x/pairing/keeper/delegator_rewards_test.go index d5bcb392b1..e62606da79 100644 --- a/x/pairing/keeper/delegator_rewards_test.go +++ b/x/pairing/keeper/delegator_rewards_test.go @@ -285,7 +285,7 @@ func TestProviderRewardWithCommission(t *testing.T) { func(d dualstakingtypes.Delegation) bool { return d.ChainID == ts.spec.Index && d.IsFirstMonthPassed(currentTimestamp) }) - totalReward := math.NewInt(int64(relayCuSum)) + totalReward := sdk.NewCoin(ts.TokenDenom(), math.NewInt(int64(relayCuSum))) providerReward, _ := ts.Keepers.Dualstaking.CalcRewards(stakeEntry, totalReward, relevantDelegations) require.True(t, totalReward.Equal(providerReward)) @@ -315,7 +315,7 @@ func TestProviderRewardWithCommission(t *testing.T) { require.Equal(t, 1, len(resRewards.Rewards)) dReward := resRewards.Rewards[0] expectedDRewardForRelay := totalReward - require.Equal(t, expectedDRewardForRelay.Int64()/2, dReward.Amount.Amount.Int64()) + require.Equal(t, expectedDRewardForRelay.Amount.Int64()/2, dReward.Amount.Amount.Int64()) // claim delegator rewards and verify balance claimRewardsAndVerifyBalance(ts, delegator1Acc.Addr, provider, ts.spec.Index) @@ -564,7 +564,7 @@ func TestDelegationFirstMonthReward(t *testing.T) { // the delegation will already mature enough to be part of the reward process. To go around // this, we'll call the reward calculation function directly with a fabricated reward just to // verify that the delegator gets nothing from the total reward - fakeReward := sdk.NewInt(testStake) + fakeReward := sdk.NewCoin(ts.TokenDenom(), sdk.NewInt(testStake)) providerReward, _, err := ts.Keepers.Dualstaking.RewardProvidersAndDelegators(ts.Ctx, providerAcc.Addr, ts.spec.Index, fakeReward, subscriptiontypes.ModuleName, true, true, true) require.NoError(t, err) @@ -628,7 +628,7 @@ func TestRedelegationFirstMonthReward(t *testing.T) { // this, we'll call the reward calculation function directly with a fabricated reward just to // verify that the delegator gets nothing from the total reward from provider1 but does get // reward from provider - fakeReward := sdk.NewInt(testStake) + fakeReward := sdk.NewCoin(ts.TokenDenom(), sdk.NewInt(testStake)) provider1Reward, _, err := ts.Keepers.Dualstaking.RewardProvidersAndDelegators(ts.Ctx, provider1Acc.Addr, ts.spec.Index, fakeReward, subscriptiontypes.ModuleName, true, false, true) require.NoError(t, err) diff --git a/x/pairing/keeper/grpc_query_provider_monthly_payout.go b/x/pairing/keeper/grpc_query_provider_monthly_payout.go index a0b3d2f186..97796de386 100644 --- a/x/pairing/keeper/grpc_query_provider_monthly_payout.go +++ b/x/pairing/keeper/grpc_query_provider_monthly_payout.go @@ -74,7 +74,7 @@ func (k Keeper) ProviderMonthlyPayout(goCtx context.Context, req *types.QueryPro totalMonthlyReward := k.subscriptionKeeper.CalcTotalMonthlyReward(ctx, totalTokenAmount, providerCu, totalCuTracked) // calculate only the provider reward - providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, totalMonthlyReward, subsciptiontypes.ModuleName, true, true, true) + providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), totalMonthlyReward), subsciptiontypes.ModuleName, true, true, true) if err != nil { return nil, err } @@ -82,9 +82,9 @@ func (k Keeper) ProviderMonthlyPayout(goCtx context.Context, req *types.QueryPro details = append(details, &types.SubscriptionPayout{ Subscription: sub, ChainId: chainID, - Amount: providerReward.Uint64(), + Amount: providerReward.Amount.Uint64(), }) - total += providerReward.Uint64() + total += providerReward.Amount.Uint64() } } diff --git a/x/pairing/types/debug_query.pb.go b/x/pairing/types/debug_query.pb.go index 87b849474c..8a57a5dda2 100644 --- a/x/pairing/types/debug_query.pb.go +++ b/x/pairing/types/debug_query.pb.go @@ -31,10 +31,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type QueryDebugQueryResponse struct { BlockReward uint64 `protobuf:"varint,1,opt,name=block_reward,json=blockReward,proto3" json:"block_reward,omitempty"` - ValDistPoolBalance uint64 `protobuf:"varint,2,opt,name=val_dist_pool_balance,json=valDistPoolBalance,proto3" json:"val_dist_pool_balance,omitempty"` - ValAllocPoolBalance uint64 `protobuf:"varint,3,opt,name=val_alloc_pool_balance,json=valAllocPoolBalance,proto3" json:"val_alloc_pool_balance,omitempty"` - ProviderDistPoolBalance uint64 `protobuf:"varint,4,opt,name=provider_dist_pool_balance,json=providerDistPoolBalance,proto3" json:"provider_dist_pool_balance,omitempty"` - ProviderAllocPoolBalance uint64 `protobuf:"varint,5,opt,name=provider_alloc_pool_balance,json=providerAllocPoolBalance,proto3" json:"provider_alloc_pool_balance,omitempty"` + ValDistPoolBalance string `protobuf:"bytes,2,opt,name=val_dist_pool_balance,json=valDistPoolBalance,proto3" json:"val_dist_pool_balance,omitempty"` + ValAllocPoolBalance string `protobuf:"bytes,3,opt,name=val_alloc_pool_balance,json=valAllocPoolBalance,proto3" json:"val_alloc_pool_balance,omitempty"` + ProviderDistPoolBalance string `protobuf:"bytes,4,opt,name=provider_dist_pool_balance,json=providerDistPoolBalance,proto3" json:"provider_dist_pool_balance,omitempty"` + ProviderAllocPoolBalance string `protobuf:"bytes,5,opt,name=provider_alloc_pool_balance,json=providerAllocPoolBalance,proto3" json:"provider_alloc_pool_balance,omitempty"` ProviderFullReward uint64 `protobuf:"varint,6,opt,name=provider_full_reward,json=providerFullReward,proto3" json:"provider_full_reward,omitempty"` ProviderRewardNoBonus uint64 `protobuf:"varint,7,opt,name=provider_reward_no_bonus,json=providerRewardNoBonus,proto3" json:"provider_reward_no_bonus,omitempty"` Block uint64 `protobuf:"varint,8,opt,name=block,proto3" json:"block,omitempty"` @@ -82,32 +82,32 @@ func (m *QueryDebugQueryResponse) GetBlockReward() uint64 { return 0 } -func (m *QueryDebugQueryResponse) GetValDistPoolBalance() uint64 { +func (m *QueryDebugQueryResponse) GetValDistPoolBalance() string { if m != nil { return m.ValDistPoolBalance } - return 0 + return "" } -func (m *QueryDebugQueryResponse) GetValAllocPoolBalance() uint64 { +func (m *QueryDebugQueryResponse) GetValAllocPoolBalance() string { if m != nil { return m.ValAllocPoolBalance } - return 0 + return "" } -func (m *QueryDebugQueryResponse) GetProviderDistPoolBalance() uint64 { +func (m *QueryDebugQueryResponse) GetProviderDistPoolBalance() string { if m != nil { return m.ProviderDistPoolBalance } - return 0 + return "" } -func (m *QueryDebugQueryResponse) GetProviderAllocPoolBalance() uint64 { +func (m *QueryDebugQueryResponse) GetProviderAllocPoolBalance() string { if m != nil { return m.ProviderAllocPoolBalance } - return 0 + return "" } func (m *QueryDebugQueryResponse) GetProviderFullReward() uint64 { @@ -154,38 +154,38 @@ func init() { } var fileDescriptor_a315cb51b0edeaef = []byte{ - // 488 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, - 0x10, 0xc6, 0x13, 0xfa, 0x07, 0xd8, 0x22, 0x81, 0x4c, 0x4a, 0xad, 0x20, 0x99, 0xbf, 0xa2, 0x20, - 0x50, 0x4c, 0xd4, 0x03, 0x07, 0xc4, 0xa1, 0x51, 0xc5, 0x09, 0x21, 0xc8, 0x91, 0x8b, 0x35, 0xb6, - 0x27, 0x8e, 0xe9, 0xc4, 0xb3, 0xec, 0xae, 0x5d, 0xfa, 0x16, 0x3c, 0x16, 0xc7, 0x1e, 0x39, 0xa2, - 0xe4, 0xcc, 0x3b, 0x20, 0xaf, 0xbd, 0x16, 0xa6, 0x3d, 0xed, 0xcc, 0x7c, 0xbf, 0x6f, 0xbf, 0x64, - 0xb4, 0x16, 0xcf, 0x08, 0x2a, 0x28, 0xd0, 0x84, 0xf5, 0x19, 0x4a, 0xc8, 0x55, 0x5e, 0x64, 0x61, - 0x8a, 0x71, 0x99, 0x45, 0xdf, 0x4a, 0x54, 0xe7, 0x13, 0xa9, 0xd8, 0xb0, 0x37, 0x6a, 0xb9, 0x49, - 0x7d, 0x4e, 0x5a, 0x6e, 0x3c, 0xca, 0x38, 0x63, 0x0b, 0x84, 0x75, 0xd5, 0xb0, 0xe3, 0x20, 0x63, - 0xce, 0x08, 0x43, 0xdb, 0xc5, 0xe5, 0x22, 0x3c, 0x53, 0x20, 0x25, 0x2a, 0xdd, 0xea, 0x2f, 0x7b, - 0x99, 0x28, 0x39, 0x59, 0x6a, 0xc3, 0x0a, 0x32, 0x0c, 0xb5, 0x81, 0x53, 0x8c, 0xb0, 0x30, 0x2e, - 0x78, 0x7c, 0xd8, 0x83, 0xd3, 0x12, 0xa8, 0x66, 0x9a, 0x1f, 0x49, 0x98, 0x81, 0xc1, 0x16, 0x7c, - 0x9a, 0xb0, 0x5e, 0xb1, 0x0e, 0x9d, 0x5c, 0x4d, 0x63, 0x34, 0x30, 0x75, 0x7d, 0x4b, 0xbd, 0xea, - 0x5d, 0xa7, 0xcb, 0x58, 0x27, 0x2a, 0x97, 0x26, 0xe7, 0xa2, 0xd7, 0xb4, 0xf4, 0x93, 0xfe, 0x76, - 0x14, 0x7f, 0xc5, 0xc4, 0x68, 0x57, 0x34, 0xd0, 0xe3, 0x3f, 0x5b, 0xe2, 0xe0, 0x73, 0xbd, 0xaa, - 0x93, 0x7a, 0x6b, 0xb6, 0x9a, 0xa3, 0x96, 0x5c, 0x68, 0xf4, 0x1e, 0x89, 0x5b, 0x31, 0x71, 0x72, - 0x1a, 0x29, 0x3c, 0x03, 0x95, 0xfa, 0xc3, 0x87, 0xc3, 0xe7, 0xdb, 0xf3, 0x3d, 0x3b, 0x9b, 0xdb, - 0x91, 0x37, 0x15, 0xfb, 0x15, 0x50, 0x94, 0xe6, 0xda, 0x44, 0x92, 0x99, 0xa2, 0x18, 0x08, 0x8a, - 0x04, 0xfd, 0x6b, 0x96, 0xf5, 0x2a, 0xa0, 0x93, 0x5c, 0x9b, 0x4f, 0xcc, 0x34, 0x6b, 0x14, 0xef, - 0x48, 0xdc, 0xab, 0x2d, 0x40, 0xc4, 0x49, 0xdf, 0xb3, 0x65, 0x3d, 0x77, 0x2b, 0xa0, 0xe3, 0x5a, - 0xfc, 0xd7, 0xf4, 0x56, 0x8c, 0xa5, 0xe2, 0x2a, 0x4f, 0x51, 0x5d, 0x11, 0xb6, 0x6d, 0x8d, 0x07, - 0x8e, 0xf8, 0x3f, 0xf1, 0x9d, 0xb8, 0xdf, 0x99, 0xaf, 0x88, 0xdd, 0xb1, 0x6e, 0xdf, 0x21, 0x97, - 0xb2, 0x5f, 0x8b, 0x51, 0x67, 0x5f, 0x94, 0x44, 0x6e, 0x1d, 0xbb, 0xcd, 0x5f, 0x74, 0xda, 0xfb, - 0x92, 0xa8, 0xdd, 0xca, 0x1b, 0xd1, 0xdd, 0xd6, 0xc2, 0x51, 0xc1, 0x51, 0xcc, 0x45, 0xa9, 0xfd, - 0xeb, 0xd6, 0xb5, 0xef, 0xf4, 0xc6, 0xf1, 0x91, 0x67, 0xb5, 0xe8, 0x8d, 0xc4, 0x8e, 0xdd, 0xae, - 0x7f, 0xc3, 0x52, 0x4d, 0xe3, 0x3d, 0x10, 0x7b, 0x2b, 0x2e, 0xcc, 0x52, 0x47, 0x84, 0x0b, 0xe3, - 0xdf, 0xb4, 0x9a, 0x68, 0x46, 0x1f, 0x70, 0x61, 0xbc, 0x17, 0xe2, 0x4e, 0x05, 0x94, 0xa7, 0x60, - 0xd8, 0x05, 0xfa, 0xc2, 0x52, 0xb7, 0xbb, 0x79, 0x13, 0x34, 0x3b, 0xfe, 0xb9, 0x0e, 0x86, 0x17, - 0xeb, 0x60, 0xf8, 0x7b, 0x1d, 0x0c, 0x7f, 0x6c, 0x82, 0xc1, 0xc5, 0x26, 0x18, 0xfc, 0xda, 0x04, - 0x83, 0x2f, 0x87, 0x59, 0x6e, 0x96, 0x65, 0x3c, 0x49, 0x78, 0x15, 0xf6, 0x5e, 0xce, 0xf7, 0xee, - 0xcb, 0x32, 0xe7, 0x12, 0x75, 0xbc, 0x6b, 0x5f, 0xce, 0xd1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x75, 0x48, 0x29, 0xd9, 0x7e, 0x03, 0x00, 0x00, + // 492 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0xcd, 0x6e, 0xd3, 0x40, + 0x14, 0x85, 0x63, 0xfa, 0x03, 0x9d, 0x22, 0x81, 0x4c, 0x4a, 0xad, 0x20, 0x99, 0xf2, 0x23, 0x5a, + 0x04, 0x8a, 0x89, 0xba, 0x60, 0x81, 0x58, 0x34, 0xaa, 0x58, 0x21, 0x04, 0x59, 0xb2, 0xb1, 0xc6, + 0xf6, 0x8d, 0x63, 0x7a, 0xe3, 0x3b, 0xcc, 0x8c, 0x5d, 0xfa, 0x16, 0x3c, 0x16, 0xcb, 0x2e, 0x59, + 0xa2, 0x64, 0xcd, 0x3b, 0xa0, 0x19, 0x7b, 0x2c, 0x0c, 0x59, 0x79, 0xee, 0x3d, 0xdf, 0x99, 0x13, + 0x1d, 0x4d, 0xd8, 0x33, 0xe4, 0x35, 0x2f, 0x41, 0x47, 0xe6, 0x1b, 0x09, 0x5e, 0xc8, 0xa2, 0xcc, + 0xa3, 0x0c, 0x92, 0x2a, 0x8f, 0xbf, 0x56, 0x20, 0xaf, 0xc6, 0x42, 0x92, 0x26, 0x7f, 0xd8, 0x72, + 0x63, 0xf3, 0x1d, 0xb7, 0xdc, 0x68, 0x98, 0x53, 0x4e, 0x16, 0x88, 0xcc, 0xa9, 0x61, 0x47, 0x61, + 0x4e, 0x94, 0x23, 0x44, 0x76, 0x4a, 0xaa, 0x79, 0x74, 0x29, 0xb9, 0x10, 0x20, 0x55, 0xab, 0xbf, + 0xe8, 0x65, 0x82, 0xa0, 0x74, 0xa1, 0x34, 0x49, 0x9e, 0x43, 0xa4, 0x34, 0xbf, 0x80, 0x18, 0x4a, + 0xed, 0x82, 0x47, 0xc7, 0x3d, 0x38, 0xab, 0x38, 0x1a, 0xa6, 0xf9, 0x91, 0x08, 0x39, 0xd7, 0xd0, + 0x82, 0x4f, 0x53, 0x52, 0x4b, 0x52, 0x91, 0x93, 0xeb, 0x49, 0x02, 0x9a, 0x4f, 0xdc, 0xdc, 0x52, + 0x2f, 0x7b, 0xd7, 0xa9, 0x2a, 0x51, 0xa9, 0x2c, 0x84, 0x2e, 0xa8, 0xec, 0x0d, 0x2d, 0xfd, 0xa4, + 0xdf, 0x8e, 0xa4, 0x2f, 0x90, 0x6a, 0xe5, 0x0e, 0x0d, 0xf4, 0xf8, 0xf7, 0x16, 0x3b, 0xfc, 0x64, + 0xaa, 0x3a, 0x37, 0xad, 0xd9, 0xd3, 0x0c, 0x94, 0xa0, 0x52, 0x81, 0xff, 0x88, 0xdd, 0x4e, 0x90, + 0xd2, 0x8b, 0x58, 0xc2, 0x25, 0x97, 0x59, 0xe0, 0x1d, 0x79, 0x27, 0xdb, 0xb3, 0x7d, 0xbb, 0x9b, + 0xd9, 0x95, 0x3f, 0x61, 0x07, 0x35, 0xc7, 0x38, 0x2b, 0x94, 0x8e, 0x05, 0x11, 0xc6, 0x09, 0x47, + 0x5e, 0xa6, 0x10, 0xdc, 0x38, 0xf2, 0x4e, 0xf6, 0x66, 0x7e, 0xcd, 0xf1, 0xbc, 0x50, 0xfa, 0x23, + 0x11, 0x4e, 0x1b, 0xc5, 0x3f, 0x65, 0xf7, 0x8d, 0x85, 0x23, 0x52, 0xda, 0xf7, 0x6c, 0x59, 0xcf, + 0xbd, 0x9a, 0xe3, 0x99, 0x11, 0xff, 0x36, 0xbd, 0x61, 0x23, 0x21, 0xa9, 0x2e, 0x32, 0x90, 0x1b, + 0xc2, 0xb6, 0xad, 0xf1, 0xd0, 0x11, 0xff, 0x26, 0xbe, 0x65, 0x0f, 0x3a, 0xf3, 0x86, 0xd8, 0x1d, + 0xeb, 0x0e, 0x1c, 0xf2, 0x5f, 0xf6, 0x2b, 0x36, 0xec, 0xec, 0xf3, 0x0a, 0xd1, 0xd5, 0xb1, 0x6b, + 0xeb, 0xf0, 0x9d, 0xf6, 0xae, 0x42, 0x6c, 0x5b, 0x79, 0xcd, 0xba, 0xdb, 0x5a, 0x38, 0x2e, 0x29, + 0x4e, 0xa8, 0xac, 0x54, 0x70, 0xd3, 0xba, 0x0e, 0x9c, 0xde, 0x38, 0x3e, 0xd0, 0xd4, 0x88, 0xfe, + 0x90, 0xed, 0xd8, 0x76, 0x83, 0x5b, 0x96, 0x6a, 0x06, 0xff, 0x21, 0xdb, 0x5f, 0x52, 0xa9, 0x17, + 0x2a, 0x46, 0x98, 0xeb, 0x60, 0xcf, 0x6a, 0xac, 0x59, 0xbd, 0x87, 0xb9, 0xf6, 0x9f, 0xb3, 0xbb, + 0x35, 0xc7, 0x22, 0xe3, 0x9a, 0x5c, 0x60, 0xc0, 0x2c, 0x75, 0xa7, 0xdb, 0x37, 0x41, 0xd3, 0xb3, + 0x1f, 0xab, 0xd0, 0xbb, 0x5e, 0x85, 0xde, 0xaf, 0x55, 0xe8, 0x7d, 0x5f, 0x87, 0x83, 0xeb, 0x75, + 0x38, 0xf8, 0xb9, 0x0e, 0x07, 0x9f, 0x8f, 0xf3, 0x42, 0x2f, 0xaa, 0x64, 0x9c, 0xd2, 0x32, 0xea, + 0xbd, 0x9c, 0x6f, 0xdd, 0x3f, 0x4b, 0x5f, 0x09, 0x50, 0xc9, 0xae, 0x7d, 0x39, 0xa7, 0x7f, 0x02, + 0x00, 0x00, 0xff, 0xff, 0x84, 0xea, 0xd9, 0x17, 0x7e, 0x03, 0x00, 0x00, } func (m *QueryDebugQueryResponse) Marshal() (dAtA []byte, err error) { @@ -233,25 +233,33 @@ func (m *QueryDebugQueryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x30 } - if m.ProviderAllocPoolBalance != 0 { - i = encodeVarintDebugQuery(dAtA, i, uint64(m.ProviderAllocPoolBalance)) + if len(m.ProviderAllocPoolBalance) > 0 { + i -= len(m.ProviderAllocPoolBalance) + copy(dAtA[i:], m.ProviderAllocPoolBalance) + i = encodeVarintDebugQuery(dAtA, i, uint64(len(m.ProviderAllocPoolBalance))) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x2a } - if m.ProviderDistPoolBalance != 0 { - i = encodeVarintDebugQuery(dAtA, i, uint64(m.ProviderDistPoolBalance)) + if len(m.ProviderDistPoolBalance) > 0 { + i -= len(m.ProviderDistPoolBalance) + copy(dAtA[i:], m.ProviderDistPoolBalance) + i = encodeVarintDebugQuery(dAtA, i, uint64(len(m.ProviderDistPoolBalance))) i-- - dAtA[i] = 0x20 + dAtA[i] = 0x22 } - if m.ValAllocPoolBalance != 0 { - i = encodeVarintDebugQuery(dAtA, i, uint64(m.ValAllocPoolBalance)) + if len(m.ValAllocPoolBalance) > 0 { + i -= len(m.ValAllocPoolBalance) + copy(dAtA[i:], m.ValAllocPoolBalance) + i = encodeVarintDebugQuery(dAtA, i, uint64(len(m.ValAllocPoolBalance))) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x1a } - if m.ValDistPoolBalance != 0 { - i = encodeVarintDebugQuery(dAtA, i, uint64(m.ValDistPoolBalance)) + if len(m.ValDistPoolBalance) > 0 { + i -= len(m.ValDistPoolBalance) + copy(dAtA[i:], m.ValDistPoolBalance) + i = encodeVarintDebugQuery(dAtA, i, uint64(len(m.ValDistPoolBalance))) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x12 } if m.BlockReward != 0 { i = encodeVarintDebugQuery(dAtA, i, uint64(m.BlockReward)) @@ -281,17 +289,21 @@ func (m *QueryDebugQueryResponse) Size() (n int) { if m.BlockReward != 0 { n += 1 + sovDebugQuery(uint64(m.BlockReward)) } - if m.ValDistPoolBalance != 0 { - n += 1 + sovDebugQuery(uint64(m.ValDistPoolBalance)) + l = len(m.ValDistPoolBalance) + if l > 0 { + n += 1 + l + sovDebugQuery(uint64(l)) } - if m.ValAllocPoolBalance != 0 { - n += 1 + sovDebugQuery(uint64(m.ValAllocPoolBalance)) + l = len(m.ValAllocPoolBalance) + if l > 0 { + n += 1 + l + sovDebugQuery(uint64(l)) } - if m.ProviderDistPoolBalance != 0 { - n += 1 + sovDebugQuery(uint64(m.ProviderDistPoolBalance)) + l = len(m.ProviderDistPoolBalance) + if l > 0 { + n += 1 + l + sovDebugQuery(uint64(l)) } - if m.ProviderAllocPoolBalance != 0 { - n += 1 + sovDebugQuery(uint64(m.ProviderAllocPoolBalance)) + l = len(m.ProviderAllocPoolBalance) + if l > 0 { + n += 1 + l + sovDebugQuery(uint64(l)) } if m.ProviderFullReward != 0 { n += 1 + sovDebugQuery(uint64(m.ProviderFullReward)) @@ -366,10 +378,10 @@ func (m *QueryDebugQueryResponse) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ValDistPoolBalance", wireType) } - m.ValDistPoolBalance = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDebugQuery @@ -379,16 +391,29 @@ func (m *QueryDebugQueryResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ValDistPoolBalance |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDebugQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDebugQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValDistPoolBalance = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 3: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ValAllocPoolBalance", wireType) } - m.ValAllocPoolBalance = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDebugQuery @@ -398,16 +423,29 @@ func (m *QueryDebugQueryResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ValAllocPoolBalance |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDebugQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDebugQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValAllocPoolBalance = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 4: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderDistPoolBalance", wireType) } - m.ProviderDistPoolBalance = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDebugQuery @@ -417,16 +455,29 @@ func (m *QueryDebugQueryResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ProviderDistPoolBalance |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDebugQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDebugQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderDistPoolBalance = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 5: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderAllocPoolBalance", wireType) } - m.ProviderAllocPoolBalance = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDebugQuery @@ -436,11 +487,24 @@ func (m *QueryDebugQueryResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ProviderAllocPoolBalance |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDebugQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDebugQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderAllocPoolBalance = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ProviderFullReward", wireType) diff --git a/x/pairing/types/expected_keepers.go b/x/pairing/types/expected_keepers.go index 6a68c454b1..258ca6302f 100644 --- a/x/pairing/types/expected_keepers.go +++ b/x/pairing/types/expected_keepers.go @@ -102,7 +102,7 @@ type DowntimeKeeper interface { } type DualstakingKeeper interface { - RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward math.Int, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward math.Int, totalRewards math.Int, err error) + RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, totalRewards sdk.Coin, err error) DelegateFull(ctx sdk.Context, delegator string, validator string, provider string, chainID string, amount sdk.Coin) error UnbondFull(ctx sdk.Context, delegator string, validator string, provider string, chainID string, amount sdk.Coin, unstake bool) error } diff --git a/x/rewards/genesis_test.go b/x/rewards/genesis_test.go index 23c3bcb4e8..f2015035c7 100644 --- a/x/rewards/genesis_test.go +++ b/x/rewards/genesis_test.go @@ -16,10 +16,12 @@ func TestGenesis(t *testing.T) { IprpcRewards: []types.IprpcReward{ { - Id: 0, + Id: 0, + SpecFunds: []types.Specfund{{Fund: []sdk.Coin{}}}, }, { - Id: 1, + Id: 1, + SpecFunds: []types.Specfund{{Fund: []sdk.Coin{}}}, }, }, IprpcRewardsCount: 2, diff --git a/x/rewards/keeper/grpc_query_block_reward.go b/x/rewards/keeper/grpc_query_block_reward.go index b00516edb9..3753686f41 100644 --- a/x/rewards/keeper/grpc_query_block_reward.go +++ b/x/rewards/keeper/grpc_query_block_reward.go @@ -23,7 +23,8 @@ func (k Keeper) BlockReward(goCtx context.Context, req *types.QueryBlockRewardRe blocksToNextTimerExpiry := k.BlocksToNextTimerExpiry(ctx) // get validator block pool balance - blockPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx)) + coins := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName) + blockPoolBalance := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)) if blocksToNextTimerExpiry == 0 { return nil, utils.LavaFormatWarning("blocksToNextTimerExpiry is zero", fmt.Errorf("critical: Attempt to divide by zero"), utils.LogAttr("blocksToNextTimerExpiry", blocksToNextTimerExpiry), diff --git a/x/rewards/keeper/grpc_query_pools.go b/x/rewards/keeper/grpc_query_pools.go index de14e08aa5..4e6d35d3d6 100644 --- a/x/rewards/keeper/grpc_query_pools.go +++ b/x/rewards/keeper/grpc_query_pools.go @@ -19,19 +19,23 @@ func (k Keeper) Pools(goCtx context.Context, req *types.QueryPoolsRequest) (*typ pools := []types.PoolInfo{ { Name: string(types.ValidatorsRewardsDistributionPoolName), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx))), + Balance: k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName), }, { Name: string(types.ValidatorsRewardsAllocationPoolName), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ValidatorsRewardsAllocationPoolName, k.stakingKeeper.BondDenom(ctx))), + Balance: k.TotalPoolTokens(ctx, types.ValidatorsRewardsAllocationPoolName), }, { Name: string(types.ProviderRewardsDistributionPool), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool, k.stakingKeeper.BondDenom(ctx))), + Balance: k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool), }, { Name: string(types.ProvidersRewardsAllocationPool), - Balance: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), k.TotalPoolTokens(ctx, types.ProvidersRewardsAllocationPool, k.stakingKeeper.BondDenom(ctx))), + Balance: k.TotalPoolTokens(ctx, types.ProvidersRewardsAllocationPool), + }, + { + Name: string(types.IprpcPoolName), + Balance: k.TotalPoolTokens(ctx, types.IprpcPoolName), }, } diff --git a/x/rewards/keeper/helpers_test.go b/x/rewards/keeper/helpers_test.go index 0b34692451..e2d009ab50 100644 --- a/x/rewards/keeper/helpers_test.go +++ b/x/rewards/keeper/helpers_test.go @@ -12,7 +12,6 @@ import ( planstypes "github.com/lavanet/lava/x/plans/types" rewardsTypes "github.com/lavanet/lava/x/rewards/types" spectypes "github.com/lavanet/lava/x/spec/types" - subscriptiontypes "github.com/lavanet/lava/x/subscription/types" "github.com/stretchr/testify/require" ) @@ -39,10 +38,11 @@ func newTester(t *testing.T, addValidator bool) *tester { } ts.plan = common.CreateMockPlan() - monthlyProvidersPool := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardsTypes.ProviderRewardsDistributionPool, ts.BondDenom()) - ts.plan.Price.Amount = monthlyProvidersPool.QuoRaw(5).AddRaw(5) - ts.plan.PlanPolicy.EpochCuLimit = monthlyProvidersPool.Uint64() * 5 - ts.plan.PlanPolicy.TotalCuLimit = monthlyProvidersPool.Uint64() * 5 + coins := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardsTypes.ProviderRewardsDistributionPool) + _, monthlyProvidersPool := coins.Find(ts.BondDenom()) + ts.plan.Price.Amount = monthlyProvidersPool.Amount.QuoRaw(5).AddRaw(5) + ts.plan.PlanPolicy.EpochCuLimit = monthlyProvidersPool.Amount.Uint64() * 5 + ts.plan.PlanPolicy.TotalCuLimit = monthlyProvidersPool.Amount.Uint64() * 5 ts.plan.PlanPolicy.MaxProvidersToPair = 5 ts.AddPlan(ts.plan.Index, ts.plan) ts.spec = ts.AddSpec("mock", common.CreateMockSpec()).Spec("mock") @@ -61,10 +61,15 @@ func (ts *tester) feeCollector() sdk.AccAddress { return testkeeper.GetModuleAddress(feeCollectorName) } +func (ts *tester) getPoolBalance(pool rewardsTypes.Pool, denom string) math.Int { + coins := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, pool) + return coins.AmountOf(denom) +} + // deductParticipationFees calculates the validators and community participation // fees and returns the providers reward after deducting them func (ts *tester) DeductParticipationFees(reward math.Int) (updatedReward math.Int, valParticipation math.Int, communityParticipation math.Int) { - valPerc, communityPerc, err := ts.Keepers.Rewards.CalculateContributionPercentages(ts.Ctx, reward, subscriptiontypes.ModuleName) + valPerc, communityPerc, err := ts.Keepers.Rewards.CalculateContributionPercentages(ts.Ctx, reward) require.Nil(ts.T, err) valParticipation = valPerc.MulInt(reward).TruncateInt() communityParticipation = communityPerc.MulInt(reward).TruncateInt() diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index d2bcfce160..0f521a69f4 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/binary" + "sort" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -104,3 +105,27 @@ func GetIprpcRewardIDBytes(id uint64) []byte { func GetIprpcRewardIDFromBytes(bz []byte) uint64 { return binary.BigEndian.Uint64(bz) } + +// PopIprpcReward gets the lowest id IprpcReward object and removes it +func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { + // Get all IprpcReward + allRewards := k.GetAllIprpcReward(ctx) + + // Check if there are any rewards + if len(allRewards) == 0 { + return types.IprpcReward{}, false + } + + // Sort rewards by index + sort.SliceStable(allRewards, func(i, j int) bool { + return allRewards[i].Id < allRewards[j].Id + }) + + // Get the first reward + firstReward := allRewards[0] + + // Remove the first reward + k.RemoveIprpcReward(ctx, firstReward.Id) + + return firstReward, true +} diff --git a/x/rewards/keeper/pool.go b/x/rewards/keeper/pool.go index 01b1ba8252..7d2cf221a8 100644 --- a/x/rewards/keeper/pool.go +++ b/x/rewards/keeper/pool.go @@ -8,9 +8,9 @@ import ( ) // TotalPoolTokens gets the total tokens supply from a pool -func (k Keeper) TotalPoolTokens(ctx sdk.Context, pool types.Pool, denom string) math.Int { +func (k Keeper) TotalPoolTokens(ctx sdk.Context, pool types.Pool) sdk.Coins { poolAddr := k.accountKeeper.GetModuleAddress(string(pool)) - return k.bankKeeper.GetBalance(ctx, poolAddr, denom).Amount + return k.bankKeeper.GetAllBalances(ctx, poolAddr) } // BurnPoolTokens removes coins from a pool module account diff --git a/x/rewards/keeper/pool_test.go b/x/rewards/keeper/pool_test.go index f3656aa49e..f1fccf4c2c 100644 --- a/x/rewards/keeper/pool_test.go +++ b/x/rewards/keeper/pool_test.go @@ -61,9 +61,9 @@ func TestRewardsModuleSetup(t *testing.T) { for _, pool := range res.Pools { switch pool.Name { case string(types.ValidatorsRewardsAllocationPoolName): - require.Equal(t, allocationPoolBalance*(lifetime-1)/lifetime, pool.Balance.Amount.Int64()) + require.Equal(t, allocationPoolBalance*(lifetime-1)/lifetime, pool.Balance.AmountOf(ts.BondDenom()).Int64()) case string(types.ValidatorsRewardsDistributionPoolName): - require.Equal(t, (allocationPoolBalance/lifetime)-blockReward, pool.Balance.Amount.Int64()) + require.Equal(t, (allocationPoolBalance/lifetime)-blockReward, pool.Balance.AmountOf(ts.BondDenom()).Int64()) } } @@ -78,8 +78,7 @@ func TestRewardsModuleSetup(t *testing.T) { func TestBurnRateParam(t *testing.T) { ts := newTester(t, true) lifetime := int64(types.RewardsAllocationPoolsLifetime) - allocPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()).Int64() - + allocPoolBalance := ts.getPoolBalance(types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()).Int64() // advance a month to trigger monthly pool refill callback // to see why these 3 are called, see general note 2 resp, err := ts.QueryRewardsPools() @@ -90,7 +89,7 @@ func TestBurnRateParam(t *testing.T) { // default burn rate = 1, distribution pool's old balance should be wiped // current balance should be exactly the expected monthly quota minus block reward expectedMonthlyQuota := allocPoolBalance / (lifetime - 1) - distPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() + distPoolBalance := ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() require.Equal(t, expectedMonthlyQuota, distPoolBalance) // change the burn rate param to be zero @@ -105,12 +104,12 @@ func TestBurnRateParam(t *testing.T) { resp, err = ts.QueryRewardsPools() require.NoError(t, err) ts.AdvanceBlock(time.Duration(resp.TimeToRefill) * time.Second) - prevDistPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() + prevDistPoolBalance := ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() testkeeper.EndBlock(ts.Ctx, ts.Keepers) // burn rate = 0, distribution pool's old balance should not be wiped // current balance should be previous balance (minus block reward) plus new quota - distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() + distPoolBalance = ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()).Int64() require.Equal(t, prevDistPoolBalance+expectedMonthlyQuota, distPoolBalance) } @@ -125,11 +124,11 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { // calc expectedMonthlyQuota. Check that it was subtracted from the allocation pool and added // to the distribution pool (its balance should be the monthly quota minus the fee collector's balance) expectedMonthlyQuota := allocationPoolBalance / lifetime - currentAllocPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) + currentAllocPoolBalance := ts.getPoolBalance(types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) require.Equal(t, expectedMonthlyQuota, allocationPoolBalance-currentAllocPoolBalance.Int64()) feeCollectorBalance := ts.GetBalance(ts.feeCollector()) - currentDistPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) + currentDistPoolBalance := ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) require.Equal(t, expectedMonthlyQuota, feeCollectorBalance+currentDistPoolBalance.Int64()) // check the monthly quota is as expected with advancement of months @@ -141,7 +140,7 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { monthsLeft := ts.Keepers.Rewards.AllocationPoolMonthsLeft(ts.Ctx) prevAllocPoolBalance := currentAllocPoolBalance - currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) + currentAllocPoolBalance = ts.getPoolBalance(types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) var monthlyQuota int64 if monthsLeft != 0 { @@ -160,7 +159,7 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { ts.AdvanceMonths(1) ts.AdvanceBlock() testkeeper.EndBlock(ts.Ctx, ts.Keepers) - currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) + currentAllocPoolBalance = ts.getPoolBalance(types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) require.True(t, currentAllocPoolBalance.IsZero()) // advance another month to distribute the last quota to the fee collector @@ -174,7 +173,7 @@ func TestAllocationPoolMonthlyQuota(t *testing.T) { ts.AdvanceBlock() testkeeper.EndBlock(ts.Ctx, ts.Keepers) - currentAllocPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) + currentAllocPoolBalance = ts.getPoolBalance(types.ValidatorsRewardsAllocationPoolName, ts.BondDenom()) require.True(t, currentAllocPoolBalance.IsZero()) currentFeeCollectorBalance := ts.GetBalance(ts.feeCollector()) @@ -212,7 +211,7 @@ func TestValidatorBlockRewards(t *testing.T) { res, err := ts.QueryRewardsBlockReward() require.NoError(t, err) blockReward := res.Reward.Amount - distPoolBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) + distPoolBalance := ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) blocksToNextExpiry := ts.Keepers.Rewards.BlocksToNextTimerExpiry(ts.Ctx) bondedTargetFactor := sdk.OneDec().MulInt(blockReward).MulInt64(blocksToNextExpiry).QuoInt(distPoolBalance).TruncateInt() require.True(t, bondedTargetFactor.Equal(expectedBondedTargetFactor)) @@ -228,7 +227,7 @@ func TestValidatorBlockRewards(t *testing.T) { blockReward = res.Reward.Amount // transfer half of the total distribution pool balance to the allocation pool - distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) + distPoolBalance = ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) err = ts.Keepers.BankKeeper.SendCoinsFromModuleToModule( ts.Ctx, string(types.ValidatorsRewardsDistributionPoolName), @@ -263,7 +262,7 @@ func TestValidatorBlockRewards(t *testing.T) { require.NoError(t, err) blockReward = res.Reward.Amount bondedTargetFactor = ts.Keepers.Rewards.BondedTargetFactor(ts.Ctx).TruncateInt() - distPoolBalance = ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) + distPoolBalance = ts.getPoolBalance(types.ValidatorsRewardsDistributionPoolName, ts.BondDenom()) blocksToNextExpiry = bondedTargetFactor.Mul(distPoolBalance).Quo(blockReward).Int64() require.Equal(t, refBlocksToExpiry, blocksToNextExpiry) } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index f719e95469..c9ae3e6588 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -2,6 +2,8 @@ package keeper import ( "fmt" + "sort" + "strings" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -34,7 +36,8 @@ func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adju // Distribute bonus rewards to providers across all chains based on performance func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { details := map[string]string{} - total := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool, k.stakingKeeper.BondDenom(ctx)) + coins := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool) + total := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)) totalRewarded := sdk.ZeroInt() // specs emissions from the total reward pool base on stake specs := k.specEmissionParts(ctx) @@ -43,6 +46,9 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { k.removeAllBasePay(ctx) utils.LogLavaEvent(ctx, k.Logger(ctx), types.ProvidersBonusRewardsEventName, details, "provider bonus rewards distributed successfully") }() + + // Get serviced CU for each provider + spec + specCuMap := map[string]types.SpecCuType{} // spec -> specCu for _, spec := range specs { // all providers basepays and the total basepay of the spec basepays, totalbasepay := k.specProvidersBasePay(ctx, spec.ChainID) @@ -54,6 +60,23 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { specTotalPayout := k.specTotalPayout(ctx, total, sdk.NewDecFromInt(totalbasepay), spec) // distribute the rewards to all providers for _, basepay := range basepays { + // count iprpc cu + specCu, ok := specCuMap[spec.ChainID] + if !ok { + specCuMap[spec.ChainID] = types.SpecCuType{ + ProvidersCu: map[string]uint64{basepay.Provider: basepay.IprpcCu}, + TotalCu: basepay.IprpcCu, + } + } else { + _, ok := specCu.ProvidersCu[basepay.Provider] + if !ok { + specCu.ProvidersCu[basepay.Provider] = basepay.IprpcCu + } else { + specCu.ProvidersCu[basepay.Provider] += basepay.IprpcCu + } + specCu.TotalCu += basepay.IprpcCu + } + // calculate the providers bonus base on adjusted base pay reward := specTotalPayout.Mul(basepay.TotalAdjusted).QuoInt(totalbasepay).TruncateInt() totalRewarded = totalRewarded.Add(reward) @@ -69,7 +92,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { if err != nil { continue } - _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, basepay.ChainID, reward, string(types.ProviderRewardsDistributionPool), false, false, false) + _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, basepay.ChainID, sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), reward), string(types.ProviderRewardsDistributionPool), false, false, false) if err != nil { utils.LavaFormatError("failed to send bonus rewards to provider", err, utils.LogAttr("provider", basepay.Provider)) } @@ -77,6 +100,72 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { details[providerAddr.String()+" "+spec.ChainID] = reward.String() } } + + // Get current month IprpcReward and use it to distribute rewards + iprpcReward, found := k.PopIprpcReward(ctx) + if !found { + utils.LavaFormatError("current month iprpc reward not found", fmt.Errorf("did not reward providers IPRPC bonus")) + return + } + for _, specFund := range iprpcReward.SpecFunds { + // collect details + details := map[string]string{"spec": specFund.Spec} + rewardsStr := []string{} + for _, reward := range specFund.Fund { + rewardsStr = append(rewardsStr, reward.String()) + } + details["rewards"] = strings.Join(rewardsStr, ",") + + // verify specCuMap holds an entry for the relevant spec + specCu, ok := specCuMap[specFund.Spec] + if !ok { + utils.LavaFormatError("did not distribute iprpc rewards to providers in spec", fmt.Errorf("specCU not found"), + utils.LogAttr("spec", details["spec"]), + utils.LogAttr("rewards", details["rewards"]), + ) + continue + } + + // collect providers details + providers := []string{} + for provider := range specCu.ProvidersCu { + providers = append(providers, provider) + } + sort.Strings(providers) + details["providers"] = strings.Join(providers, ",") + + // distribute IPRPC reward for spec + usedReward := sdk.NewCoins() + for _, provider := range providers { + providerAddr, err := sdk.AccAddressFromBech32(provider) + if err != nil { + continue + } + // calculate provider IPRPC reward + providerIprpcRewardPerc := math.LegacyNewDec(int64(specCu.ProvidersCu[provider])).QuoInt64(int64(specCu.TotalCu)) + + for _, reward := range specFund.Fund { + // reward the provider + providerIprpcRewardAmount := providerIprpcRewardPerc.MulInt(reward.Amount).TruncateInt() + providerIprpcReward := sdk.NewCoin(reward.Denom, providerIprpcRewardAmount) + _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, specFund.Spec, providerIprpcReward, string(types.IprpcPoolName), false, false, false) + if err != nil { + utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", provider)) + } + + usedReward = usedReward.Add(providerIprpcReward) + } + } + + // handle leftovers + usedReward = specFund.Fund.Sub(usedReward...) + err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) + if err != nil { + utils.LavaFormatError("could not send iprpc leftover to community pool", err) + } + + utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, details, "IPRPC monthly rewards distributed successfully") + } } // specTotalPayout calculates the total bonus for a specific spec @@ -145,28 +234,28 @@ func (k Keeper) specProvidersBasePay(ctx sdk.Context, chainID string) ([]types.B // ContributeToValidatorsAndCommunityPool transfers some of the providers' rewards to the validators and community pool // the function return the updated reward after the participation deduction -func (k Keeper) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward math.Int, senderModule string) (updatedReward math.Int, err error) { +func (k Keeper) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward sdk.Coin, senderModule string) (updatedReward sdk.Coin, err error) { // calculate validators and community participation fractions - validatorsParticipation, communityParticipation, err := k.CalculateContributionPercentages(ctx, reward, senderModule) + validatorsParticipation, communityParticipation, err := k.CalculateContributionPercentages(ctx, reward.Amount) if err != nil { return reward, err } if communityParticipation.Equal(sdk.OneDec()) { - err := k.FundCommunityPoolFromModule(ctx, reward, senderModule) + err := k.FundCommunityPoolFromModule(ctx, sdk.NewCoins(reward), senderModule) if err != nil { return reward, utils.LavaFormatError("failed funding the community pool with whole reward", err, utils.Attribute{Key: "reward", Value: reward.String()}, utils.Attribute{Key: "community_participation", Value: communityParticipation.String()}, ) } - return sdk.ZeroInt(), nil + return sdk.NewCoin(reward.Denom, math.ZeroInt()), nil } // send validators participation - validatorsParticipationReward := validatorsParticipation.MulInt(reward).TruncateInt() + validatorsParticipationReward := validatorsParticipation.MulInt(reward.Amount).TruncateInt() if !validatorsParticipationReward.IsZero() { - coins := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), validatorsParticipationReward)) + coins := sdk.NewCoins(sdk.NewCoin(reward.Denom, validatorsParticipationReward)) pool := types.ValidatorsRewardsDistributionPoolName if k.isEndOfMonth(ctx) { pool = types.ValidatorsRewardsAllocationPoolName @@ -182,9 +271,9 @@ func (k Keeper) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward m } // send community participation - communityParticipationReward := communityParticipation.MulInt(reward).TruncateInt() + communityParticipationReward := communityParticipation.MulInt(reward.Amount).TruncateInt() if !communityParticipationReward.IsZero() { - err = k.FundCommunityPoolFromModule(ctx, communityParticipationReward, senderModule) + err = k.FundCommunityPoolFromModule(ctx, sdk.NewCoins(sdk.NewCoin(reward.Denom, communityParticipationReward)), senderModule) if err != nil { return reward, utils.LavaFormatError("sending community participation failed", err, utils.Attribute{Key: "community_participation_reward", Value: communityParticipationReward.String() + k.stakingKeeper.BondDenom(ctx)}, @@ -195,13 +284,13 @@ func (k Keeper) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward m } // update reward amount - reward = reward.Sub(communityParticipationReward).Sub(validatorsParticipationReward) + reward = reward.SubAmount(communityParticipationReward).SubAmount(validatorsParticipationReward) return reward, nil } // CalculateContributionPercentages calculates the providers' rewards participation to the validators and community pool -func (k Keeper) CalculateContributionPercentages(ctx sdk.Context, reward math.Int, senderModule string) (validatorsParticipation math.LegacyDec, communityParticipation math.LegacyDec, err error) { +func (k Keeper) CalculateContributionPercentages(ctx sdk.Context, reward math.Int) (validatorsParticipation math.LegacyDec, communityParticipation math.LegacyDec, err error) { communityTax := k.distributionKeeper.GetParams(ctx).CommunityTax if communityTax.Equal(sdk.OneDec()) { return sdk.ZeroDec(), sdk.OneDec(), nil @@ -240,14 +329,13 @@ func (k Keeper) CalculateContributionPercentages(ctx sdk.Context, reward math.In return validatorsParticipation, communityParticipation, nil } -func (k Keeper) FundCommunityPoolFromModule(ctx sdk.Context, amount math.Int, senderModule string) error { - coins := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), amount)) - if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, senderModule, distributiontypes.ModuleName, coins); err != nil { +func (k Keeper) FundCommunityPoolFromModule(ctx sdk.Context, amount sdk.Coins, senderModule string) error { + if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, senderModule, distributiontypes.ModuleName, amount); err != nil { return err } feePool := k.distributionKeeper.GetFeePool(ctx) - feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(coins...)...) + feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...) k.distributionKeeper.SetFeePool(ctx, feePool) return nil diff --git a/x/rewards/keeper/providers_test.go b/x/rewards/keeper/providers_test.go index 5e889e227d..09f6d3bb2a 100644 --- a/x/rewards/keeper/providers_test.go +++ b/x/rewards/keeper/providers_test.go @@ -124,7 +124,7 @@ func TestSpecAllocationProvidersRewards(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) + distBalance := ts.getPoolBalance(types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") @@ -172,7 +172,7 @@ func TestProvidersDiminishingRewards(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) + distBalance := ts.getPoolBalance(types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") @@ -280,7 +280,7 @@ func Test2SpecsZeroShares(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) + distBalance := ts.getPoolBalance(types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") @@ -414,7 +414,7 @@ func TestBonusRewards3Providers(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) + distBalance := ts.getPoolBalance(types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() res1, err := ts.QueryDualstakingDelegatorRewards(providerAcc1.Addr.String(), "", "") @@ -596,7 +596,7 @@ func TestBonusRewardsEquall5Providers(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) + distBalance := ts.getPoolBalance(types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() for _, providerAcc := range providerAccs { @@ -663,7 +663,7 @@ func TestBonusRewards5Providers(t *testing.T) { // now the provider should get all of the provider allocation ts.AdvanceMonths(1) - distBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, types.ProviderRewardsDistributionPool, ts.BondDenom()) + distBalance := ts.getPoolBalance(types.ProviderRewardsDistributionPool, ts.BondDenom()) ts.AdvanceEpoch() // distribution pool divided between all providers (5) equally (they served the same amount of CU in total) diff --git a/x/rewards/keeper/rewards.go b/x/rewards/keeper/rewards.go index 4d696b42e3..5baa6087b0 100644 --- a/x/rewards/keeper/rewards.go +++ b/x/rewards/keeper/rewards.go @@ -20,8 +20,8 @@ func (k Keeper) DistributeBlockReward(ctx sdk.Context) { blocksToNextTimerExpiry := k.BlocksToNextTimerExpiry(ctx) // get validator distribution pool balance - distributionPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx)) - + coins := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName) + distributionPoolBalance := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)) if blocksToNextTimerExpiry == 0 { utils.LavaFormatWarning("blocksToNextTimerExpiry is zero", fmt.Errorf("critical: Attempt to divide by zero"), utils.LogAttr("blocksToNextTimerExpiry", blocksToNextTimerExpiry), @@ -84,8 +84,10 @@ func (k Keeper) RefillRewardsPools(ctx sdk.Context, _ []byte, data []byte) { nextMonth := utils.NextMonth(ctx.BlockTime()).UTC() k.refillRewardsPoolTS.AddTimerByBlockTime(ctx, uint64(nextMonth.Unix()), []byte(types.RefillRewardsPoolTimerName), monthsLeftBytes) - valDistPoolBalance := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName, k.stakingKeeper.BondDenom(ctx)).Int64() - providerDistPoolBalance := k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool, k.stakingKeeper.BondDenom(ctx)).Int64() + coins := k.TotalPoolTokens(ctx, types.ValidatorsRewardsDistributionPoolName) + valDistPoolBalance := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)).Int64() + coins = k.TotalPoolTokens(ctx, types.ProviderRewardsDistributionPool) + providerDistPoolBalance := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)).Int64() nextRefillBlock := k.blocksToNextTimerExpiry(ctx, nextMonth.Unix()-ctx.BlockTime().UTC().Unix()) + ctx.BlockHeight() details := map[string]string{ "allocation_pool_remaining_lifetime": strconv.FormatUint(monthsLeft, 10), @@ -101,7 +103,9 @@ func (k Keeper) RefillRewardsPools(ctx sdk.Context, _ []byte, data []byte) { func (k Keeper) refillDistributionPool(ctx sdk.Context, monthsLeft uint64, allocationPool types.Pool, distributionPool types.Pool, burnRate sdkmath.LegacyDec) { // burn remaining tokens in the distribution pool - tokensToBurn := burnRate.MulInt(k.TotalPoolTokens(ctx, distributionPool, k.stakingKeeper.BondDenom(ctx))).TruncateInt() + coins := k.TotalPoolTokens(ctx, distributionPool) + distPoolBalance := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)) + tokensToBurn := burnRate.MulInt(distPoolBalance).TruncateInt() err := k.BurnPoolTokens(ctx, distributionPool, tokensToBurn, k.stakingKeeper.BondDenom(ctx)) if err != nil { utils.LavaFormatError("critical - could not burn distribution pool tokens", err, @@ -111,7 +115,8 @@ func (k Keeper) refillDistributionPool(ctx sdk.Context, monthsLeft uint64, alloc } // transfer the new monthly quota (if allocation pool is expired, rewards=0) - allocPoolBalance := k.TotalPoolTokens(ctx, allocationPool, k.stakingKeeper.BondDenom(ctx)) + coins = k.TotalPoolTokens(ctx, allocationPool) + allocPoolBalance := coins.AmountOf(k.stakingKeeper.BondDenom(ctx)) if monthsLeft != 0 && !allocPoolBalance.IsZero() { monthlyQuota := sdk.Coin{Denom: k.stakingKeeper.BondDenom(ctx), Amount: allocPoolBalance.QuoRaw(int64(monthsLeft))} diff --git a/x/rewards/types/expected_keepers.go b/x/rewards/types/expected_keepers.go index 3a5a265d1e..c691f8f5ab 100644 --- a/x/rewards/types/expected_keepers.go +++ b/x/rewards/types/expected_keepers.go @@ -22,6 +22,7 @@ type BankKeeper interface { BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin SendCoinsFromModuleToModule(ctx sdk.Context, senderPool, recipientPool string, amt sdk.Coins) error + GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins // Methods imported from bank should be defined here } @@ -49,7 +50,7 @@ type StakingKeeper interface { } type DualStakingKeeper interface { - RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward math.Int, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward math.Int, totalRewards math.Int, err error) + RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, totalRewards sdk.Coin, err error) // Methods imported from bank should be defined here } diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index d3ec2e073f..65f22e3fa4 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -22,7 +22,7 @@ func DefaultGenesis() *GenesisState { BasePays: []BasePayGenesis{}, IprpcSubscriptions: []string{}, MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, sdk.ZeroInt()), - IprpcRewards: []IprpcReward{{SpecFunds: []Specfund{}}}, + IprpcRewards: []IprpcReward{}, } } diff --git a/x/rewards/types/iprpc.pb.go b/x/rewards/types/iprpc.pb.go index eeef70a024..123a2982d6 100644 --- a/x/rewards/types/iprpc.pb.go +++ b/x/rewards/types/iprpc.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -78,8 +79,8 @@ func (m *IprpcReward) GetSpecFunds() []Specfund { } type Specfund struct { - Spec string `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` - Fund []types.Coin `protobuf:"bytes,2,rep,name=fund,proto3" json:"fund"` + Spec string `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + Fund github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=fund,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"fund"` } func (m *Specfund) Reset() { *m = Specfund{} } @@ -122,7 +123,7 @@ func (m *Specfund) GetSpec() string { return "" } -func (m *Specfund) GetFund() []types.Coin { +func (m *Specfund) GetFund() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Fund } @@ -137,25 +138,26 @@ func init() { func init() { proto.RegisterFile("lavanet/lava/rewards/iprpc.proto", fileDescriptor_1293618a311573f7) } var fileDescriptor_1293618a311573f7 = []byte{ - // 277 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4a, 0xc3, 0x40, - 0x10, 0x86, 0x93, 0x1a, 0xc4, 0x6e, 0xc1, 0xc3, 0xd2, 0x43, 0xed, 0x61, 0x0d, 0xbd, 0xd8, 0xd3, - 0x2c, 0xb5, 0x4f, 0x60, 0x0b, 0x82, 0xd7, 0xf4, 0xe6, 0x45, 0x92, 0xcd, 0x1a, 0x17, 0x6c, 0x76, - 0xc9, 0x6e, 0xab, 0xbe, 0x85, 0x8f, 0xd5, 0x63, 0x8f, 0x9e, 0x44, 0x92, 0x17, 0x91, 0xd9, 0xac, - 0x82, 0xe0, 0x69, 0x06, 0xfe, 0x6f, 0xfe, 0xf9, 0xf9, 0x49, 0xfa, 0x9c, 0xef, 0xf3, 0x5a, 0x3a, - 0x8e, 0x93, 0x37, 0xf2, 0x25, 0x6f, 0x4a, 0xcb, 0x95, 0x69, 0x8c, 0x00, 0xd3, 0x68, 0xa7, 0xe9, - 0x38, 0x10, 0x80, 0x13, 0x02, 0x31, 0x1d, 0x57, 0xba, 0xd2, 0x1e, 0xe0, 0xb8, 0xf5, 0xec, 0x94, - 0x09, 0x6d, 0xb7, 0xda, 0xf2, 0x22, 0xb7, 0x92, 0xef, 0x17, 0x85, 0x74, 0xf9, 0x82, 0x0b, 0xad, - 0xea, 0x5e, 0x9f, 0x15, 0x64, 0x74, 0x87, 0xd6, 0x99, 0x77, 0xa1, 0xe7, 0x64, 0xa0, 0xca, 0x49, - 0x9c, 0xc6, 0xf3, 0x24, 0x1b, 0xa8, 0x92, 0xae, 0x09, 0xb1, 0x46, 0x8a, 0x87, 0xc7, 0x5d, 0x5d, - 0xda, 0xc9, 0x20, 0x3d, 0x99, 0x8f, 0xae, 0x19, 0xfc, 0xf7, 0x1f, 0x36, 0x46, 0x0a, 0xc4, 0x56, - 0xc9, 0xe1, 0xf3, 0x32, 0xca, 0x86, 0x78, 0x77, 0x8b, 0x67, 0xb3, 0x0d, 0x39, 0xfb, 0x11, 0x29, - 0x25, 0x09, 0x0a, 0xfe, 0xc5, 0x30, 0xf3, 0x3b, 0x5d, 0x92, 0x04, 0xb5, 0x60, 0x7f, 0x01, 0x7d, - 0x64, 0xc0, 0xc8, 0x10, 0x22, 0xc3, 0x5a, 0xab, 0x3a, 0x38, 0x7b, 0x78, 0x75, 0x73, 0x68, 0x59, - 0x7c, 0x6c, 0x59, 0xfc, 0xd5, 0xb2, 0xf8, 0xbd, 0x63, 0xd1, 0xb1, 0x63, 0xd1, 0x47, 0xc7, 0xa2, - 0xfb, 0xab, 0x4a, 0xb9, 0xa7, 0x5d, 0x01, 0x42, 0x6f, 0xf9, 0x9f, 0x2e, 0x5f, 0x7f, 0xdb, 0x74, - 0x6f, 0x46, 0xda, 0xe2, 0xd4, 0x57, 0xb0, 0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x08, 0xfc, 0xb5, - 0xc2, 0x72, 0x01, 0x00, 0x00, + // 301 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4e, 0xf3, 0x30, + 0x14, 0x85, 0x93, 0xfc, 0xd1, 0x2f, 0xea, 0x4a, 0x0c, 0x56, 0x87, 0xd2, 0xc1, 0x8d, 0xba, 0x90, + 0x05, 0x9b, 0xc2, 0x13, 0x90, 0x4a, 0x48, 0xac, 0x61, 0x63, 0xa9, 0x12, 0xc7, 0x04, 0x0b, 0x1a, + 0x5b, 0x71, 0x5a, 0x60, 0xe2, 0x15, 0x78, 0x0e, 0x9e, 0xa4, 0x63, 0x47, 0x26, 0x40, 0xc9, 0x8b, + 0xa0, 0xeb, 0x18, 0x04, 0x12, 0xd3, 0xb5, 0x74, 0xce, 0xfd, 0xee, 0xf1, 0x41, 0xd1, 0x5d, 0xb6, + 0xc9, 0x2a, 0xd1, 0x30, 0x98, 0xac, 0x16, 0xf7, 0x59, 0x5d, 0x18, 0x26, 0x75, 0xad, 0x39, 0xd5, + 0xb5, 0x6a, 0x14, 0x1e, 0x39, 0x07, 0x85, 0x49, 0x9d, 0x63, 0x32, 0x2a, 0x55, 0xa9, 0xac, 0x81, + 0xc1, 0xab, 0xf7, 0x4e, 0x08, 0x57, 0x66, 0xa5, 0x0c, 0xcb, 0x33, 0x23, 0xd8, 0x66, 0x9e, 0x8b, + 0x26, 0x9b, 0x33, 0xae, 0x64, 0xd5, 0xeb, 0xb3, 0x1c, 0x0d, 0x2f, 0x00, 0x9d, 0x5a, 0x0a, 0xde, + 0x47, 0x81, 0x2c, 0xc6, 0x7e, 0xe4, 0xc7, 0x61, 0x1a, 0xc8, 0x02, 0x2f, 0x10, 0x32, 0x5a, 0xf0, + 0xe5, 0xf5, 0xba, 0x2a, 0xcc, 0x38, 0x88, 0xfe, 0xc5, 0xc3, 0x13, 0x42, 0xff, 0xba, 0x4f, 0x2f, + 0xb5, 0xe0, 0x60, 0x4b, 0xc2, 0xed, 0xdb, 0xd4, 0x4b, 0x07, 0xb0, 0x77, 0x0e, 0x6b, 0xb3, 0x27, + 0xb4, 0xf7, 0x25, 0x62, 0x8c, 0x42, 0x10, 0xec, 0x89, 0x41, 0x6a, 0xdf, 0x78, 0x89, 0x42, 0xd0, + 0x1c, 0xfe, 0x80, 0xf6, 0x91, 0x29, 0x44, 0xa6, 0x2e, 0x32, 0x5d, 0x28, 0x59, 0x25, 0xc7, 0x40, + 0x7e, 0x79, 0x9f, 0xc6, 0xa5, 0x6c, 0x6e, 0xd6, 0x39, 0xe5, 0x6a, 0xc5, 0xdc, 0xff, 0xfa, 0x71, + 0x64, 0x8a, 0x5b, 0xd6, 0x3c, 0x6a, 0x61, 0xec, 0x82, 0x49, 0x2d, 0x38, 0x39, 0xdb, 0xb6, 0xc4, + 0xdf, 0xb5, 0xc4, 0xff, 0x68, 0x89, 0xff, 0xdc, 0x11, 0x6f, 0xd7, 0x11, 0xef, 0xb5, 0x23, 0xde, + 0xd5, 0xe1, 0x0f, 0xd2, 0xaf, 0xde, 0x1f, 0xbe, 0x9b, 0xb7, 0xb8, 0xfc, 0xbf, 0xad, 0xeb, 0xf4, + 0x33, 0x00, 0x00, 0xff, 0xff, 0x19, 0x8c, 0x21, 0xa2, 0x9e, 0x01, 0x00, 0x00, } func (m *IprpcReward) Marshal() (dAtA []byte, err error) { diff --git a/x/rewards/types/keys.go b/x/rewards/types/keys.go index 4e984f80b6..5c61258d7c 100644 --- a/x/rewards/types/keys.go +++ b/x/rewards/types/keys.go @@ -29,7 +29,7 @@ const ( IprpcRewardPrefix = "iprpc-reward" // prefix for IPRPC rewards count - IprpcRewardsCountPrefix = "iprpc-rewards-count" + IprpcRewardsCountPrefix = "count-iprpc-rewards" ) func KeyPrefix(p string) []byte { diff --git a/x/rewards/types/query.pb.go b/x/rewards/types/query.pb.go index d51e38f015..76394786fd 100644 --- a/x/rewards/types/query.pb.go +++ b/x/rewards/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" @@ -152,8 +153,8 @@ func (m *QueryPoolsRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryPoolsRequest proto.InternalMessageInfo type PoolInfo struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Balance types.Coin `protobuf:"bytes,2,opt,name=balance,proto3" json:"balance"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Balance github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=balance,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"balance"` } func (m *PoolInfo) Reset() { *m = PoolInfo{} } @@ -196,11 +197,11 @@ func (m *PoolInfo) GetName() string { return "" } -func (m *PoolInfo) GetBalance() types.Coin { +func (m *PoolInfo) GetBalance() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Balance } - return types.Coin{} + return nil } // QueryPoolsResponse is response type for the Query/Pools RPC method. @@ -460,50 +461,52 @@ func init() { func init() { proto.RegisterFile("lavanet/lava/rewards/query.proto", fileDescriptor_15bce9a904340007) } var fileDescriptor_15bce9a904340007 = []byte{ - // 688 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4f, 0x4f, 0xd4, 0x40, - 0x14, 0xdf, 0xb2, 0xcb, 0x02, 0x83, 0x9a, 0x38, 0x90, 0x50, 0x0a, 0xd6, 0xb5, 0x62, 0x58, 0x49, - 0x68, 0x05, 0x0f, 0x46, 0x8d, 0x07, 0xc1, 0x0b, 0x89, 0x26, 0x52, 0xbc, 0xe8, 0xa5, 0x99, 0x96, - 0xd9, 0xdd, 0xc6, 0xb6, 0xaf, 0x74, 0x66, 0x41, 0x4e, 0x26, 0x7a, 0xf2, 0x66, 0xe2, 0xc5, 0xab, - 0xdf, 0x86, 0x8b, 0x09, 0x89, 0x17, 0x4f, 0xc6, 0x80, 0x9f, 0xc0, 0x4f, 0x60, 0xfa, 0x3a, 0xbb, - 0x2e, 0xa1, 0x2c, 0x7b, 0x6a, 0x3b, 0xf3, 0x7b, 0xbf, 0x3f, 0x33, 0xef, 0x95, 0x34, 0x22, 0xb6, - 0xcf, 0x12, 0x2e, 0x9d, 0xfc, 0xe9, 0x64, 0xfc, 0x80, 0x65, 0xbb, 0xc2, 0xd9, 0xeb, 0xf2, 0xec, - 0xd0, 0x4e, 0x33, 0x90, 0x40, 0x67, 0x15, 0xc2, 0xce, 0x9f, 0xb6, 0x42, 0x18, 0xb3, 0x6d, 0x68, - 0x03, 0x02, 0x9c, 0xfc, 0xad, 0xc0, 0x1a, 0x8b, 0x6d, 0x80, 0x76, 0xc4, 0x1d, 0x96, 0x86, 0x0e, - 0x4b, 0x12, 0x90, 0x4c, 0x86, 0x90, 0x08, 0xb5, 0xbb, 0x12, 0x80, 0x88, 0x41, 0x38, 0x3e, 0x13, - 0xbc, 0x90, 0x70, 0xf6, 0xd7, 0x7c, 0x2e, 0xd9, 0x9a, 0x93, 0xb2, 0x76, 0x98, 0x20, 0x58, 0x61, - 0x6f, 0x95, 0xfa, 0x4a, 0x59, 0xc6, 0xe2, 0x1e, 0x9d, 0x39, 0x48, 0xd7, 0x23, 0x0a, 0x20, 0x54, - 0x14, 0xd6, 0x2c, 0xa1, 0xdb, 0xb9, 0xc8, 0x4b, 0x2c, 0x72, 0xf9, 0x5e, 0x97, 0x0b, 0x69, 0x6d, - 0x93, 0x99, 0x33, 0xab, 0x22, 0x85, 0x44, 0x70, 0xfa, 0x88, 0xd4, 0x0b, 0x72, 0x5d, 0x6b, 0x68, - 0xcd, 0xe9, 0xf5, 0x45, 0xbb, 0x2c, 0xb6, 0x5d, 0x54, 0x6d, 0xd4, 0x8e, 0x7e, 0xdd, 0xac, 0xb8, - 0xaa, 0xc2, 0x9a, 0x21, 0xd7, 0x0b, 0x4a, 0x80, 0xa8, 0xaf, 0xf3, 0x9a, 0x4c, 0xe6, 0xdf, 0x5b, - 0x49, 0x0b, 0x28, 0x25, 0xb5, 0x84, 0xc5, 0x1c, 0xa9, 0xa7, 0x5c, 0x7c, 0xa7, 0x0f, 0xc9, 0x84, - 0xcf, 0x22, 0x96, 0x04, 0x5c, 0x1f, 0x43, 0xc5, 0x79, 0xbb, 0xc8, 0x63, 0xe7, 0x79, 0x6c, 0x95, - 0xc7, 0xde, 0x84, 0x30, 0x51, 0x72, 0x3d, 0xbc, 0xf5, 0x57, 0xeb, 0x25, 0x2b, 0x04, 0xfb, 0x11, - 0xc6, 0xd3, 0x7c, 0x41, 0xd7, 0x1a, 0xd5, 0xe6, 0xf4, 0xba, 0x79, 0x41, 0x02, 0x65, 0x4a, 0x91, - 0x16, 0x25, 0x74, 0x89, 0x5c, 0x93, 0x61, 0xcc, 0x3d, 0x09, 0x5e, 0xc6, 0x5b, 0x61, 0x14, 0xa1, - 0xa9, 0xaa, 0x7b, 0x25, 0x5f, 0x7d, 0x05, 0x2e, 0xae, 0xd1, 0xc7, 0xc4, 0xe0, 0x42, 0x86, 0x31, - 0x93, 0x7c, 0xd7, 0xf3, 0x23, 0x08, 0xde, 0x8a, 0x81, 0x8a, 0x2a, 0x56, 0xcc, 0xf5, 0x11, 0x1b, - 0x08, 0xe8, 0x17, 0x3f, 0x21, 0x0b, 0x2c, 0x8a, 0x20, 0xc0, 0x5b, 0xf6, 0x72, 0x59, 0x2f, 0x86, - 0x44, 0x76, 0x84, 0x17, 0xf1, 0x96, 0xd4, 0x6b, 0x58, 0xad, 0xff, 0x87, 0xe4, 0x46, 0x5f, 0x20, - 0xe0, 0x39, 0x6f, 0x49, 0x6b, 0x9e, 0xcc, 0x61, 0x66, 0x64, 0x75, 0x31, 0x4c, 0xef, 0xa8, 0x77, - 0x88, 0x7e, 0x7e, 0x4b, 0x1d, 0xca, 0x03, 0x52, 0x2f, 0x92, 0xab, 0x7b, 0xbd, 0xf4, 0x94, 0x15, - 0xdc, 0x5a, 0x20, 0xf3, 0x48, 0xba, 0xd3, 0x81, 0x83, 0xad, 0x34, 0x4b, 0x83, 0x67, 0x4c, 0xb2, - 0x9e, 0xe2, 0x27, 0x8d, 0x18, 0x65, 0xbb, 0xfd, 0x9b, 0x98, 0x8c, 0xc3, 0xc4, 0x0b, 0x40, 0xc8, - 0x51, 0x65, 0x27, 0xe2, 0x30, 0xd9, 0x04, 0x21, 0xa9, 0x43, 0x66, 0xc2, 0x9c, 0xd0, 0x13, 0x5d, - 0x5f, 0x04, 0x59, 0x98, 0xe2, 0x04, 0xe9, 0x63, 0x8d, 0x6a, 0x73, 0xca, 0xa5, 0xb8, 0xb5, 0x33, - 0xb8, 0xb3, 0xfe, 0xbd, 0x46, 0xc6, 0xd1, 0x0b, 0xfd, 0xa8, 0x91, 0x7a, 0xd1, 0xa0, 0xb4, 0x59, - 0x7e, 0xf9, 0xe7, 0xe7, 0xc1, 0xb8, 0x3b, 0x02, 0xb2, 0x88, 0x65, 0x2d, 0x7d, 0xf8, 0xf1, 0xe7, - 0xcb, 0x98, 0x49, 0x17, 0x9d, 0x21, 0xc3, 0x49, 0xdf, 0x93, 0x71, 0xec, 0x4b, 0xba, 0x3c, 0x8c, - 0x79, 0x60, 0x54, 0x8c, 0xe6, 0xe5, 0x40, 0xe5, 0xe0, 0x36, 0x3a, 0xb8, 0x41, 0x17, 0x2e, 0x70, - 0x80, 0xba, 0x5f, 0x35, 0x32, 0x3d, 0xd0, 0x0a, 0x74, 0x75, 0x08, 0xfd, 0xf9, 0x6e, 0x32, 0xec, - 0x51, 0xe1, 0xca, 0xd3, 0x0a, 0x7a, 0x5a, 0xa2, 0x56, 0xb9, 0x27, 0x1c, 0x13, 0xaf, 0xf8, 0xa2, - 0xdf, 0x34, 0x72, 0xf5, 0x4c, 0xcb, 0x50, 0x67, 0x88, 0x5a, 0x59, 0xeb, 0x19, 0xf7, 0x46, 0x2f, - 0x50, 0x06, 0x57, 0xd1, 0xe0, 0x32, 0xbd, 0x53, 0x6e, 0x50, 0x74, 0xe0, 0xc0, 0x2b, 0x5a, 0x6e, - 0x97, 0x49, 0xb6, 0xf1, 0xf4, 0xe8, 0xc4, 0xd4, 0x8e, 0x4f, 0x4c, 0xed, 0xf7, 0x89, 0xa9, 0x7d, - 0x3e, 0x35, 0x2b, 0xc7, 0xa7, 0x66, 0xe5, 0xe7, 0xa9, 0x59, 0x79, 0xb3, 0xdc, 0x0e, 0x65, 0xa7, - 0xeb, 0xdb, 0x01, 0xc4, 0x67, 0xa9, 0xde, 0xf5, 0xc9, 0xe4, 0x61, 0xca, 0x85, 0x5f, 0xc7, 0x1f, - 0xf0, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x15, 0xaa, 0x4c, 0x5d, 0x06, 0x00, 0x00, + // 718 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xc1, 0x4f, 0x13, 0x4f, + 0x18, 0xed, 0x42, 0x29, 0x30, 0xfc, 0x7e, 0x26, 0x0e, 0x24, 0x94, 0x05, 0x97, 0xba, 0x62, 0xa8, + 0x24, 0xec, 0x00, 0x1e, 0x4c, 0x34, 0x1e, 0x2c, 0x5e, 0x48, 0x34, 0x91, 0xc5, 0x93, 0x97, 0xcd, + 0xec, 0x76, 0xda, 0x6e, 0xd8, 0xdd, 0x59, 0x76, 0xa6, 0x20, 0x27, 0x13, 0x8d, 0x07, 0x6f, 0x26, + 0x5e, 0xbc, 0x7a, 0xf5, 0x2f, 0xe1, 0x62, 0x42, 0xe2, 0xc5, 0x93, 0x1a, 0xf0, 0x2f, 0xf0, 0x2f, + 0x30, 0xfb, 0xcd, 0xb4, 0x96, 0xb0, 0xd4, 0x9e, 0xa6, 0x9d, 0x79, 0xdf, 0xfb, 0xde, 0xdb, 0x79, + 0xdf, 0xa0, 0x5a, 0x44, 0x0f, 0x69, 0xc2, 0x24, 0xc9, 0x57, 0x92, 0xb1, 0x23, 0x9a, 0x35, 0x05, + 0x39, 0xe8, 0xb2, 0xec, 0xd8, 0x49, 0x33, 0x2e, 0x39, 0x9e, 0xd3, 0x08, 0x27, 0x5f, 0x1d, 0x8d, + 0x30, 0xe7, 0xda, 0xbc, 0xcd, 0x01, 0x40, 0xf2, 0x5f, 0x0a, 0x6b, 0x2e, 0xb5, 0x39, 0x6f, 0x47, + 0x8c, 0xd0, 0x34, 0x24, 0x34, 0x49, 0xb8, 0xa4, 0x32, 0xe4, 0x89, 0xd0, 0xa7, 0x6b, 0x01, 0x17, + 0x31, 0x17, 0xc4, 0xa7, 0x82, 0xa9, 0x16, 0xe4, 0x70, 0xd3, 0x67, 0x92, 0x6e, 0x92, 0x94, 0xb6, + 0xc3, 0x04, 0xc0, 0x1a, 0x7b, 0xb3, 0x50, 0x57, 0x4a, 0x33, 0x1a, 0xf7, 0xe8, 0xac, 0x41, 0xba, + 0x1e, 0x51, 0xc0, 0x43, 0x4d, 0x61, 0xcf, 0x21, 0xbc, 0x9b, 0x37, 0x79, 0x06, 0x45, 0x2e, 0x3b, + 0xe8, 0x32, 0x21, 0xed, 0x5d, 0x34, 0x7b, 0x61, 0x57, 0xa4, 0x3c, 0x11, 0x0c, 0xdf, 0x47, 0x15, + 0x45, 0x5e, 0x35, 0x6a, 0x46, 0x7d, 0x66, 0x6b, 0xc9, 0x29, 0xb2, 0xed, 0xa8, 0xaa, 0x46, 0xf9, + 0xe4, 0xfb, 0x72, 0xc9, 0xd5, 0x15, 0xf6, 0x2c, 0xba, 0xae, 0x28, 0x39, 0x8f, 0xfa, 0x7d, 0xde, + 0x1a, 0x68, 0x2a, 0xdf, 0xd8, 0x49, 0x5a, 0x1c, 0x63, 0x54, 0x4e, 0x68, 0xcc, 0x80, 0x7b, 0xda, + 0x85, 0xdf, 0x98, 0xa1, 0x49, 0x9f, 0x46, 0x34, 0x09, 0x58, 0x75, 0xac, 0x36, 0x5e, 0x9f, 0xd9, + 0x5a, 0x70, 0x94, 0x21, 0x27, 0x37, 0xe4, 0x68, 0x43, 0xce, 0x36, 0x0f, 0x93, 0xc6, 0x46, 0xde, + 0xef, 0xf3, 0x8f, 0xe5, 0x7a, 0x3b, 0x94, 0x9d, 0xae, 0xef, 0x04, 0x3c, 0x26, 0xda, 0xbd, 0x5a, + 0xd6, 0x45, 0x73, 0x9f, 0xc8, 0xe3, 0x94, 0x09, 0x28, 0x10, 0x6e, 0x8f, 0xdb, 0xfe, 0x6d, 0xf4, + 0x3e, 0x83, 0x52, 0xd7, 0xf7, 0x3b, 0x91, 0xe6, 0x1b, 0x55, 0x03, 0x7a, 0x5b, 0x57, 0xd8, 0xd5, + 0x06, 0xb4, 0x61, 0x55, 0x82, 0x57, 0xd0, 0x35, 0x19, 0xc6, 0xcc, 0x93, 0xdc, 0xcb, 0x58, 0x2b, + 0x8c, 0xa2, 0xea, 0x58, 0xcd, 0xa8, 0x8f, 0xbb, 0xff, 0xe5, 0xbb, 0xcf, 0xb9, 0x0b, 0x7b, 0xf8, + 0x01, 0x32, 0x99, 0x90, 0x61, 0x4c, 0x25, 0x6b, 0x7a, 0x7e, 0xc4, 0x83, 0x7d, 0x31, 0x50, 0x31, + 0x0e, 0x15, 0xf3, 0x7d, 0x44, 0x03, 0x00, 0xfd, 0xe2, 0x87, 0x68, 0x91, 0x46, 0x11, 0x0f, 0x20, + 0x12, 0x5e, 0xde, 0xd6, 0x8b, 0x79, 0x22, 0x3b, 0xc2, 0x8b, 0x58, 0x4b, 0x56, 0xcb, 0x50, 0x5d, + 0xfd, 0x0b, 0xc9, 0x85, 0x3e, 0x05, 0xc0, 0x13, 0xd6, 0x92, 0xf6, 0x02, 0x9a, 0x07, 0xcf, 0xc0, + 0xea, 0x82, 0x99, 0xde, 0xbd, 0xec, 0xa1, 0xea, 0xe5, 0x23, 0xfd, 0x51, 0xee, 0xa1, 0x8a, 0x72, + 0xae, 0x43, 0x30, 0xe4, 0x46, 0x74, 0x02, 0x14, 0xdc, 0x5e, 0x44, 0x0b, 0x40, 0xba, 0xd7, 0xe1, + 0x47, 0x3b, 0x69, 0x96, 0x06, 0x8f, 0xa9, 0xa4, 0xbd, 0x8e, 0xef, 0x0c, 0x64, 0x16, 0x9d, 0xf6, + 0x6f, 0x62, 0x2a, 0x0e, 0x13, 0x2f, 0xe0, 0x42, 0x8e, 0xda, 0x76, 0x32, 0x0e, 0x93, 0x6d, 0x2e, + 0x24, 0x26, 0x68, 0x36, 0xcc, 0x09, 0x3d, 0xd1, 0xf5, 0x45, 0x90, 0x85, 0x29, 0x8c, 0x1b, 0xe4, + 0x69, 0xda, 0xc5, 0x70, 0xb4, 0x37, 0x78, 0xb2, 0xf5, 0xa5, 0x8c, 0x26, 0x40, 0x0b, 0x7e, 0x63, + 0xa0, 0x8a, 0x4a, 0x33, 0xae, 0x17, 0x5f, 0xfe, 0xe5, 0xe1, 0x31, 0xef, 0x8c, 0x80, 0x54, 0xb6, + 0xec, 0x95, 0xd7, 0x5f, 0x7f, 0x7d, 0x18, 0xb3, 0xf0, 0x12, 0x19, 0x32, 0xc9, 0xf8, 0x15, 0x9a, + 0x80, 0x5c, 0xe2, 0xd5, 0x61, 0xcc, 0x03, 0x73, 0x65, 0xd6, 0xff, 0x0d, 0xd4, 0x0a, 0x6e, 0x81, + 0x82, 0x1b, 0x78, 0xf1, 0x0a, 0x05, 0xd0, 0xf7, 0xa3, 0x81, 0x66, 0x06, 0xa2, 0x80, 0xd7, 0x87, + 0xd0, 0x5f, 0x4e, 0x93, 0xe9, 0x8c, 0x0a, 0xd7, 0x9a, 0xd6, 0x40, 0xd3, 0x0a, 0xb6, 0x8b, 0x35, + 0xc1, 0x98, 0x78, 0xea, 0x1f, 0xfe, 0x64, 0xa0, 0xff, 0x2f, 0x44, 0x06, 0x93, 0x21, 0xdd, 0x8a, + 0xa2, 0x67, 0x6e, 0x8c, 0x5e, 0xa0, 0x05, 0xae, 0x83, 0xc0, 0x55, 0x7c, 0xbb, 0x58, 0xa0, 0xe8, + 0xf0, 0x23, 0x4f, 0x45, 0xae, 0x49, 0x25, 0x6d, 0x3c, 0x3a, 0x39, 0xb3, 0x8c, 0xd3, 0x33, 0xcb, + 0xf8, 0x79, 0x66, 0x19, 0xef, 0xcf, 0xad, 0xd2, 0xe9, 0xb9, 0x55, 0xfa, 0x76, 0x6e, 0x95, 0x5e, + 0xac, 0x0e, 0x3c, 0x55, 0x17, 0xa8, 0x5e, 0xf6, 0xc9, 0xe0, 0xbd, 0xf2, 0x2b, 0xf0, 0x5a, 0xdf, + 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xce, 0xcd, 0x6c, 0x8a, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -801,16 +804,20 @@ func (m *PoolInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.Balance.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Balance) > 0 { + for iNdEx := len(m.Balance) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Balance[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x12 if len(m.Name) > 0 { i -= len(m.Name) copy(dAtA[i:], m.Name) @@ -1044,8 +1051,12 @@ func (m *PoolInfo) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - l = m.Balance.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.Balance) > 0 { + for _, e := range m.Balance { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -1398,7 +1409,8 @@ func (m *PoolInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Balance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Balance = append(m.Balance, types.Coin{}) + if err := m.Balance[len(m.Balance)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/rewards/types/types.go b/x/rewards/types/types.go index 7e3473777a..c06d5dbb4a 100644 --- a/x/rewards/types/types.go +++ b/x/rewards/types/types.go @@ -49,9 +49,12 @@ const ( // basis const ( IprpcPoolName Pool = "iprpc_pool" - IprpcPoolEmissionEventName string = "iprpc_pool_emmission" + IprpcPoolEmissionEventName string = "iprpc-pool-emmission" + SetIprpcDataEventName = "set-iprpc-data" ) -const ( - SetIprpcDataEventName = "set-iprpc-data" -) +// helper struct to track the serviced IPRPC CU for each spec+provider +type SpecCuType struct { + ProvidersCu map[string]uint64 // provider -> cu + TotalCu uint64 +} diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index bf7b4bc194..d822084374 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -184,23 +184,23 @@ func (k Keeper) RewardAndResetCuTracker(ctx sdk.Context, cuTrackerTimerKeyBytes // calculate the provider reward (smaller than totalMonthlyReward // because it's shared with delegators) - totalMonthlyReward := k.CalcTotalMonthlyReward(ctx, totalTokenAmount, trackedCu, totalCuTracked) - creditToSub := sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), totalMonthlyReward) - totalTokenRewarded = totalTokenRewarded.Add(totalMonthlyReward) + totalMonthlyRewardAmount := k.CalcTotalMonthlyReward(ctx, totalTokenAmount, trackedCu, totalCuTracked) + creditToSub := sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), totalMonthlyRewardAmount) + totalTokenRewarded = totalTokenRewarded.Add(totalMonthlyRewardAmount) // aggregate the reward for the provider - k.rewardsKeeper.AggregateRewards(ctx, provider, chainID, providerAdjustment, totalMonthlyReward, sub, trackedCu) + k.rewardsKeeper.AggregateRewards(ctx, provider, chainID, providerAdjustment, totalMonthlyRewardAmount, sub, trackedCu) // Transfer some of the total monthly reward to validators contribution and community pool - totalMonthlyReward, err = k.rewardsKeeper.ContributeToValidatorsAndCommunityPool(ctx, totalMonthlyReward, types.ModuleName) + creditToSub, err = k.rewardsKeeper.ContributeToValidatorsAndCommunityPool(ctx, creditToSub, types.ModuleName) if err != nil { utils.LavaFormatError("could not contribute to validators and community pool", err, - utils.Attribute{Key: "total_monthly_reward", Value: totalMonthlyReward.String() + k.stakingKeeper.BondDenom(ctx)}) + utils.Attribute{Key: "total_monthly_reward", Value: creditToSub.String()}) } // Note: if the reward function doesn't reward the provider // because he was unstaked, we only print an error and not returning - providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, totalMonthlyReward, types.ModuleName, false, false, false) + providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, creditToSub, types.ModuleName, false, false, false) if errors.Is(err, epochstoragetypes.ErrProviderNotStaked) || errors.Is(err, epochstoragetypes.ErrStakeStorageNotFound) { utils.LavaFormatWarning("sending provider reward with delegations failed", err, utils.Attribute{Key: "provider", Value: provider}, @@ -251,7 +251,7 @@ func (k Keeper) RewardAndResetCuTracker(ctx sdk.Context, cuTrackerTimerKeyBytes } else if !rewardsRemainder.IsZero() { { // sub expired (no need to update credit), send rewards remainder to the community pool - err = k.rewardsKeeper.FundCommunityPoolFromModule(ctx, rewardsRemainder, types.ModuleName) + err = k.rewardsKeeper.FundCommunityPoolFromModule(ctx, sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), rewardsRemainder)), types.ModuleName) if err != nil { utils.LavaFormatError("failed sending remainder of rewards to the community pool", err, utils.Attribute{Key: "rewards_remainder", Value: rewardsRemainder.String()}, diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index d6a81b47c9..ddb574aca3 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -60,14 +60,14 @@ type TimerStoreKeeper interface { } type DualStakingKeeper interface { - RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward math.Int, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward math.Int, totalRewards math.Int, err error) + RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, totalRewards sdk.Coin, err error) } type RewardsKeeper interface { AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int, sub string, cu uint64) MaxRewardBoost(ctx sdk.Context) (res uint64) - ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward math.Int, senderModule string) (updatedReward math.Int, err error) - FundCommunityPoolFromModule(ctx sdk.Context, amount math.Int, senderModule string) error + ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward sdk.Coin, senderModule string) (updatedReward sdk.Coin, err error) + FundCommunityPoolFromModule(ctx sdk.Context, amount sdk.Coins, senderModule string) error } type StakingKeeper interface { From a04e9127944ab7a05c76bb003f79fdc757d92aca Mon Sep 17 00:00:00 2001 From: oren-lava Date: Tue, 13 Feb 2024 13:50:56 +0200 Subject: [PATCH 15/64] CNS-870: fix lint --- x/rewards/keeper/iprpc_reward.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 0f521a69f4..19de8acc69 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -36,17 +36,17 @@ func (k Keeper) SetIprpcRewardCount(ctx sdk.Context, count uint64) { // AppendIprpcReward appends a IprpcReward in the store with a new id and update the count func (k Keeper) AppendIprpcReward( ctx sdk.Context, - IprpcReward types.IprpcReward, + iprpcReward types.IprpcReward, ) uint64 { // Create the IprpcReward count := k.GetIprpcRewardCount(ctx) // Set the ID of the appended value - IprpcReward.Id = count + iprpcReward.Id = count store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) - appendedValue := k.cdc.MustMarshal(&IprpcReward) - store.Set(GetIprpcRewardIDBytes(IprpcReward.Id), appendedValue) + appendedValue := k.cdc.MustMarshal(&iprpcReward) + store.Set(GetIprpcRewardIDBytes(iprpcReward.Id), appendedValue) // Update IprpcReward count k.SetIprpcRewardCount(ctx, count+1) @@ -55,10 +55,10 @@ func (k Keeper) AppendIprpcReward( } // SetIprpcReward set a specific IprpcReward in the store -func (k Keeper) SetIprpcReward(ctx sdk.Context, IprpcReward types.IprpcReward) { +func (k Keeper) SetIprpcReward(ctx sdk.Context, iprpcReward types.IprpcReward) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) - b := k.cdc.MustMarshal(&IprpcReward) - store.Set(GetIprpcRewardIDBytes(IprpcReward.Id), b) + b := k.cdc.MustMarshal(&iprpcReward) + store.Set(GetIprpcRewardIDBytes(iprpcReward.Id), b) } // GetIprpcReward returns a IprpcReward from its id From f18c95eac8ba80dcafe27a6ac1eebdb51139010f Mon Sep 17 00:00:00 2001 From: oren-lava Date: Tue, 13 Feb 2024 19:18:22 +0200 Subject: [PATCH 16/64] CNS-870: updated IPRPC reward to work with Current and not Count --- proto/lavanet/lava/rewards/genesis.proto | 2 +- x/rewards/genesis.go | 4 +- x/rewards/genesis_test.go | 4 +- x/rewards/keeper/iprpc_reward.go | 87 ++++++++++++------------ x/rewards/keeper/providers.go | 1 + x/rewards/types/genesis.pb.go | 86 +++++++++++------------ x/rewards/types/keys.go | 6 +- 7 files changed, 95 insertions(+), 95 deletions(-) diff --git a/proto/lavanet/lava/rewards/genesis.proto b/proto/lavanet/lava/rewards/genesis.proto index 34d02ca9c3..90d8e9f533 100644 --- a/proto/lavanet/lava/rewards/genesis.proto +++ b/proto/lavanet/lava/rewards/genesis.proto @@ -19,6 +19,6 @@ message GenesisState { repeated string iprpc_subscriptions = 4; cosmos.base.v1beta1.Coin min_iprpc_cost = 5 [(gogoproto.nullable) = false]; repeated IprpcReward iprpc_rewards = 6 [(gogoproto.nullable) = false]; - uint64 iprpc_rewards_count = 7; + uint64 iprpc_rewards_current = 7; // this line is used by starport scaffolding # genesis/proto/state } \ No newline at end of file diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index e14b873de6..a339109e69 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -27,7 +27,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) for _, iprpcReward := range genState.IprpcRewards { k.SetIprpcReward(ctx, iprpcReward) } - k.SetIprpcRewardCount(ctx, genState.IprpcRewardsCount) + k.SetIprpcRewardsCurrent(ctx, genState.IprpcRewardsCurrent) } // ExportGenesis returns the capability module's exported genesis. @@ -39,7 +39,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.IprpcSubscriptions = k.GetAllIprpcSubscription(ctx) genesis.MinIprpcCost = k.GetMinIprpcCost(ctx) genesis.IprpcRewards = k.GetAllIprpcReward(ctx) - genesis.IprpcRewardsCount = k.GetIprpcRewardCount(ctx) + genesis.IprpcRewardsCurrent = k.GetIprpcRewardsCurrent(ctx) // this line is used by starport scaffolding # genesis/module/export return genesis diff --git a/x/rewards/genesis_test.go b/x/rewards/genesis_test.go index f2015035c7..cd7e508195 100644 --- a/x/rewards/genesis_test.go +++ b/x/rewards/genesis_test.go @@ -24,7 +24,7 @@ func TestGenesis(t *testing.T) { SpecFunds: []types.Specfund{{Fund: []sdk.Coin{}}}, }, }, - IprpcRewardsCount: 2, + IprpcRewardsCurrent: 2, // this line is used by starport scaffolding # genesis/test/state } @@ -39,6 +39,6 @@ func TestGenesis(t *testing.T) { nullify.Fill(got) require.ElementsMatch(t, genesisState.IprpcRewards, got.IprpcRewards) - require.Equal(t, genesisState.IprpcRewardsCount, got.IprpcRewardsCount) + require.Equal(t, genesisState.IprpcRewardsCurrent, got.IprpcRewardsCurrent) // this line is used by starport scaffolding # genesis/test/assert } diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 19de8acc69..5e86860ccb 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -2,20 +2,19 @@ package keeper import ( "encoding/binary" - "sort" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/lavanet/lava/x/rewards/types" ) -// GetIprpcRewardCount get the total number of IprpcReward -func (k Keeper) GetIprpcRewardCount(ctx sdk.Context) uint64 { +// GetIprpcRewardsCurrent get the total number of IprpcReward +func (k Keeper) GetIprpcRewardsCurrent(ctx sdk.Context) uint64 { store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{}) - byteKey := types.KeyPrefix(types.IprpcRewardsCountPrefix) + byteKey := types.KeyPrefix(types.IprpcRewardsCurrentPrefix) bz := store.Get(byteKey) - // Count doesn't exist: no element + // Current doesn't exist: no element if bz == nil { return 0 } @@ -24,36 +23,15 @@ func (k Keeper) GetIprpcRewardCount(ctx sdk.Context) uint64 { return binary.BigEndian.Uint64(bz) } -// SetIprpcRewardCount set the total number of IprpcReward -func (k Keeper) SetIprpcRewardCount(ctx sdk.Context, count uint64) { +// SetIprpcRewardsCurrent set the total number of IprpcReward +func (k Keeper) SetIprpcRewardsCurrent(ctx sdk.Context, current uint64) { store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{}) - byteKey := types.KeyPrefix(types.IprpcRewardsCountPrefix) + byteKey := types.KeyPrefix(types.IprpcRewardsCurrentPrefix) bz := make([]byte, 8) - binary.BigEndian.PutUint64(bz, count) + binary.BigEndian.PutUint64(bz, current) store.Set(byteKey, bz) } -// AppendIprpcReward appends a IprpcReward in the store with a new id and update the count -func (k Keeper) AppendIprpcReward( - ctx sdk.Context, - iprpcReward types.IprpcReward, -) uint64 { - // Create the IprpcReward - count := k.GetIprpcRewardCount(ctx) - - // Set the ID of the appended value - iprpcReward.Id = count - - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) - appendedValue := k.cdc.MustMarshal(&iprpcReward) - store.Set(GetIprpcRewardIDBytes(iprpcReward.Id), appendedValue) - - // Update IprpcReward count - k.SetIprpcRewardCount(ctx, count+1) - - return count -} - // SetIprpcReward set a specific IprpcReward in the store func (k Keeper) SetIprpcReward(ctx sdk.Context, iprpcReward types.IprpcReward) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.IprpcRewardPrefix)) @@ -108,24 +86,45 @@ func GetIprpcRewardIDFromBytes(bz []byte) uint64 { // PopIprpcReward gets the lowest id IprpcReward object and removes it func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { - // Get all IprpcReward - allRewards := k.GetAllIprpcReward(ctx) - - // Check if there are any rewards - if len(allRewards) == 0 { + // Get current IprpcReward + iprpcReward, found := k.GetIprpcReward(ctx, k.GetIprpcRewardsCurrent(ctx)) + if !found { return types.IprpcReward{}, false } - // Sort rewards by index - sort.SliceStable(allRewards, func(i, j int) bool { - return allRewards[i].Id < allRewards[j].Id - }) + // Remove the reward + k.RemoveIprpcReward(ctx, iprpcReward.Id) - // Get the first reward - firstReward := allRewards[0] + return iprpcReward, true +} - // Remove the first reward - k.RemoveIprpcReward(ctx, firstReward.Id) +// AddSpecFunds adds funds for a specific spec for of months. +// This function is used by the fund-iprpc TX. +func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64, fromNextMonth bool) { + startID := k.GetIprpcRewardsCurrent(ctx) + if fromNextMonth { + startID += 1 + } - return firstReward, true + for i := startID; i < duration; i++ { + iprpcReward, found := k.GetIprpcReward(ctx, i) + if !found { + // found IPRPC reward + for i := 0; i < len(iprpcReward.SpecFunds); i++ { + if iprpcReward.SpecFunds[i].Spec == spec { + iprpcReward.SpecFunds[i].Fund = iprpcReward.SpecFunds[i].Fund.Add(fund...) + k.SetIprpcReward(ctx, iprpcReward) + return + } + } + // did not find spec in IPRPC reward -> create a new one + iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) + } else { + // did not find IPRPC reward -> create a new one + iprpcReward.Id = i + iprpcReward.SpecFunds = []types.Specfund{{Spec: spec, Fund: fund}} + } + + k.SetIprpcReward(ctx, iprpcReward) + } } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index c9ae3e6588..b83c553945 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -107,6 +107,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { utils.LavaFormatError("current month iprpc reward not found", fmt.Errorf("did not reward providers IPRPC bonus")) return } + k.SetIprpcRewardsCurrent(ctx, iprpcReward.Id+1) for _, specFund := range iprpcReward.SpecFunds { // collect details details := map[string]string{"spec": specFund.Spec} diff --git a/x/rewards/types/genesis.pb.go b/x/rewards/types/genesis.pb.go index b6399f4224..d39a2fc306 100644 --- a/x/rewards/types/genesis.pb.go +++ b/x/rewards/types/genesis.pb.go @@ -27,13 +27,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the rewards module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - RefillRewardsTS types.GenesisState `protobuf:"bytes,2,opt,name=refillRewardsTS,proto3" json:"refillRewardsTS"` - BasePays []BasePayGenesis `protobuf:"bytes,3,rep,name=base_pays,json=basePays,proto3" json:"base_pays"` - IprpcSubscriptions []string `protobuf:"bytes,4,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` - MinIprpcCost types1.Coin `protobuf:"bytes,5,opt,name=min_iprpc_cost,json=minIprpcCost,proto3" json:"min_iprpc_cost"` - IprpcRewards []IprpcReward `protobuf:"bytes,6,rep,name=iprpc_rewards,json=iprpcRewards,proto3" json:"iprpc_rewards"` - IprpcRewardsCount uint64 `protobuf:"varint,7,opt,name=iprpc_rewards_count,json=iprpcRewardsCount,proto3" json:"iprpc_rewards_count,omitempty"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + RefillRewardsTS types.GenesisState `protobuf:"bytes,2,opt,name=refillRewardsTS,proto3" json:"refillRewardsTS"` + BasePays []BasePayGenesis `protobuf:"bytes,3,rep,name=base_pays,json=basePays,proto3" json:"base_pays"` + IprpcSubscriptions []string `protobuf:"bytes,4,rep,name=iprpc_subscriptions,json=iprpcSubscriptions,proto3" json:"iprpc_subscriptions,omitempty"` + MinIprpcCost types1.Coin `protobuf:"bytes,5,opt,name=min_iprpc_cost,json=minIprpcCost,proto3" json:"min_iprpc_cost"` + IprpcRewards []IprpcReward `protobuf:"bytes,6,rep,name=iprpc_rewards,json=iprpcRewards,proto3" json:"iprpc_rewards"` + IprpcRewardsCurrent uint64 `protobuf:"varint,7,opt,name=iprpc_rewards_current,json=iprpcRewardsCurrent,proto3" json:"iprpc_rewards_current,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -111,9 +111,9 @@ func (m *GenesisState) GetIprpcRewards() []IprpcReward { return nil } -func (m *GenesisState) GetIprpcRewardsCount() uint64 { +func (m *GenesisState) GetIprpcRewardsCurrent() uint64 { if m != nil { - return m.IprpcRewardsCount + return m.IprpcRewardsCurrent } return 0 } @@ -127,34 +127,34 @@ func init() { } var fileDescriptor_02c24f4df31ca14e = []byte{ - // 428 bytes of a gzipped FileDescriptorProto + // 429 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x41, 0x6f, 0xd3, 0x30, - 0x14, 0xc7, 0x13, 0x52, 0x0a, 0xf3, 0x06, 0x08, 0xb3, 0x43, 0xa8, 0x50, 0xc8, 0x06, 0x88, 0x9c, - 0x6c, 0x6d, 0xdc, 0xb8, 0xd1, 0x0a, 0x4d, 0x48, 0x1c, 0xa6, 0x14, 0x2e, 0x5c, 0x22, 0x27, 0x98, - 0x60, 0xa9, 0xb1, 0x23, 0x3f, 0x77, 0xd0, 0x6f, 0xc1, 0xc7, 0xda, 0xb1, 0x47, 0x4e, 0xa8, 0x6a, - 0xbf, 0x08, 0x8a, 0xed, 0xd2, 0x16, 0xe5, 0x64, 0xcb, 0xef, 0xff, 0xff, 0xf9, 0xfd, 0x9f, 0x1e, - 0x3a, 0x9f, 0xb1, 0x1b, 0x26, 0xb9, 0xa1, 0xdd, 0x49, 0x35, 0xff, 0xc1, 0xf4, 0x57, 0xa0, 0x35, - 0x97, 0x1c, 0x04, 0x90, 0x56, 0x2b, 0xa3, 0xf0, 0xa9, 0xd7, 0x90, 0xee, 0x24, 0x5e, 0x33, 0x3a, - 0xad, 0x55, 0xad, 0xac, 0x80, 0x76, 0x37, 0xa7, 0x1d, 0x9d, 0xf5, 0xf2, 0x5a, 0xa6, 0x59, 0xe3, - 0x71, 0xa3, 0x17, 0xbd, 0x92, 0x92, 0x01, 0x2f, 0x5a, 0xb6, 0xf0, 0xa2, 0xb4, 0x57, 0x24, 0x5a, - 0xdd, 0x56, 0xbd, 0x18, 0x23, 0x1a, 0xae, 0xc1, 0x28, 0xcd, 0xdd, 0xd5, 0x8b, 0x92, 0x4a, 0x41, - 0xa3, 0x1c, 0x9d, 0xde, 0x5c, 0x94, 0xdc, 0xb0, 0x0b, 0x5a, 0x29, 0x21, 0x5d, 0xfd, 0x7c, 0x15, - 0xa1, 0x93, 0x2b, 0x17, 0x76, 0x6a, 0x98, 0xe1, 0xf8, 0x2d, 0x1a, 0xba, 0x66, 0xe3, 0x30, 0x0d, - 0xb3, 0xe3, 0xcb, 0x67, 0xa4, 0x2f, 0x3c, 0xb9, 0xb6, 0x9a, 0xf1, 0xe0, 0xf6, 0xcf, 0xf3, 0x20, - 0xf7, 0x0e, 0xfc, 0x19, 0x3d, 0xd2, 0xfc, 0x9b, 0x98, 0xcd, 0x72, 0xa7, 0xfa, 0x34, 0x8d, 0xef, - 0x58, 0xc8, 0xab, 0x43, 0xc8, 0xae, 0x57, 0xb2, 0xff, 0xb7, 0xa7, 0xfd, 0xcf, 0xc0, 0x57, 0xe8, - 0x68, 0x3b, 0x1c, 0x88, 0xa3, 0x34, 0xca, 0x8e, 0x2f, 0x5f, 0xf6, 0x77, 0x35, 0x66, 0xc0, 0xaf, - 0xd9, 0xc2, 0x43, 0x3d, 0xef, 0x7e, 0xe9, 0x5e, 0x01, 0x53, 0xf4, 0xc4, 0x0e, 0xb0, 0x80, 0x79, - 0x09, 0x95, 0x16, 0xad, 0x11, 0x4a, 0x42, 0x3c, 0x48, 0xa3, 0xec, 0x28, 0xc7, 0xb6, 0x34, 0xdd, - 0xaf, 0xe0, 0xf7, 0xe8, 0x61, 0x23, 0x64, 0xe1, 0x4c, 0x95, 0x02, 0x13, 0xdf, 0xb5, 0x79, 0x9e, - 0x12, 0x37, 0x56, 0xd2, 0xa1, 0x89, 0x1f, 0x2b, 0x99, 0x28, 0x21, 0xfd, 0x9f, 0x27, 0x8d, 0x90, - 0x1f, 0x3a, 0xd7, 0x44, 0x81, 0xc1, 0x1f, 0xd1, 0x03, 0x87, 0xf0, 0x7d, 0xc6, 0x43, 0x1b, 0xe2, - 0xac, 0x3f, 0x84, 0xf5, 0xb9, 0xf4, 0x5b, 0x9a, 0xd8, 0x3d, 0x01, 0x26, 0xdb, 0x14, 0xde, 0x50, - 0x54, 0x6a, 0x2e, 0x4d, 0x7c, 0x2f, 0x0d, 0xb3, 0x41, 0xfe, 0x78, 0x5f, 0x3a, 0xe9, 0x0a, 0xe3, - 0x77, 0xb7, 0xeb, 0x24, 0x5c, 0xae, 0x93, 0x70, 0xb5, 0x4e, 0xc2, 0x5f, 0x9b, 0x24, 0x58, 0x6e, - 0x92, 0xe0, 0xf7, 0x26, 0x09, 0xbe, 0xbc, 0xae, 0x85, 0xf9, 0x3e, 0x2f, 0x49, 0xa5, 0x1a, 0x7a, - 0xb0, 0x4c, 0x3f, 0xff, 0x2d, 0x9c, 0x59, 0xb4, 0x1c, 0xca, 0xa1, 0x5d, 0x96, 0x37, 0x7f, 0x03, - 0x00, 0x00, 0xff, 0xff, 0x38, 0x36, 0xec, 0x19, 0x2d, 0x03, 0x00, 0x00, + 0x14, 0x80, 0x13, 0x52, 0x0a, 0xf3, 0x06, 0x48, 0xde, 0x90, 0x42, 0x85, 0x42, 0x36, 0x40, 0xe4, + 0x64, 0x6b, 0xe5, 0xc6, 0x8d, 0x56, 0x68, 0x42, 0xe2, 0x30, 0xa5, 0x70, 0xe1, 0x12, 0x39, 0xc1, + 0x04, 0x4b, 0x8d, 0x1d, 0xf9, 0xb9, 0x83, 0xfe, 0x0b, 0x7e, 0xd6, 0x8e, 0x3b, 0x72, 0x42, 0xa8, + 0xe5, 0x87, 0xa0, 0xd8, 0x2e, 0x6d, 0xa7, 0x9c, 0x6c, 0xf9, 0x7d, 0xef, 0xf3, 0x7b, 0x4f, 0x0f, + 0x9d, 0xcd, 0xd9, 0x15, 0x93, 0xdc, 0xd0, 0xee, 0xa4, 0x9a, 0x7f, 0x67, 0xfa, 0x0b, 0xd0, 0x9a, + 0x4b, 0x0e, 0x02, 0x48, 0xab, 0x95, 0x51, 0xf8, 0xc4, 0x33, 0xa4, 0x3b, 0x89, 0x67, 0x46, 0x27, + 0xb5, 0xaa, 0x95, 0x05, 0x68, 0x77, 0x73, 0xec, 0xe8, 0xb4, 0xd7, 0xd7, 0x32, 0xcd, 0x1a, 0xaf, + 0x1b, 0x3d, 0xef, 0x45, 0x4a, 0x06, 0xbc, 0x68, 0xd9, 0xd2, 0x43, 0x69, 0x2f, 0x24, 0x5a, 0xdd, + 0x56, 0xbd, 0x1a, 0x23, 0x1a, 0xae, 0xc1, 0x28, 0xcd, 0xdd, 0xd5, 0x43, 0x49, 0xa5, 0xa0, 0x51, + 0xce, 0x4e, 0xaf, 0xce, 0x4b, 0x6e, 0xd8, 0x39, 0xad, 0x94, 0x90, 0x2e, 0x7e, 0xf6, 0x37, 0x42, + 0x47, 0x17, 0xae, 0xd9, 0x99, 0x61, 0x86, 0xe3, 0x37, 0x68, 0xe8, 0x8a, 0x8d, 0xc3, 0x34, 0xcc, + 0x0e, 0xc7, 0x4f, 0x49, 0x5f, 0xf3, 0xe4, 0xd2, 0x32, 0x93, 0xc1, 0xf5, 0xef, 0x67, 0x41, 0xee, + 0x33, 0xf0, 0x27, 0xf4, 0x48, 0xf3, 0xaf, 0x62, 0x3e, 0xcf, 0x1d, 0xf5, 0x71, 0x16, 0xdf, 0xb1, + 0x92, 0x97, 0xfb, 0x92, 0x6d, 0xad, 0x64, 0xf7, 0x6f, 0x6f, 0xbb, 0xed, 0xc0, 0x17, 0xe8, 0x60, + 0x33, 0x1c, 0x88, 0xa3, 0x34, 0xca, 0x0e, 0xc7, 0x2f, 0xfa, 0xab, 0x9a, 0x30, 0xe0, 0x97, 0x6c, + 0xe9, 0xa5, 0xde, 0x77, 0xbf, 0x74, 0xaf, 0x80, 0x29, 0x3a, 0xb6, 0x03, 0x2c, 0x60, 0x51, 0x42, + 0xa5, 0x45, 0x6b, 0x84, 0x92, 0x10, 0x0f, 0xd2, 0x28, 0x3b, 0xc8, 0xb1, 0x0d, 0xcd, 0x76, 0x23, + 0xf8, 0x1d, 0x7a, 0xd8, 0x08, 0x59, 0xb8, 0xa4, 0x4a, 0x81, 0x89, 0xef, 0xda, 0x7e, 0x9e, 0x10, + 0x37, 0x56, 0xd2, 0xa9, 0x89, 0x1f, 0x2b, 0x99, 0x2a, 0x21, 0xfd, 0x9f, 0x47, 0x8d, 0x90, 0xef, + 0xbb, 0xac, 0xa9, 0x02, 0x83, 0x3f, 0xa0, 0x07, 0x4e, 0xe1, 0xeb, 0x8c, 0x87, 0xb6, 0x89, 0xd3, + 0xfe, 0x26, 0x6c, 0x9e, 0xeb, 0x7e, 0x63, 0x13, 0xdb, 0x27, 0xc0, 0x63, 0xf4, 0x78, 0xcf, 0x56, + 0x54, 0x0b, 0xad, 0xb9, 0x34, 0xf1, 0xbd, 0x34, 0xcc, 0x06, 0xf9, 0xf1, 0x2e, 0x3c, 0x75, 0xa1, + 0xc9, 0xdb, 0xeb, 0x55, 0x12, 0xde, 0xac, 0x92, 0xf0, 0xcf, 0x2a, 0x09, 0x7f, 0xae, 0x93, 0xe0, + 0x66, 0x9d, 0x04, 0xbf, 0xd6, 0x49, 0xf0, 0xf9, 0x55, 0x2d, 0xcc, 0xb7, 0x45, 0x49, 0x2a, 0xd5, + 0xd0, 0xbd, 0x85, 0xfa, 0xf1, 0x7f, 0xe9, 0xcc, 0xb2, 0xe5, 0x50, 0x0e, 0xed, 0xc2, 0xbc, 0xfe, + 0x17, 0x00, 0x00, 0xff, 0xff, 0x15, 0xb1, 0xb4, 0xbe, 0x31, 0x03, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -177,8 +177,8 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.IprpcRewardsCount != 0 { - i = encodeVarintGenesis(dAtA, i, uint64(m.IprpcRewardsCount)) + if m.IprpcRewardsCurrent != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.IprpcRewardsCurrent)) i-- dAtA[i] = 0x38 } @@ -293,8 +293,8 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - if m.IprpcRewardsCount != 0 { - n += 1 + sovGenesis(uint64(m.IprpcRewardsCount)) + if m.IprpcRewardsCurrent != 0 { + n += 1 + sovGenesis(uint64(m.IprpcRewardsCurrent)) } return n } @@ -535,9 +535,9 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 7: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IprpcRewardsCount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IprpcRewardsCurrent", wireType) } - m.IprpcRewardsCount = 0 + m.IprpcRewardsCurrent = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -547,7 +547,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.IprpcRewardsCount |= uint64(b&0x7F) << shift + m.IprpcRewardsCurrent |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/rewards/types/keys.go b/x/rewards/types/keys.go index 5c61258d7c..b5f04af3a0 100644 --- a/x/rewards/types/keys.go +++ b/x/rewards/types/keys.go @@ -26,10 +26,10 @@ const ( MinIprpcCostPrefix = "min-iprpc-cost" // prefix for IPRPC reward element - IprpcRewardPrefix = "iprpc-reward" + IprpcRewardPrefix = "iprpc-reward/" - // prefix for IPRPC rewards count - IprpcRewardsCountPrefix = "count-iprpc-rewards" + // prefix for the current IPRPC reward index + IprpcRewardsCurrentPrefix = "iprpc-rewards-current/" ) func KeyPrefix(p string) []byte { From 3db52d234bc3570cf3139ef15b60a683ac9ffd88 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 14 Feb 2024 12:53:53 +0200 Subject: [PATCH 17/64] CNS-868: make min cost flag in set-iprpc-data required --- x/rewards/client/cli/tx.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/rewards/client/cli/tx.go b/x/rewards/client/cli/tx.go index e34b4d5bf0..3fe5071947 100644 --- a/x/rewards/client/cli/tx.go +++ b/x/rewards/client/cli/tx.go @@ -146,5 +146,6 @@ $ %s tx gov submit-legacy-proposal set-iprpc-data --min-cost 0ulava --add-subscr cmd.Flags().StringSlice(addIprpcSubscriptionsFlagName, []string{}, "add iprpc eligible subscriptions") cmd.Flags().StringSlice(removeIprpcSubscriptionsFlagName, []string{}, "remove iprpc eligible subscriptions") cmd.Flags().Bool(expeditedFlagName, false, "set to true to make the spec proposal expedited") + cmd.MarkFlagRequired(minIprpcCostFlagName) return cmd } From dc29e1a1e0181b1110dac3e10733bc10915a321e Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 14 Feb 2024 12:59:15 +0200 Subject: [PATCH 18/64] CNS-868: genesis fixes --- x/rewards/genesis.go | 1 + x/rewards/types/genesis.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index 3eb9454a48..74c4bd3a1a 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -23,6 +23,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) for _, sub := range genState.IprpcSubscriptions { k.SetIprpcSubscription(ctx, sub) } + k.SetIprpcData(ctx, genState.MinIprpcCost, genState.IprpcSubscriptions) } // ExportGenesis returns the capability module's exported genesis. diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index 609f7f4a84..e066aaba9f 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -35,14 +35,20 @@ func (gs GenesisState) Validate() error { at all times. amount of timers found: %v`, len(timeEntries)) } + unique := map[string]struct{}{} for _, sub := range gs.IprpcSubscriptions { _, err := sdk.AccAddressFromBech32(sub) if err != nil { return fmt.Errorf("invalid subscription address. err: %s", err.Error()) } + _, ok := unique[sub] + if ok { + return fmt.Errorf("iprpc subscription address is duplicated. address: %s", sub) + } + unique[sub] = struct{}{} } - if gs.MinIprpcCost.Denom != DefaultGenesis().MinIprpcCost.Denom { + if gs.MinIprpcCost.Denom != "ulava" { return fmt.Errorf("invalid min iprpc cost denom. MinIprpcCost: %s", gs.MinIprpcCost.String()) } From d3a07dde7f78c75958e4befa3ea4492544799f0c Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 14 Feb 2024 13:05:06 +0200 Subject: [PATCH 19/64] CNS-868: PR fix --- x/rewards/types/base_pay.go | 2 +- x/rewards/types/iprpc_data.go | 9 +++++++++ x/rewards/types/keys.go | 6 ------ 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 x/rewards/types/iprpc_data.go diff --git a/x/rewards/types/base_pay.go b/x/rewards/types/base_pay.go index 2a8d26bf79..f654bcd40c 100644 --- a/x/rewards/types/base_pay.go +++ b/x/rewards/types/base_pay.go @@ -5,7 +5,7 @@ import ( ) const ( - // StakeStorageKeyPrefix is the prefix to retrieve all StakeStorage + // BasePayPrefix is the prefix to retrieve all BasePay BasePayPrefix = "BasePay/" ) diff --git a/x/rewards/types/iprpc_data.go b/x/rewards/types/iprpc_data.go new file mode 100644 index 0000000000..c757d6d0c8 --- /dev/null +++ b/x/rewards/types/iprpc_data.go @@ -0,0 +1,9 @@ +package types + +const ( + // IprpcSubscriptionPrefix is the prefix to retrieve all IprpcSubscription + IprpcSubscriptionPrefix = "IprpcSubscription/" + + // MinIprpcCostPrefix is the prefix to retrieve all MinIprpcCost + MinIprpcCostPrefix = "MinIprpcCost/" +) diff --git a/x/rewards/types/keys.go b/x/rewards/types/keys.go index 89f06bb3e6..ac8f682afb 100644 --- a/x/rewards/types/keys.go +++ b/x/rewards/types/keys.go @@ -18,12 +18,6 @@ const ( // prefix for the CU tracker timer store MonthlyRewardsTSPrefix = "monthly-rewards-ts" - - // prefix for IPRPC eligible subscriptions - IprpcSubscriptionPrefix = "iprpc-subscription" - - // prefix for min IPRPC cost - MinIprpcCostPrefix = "min-iprpc-cost" ) func KeyPrefix(p string) []byte { From bb5f4b7dd3ea224d312f82063b02b3c0d38ca2b9 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 14 Feb 2024 19:02:38 +0200 Subject: [PATCH 20/64] CNS-869: scaffold TX fund iprpc --- proto/lavanet/lava/rewards/tx.proto | 14 + scripts/init_chain_commands.sh | 4 + utils/time.go | 12 + x/rewards/client/cli/tx.go | 1 + x/rewards/client/cli/tx_fund_iprpc.go | 60 +++ x/rewards/handler.go | 5 + x/rewards/keeper/iprpc.go | 72 +++ x/rewards/keeper/iprpc_reward.go | 6 +- x/rewards/keeper/msg_server_fund_iprpc.go | 32 ++ x/rewards/keeper/providers.go | 19 +- x/rewards/types/codec.go | 2 + x/rewards/types/errors.go | 2 +- x/rewards/types/expected_keepers.go | 2 + x/rewards/types/message_fund_iprpc.go | 63 +++ x/rewards/types/message_fund_iprpc_test.go | 49 ++ x/rewards/types/tx.pb.go | 525 ++++++++++++++++++++- x/rewards/types/types.go | 1 + 17 files changed, 834 insertions(+), 35 deletions(-) create mode 100644 x/rewards/client/cli/tx_fund_iprpc.go create mode 100644 x/rewards/keeper/iprpc.go create mode 100644 x/rewards/keeper/msg_server_fund_iprpc.go create mode 100644 x/rewards/types/message_fund_iprpc.go create mode 100644 x/rewards/types/message_fund_iprpc_test.go diff --git a/proto/lavanet/lava/rewards/tx.proto b/proto/lavanet/lava/rewards/tx.proto index c89345cef4..1e4c23daee 100644 --- a/proto/lavanet/lava/rewards/tx.proto +++ b/proto/lavanet/lava/rewards/tx.proto @@ -11,6 +11,7 @@ option go_package = "github.com/lavanet/lava/x/rewards/types"; // Msg defines the Msg service. service Msg { rpc SetIprpcData(MsgSetIprpcData) returns (MsgSetIprpcDataResponse); + rpc FundIprpc(MsgFundIprpc) returns (MsgFundIprpcResponse); // this line is used by starport scaffolding # proto/tx/rpc } @@ -23,4 +24,17 @@ message MsgSetIprpcData { message MsgSetIprpcDataResponse { } +message MsgFundIprpc { + string creator = 1; + uint64 duration = 2; // vesting duration in months + repeated cosmos.base.v1beta1.Coin amounts = 3 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; // tokens to be distributed as reward + string spec = 4; // spec on which the providers get incentive +} + +message MsgFundIprpcResponse { +} + // this line is used by starport scaffolding # proto/tx/message \ No newline at end of file diff --git a/scripts/init_chain_commands.sh b/scripts/init_chain_commands.sh index e5d916c14b..45ccd1f4e1 100755 --- a/scripts/init_chain_commands.sh +++ b/scripts/init_chain_commands.sh @@ -106,6 +106,10 @@ sleep_until_next_epoch HEALTH_FILE="config/health_examples/health_template.yml" create_health_config $HEALTH_FILE $(lavad keys show user1 -a) $(lavad keys show servicer2 -a) $(lavad keys show servicer3 -a) +lavad tx gov submit-legacy-proposal set-iprpc-data 1000000000ulava --min-cost 100ulava --add-subscriptions $(lavad keys show -a user1) --from alice -y +wait_count_blocks 1 +lavad tx gov vote $(latest_vote) yes -y --from alice --gas-adjustment "1.5" --gas "auto" --gas-prices $GASPRICE + if [[ "$1" != "--skip-providers" ]]; then . ${__dir}/setup_providers.sh echo "letting providers start and running health check" diff --git a/utils/time.go b/utils/time.go index c96dcf0ad9..88ae7fddc4 100644 --- a/utils/time.go +++ b/utils/time.go @@ -41,3 +41,15 @@ func NextMonth(date time.Time) time.Time { time.UTC, ) } + +func IsMiddleOfMonthPassed(date time.Time) bool { + // Get the total number of days in the current month + _, month, year := date.Date() + daysInMonth := time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC).Day() + + // Calculate the middle day of the month + middleDay := daysInMonth / 2 + + // Check if the day of the given date is greater than the middle day + return date.Day() > middleDay +} diff --git a/x/rewards/client/cli/tx.go b/x/rewards/client/cli/tx.go index 3fe5071947..ff8d00261d 100644 --- a/x/rewards/client/cli/tx.go +++ b/x/rewards/client/cli/tx.go @@ -41,6 +41,7 @@ func GetTxCmd() *cobra.Command { RunE: client.ValidateCmd, } + cmd.AddCommand(CmdFundIprpc()) // this line is used by starport scaffolding # 1 return cmd diff --git a/x/rewards/client/cli/tx_fund_iprpc.go b/x/rewards/client/cli/tx_fund_iprpc.go new file mode 100644 index 0000000000..c51c2abc59 --- /dev/null +++ b/x/rewards/client/cli/tx_fund_iprpc.go @@ -0,0 +1,60 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/rewards/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdFundIprpc() *cobra.Command { + cmd := &cobra.Command{ + Use: "fund-iprpc [spec] [duration] [coins] --from ", + Short: `fund the IPRPC pool to a specific spec with ulava or IBC wrapped tokens. The tokens will be vested for months. + Note that the amount of coins you put is the monthly quota (it's not for the total period of time). + Also, the tokens must include duration*min_iprpc_cost of ulava tokens (min_iprpc_cost is shown with the show-iprpc-data command)`, + Example: `lavad tx rewards fund-iprpc ETH1 4 100000ulava,50000ibctoken --from alice + This command will transfer 4*100000ulava and 4*50000ibctoken to the IPRPC pool to be distributed for 4 months`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + spec := args[0] + durationStr := args[1] + duration, err := strconv.ParseUint(durationStr, 10, 64) + if err != nil { + return err + } + + fundStr := args[2] + fund, err := sdk.ParseCoinsNormalized(fundStr) + if err != nil { + return err + } + + msg := types.NewMsgFundIprpc( + clientCtx.GetFromAddress().String(), + spec, + duration, + fund, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/rewards/handler.go b/x/rewards/handler.go index 068fa10b23..0692e0efcb 100644 --- a/x/rewards/handler.go +++ b/x/rewards/handler.go @@ -14,10 +14,15 @@ import ( func NewHandler(k keeper.Keeper) sdk.Handler { // this line is used by starport scaffolding # handler/msgServer + msgServer := keeper.NewMsgServerImpl(k) + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { _ = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { + case *types.MsgFundIprpc: + res, err := msgServer.FundIprpc(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) // this line is used by starport scaffolding # 1 default: errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go new file mode 100644 index 0000000000..fdeaf189f6 --- /dev/null +++ b/x/rewards/keeper/iprpc.go @@ -0,0 +1,72 @@ +package keeper + +import ( + "strconv" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/utils" + "github.com/lavanet/lava/x/rewards/types" +) + +func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund sdk.Coins, spec string) error { + // verify spec exists and active + foundAndActive, _, _ := k.specKeeper.IsSpecFoundAndActive(ctx, spec) + if !foundAndActive { + return utils.LavaFormatWarning("spec not found or disabled", types.ErrFundIprpc) + } + + // check fund consists of minimum amount of ulava (duration * min_iprpc_cost) + minIprpcFundCost := k.GetMinIprpcCost(ctx).Amount.MulRaw(int64(duration)) + if fund.AmountOf(k.stakingKeeper.BondDenom(ctx)).LT(minIprpcFundCost) { + return utils.LavaFormatWarning("insufficient ulava tokens in fund. should be at least min iprpc cost * duration", types.ErrFundIprpc, + utils.LogAttr("min_iprpc_cost", k.GetMinIprpcCost(ctx).String()), + utils.LogAttr("duration", strconv.FormatUint(duration, 10)), + utils.LogAttr("fund_ulava_amount", fund.AmountOf(k.stakingKeeper.BondDenom(ctx))), + ) + } + + // check creator has enough balance + addr, err := sdk.AccAddressFromBech32(creator) + if err != nil { + return utils.LavaFormatWarning("invalid creator address", types.ErrFundIprpc) + } + creatorUlavaBalance := k.bankKeeper.GetBalance(ctx, addr, k.stakingKeeper.BondDenom(ctx)) + if creatorUlavaBalance.Amount.LT(minIprpcFundCost) { + return utils.LavaFormatWarning("insufficient ulava tokens in fund. should be at least min iprpc cost * duration", types.ErrFundIprpc, + utils.LogAttr("min_iprpc_cost", k.GetMinIprpcCost(ctx).String()), + utils.LogAttr("duration", strconv.FormatUint(duration, 10)), + utils.LogAttr("creator_ulava_balance", creatorUlavaBalance.String()), + ) + } + + // send the minimum cost to the validators allocation pool (and subtract them from the fund) + minIprpcFundCostCoins := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), minIprpcFundCost)) + err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, addr, string(types.ValidatorsRewardsAllocationPoolName), minIprpcFundCostCoins) + if err != nil { + return utils.LavaFormatError(types.ErrFundIprpc.Error()+"for funding validator allocation pool", err, + utils.LogAttr("creator", creator), + utils.LogAttr("min_iprpc_fund_cost", minIprpcFundCost.String()), + ) + } + fund = fund.Sub(minIprpcFundCostCoins...) + + // send the funds to the iprpc pool + err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, addr, string(types.IprpcPoolName), fund) + if err != nil { + return utils.LavaFormatError(types.ErrFundIprpc.Error()+"for funding iprpc pool", err, + utils.LogAttr("creator", creator), + utils.LogAttr("fund", fund.String()), + ) + } + + // check if to add funds from next month or to current month + fromNextMonth := false + if utils.IsMiddleOfMonthPassed(ctx.BlockTime()) { + fromNextMonth = true + } + + // add spec funds to current/next month IPRPC reward object + k.addSpecFunds(ctx, spec, fund, duration, fromNextMonth) + + return nil +} diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 5e86860ccb..b124b55e72 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -108,7 +108,7 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat for i := startID; i < duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) - if !found { + if found { // found IPRPC reward for i := 0; i < len(iprpcReward.SpecFunds); i++ { if iprpcReward.SpecFunds[i].Spec == spec { @@ -119,12 +119,12 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat } // did not find spec in IPRPC reward -> create a new one iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) + k.SetIprpcReward(ctx, iprpcReward) } else { // did not find IPRPC reward -> create a new one iprpcReward.Id = i iprpcReward.SpecFunds = []types.Specfund{{Spec: spec, Fund: fund}} + k.SetIprpcReward(ctx, iprpcReward) } - - k.SetIprpcReward(ctx, iprpcReward) } } diff --git a/x/rewards/keeper/msg_server_fund_iprpc.go b/x/rewards/keeper/msg_server_fund_iprpc.go new file mode 100644 index 0000000000..d0e4e4a678 --- /dev/null +++ b/x/rewards/keeper/msg_server_fund_iprpc.go @@ -0,0 +1,32 @@ +package keeper + +import ( + "context" + "strconv" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/utils" + "github.com/lavanet/lava/x/rewards/types" +) + +func (k msgServer) FundIprpc(goCtx context.Context, msg *types.MsgFundIprpc) (*types.MsgFundIprpcResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + err := msg.ValidateBasic() + if err != nil { + return &types.MsgFundIprpcResponse{}, err + } + + err = k.Keeper.FundIprpc(ctx, msg.Creator, msg.Duration, msg.Amounts, msg.Spec) + if err == nil { + logger := k.Keeper.Logger(ctx) + details := map[string]string{ + "spec": msg.Spec, + "duration": strconv.FormatUint(msg.Duration, 10), + "amounts": msg.Amounts.String(), + } + utils.LogLavaEvent(ctx, logger, types.FundIprpcEventName, details, "Funded IPRPC pool successfully") + } + + return &types.MsgFundIprpcResponse{}, err +} diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index b83c553945..94eb41c3d3 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -110,12 +110,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { k.SetIprpcRewardsCurrent(ctx, iprpcReward.Id+1) for _, specFund := range iprpcReward.SpecFunds { // collect details - details := map[string]string{"spec": specFund.Spec} - rewardsStr := []string{} - for _, reward := range specFund.Fund { - rewardsStr = append(rewardsStr, reward.String()) - } - details["rewards"] = strings.Join(rewardsStr, ",") + details := map[string]string{"spec": specFund.Spec, "rewards": specFund.Fund.String()} // verify specCuMap holds an entry for the relevant spec specCu, ok := specCuMap[specFund.Spec] @@ -142,6 +137,10 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { if err != nil { continue } + if specCu.TotalCu == 0 { + // spec was not serviced by any provider, continue + continue + } // calculate provider IPRPC reward providerIprpcRewardPerc := math.LegacyNewDec(int64(specCu.ProvidersCu[provider])).QuoInt64(int64(specCu.TotalCu)) @@ -160,9 +159,11 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { // handle leftovers usedReward = specFund.Fund.Sub(usedReward...) - err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) - if err != nil { - utils.LavaFormatError("could not send iprpc leftover to community pool", err) + if !usedReward.IsZero() { + err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) + if err != nil { + utils.LavaFormatError("could not send iprpc leftover to community pool", err) + } } utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, details, "IPRPC monthly rewards distributed successfully") diff --git a/x/rewards/types/codec.go b/x/rewards/types/codec.go index 4a3fc0d903..8ec03098ef 100644 --- a/x/rewards/types/codec.go +++ b/x/rewards/types/codec.go @@ -11,6 +11,7 @@ import ( func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgSetIprpcData{}, "rewards/MsgSetIprpcData", nil) + cdc.RegisterConcrete(&MsgFundIprpc{}, "rewards/MsgFundIprpc", nil) // this line is used by starport scaffolding # 2 } @@ -18,6 +19,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { // this line is used by starport scaffolding # 3 registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSetIprpcData{}, + &MsgFundIprpc{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/rewards/types/errors.go b/x/rewards/types/errors.go index 00faef99f3..f3d7d64317 100644 --- a/x/rewards/types/errors.go +++ b/x/rewards/types/errors.go @@ -8,5 +8,5 @@ import ( // x/rewards module sentinel errors var ( - ErrSample = sdkerrors.Register(ModuleName, 1100, "sample error") + ErrFundIprpc = sdkerrors.Register(ModuleName, 1, "fund iprpc TX failed") ) diff --git a/x/rewards/types/expected_keepers.go b/x/rewards/types/expected_keepers.go index c691f8f5ab..af864f67ef 100644 --- a/x/rewards/types/expected_keepers.go +++ b/x/rewards/types/expected_keepers.go @@ -23,12 +23,14 @@ type BankKeeper interface { GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin SendCoinsFromModuleToModule(ctx sdk.Context, senderPool, recipientPool string, amt sdk.Coins) error GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error // Methods imported from bank should be defined here } type SpecKeeper interface { GetAllChainIDs(ctx sdk.Context) (chainIDs []string) GetSpec(ctx sdk.Context, index string) (val spectypes.Spec, found bool) + IsSpecFoundAndActive(ctx sdk.Context, chainID string) (foundAndActive, found bool, providersType spectypes.Spec_ProvidersTypes) } type TimerStoreKeeper interface { diff --git a/x/rewards/types/message_fund_iprpc.go b/x/rewards/types/message_fund_iprpc.go new file mode 100644 index 0000000000..dbbd57e667 --- /dev/null +++ b/x/rewards/types/message_fund_iprpc.go @@ -0,0 +1,63 @@ +package types + +import ( + fmt "fmt" + + sdkerrors "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + legacyerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgFundIprpc = "fund_iprpc" + +var _ sdk.Msg = &MsgFundIprpc{} + +func NewMsgFundIprpc(creator string, spec string, duration uint64, amounts sdk.Coins) *MsgFundIprpc { + return &MsgFundIprpc{ + Creator: creator, + Spec: spec, + Duration: duration, + Amounts: amounts, + } +} + +func (msg *MsgFundIprpc) Route() string { + return RouterKey +} + +func (msg *MsgFundIprpc) Type() string { + return TypeMsgFundIprpc +} + +func (msg *MsgFundIprpc) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgFundIprpc) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgFundIprpc) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(legacyerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + unique := map[string]struct{}{} + for _, amount := range msg.Amounts { + if !amount.IsValid() { + return sdkerrors.Wrap(fmt.Errorf("invalid amount; invalid denom or negative amount. coin: %s", amount.String()), "") + } + if _, ok := unique[amount.Denom]; ok { + return sdkerrors.Wrap(fmt.Errorf("invalid coins, duplicated denom: %s", amount.Denom), "") + } + unique[amount.Denom] = struct{}{} + } + + return nil +} diff --git a/x/rewards/types/message_fund_iprpc_test.go b/x/rewards/types/message_fund_iprpc_test.go new file mode 100644 index 0000000000..b44c983b30 --- /dev/null +++ b/x/rewards/types/message_fund_iprpc_test.go @@ -0,0 +1,49 @@ +package types + +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/testutil/sample" + "github.com/stretchr/testify/require" +) + +func TestFundIprpc_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg MsgFundIprpc + valid bool + }{ + { + name: "valid", + msg: MsgFundIprpc{ + Creator: sample.AccAddress(), + Duration: 2, + Amounts: sdk.NewCoins(sdk.NewCoin("denom", math.OneInt())), + Spec: "spec", + }, + valid: true, + }, + { + name: "invalid creator address", + msg: MsgFundIprpc{ + Creator: "invalid_address", + Duration: 2, + Amounts: sdk.NewCoins(sdk.NewCoin("denom", math.OneInt())), + Spec: "spec", + }, + valid: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.msg.ValidateBasic() + if tt.valid { + require.NoError(t, err) + return + } + require.Error(t, err) + }) + } +} diff --git a/x/rewards/types/tx.pb.go b/x/rewards/types/tx.pb.go index e0886a5318..36a497f99f 100644 --- a/x/rewards/types/tx.pb.go +++ b/x/rewards/types/tx.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -125,36 +126,149 @@ func (m *MsgSetIprpcDataResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgSetIprpcDataResponse proto.InternalMessageInfo +type MsgFundIprpc struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + Duration uint64 `protobuf:"varint,2,opt,name=duration,proto3" json:"duration,omitempty"` + Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` + Spec string `protobuf:"bytes,4,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (m *MsgFundIprpc) Reset() { *m = MsgFundIprpc{} } +func (m *MsgFundIprpc) String() string { return proto.CompactTextString(m) } +func (*MsgFundIprpc) ProtoMessage() {} +func (*MsgFundIprpc) Descriptor() ([]byte, []int) { + return fileDescriptor_6a4c66e189226d78, []int{2} +} +func (m *MsgFundIprpc) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgFundIprpc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgFundIprpc.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 *MsgFundIprpc) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgFundIprpc.Merge(m, src) +} +func (m *MsgFundIprpc) XXX_Size() int { + return m.Size() +} +func (m *MsgFundIprpc) XXX_DiscardUnknown() { + xxx_messageInfo_MsgFundIprpc.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgFundIprpc proto.InternalMessageInfo + +func (m *MsgFundIprpc) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgFundIprpc) GetDuration() uint64 { + if m != nil { + return m.Duration + } + return 0 +} + +func (m *MsgFundIprpc) GetAmounts() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Amounts + } + return nil +} + +func (m *MsgFundIprpc) GetSpec() string { + if m != nil { + return m.Spec + } + return "" +} + +type MsgFundIprpcResponse struct { +} + +func (m *MsgFundIprpcResponse) Reset() { *m = MsgFundIprpcResponse{} } +func (m *MsgFundIprpcResponse) String() string { return proto.CompactTextString(m) } +func (*MsgFundIprpcResponse) ProtoMessage() {} +func (*MsgFundIprpcResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6a4c66e189226d78, []int{3} +} +func (m *MsgFundIprpcResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgFundIprpcResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgFundIprpcResponse.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 *MsgFundIprpcResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgFundIprpcResponse.Merge(m, src) +} +func (m *MsgFundIprpcResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgFundIprpcResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgFundIprpcResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgFundIprpcResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgSetIprpcData)(nil), "lavanet.lava.rewards.MsgSetIprpcData") proto.RegisterType((*MsgSetIprpcDataResponse)(nil), "lavanet.lava.rewards.MsgSetIprpcDataResponse") + proto.RegisterType((*MsgFundIprpc)(nil), "lavanet.lava.rewards.MsgFundIprpc") + proto.RegisterType((*MsgFundIprpcResponse)(nil), "lavanet.lava.rewards.MsgFundIprpcResponse") } func init() { proto.RegisterFile("lavanet/lava/rewards/tx.proto", fileDescriptor_6a4c66e189226d78) } var fileDescriptor_6a4c66e189226d78 = []byte{ - // 326 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xcf, 0x4e, 0x3a, 0x31, - 0x10, 0xc7, 0xb7, 0x3f, 0x7e, 0x31, 0xa1, 0x12, 0x4d, 0x56, 0x12, 0x81, 0x68, 0x25, 0x24, 0x46, - 0x2e, 0xb6, 0x01, 0x9f, 0x40, 0xd0, 0x83, 0x07, 0x2e, 0xcb, 0xcd, 0x0b, 0xe9, 0x2e, 0xcd, 0xd2, - 0xe8, 0x76, 0x36, 0x3b, 0x05, 0xe1, 0x2d, 0x7c, 0x0b, 0x5f, 0x85, 0x23, 0x47, 0x4f, 0xc6, 0xc0, - 0x8b, 0x98, 0xfd, 0x63, 0x10, 0xe2, 0xc1, 0xd3, 0x4c, 0xe6, 0x3b, 0x9d, 0xf9, 0x74, 0xbe, 0xf4, - 0xfc, 0x59, 0xce, 0xa4, 0x51, 0x56, 0xa4, 0x51, 0x24, 0xea, 0x45, 0x26, 0x63, 0x14, 0x76, 0xce, - 0xe3, 0x04, 0x2c, 0xb8, 0xd5, 0x42, 0xe6, 0x69, 0xe4, 0x85, 0xdc, 0x60, 0x01, 0x60, 0x04, 0x28, - 0x7c, 0x89, 0x4a, 0xcc, 0x3a, 0xbe, 0xb2, 0xb2, 0x23, 0x02, 0xd0, 0x26, 0x7f, 0xd5, 0xa8, 0x86, - 0x10, 0x42, 0x96, 0x8a, 0x34, 0xcb, 0xab, 0xad, 0x37, 0x42, 0x8f, 0x07, 0x18, 0x0e, 0x95, 0x7d, - 0x88, 0x93, 0x38, 0xb8, 0x93, 0x56, 0xba, 0x67, 0xb4, 0x2c, 0xa7, 0x76, 0x02, 0x89, 0xb6, 0x8b, - 0x1a, 0x69, 0x92, 0x76, 0xd9, 0xdb, 0x16, 0xdc, 0x7b, 0x7a, 0x14, 0x69, 0x33, 0xd2, 0x69, 0xfb, - 0x28, 0x00, 0xb4, 0xb5, 0x7f, 0x4d, 0xd2, 0x3e, 0xec, 0xd6, 0x79, 0x0e, 0xc0, 0x53, 0x00, 0x5e, - 0x00, 0xf0, 0x3e, 0x68, 0xd3, 0xfb, 0xbf, 0xfc, 0xb8, 0x70, 0xbc, 0x4a, 0xa4, 0x4d, 0xb6, 0xa4, - 0x0f, 0x68, 0x5d, 0x41, 0x4f, 0xf2, 0x11, 0x38, 0xf5, 0x31, 0x48, 0x74, 0x6c, 0x35, 0x18, 0xac, - 0x95, 0x9a, 0xa5, 0x76, 0xd9, 0x73, 0x33, 0x69, 0xf8, 0x53, 0x69, 0xd5, 0xe9, 0xe9, 0x1e, 0xa8, - 0xa7, 0x30, 0x06, 0x83, 0xaa, 0xfb, 0x44, 0x4b, 0x03, 0x0c, 0xdd, 0x31, 0xad, 0xec, 0xfc, 0xe3, - 0x92, 0xff, 0x76, 0x28, 0xbe, 0x37, 0xa5, 0x71, 0xfd, 0xa7, 0xb6, 0xef, 0x65, 0xbd, 0xdb, 0xe5, - 0x9a, 0x91, 0xd5, 0x9a, 0x91, 0xcf, 0x35, 0x23, 0xaf, 0x1b, 0xe6, 0xac, 0x36, 0xcc, 0x79, 0xdf, - 0x30, 0xe7, 0xf1, 0x2a, 0xd4, 0x76, 0x32, 0xf5, 0x79, 0x00, 0x91, 0xd8, 0x71, 0x70, 0xbe, 0xf5, - 0x70, 0x11, 0x2b, 0xf4, 0x0f, 0xb2, 0xdb, 0xdf, 0x7c, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7e, 0xc1, - 0x85, 0x7c, 0xe8, 0x01, 0x00, 0x00, + // 443 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcd, 0x6e, 0xd4, 0x30, + 0x10, 0xc7, 0xd7, 0xec, 0x8a, 0xb2, 0x66, 0x05, 0x92, 0x59, 0x41, 0x1a, 0x41, 0xba, 0x8a, 0x84, + 0x88, 0x90, 0x6a, 0xd3, 0xf2, 0x04, 0xb4, 0x80, 0xc4, 0x61, 0x2f, 0xe9, 0x0d, 0x0e, 0x95, 0x93, + 0x58, 0xa9, 0x05, 0xb1, 0x23, 0x8f, 0x53, 0xda, 0xb7, 0xe0, 0x2d, 0x90, 0x78, 0x09, 0xae, 0x7b, + 0xec, 0x91, 0x13, 0xa0, 0xdd, 0x17, 0x41, 0x76, 0x92, 0xee, 0xb6, 0xe2, 0xeb, 0x34, 0x63, 0xff, + 0x67, 0xc6, 0xbf, 0x19, 0x0f, 0x7e, 0xf4, 0x81, 0x9f, 0x72, 0x25, 0x2c, 0x73, 0x96, 0x19, 0xf1, + 0x91, 0x9b, 0x02, 0x98, 0x3d, 0xa3, 0xb5, 0xd1, 0x56, 0x93, 0x69, 0x27, 0x53, 0x67, 0x69, 0x27, + 0x87, 0x51, 0xae, 0xa1, 0xd2, 0xc0, 0x32, 0x0e, 0x82, 0x9d, 0xee, 0x65, 0xc2, 0xf2, 0x3d, 0x96, + 0x6b, 0xa9, 0xda, 0xac, 0x70, 0x5a, 0xea, 0x52, 0x7b, 0x97, 0x39, 0xaf, 0xbd, 0x8d, 0x3f, 0x23, + 0x7c, 0x77, 0x0e, 0xe5, 0x91, 0xb0, 0x6f, 0x6a, 0x53, 0xe7, 0x2f, 0xb9, 0xe5, 0xe4, 0x21, 0x1e, + 0xf3, 0xc6, 0x9e, 0x68, 0x23, 0xed, 0x79, 0x80, 0x66, 0x28, 0x19, 0xa7, 0xeb, 0x0b, 0xf2, 0x0a, + 0xdf, 0xa9, 0xa4, 0x3a, 0x96, 0x2e, 0xfc, 0x38, 0xd7, 0x60, 0x83, 0x1b, 0x33, 0x94, 0xdc, 0xde, + 0xdf, 0xa6, 0x2d, 0x00, 0x75, 0x00, 0xb4, 0x03, 0xa0, 0x87, 0x5a, 0xaa, 0x83, 0xd1, 0xe2, 0xfb, + 0xce, 0x20, 0x9d, 0x54, 0x52, 0xf9, 0x47, 0x0e, 0x35, 0x58, 0xc2, 0xf0, 0xbd, 0xb6, 0x04, 0x34, + 0x19, 0xe4, 0x46, 0xd6, 0x56, 0x6a, 0x05, 0xc1, 0x70, 0x36, 0x4c, 0xc6, 0x29, 0xf1, 0xd2, 0xd1, + 0xa6, 0x12, 0x6f, 0xe3, 0x07, 0xd7, 0x40, 0x53, 0x01, 0xb5, 0x56, 0x20, 0xe2, 0xaf, 0x08, 0x4f, + 0xe6, 0x50, 0xbe, 0x6e, 0x54, 0xe1, 0x45, 0x12, 0xe0, 0xad, 0xdc, 0x08, 0x6e, 0xb5, 0xe9, 0xf8, + 0xfb, 0x23, 0x09, 0xf1, 0xad, 0xa2, 0x31, 0xdc, 0x95, 0xf4, 0xdc, 0xa3, 0xf4, 0xf2, 0x4c, 0x04, + 0xde, 0xe2, 0x95, 0x6e, 0x94, 0x6d, 0x31, 0xfe, 0xda, 0xd2, 0x33, 0xd7, 0xd2, 0x97, 0x1f, 0x3b, + 0x49, 0x29, 0xed, 0x49, 0x93, 0xd1, 0x5c, 0x57, 0xac, 0xfb, 0x80, 0xd6, 0xec, 0x42, 0xf1, 0x9e, + 0xd9, 0xf3, 0x5a, 0x80, 0x4f, 0x80, 0xb4, 0xaf, 0x4d, 0x08, 0x1e, 0x41, 0x2d, 0xf2, 0x60, 0xe4, + 0xc9, 0xbc, 0x1f, 0xdf, 0xc7, 0xd3, 0xcd, 0x06, 0xfa, 0xce, 0xf6, 0x17, 0x08, 0x0f, 0xe7, 0x50, + 0x92, 0x02, 0x4f, 0xae, 0x7c, 0xd1, 0x63, 0xfa, 0xbb, 0x1d, 0xa0, 0xd7, 0x06, 0x14, 0xee, 0xfe, + 0x57, 0x58, 0xff, 0x1a, 0x79, 0x87, 0xc7, 0xeb, 0x19, 0xc6, 0x7f, 0xcc, 0xbd, 0x8c, 0x09, 0x9f, + 0xfe, 0x3b, 0xa6, 0x2f, 0x7e, 0xf0, 0x62, 0xb1, 0x8c, 0xd0, 0xc5, 0x32, 0x42, 0x3f, 0x97, 0x11, + 0xfa, 0xb4, 0x8a, 0x06, 0x17, 0xab, 0x68, 0xf0, 0x6d, 0x15, 0x0d, 0xde, 0x3e, 0xd9, 0x98, 0xe1, + 0x95, 0xcd, 0x3f, 0x5b, 0xef, 0xbe, 0x1b, 0x64, 0x76, 0xd3, 0xef, 0xec, 0xf3, 0x5f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x87, 0x10, 0x57, 0xff, 0x20, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -170,6 +284,7 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { SetIprpcData(ctx context.Context, in *MsgSetIprpcData, opts ...grpc.CallOption) (*MsgSetIprpcDataResponse, error) + FundIprpc(ctx context.Context, in *MsgFundIprpc, opts ...grpc.CallOption) (*MsgFundIprpcResponse, error) } type msgClient struct { @@ -189,9 +304,19 @@ func (c *msgClient) SetIprpcData(ctx context.Context, in *MsgSetIprpcData, opts return out, nil } +func (c *msgClient) FundIprpc(ctx context.Context, in *MsgFundIprpc, opts ...grpc.CallOption) (*MsgFundIprpcResponse, error) { + out := new(MsgFundIprpcResponse) + err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Msg/FundIprpc", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { SetIprpcData(context.Context, *MsgSetIprpcData) (*MsgSetIprpcDataResponse, error) + FundIprpc(context.Context, *MsgFundIprpc) (*MsgFundIprpcResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -201,6 +326,9 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) SetIprpcData(ctx context.Context, req *MsgSetIprpcData) (*MsgSetIprpcDataResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SetIprpcData not implemented") } +func (*UnimplementedMsgServer) FundIprpc(ctx context.Context, req *MsgFundIprpc) (*MsgFundIprpcResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FundIprpc not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -224,6 +352,24 @@ func _Msg_SetIprpcData_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_FundIprpc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgFundIprpc) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).FundIprpc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/lavanet.lava.rewards.Msg/FundIprpc", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).FundIprpc(ctx, req.(*MsgFundIprpc)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "lavanet.lava.rewards.Msg", HandlerType: (*MsgServer)(nil), @@ -232,6 +378,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "SetIprpcData", Handler: _Msg_SetIprpcData_Handler, }, + { + MethodName: "FundIprpc", + Handler: _Msg_FundIprpc_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "lavanet/lava/rewards/tx.proto", @@ -309,6 +459,85 @@ func (m *MsgSetIprpcDataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *MsgFundIprpc) 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 *MsgFundIprpc) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgFundIprpc) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Spec) > 0 { + i -= len(m.Spec) + copy(dAtA[i:], m.Spec) + i = encodeVarintTx(dAtA, i, uint64(len(m.Spec))) + i-- + dAtA[i] = 0x22 + } + if len(m.Amounts) > 0 { + for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Duration != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Duration)) + i-- + dAtA[i] = 0x10 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgFundIprpcResponse) 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 *MsgFundIprpcResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgFundIprpcResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -350,6 +579,41 @@ func (m *MsgSetIprpcDataResponse) Size() (n int) { return n } +func (m *MsgFundIprpc) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Duration != 0 { + n += 1 + sovTx(uint64(m.Duration)) + } + if len(m.Amounts) > 0 { + for _, e := range m.Amounts { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + l = len(m.Spec) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgFundIprpcResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -553,6 +817,223 @@ func (m *MsgSetIprpcDataResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgFundIprpc) 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 ErrIntOverflowTx + } + 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: MsgFundIprpc: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgFundIprpc: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + } + m.Duration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Duration |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amounts = append(m.Amounts, types.Coin{}) + if err := m.Amounts[len(m.Amounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Spec = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgFundIprpcResponse) 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 ErrIntOverflowTx + } + 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: MsgFundIprpcResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgFundIprpcResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/rewards/types/types.go b/x/rewards/types/types.go index c06d5dbb4a..08db41ee80 100644 --- a/x/rewards/types/types.go +++ b/x/rewards/types/types.go @@ -51,6 +51,7 @@ const ( IprpcPoolName Pool = "iprpc_pool" IprpcPoolEmissionEventName string = "iprpc-pool-emmission" SetIprpcDataEventName = "set-iprpc-data" + FundIprpcEventName = "fund-iprpc" ) // helper struct to track the serviced IPRPC CU for each spec+provider From 6d9c6c0f78292918c0b4edd9162681256810104d Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 11:29:24 +0200 Subject: [PATCH 21/64] CNS-871: implemented iprpc provider reward --- proto/lavanet/lava/rewards/query.proto | 16 + scripts/cli_test.sh | 1 + testutil/common/tester.go | 9 +- x/rewards/client/cli/query.go | 1 + .../client/cli/query_iprpc_provider_reward.go | 43 ++ .../grpc_query_iprpc_provider_reward.go | 57 ++ x/rewards/types/query.pb.go | 490 ++++++++++++++++-- x/rewards/types/query.pb.gw.go | 101 ++++ 8 files changed, 671 insertions(+), 47 deletions(-) create mode 100644 x/rewards/client/cli/query_iprpc_provider_reward.go create mode 100644 x/rewards/keeper/grpc_query_iprpc_provider_reward.go diff --git a/proto/lavanet/lava/rewards/query.proto b/proto/lavanet/lava/rewards/query.proto index dd0ec78fe3..8f3bab30ef 100644 --- a/proto/lavanet/lava/rewards/query.proto +++ b/proto/lavanet/lava/rewards/query.proto @@ -5,6 +5,7 @@ import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "lavanet/lava/rewards/params.proto"; +import "lavanet/lava/rewards/iprpc.proto"; import "cosmos/base/v1beta1/coin.proto"; // this line is used by starport scaffolding # 1 @@ -31,6 +32,11 @@ service Query { rpc ShowIprpcData(QueryShowIprpcDataRequest) returns (QueryShowIprpcDataResponse) { option (google.api.http).get = "/lavanet/lava/rewards/show_iprpc_data"; } + + // ShowIprpcData queries for the iprpc data + rpc IprpcProviderReward(QueryIprpcProviderRewardRequest) returns (QueryIprpcProviderRewardResponse) { + option (google.api.http).get = "/lavanet/lava/rewards/iprpc_provider_reward/{provider}"; + } // this line is used by starport scaffolding # 2 } @@ -80,4 +86,14 @@ message QueryShowIprpcDataResponse { repeated string iprpc_subscriptions = 2; } +// QueryIprpcProviderRewardRequest is request type for the Query/IprpcProviderReward RPC method. +message QueryIprpcProviderRewardRequest { + string provider = 1; +} + +// QueryIprpcProviderRewardResponse is response type for the Query/IprpcProviderReward RPC method. +message QueryIprpcProviderRewardResponse { + repeated Specfund spec_funds = 1 [(gogoproto.nullable) = false]; +} + // this line is used by starport scaffolding # 3 \ No newline at end of file diff --git a/scripts/cli_test.sh b/scripts/cli_test.sh index 212e2db1b9..9ccd352adb 100755 --- a/scripts/cli_test.sh +++ b/scripts/cli_test.sh @@ -183,6 +183,7 @@ echo "Testing rewards q commands" trace lavad q rewards pools >/dev/null trace lavad q rewards block-reward >/dev/null trace lavad q rewards show-iprpc-data > /dev/null +trace lavad q rewards iprpc-provider-reward > /dev/null echo "Testing events command" trace lavad test events 30 10 --event lava_relay_payment --from alice --timeout 1s >/dev/null diff --git a/testutil/common/tester.go b/testutil/common/tester.go index b664e151ac..6e0f63232b 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -859,11 +859,18 @@ func (ts *Tester) QueryRewardsBlockReward() (*rewardstypes.QueryBlockRewardRespo return ts.Keepers.Rewards.BlockReward(ts.GoCtx, msg) } -func (ts *Tester) QueryShowIprpcData() (*rewardstypes.QueryShowIprpcDataResponse, error) { +func (ts *Tester) QueryRewardsShowIprpcData() (*rewardstypes.QueryShowIprpcDataResponse, error) { msg := &rewardstypes.QueryShowIprpcDataRequest{} return ts.Keepers.Rewards.ShowIprpcData(ts.GoCtx, msg) } +func (ts *Tester) QueryRewardsIprpcProviderReward(provider string) (*rewardstypes.QueryIprpcProviderRewardResponse, error) { + msg := &rewardstypes.QueryIprpcProviderRewardRequest{ + Provider: provider, + } + return ts.Keepers.Rewards.IprpcProviderReward(ts.GoCtx, msg) +} + // block/epoch helpers func (ts *Tester) BlockHeight() uint64 { diff --git a/x/rewards/client/cli/query.go b/x/rewards/client/cli/query.go index c109ab1701..0f9627ec93 100644 --- a/x/rewards/client/cli/query.go +++ b/x/rewards/client/cli/query.go @@ -28,6 +28,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdQueryPools()) cmd.AddCommand(CmdQueryBlockReward()) cmd.AddCommand(CmdQueryShowIprpcData()) + cmd.AddCommand(CmdQueryIprpcProviderReward()) // this line is used by starport scaffolding # 1 return cmd diff --git a/x/rewards/client/cli/query_iprpc_provider_reward.go b/x/rewards/client/cli/query_iprpc_provider_reward.go new file mode 100644 index 0000000000..56e83ddaf4 --- /dev/null +++ b/x/rewards/client/cli/query_iprpc_provider_reward.go @@ -0,0 +1,43 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/lavanet/lava/x/rewards/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdQueryIprpcProviderReward() *cobra.Command { + cmd := &cobra.Command{ + Use: "iprpc-provider-reward [provider]", + Short: "Query for current IPRPC reward for a specific provider", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryIprpcProviderRewardRequest{ + Provider: args[0], + } + + res, err := queryClient.IprpcProviderReward(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/rewards/keeper/grpc_query_iprpc_provider_reward.go b/x/rewards/keeper/grpc_query_iprpc_provider_reward.go new file mode 100644 index 0000000000..2a2cfd0ffc --- /dev/null +++ b/x/rewards/keeper/grpc_query_iprpc_provider_reward.go @@ -0,0 +1,57 @@ +package keeper + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/rewards/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k Keeper) IprpcProviderReward(goCtx context.Context, req *types.QueryIprpcProviderRewardRequest) (*types.QueryIprpcProviderRewardResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + // get current month IPRPC reward + id := k.GetIprpcRewardsCurrent(ctx) + iprpcReward, found := k.GetIprpcReward(ctx, id) + if !found { + return nil, fmt.Errorf("current month IPRPC reward does not exist") + } + + // go over all the IPRPC reward specs and get the provider's relative reward (by CU) + providerSpecFunds := []types.Specfund{} + for _, specFund := range iprpcReward.SpecFunds { + // get all spec basepays and count IPRPC CU + bps, _ := k.specProvidersBasePay(ctx, specFund.Spec) + providerIprpcCu := uint64(0) + totalIprpcCu := uint64(0) + providerBpIndex := types.BasePayIndex{Provider: req.Provider, ChainID: specFund.Spec} + for _, bp := range bps { + if bp.BasePayIndex.String() == providerBpIndex.String() { + providerIprpcCu = bp.IprpcCu + } + totalIprpcCu += bp.IprpcCu + } + + // get the provider's relative reward by CU + providerFund, isValid := specFund.Fund.SafeMulInt(sdk.NewIntFromUint64(providerIprpcCu)) + if !isValid { + continue + } + providerFund, isValid = providerFund.SafeQuoInt(sdk.NewIntFromUint64(totalIprpcCu)) + if !isValid { + continue + } + + // save the provider's reward + providerSpecFunds = append(providerSpecFunds, types.Specfund{Spec: specFund.Spec, Fund: providerFund}) + } + + return &types.QueryIprpcProviderRewardResponse{SpecFunds: providerSpecFunds}, nil +} diff --git a/x/rewards/types/query.pb.go b/x/rewards/types/query.pb.go index 76394786fd..4b720bf75f 100644 --- a/x/rewards/types/query.pb.go +++ b/x/rewards/types/query.pb.go @@ -446,6 +446,96 @@ func (m *QueryShowIprpcDataResponse) GetIprpcSubscriptions() []string { return nil } +// QueryIprpcProviderRewardRequest is request type for the Query/IprpcProviderReward RPC method. +type QueryIprpcProviderRewardRequest struct { + Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` +} + +func (m *QueryIprpcProviderRewardRequest) Reset() { *m = QueryIprpcProviderRewardRequest{} } +func (m *QueryIprpcProviderRewardRequest) String() string { return proto.CompactTextString(m) } +func (*QueryIprpcProviderRewardRequest) ProtoMessage() {} +func (*QueryIprpcProviderRewardRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_15bce9a904340007, []int{9} +} +func (m *QueryIprpcProviderRewardRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryIprpcProviderRewardRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryIprpcProviderRewardRequest.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 *QueryIprpcProviderRewardRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIprpcProviderRewardRequest.Merge(m, src) +} +func (m *QueryIprpcProviderRewardRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryIprpcProviderRewardRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIprpcProviderRewardRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryIprpcProviderRewardRequest proto.InternalMessageInfo + +func (m *QueryIprpcProviderRewardRequest) GetProvider() string { + if m != nil { + return m.Provider + } + return "" +} + +// QueryIprpcProviderRewardResponse is response type for the Query/IprpcProviderReward RPC method. +type QueryIprpcProviderRewardResponse struct { + SpecFunds []Specfund `protobuf:"bytes,1,rep,name=spec_funds,json=specFunds,proto3" json:"spec_funds"` +} + +func (m *QueryIprpcProviderRewardResponse) Reset() { *m = QueryIprpcProviderRewardResponse{} } +func (m *QueryIprpcProviderRewardResponse) String() string { return proto.CompactTextString(m) } +func (*QueryIprpcProviderRewardResponse) ProtoMessage() {} +func (*QueryIprpcProviderRewardResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_15bce9a904340007, []int{10} +} +func (m *QueryIprpcProviderRewardResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryIprpcProviderRewardResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryIprpcProviderRewardResponse.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 *QueryIprpcProviderRewardResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIprpcProviderRewardResponse.Merge(m, src) +} +func (m *QueryIprpcProviderRewardResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryIprpcProviderRewardResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIprpcProviderRewardResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryIprpcProviderRewardResponse proto.InternalMessageInfo + +func (m *QueryIprpcProviderRewardResponse) GetSpecFunds() []Specfund { + if m != nil { + return m.SpecFunds + } + return nil +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "lavanet.lava.rewards.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "lavanet.lava.rewards.QueryParamsResponse") @@ -456,57 +546,66 @@ func init() { proto.RegisterType((*QueryBlockRewardResponse)(nil), "lavanet.lava.rewards.QueryBlockRewardResponse") proto.RegisterType((*QueryShowIprpcDataRequest)(nil), "lavanet.lava.rewards.QueryShowIprpcDataRequest") proto.RegisterType((*QueryShowIprpcDataResponse)(nil), "lavanet.lava.rewards.QueryShowIprpcDataResponse") + proto.RegisterType((*QueryIprpcProviderRewardRequest)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardRequest") + proto.RegisterType((*QueryIprpcProviderRewardResponse)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardResponse") } func init() { proto.RegisterFile("lavanet/lava/rewards/query.proto", fileDescriptor_15bce9a904340007) } var fileDescriptor_15bce9a904340007 = []byte{ - // 718 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xc1, 0x4f, 0x13, 0x4f, - 0x18, 0xed, 0x42, 0x29, 0x30, 0xfc, 0x7e, 0x26, 0x0e, 0x24, 0x94, 0x05, 0x97, 0xba, 0x62, 0xa8, - 0x24, 0xec, 0x00, 0x1e, 0x4c, 0x34, 0x1e, 0x2c, 0x5e, 0x48, 0x34, 0x91, 0xc5, 0x93, 0x97, 0xcd, - 0xec, 0x76, 0xda, 0x6e, 0xd8, 0xdd, 0x59, 0x76, 0xa6, 0x20, 0x27, 0x13, 0x8d, 0x07, 0x6f, 0x26, - 0x5e, 0xbc, 0x7a, 0xf5, 0x2f, 0xe1, 0x62, 0x42, 0xe2, 0xc5, 0x93, 0x1a, 0xf0, 0x2f, 0xf0, 0x2f, - 0x30, 0xfb, 0xcd, 0xb4, 0x96, 0xb0, 0xd4, 0x9e, 0xa6, 0x9d, 0x79, 0xdf, 0xfb, 0xde, 0xdb, 0x79, - 0xdf, 0xa0, 0x5a, 0x44, 0x0f, 0x69, 0xc2, 0x24, 0xc9, 0x57, 0x92, 0xb1, 0x23, 0x9a, 0x35, 0x05, - 0x39, 0xe8, 0xb2, 0xec, 0xd8, 0x49, 0x33, 0x2e, 0x39, 0x9e, 0xd3, 0x08, 0x27, 0x5f, 0x1d, 0x8d, - 0x30, 0xe7, 0xda, 0xbc, 0xcd, 0x01, 0x40, 0xf2, 0x5f, 0x0a, 0x6b, 0x2e, 0xb5, 0x39, 0x6f, 0x47, - 0x8c, 0xd0, 0x34, 0x24, 0x34, 0x49, 0xb8, 0xa4, 0x32, 0xe4, 0x89, 0xd0, 0xa7, 0x6b, 0x01, 0x17, - 0x31, 0x17, 0xc4, 0xa7, 0x82, 0xa9, 0x16, 0xe4, 0x70, 0xd3, 0x67, 0x92, 0x6e, 0x92, 0x94, 0xb6, - 0xc3, 0x04, 0xc0, 0x1a, 0x7b, 0xb3, 0x50, 0x57, 0x4a, 0x33, 0x1a, 0xf7, 0xe8, 0xac, 0x41, 0xba, - 0x1e, 0x51, 0xc0, 0x43, 0x4d, 0x61, 0xcf, 0x21, 0xbc, 0x9b, 0x37, 0x79, 0x06, 0x45, 0x2e, 0x3b, - 0xe8, 0x32, 0x21, 0xed, 0x5d, 0x34, 0x7b, 0x61, 0x57, 0xa4, 0x3c, 0x11, 0x0c, 0xdf, 0x47, 0x15, - 0x45, 0x5e, 0x35, 0x6a, 0x46, 0x7d, 0x66, 0x6b, 0xc9, 0x29, 0xb2, 0xed, 0xa8, 0xaa, 0x46, 0xf9, - 0xe4, 0xfb, 0x72, 0xc9, 0xd5, 0x15, 0xf6, 0x2c, 0xba, 0xae, 0x28, 0x39, 0x8f, 0xfa, 0x7d, 0xde, - 0x1a, 0x68, 0x2a, 0xdf, 0xd8, 0x49, 0x5a, 0x1c, 0x63, 0x54, 0x4e, 0x68, 0xcc, 0x80, 0x7b, 0xda, - 0x85, 0xdf, 0x98, 0xa1, 0x49, 0x9f, 0x46, 0x34, 0x09, 0x58, 0x75, 0xac, 0x36, 0x5e, 0x9f, 0xd9, - 0x5a, 0x70, 0x94, 0x21, 0x27, 0x37, 0xe4, 0x68, 0x43, 0xce, 0x36, 0x0f, 0x93, 0xc6, 0x46, 0xde, - 0xef, 0xf3, 0x8f, 0xe5, 0x7a, 0x3b, 0x94, 0x9d, 0xae, 0xef, 0x04, 0x3c, 0x26, 0xda, 0xbd, 0x5a, - 0xd6, 0x45, 0x73, 0x9f, 0xc8, 0xe3, 0x94, 0x09, 0x28, 0x10, 0x6e, 0x8f, 0xdb, 0xfe, 0x6d, 0xf4, - 0x3e, 0x83, 0x52, 0xd7, 0xf7, 0x3b, 0x91, 0xe6, 0x1b, 0x55, 0x03, 0x7a, 0x5b, 0x57, 0xd8, 0xd5, - 0x06, 0xb4, 0x61, 0x55, 0x82, 0x57, 0xd0, 0x35, 0x19, 0xc6, 0xcc, 0x93, 0xdc, 0xcb, 0x58, 0x2b, - 0x8c, 0xa2, 0xea, 0x58, 0xcd, 0xa8, 0x8f, 0xbb, 0xff, 0xe5, 0xbb, 0xcf, 0xb9, 0x0b, 0x7b, 0xf8, - 0x01, 0x32, 0x99, 0x90, 0x61, 0x4c, 0x25, 0x6b, 0x7a, 0x7e, 0xc4, 0x83, 0x7d, 0x31, 0x50, 0x31, - 0x0e, 0x15, 0xf3, 0x7d, 0x44, 0x03, 0x00, 0xfd, 0xe2, 0x87, 0x68, 0x91, 0x46, 0x11, 0x0f, 0x20, - 0x12, 0x5e, 0xde, 0xd6, 0x8b, 0x79, 0x22, 0x3b, 0xc2, 0x8b, 0x58, 0x4b, 0x56, 0xcb, 0x50, 0x5d, - 0xfd, 0x0b, 0xc9, 0x85, 0x3e, 0x05, 0xc0, 0x13, 0xd6, 0x92, 0xf6, 0x02, 0x9a, 0x07, 0xcf, 0xc0, - 0xea, 0x82, 0x99, 0xde, 0xbd, 0xec, 0xa1, 0xea, 0xe5, 0x23, 0xfd, 0x51, 0xee, 0xa1, 0x8a, 0x72, - 0xae, 0x43, 0x30, 0xe4, 0x46, 0x74, 0x02, 0x14, 0xdc, 0x5e, 0x44, 0x0b, 0x40, 0xba, 0xd7, 0xe1, - 0x47, 0x3b, 0x69, 0x96, 0x06, 0x8f, 0xa9, 0xa4, 0xbd, 0x8e, 0xef, 0x0c, 0x64, 0x16, 0x9d, 0xf6, - 0x6f, 0x62, 0x2a, 0x0e, 0x13, 0x2f, 0xe0, 0x42, 0x8e, 0xda, 0x76, 0x32, 0x0e, 0x93, 0x6d, 0x2e, - 0x24, 0x26, 0x68, 0x36, 0xcc, 0x09, 0x3d, 0xd1, 0xf5, 0x45, 0x90, 0x85, 0x29, 0x8c, 0x1b, 0xe4, - 0x69, 0xda, 0xc5, 0x70, 0xb4, 0x37, 0x78, 0xb2, 0xf5, 0xa5, 0x8c, 0x26, 0x40, 0x0b, 0x7e, 0x63, - 0xa0, 0x8a, 0x4a, 0x33, 0xae, 0x17, 0x5f, 0xfe, 0xe5, 0xe1, 0x31, 0xef, 0x8c, 0x80, 0x54, 0xb6, - 0xec, 0x95, 0xd7, 0x5f, 0x7f, 0x7d, 0x18, 0xb3, 0xf0, 0x12, 0x19, 0x32, 0xc9, 0xf8, 0x15, 0x9a, - 0x80, 0x5c, 0xe2, 0xd5, 0x61, 0xcc, 0x03, 0x73, 0x65, 0xd6, 0xff, 0x0d, 0xd4, 0x0a, 0x6e, 0x81, - 0x82, 0x1b, 0x78, 0xf1, 0x0a, 0x05, 0xd0, 0xf7, 0xa3, 0x81, 0x66, 0x06, 0xa2, 0x80, 0xd7, 0x87, - 0xd0, 0x5f, 0x4e, 0x93, 0xe9, 0x8c, 0x0a, 0xd7, 0x9a, 0xd6, 0x40, 0xd3, 0x0a, 0xb6, 0x8b, 0x35, - 0xc1, 0x98, 0x78, 0xea, 0x1f, 0xfe, 0x64, 0xa0, 0xff, 0x2f, 0x44, 0x06, 0x93, 0x21, 0xdd, 0x8a, - 0xa2, 0x67, 0x6e, 0x8c, 0x5e, 0xa0, 0x05, 0xae, 0x83, 0xc0, 0x55, 0x7c, 0xbb, 0x58, 0xa0, 0xe8, - 0xf0, 0x23, 0x4f, 0x45, 0xae, 0x49, 0x25, 0x6d, 0x3c, 0x3a, 0x39, 0xb3, 0x8c, 0xd3, 0x33, 0xcb, - 0xf8, 0x79, 0x66, 0x19, 0xef, 0xcf, 0xad, 0xd2, 0xe9, 0xb9, 0x55, 0xfa, 0x76, 0x6e, 0x95, 0x5e, - 0xac, 0x0e, 0x3c, 0x55, 0x17, 0xa8, 0x5e, 0xf6, 0xc9, 0xe0, 0xbd, 0xf2, 0x2b, 0xf0, 0x5a, 0xdf, - 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xce, 0xcd, 0x6c, 0x8a, 0x06, 0x00, 0x00, + // 827 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcf, 0x6f, 0xe3, 0x44, + 0x18, 0x8d, 0xfb, 0x23, 0x6d, 0xa7, 0x80, 0xc4, 0xa4, 0x52, 0x53, 0xb7, 0xb8, 0xc1, 0x14, 0x35, + 0x54, 0xaa, 0xa7, 0x2d, 0xa2, 0x20, 0x50, 0x91, 0x48, 0x11, 0x52, 0x25, 0x90, 0x5a, 0x87, 0x13, + 0x17, 0x6b, 0xe2, 0x4c, 0x12, 0xab, 0xb6, 0xc7, 0xf5, 0x4c, 0x5a, 0x2a, 0x84, 0x90, 0x40, 0x1c, + 0xb8, 0x21, 0xc1, 0x81, 0x2b, 0x57, 0xfe, 0x0e, 0x0e, 0x3d, 0x56, 0xe2, 0xc2, 0x69, 0x77, 0xd5, + 0xee, 0x5f, 0xb0, 0x7f, 0xc1, 0x6a, 0x3e, 0x8f, 0xb3, 0x89, 0xea, 0xa4, 0xd9, 0x93, 0xe3, 0x99, + 0xf7, 0xbe, 0xf7, 0xde, 0xf8, 0xfb, 0x32, 0xa8, 0x16, 0xd2, 0x4b, 0x1a, 0x33, 0x49, 0xd4, 0x93, + 0xa4, 0xec, 0x8a, 0xa6, 0x6d, 0x41, 0x2e, 0xfa, 0x2c, 0xbd, 0x76, 0x92, 0x94, 0x4b, 0x8e, 0x57, + 0x34, 0xc2, 0x51, 0x4f, 0x47, 0x23, 0xcc, 0x95, 0x2e, 0xef, 0x72, 0x00, 0x10, 0xf5, 0x2b, 0xc3, + 0x9a, 0x1b, 0x5d, 0xce, 0xbb, 0x21, 0x23, 0x34, 0x09, 0x08, 0x8d, 0x63, 0x2e, 0xa9, 0x0c, 0x78, + 0x2c, 0xf4, 0xee, 0x8e, 0xcf, 0x45, 0xc4, 0x05, 0x69, 0x51, 0xc1, 0x32, 0x09, 0x72, 0xb9, 0xdf, + 0x62, 0x92, 0xee, 0x93, 0x84, 0x76, 0x83, 0x18, 0xc0, 0x1a, 0xfb, 0x6e, 0xa1, 0xaf, 0x84, 0xa6, + 0x34, 0xca, 0xcb, 0x15, 0x5b, 0x0f, 0x92, 0x34, 0xf1, 0x35, 0xc2, 0x1a, 0x16, 0xcc, 0xa5, 0x7c, + 0x1e, 0x68, 0x11, 0x7b, 0x05, 0xe1, 0x33, 0x65, 0xe3, 0x14, 0xca, 0xba, 0xec, 0xa2, 0xcf, 0x84, + 0xb4, 0xcf, 0x50, 0x65, 0x64, 0x55, 0x24, 0x3c, 0x16, 0x0c, 0x7f, 0x8a, 0xca, 0x99, 0x7c, 0xd5, + 0xa8, 0x19, 0xf5, 0xe5, 0x83, 0x0d, 0xa7, 0xe8, 0x60, 0x9c, 0x8c, 0xd5, 0x98, 0xbb, 0x79, 0xb2, + 0x59, 0x72, 0x35, 0xc3, 0xae, 0xa0, 0xb7, 0xb3, 0x92, 0x9c, 0x87, 0x03, 0x9d, 0x5f, 0x0d, 0xb4, + 0xa8, 0x16, 0x4e, 0xe2, 0x0e, 0xc7, 0x18, 0xcd, 0xc5, 0x34, 0x62, 0x50, 0x7b, 0xc9, 0x85, 0xdf, + 0x98, 0xa1, 0x85, 0x16, 0x0d, 0x69, 0xec, 0xb3, 0xea, 0x4c, 0x6d, 0xb6, 0xbe, 0x7c, 0xb0, 0xe6, + 0x64, 0x81, 0x1c, 0x15, 0xc8, 0xd1, 0x81, 0x9c, 0x63, 0x1e, 0xc4, 0x8d, 0x3d, 0xa5, 0xf7, 0xcf, + 0xd3, 0xcd, 0x7a, 0x37, 0x90, 0xbd, 0x7e, 0xcb, 0xf1, 0x79, 0x44, 0x74, 0xfa, 0xec, 0xb1, 0x2b, + 0xda, 0xe7, 0x44, 0x5e, 0x27, 0x4c, 0x00, 0x41, 0xb8, 0x79, 0x6d, 0xfb, 0x85, 0x91, 0x1f, 0x43, + 0xe6, 0x6e, 0x90, 0x77, 0x3e, 0x51, 0x0b, 0x55, 0x03, 0xb4, 0xad, 0x31, 0x71, 0x75, 0x00, 0x1d, + 0x38, 0xa3, 0xe0, 0x2d, 0xf4, 0x96, 0x0c, 0x22, 0xe6, 0x49, 0xee, 0xa5, 0xac, 0x13, 0x84, 0x61, + 0x75, 0xa6, 0x66, 0xd4, 0x67, 0xdd, 0x37, 0xd4, 0xea, 0xb7, 0xdc, 0x85, 0x35, 0xfc, 0x19, 0x32, + 0x99, 0x90, 0x41, 0x44, 0x25, 0x6b, 0x7b, 0xad, 0x90, 0xfb, 0xe7, 0x62, 0x88, 0x31, 0x0b, 0x8c, + 0xd5, 0x01, 0xa2, 0x01, 0x80, 0x01, 0xf9, 0x08, 0xad, 0xd3, 0x30, 0xe4, 0x3e, 0x34, 0x8d, 0xa7, + 0x64, 0xbd, 0x88, 0xc7, 0xb2, 0x27, 0xbc, 0x90, 0x75, 0x64, 0x75, 0x0e, 0xd8, 0xd5, 0x57, 0x10, + 0x65, 0xf4, 0x1b, 0x00, 0x7c, 0xcd, 0x3a, 0xd2, 0x5e, 0x43, 0xab, 0x90, 0x19, 0xaa, 0xba, 0x10, + 0x26, 0xff, 0x2e, 0x4d, 0x54, 0x7d, 0xb8, 0xa5, 0x0f, 0xe5, 0x63, 0x54, 0xce, 0x92, 0xeb, 0x26, + 0x98, 0xf0, 0x45, 0x74, 0x07, 0x64, 0x70, 0x7b, 0x1d, 0xad, 0x41, 0xd1, 0x66, 0x8f, 0x5f, 0x9d, + 0xa8, 0x16, 0xfd, 0x92, 0x4a, 0x9a, 0x2b, 0xfe, 0x66, 0x20, 0xb3, 0x68, 0x77, 0xf0, 0x25, 0x16, + 0xa3, 0x20, 0xf6, 0x7c, 0x2e, 0xe4, 0xb4, 0xb2, 0x0b, 0x51, 0x10, 0x1f, 0x73, 0x21, 0x31, 0x41, + 0x15, 0x98, 0x08, 0x4f, 0xf4, 0x5b, 0xc2, 0x4f, 0x83, 0x04, 0x06, 0x12, 0xfa, 0x69, 0xc9, 0xc5, + 0xb0, 0xd5, 0x1c, 0xde, 0xb1, 0x8f, 0xd0, 0x26, 0x58, 0x01, 0x1b, 0xa7, 0x29, 0xbf, 0x0c, 0xda, + 0x2c, 0x1d, 0x39, 0x20, 0x6c, 0xa2, 0xc5, 0x44, 0x6f, 0xe8, 0x7e, 0x1d, 0xbc, 0xdb, 0x5d, 0x54, + 0x1b, 0x4f, 0xd7, 0x79, 0x8e, 0x11, 0x12, 0x09, 0xf3, 0xbd, 0x4e, 0x3f, 0x6e, 0x3f, 0xd2, 0x5e, + 0xcd, 0x84, 0xf9, 0x0a, 0xa6, 0x63, 0x2d, 0x29, 0xde, 0x57, 0x8a, 0x76, 0xf0, 0x67, 0x19, 0xcd, + 0x83, 0x12, 0xfe, 0xc5, 0x40, 0xe5, 0x6c, 0xea, 0x70, 0xbd, 0xb8, 0xca, 0xc3, 0x21, 0x37, 0x3f, + 0x98, 0x02, 0x99, 0xd9, 0xb5, 0xb7, 0x7e, 0xfe, 0xef, 0xf9, 0x1f, 0x33, 0x16, 0xde, 0x20, 0x13, + 0xfe, 0x93, 0xf0, 0x4f, 0x68, 0x1e, 0xe6, 0x07, 0x6f, 0x4f, 0xaa, 0x3c, 0x34, 0xff, 0x66, 0xfd, + 0x71, 0xa0, 0x76, 0xf0, 0x1e, 0x38, 0x78, 0x07, 0xaf, 0x8f, 0x71, 0x00, 0xba, 0x7f, 0x19, 0x68, + 0x79, 0xa8, 0x65, 0xf1, 0xee, 0x84, 0xf2, 0x0f, 0xbb, 0xde, 0x74, 0xa6, 0x85, 0x6b, 0x4f, 0x3b, + 0xe0, 0x69, 0x0b, 0xdb, 0xc5, 0x9e, 0x60, 0x9c, 0xbd, 0xec, 0x0d, 0xff, 0x6d, 0xa0, 0x37, 0x47, + 0x5a, 0x1b, 0x93, 0x09, 0x6a, 0x45, 0x23, 0x62, 0xee, 0x4d, 0x4f, 0xd0, 0x06, 0x77, 0xc1, 0xe0, + 0x36, 0x7e, 0xbf, 0xd8, 0xa0, 0xe8, 0xf1, 0x2b, 0x2f, 0x1b, 0x8d, 0xb6, 0x72, 0xf4, 0xaf, 0x81, + 0x2a, 0x05, 0x4d, 0x8b, 0x3f, 0x9a, 0x20, 0x3c, 0x7e, 0x46, 0xcc, 0xc3, 0xd7, 0xa5, 0x69, 0xd7, + 0x9f, 0x83, 0xeb, 0x4f, 0xf0, 0x21, 0x19, 0x7f, 0xbb, 0x79, 0xf9, 0xb4, 0xe9, 0xf3, 0x25, 0x3f, + 0xe4, 0x0b, 0x3f, 0x36, 0xbe, 0xb8, 0xb9, 0xb3, 0x8c, 0xdb, 0x3b, 0xcb, 0x78, 0x76, 0x67, 0x19, + 0xbf, 0xdf, 0x5b, 0xa5, 0xdb, 0x7b, 0xab, 0xf4, 0xff, 0xbd, 0x55, 0xfa, 0x6e, 0x7b, 0xe8, 0x66, + 0x18, 0xa9, 0xfd, 0xfd, 0xa0, 0x3a, 0x5c, 0x0f, 0xad, 0x32, 0x5c, 0x8e, 0x1f, 0xbe, 0x0c, 0x00, + 0x00, 0xff, 0xff, 0x22, 0x23, 0xbb, 0x03, 0x1b, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -529,6 +628,8 @@ type QueryClient interface { BlockReward(ctx context.Context, in *QueryBlockRewardRequest, opts ...grpc.CallOption) (*QueryBlockRewardResponse, error) // ShowIprpcData queries for the iprpc data ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataRequest, opts ...grpc.CallOption) (*QueryShowIprpcDataResponse, error) + // ShowIprpcData queries for the iprpc data + IprpcProviderReward(ctx context.Context, in *QueryIprpcProviderRewardRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardResponse, error) } type queryClient struct { @@ -575,6 +676,15 @@ func (c *queryClient) ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataR return out, nil } +func (c *queryClient) IprpcProviderReward(ctx context.Context, in *QueryIprpcProviderRewardRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardResponse, error) { + out := new(QueryIprpcProviderRewardResponse) + err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Query/IprpcProviderReward", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Parameters queries the parameters of the module. @@ -585,6 +695,8 @@ type QueryServer interface { BlockReward(context.Context, *QueryBlockRewardRequest) (*QueryBlockRewardResponse, error) // ShowIprpcData queries for the iprpc data ShowIprpcData(context.Context, *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) + // ShowIprpcData queries for the iprpc data + IprpcProviderReward(context.Context, *QueryIprpcProviderRewardRequest) (*QueryIprpcProviderRewardResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -603,6 +715,9 @@ func (*UnimplementedQueryServer) BlockReward(ctx context.Context, req *QueryBloc func (*UnimplementedQueryServer) ShowIprpcData(ctx context.Context, req *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ShowIprpcData not implemented") } +func (*UnimplementedQueryServer) IprpcProviderReward(ctx context.Context, req *QueryIprpcProviderRewardRequest) (*QueryIprpcProviderRewardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IprpcProviderReward not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -680,6 +795,24 @@ func _Query_ShowIprpcData_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Query_IprpcProviderReward_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryIprpcProviderRewardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).IprpcProviderReward(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/lavanet.lava.rewards.Query/IprpcProviderReward", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).IprpcProviderReward(ctx, req.(*QueryIprpcProviderRewardRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "lavanet.lava.rewards.Query", HandlerType: (*QueryServer)(nil), @@ -700,6 +833,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ShowIprpcData", Handler: _Query_ShowIprpcData_Handler, }, + { + MethodName: "IprpcProviderReward", + Handler: _Query_IprpcProviderReward_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "lavanet/lava/rewards/query.proto", @@ -1001,6 +1138,73 @@ func (m *QueryShowIprpcDataResponse) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *QueryIprpcProviderRewardRequest) 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 *QueryIprpcProviderRewardRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryIprpcProviderRewardRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Provider) > 0 { + i -= len(m.Provider) + copy(dAtA[i:], m.Provider) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Provider))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryIprpcProviderRewardResponse) 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 *QueryIprpcProviderRewardResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryIprpcProviderRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SpecFunds) > 0 { + for iNdEx := len(m.SpecFunds) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SpecFunds[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 @@ -1130,6 +1334,34 @@ func (m *QueryShowIprpcDataResponse) Size() (n int) { return n } +func (m *QueryIprpcProviderRewardRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Provider) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryIprpcProviderRewardResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.SpecFunds) > 0 { + for _, e := range m.SpecFunds { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1874,6 +2106,172 @@ func (m *QueryShowIprpcDataResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryIprpcProviderRewardRequest) 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: QueryIprpcProviderRewardRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryIprpcProviderRewardRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Provider", 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.Provider = 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 *QueryIprpcProviderRewardResponse) 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: QueryIprpcProviderRewardResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryIprpcProviderRewardResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpecFunds", 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.SpecFunds = append(m.SpecFunds, Specfund{}) + if err := m.SpecFunds[len(m.SpecFunds)-1].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 diff --git a/x/rewards/types/query.pb.gw.go b/x/rewards/types/query.pb.gw.go index 946b59839e..7e0cc7f2c8 100644 --- a/x/rewards/types/query.pb.gw.go +++ b/x/rewards/types/query.pb.gw.go @@ -105,6 +105,60 @@ func local_request_Query_ShowIprpcData_0(ctx context.Context, marshaler runtime. } +func request_Query_IprpcProviderReward_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIprpcProviderRewardRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["provider"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "provider") + } + + protoReq.Provider, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider", err) + } + + msg, err := client.IprpcProviderReward(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_IprpcProviderReward_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIprpcProviderRewardRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["provider"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "provider") + } + + protoReq.Provider, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider", err) + } + + msg, err := server.IprpcProviderReward(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. @@ -203,6 +257,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_IprpcProviderReward_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_IprpcProviderReward_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_IprpcProviderReward_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -324,6 +401,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_IprpcProviderReward_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_IprpcProviderReward_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_IprpcProviderReward_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -335,6 +432,8 @@ var ( pattern_Query_BlockReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "block_reward"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ShowIprpcData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "show_iprpc_data"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_IprpcProviderReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"lavanet", "lava", "rewards", "iprpc_provider_reward", "provider"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -345,4 +444,6 @@ var ( forward_Query_BlockReward_0 = runtime.ForwardResponseMessage forward_Query_ShowIprpcData_0 = runtime.ForwardResponseMessage + + forward_Query_IprpcProviderReward_0 = runtime.ForwardResponseMessage ) From fa40bcf5b66c0124108b6be90375946414fc7bba Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 11:38:36 +0200 Subject: [PATCH 22/64] CNS-871: fix query client context in all queries --- x/pairing/client/cli/query_effective_policy.go | 2 +- x/rewards/client/cli/query_block_reward.go | 2 +- x/rewards/client/cli/query_params.go | 6 ++++-- x/rewards/client/cli/query_pools.go | 2 +- x/rewards/client/cli/query_show_iprpc_data.go | 2 +- x/rewards/keeper/iprpc_data_test.go | 2 +- x/subscription/client/cli/query_list.go | 2 +- x/subscription/client/cli/query_list_projects.go | 2 +- x/subscription/client/cli/query_next_to_month_expiry.go | 2 +- 9 files changed, 12 insertions(+), 10 deletions(-) diff --git a/x/pairing/client/cli/query_effective_policy.go b/x/pairing/client/cli/query_effective_policy.go index 74a4dad791..b772915ead 100644 --- a/x/pairing/client/cli/query_effective_policy.go +++ b/x/pairing/client/cli/query_effective_policy.go @@ -21,7 +21,7 @@ func CmdEffectivePolicy() *cobra.Command { if len(args) > 1 { address = args[1] } else { - clientCtxForTx, err := client.GetClientTxContext(cmd) + clientCtxForTx, err := client.GetClientQueryContext(cmd) if err != nil { return err } diff --git a/x/rewards/client/cli/query_block_reward.go b/x/rewards/client/cli/query_block_reward.go index 12d7dbece9..55957e4dd0 100644 --- a/x/rewards/client/cli/query_block_reward.go +++ b/x/rewards/client/cli/query_block_reward.go @@ -17,7 +17,7 @@ func CmdQueryBlockReward() *cobra.Command { Short: "Query for amount of validator rewards for proposing a block", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } diff --git a/x/rewards/client/cli/query_params.go b/x/rewards/client/cli/query_params.go index 29c8fdf565..7efc38eb5a 100644 --- a/x/rewards/client/cli/query_params.go +++ b/x/rewards/client/cli/query_params.go @@ -15,8 +15,10 @@ func CmdQueryParams() *cobra.Command { Short: "shows the parameters of the module", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } queryClient := types.NewQueryClient(clientCtx) res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) diff --git a/x/rewards/client/cli/query_pools.go b/x/rewards/client/cli/query_pools.go index 7a2c7a25eb..9911dc7272 100644 --- a/x/rewards/client/cli/query_pools.go +++ b/x/rewards/client/cli/query_pools.go @@ -17,7 +17,7 @@ func CmdQueryPools() *cobra.Command { Short: "Query for validators and providers rewards pools information", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } diff --git a/x/rewards/client/cli/query_show_iprpc_data.go b/x/rewards/client/cli/query_show_iprpc_data.go index 4448e42323..c07c4a25bf 100644 --- a/x/rewards/client/cli/query_show_iprpc_data.go +++ b/x/rewards/client/cli/query_show_iprpc_data.go @@ -17,7 +17,7 @@ func CmdQueryShowIprpcData() *cobra.Command { Short: "Query for IPRPC data: min cost and IPRPC eligible subscriptions", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } diff --git a/x/rewards/keeper/iprpc_data_test.go b/x/rewards/keeper/iprpc_data_test.go index 330cb09879..f88cb59fbd 100644 --- a/x/rewards/keeper/iprpc_data_test.go +++ b/x/rewards/keeper/iprpc_data_test.go @@ -112,7 +112,7 @@ func TestIprpcDataValidation(t *testing.T) { _, err := ts.TxRewardsSetIprpcDataProposal(ts.Ctx, tt.authority, tt.cost, tt.subs) if tt.success { require.NoError(t, err) - res, err := ts.QueryShowIprpcData() + res, err := ts.QueryRewardsShowIprpcData() require.NoError(t, err) require.True(t, tt.cost.IsEqual(res.MinCost)) require.Equal(t, tt.subs, res.IprpcSubscriptions) diff --git a/x/subscription/client/cli/query_list.go b/x/subscription/client/cli/query_list.go index c60b5f03c3..6311b55f74 100644 --- a/x/subscription/client/cli/query_list.go +++ b/x/subscription/client/cli/query_list.go @@ -17,7 +17,7 @@ func CmdList() *cobra.Command { Short: "Query all current subscriptions", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } diff --git a/x/subscription/client/cli/query_list_projects.go b/x/subscription/client/cli/query_list_projects.go index 543ce42a08..b25ff1f3a8 100644 --- a/x/subscription/client/cli/query_list_projects.go +++ b/x/subscription/client/cli/query_list_projects.go @@ -19,7 +19,7 @@ func CmdListProjects() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) (err error) { reqSubscription := args[0] - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } diff --git a/x/subscription/client/cli/query_next_to_month_expiry.go b/x/subscription/client/cli/query_next_to_month_expiry.go index a8b99c110e..50a0143b30 100644 --- a/x/subscription/client/cli/query_next_to_month_expiry.go +++ b/x/subscription/client/cli/query_next_to_month_expiry.go @@ -17,7 +17,7 @@ func CmdNextToMonthExpiry() *cobra.Command { Short: "Query the subscriptions with the closest month expiry", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } From 754e215188fee5364ff1328e9afaaf8bc9340aad Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 11:57:26 +0200 Subject: [PATCH 23/64] CNS-871: scaffold query iprpc spec rewards --- proto/lavanet/lava/rewards/query.proto | 18 +- scripts/cli_test.sh | 1 + testutil/common/tester.go | 7 + x/rewards/client/cli/query.go | 1 + .../client/cli/query_iprpc_spec_reward.go | 48 ++ .../keeper/grpc_query_iprpc_spec_reward.go | 37 ++ x/rewards/types/query.pb.go | 543 ++++++++++++++++-- x/rewards/types/query.pb.gw.go | 101 ++++ 8 files changed, 700 insertions(+), 56 deletions(-) create mode 100644 x/rewards/client/cli/query_iprpc_spec_reward.go create mode 100644 x/rewards/keeper/grpc_query_iprpc_spec_reward.go diff --git a/proto/lavanet/lava/rewards/query.proto b/proto/lavanet/lava/rewards/query.proto index 8f3bab30ef..d4c6d9e89f 100644 --- a/proto/lavanet/lava/rewards/query.proto +++ b/proto/lavanet/lava/rewards/query.proto @@ -33,10 +33,15 @@ service Query { option (google.api.http).get = "/lavanet/lava/rewards/show_iprpc_data"; } - // ShowIprpcData queries for the iprpc data + // IprpcProviderReward queries for a provider's current IPRPC reward (relative to its serviced CU) rpc IprpcProviderReward(QueryIprpcProviderRewardRequest) returns (QueryIprpcProviderRewardResponse) { option (google.api.http).get = "/lavanet/lava/rewards/iprpc_provider_reward/{provider}"; } + + // IprpcSpecReward queries for a spec's IPRPC reward + rpc IprpcSpecReward(QueryIprpcSpecRewardRequest) returns (QueryIprpcSpecRewardResponse) { + option (google.api.http).get = "/lavanet/lava/rewards/iprpc_spec_reward/{spec}"; + } // this line is used by starport scaffolding # 2 } @@ -96,4 +101,15 @@ message QueryIprpcProviderRewardResponse { repeated Specfund spec_funds = 1 [(gogoproto.nullable) = false]; } +// QueryIprpcSpecRewardRequest is request type for the Query/IprpcSpecReward RPC method. +message QueryIprpcSpecRewardRequest { + string spec = 1; +} + +// QueryIprpcSpecRewardResponse is response type for the Query/IprpcSpecReward RPC method. +message QueryIprpcSpecRewardResponse { + repeated IprpcReward iprpc_rewards = 1 [(gogoproto.nullable) = false]; + uint64 current_month_id = 2; +} + // this line is used by starport scaffolding # 3 \ No newline at end of file diff --git a/scripts/cli_test.sh b/scripts/cli_test.sh index 9ccd352adb..b14d7d6052 100755 --- a/scripts/cli_test.sh +++ b/scripts/cli_test.sh @@ -184,6 +184,7 @@ trace lavad q rewards pools >/dev/null trace lavad q rewards block-reward >/dev/null trace lavad q rewards show-iprpc-data > /dev/null trace lavad q rewards iprpc-provider-reward > /dev/null +trace lavad q rewards iprpc-spec-reward > /dev/null echo "Testing events command" trace lavad test events 30 10 --event lava_relay_payment --from alice --timeout 1s >/dev/null diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 6e0f63232b..8b0f5807a3 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -871,6 +871,13 @@ func (ts *Tester) QueryRewardsIprpcProviderReward(provider string) (*rewardstype return ts.Keepers.Rewards.IprpcProviderReward(ts.GoCtx, msg) } +func (ts *Tester) QueryRewardsIprpcSpecReward(spec string) (*rewardstypes.QueryIprpcSpecRewardResponse, error) { + msg := &rewardstypes.QueryIprpcSpecRewardRequest{ + Spec: spec, + } + return ts.Keepers.Rewards.IprpcSpecReward(ts.GoCtx, msg) +} + // block/epoch helpers func (ts *Tester) BlockHeight() uint64 { diff --git a/x/rewards/client/cli/query.go b/x/rewards/client/cli/query.go index 0f9627ec93..b68b7c316c 100644 --- a/x/rewards/client/cli/query.go +++ b/x/rewards/client/cli/query.go @@ -29,6 +29,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdQueryBlockReward()) cmd.AddCommand(CmdQueryShowIprpcData()) cmd.AddCommand(CmdQueryIprpcProviderReward()) + cmd.AddCommand(CmdQueryIprpcSpecReward()) // this line is used by starport scaffolding # 1 return cmd diff --git a/x/rewards/client/cli/query_iprpc_spec_reward.go b/x/rewards/client/cli/query_iprpc_spec_reward.go new file mode 100644 index 0000000000..f10ccdaddf --- /dev/null +++ b/x/rewards/client/cli/query_iprpc_spec_reward.go @@ -0,0 +1,48 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/lavanet/lava/x/rewards/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdQueryIprpcSpecReward() *cobra.Command { + cmd := &cobra.Command{ + Use: "iprpc-spec-reward {spec}", + Short: "Query for IPRPC rewards for a specific spec. If no spec is given, all IPRPC rewards will be shown", + Args: cobra.RangeArgs(0, 1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + var spec string + if len(args) > 0 { + spec = args[0] + } + + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryIprpcSpecRewardRequest{ + Spec: spec, + } + + res, err := queryClient.IprpcSpecReward(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/rewards/keeper/grpc_query_iprpc_spec_reward.go b/x/rewards/keeper/grpc_query_iprpc_spec_reward.go new file mode 100644 index 0000000000..c3ad6acaea --- /dev/null +++ b/x/rewards/keeper/grpc_query_iprpc_spec_reward.go @@ -0,0 +1,37 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/rewards/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k Keeper) IprpcSpecReward(goCtx context.Context, req *types.QueryIprpcSpecRewardRequest) (*types.QueryIprpcSpecRewardResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + iprpcRewards := k.GetAllIprpcReward(ctx) + currentMonthId := k.GetIprpcRewardsCurrent(ctx) + + if req.Spec == "" { + return &types.QueryIprpcSpecRewardResponse{IprpcRewards: iprpcRewards, CurrentMonthId: currentMonthId}, nil + } + + specIprpcRewards := []types.IprpcReward{} + for _, iprpcReward := range iprpcRewards { + for _, specFund := range iprpcReward.SpecFunds { + if specFund.Spec == req.Spec { + specIprpcReward := types.IprpcReward{Id: iprpcReward.Id, SpecFunds: []types.Specfund{specFund}} + specIprpcRewards = append(specIprpcRewards, specIprpcReward) + break + } + } + } + + return &types.QueryIprpcSpecRewardResponse{IprpcRewards: specIprpcRewards, CurrentMonthId: currentMonthId}, nil +} diff --git a/x/rewards/types/query.pb.go b/x/rewards/types/query.pb.go index 4b720bf75f..d404dd214a 100644 --- a/x/rewards/types/query.pb.go +++ b/x/rewards/types/query.pb.go @@ -536,6 +536,104 @@ func (m *QueryIprpcProviderRewardResponse) GetSpecFunds() []Specfund { return nil } +// QueryIprpcSpecRewardRequest is request type for the Query/IprpcSpecReward RPC method. +type QueryIprpcSpecRewardRequest struct { + Spec string `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (m *QueryIprpcSpecRewardRequest) Reset() { *m = QueryIprpcSpecRewardRequest{} } +func (m *QueryIprpcSpecRewardRequest) String() string { return proto.CompactTextString(m) } +func (*QueryIprpcSpecRewardRequest) ProtoMessage() {} +func (*QueryIprpcSpecRewardRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_15bce9a904340007, []int{11} +} +func (m *QueryIprpcSpecRewardRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryIprpcSpecRewardRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryIprpcSpecRewardRequest.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 *QueryIprpcSpecRewardRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIprpcSpecRewardRequest.Merge(m, src) +} +func (m *QueryIprpcSpecRewardRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryIprpcSpecRewardRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIprpcSpecRewardRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryIprpcSpecRewardRequest proto.InternalMessageInfo + +func (m *QueryIprpcSpecRewardRequest) GetSpec() string { + if m != nil { + return m.Spec + } + return "" +} + +// QueryIprpcSpecRewardResponse is response type for the Query/IprpcSpecReward RPC method. +type QueryIprpcSpecRewardResponse struct { + IprpcRewards []IprpcReward `protobuf:"bytes,1,rep,name=iprpc_rewards,json=iprpcRewards,proto3" json:"iprpc_rewards"` + CurrentMonthId uint64 `protobuf:"varint,2,opt,name=current_month_id,json=currentMonthId,proto3" json:"current_month_id,omitempty"` +} + +func (m *QueryIprpcSpecRewardResponse) Reset() { *m = QueryIprpcSpecRewardResponse{} } +func (m *QueryIprpcSpecRewardResponse) String() string { return proto.CompactTextString(m) } +func (*QueryIprpcSpecRewardResponse) ProtoMessage() {} +func (*QueryIprpcSpecRewardResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_15bce9a904340007, []int{12} +} +func (m *QueryIprpcSpecRewardResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryIprpcSpecRewardResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryIprpcSpecRewardResponse.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 *QueryIprpcSpecRewardResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIprpcSpecRewardResponse.Merge(m, src) +} +func (m *QueryIprpcSpecRewardResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryIprpcSpecRewardResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIprpcSpecRewardResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryIprpcSpecRewardResponse proto.InternalMessageInfo + +func (m *QueryIprpcSpecRewardResponse) GetIprpcRewards() []IprpcReward { + if m != nil { + return m.IprpcRewards + } + return nil +} + +func (m *QueryIprpcSpecRewardResponse) GetCurrentMonthId() uint64 { + if m != nil { + return m.CurrentMonthId + } + return 0 +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "lavanet.lava.rewards.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "lavanet.lava.rewards.QueryParamsResponse") @@ -548,64 +646,73 @@ func init() { proto.RegisterType((*QueryShowIprpcDataResponse)(nil), "lavanet.lava.rewards.QueryShowIprpcDataResponse") proto.RegisterType((*QueryIprpcProviderRewardRequest)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardRequest") proto.RegisterType((*QueryIprpcProviderRewardResponse)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardResponse") + proto.RegisterType((*QueryIprpcSpecRewardRequest)(nil), "lavanet.lava.rewards.QueryIprpcSpecRewardRequest") + proto.RegisterType((*QueryIprpcSpecRewardResponse)(nil), "lavanet.lava.rewards.QueryIprpcSpecRewardResponse") } func init() { proto.RegisterFile("lavanet/lava/rewards/query.proto", fileDescriptor_15bce9a904340007) } var fileDescriptor_15bce9a904340007 = []byte{ - // 827 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcf, 0x6f, 0xe3, 0x44, - 0x18, 0x8d, 0xfb, 0x23, 0x6d, 0xa7, 0x80, 0xc4, 0xa4, 0x52, 0x53, 0xb7, 0xb8, 0xc1, 0x14, 0x35, - 0x54, 0xaa, 0xa7, 0x2d, 0xa2, 0x20, 0x50, 0x91, 0x48, 0x11, 0x52, 0x25, 0x90, 0x5a, 0x87, 0x13, - 0x17, 0x6b, 0xe2, 0x4c, 0x12, 0xab, 0xb6, 0xc7, 0xf5, 0x4c, 0x5a, 0x2a, 0x84, 0x90, 0x40, 0x1c, - 0xb8, 0x21, 0xc1, 0x81, 0x2b, 0x57, 0xfe, 0x0e, 0x0e, 0x3d, 0x56, 0xe2, 0xc2, 0x69, 0x77, 0xd5, - 0xee, 0x5f, 0xb0, 0x7f, 0xc1, 0x6a, 0x3e, 0x8f, 0xb3, 0x89, 0xea, 0xa4, 0xd9, 0x93, 0xe3, 0x99, - 0xf7, 0xbe, 0xf7, 0xde, 0xf8, 0xfb, 0x32, 0xa8, 0x16, 0xd2, 0x4b, 0x1a, 0x33, 0x49, 0xd4, 0x93, - 0xa4, 0xec, 0x8a, 0xa6, 0x6d, 0x41, 0x2e, 0xfa, 0x2c, 0xbd, 0x76, 0x92, 0x94, 0x4b, 0x8e, 0x57, - 0x34, 0xc2, 0x51, 0x4f, 0x47, 0x23, 0xcc, 0x95, 0x2e, 0xef, 0x72, 0x00, 0x10, 0xf5, 0x2b, 0xc3, - 0x9a, 0x1b, 0x5d, 0xce, 0xbb, 0x21, 0x23, 0x34, 0x09, 0x08, 0x8d, 0x63, 0x2e, 0xa9, 0x0c, 0x78, - 0x2c, 0xf4, 0xee, 0x8e, 0xcf, 0x45, 0xc4, 0x05, 0x69, 0x51, 0xc1, 0x32, 0x09, 0x72, 0xb9, 0xdf, - 0x62, 0x92, 0xee, 0x93, 0x84, 0x76, 0x83, 0x18, 0xc0, 0x1a, 0xfb, 0x6e, 0xa1, 0xaf, 0x84, 0xa6, - 0x34, 0xca, 0xcb, 0x15, 0x5b, 0x0f, 0x92, 0x34, 0xf1, 0x35, 0xc2, 0x1a, 0x16, 0xcc, 0xa5, 0x7c, - 0x1e, 0x68, 0x11, 0x7b, 0x05, 0xe1, 0x33, 0x65, 0xe3, 0x14, 0xca, 0xba, 0xec, 0xa2, 0xcf, 0x84, - 0xb4, 0xcf, 0x50, 0x65, 0x64, 0x55, 0x24, 0x3c, 0x16, 0x0c, 0x7f, 0x8a, 0xca, 0x99, 0x7c, 0xd5, - 0xa8, 0x19, 0xf5, 0xe5, 0x83, 0x0d, 0xa7, 0xe8, 0x60, 0x9c, 0x8c, 0xd5, 0x98, 0xbb, 0x79, 0xb2, - 0x59, 0x72, 0x35, 0xc3, 0xae, 0xa0, 0xb7, 0xb3, 0x92, 0x9c, 0x87, 0x03, 0x9d, 0x5f, 0x0d, 0xb4, - 0xa8, 0x16, 0x4e, 0xe2, 0x0e, 0xc7, 0x18, 0xcd, 0xc5, 0x34, 0x62, 0x50, 0x7b, 0xc9, 0x85, 0xdf, - 0x98, 0xa1, 0x85, 0x16, 0x0d, 0x69, 0xec, 0xb3, 0xea, 0x4c, 0x6d, 0xb6, 0xbe, 0x7c, 0xb0, 0xe6, - 0x64, 0x81, 0x1c, 0x15, 0xc8, 0xd1, 0x81, 0x9c, 0x63, 0x1e, 0xc4, 0x8d, 0x3d, 0xa5, 0xf7, 0xcf, - 0xd3, 0xcd, 0x7a, 0x37, 0x90, 0xbd, 0x7e, 0xcb, 0xf1, 0x79, 0x44, 0x74, 0xfa, 0xec, 0xb1, 0x2b, - 0xda, 0xe7, 0x44, 0x5e, 0x27, 0x4c, 0x00, 0x41, 0xb8, 0x79, 0x6d, 0xfb, 0x85, 0x91, 0x1f, 0x43, - 0xe6, 0x6e, 0x90, 0x77, 0x3e, 0x51, 0x0b, 0x55, 0x03, 0xb4, 0xad, 0x31, 0x71, 0x75, 0x00, 0x1d, - 0x38, 0xa3, 0xe0, 0x2d, 0xf4, 0x96, 0x0c, 0x22, 0xe6, 0x49, 0xee, 0xa5, 0xac, 0x13, 0x84, 0x61, - 0x75, 0xa6, 0x66, 0xd4, 0x67, 0xdd, 0x37, 0xd4, 0xea, 0xb7, 0xdc, 0x85, 0x35, 0xfc, 0x19, 0x32, - 0x99, 0x90, 0x41, 0x44, 0x25, 0x6b, 0x7b, 0xad, 0x90, 0xfb, 0xe7, 0x62, 0x88, 0x31, 0x0b, 0x8c, - 0xd5, 0x01, 0xa2, 0x01, 0x80, 0x01, 0xf9, 0x08, 0xad, 0xd3, 0x30, 0xe4, 0x3e, 0x34, 0x8d, 0xa7, - 0x64, 0xbd, 0x88, 0xc7, 0xb2, 0x27, 0xbc, 0x90, 0x75, 0x64, 0x75, 0x0e, 0xd8, 0xd5, 0x57, 0x10, - 0x65, 0xf4, 0x1b, 0x00, 0x7c, 0xcd, 0x3a, 0xd2, 0x5e, 0x43, 0xab, 0x90, 0x19, 0xaa, 0xba, 0x10, - 0x26, 0xff, 0x2e, 0x4d, 0x54, 0x7d, 0xb8, 0xa5, 0x0f, 0xe5, 0x63, 0x54, 0xce, 0x92, 0xeb, 0x26, - 0x98, 0xf0, 0x45, 0x74, 0x07, 0x64, 0x70, 0x7b, 0x1d, 0xad, 0x41, 0xd1, 0x66, 0x8f, 0x5f, 0x9d, - 0xa8, 0x16, 0xfd, 0x92, 0x4a, 0x9a, 0x2b, 0xfe, 0x66, 0x20, 0xb3, 0x68, 0x77, 0xf0, 0x25, 0x16, - 0xa3, 0x20, 0xf6, 0x7c, 0x2e, 0xe4, 0xb4, 0xb2, 0x0b, 0x51, 0x10, 0x1f, 0x73, 0x21, 0x31, 0x41, - 0x15, 0x98, 0x08, 0x4f, 0xf4, 0x5b, 0xc2, 0x4f, 0x83, 0x04, 0x06, 0x12, 0xfa, 0x69, 0xc9, 0xc5, - 0xb0, 0xd5, 0x1c, 0xde, 0xb1, 0x8f, 0xd0, 0x26, 0x58, 0x01, 0x1b, 0xa7, 0x29, 0xbf, 0x0c, 0xda, - 0x2c, 0x1d, 0x39, 0x20, 0x6c, 0xa2, 0xc5, 0x44, 0x6f, 0xe8, 0x7e, 0x1d, 0xbc, 0xdb, 0x5d, 0x54, - 0x1b, 0x4f, 0xd7, 0x79, 0x8e, 0x11, 0x12, 0x09, 0xf3, 0xbd, 0x4e, 0x3f, 0x6e, 0x3f, 0xd2, 0x5e, - 0xcd, 0x84, 0xf9, 0x0a, 0xa6, 0x63, 0x2d, 0x29, 0xde, 0x57, 0x8a, 0x76, 0xf0, 0x67, 0x19, 0xcd, - 0x83, 0x12, 0xfe, 0xc5, 0x40, 0xe5, 0x6c, 0xea, 0x70, 0xbd, 0xb8, 0xca, 0xc3, 0x21, 0x37, 0x3f, - 0x98, 0x02, 0x99, 0xd9, 0xb5, 0xb7, 0x7e, 0xfe, 0xef, 0xf9, 0x1f, 0x33, 0x16, 0xde, 0x20, 0x13, - 0xfe, 0x93, 0xf0, 0x4f, 0x68, 0x1e, 0xe6, 0x07, 0x6f, 0x4f, 0xaa, 0x3c, 0x34, 0xff, 0x66, 0xfd, - 0x71, 0xa0, 0x76, 0xf0, 0x1e, 0x38, 0x78, 0x07, 0xaf, 0x8f, 0x71, 0x00, 0xba, 0x7f, 0x19, 0x68, - 0x79, 0xa8, 0x65, 0xf1, 0xee, 0x84, 0xf2, 0x0f, 0xbb, 0xde, 0x74, 0xa6, 0x85, 0x6b, 0x4f, 0x3b, - 0xe0, 0x69, 0x0b, 0xdb, 0xc5, 0x9e, 0x60, 0x9c, 0xbd, 0xec, 0x0d, 0xff, 0x6d, 0xa0, 0x37, 0x47, - 0x5a, 0x1b, 0x93, 0x09, 0x6a, 0x45, 0x23, 0x62, 0xee, 0x4d, 0x4f, 0xd0, 0x06, 0x77, 0xc1, 0xe0, - 0x36, 0x7e, 0xbf, 0xd8, 0xa0, 0xe8, 0xf1, 0x2b, 0x2f, 0x1b, 0x8d, 0xb6, 0x72, 0xf4, 0xaf, 0x81, - 0x2a, 0x05, 0x4d, 0x8b, 0x3f, 0x9a, 0x20, 0x3c, 0x7e, 0x46, 0xcc, 0xc3, 0xd7, 0xa5, 0x69, 0xd7, - 0x9f, 0x83, 0xeb, 0x4f, 0xf0, 0x21, 0x19, 0x7f, 0xbb, 0x79, 0xf9, 0xb4, 0xe9, 0xf3, 0x25, 0x3f, - 0xe4, 0x0b, 0x3f, 0x36, 0xbe, 0xb8, 0xb9, 0xb3, 0x8c, 0xdb, 0x3b, 0xcb, 0x78, 0x76, 0x67, 0x19, - 0xbf, 0xdf, 0x5b, 0xa5, 0xdb, 0x7b, 0xab, 0xf4, 0xff, 0xbd, 0x55, 0xfa, 0x6e, 0x7b, 0xe8, 0x66, - 0x18, 0xa9, 0xfd, 0xfd, 0xa0, 0x3a, 0x5c, 0x0f, 0xad, 0x32, 0x5c, 0x8e, 0x1f, 0xbe, 0x0c, 0x00, - 0x00, 0xff, 0xff, 0x22, 0x23, 0xbb, 0x03, 0x1b, 0x08, 0x00, 0x00, + // 936 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6f, 0xdc, 0x44, + 0x14, 0x8e, 0x93, 0xcd, 0xaf, 0x97, 0xb6, 0xc0, 0x24, 0x52, 0x37, 0x4e, 0x70, 0xb6, 0x26, 0x28, + 0x4b, 0xa5, 0xd8, 0x49, 0x10, 0x01, 0x81, 0x8a, 0x44, 0x82, 0x90, 0x22, 0x15, 0xa9, 0x75, 0x38, + 0x71, 0xb1, 0x66, 0xbd, 0xb3, 0x1b, 0xab, 0xb6, 0xc7, 0xf5, 0xcc, 0x26, 0x54, 0xa8, 0x42, 0x02, + 0x71, 0xe0, 0x86, 0x84, 0x84, 0xb8, 0x72, 0xe5, 0xc4, 0x1f, 0x81, 0x44, 0x8f, 0x95, 0xb8, 0x70, + 0x02, 0x94, 0xf0, 0x17, 0xf0, 0x17, 0xa0, 0x79, 0x33, 0xde, 0xec, 0x36, 0xde, 0xcd, 0xf6, 0x64, + 0xef, 0xcc, 0xf7, 0xbd, 0xef, 0x7b, 0xe3, 0xf7, 0xde, 0x2c, 0x34, 0x12, 0x7a, 0x4a, 0x33, 0x26, + 0x7d, 0xf5, 0xf4, 0x0b, 0x76, 0x46, 0x8b, 0xb6, 0xf0, 0x1f, 0xf7, 0x58, 0xf1, 0xc4, 0xcb, 0x0b, + 0x2e, 0x39, 0x59, 0x31, 0x08, 0x4f, 0x3d, 0x3d, 0x83, 0xb0, 0x57, 0xba, 0xbc, 0xcb, 0x11, 0xe0, + 0xab, 0x37, 0x8d, 0xb5, 0xd7, 0xbb, 0x9c, 0x77, 0x13, 0xe6, 0xd3, 0x3c, 0xf6, 0x69, 0x96, 0x71, + 0x49, 0x65, 0xcc, 0x33, 0x61, 0x76, 0xef, 0x46, 0x5c, 0xa4, 0x5c, 0xf8, 0x2d, 0x2a, 0x98, 0x96, + 0xf0, 0x4f, 0x77, 0x5b, 0x4c, 0xd2, 0x5d, 0x3f, 0xa7, 0xdd, 0x38, 0x43, 0xb0, 0xc1, 0xde, 0xa9, + 0xf4, 0x95, 0xd3, 0x82, 0xa6, 0x65, 0xb8, 0x6a, 0xeb, 0x71, 0x5e, 0xe4, 0x91, 0x41, 0x38, 0x83, + 0x82, 0xa5, 0x54, 0xc4, 0x63, 0x23, 0xe2, 0xae, 0x00, 0x79, 0xa8, 0x6c, 0x3c, 0xc0, 0xb0, 0x01, + 0x7b, 0xdc, 0x63, 0x42, 0xba, 0x0f, 0x61, 0x79, 0x68, 0x55, 0xe4, 0x3c, 0x13, 0x8c, 0xbc, 0x0f, + 0x73, 0x5a, 0xbe, 0x6e, 0x35, 0xac, 0xe6, 0xd2, 0xde, 0xba, 0x57, 0x75, 0x30, 0x9e, 0x66, 0x1d, + 0xd4, 0x9e, 0xfd, 0xb5, 0x31, 0x15, 0x18, 0x86, 0xbb, 0x0c, 0xaf, 0xe9, 0x90, 0x9c, 0x27, 0x7d, + 0x9d, 0x6f, 0x2d, 0x58, 0x50, 0x0b, 0x47, 0x59, 0x87, 0x13, 0x02, 0xb5, 0x8c, 0xa6, 0x0c, 0x63, + 0x2f, 0x06, 0xf8, 0x4e, 0x18, 0xcc, 0xb7, 0x68, 0x42, 0xb3, 0x88, 0xd5, 0xa7, 0x1b, 0x33, 0xcd, + 0xa5, 0xbd, 0x55, 0x4f, 0x27, 0xe4, 0xa9, 0x84, 0x3c, 0x93, 0x90, 0x77, 0xc8, 0xe3, 0xec, 0x60, + 0x47, 0xe9, 0xfd, 0xf2, 0xf7, 0x46, 0xb3, 0x1b, 0xcb, 0x93, 0x5e, 0xcb, 0x8b, 0x78, 0xea, 0x9b, + 0xec, 0xf5, 0x63, 0x5b, 0xb4, 0x1f, 0xf9, 0xf2, 0x49, 0xce, 0x04, 0x12, 0x44, 0x50, 0xc6, 0x76, + 0xff, 0xb3, 0xca, 0x63, 0xd0, 0xee, 0xfa, 0xf9, 0xce, 0xe6, 0x6a, 0xa1, 0x6e, 0xa1, 0xb6, 0x33, + 0x22, 0x5d, 0x93, 0x80, 0x49, 0x58, 0x53, 0xc8, 0x26, 0xdc, 0x92, 0x71, 0xca, 0x42, 0xc9, 0xc3, + 0x82, 0x75, 0xe2, 0x24, 0xa9, 0x4f, 0x37, 0xac, 0xe6, 0x4c, 0x70, 0x43, 0xad, 0x7e, 0xc6, 0x03, + 0x5c, 0x23, 0x1f, 0x80, 0xcd, 0x84, 0x8c, 0x53, 0x2a, 0x59, 0x3b, 0x6c, 0x25, 0x3c, 0x7a, 0x24, + 0x06, 0x18, 0x33, 0xc8, 0xb8, 0xdd, 0x47, 0x1c, 0x20, 0xa0, 0x4f, 0xbe, 0x07, 0x6b, 0x34, 0x49, + 0x78, 0x84, 0x45, 0x13, 0x2a, 0xd9, 0x30, 0xe5, 0x99, 0x3c, 0x11, 0x61, 0xc2, 0x3a, 0xb2, 0x5e, + 0x43, 0x76, 0xfd, 0x12, 0xa2, 0x8c, 0x7e, 0x8a, 0x80, 0xfb, 0xac, 0x23, 0xdd, 0x55, 0xb8, 0x8d, + 0x39, 0x63, 0xd4, 0x00, 0x93, 0x29, 0xbf, 0xcb, 0x31, 0xd4, 0xaf, 0x6e, 0x99, 0x43, 0x79, 0x17, + 0xe6, 0x74, 0xe6, 0xa6, 0x08, 0xc6, 0x7c, 0x11, 0x53, 0x01, 0x1a, 0xee, 0xae, 0xc1, 0x2a, 0x06, + 0x3d, 0x3e, 0xe1, 0x67, 0x47, 0xaa, 0x44, 0x3f, 0xa6, 0x92, 0x96, 0x8a, 0xdf, 0x59, 0x60, 0x57, + 0xed, 0xf6, 0xbf, 0xc4, 0x42, 0x1a, 0x67, 0x61, 0xc4, 0x85, 0x9c, 0x54, 0x76, 0x3e, 0x8d, 0xb3, + 0x43, 0x2e, 0x24, 0xf1, 0x61, 0x19, 0x3b, 0x22, 0x14, 0xbd, 0x96, 0x88, 0x8a, 0x38, 0xc7, 0x86, + 0xc4, 0x7a, 0x5a, 0x0c, 0x08, 0x6e, 0x1d, 0x0f, 0xee, 0xb8, 0xf7, 0x60, 0x03, 0xad, 0xa0, 0x8d, + 0x07, 0x05, 0x3f, 0x8d, 0xdb, 0xac, 0x18, 0x3a, 0x20, 0x62, 0xc3, 0x42, 0x6e, 0x36, 0x4c, 0xbd, + 0xf6, 0x7f, 0xbb, 0x5d, 0x68, 0x8c, 0xa6, 0x9b, 0x7c, 0x0e, 0x01, 0x44, 0xce, 0xa2, 0xb0, 0xd3, + 0xcb, 0xda, 0xd7, 0x94, 0xd7, 0x71, 0xce, 0x22, 0x05, 0x33, 0x69, 0x2d, 0x2a, 0xde, 0x27, 0x8a, + 0xe6, 0xee, 0xc2, 0xda, 0xa5, 0x90, 0x82, 0x0d, 0x7b, 0x24, 0x50, 0x53, 0xd8, 0xb2, 0x9f, 0xd4, + 0xbb, 0xfb, 0xa3, 0x05, 0xeb, 0xd5, 0x1c, 0x63, 0xec, 0x3e, 0xdc, 0xd4, 0x87, 0x65, 0xe4, 0x8d, + 0xb7, 0x3b, 0xd5, 0xde, 0x30, 0x8a, 0x8e, 0x60, 0xec, 0xdd, 0x88, 0x2f, 0x97, 0x04, 0x69, 0xc2, + 0xab, 0x51, 0xaf, 0x28, 0x58, 0x26, 0x75, 0x65, 0x86, 0x71, 0x1b, 0xdb, 0xa0, 0x16, 0xdc, 0x32, + 0xeb, 0x58, 0x8f, 0x47, 0xed, 0xbd, 0xdf, 0xe7, 0x61, 0x16, 0x8d, 0x91, 0x6f, 0x2c, 0x98, 0xd3, + 0x13, 0x84, 0x34, 0xab, 0x55, 0xaf, 0x0e, 0x2c, 0xfb, 0xad, 0x09, 0x90, 0x3a, 0x43, 0x77, 0xf3, + 0xeb, 0x3f, 0xfe, 0xfd, 0x61, 0xda, 0x21, 0xeb, 0xfe, 0x98, 0xf9, 0x4a, 0xbe, 0x82, 0x59, 0x9c, + 0x05, 0x64, 0x6b, 0x5c, 0xe4, 0x81, 0x59, 0x66, 0x37, 0xaf, 0x07, 0x1a, 0x07, 0x6f, 0xa0, 0x83, + 0xd7, 0xc9, 0xda, 0x08, 0x07, 0xa8, 0xfb, 0x93, 0x05, 0x4b, 0x03, 0xed, 0x47, 0xb6, 0xc7, 0x84, + 0xbf, 0xda, 0xc1, 0xb6, 0x37, 0x29, 0xdc, 0x78, 0xba, 0x8b, 0x9e, 0x36, 0x89, 0x5b, 0xed, 0x09, + 0x47, 0x93, 0xa9, 0x09, 0xf2, 0xb3, 0x05, 0x37, 0x87, 0xda, 0x94, 0xf8, 0x63, 0xd4, 0xaa, 0xda, + 0xdd, 0xde, 0x99, 0x9c, 0x60, 0x0c, 0x6e, 0xa3, 0xc1, 0x2d, 0xf2, 0x66, 0xb5, 0x41, 0x71, 0xc2, + 0xcf, 0x42, 0x5d, 0xb9, 0x6d, 0xe5, 0xe8, 0x37, 0x0b, 0x96, 0x2b, 0x1a, 0x90, 0xbc, 0x33, 0x46, + 0x78, 0x74, 0xbf, 0xdb, 0xfb, 0x2f, 0x4b, 0x33, 0xae, 0x3f, 0x44, 0xd7, 0xef, 0x91, 0x7d, 0x7f, + 0xf4, 0x4d, 0x1d, 0x96, 0x93, 0xc3, 0x9c, 0xaf, 0xff, 0x65, 0xb9, 0xf0, 0x94, 0xfc, 0x6a, 0xc1, + 0x2b, 0x2f, 0xb4, 0x2a, 0xd9, 0xbd, 0xce, 0xcb, 0x95, 0x51, 0x60, 0xef, 0xbd, 0x0c, 0xc5, 0x58, + 0xdf, 0x47, 0xeb, 0x3b, 0xc4, 0x1b, 0x67, 0x1d, 0x87, 0x58, 0x69, 0x5b, 0xfd, 0x78, 0x7a, 0xf0, + 0xd1, 0xb3, 0x73, 0xc7, 0x7a, 0x7e, 0xee, 0x58, 0xff, 0x9c, 0x3b, 0xd6, 0xf7, 0x17, 0xce, 0xd4, + 0xf3, 0x0b, 0x67, 0xea, 0xcf, 0x0b, 0x67, 0xea, 0xf3, 0xad, 0x81, 0x8b, 0x79, 0x28, 0xe6, 0x17, + 0xfd, 0xa8, 0x78, 0x3b, 0xb7, 0xe6, 0xf0, 0xbf, 0xc9, 0xdb, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x0c, 0x25, 0x99, 0x21, 0x9a, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -628,8 +735,10 @@ type QueryClient interface { BlockReward(ctx context.Context, in *QueryBlockRewardRequest, opts ...grpc.CallOption) (*QueryBlockRewardResponse, error) // ShowIprpcData queries for the iprpc data ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataRequest, opts ...grpc.CallOption) (*QueryShowIprpcDataResponse, error) - // ShowIprpcData queries for the iprpc data + // IprpcProviderReward queries for a provider's current IPRPC reward (relative to its serviced CU) IprpcProviderReward(ctx context.Context, in *QueryIprpcProviderRewardRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardResponse, error) + // IprpcSpecReward queries for a spec's IPRPC reward + IprpcSpecReward(ctx context.Context, in *QueryIprpcSpecRewardRequest, opts ...grpc.CallOption) (*QueryIprpcSpecRewardResponse, error) } type queryClient struct { @@ -685,6 +794,15 @@ func (c *queryClient) IprpcProviderReward(ctx context.Context, in *QueryIprpcPro return out, nil } +func (c *queryClient) IprpcSpecReward(ctx context.Context, in *QueryIprpcSpecRewardRequest, opts ...grpc.CallOption) (*QueryIprpcSpecRewardResponse, error) { + out := new(QueryIprpcSpecRewardResponse) + err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Query/IprpcSpecReward", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Parameters queries the parameters of the module. @@ -695,8 +813,10 @@ type QueryServer interface { BlockReward(context.Context, *QueryBlockRewardRequest) (*QueryBlockRewardResponse, error) // ShowIprpcData queries for the iprpc data ShowIprpcData(context.Context, *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) - // ShowIprpcData queries for the iprpc data + // IprpcProviderReward queries for a provider's current IPRPC reward (relative to its serviced CU) IprpcProviderReward(context.Context, *QueryIprpcProviderRewardRequest) (*QueryIprpcProviderRewardResponse, error) + // IprpcSpecReward queries for a spec's IPRPC reward + IprpcSpecReward(context.Context, *QueryIprpcSpecRewardRequest) (*QueryIprpcSpecRewardResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -718,6 +838,9 @@ func (*UnimplementedQueryServer) ShowIprpcData(ctx context.Context, req *QuerySh func (*UnimplementedQueryServer) IprpcProviderReward(ctx context.Context, req *QueryIprpcProviderRewardRequest) (*QueryIprpcProviderRewardResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method IprpcProviderReward not implemented") } +func (*UnimplementedQueryServer) IprpcSpecReward(ctx context.Context, req *QueryIprpcSpecRewardRequest) (*QueryIprpcSpecRewardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IprpcSpecReward not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -813,6 +936,24 @@ func _Query_IprpcProviderReward_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _Query_IprpcSpecReward_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryIprpcSpecRewardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).IprpcSpecReward(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/lavanet.lava.rewards.Query/IprpcSpecReward", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).IprpcSpecReward(ctx, req.(*QueryIprpcSpecRewardRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "lavanet.lava.rewards.Query", HandlerType: (*QueryServer)(nil), @@ -837,6 +978,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "IprpcProviderReward", Handler: _Query_IprpcProviderReward_Handler, }, + { + MethodName: "IprpcSpecReward", + Handler: _Query_IprpcSpecReward_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "lavanet/lava/rewards/query.proto", @@ -1205,6 +1350,78 @@ func (m *QueryIprpcProviderRewardResponse) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } +func (m *QueryIprpcSpecRewardRequest) 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 *QueryIprpcSpecRewardRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryIprpcSpecRewardRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Spec) > 0 { + i -= len(m.Spec) + copy(dAtA[i:], m.Spec) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Spec))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryIprpcSpecRewardResponse) 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 *QueryIprpcSpecRewardResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryIprpcSpecRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CurrentMonthId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.CurrentMonthId)) + i-- + dAtA[i] = 0x10 + } + if len(m.IprpcRewards) > 0 { + for iNdEx := len(m.IprpcRewards) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IprpcRewards[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 @@ -1362,6 +1579,37 @@ func (m *QueryIprpcProviderRewardResponse) Size() (n int) { return n } +func (m *QueryIprpcSpecRewardRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Spec) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryIprpcSpecRewardResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.IprpcRewards) > 0 { + for _, e := range m.IprpcRewards { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.CurrentMonthId != 0 { + n += 1 + sovQuery(uint64(m.CurrentMonthId)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2272,6 +2520,191 @@ func (m *QueryIprpcProviderRewardResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryIprpcSpecRewardRequest) 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: QueryIprpcSpecRewardRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryIprpcSpecRewardRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", 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.Spec = 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 *QueryIprpcSpecRewardResponse) 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: QueryIprpcSpecRewardResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryIprpcSpecRewardResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IprpcRewards", 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.IprpcRewards = append(m.IprpcRewards, IprpcReward{}) + if err := m.IprpcRewards[len(m.IprpcRewards)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentMonthId", wireType) + } + m.CurrentMonthId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentMonthId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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 diff --git a/x/rewards/types/query.pb.gw.go b/x/rewards/types/query.pb.gw.go index 7e0cc7f2c8..2054cc9331 100644 --- a/x/rewards/types/query.pb.gw.go +++ b/x/rewards/types/query.pb.gw.go @@ -159,6 +159,60 @@ func local_request_Query_IprpcProviderReward_0(ctx context.Context, marshaler ru } +func request_Query_IprpcSpecReward_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIprpcSpecRewardRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["spec"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "spec") + } + + protoReq.Spec, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "spec", err) + } + + msg, err := client.IprpcSpecReward(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_IprpcSpecReward_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIprpcSpecRewardRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["spec"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "spec") + } + + protoReq.Spec, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "spec", err) + } + + msg, err := server.IprpcSpecReward(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. @@ -280,6 +334,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_IprpcSpecReward_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_IprpcSpecReward_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_IprpcSpecReward_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -421,6 +498,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_IprpcSpecReward_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_IprpcSpecReward_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_IprpcSpecReward_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -434,6 +531,8 @@ var ( pattern_Query_ShowIprpcData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "show_iprpc_data"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_IprpcProviderReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"lavanet", "lava", "rewards", "iprpc_provider_reward", "provider"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_IprpcSpecReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"lavanet", "lava", "rewards", "iprpc_spec_reward", "spec"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -446,4 +545,6 @@ var ( forward_Query_ShowIprpcData_0 = runtime.ForwardResponseMessage forward_Query_IprpcProviderReward_0 = runtime.ForwardResponseMessage + + forward_Query_IprpcSpecReward_0 = runtime.ForwardResponseMessage ) From b7ba787b62955511a064579c9bc16f019bcd5c28 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 13:55:44 +0200 Subject: [PATCH 24/64] CNS-872: fix for iprpc reward object update --- x/rewards/keeper/iprpc_reward.go | 13 +++---------- x/rewards/keeper/providers.go | 3 ++- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index b124b55e72..083e674908 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -86,16 +86,9 @@ func GetIprpcRewardIDFromBytes(bz []byte) uint64 { // PopIprpcReward gets the lowest id IprpcReward object and removes it func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { - // Get current IprpcReward - iprpcReward, found := k.GetIprpcReward(ctx, k.GetIprpcRewardsCurrent(ctx)) - if !found { - return types.IprpcReward{}, false - } - - // Remove the reward - k.RemoveIprpcReward(ctx, iprpcReward.Id) - - return iprpcReward, true + current := k.GetIprpcRewardsCurrent(ctx) + k.SetIprpcRewardsCurrent(ctx, current+1) + return k.GetIprpcReward(ctx, current) } // AddSpecFunds adds funds for a specific spec for of months. diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 94eb41c3d3..48f09a2694 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -107,7 +107,8 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { utils.LavaFormatError("current month iprpc reward not found", fmt.Errorf("did not reward providers IPRPC bonus")) return } - k.SetIprpcRewardsCurrent(ctx, iprpcReward.Id+1) + k.RemoveIprpcReward(ctx, iprpcReward.Id) + for _, specFund := range iprpcReward.SpecFunds { // collect details details := map[string]string{"spec": specFund.Spec, "rewards": specFund.Fund.String()} From 6b9cb8f069ff5a684e9bbfb78732dab10f2df56a Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 14:41:56 +0200 Subject: [PATCH 25/64] CNS-872: update pool test with iprpc pool --- x/rewards/keeper/pool_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/rewards/keeper/pool_test.go b/x/rewards/keeper/pool_test.go index f1fccf4c2c..ab18224d7a 100644 --- a/x/rewards/keeper/pool_test.go +++ b/x/rewards/keeper/pool_test.go @@ -37,8 +37,6 @@ import ( // 1. The allocation pool has the expected allocated funds minus one block reward // 2. The distribution pool has the expected monthly quota minus one block reward // 3. The fee collector has one block reward -// -// the validator got rewards func TestRewardsModuleSetup(t *testing.T) { ts := newTester(t, false) lifetime := int64(types.RewardsAllocationPoolsLifetime) @@ -64,6 +62,8 @@ func TestRewardsModuleSetup(t *testing.T) { require.Equal(t, allocationPoolBalance*(lifetime-1)/lifetime, pool.Balance.AmountOf(ts.BondDenom()).Int64()) case string(types.ValidatorsRewardsDistributionPoolName): require.Equal(t, (allocationPoolBalance/lifetime)-blockReward, pool.Balance.AmountOf(ts.BondDenom()).Int64()) + case string(types.IprpcPoolName): + require.True(t, pool.Balance.Empty()) } } From 8ae57c53215ff2bf60914a502c4281b43d9d1435 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 14:47:58 +0200 Subject: [PATCH 26/64] CNS-872: create small helper --- testutil/common/tester.go | 5 +++-- x/rewards/keeper/helpers_test.go | 5 +++++ x/rewards/keeper/iprpc_data_test.go | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 8b0f5807a3..708f4c1a14 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -610,9 +610,9 @@ func (ts *Tester) TxPairingUnfreezeProvider(addr, chainID string) (*pairingtypes return ts.Servers.PairingServer.UnfreezeProvider(ts.GoCtx, msg) } -func (ts *Tester) TxRewardsSetIprpcDataProposal(ctx sdk.Context, authority string, cost sdk.Coin, subs []string) (*rewardstypes.MsgSetIprpcDataResponse, error) { +func (ts *Tester) TxRewardsSetIprpcDataProposal(authority string, cost sdk.Coin, subs []string) (*rewardstypes.MsgSetIprpcDataResponse, error) { msg := rewardstypes.NewMsgSetIprpcData(authority, cost, subs) - return ts.Servers.RewardsServer.SetIprpcData(sdk.WrapSDKContext(ctx), msg) + return ts.Servers.RewardsServer.SetIprpcData(ts.GoCtx, msg) } // TxCreateValidator: implement 'tx staking createvalidator' and bond its tokens @@ -859,6 +859,7 @@ func (ts *Tester) QueryRewardsBlockReward() (*rewardstypes.QueryBlockRewardRespo return ts.Keepers.Rewards.BlockReward(ts.GoCtx, msg) } +// QueryRewardsShowIprpcData implements 'q rewards show-iprpc-data' func (ts *Tester) QueryRewardsShowIprpcData() (*rewardstypes.QueryShowIprpcDataResponse, error) { msg := &rewardstypes.QueryShowIprpcDataRequest{} return ts.Keepers.Rewards.ShowIprpcData(ts.GoCtx, msg) diff --git a/x/rewards/keeper/helpers_test.go b/x/rewards/keeper/helpers_test.go index e2d009ab50..ddff8d8474 100644 --- a/x/rewards/keeper/helpers_test.go +++ b/x/rewards/keeper/helpers_test.go @@ -6,6 +6,7 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/lavanet/lava/testutil/common" testkeeper "github.com/lavanet/lava/testutil/keeper" @@ -66,6 +67,10 @@ func (ts *tester) getPoolBalance(pool rewardsTypes.Pool, denom string) math.Int return coins.AmountOf(denom) } +func (ts *tester) iprpcAuthority() string { + return authtypes.NewModuleAddress(govtypes.ModuleName).String() +} + // deductParticipationFees calculates the validators and community participation // fees and returns the providers reward after deducting them func (ts *tester) DeductParticipationFees(reward math.Int) (updatedReward math.Int, valParticipation math.Int, communityParticipation math.Int) { diff --git a/x/rewards/keeper/iprpc_data_test.go b/x/rewards/keeper/iprpc_data_test.go index f88cb59fbd..8d949565b1 100644 --- a/x/rewards/keeper/iprpc_data_test.go +++ b/x/rewards/keeper/iprpc_data_test.go @@ -109,7 +109,7 @@ func TestIprpcDataValidation(t *testing.T) { for _, tt := range template { t.Run(tt.name, func(t *testing.T) { - _, err := ts.TxRewardsSetIprpcDataProposal(ts.Ctx, tt.authority, tt.cost, tt.subs) + _, err := ts.TxRewardsSetIprpcDataProposal(tt.authority, tt.cost, tt.subs) if tt.success { require.NoError(t, err) res, err := ts.QueryRewardsShowIprpcData() From e287193bf6570b71e6696df67429056e700218bb Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 18:12:17 +0200 Subject: [PATCH 27/64] CNS-872: make mock bank keeper support multiple coins --- testutil/keeper/mock_keepers.go | 47 +++------------------------------ 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/testutil/keeper/mock_keepers.go b/testutil/keeper/mock_keepers.go index fbe2c741ce..e0cb927683 100644 --- a/testutil/keeper/mock_keepers.go +++ b/testutil/keeper/mock_keepers.go @@ -77,15 +77,9 @@ func (k mockBankKeeper) GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk } func (k mockBankKeeper) SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error { - // TODO support multiple coins moduleAcc := GetModuleAddress(recipientModule) - if amt.Len() > 1 { - return fmt.Errorf("mockbankkeeper dont support more than 1 coin") - } - coin := amt[0] - - accountCoin := k.GetBalance(ctx, senderAddr, coin.Denom) - if coin.Amount.GT(accountCoin.Amount) { + accountCoins := k.GetAllBalances(ctx, senderAddr) + if !accountCoins.IsAllGTE(amt) { return fmt.Errorf("not enough coins") } @@ -99,47 +93,14 @@ func (k mockBankKeeper) UndelegateCoinsFromModuleToAccount(ctx sdk.Context, send } func (k mockBankKeeper) SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error { - // TODO support multiple coins moduleAcc := GetModuleAddress(senderModule) - - if amt.Len() > 1 { - return fmt.Errorf("mockbankkeeper doesn't support more than 1 coin") - } - coin := amt[0] - - accountCoin := k.GetBalance(ctx, moduleAcc, coin.Denom) - if coin.Amount.GT(accountCoin.Amount) { - return fmt.Errorf("not enough coins") - } - - k.SubFromBalance(moduleAcc, amt) - - k.AddToBalance(recipientAddr, amt) - - return nil + return k.SendCoinsFromAccountToModule(ctx, moduleAcc, recipientAddr.String(), amt) } func (k mockBankKeeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error { - // TODO support multiple coins - senderModuleAcc := GetModuleAddress(senderModule) recipientModuleAcc := GetModuleAddress(recipientModule) - - if amt.Len() > 1 { - return fmt.Errorf("mockbankkeeper doesn't support more than 1 coin") - } - coin := amt[0] - - senderAccountCoin := k.GetBalance(ctx, senderModuleAcc, coin.Denom) - if coin.Amount.GT(senderAccountCoin.Amount) { - return fmt.Errorf("not enough coins") - } - - k.SubFromBalance(senderModuleAcc, amt) - - k.AddToBalance(recipientModuleAcc, amt) - - return nil + return k.SendCoinsFromAccountToModule(ctx, senderModuleAcc, recipientModuleAcc.String(), amt) } func (k mockBankKeeper) DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error { From bbf3f1106e6d34373f686eda6192ebe63383f4a2 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Thu, 15 Feb 2024 18:45:03 +0200 Subject: [PATCH 28/64] CNS-872: fix mock bank keeper --- testutil/keeper/mock_keepers.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testutil/keeper/mock_keepers.go b/testutil/keeper/mock_keepers.go index e0cb927683..ab465c0e22 100644 --- a/testutil/keeper/mock_keepers.go +++ b/testutil/keeper/mock_keepers.go @@ -99,8 +99,7 @@ func (k mockBankKeeper) SendCoinsFromModuleToAccount(ctx sdk.Context, senderModu func (k mockBankKeeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error { senderModuleAcc := GetModuleAddress(senderModule) - recipientModuleAcc := GetModuleAddress(recipientModule) - return k.SendCoinsFromAccountToModule(ctx, senderModuleAcc, recipientModuleAcc.String(), amt) + return k.SendCoinsFromAccountToModule(ctx, senderModuleAcc, recipientModule, amt) } func (k mockBankKeeper) DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error { From aaf6d4baa392fc1e00537201b84abafbe4418a33 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 18 Feb 2024 12:29:57 +0200 Subject: [PATCH 29/64] CNS-872: fix iprpc reward bug --- x/rewards/keeper/iprpc_reward.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 083e674908..067a009003 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -102,22 +102,24 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat for i := startID; i < duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) if found { - // found IPRPC reward + // found IPRPC reward, find if spec exists + specIndex := -1 for i := 0; i < len(iprpcReward.SpecFunds); i++ { if iprpcReward.SpecFunds[i].Spec == spec { - iprpcReward.SpecFunds[i].Fund = iprpcReward.SpecFunds[i].Fund.Add(fund...) - k.SetIprpcReward(ctx, iprpcReward) - return + specIndex = i } } - // did not find spec in IPRPC reward -> create a new one - iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) - k.SetIprpcReward(ctx, iprpcReward) + // update spec funds + if specIndex >= 0 { + iprpcReward.SpecFunds[specIndex].Fund = iprpcReward.SpecFunds[specIndex].Fund.Add(fund...) + } else { + iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) + } } else { // did not find IPRPC reward -> create a new one iprpcReward.Id = i iprpcReward.SpecFunds = []types.Specfund{{Spec: spec, Fund: fund}} - k.SetIprpcReward(ctx, iprpcReward) } + k.SetIprpcReward(ctx, iprpcReward) } } From f7932f18a7e41c702a998c4bc3046f1f40855ade Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 18 Feb 2024 17:57:46 +0200 Subject: [PATCH 30/64] CNS-870: count iprpc cu with cu tracker and not with sub expiry --- x/rewards/keeper/providers.go | 15 +++++++++++---- x/subscription/keeper/cu_tracker.go | 5 +++++ x/subscription/types/expected_keepers.go | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index b83c553945..66cd592b30 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -14,6 +14,17 @@ import ( const DAY_SECONDS = 60 * 60 * 24 +func (k Keeper) AddIprpcCu(ctx sdk.Context, provider string, chainID string, cu uint64) { + index := types.BasePayIndex{Provider: provider, ChainID: chainID} + basepay, found := k.getBasePay(ctx, index) + if !found { + basepay = types.BasePay{IprpcCu: cu} + } else { + basepay.IprpcCu += cu + } + k.setBasePay(ctx, index, basepay) +} + func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int, sub string, cu uint64) { index := types.BasePayIndex{Provider: provider, ChainID: chainid} basepay, found := k.getBasePay(ctx, index) @@ -26,10 +37,6 @@ func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adju basepay.TotalAdjusted = basepay.TotalAdjusted.Add(adjustedPay) } - if k.IsIprpcSubscription(ctx, sub) { - basepay.IprpcCu += cu - } - k.setBasePay(ctx, index, basepay) } diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index d822084374..d3b3300184 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -28,7 +28,12 @@ func (k Keeper) GetTrackedCu(ctx sdk.Context, sub string, provider string, chain } // AddTrackedCu adds CU to the CU counters in relevant trackedCu entry +// Also, it counts the IPRPC CU if the subscription is IPRPC eligible func (k Keeper) AddTrackedCu(ctx sdk.Context, sub string, provider string, chainID string, cuToAdd uint64, block uint64) error { + if k.rewardsKeeper.IsIprpcSubscription(ctx, sub) { + k.rewardsKeeper.AddIprpcCu(ctx, provider, chainID, cuToAdd) + } + cu, found, key := k.GetTrackedCu(ctx, sub, provider, chainID, block) // Note that the trackedCu entry usually has one version since we used diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index ddb574aca3..471b306af4 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -68,6 +68,8 @@ type RewardsKeeper interface { MaxRewardBoost(ctx sdk.Context) (res uint64) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward sdk.Coin, senderModule string) (updatedReward sdk.Coin, err error) FundCommunityPoolFromModule(ctx sdk.Context, amount sdk.Coins, senderModule string) error + IsIprpcSubscription(ctx sdk.Context, address string) bool + AddIprpcCu(ctx sdk.Context, provider string, chainID string, cu uint64) } type StakingKeeper interface { From 7ff42ade20c61823920e9beebfb24b2bbb9867ba Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 18 Feb 2024 18:12:14 +0200 Subject: [PATCH 31/64] CNS-869: fund iprpc only from the next month --- x/rewards/keeper/iprpc.go | 10 ++-------- x/rewards/keeper/iprpc_reward.go | 7 ++----- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index fdeaf189f6..9dceaa498c 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -59,14 +59,8 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund ) } - // check if to add funds from next month or to current month - fromNextMonth := false - if utils.IsMiddleOfMonthPassed(ctx.BlockTime()) { - fromNextMonth = true - } - - // add spec funds to current/next month IPRPC reward object - k.addSpecFunds(ctx, spec, fund, duration, fromNextMonth) + // add spec funds to next month IPRPC reward object + k.addSpecFunds(ctx, spec, fund, duration) return nil } diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index b124b55e72..9db89a64a8 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -100,11 +100,8 @@ func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { // AddSpecFunds adds funds for a specific spec for of months. // This function is used by the fund-iprpc TX. -func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64, fromNextMonth bool) { - startID := k.GetIprpcRewardsCurrent(ctx) - if fromNextMonth { - startID += 1 - } +func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { + startID := k.GetIprpcRewardsCurrent(ctx) + 1 // start funding from the next month for i := startID; i < duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) From 6013bc897ed851397c07ea913546de11a5344253 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 18 Feb 2024 18:27:18 +0200 Subject: [PATCH 32/64] CNS-870: changes for bug fixes --- x/rewards/keeper/iprpc_reward.go | 39 ++++++++++++-------------------- x/rewards/keeper/providers.go | 17 +++++++++++++- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 5e86860ccb..360e3d0166 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -86,45 +86,36 @@ func GetIprpcRewardIDFromBytes(bz []byte) uint64 { // PopIprpcReward gets the lowest id IprpcReward object and removes it func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { - // Get current IprpcReward - iprpcReward, found := k.GetIprpcReward(ctx, k.GetIprpcRewardsCurrent(ctx)) - if !found { - return types.IprpcReward{}, false - } - - // Remove the reward - k.RemoveIprpcReward(ctx, iprpcReward.Id) - - return iprpcReward, true + current := k.GetIprpcRewardsCurrent(ctx) + k.SetIprpcRewardsCurrent(ctx, current+1) + return k.GetIprpcReward(ctx, current) } // AddSpecFunds adds funds for a specific spec for of months. // This function is used by the fund-iprpc TX. -func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64, fromNextMonth bool) { - startID := k.GetIprpcRewardsCurrent(ctx) - if fromNextMonth { - startID += 1 - } - +func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { + startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for i := startID; i < duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) - if !found { - // found IPRPC reward + if found { + // found IPRPC reward, find if spec exists + specIndex := -1 for i := 0; i < len(iprpcReward.SpecFunds); i++ { if iprpcReward.SpecFunds[i].Spec == spec { - iprpcReward.SpecFunds[i].Fund = iprpcReward.SpecFunds[i].Fund.Add(fund...) - k.SetIprpcReward(ctx, iprpcReward) - return + specIndex = i } } - // did not find spec in IPRPC reward -> create a new one - iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) + // update spec funds + if specIndex >= 0 { + iprpcReward.SpecFunds[specIndex].Fund = iprpcReward.SpecFunds[specIndex].Fund.Add(fund...) + } else { + iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) + } } else { // did not find IPRPC reward -> create a new one iprpcReward.Id = i iprpcReward.SpecFunds = []types.Specfund{{Spec: spec, Fund: fund}} } - k.SetIprpcReward(ctx, iprpcReward) } } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 66cd592b30..45c5d623e0 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -82,6 +82,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { specCu.ProvidersCu[basepay.Provider] += basepay.IprpcCu } specCu.TotalCu += basepay.IprpcCu + specCuMap[spec.ChainID] = specCu } // calculate the providers bonus base on adjusted base pay @@ -114,7 +115,21 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { utils.LavaFormatError("current month iprpc reward not found", fmt.Errorf("did not reward providers IPRPC bonus")) return } - k.SetIprpcRewardsCurrent(ctx, iprpcReward.Id+1) + if len(specCuMap) == 0 { + // none of the providers will get the IPRPC reward this month, transfer the funds to the next month + nextMonthIprpcReward, found := k.PopIprpcReward(ctx) + nextMonthId := k.GetIprpcRewardsCurrent(ctx) + if !found { + nextMonthIprpcReward = types.IprpcReward{Id: nextMonthId, SpecFunds: iprpcReward.SpecFunds} + } else { + for _, specFund := range nextMonthIprpcReward.SpecFunds { + k.addSpecFunds(ctx, specFund.Spec, specFund.Fund, 1) // TODO: duration might be wrong + } + } + } else { + // providers will get this month's reward, remove the popped reward object + k.RemoveIprpcReward(ctx, iprpcReward.Id) + } for _, specFund := range iprpcReward.SpecFunds { // collect details details := map[string]string{"spec": specFund.Spec} From 7581b83e000df12ad73d3e018263dfbde58b9ea7 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 18 Feb 2024 18:40:26 +0200 Subject: [PATCH 33/64] CNS-870: fix small bug in addSpecsFunds --- x/rewards/keeper/iprpc_reward.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 360e3d0166..fa4422a42f 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -94,8 +94,8 @@ func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { // AddSpecFunds adds funds for a specific spec for of months. // This function is used by the fund-iprpc TX. func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { - startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month - for i := startID; i < duration; i++ { + startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for months + for i := startID; i < duration+1; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) if found { // found IPRPC reward, find if spec exists From 5cdea2077551becbfb0d2d2fc22fe1dc4507aa03 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Sun, 18 Feb 2024 18:41:17 +0200 Subject: [PATCH 34/64] CNS-870: fix addSpecFunds bug --- x/rewards/keeper/iprpc_reward.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 360e3d0166..fa4422a42f 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -94,8 +94,8 @@ func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { // AddSpecFunds adds funds for a specific spec for of months. // This function is used by the fund-iprpc TX. func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { - startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month - for i := startID; i < duration; i++ { + startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for months + for i := startID; i < duration+1; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) if found { // found IPRPC reward, find if spec exists From 79fa8e89fab64026388c5f3427dfd6b7f44de4b2 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 19 Feb 2024 15:39:59 +0200 Subject: [PATCH 35/64] CNS-870: change funcs to use sdk.Coins instead of Coin --- .../lava/dualstaking/delegator_reward.proto | 5 +- proto/lavanet/lava/dualstaking/query.proto | 5 +- testutil/e2e/paymentE2E.go | 2 +- x/dualstaking/keeper/delegator_reward.go | 81 +++++------ x/dualstaking/types/delegator_reward.pb.go | 83 ++++++----- x/dualstaking/types/query.pb.go | 130 ++++++++++-------- x/pairing/client/cli/query_debug_query.go | 2 +- x/pairing/keeper/cu_tracker_test.go | 10 +- x/pairing/keeper/delegator_rewards_test.go | 26 ++-- .../grpc_query_provider_monthly_payout.go | 6 +- x/pairing/keeper/helpers_test.go | 2 +- x/pairing/types/expected_keepers.go | 2 +- x/rewards/keeper/providers.go | 97 ++++++------- x/rewards/keeper/providers_test.go | 36 ++--- x/rewards/types/expected_keepers.go | 2 +- x/subscription/keeper/cu_tracker.go | 2 +- x/subscription/keeper/subscription_test.go | 2 +- x/subscription/types/expected_keepers.go | 2 +- 18 files changed, 260 insertions(+), 235 deletions(-) diff --git a/proto/lavanet/lava/dualstaking/delegator_reward.proto b/proto/lavanet/lava/dualstaking/delegator_reward.proto index 6ff81e08f1..b920e30882 100644 --- a/proto/lavanet/lava/dualstaking/delegator_reward.proto +++ b/proto/lavanet/lava/dualstaking/delegator_reward.proto @@ -10,5 +10,8 @@ message DelegatorReward { string delegator = 1; string provider = 2; string chain_id = 3; - cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false]; + repeated cosmos.base.v1beta1.Coin amount = 4 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; } \ No newline at end of file diff --git a/proto/lavanet/lava/dualstaking/query.proto b/proto/lavanet/lava/dualstaking/query.proto index 169b8750ae..dd861493b4 100644 --- a/proto/lavanet/lava/dualstaking/query.proto +++ b/proto/lavanet/lava/dualstaking/query.proto @@ -73,5 +73,8 @@ message QueryDelegatorRewardsResponse { message DelegatorRewardInfo { string provider = 1; string chain_id = 2; - cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; + repeated cosmos.base.v1beta1.Coin amount = 3 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false +]; } \ No newline at end of file diff --git a/testutil/e2e/paymentE2E.go b/testutil/e2e/paymentE2E.go index 26e0743bc2..4c68abdda5 100644 --- a/testutil/e2e/paymentE2E.go +++ b/testutil/e2e/paymentE2E.go @@ -119,7 +119,7 @@ func (lt *lavaTest) getRewards(addresses []string) ([]sdk.Coin, error) { } total := sdk.NewCoin(commonconsts.TestTokenDenom, sdk.ZeroInt()) for _, r := range res.Rewards { - total = total.Add(r.Amount) + total = total.AddAmount(r.Amount.AmountOf(commonconsts.TestTokenDenom)) } rewards = append(rewards, total) } diff --git a/x/dualstaking/keeper/delegator_reward.go b/x/dualstaking/keeper/delegator_reward.go index 99a82a68a1..a04e41dc3e 100644 --- a/x/dualstaking/keeper/delegator_reward.go +++ b/x/dualstaking/keeper/delegator_reward.go @@ -82,21 +82,22 @@ func (k Keeper) GetAllDelegatorReward(ctx sdk.Context) (list []types.DelegatorRe // CalcRewards calculates the provider reward and the total reward for delegators // providerReward = totalReward * ((effectiveDelegations*commission + providerStake) / effectiveStake) // delegatorsReward = totalReward - providerReward -func (k Keeper) CalcRewards(stakeEntry epochstoragetypes.StakeEntry, totalReward sdk.Coin, delegations []types.Delegation) (providerReward sdk.Coin, delegatorsReward sdk.Coin) { - zeroCoin := sdk.NewCoin(totalReward.Denom, math.ZeroInt()) +func (k Keeper) CalcRewards(ctx sdk.Context, stakeEntry epochstoragetypes.StakeEntry, totalReward sdk.Coins, delegations []types.Delegation) (providerReward sdk.Coins, delegatorsReward sdk.Coins) { + zeroCoin := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) effectiveDelegations, effectiveStake := k.CalcEffectiveDelegationsAndStake(stakeEntry, delegations) // Sanity check - effectiveStake != 0 if effectiveStake.IsZero() { return zeroCoin, zeroCoin } - providerRewardAmount := totalReward.Amount.Mul(stakeEntry.Stake.Amount).Quo(effectiveStake) - rawDelegatorsRewardAmount := totalReward.Amount.Mul(effectiveDelegations).Quo(effectiveStake) - providerCommission := rawDelegatorsRewardAmount.MulRaw(int64(stakeEntry.DelegateCommission)).QuoRaw(100) - providerRewardAmount = providerRewardAmount.Add(providerCommission) + providerReward = totalReward.MulInt(stakeEntry.Stake.Amount).QuoInt(effectiveStake) + if !effectiveDelegations.IsZero() && stakeEntry.DelegateCommission != 0 { + rawDelegatorsReward := totalReward.MulInt(effectiveDelegations).QuoInt(effectiveStake) + providerCommission := rawDelegatorsReward.MulInt(sdk.NewIntFromUint64(stakeEntry.DelegateCommission)).QuoInt(sdk.NewInt(100)) + providerReward = providerReward.Add(providerCommission...) + } - providerReward = sdk.NewCoin(totalReward.Denom, providerRewardAmount) - return providerReward, totalReward.Sub(providerReward) + return providerReward, totalReward.Sub(providerReward...) } // CalcEffectiveDelegationsAndStake calculates the effective stake and effective delegations (for delegator rewards calculations) @@ -115,12 +116,12 @@ func (k Keeper) CalcEffectiveDelegationsAndStake(stakeEntry epochstoragetypes.St // CalcDelegatorReward calculates a single delegator reward according to its delegation // delegatorReward = delegatorsReward * (delegatorStake / totalDelegations) = (delegatorsReward * delegatorStake) / totalDelegations -func (k Keeper) CalcDelegatorReward(delegatorsReward math.Int, totalDelegations math.Int, delegation types.Delegation) math.Int { +func (k Keeper) CalcDelegatorReward(ctx sdk.Context, delegatorsReward sdk.Coins, totalDelegations math.Int, delegation types.Delegation) sdk.Coins { // Sanity check - totalDelegations != 0 if totalDelegations.IsZero() { - return math.ZeroInt() + return sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) } - return delegatorsReward.Mul(delegation.Amount.Amount).Quo(totalDelegations) + return delegatorsReward.MulInt(delegation.Amount.Amount).QuoInt(totalDelegations) } func (k Keeper) ClaimRewards(ctx sdk.Context, delegator string, provider string) error { @@ -142,17 +143,15 @@ func (k Keeper) ClaimRewards(ctx sdk.Context, delegator string, provider string) continue } - rewardCoins := sdk.Coins{sdk.Coin{Denom: k.stakingKeeper.BondDenom(ctx), Amount: reward.Amount.Amount}} - // not minting new coins because they're minted when the provider // asked for payment (and the delegator reward map was updated) - err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delegatorAcc, rewardCoins) + err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delegatorAcc, reward.Amount) if err != nil { // panic:ok: reward transfer should never fail utils.LavaFormatPanic("critical: failed to send reward to delegator for provider", err, utils.Attribute{Key: "provider", Value: provider}, utils.Attribute{Key: "delegator", Value: delegator}, - utils.Attribute{Key: "reward", Value: rewardCoins}, + utils.Attribute{Key: "reward", Value: reward.Amount.String()}, ) } @@ -165,9 +164,9 @@ func (k Keeper) ClaimRewards(ctx sdk.Context, delegator string, provider string) // RewardProvidersAndDelegators is the main function handling provider rewards with delegations // it returns the provider reward amount and updates the delegatorReward map with the reward portion for each delegator -func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, claimableRewards sdk.Coin, err error) { +func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coins, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coins, claimableRewards sdk.Coins, err error) { block := uint64(ctx.BlockHeight()) - zeroCoin := sdk.NewCoin(totalReward.Denom, math.ZeroInt()) + zeroCoin := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) epoch, _, err := k.epochstorageKeeper.GetEpochStartForBlock(ctx, block) if err != nil { return zeroCoin, zeroCoin, utils.LavaFormatError(types.ErrCalculatingProviderReward.Error(), err, @@ -186,13 +185,12 @@ func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.A claimableRewards = totalReward // make sure this is post boost when rewards pool is introduced contributorAddresses, contributorPart := k.specKeeper.GetContributorReward(ctx, chainID) - contributorsNum := int64(len(contributorAddresses)) - if contributorsNum != 0 && contributorPart.GT(math.LegacyZeroDec()) { - contributorRewardAmount := totalReward.Amount.MulRaw(contributorPart.MulInt64(spectypes.ContributorPrecision).RoundInt64()).QuoRaw(spectypes.ContributorPrecision) + contributorsNum := sdk.NewInt(int64(len(contributorAddresses))) + if !contributorsNum.IsZero() && contributorPart.GT(math.LegacyZeroDec()) { + contributorReward := totalReward.MulInt(contributorPart.MulInt64(spectypes.ContributorPrecision).RoundInt()).QuoInt(sdk.NewInt(spectypes.ContributorPrecision)) // make sure to round it down for the integers division - contributorRewardAmount = contributorRewardAmount.QuoRaw(contributorsNum).MulRaw(contributorsNum) - contributorReward := sdk.NewCoin(totalReward.Denom, contributorRewardAmount) - claimableRewards = totalReward.Sub(contributorReward) + contributorReward = contributorReward.QuoInt(contributorsNum).MulInt(contributorsNum) + claimableRewards = totalReward.Sub(contributorReward...) if !calcOnlyContributer { err = k.PayContributors(ctx, senderModule, contributorAddresses, contributorReward, chainID) if err != nil { @@ -206,39 +204,36 @@ func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.A return d.ChainID == chainID && d.IsFirstMonthPassed(ctx.BlockTime().UTC().Unix()) && d.Delegator != d.Provider }) - providerRewardAmount, delegatorsReward := k.CalcRewards(*stakeEntry, claimableRewards, relevantDelegations) + providerReward, delegatorsReward := k.CalcRewards(ctx, *stakeEntry, claimableRewards, relevantDelegations) leftoverRewards := k.updateDelegatorsReward(ctx, stakeEntry.DelegateTotal.Amount, relevantDelegations, delegatorsReward, senderModule, calcOnlyDelegators) - fullProviderReward := providerRewardAmount.Add(leftoverRewards) + fullProviderReward := providerReward.Add(leftoverRewards...) if !calcOnlyProvider { - if fullProviderReward.Amount.GT(math.ZeroInt()) { - k.rewardDelegator(ctx, types.Delegation{Provider: providerAddr.String(), ChainID: chainID, Delegator: providerAddr.String()}, fullProviderReward, senderModule) - } + k.rewardDelegator(ctx, types.Delegation{Provider: providerAddr.String(), ChainID: chainID, Delegator: providerAddr.String()}, fullProviderReward, senderModule) } return fullProviderReward, claimableRewards, nil } // updateDelegatorsReward updates the delegator rewards map -func (k Keeper) updateDelegatorsReward(ctx sdk.Context, totalDelegations math.Int, delegations []types.Delegation, delegatorsReward sdk.Coin, senderModule string, calcOnly bool) (leftoverRewards sdk.Coin) { - usedDelegatorRewards := sdk.NewCoin(delegatorsReward.Denom, math.ZeroInt()) // the delegator rewards are calculated using int division, so there might be leftovers +func (k Keeper) updateDelegatorsReward(ctx sdk.Context, totalDelegations math.Int, delegations []types.Delegation, delegatorsReward sdk.Coins, senderModule string, calcOnly bool) (leftoverRewards sdk.Coins) { + usedDelegatorRewards := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) // the delegator rewards are calculated using int division, so there might be leftovers for _, delegation := range delegations { - delegatorRewardAmount := k.CalcDelegatorReward(delegatorsReward.Amount, totalDelegations, delegation) - delegatorReward := sdk.NewCoin(delegatorsReward.Denom, delegatorRewardAmount) + delegatorReward := k.CalcDelegatorReward(ctx, delegatorsReward, totalDelegations, delegation) if !calcOnly { k.rewardDelegator(ctx, delegation, delegatorReward, senderModule) } - usedDelegatorRewards = usedDelegatorRewards.Add(delegatorReward) + usedDelegatorRewards = usedDelegatorRewards.Add(delegatorReward...) } - return delegatorsReward.Sub(usedDelegatorRewards) + return delegatorsReward.Sub(usedDelegatorRewards...) } -func (k Keeper) rewardDelegator(ctx sdk.Context, delegation types.Delegation, amount sdk.Coin, senderModule string) { +func (k Keeper) rewardDelegator(ctx sdk.Context, delegation types.Delegation, amount sdk.Coins, senderModule string) { if amount.IsZero() { return } @@ -251,23 +246,22 @@ func (k Keeper) rewardDelegator(ctx sdk.Context, delegation types.Delegation, am delegatorReward.ChainId = delegation.ChainID delegatorReward.Amount = amount } else { - delegatorReward.Amount = delegatorReward.Amount.Add(amount) + delegatorReward.Amount = delegatorReward.Amount.Add(amount...) } k.SetDelegatorReward(ctx, delegatorReward) - err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, senderModule, types.ModuleName, sdk.NewCoins(amount)) + err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, senderModule, types.ModuleName, amount) if err != nil { utils.LavaFormatError("failed to send rewards to module", err, utils.LogAttr("sender", senderModule), utils.LogAttr("amount", amount.String())) } } -func (k Keeper) PayContributors(ctx sdk.Context, senderModule string, contributorAddresses []sdk.AccAddress, contributorReward sdk.Coin, specId string) error { +func (k Keeper) PayContributors(ctx sdk.Context, senderModule string, contributorAddresses []sdk.AccAddress, contributorReward sdk.Coins, specId string) error { if len(contributorAddresses) == 0 { // do not return this error since we don;t want to bail utils.LavaFormatError("contributor addresses for pay are empty", nil) return nil } - rewardPerContributor := contributorReward.Amount.QuoRaw(int64(len(contributorAddresses))) - rewardCoins := sdk.Coins{sdk.NewCoin(contributorReward.Denom, rewardPerContributor)} + rewardCoins := contributorReward.QuoInt(sdk.NewInt(int64(len(contributorAddresses)))) details := map[string]string{ "rewardCoins": rewardCoins.String(), "specId": specId, @@ -275,18 +269,17 @@ func (k Keeper) PayContributors(ctx sdk.Context, senderModule string, contributo leftRewards := contributorReward for i, contributorAddress := range contributorAddresses { details["address."+strconv.Itoa(i)] = contributorAddress.String() - rewardCoin := sdk.NewCoin(contributorReward.Denom, rewardCoins.AmountOf(contributorReward.Denom)) - if leftRewards.IsLT(rewardCoin) { + if !leftRewards.IsAnyGTE(rewardCoins) { return utils.LavaFormatError("trying to pay contributors more than their allowed amount", nil, utils.LogAttr("rewardCoins", rewardCoins.String()), utils.LogAttr("contributorReward", contributorReward.String()), utils.LogAttr("leftRewards", leftRewards.String())) } - leftRewards = leftRewards.Sub(rewardCoin) + leftRewards = leftRewards.Sub(rewardCoins...) err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, senderModule, contributorAddress, rewardCoins) if err != nil { return err } } utils.LogLavaEvent(ctx, k.Logger(ctx), types.ContributorRewardEventName, details, "contributors rewards given") - if leftRewards.Amount.GT(math.ZeroInt()) { + if !leftRewards.IsZero() { utils.LavaFormatError("leftover rewards", nil, utils.LogAttr("rewardCoins", rewardCoins.String()), utils.LogAttr("contributorReward", contributorReward.String()), utils.LogAttr("leftRewards", leftRewards.String())) // we don;t want to bail on this return nil diff --git a/x/dualstaking/types/delegator_reward.pb.go b/x/dualstaking/types/delegator_reward.pb.go index 521f36978c..831a94b1e3 100644 --- a/x/dualstaking/types/delegator_reward.pb.go +++ b/x/dualstaking/types/delegator_reward.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -25,10 +26,10 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type DelegatorReward struct { - Delegator string `protobuf:"bytes,1,opt,name=delegator,proto3" json:"delegator,omitempty"` - Provider string `protobuf:"bytes,2,opt,name=provider,proto3" json:"provider,omitempty"` - ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Amount types.Coin `protobuf:"bytes,4,opt,name=amount,proto3" json:"amount"` + Delegator string `protobuf:"bytes,1,opt,name=delegator,proto3" json:"delegator,omitempty"` + Provider string `protobuf:"bytes,2,opt,name=provider,proto3" json:"provider,omitempty"` + ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` } func (m *DelegatorReward) Reset() { *m = DelegatorReward{} } @@ -85,11 +86,11 @@ func (m *DelegatorReward) GetChainId() string { return "" } -func (m *DelegatorReward) GetAmount() types.Coin { +func (m *DelegatorReward) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Amount } - return types.Coin{} + return nil } func init() { @@ -101,25 +102,26 @@ func init() { } var fileDescriptor_c8b6da054bf40d1f = []byte{ - // 281 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x50, 0xb1, 0x4e, 0xf3, 0x30, - 0x18, 0x8c, 0xff, 0xbf, 0x2a, 0xad, 0x19, 0x90, 0x22, 0x86, 0x34, 0x42, 0xa6, 0x62, 0xaa, 0x84, - 0x64, 0xab, 0x30, 0xb0, 0x17, 0x18, 0x58, 0x33, 0xb2, 0x54, 0x4e, 0x6c, 0xa5, 0x16, 0x89, 0xbf, - 0xc8, 0x71, 0x02, 0xbc, 0x05, 0x6f, 0xc0, 0xeb, 0x74, 0xec, 0xc8, 0x84, 0x50, 0xf2, 0x22, 0x28, - 0x4e, 0x28, 0x74, 0xfa, 0xfc, 0xf9, 0xee, 0x74, 0xf7, 0x1d, 0x66, 0x19, 0xaf, 0xb9, 0x96, 0xd6, - 0x4d, 0x26, 0x2a, 0x9e, 0x95, 0x96, 0x3f, 0x29, 0x9d, 0x32, 0x21, 0x33, 0x99, 0x72, 0x0b, 0x66, - 0x6d, 0xe4, 0x33, 0x37, 0x82, 0x16, 0x06, 0x2c, 0xf8, 0xc1, 0x20, 0xa0, 0xdd, 0xa4, 0x7f, 0x04, - 0xe1, 0x69, 0x0a, 0x29, 0x38, 0x12, 0xeb, 0x5e, 0x3d, 0x3f, 0x24, 0x09, 0x94, 0x39, 0x94, 0x2c, - 0xe6, 0xa5, 0x64, 0xf5, 0x32, 0x96, 0x96, 0x2f, 0x59, 0x02, 0x4a, 0xf7, 0xf8, 0xc5, 0x3b, 0xc2, - 0x27, 0x77, 0x3f, 0x56, 0x91, 0x73, 0xf2, 0xcf, 0xf0, 0x74, 0xef, 0x1e, 0xa0, 0x39, 0x5a, 0x4c, - 0xa3, 0xdf, 0x0f, 0x3f, 0xc4, 0x93, 0xc2, 0x40, 0xad, 0x84, 0x34, 0xc1, 0x3f, 0x07, 0xee, 0x77, - 0x7f, 0x86, 0x27, 0xc9, 0x86, 0x2b, 0xbd, 0x56, 0x22, 0xf8, 0xef, 0xb0, 0x23, 0xb7, 0x3f, 0x08, - 0xff, 0x06, 0x8f, 0x79, 0x0e, 0x95, 0xb6, 0xc1, 0x68, 0x8e, 0x16, 0xc7, 0x57, 0x33, 0xda, 0x27, - 0xa3, 0x5d, 0x32, 0x3a, 0x24, 0xa3, 0xb7, 0xa0, 0xf4, 0x6a, 0xb4, 0xfd, 0x3c, 0xf7, 0xa2, 0x81, - 0xbe, 0xba, 0xdf, 0x36, 0x04, 0xed, 0x1a, 0x82, 0xbe, 0x1a, 0x82, 0xde, 0x5a, 0xe2, 0xed, 0x5a, - 0xe2, 0x7d, 0xb4, 0xc4, 0x7b, 0xbc, 0x4c, 0x95, 0xdd, 0x54, 0x31, 0x4d, 0x20, 0x3f, 0xec, 0xf1, - 0xe5, 0xa0, 0x49, 0xfb, 0x5a, 0xc8, 0x32, 0x1e, 0xbb, 0x7b, 0xaf, 0xbf, 0x03, 0x00, 0x00, 0xff, - 0xff, 0x2c, 0x0a, 0x50, 0x1d, 0x72, 0x01, 0x00, 0x00, + // 300 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x50, 0xbd, 0x4e, 0xf3, 0x30, + 0x14, 0x8d, 0xbf, 0x7e, 0x2a, 0xad, 0x19, 0x90, 0x22, 0x86, 0xb4, 0x42, 0x6e, 0xc5, 0x54, 0x09, + 0x61, 0x53, 0x78, 0x83, 0x02, 0x03, 0x6b, 0x47, 0x96, 0xca, 0x89, 0xad, 0xd4, 0x6a, 0xeb, 0x5b, + 0xd9, 0x4e, 0x80, 0xb7, 0xe0, 0x39, 0x78, 0x92, 0x4a, 0x2c, 0x1d, 0x99, 0x00, 0x25, 0x2f, 0x82, + 0xe2, 0x84, 0xd2, 0x4e, 0x37, 0x37, 0xe7, 0x9e, 0x1f, 0x1f, 0xcc, 0x96, 0x3c, 0xe7, 0x5a, 0x3a, + 0x3f, 0x99, 0xc8, 0xf8, 0xd2, 0x3a, 0xbe, 0x50, 0x3a, 0x65, 0x42, 0x2e, 0x65, 0xca, 0x1d, 0x98, + 0x99, 0x91, 0x4f, 0xdc, 0x08, 0xba, 0x36, 0xe0, 0x20, 0x8c, 0x1a, 0x02, 0xad, 0x26, 0xdd, 0x23, + 0xf4, 0x4f, 0x53, 0x48, 0xc1, 0x1f, 0xb1, 0xea, 0xab, 0xbe, 0xef, 0x93, 0x04, 0xec, 0x0a, 0x2c, + 0x8b, 0xb9, 0x95, 0x2c, 0x1f, 0xc7, 0xd2, 0xf1, 0x31, 0x4b, 0x40, 0xe9, 0x1a, 0x3f, 0x7f, 0x47, + 0xf8, 0xe4, 0xee, 0xd7, 0x6a, 0xea, 0x9d, 0xc2, 0x33, 0xdc, 0xdd, 0xb9, 0x47, 0x68, 0x88, 0x46, + 0xdd, 0xe9, 0xdf, 0x8f, 0xb0, 0x8f, 0x3b, 0x6b, 0x03, 0xb9, 0x12, 0xd2, 0x44, 0xff, 0x3c, 0xb8, + 0xdb, 0xc3, 0x1e, 0xee, 0x24, 0x73, 0xae, 0xf4, 0x4c, 0x89, 0xa8, 0xe5, 0xb1, 0x23, 0xbf, 0x3f, + 0x88, 0x30, 0xc1, 0x6d, 0xbe, 0x82, 0x4c, 0xbb, 0xe8, 0xff, 0xb0, 0x35, 0x3a, 0xbe, 0xee, 0xd1, + 0x3a, 0x19, 0xad, 0x92, 0xd1, 0x26, 0x19, 0xbd, 0x05, 0xa5, 0x27, 0x57, 0x9b, 0xcf, 0x41, 0xf0, + 0xf6, 0x35, 0x18, 0xa5, 0xca, 0xcd, 0xb3, 0x98, 0x26, 0xb0, 0x62, 0xcd, 0x33, 0xea, 0x71, 0x69, + 0xc5, 0x82, 0xb9, 0x97, 0xb5, 0xb4, 0x9e, 0x60, 0xa7, 0x8d, 0xf4, 0xe4, 0x7e, 0x53, 0x10, 0xb4, + 0x2d, 0x08, 0xfa, 0x2e, 0x08, 0x7a, 0x2d, 0x49, 0xb0, 0x2d, 0x49, 0xf0, 0x51, 0x92, 0xe0, 0xf1, + 0x62, 0x4f, 0xeb, 0xa0, 0xf3, 0xe7, 0x83, 0xd6, 0xbd, 0x68, 0xdc, 0xf6, 0xdd, 0xdc, 0xfc, 0x04, + 0x00, 0x00, 0xff, 0xff, 0x3d, 0x8e, 0xbf, 0x24, 0x9e, 0x01, 0x00, 0x00, } func (m *DelegatorReward) Marshal() (dAtA []byte, err error) { @@ -142,16 +144,20 @@ func (m *DelegatorReward) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Amount) > 0 { + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintDelegatorReward(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 } - i -= size - i = encodeVarintDelegatorReward(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x22 if len(m.ChainId) > 0 { i -= len(m.ChainId) copy(dAtA[i:], m.ChainId) @@ -205,8 +211,12 @@ func (m *DelegatorReward) Size() (n int) { if l > 0 { n += 1 + l + sovDelegatorReward(uint64(l)) } - l = m.Amount.Size() - n += 1 + l + sovDelegatorReward(uint64(l)) + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovDelegatorReward(uint64(l)) + } + } return n } @@ -370,7 +380,8 @@ func (m *DelegatorReward) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Amount = append(m.Amount, types.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/dualstaking/types/query.pb.go b/x/dualstaking/types/query.pb.go index 57e725dcc6..939af107fb 100644 --- a/x/dualstaking/types/query.pb.go +++ b/x/dualstaking/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" @@ -411,9 +412,9 @@ func (m *QueryDelegatorRewardsResponse) GetRewards() []DelegatorRewardInfo { } type DelegatorRewardInfo struct { - Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` - ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Amount types.Coin `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount"` + Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount"` } func (m *DelegatorRewardInfo) Reset() { *m = DelegatorRewardInfo{} } @@ -463,11 +464,11 @@ func (m *DelegatorRewardInfo) GetChainId() string { return "" } -func (m *DelegatorRewardInfo) GetAmount() types.Coin { +func (m *DelegatorRewardInfo) GetAmount() github_com_cosmos_cosmos_sdk_types.Coins { if m != nil { return m.Amount } - return types.Coin{} + return nil } func init() { @@ -487,49 +488,51 @@ func init() { } var fileDescriptor_8393eed0cfbc46b2 = []byte{ - // 670 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x41, 0x4f, 0x13, 0x4f, - 0x18, 0xc6, 0x3b, 0xe5, 0xff, 0x2f, 0x30, 0xf5, 0x60, 0x06, 0x0e, 0xa5, 0xc1, 0xa5, 0x6e, 0x30, - 0x36, 0x2a, 0x3b, 0xa1, 0x26, 0x02, 0x9a, 0x18, 0x45, 0x3c, 0x90, 0x48, 0xc4, 0x26, 0x5c, 0xbc, - 0x34, 0xd3, 0xee, 0xb8, 0x4c, 0x6c, 0x67, 0x96, 0x9d, 0x29, 0x48, 0x08, 0x17, 0x13, 0xcf, 0x9a, - 0xf0, 0xa5, 0x48, 0xf4, 0x40, 0xe2, 0xc5, 0x78, 0x30, 0x06, 0xfc, 0x20, 0x66, 0x67, 0x67, 0xeb, - 0x2e, 0x65, 0xd9, 0x62, 0xe2, 0x69, 0xbb, 0xef, 0x3c, 0x33, 0xcf, 0xfb, 0x9b, 0x37, 0xcf, 0x16, - 0xce, 0x77, 0xc9, 0x2e, 0xe1, 0x54, 0xe1, 0xf0, 0x89, 0xdd, 0x3e, 0xe9, 0x4a, 0x45, 0xde, 0x32, - 0xee, 0xe1, 0x9d, 0x3e, 0x0d, 0xf6, 0x1d, 0x3f, 0x10, 0x4a, 0xa0, 0x8a, 0x51, 0x39, 0xe1, 0xd3, - 0x49, 0xa8, 0xaa, 0xd3, 0x9e, 0xf0, 0x84, 0x16, 0xe1, 0xf0, 0x57, 0xa4, 0xaf, 0xce, 0x7a, 0x42, - 0x78, 0x5d, 0x8a, 0x89, 0xcf, 0x30, 0xe1, 0x5c, 0x28, 0xa2, 0x98, 0xe0, 0xd2, 0xac, 0xde, 0xe9, - 0x08, 0xd9, 0x13, 0x12, 0xb7, 0x89, 0xa4, 0x91, 0x0d, 0xde, 0x5d, 0x6c, 0x53, 0x45, 0x16, 0xb1, - 0x4f, 0x3c, 0xc6, 0xb5, 0xd8, 0x68, 0x6f, 0x65, 0xf6, 0xe7, 0x93, 0x80, 0xf4, 0xe2, 0x23, 0x6f, - 0x67, 0xca, 0x5c, 0xda, 0xa5, 0x1e, 0x51, 0xd4, 0x08, 0xad, 0xa4, 0x77, 0xec, 0xda, 0x11, 0xcc, - 0xf8, 0xd9, 0xd3, 0x10, 0xbd, 0x0a, 0x3b, 0xda, 0xd4, 0xa7, 0x37, 0xe9, 0x4e, 0x9f, 0x4a, 0x65, - 0x6f, 0xc1, 0xa9, 0x54, 0x55, 0xfa, 0x82, 0x4b, 0x8a, 0x1e, 0xc3, 0x52, 0xd4, 0x45, 0x05, 0xd4, - 0x40, 0xbd, 0xdc, 0xa8, 0x39, 0x59, 0xf7, 0xe4, 0x44, 0x3b, 0x57, 0xff, 0x3b, 0xfe, 0x31, 0x57, - 0x68, 0x9a, 0x5d, 0x36, 0x81, 0x96, 0x3e, 0x76, 0x2d, 0xea, 0x51, 0x04, 0x9b, 0x81, 0xd8, 0x65, - 0x2e, 0x0d, 0x62, 0x63, 0x34, 0x0b, 0x27, 0xdd, 0x78, 0x51, 0x9b, 0x4c, 0x36, 0xff, 0x14, 0xd0, - 0x4d, 0x78, 0x6d, 0x8f, 0xa9, 0xed, 0x96, 0x4f, 0xb9, 0xcb, 0xb8, 0x57, 0x29, 0xd6, 0x40, 0x7d, - 0xa2, 0x59, 0x0e, 0x6b, 0x9b, 0x51, 0xc9, 0x16, 0x70, 0x2e, 0xd3, 0xc2, 0x50, 0xbc, 0x80, 0x65, - 0x73, 0x64, 0x38, 0xa3, 0x0a, 0xa8, 0x8d, 0xd5, 0xcb, 0x8d, 0xf9, 0x6c, 0x94, 0xb5, 0x81, 0xd8, - 0xe0, 0x24, 0xb7, 0xdb, 0x2d, 0xc3, 0x14, 0xfb, 0x0c, 0x8c, 0x07, 0x4c, 0x55, 0x38, 0xe1, 0x9b, - 0x45, 0x83, 0x34, 0x78, 0xbf, 0x0a, 0xd1, 0x45, 0x06, 0xff, 0x84, 0x48, 0xc2, 0xd9, 0xf4, 0x15, - 0x36, 0xe9, 0x1e, 0x09, 0xdc, 0x11, 0x67, 0x94, 0xa4, 0x2d, 0x9e, 0xa3, 0x9d, 0x81, 0x13, 0x9d, - 0x6d, 0xc2, 0x78, 0x8b, 0xb9, 0x95, 0x31, 0xbd, 0x36, 0xae, 0xdf, 0xd7, 0x5d, 0x9b, 0xc3, 0x1b, - 0x19, 0xa6, 0x86, 0x71, 0x03, 0x8e, 0x07, 0x51, 0xc9, 0xf0, 0x2d, 0xe4, 0xf2, 0xc5, 0x87, 0xac, - 0xf3, 0x37, 0xc2, 0x80, 0xc6, 0x67, 0xd8, 0x1f, 0x00, 0x9c, 0xba, 0x40, 0x76, 0xe9, 0xb0, 0x92, - 0xed, 0x17, 0x53, 0xed, 0xa3, 0x25, 0x58, 0x22, 0x3d, 0xd1, 0xe7, 0x4a, 0x73, 0x95, 0x1b, 0x33, - 0x4e, 0x94, 0x3b, 0x27, 0xcc, 0x9d, 0x63, 0x72, 0xe7, 0x3c, 0x13, 0x2c, 0xbe, 0x71, 0x23, 0x6f, - 0x1c, 0x95, 0xe0, 0xff, 0x1a, 0x1c, 0x7d, 0x04, 0xb0, 0x14, 0xa5, 0x06, 0xdd, 0xcb, 0x46, 0x1b, - 0x0e, 0x6b, 0x75, 0x61, 0x44, 0x75, 0x74, 0x91, 0x76, 0xfd, 0xfd, 0xd7, 0x5f, 0x47, 0x45, 0x1b, - 0xd5, 0x70, 0xce, 0xa7, 0x06, 0x7d, 0x01, 0x10, 0x0d, 0xe7, 0x08, 0x2d, 0xe7, 0xf8, 0x65, 0xa6, - 0xbb, 0xba, 0xf2, 0x17, 0x3b, 0x4d, 0xd7, 0x4f, 0x75, 0xd7, 0x8f, 0xd0, 0x0a, 0xce, 0xfb, 0xf2, - 0x89, 0xa0, 0x15, 0x4f, 0x4c, 0xe2, 0x83, 0x41, 0xf1, 0x10, 0x7d, 0x06, 0x10, 0x0d, 0x87, 0x28, - 0x17, 0x27, 0x33, 0xd8, 0xb9, 0x38, 0xd9, 0x89, 0xb5, 0x9f, 0x68, 0x9c, 0x87, 0x68, 0xf9, 0x92, - 0x21, 0x98, 0xdd, 0xad, 0x01, 0x82, 0xc4, 0x07, 0x71, 0xf1, 0x10, 0x7d, 0x07, 0xf0, 0xfa, 0xf9, - 0xb0, 0xa0, 0x07, 0xa3, 0x5e, 0x70, 0x3a, 0xd2, 0xd5, 0xa5, 0x2b, 0xef, 0x33, 0x1c, 0x5b, 0x9a, - 0xe3, 0x25, 0xda, 0x18, 0x65, 0x2c, 0x26, 0x7b, 0xc9, 0xa1, 0x24, 0x88, 0xf0, 0x41, 0x1c, 0xae, - 0xc3, 0xd5, 0xe7, 0xc7, 0xa7, 0x16, 0x38, 0x39, 0xb5, 0xc0, 0xcf, 0x53, 0x0b, 0x7c, 0x3a, 0xb3, - 0x0a, 0x27, 0x67, 0x56, 0xe1, 0xdb, 0x99, 0x55, 0x78, 0x7d, 0xd7, 0x63, 0x6a, 0xbb, 0xdf, 0x76, - 0x3a, 0xa2, 0x97, 0xb6, 0x7c, 0x97, 0x32, 0x55, 0xfb, 0x3e, 0x95, 0xed, 0x92, 0xfe, 0x8f, 0xbb, - 0xff, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x17, 0xcc, 0x53, 0x88, 0xf5, 0x07, 0x00, 0x00, + // 695 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x41, 0x4f, 0x13, 0x41, + 0x14, 0xee, 0x14, 0x2d, 0x30, 0xf5, 0x60, 0x06, 0x0e, 0xa5, 0xc1, 0xa5, 0x6e, 0x30, 0x36, 0x2a, + 0x3b, 0x82, 0x89, 0x82, 0x26, 0x46, 0x11, 0x0f, 0x24, 0x12, 0xb1, 0x09, 0x17, 0x2f, 0xcd, 0xb4, + 0x3b, 0x2e, 0x13, 0xda, 0x99, 0x65, 0x67, 0x0a, 0x12, 0xc2, 0xc5, 0x3f, 0xa0, 0x09, 0xff, 0xc2, + 0x9b, 0xff, 0x82, 0x44, 0x0f, 0x24, 0x5e, 0x8c, 0x07, 0x35, 0xe0, 0x0f, 0x31, 0x3b, 0x3b, 0x5b, + 0x77, 0x81, 0x65, 0x8b, 0x89, 0xa7, 0xe9, 0xbe, 0xf9, 0xde, 0xfb, 0xde, 0xf7, 0x5e, 0xbe, 0x29, + 0x9c, 0xee, 0x90, 0x2d, 0xc2, 0xa9, 0xc2, 0xe1, 0x89, 0xdd, 0x1e, 0xe9, 0x48, 0x45, 0x36, 0x18, + 0xf7, 0xf0, 0x66, 0x8f, 0x06, 0x3b, 0x8e, 0x1f, 0x08, 0x25, 0x50, 0xc5, 0xa0, 0x9c, 0xf0, 0x74, + 0x12, 0xa8, 0xea, 0xb8, 0x27, 0x3c, 0xa1, 0x41, 0x38, 0xfc, 0x15, 0xe1, 0xab, 0x93, 0x9e, 0x10, + 0x5e, 0x87, 0x62, 0xe2, 0x33, 0x4c, 0x38, 0x17, 0x8a, 0x28, 0x26, 0xb8, 0x34, 0xb7, 0xb7, 0xda, + 0x42, 0x76, 0x85, 0xc4, 0x2d, 0x22, 0x69, 0x44, 0x83, 0xb7, 0x66, 0x5b, 0x54, 0x91, 0x59, 0xec, + 0x13, 0x8f, 0x71, 0x0d, 0x36, 0xd8, 0x1b, 0x99, 0xfd, 0xf9, 0x24, 0x20, 0xdd, 0xb8, 0xe4, 0xcd, + 0x4c, 0x98, 0x4b, 0x3b, 0xd4, 0x23, 0x8a, 0x1a, 0xa0, 0x95, 0xe4, 0x8e, 0x59, 0xdb, 0x82, 0x19, + 0x3e, 0x7b, 0x1c, 0xa2, 0x57, 0x61, 0x47, 0xab, 0xba, 0x7a, 0x83, 0x6e, 0xf6, 0xa8, 0x54, 0xf6, + 0x1a, 0x1c, 0x4b, 0x45, 0xa5, 0x2f, 0xb8, 0xa4, 0xe8, 0x31, 0x2c, 0x45, 0x5d, 0x54, 0x40, 0x0d, + 0xd4, 0xcb, 0x73, 0x35, 0x27, 0x6b, 0x4e, 0x4e, 0x94, 0xb9, 0x78, 0xe9, 0xe0, 0xc7, 0x54, 0xa1, + 0x61, 0xb2, 0x6c, 0x02, 0x2d, 0x5d, 0x76, 0x29, 0xea, 0x51, 0x04, 0xab, 0x81, 0xd8, 0x62, 0x2e, + 0x0d, 0x62, 0x62, 0x34, 0x09, 0x47, 0xdd, 0xf8, 0x52, 0x93, 0x8c, 0x36, 0xfe, 0x06, 0xd0, 0x75, + 0x78, 0x65, 0x9b, 0xa9, 0xf5, 0xa6, 0x4f, 0xb9, 0xcb, 0xb8, 0x57, 0x29, 0xd6, 0x40, 0x7d, 0xa4, + 0x51, 0x0e, 0x63, 0xab, 0x51, 0xc8, 0x16, 0x70, 0x2a, 0x93, 0xc2, 0xa8, 0x78, 0x01, 0xcb, 0xa6, + 0x64, 0xb8, 0xa3, 0x0a, 0xa8, 0x0d, 0xd5, 0xcb, 0x73, 0xd3, 0xd9, 0x52, 0x96, 0xfa, 0x60, 0x23, + 0x27, 0x99, 0x6e, 0x37, 0x8d, 0xa6, 0x98, 0xa7, 0x4f, 0xdc, 0xd7, 0x54, 0x85, 0x23, 0xbe, 0xb9, + 0x34, 0x92, 0xfa, 0xdf, 0x17, 0x51, 0x74, 0x16, 0xc1, 0x7f, 0x51, 0x24, 0xe1, 0x64, 0x7a, 0x84, + 0x0d, 0xba, 0x4d, 0x02, 0x77, 0xc0, 0x1d, 0x25, 0xd5, 0x16, 0x4f, 0xa8, 0x9d, 0x80, 0x23, 0xed, + 0x75, 0xc2, 0x78, 0x93, 0xb9, 0x95, 0x21, 0x7d, 0x37, 0xac, 0xbf, 0x97, 0x5d, 0x9b, 0xc3, 0x6b, + 0x19, 0xa4, 0x46, 0xe3, 0x0a, 0x1c, 0x0e, 0xa2, 0x90, 0xd1, 0x37, 0x93, 0xab, 0x2f, 0x2e, 0xb2, + 0xcc, 0xdf, 0x08, 0x23, 0x34, 0xae, 0x61, 0x7f, 0x02, 0x70, 0xec, 0x0c, 0xd8, 0xb9, 0xcb, 0x4a, + 0xb6, 0x5f, 0x4c, 0xb5, 0x8f, 0xda, 0xb0, 0x44, 0xba, 0xa2, 0xc7, 0x55, 0x65, 0x48, 0x37, 0x37, + 0xe1, 0x44, 0xbe, 0x73, 0x42, 0xdf, 0x39, 0xc6, 0x77, 0xce, 0x33, 0xc1, 0xf8, 0xe2, 0xdd, 0xb0, + 0x91, 0x8f, 0x3f, 0xa7, 0xea, 0x1e, 0x53, 0xeb, 0xbd, 0x96, 0xd3, 0x16, 0x5d, 0x6c, 0x4c, 0x1a, + 0x1d, 0x33, 0xd2, 0xdd, 0xc0, 0x6a, 0xc7, 0xa7, 0x52, 0x27, 0xc8, 0x86, 0x29, 0x3d, 0xb7, 0x5f, + 0x82, 0x97, 0xf5, 0x90, 0xd0, 0x7b, 0x00, 0x4b, 0x91, 0xc3, 0xd0, 0x9d, 0xec, 0x31, 0x9c, 0x36, + 0x76, 0x75, 0x66, 0x40, 0x74, 0x34, 0x74, 0xbb, 0xfe, 0xee, 0xeb, 0xef, 0xfd, 0xa2, 0x8d, 0x6a, + 0x38, 0xe7, 0x59, 0x42, 0x5f, 0x00, 0x44, 0xa7, 0x3d, 0x87, 0xe6, 0x73, 0xf8, 0x32, 0x5f, 0x82, + 0xea, 0xc2, 0x3f, 0x64, 0x9a, 0xae, 0x9f, 0xea, 0xae, 0x1f, 0xa1, 0x05, 0x9c, 0xf7, 0x4a, 0x8a, + 0xa0, 0x19, 0x6f, 0x57, 0xe2, 0xdd, 0x7e, 0x70, 0x0f, 0x7d, 0x06, 0x10, 0x9d, 0x36, 0x5c, 0xae, + 0x9c, 0xcc, 0x47, 0x20, 0x57, 0x4e, 0xb6, 0xbb, 0xed, 0x27, 0x5a, 0xce, 0x43, 0x34, 0x7f, 0xce, + 0x12, 0x4c, 0x76, 0xb3, 0x2f, 0x41, 0xe2, 0xdd, 0x38, 0xb8, 0x87, 0xbe, 0x03, 0x78, 0xf5, 0xa4, + 0xb1, 0xd0, 0xfd, 0x41, 0x07, 0x9c, 0xb6, 0x7f, 0xf5, 0xc1, 0x85, 0xf3, 0x8c, 0x8e, 0x35, 0xad, + 0xe3, 0x25, 0x5a, 0x19, 0x64, 0x2d, 0xc6, 0xa7, 0xc9, 0xa5, 0x24, 0x14, 0xe1, 0xdd, 0xd8, 0x88, + 0x7b, 0x8b, 0xcf, 0x0f, 0x8e, 0x2c, 0x70, 0x78, 0x64, 0x81, 0x5f, 0x47, 0x16, 0xf8, 0x70, 0x6c, + 0x15, 0x0e, 0x8f, 0xad, 0xc2, 0xb7, 0x63, 0xab, 0xf0, 0xfa, 0x76, 0xc2, 0x61, 0x29, 0xca, 0xb7, + 0x29, 0x52, 0x6d, 0xb5, 0x56, 0x49, 0xff, 0x1f, 0xde, 0xfb, 0x13, 0x00, 0x00, 0xff, 0xff, 0x87, + 0xee, 0x91, 0xfe, 0x21, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1039,16 +1042,20 @@ func (m *DelegatorRewardInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Amount) > 0 { + for iNdEx := len(m.Amount) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amount[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x1a if len(m.ChainId) > 0 { i -= len(m.ChainId) copy(dAtA[i:], m.ChainId) @@ -1209,8 +1216,12 @@ func (m *DelegatorRewardInfo) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - l = m.Amount.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.Amount) > 0 { + for _, e := range m.Amount { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -2077,7 +2088,8 @@ func (m *DelegatorRewardInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Amount = append(m.Amount, types.Coin{}) + if err := m.Amount[len(m.Amount)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/pairing/client/cli/query_debug_query.go b/x/pairing/client/cli/query_debug_query.go index 4e582b971a..a13ef15fab 100644 --- a/x/pairing/client/cli/query_debug_query.go +++ b/x/pairing/client/cli/query_debug_query.go @@ -96,7 +96,7 @@ func CmdDebugQuery() *cobra.Command { } else if len(resDelegatorRewards.Rewards) != 1 { info.ProviderFullReward = 0 } else { - info.ProviderFullReward = resDelegatorRewards.Rewards[0].Amount.Amount.Uint64() + info.ProviderFullReward = resDelegatorRewards.Rewards[0].Amount.AmountOf(commontypes.TokenDenom).Uint64() } // provider rewards without bonuses diff --git a/x/pairing/keeper/cu_tracker_test.go b/x/pairing/keeper/cu_tracker_test.go index c0ec6c471e..9cd2273574 100644 --- a/x/pairing/keeper/cu_tracker_test.go +++ b/x/pairing/keeper/cu_tracker_test.go @@ -166,7 +166,7 @@ func TestTrackedCuWithDelegations(t *testing.T) { // sanity check - delegator reward should be 34% of the reward (which is the plan price) res, err := ts.QueryDualstakingDelegatorRewards(delegator, provider, ts.spec.Index) require.NoError(t, err) - require.Equal(t, ts.plan.Price.Amount.Int64()*34/100, res.Rewards[0].Amount.Amount.Int64()) + require.Equal(t, ts.plan.Price.Amount.Int64()*34/100, res.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64()) } // TestTrackedCuWithQos checks that the tracked CU is counted properly when considering QoS @@ -263,13 +263,13 @@ func TestTrackedCuWithQos(t *testing.T) { reward, err := ts.QueryDualstakingDelegatorRewards(provider1Acc.Addr.String(), provider1Acc.Addr.String(), ts.spec.Index) require.Nil(ts.T, err) require.Len(t, reward.Rewards, 1) - require.Equal(ts.T, tt.p1ExpectedReward, reward.Rewards[0].Amount.Amount.Int64()) + require.Equal(ts.T, tt.p1ExpectedReward, reward.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64()) _, err = ts.TxDualstakingClaimRewards(provider1Acc.Addr.String(), provider1Acc.Addr.String()) require.Nil(ts.T, err) reward, err = ts.QueryDualstakingDelegatorRewards(provider2Acc.Addr.String(), provider2Acc.Addr.String(), ts.spec.Index) require.Nil(ts.T, err) - require.Equal(ts.T, tt.p2ExpectedReward, reward.Rewards[0].Amount.Amount.Int64()) + require.Equal(ts.T, tt.p2ExpectedReward, reward.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64()) _, err = ts.TxDualstakingClaimRewards(provider2Acc.Addr.String(), provider2Acc.Addr.String()) require.Nil(ts.T, err) @@ -370,7 +370,7 @@ func TestTrackedCuPlanPriceChange(t *testing.T) { reward, err := ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), ts.spec.Index) require.Nil(ts.T, err) - require.Equal(ts.T, originalPlanPrice, reward.Rewards[0].Amount.Amount.Int64()) + require.Equal(ts.T, originalPlanPrice, reward.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64()) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.Nil(ts.T, err) @@ -656,7 +656,7 @@ func TestFrozenProviderGetReward(t *testing.T) { planPrice := ts.plan.Price.Amount.Int64() reward, err := ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), ts.spec.Index) require.Nil(ts.T, err) - require.Equal(ts.T, planPrice, reward.Rewards[0].Amount.Amount.Int64()) + require.Equal(ts.T, planPrice, reward.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64()) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.Nil(ts.T, err) diff --git a/x/pairing/keeper/delegator_rewards_test.go b/x/pairing/keeper/delegator_rewards_test.go index e62606da79..489dd79365 100644 --- a/x/pairing/keeper/delegator_rewards_test.go +++ b/x/pairing/keeper/delegator_rewards_test.go @@ -130,7 +130,7 @@ func TestProviderDelegatorsRewards(t *testing.T) { if tt.d1Reward == 0 { require.Len(t, resRewards1.Rewards, 0) } else { - d1Reward = resRewards1.Rewards[0].Amount.Amount.Int64() + d1Reward = resRewards1.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64() require.Equal(t, tt.d1Reward, d1Reward) // claim delegator rewards and verify balance delegator1Addr, err := sdk.AccAddressFromBech32(delegator1) @@ -142,7 +142,7 @@ func TestProviderDelegatorsRewards(t *testing.T) { if tt.d2Reward == 0 { require.Len(t, resRewards2.Rewards, 0) } else { - d2Reward = resRewards2.Rewards[0].Amount.Amount.Int64() + d2Reward = resRewards2.Rewards[0].Amount.AmountOf(ts.BondDenom()).Int64() require.Equal(t, tt.d2Reward, d2Reward) // claim delegator rewards and verify balance delegator2Addr, err := sdk.AccAddressFromBech32(delegator2) @@ -285,10 +285,10 @@ func TestProviderRewardWithCommission(t *testing.T) { func(d dualstakingtypes.Delegation) bool { return d.ChainID == ts.spec.Index && d.IsFirstMonthPassed(currentTimestamp) }) - totalReward := sdk.NewCoin(ts.TokenDenom(), math.NewInt(int64(relayCuSum))) - providerReward, _ := ts.Keepers.Dualstaking.CalcRewards(stakeEntry, totalReward, relevantDelegations) + totalReward := sdk.NewCoins(sdk.NewCoin(ts.TokenDenom(), math.NewInt(int64(relayCuSum)))) + providerReward, _ := ts.Keepers.Dualstaking.CalcRewards(ts.Ctx, stakeEntry, totalReward, relevantDelegations) - require.True(t, totalReward.Equal(providerReward)) + require.True(t, totalReward.IsEqual(providerReward)) // check that the expected reward equals to the provider's new balance minus old balance relayPaymentMessage := sendRelay(ts, provider, clientAcc, []string{ts.spec.Index}) @@ -315,7 +315,7 @@ func TestProviderRewardWithCommission(t *testing.T) { require.Equal(t, 1, len(resRewards.Rewards)) dReward := resRewards.Rewards[0] expectedDRewardForRelay := totalReward - require.Equal(t, expectedDRewardForRelay.Amount.Int64()/2, dReward.Amount.Amount.Int64()) + require.Equal(t, expectedDRewardForRelay.AmountOf(ts.BondDenom()).Int64()/2, dReward.Amount.AmountOf(ts.BondDenom()).Int64()) // claim delegator rewards and verify balance claimRewardsAndVerifyBalance(ts, delegator1Acc.Addr, provider, ts.spec.Index) @@ -332,7 +332,7 @@ func claimRewardsAndVerifyBalance(ts *tester, delegator sdk.AccAddress, provider require.Nil(ts.T, err) newBalance := ts.GetBalance(delegator) - require.Equal(ts.T, balance+reward.Amount.Amount.Int64(), newBalance) + require.Equal(ts.T, balance+reward.Amount.AmountOf(ts.BondDenom()).Int64(), newBalance) res, err = ts.QueryDualstakingDelegatorRewards(delegator.String(), provider, chainID) require.Nil(ts.T, err) @@ -424,7 +424,7 @@ func TestQueryDelegatorRewards(t *testing.T) { require.NoError(t, err) delegatorReward := int64(0) for _, reward := range res.Rewards { - delegatorReward += reward.Amount.Amount.Int64() + delegatorReward += reward.Amount.AmountOf(ts.BondDenom()).Int64() } require.Equal(t, tt.expectedRewards, delegatorReward) }) @@ -564,11 +564,11 @@ func TestDelegationFirstMonthReward(t *testing.T) { // the delegation will already mature enough to be part of the reward process. To go around // this, we'll call the reward calculation function directly with a fabricated reward just to // verify that the delegator gets nothing from the total reward - fakeReward := sdk.NewCoin(ts.TokenDenom(), sdk.NewInt(testStake)) + fakeReward := sdk.NewCoins(sdk.NewCoin(ts.TokenDenom(), sdk.NewInt(testStake))) providerReward, _, err := ts.Keepers.Dualstaking.RewardProvidersAndDelegators(ts.Ctx, providerAcc.Addr, ts.spec.Index, fakeReward, subscriptiontypes.ModuleName, true, true, true) require.NoError(t, err) - require.True(t, fakeReward.Equal(providerReward)) // if the delegator got anything, this would fail + require.True(t, fakeReward.IsEqual(providerReward)) // if the delegator got anything, this would fail // verify again that the delegator has no unclaimed rewards resRewards, err := ts.QueryDualstakingDelegatorRewards(delegator, provider, ts.spec.Index) @@ -628,15 +628,15 @@ func TestRedelegationFirstMonthReward(t *testing.T) { // this, we'll call the reward calculation function directly with a fabricated reward just to // verify that the delegator gets nothing from the total reward from provider1 but does get // reward from provider - fakeReward := sdk.NewCoin(ts.TokenDenom(), sdk.NewInt(testStake)) + fakeReward := sdk.NewCoins(sdk.NewCoin(ts.TokenDenom(), sdk.NewInt(testStake))) provider1Reward, _, err := ts.Keepers.Dualstaking.RewardProvidersAndDelegators(ts.Ctx, provider1Acc.Addr, ts.spec.Index, fakeReward, subscriptiontypes.ModuleName, true, false, true) require.NoError(t, err) - require.True(t, fakeReward.Equal(provider1Reward)) // if the delegator got anything, this would fail + require.True(t, fakeReward.IsEqual(provider1Reward)) // if the delegator got anything, this would fail providerReward, _, err := ts.Keepers.Dualstaking.RewardProvidersAndDelegators(ts.Ctx, providerAcc.Addr, ts.spec.Index, fakeReward, subscriptiontypes.ModuleName, true, false, true) require.NoError(t, err) - require.False(t, fakeReward.Equal(providerReward)) // the delegator should have rewards + require.False(t, fakeReward.IsEqual(providerReward)) // the delegator should have rewards // verify again that the delegator has no unclaimed rewards with provider1 but has some with provider resRewards, err := ts.QueryDualstakingDelegatorRewards(delegator, provider1, ts.spec.Index) diff --git a/x/pairing/keeper/grpc_query_provider_monthly_payout.go b/x/pairing/keeper/grpc_query_provider_monthly_payout.go index 97796de386..6e141e5fed 100644 --- a/x/pairing/keeper/grpc_query_provider_monthly_payout.go +++ b/x/pairing/keeper/grpc_query_provider_monthly_payout.go @@ -74,7 +74,7 @@ func (k Keeper) ProviderMonthlyPayout(goCtx context.Context, req *types.QueryPro totalMonthlyReward := k.subscriptionKeeper.CalcTotalMonthlyReward(ctx, totalTokenAmount, providerCu, totalCuTracked) // calculate only the provider reward - providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), totalMonthlyReward), subsciptiontypes.ModuleName, true, true, true) + providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), totalMonthlyReward)), subsciptiontypes.ModuleName, true, true, true) if err != nil { return nil, err } @@ -82,9 +82,9 @@ func (k Keeper) ProviderMonthlyPayout(goCtx context.Context, req *types.QueryPro details = append(details, &types.SubscriptionPayout{ Subscription: sub, ChainId: chainID, - Amount: providerReward.Amount.Uint64(), + Amount: providerReward.AmountOf(k.stakingKeeper.BondDenom(ctx)).Uint64(), }) - total += providerReward.Amount.Uint64() + total += providerReward.AmountOf(k.stakingKeeper.BondDenom(ctx)).Uint64() } } diff --git a/x/pairing/keeper/helpers_test.go b/x/pairing/keeper/helpers_test.go index f07e13d57e..832b7ae4b3 100644 --- a/x/pairing/keeper/helpers_test.go +++ b/x/pairing/keeper/helpers_test.go @@ -241,7 +241,7 @@ func (ts *tester) payAndVerifyBalance( reward, err := ts.QueryDualstakingDelegatorRewards(providerAddr.String(), providerAddr.String(), "") require.Nil(ts.T, err) for _, reward := range reward.Rewards { - want = want.Sub(reward.Amount.Amount) + want = want.Sub(reward.Amount.AmountOf(ts.BondDenom())) } require.True(ts.T, want.IsZero()) _, err = ts.TxDualstakingClaimRewards(providerAddr.String(), providerAddr.String()) diff --git a/x/pairing/types/expected_keepers.go b/x/pairing/types/expected_keepers.go index 258ca6302f..1f1dca13ac 100644 --- a/x/pairing/types/expected_keepers.go +++ b/x/pairing/types/expected_keepers.go @@ -102,7 +102,7 @@ type DowntimeKeeper interface { } type DualstakingKeeper interface { - RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, totalRewards sdk.Coin, err error) + RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coins, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coins, totalRewards sdk.Coins, err error) DelegateFull(ctx sdk.Context, delegator string, validator string, provider string, chainID string, amount sdk.Coin) error UnbondFull(ctx sdk.Context, delegator string, validator string, provider string, chainID string, amount sdk.Coin, unstake bool) error } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 45c5d623e0..28e5bb9a81 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -59,53 +59,60 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { for _, spec := range specs { // all providers basepays and the total basepay of the spec basepays, totalbasepay := k.specProvidersBasePay(ctx, spec.ChainID) - if totalbasepay.IsZero() { + if len(basepays) == 0 { continue } // calculate the maximum rewards for the spec - specTotalPayout := k.specTotalPayout(ctx, total, sdk.NewDecFromInt(totalbasepay), spec) + specTotalPayout := math.LegacyZeroDec() + if !totalbasepay.IsZero() { + specTotalPayout = k.specTotalPayout(ctx, total, sdk.NewDecFromInt(totalbasepay), spec) + } // distribute the rewards to all providers for _, basepay := range basepays { - // count iprpc cu - specCu, ok := specCuMap[spec.ChainID] - if !ok { - specCuMap[spec.ChainID] = types.SpecCuType{ - ProvidersCu: map[string]uint64{basepay.Provider: basepay.IprpcCu}, - TotalCu: basepay.IprpcCu, + if !specTotalPayout.IsZero() { + // calculate the providers bonus base on adjusted base pay + reward := specTotalPayout.Mul(basepay.TotalAdjusted).QuoInt(totalbasepay).TruncateInt() + totalRewarded = totalRewarded.Add(reward) + if totalRewarded.GT(total) { + utils.LavaFormatError("provider rewards are larger than the distribution pool balance", nil, + utils.LogAttr("distribution_pool_balance", total.String()), + utils.LogAttr("provider_reward", totalRewarded.String())) + details["error"] = "provider rewards are larger than the distribution pool balance" + return } - } else { - _, ok := specCu.ProvidersCu[basepay.Provider] - if !ok { - specCu.ProvidersCu[basepay.Provider] = basepay.IprpcCu - } else { - specCu.ProvidersCu[basepay.Provider] += basepay.IprpcCu + // now give the reward the provider contributor and delegators + providerAddr, err := sdk.AccAddressFromBech32(basepay.Provider) + if err != nil { + continue + } + _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, basepay.ChainID, sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), reward)), string(types.ProviderRewardsDistributionPool), false, false, false) + if err != nil { + utils.LavaFormatError("failed to send bonus rewards to provider", err, utils.LogAttr("provider", basepay.Provider)) } - specCu.TotalCu += basepay.IprpcCu - specCuMap[spec.ChainID] = specCu - } - // calculate the providers bonus base on adjusted base pay - reward := specTotalPayout.Mul(basepay.TotalAdjusted).QuoInt(totalbasepay).TruncateInt() - totalRewarded = totalRewarded.Add(reward) - if totalRewarded.GT(total) { - utils.LavaFormatError("provider rewards are larger than the distribution pool balance", nil, - utils.LogAttr("distribution_pool_balance", total.String()), - utils.LogAttr("provider_reward", totalRewarded.String())) - details["error"] = "provider rewards are larger than the distribution pool balance" - return - } - // now give the reward the provider contributor and delegators - providerAddr, err := sdk.AccAddressFromBech32(basepay.Provider) - if err != nil { - continue - } - _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, basepay.ChainID, sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), reward), string(types.ProviderRewardsDistributionPool), false, false, false) - if err != nil { - utils.LavaFormatError("failed to send bonus rewards to provider", err, utils.LogAttr("provider", basepay.Provider)) + details[providerAddr.String()+" "+spec.ChainID] = reward.String() } - details[providerAddr.String()+" "+spec.ChainID] = reward.String() + // count iprpc cu + if basepay.IprpcCu != 0 { + specCu, ok := specCuMap[spec.ChainID] + if !ok { + specCuMap[spec.ChainID] = types.SpecCuType{ + ProvidersCu: map[string]uint64{basepay.Provider: basepay.IprpcCu}, + TotalCu: basepay.IprpcCu, + } + } else { + _, ok := specCu.ProvidersCu[basepay.Provider] + if !ok { + specCu.ProvidersCu[basepay.Provider] = basepay.IprpcCu + } else { + specCu.ProvidersCu[basepay.Provider] += basepay.IprpcCu + } + specCu.TotalCu += basepay.IprpcCu + specCuMap[spec.ChainID] = specCu + } + } } } @@ -165,19 +172,15 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { continue } // calculate provider IPRPC reward - providerIprpcRewardPerc := math.LegacyNewDec(int64(specCu.ProvidersCu[provider])).QuoInt64(int64(specCu.TotalCu)) + providerIprpcReward := specFund.Fund.MulInt(sdk.NewIntFromUint64(specCu.ProvidersCu[provider])).QuoInt(sdk.NewIntFromUint64(specCu.TotalCu)) - for _, reward := range specFund.Fund { - // reward the provider - providerIprpcRewardAmount := providerIprpcRewardPerc.MulInt(reward.Amount).TruncateInt() - providerIprpcReward := sdk.NewCoin(reward.Denom, providerIprpcRewardAmount) - _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, specFund.Spec, providerIprpcReward, string(types.IprpcPoolName), false, false, false) - if err != nil { - utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", provider)) - } - - usedReward = usedReward.Add(providerIprpcReward) + // reward the provider + _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, specFund.Spec, providerIprpcReward, string(types.IprpcPoolName), false, false, false) + if err != nil { + utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", provider)) } + + usedReward = usedReward.Add(providerIprpcReward...) } // handle leftovers diff --git a/x/rewards/keeper/providers_test.go b/x/rewards/keeper/providers_test.go index 09f6d3bb2a..c2ed44c47d 100644 --- a/x/rewards/keeper/providers_test.go +++ b/x/rewards/keeper/providers_test.go @@ -75,7 +75,7 @@ func TestBasicBoostProvidersRewards(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) expectedReward, _, _ := ts.DeductParticipationFees(sdk.NewIntFromUint64(baserewards * subscription.LIMIT_TOKEN_PER_CU)) - require.Equal(t, expectedReward, res.Rewards[0].Amount.Amount) + require.Equal(t, expectedReward, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) @@ -86,7 +86,7 @@ func TestBasicBoostProvidersRewards(t *testing.T) { res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") require.NoError(t, err) require.Len(t, res.Rewards, 1) - require.Equal(t, res.Rewards[0].Amount.Amount, sdk.NewIntFromUint64(baserewards*subscription.LIMIT_TOKEN_PER_CU)) + require.Equal(t, res.Rewards[0].Amount.AmountOf(ts.BondDenom()), sdk.NewIntFromUint64(baserewards*subscription.LIMIT_TOKEN_PER_CU)) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) } @@ -118,7 +118,7 @@ func TestSpecAllocationProvidersRewards(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) expectedReward, _, _ := ts.DeductParticipationFees(ts.plan.Price.Amount) - require.Equal(t, expectedReward, res.Rewards[0].Amount.Amount) + require.Equal(t, expectedReward, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) @@ -130,7 +130,7 @@ func TestSpecAllocationProvidersRewards(t *testing.T) { res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") require.NoError(t, err) require.Len(t, res.Rewards, 1) - require.Equal(t, distBalance.QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.Amount) + require.Equal(t, distBalance.QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) } @@ -166,7 +166,7 @@ func TestProvidersDiminishingRewards(t *testing.T) { expectedReward, _, _ := ts.DeductParticipationFees(ts.plan.Price.Amount) expectedReward = expectedReward.MulRaw(7) // the participation fees are done separately on each of the 7 relays - require.Equal(t, expectedReward, res.Rewards[0].Amount.Amount) + require.Equal(t, expectedReward, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) @@ -179,7 +179,7 @@ func TestProvidersDiminishingRewards(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) - require.Equal(t, sdk.NewDecWithPrec(15, 1).MulInt(distBalance).Sub(sdk.NewDecWithPrec(5, 1).MulInt(ts.plan.Price.Amount.MulRaw(7))).TruncateInt().QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.Amount) + require.Equal(t, sdk.NewDecWithPrec(15, 1).MulInt(distBalance).Sub(sdk.NewDecWithPrec(5, 1).MulInt(ts.plan.Price.Amount.MulRaw(7))).TruncateInt().QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) } @@ -214,7 +214,7 @@ func TestProvidersEndRewards(t *testing.T) { require.Len(t, res.Rewards, 1) expectedReward, _, _ := ts.DeductParticipationFees(ts.plan.Price.Amount) expectedReward = expectedReward.MulRaw(50) // the participation fees are done separately on each of the 50 relays - require.Equal(t, expectedReward, res.Rewards[0].Amount.Amount) + require.Equal(t, expectedReward, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) @@ -273,8 +273,8 @@ func Test2SpecsZeroShares(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 2) expectedReward, _, _ := ts.DeductParticipationFees(ts.plan.Price.Amount) - require.Equal(t, expectedReward, res.Rewards[0].Amount.Amount) - require.Equal(t, expectedReward, res.Rewards[1].Amount.Amount) + require.Equal(t, expectedReward, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) + require.Equal(t, expectedReward, res.Rewards[1].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), "") require.NoError(t, err) @@ -286,7 +286,7 @@ func Test2SpecsZeroShares(t *testing.T) { res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") require.NoError(t, err) require.Len(t, res.Rewards, 1) - require.Equal(t, distBalance.QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.Amount) + require.Equal(t, distBalance.QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.AmountOf(ts.BondDenom())) require.Equal(t, res.Rewards[0].ChainId, ts.spec.Index) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) @@ -337,8 +337,8 @@ func Test2SpecsDoubleShares(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 2) expectedReward, _, _ := ts.DeductParticipationFees(ts.plan.Price.Amount) - require.Equal(t, expectedReward, res.Rewards[0].Amount.Amount) - require.Equal(t, expectedReward, res.Rewards[1].Amount.Amount) + require.Equal(t, expectedReward, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) + require.Equal(t, expectedReward, res.Rewards[1].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), "") require.NoError(t, err) @@ -349,7 +349,7 @@ func Test2SpecsDoubleShares(t *testing.T) { res, err = ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), providerAcc.Addr.String(), "") require.NoError(t, err) require.Len(t, res.Rewards, 2) - require.Equal(t, res.Rewards[0].Amount.Amount.QuoRaw(2), res.Rewards[1].Amount.Amount) + require.Equal(t, res.Rewards[0].Amount.AmountOf(ts.BondDenom()).QuoRaw(2), res.Rewards[1].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) } @@ -421,7 +421,7 @@ func TestBonusRewards3Providers(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) // we sub 3 because of truncating - require.Equal(t, res1.Rewards[0].Amount.Amount, distBalance.QuoRaw(7*int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))).SubRaw(1)) + require.Equal(t, res1.Rewards[0].Amount.AmountOf(ts.BondDenom()), distBalance.QuoRaw(7*int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))).SubRaw(1)) _, err = ts.TxDualstakingClaimRewards(providerAcc1.Addr.String(), providerAcc1.Addr.String()) require.NoError(t, err) @@ -429,7 +429,7 @@ func TestBonusRewards3Providers(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) // we sub 1 because of truncating - require.Equal(t, res2.Rewards[0].Amount.Amount, distBalance.QuoRaw(7*int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))).MulRaw(2)) + require.Equal(t, res2.Rewards[0].Amount.AmountOf(ts.BondDenom()), distBalance.QuoRaw(7*int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))).MulRaw(2)) _, err = ts.TxDualstakingClaimRewards(providerAcc2.Addr.String(), providerAcc2.Addr.String()) require.NoError(t, err) @@ -437,7 +437,7 @@ func TestBonusRewards3Providers(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) // we add 6 because of truncating - require.Equal(t, res3.Rewards[0].Amount.Amount, distBalance.QuoRaw(7*int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))).MulRaw(4).AddRaw(1)) + require.Equal(t, res3.Rewards[0].Amount.AmountOf(ts.BondDenom()), distBalance.QuoRaw(7*int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))).MulRaw(4).AddRaw(1)) _, err = ts.TxDualstakingClaimRewards(providerAcc3.Addr.String(), providerAcc3.Addr.String()) require.NoError(t, err) } @@ -603,7 +603,7 @@ func TestBonusRewardsEquall5Providers(t *testing.T) { res, err := ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), "", "") require.NoError(t, err) require.Len(t, res.Rewards, 1) - require.Equal(t, distBalance.QuoRaw(int64(count)), res.Rewards[0].Amount.Amount) + require.Equal(t, distBalance.QuoRaw(int64(count)), res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), "") require.NoError(t, err) } @@ -680,7 +680,7 @@ func TestBonusRewards5Providers(t *testing.T) { res, err := ts.QueryDualstakingDelegatorRewards(providerAcc.Addr.String(), "", "") require.NoError(t, err) require.Len(t, res.Rewards, 1) - require.Equal(t, expected, res.Rewards[0].Amount.Amount) + require.Equal(t, expected, res.Rewards[0].Amount.AmountOf(ts.BondDenom())) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), "") require.NoError(t, err) } diff --git a/x/rewards/types/expected_keepers.go b/x/rewards/types/expected_keepers.go index c691f8f5ab..d5deb5ef7d 100644 --- a/x/rewards/types/expected_keepers.go +++ b/x/rewards/types/expected_keepers.go @@ -50,7 +50,7 @@ type StakingKeeper interface { } type DualStakingKeeper interface { - RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, totalRewards sdk.Coin, err error) + RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coins, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coins, totalRewards sdk.Coins, err error) // Methods imported from bank should be defined here } diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index d3b3300184..edf380bd68 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -205,7 +205,7 @@ func (k Keeper) RewardAndResetCuTracker(ctx sdk.Context, cuTrackerTimerKeyBytes // Note: if the reward function doesn't reward the provider // because he was unstaked, we only print an error and not returning - providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, creditToSub, types.ModuleName, false, false, false) + providerReward, _, err := k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, chainID, sdk.NewCoins(creditToSub), types.ModuleName, false, false, false) if errors.Is(err, epochstoragetypes.ErrProviderNotStaked) || errors.Is(err, epochstoragetypes.ErrStakeStorageNotFound) { utils.LavaFormatWarning("sending provider reward with delegations failed", err, utils.Attribute{Key: "provider", Value: provider}, diff --git a/x/subscription/keeper/subscription_test.go b/x/subscription/keeper/subscription_test.go index 80f6655849..b578be3dea 100644 --- a/x/subscription/keeper/subscription_test.go +++ b/x/subscription/keeper/subscription_test.go @@ -1553,7 +1553,7 @@ func TestSubscriptionCuExhaustAndUpgrade(t *testing.T) { // Verify that provider got rewarded for both subscriptions expectedPrice := freePlan.Price.AddAmount(premiumPlan.Price.Amount).AddAmount(premiumPlusPlan.Price.Amount) - require.Equal(t, expectedPrice, reward.Amount) + require.Equal(t, sdk.NewCoins(expectedPrice), reward.Amount) } // ### Advance Purchase Tests ### diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index 471b306af4..e58ab3b675 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -60,7 +60,7 @@ type TimerStoreKeeper interface { } type DualStakingKeeper interface { - RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coin, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coin, totalRewards sdk.Coin, err error) + RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coins, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coins, totalRewards sdk.Coins, err error) } type RewardsKeeper interface { From d21b0fc26bc68601c52a33181ec190bfd13dc8d7 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 19 Feb 2024 16:35:39 +0200 Subject: [PATCH 36/64] CNS-871: change popAllSpecBasepays to optionally delete --- x/rewards/keeper/base_pay.go | 6 ++++-- x/rewards/keeper/grpc_query_iprpc_provider_reward.go | 2 +- x/rewards/keeper/providers.go | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x/rewards/keeper/base_pay.go b/x/rewards/keeper/base_pay.go index e7639a2342..76c5ebfd50 100644 --- a/x/rewards/keeper/base_pay.go +++ b/x/rewards/keeper/base_pay.go @@ -54,7 +54,7 @@ func (k Keeper) SetAllBasePay(ctx sdk.Context, list []types.BasePayGenesis) { } } -func (k Keeper) popAllBasePayForChain(ctx sdk.Context, chainID string) (list []types.BasePayWithIndex) { +func (k Keeper) popAllBasePayForChain(ctx sdk.Context, chainID string, removeAfterPop bool) (list []types.BasePayWithIndex) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BasePayPrefix)) iterator := sdk.KVStorePrefixIterator(store, []byte(chainID)) @@ -64,7 +64,9 @@ func (k Keeper) popAllBasePayForChain(ctx sdk.Context, chainID string) (list []t var val types.BasePay k.cdc.MustUnmarshal(iterator.Value(), &val) list = append(list, types.BasePayWithIndex{BasePayIndex: types.BasePayKeyRecover(string(iterator.Key())), BasePay: val}) - store.Delete(iterator.Key()) + if removeAfterPop { + store.Delete(iterator.Key()) + } } return diff --git a/x/rewards/keeper/grpc_query_iprpc_provider_reward.go b/x/rewards/keeper/grpc_query_iprpc_provider_reward.go index 2a2cfd0ffc..03e3aa8d6c 100644 --- a/x/rewards/keeper/grpc_query_iprpc_provider_reward.go +++ b/x/rewards/keeper/grpc_query_iprpc_provider_reward.go @@ -28,7 +28,7 @@ func (k Keeper) IprpcProviderReward(goCtx context.Context, req *types.QueryIprpc providerSpecFunds := []types.Specfund{} for _, specFund := range iprpcReward.SpecFunds { // get all spec basepays and count IPRPC CU - bps, _ := k.specProvidersBasePay(ctx, specFund.Spec) + bps, _ := k.specProvidersBasePay(ctx, specFund.Spec, false) providerIprpcCu := uint64(0) totalIprpcCu := uint64(0) providerBpIndex := types.BasePayIndex{Provider: req.Provider, ChainID: specFund.Spec} diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 762002580b..f0936bd0ba 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -58,7 +58,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { specCuMap := map[string]types.SpecCuType{} // spec -> specCu for _, spec := range specs { // all providers basepays and the total basepay of the spec - basepays, totalbasepay := k.specProvidersBasePay(ctx, spec.ChainID) + basepays, totalbasepay := k.specProvidersBasePay(ctx, spec.ChainID, true) if len(basepays) == 0 { continue } @@ -250,8 +250,8 @@ func (k Keeper) specEmissionParts(ctx sdk.Context) (emissions []types.SpecEmissi return emissions } -func (k Keeper) specProvidersBasePay(ctx sdk.Context, chainID string) ([]types.BasePayWithIndex, math.Int) { - basepays := k.popAllBasePayForChain(ctx, chainID) +func (k Keeper) specProvidersBasePay(ctx sdk.Context, chainID string, removeAfterPop bool) ([]types.BasePayWithIndex, math.Int) { + basepays := k.popAllBasePayForChain(ctx, chainID, removeAfterPop) totalBasePay := math.ZeroInt() for _, basepay := range basepays { totalBasePay = totalBasePay.Add(basepay.Total) From 1106020d55fb57b9aaaabb44491be29139d7fb61 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Tue, 20 Feb 2024 18:11:16 +0200 Subject: [PATCH 37/64] CNS-870: fix handling reward transfer when there are no providers that receive iprpc rewards --- x/rewards/keeper/iprpc_reward.go | 39 +++++++++++++++++++++++++++++--- x/rewards/keeper/providers.go | 24 ++++++++++++-------- x/rewards/types/types.go | 8 ++++--- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index fa4422a42f..46b27183b6 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/binary" + "sort" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -85,9 +86,11 @@ func GetIprpcRewardIDFromBytes(bz []byte) uint64 { } // PopIprpcReward gets the lowest id IprpcReward object and removes it -func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { +func (k Keeper) PopIprpcReward(ctx sdk.Context, advanceCurrent bool) (types.IprpcReward, bool) { current := k.GetIprpcRewardsCurrent(ctx) - k.SetIprpcRewardsCurrent(ctx, current+1) + if advanceCurrent { + k.SetIprpcRewardsCurrent(ctx, current+1) + } return k.GetIprpcReward(ctx, current) } @@ -95,7 +98,7 @@ func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { // This function is used by the fund-iprpc TX. func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for months - for i := startID; i < duration+1; i++ { + for i := startID; i < startID+duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) if found { // found IPRPC reward, find if spec exists @@ -119,3 +122,33 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat k.SetIprpcReward(ctx, iprpcReward) } } + +// transferSpecFundsToNextMonth transfer the specFunds to the next month's IPRPC funds +// this function is used when there are no providers that should get the monthly IPRPC reward, +// so the reward transfers to the next month +func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMonthSpecFunds []types.Specfund) []types.Specfund { + mergedMap := make(map[string]sdk.Coins) + + // populate map with current spec funds + for i, obj := range specFunds { + mergedMap[obj.Spec] = specFunds[i].Fund + } + + // update the merged map with the next month spec funds + for i, obj := range nextMonthSpecFunds { + if fund, ok := mergedMap[obj.Spec]; ok { + mergedMap[obj.Spec] = fund.Add(nextMonthSpecFunds[i].Fund...) + } else { + mergedMap[obj.Spec] = obj.Fund + } + } + + // Convert map back to list and sort + var mergedList []types.Specfund + for spec, fund := range mergedMap { + mergedList = append(mergedList, types.Specfund{Spec: spec, Fund: fund}) + } + sort.Slice(mergedList, func(i, j int) bool { return mergedList[i].Spec < mergedList[j].Spec }) + + return mergedList +} diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 28e5bb9a81..7e86a49090 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -117,26 +117,32 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } // Get current month IprpcReward and use it to distribute rewards - iprpcReward, found := k.PopIprpcReward(ctx) + iprpcReward, found := k.PopIprpcReward(ctx, true) if !found { utils.LavaFormatError("current month iprpc reward not found", fmt.Errorf("did not reward providers IPRPC bonus")) return } + k.RemoveIprpcReward(ctx, iprpcReward.Id) + + // none of the providers will get the IPRPC reward this month, transfer the funds to the next month if len(specCuMap) == 0 { - // none of the providers will get the IPRPC reward this month, transfer the funds to the next month - nextMonthIprpcReward, found := k.PopIprpcReward(ctx) + nextMonthIprpcReward, found := k.PopIprpcReward(ctx, false) nextMonthId := k.GetIprpcRewardsCurrent(ctx) if !found { nextMonthIprpcReward = types.IprpcReward{Id: nextMonthId, SpecFunds: iprpcReward.SpecFunds} } else { - for _, specFund := range nextMonthIprpcReward.SpecFunds { - k.addSpecFunds(ctx, specFund.Spec, specFund.Fund, 1) // TODO: duration might be wrong - } + nextMonthIprpcReward.SpecFunds = k.transferSpecFundsToNextMonth(iprpcReward.SpecFunds, nextMonthIprpcReward.SpecFunds) } - } else { - // providers will get this month's reward, remove the popped reward object - k.RemoveIprpcReward(ctx, iprpcReward.Id) + k.SetIprpcReward(ctx, nextMonthIprpcReward) + details := map[string]string{ + "transfered_funds": iprpcReward.String(), + "next_month_updated_funds": nextMonthIprpcReward.String(), + } + utils.LogLavaEvent(ctx, k.Logger(ctx), types.TransferIprpcRewardToNextMonth, details, + "No provider serviced an IPRPC eligible subscription, transferring current month IPRPC funds to next month") + return } + for _, specFund := range iprpcReward.SpecFunds { // collect details details := map[string]string{"spec": specFund.Spec} diff --git a/x/rewards/types/types.go b/x/rewards/types/types.go index c06d5dbb4a..c3134beb44 100644 --- a/x/rewards/types/types.go +++ b/x/rewards/types/types.go @@ -48,9 +48,11 @@ const ( // provide service on specific specs. The rewards from this pool are distributed on a monthly // basis const ( - IprpcPoolName Pool = "iprpc_pool" - IprpcPoolEmissionEventName string = "iprpc-pool-emmission" - SetIprpcDataEventName = "set-iprpc-data" + IprpcPoolName Pool = "iprpc_pool" + IprpcPoolEmissionEventName string = "iprpc-pool-emmission" + SetIprpcDataEventName = "set-iprpc-data" + FundIprpcEventName = "fund-iprpc" + TransferIprpcRewardToNextMonth = "transfer-iprpc-reward-to-next-month" ) // helper struct to track the serviced IPRPC CU for each spec+provider From 04b7f19a69305ec59855a892af01d340597c5d2c Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 21 Feb 2024 16:20:16 +0200 Subject: [PATCH 38/64] CNS-872: unit tests --- testutil/common/tester.go | 5 + x/rewards/keeper/helpers_test.go | 76 +++- x/rewards/keeper/iprpc_test.go | 642 +++++++++++++++++++++++++++++ x/rewards/keeper/providers_test.go | 66 +-- 4 files changed, 750 insertions(+), 39 deletions(-) create mode 100644 x/rewards/keeper/iprpc_test.go diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 708f4c1a14..5ffdee65bf 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -615,6 +615,11 @@ func (ts *Tester) TxRewardsSetIprpcDataProposal(authority string, cost sdk.Coin, return ts.Servers.RewardsServer.SetIprpcData(ts.GoCtx, msg) } +func (ts *Tester) TxRewardsFundIprpc(creator string, spec string, duration uint64, fund sdk.Coins) (*rewardstypes.MsgFundIprpcResponse, error) { + msg := rewardstypes.NewMsgFundIprpc(creator, spec, duration, fund) + return ts.Servers.RewardsServer.FundIprpc(ts.GoCtx, msg) +} + // TxCreateValidator: implement 'tx staking createvalidator' and bond its tokens func (ts *Tester) TxCreateValidator(validator sigs.Account, amount math.Int) { consensusPowerTokens := ts.Keepers.StakingKeeper.TokensFromConsensusPower(ts.Ctx, 1) diff --git a/x/rewards/keeper/helpers_test.go b/x/rewards/keeper/helpers_test.go index ddff8d8474..05aaea3234 100644 --- a/x/rewards/keeper/helpers_test.go +++ b/x/rewards/keeper/helpers_test.go @@ -2,16 +2,18 @@ package keeper_test import ( "testing" + "time" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + commontypes "github.com/lavanet/lava/common/types" "github.com/lavanet/lava/testutil/common" testkeeper "github.com/lavanet/lava/testutil/keeper" planstypes "github.com/lavanet/lava/x/plans/types" - rewardsTypes "github.com/lavanet/lava/x/rewards/types" + rewardstypes "github.com/lavanet/lava/x/rewards/types" spectypes "github.com/lavanet/lava/x/spec/types" "github.com/stretchr/testify/require" ) @@ -23,10 +25,20 @@ const ( feeCollectorName = authtypes.FeeCollectorName ) +var ( + ibcDenom string = "uibc" + minIprpcCost sdk.Coin = sdk.NewCoin(commontypes.TokenDenom, sdk.NewInt(100)) + iprpcFunds sdk.Coins = sdk.NewCoins( + sdk.NewCoin(commontypes.TokenDenom, sdk.NewInt(1100)), + sdk.NewCoin(ibcDenom, sdk.NewInt(500)), + ) + mockSpec2 string = "mock2" +) + type tester struct { common.Tester - plan planstypes.Plan - spec spectypes.Spec + plan planstypes.Plan + specs []spectypes.Spec } func newTester(t *testing.T, addValidator bool) *tester { @@ -39,14 +51,14 @@ func newTester(t *testing.T, addValidator bool) *tester { } ts.plan = common.CreateMockPlan() - coins := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardsTypes.ProviderRewardsDistributionPool) + coins := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardstypes.ProviderRewardsDistributionPool) _, monthlyProvidersPool := coins.Find(ts.BondDenom()) ts.plan.Price.Amount = monthlyProvidersPool.Amount.QuoRaw(5).AddRaw(5) ts.plan.PlanPolicy.EpochCuLimit = monthlyProvidersPool.Amount.Uint64() * 5 ts.plan.PlanPolicy.TotalCuLimit = monthlyProvidersPool.Amount.Uint64() * 5 ts.plan.PlanPolicy.MaxProvidersToPair = 5 ts.AddPlan(ts.plan.Index, ts.plan) - ts.spec = ts.AddSpec("mock", common.CreateMockSpec()).Spec("mock") + ts.specs = []spectypes.Spec{ts.AddSpec("mock", common.CreateMockSpec()).Spec("mock")} return ts } @@ -62,7 +74,7 @@ func (ts *tester) feeCollector() sdk.AccAddress { return testkeeper.GetModuleAddress(feeCollectorName) } -func (ts *tester) getPoolBalance(pool rewardsTypes.Pool, denom string) math.Int { +func (ts *tester) getPoolBalance(pool rewardstypes.Pool, denom string) math.Int { coins := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, pool) return coins.AmountOf(denom) } @@ -71,6 +83,58 @@ func (ts *tester) iprpcAuthority() string { return authtypes.NewModuleAddress(govtypes.ModuleName).String() } +// setupForIprpcTests performs the following to set a proper env for iprpc tests: +// 0. it assumes that ts.newTester(t) was already executed +// 1. setting IPRPC data +// 2. fund the iprpc pool (optional, can specify if to fund from the next month) +func (ts *tester) setupForIprpcTests(fundIprpcPool bool) { + // add two consumers and buy subscriptions + consumerAcc, consumer := ts.AddAccount(common.CONSUMER, 0, testBalance*10000) + _, consumer2 := ts.AddAccount(common.CONSUMER, 1, testBalance*10000) + _, err := ts.TxSubscriptionBuy(consumer, consumer, ts.plan.Index, 5, true, false) + require.NoError(ts.T, err) + _, err = ts.TxSubscriptionBuy(consumer2, consumer2, ts.plan.Index, 5, true, false) + require.NoError(ts.T, err) + + // set iprpc data (only consumer is IPRPC eligible) + _, err = ts.TxRewardsSetIprpcDataProposal(ts.iprpcAuthority(), minIprpcCost, []string{consumer}) + require.NoError(ts.T, err) + + // create a new spec + spec2 := common.CreateMockSpec() + spec2.Index = mockSpec2 + spec2.Name = mockSpec2 + ts.specs = append(ts.specs, ts.AddSpec(mockSpec2, spec2).Spec(mockSpec2)) + + // add two providers and stake them both on the two specs + _, provider := ts.AddAccount(common.PROVIDER, 0, testBalance) + _, provider2 := ts.AddAccount(common.PROVIDER, 1, testBalance) + err = ts.StakeProvider(provider, ts.specs[0], testStake) + require.NoError(ts.T, err) + err = ts.StakeProvider(provider, ts.specs[1], testStake) + require.NoError(ts.T, err) + err = ts.StakeProvider(provider2, ts.specs[0], testStake) + require.NoError(ts.T, err) + err = ts.StakeProvider(provider2, ts.specs[1], testStake) + require.NoError(ts.T, err) + + ts.AdvanceEpoch() // apply pairing + + // reset time to the start of the month + startOfMonth := time.Date(ts.Ctx.BlockTime().Year(), ts.Ctx.BlockTime().Month(), 1, 0, 0, 0, 0, ts.Ctx.BlockTime().Location()) + ts.Ctx = ts.Ctx.WithBlockTime(startOfMonth) + ts.GoCtx = sdk.WrapSDKContext(ts.Ctx) + + if fundIprpcPool { + duration := uint64(1) + err = ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(sdk.NewIntFromUint64(duration))) + require.NoError(ts.T, err) + _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, duration, iprpcFunds) + require.NoError(ts.T, err) + ts.AdvanceMonths(1).AdvanceEpoch() // fund only fund for next month, so advance a month + } +} + // deductParticipationFees calculates the validators and community participation // fees and returns the providers reward after deducting them func (ts *tester) DeductParticipationFees(reward math.Int) (updatedReward math.Int, valParticipation math.Int, communityParticipation math.Int) { diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go new file mode 100644 index 0000000000..5d85a1abf6 --- /dev/null +++ b/x/rewards/keeper/iprpc_test.go @@ -0,0 +1,642 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/lavanet/lava/testutil/common" + "github.com/lavanet/lava/utils/sigs" + rewardstypes "github.com/lavanet/lava/x/rewards/types" + "github.com/stretchr/testify/require" +) + +// TestFundIprpcTX tests the FundIprpc TX functionality in funding the IPRPC pool +// Scenarios: +// 1. fund IPRPC with different periods (1m,3m,12m) and different denominations (also combinations) +// -> pool balance and iprpc reward should be as expected +func TestFundIprpcTX(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(false) + + consumerAcc, consumer := ts.GetAccount(common.CONSUMER, 0) + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds) + require.NoError(ts.T, err) + + type fundIprpcData struct { + spec string + duration uint64 + fund sdk.Coins + } + + // we fund as follows (to all we add the min IPRPC price. the description below is the funds that go to the pool): + // - 10ulava, 1 month, mockspec + // - 50uibc, 1 month, mockspec + // - 90ulava + 30uibc, 3 months, mockspec2 + // - 130uibc, 3 months, mockspec + // - 10ulava + 120uibc, 12 months, mockspec2 + fundIprpcTXsData := []fundIprpcData{ + {spec: ts.specs[0].Index, duration: 1, fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(10+minIprpcCost.Amount.Int64())), + )}, + {spec: ts.specs[0].Index, duration: 1, fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(minIprpcCost.Amount.Int64())), + sdk.NewCoin(ibcDenom, math.NewInt(50)), + )}, + {spec: ts.specs[1].Index, duration: 3, fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(90+minIprpcCost.Amount.Int64()*3)), + sdk.NewCoin(ibcDenom, math.NewInt(30)), + )}, + {spec: ts.specs[0].Index, duration: 3, fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(minIprpcCost.Amount.Int64()*3)), + sdk.NewCoin(ibcDenom, math.NewInt(130)), + )}, + {spec: ts.specs[1].Index, duration: 12, fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(10+minIprpcCost.Amount.Int64()*12)), + sdk.NewCoin(ibcDenom, math.NewInt(120)), + )}, + } + + for _, txData := range fundIprpcTXsData { + _, err = ts.TxRewardsFundIprpc(consumer, txData.spec, txData.duration, txData.fund) + require.NoError(t, err) + } + + // Expected total IPRPC pool balance: 110ulava (=10+90+10) and 330uibc + iprpcTotalBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardstypes.IprpcPoolName) + expectedIprpcTotalBalance := sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(110)), + sdk.NewCoin(ibcDenom, math.NewInt(330)), + ) + require.True(t, expectedIprpcTotalBalance.IsEqual(iprpcTotalBalance)) + + // Expected IPRPC rewards (by months, first month is skipped): + // 1. mockspec: 10ulava + 180uibc(=50+130), mockspec2: 100ulava(=10+90) + 150uibc(=30+120) + // 2. mockspec: 130uibc, mockspec2: 100ulava(=10+90) + 150uibc(=30+120) + // 3. mockspec: 130uibc, mockspec2: 100ulava(=10+90) + 150uibc(=30+120) + // 4-12. mockspec: nothing, mockspec2: 10ulava + 120uibc + iprpcRewards := ts.Keepers.Rewards.GetAllIprpcReward(ts.Ctx) + require.Len(t, iprpcRewards, 12) + for i := range iprpcRewards { + var expectedSpecFunds []rewardstypes.Specfund + switch i { + case 0: + // first month + expectedSpecFunds = []rewardstypes.Specfund{ + { + Spec: ts.specs[0].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(10)), + sdk.NewCoin(ibcDenom, math.NewInt(180)), + ), + }, + { + Spec: ts.specs[1].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(100)), + sdk.NewCoin(ibcDenom, math.NewInt(150)), + ), + }, + } + case 1: + // second month + expectedSpecFunds = []rewardstypes.Specfund{ + { + Spec: ts.specs[0].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ibcDenom, math.NewInt(130)), + ), + }, + { + Spec: ts.specs[1].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(100)), + sdk.NewCoin(ibcDenom, math.NewInt(150)), + ), + }, + } + case 2: + // 3rd month + expectedSpecFunds = []rewardstypes.Specfund{ + { + Spec: ts.specs[0].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ibcDenom, math.NewInt(130)), + ), + }, + { + Spec: ts.specs[1].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(100)), + sdk.NewCoin(ibcDenom, math.NewInt(150)), + ), + }, + } + default: + // rest of months (until 12) + expectedSpecFunds = []rewardstypes.Specfund{ + { + Spec: ts.specs[1].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), math.NewInt(10)), + sdk.NewCoin(ibcDenom, math.NewInt(120)), + ), + }, + } + } + require.Equal(t, i+1, int(iprpcRewards[i].Id)) + require.ElementsMatch(t, expectedSpecFunds, iprpcRewards[i].SpecFunds) + } +} + +// TestIprpcProviderRewardQuery tests the IprpcProviderReward query functionality +// Scenarios: +// 1. two providers provide different CU for two consumers, which only one is IPRPC eligible -> query should return expected reward +// 2. advance a month, fund the pool and check the query's output again (without sending relays -> provider rewards should be empty) +func TestIprpcProviderRewardQuery(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(true) // setup funds IPRPC for mock2 spec + + // get consumers and providers (note, only c1 is IPRPC eligible) + c1Acc, _ := ts.GetAccount(common.CONSUMER, 0) + c2Acc, _ := ts.GetAccount(common.CONSUMER, 1) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + _, p2 := ts.GetAccount(common.PROVIDER, 1) + + // send relays from both consumers to both providers + type relayInfo struct { + consumer sigs.Account + provider string + cu uint64 + } + relaysInfo := []relayInfo{ + {consumer: c1Acc, provider: p1, cu: 100}, + {consumer: c2Acc, provider: p1, cu: 150}, + {consumer: c1Acc, provider: p2, cu: 400}, + {consumer: c2Acc, provider: p2, cu: 450}, + } + for _, info := range relaysInfo { + msg := ts.SendRelay(info.provider, info.consumer, []string{ts.specs[1].Index}, info.cu) + _, err := ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &msg) + require.NoError(t, err) + } + + // check the IprpcProviderReward query + // p1 should get 1/5 of the reward and p2 4/5 of the reward (p1 relative serviced CU is 100/500) + // note: setupForIprpcTests() funds the IPRPC pool with 1000ulava and 500uibc + type providerRewards struct { + provider string + fund sdk.Coins + } + expectedProviderRewards := []providerRewards{ + {provider: p1, fund: iprpcFunds.Sub(minIprpcCost).QuoInt(sdk.NewInt(5))}, + {provider: p2, fund: iprpcFunds.Sub(minIprpcCost).MulInt(sdk.NewInt(4)).QuoInt(sdk.NewInt(5))}, + } + for _, expectedProviderReward := range expectedProviderRewards { + res, err := ts.QueryRewardsIprpcProviderReward(expectedProviderReward.provider) + require.NoError(t, err) + require.ElementsMatch(t, expectedProviderReward.fund, res.SpecFunds[0].Fund) // taking 0 index because there's a single spec + } + + // advance month to distribute monthly rewards + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + + // check that rewards were distributed as expected + for _, expectedProviderReward := range expectedProviderRewards { + res2, err := ts.QueryDualstakingDelegatorRewards(expectedProviderReward.provider, expectedProviderReward.provider, ts.specs[1].Index) + require.NoError(t, err) + require.True(t, res2.Rewards[0].Amount.IsEqual(expectedProviderReward.fund)) // taking 0 index because there are no delegators + } +} + +// TestIprpcSpecRewardQuery tests the IprpcSpecReward query functionality +// Scenarios: +// 0. assume IPRPC pool is funded with two denoms over different periods of vesting with two specs +// 1. query with no args should return all +// 2. query with arg should return the IPRPC rewards for the specific spec +// 3. advance a month, this month reward should transfer to next month -> query should return updated iprpc pool balance +// 4. make a provider provide service, advance a month to get his reward -> query should return updated iprpc pool balance +func TestIprpcSpecRewardQuery(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(true) // setup funds IPRPC for mock2 spec for 1 month and advances a month + + _, consumer := ts.GetAccount(common.CONSUMER, 0) + + // do another funding for mockspec and mock2 for 3 months + // Expected funds: + // first month: mock2 - 500uibc + 3000ulava, mockspec - 100000ulava + // second + third month: mock2 - 2000ulava, mockspec - 100000ulava + duration := int64(3) + minIprpcCostForFund := minIprpcCost.Amount.MulRaw(duration) + _, err := ts.TxRewardsFundIprpc(consumer, ts.specs[0].Index, uint64(duration), + sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000).Add(minIprpcCostForFund)))) + require.NoError(ts.T, err) + + _, err = ts.TxRewardsFundIprpc(consumer, ts.specs[1].Index, uint64(duration), + sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(2000).Add(minIprpcCostForFund)))) + require.NoError(ts.T, err) + + expectedResults := []rewardstypes.IprpcReward{ + { + Id: 1, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[1].Index, Fund: sdk.NewCoins(sdk.NewCoin(ibcDenom, sdk.NewInt(500)), + sdk.NewCoin(ts.BondDenom(), sdk.NewInt(1000)))}, + }, + }, + { + Id: 2, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + {Spec: ts.specs[1].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(2000)))}, + }, + }, + { + Id: 3, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + {Spec: ts.specs[1].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(2000)))}, + }, + }, + { + Id: 4, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + {Spec: ts.specs[1].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(2000)))}, + }, + }, + } + + // query with no args + res, err := ts.QueryRewardsIprpcSpecReward("") + require.NoError(t, err) + require.ElementsMatch(t, expectedResults, res.IprpcRewards) + + // query with arg = mockspec + mockspecExpectedResults := []rewardstypes.IprpcReward{ + { + Id: 2, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + }, + }, + { + Id: 3, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + }, + }, + { + Id: 4, SpecFunds: []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + }, + }, + } + res, err = ts.QueryRewardsIprpcSpecReward(ts.specs[0].Index) + require.NoError(t, err) + require.ElementsMatch(t, mockspecExpectedResults, res.IprpcRewards) + + // advance a month with no providers getting rewarded this month's reward should transfer to the next month + // 2nd month expected funds: mockspec - 100000ulava, mock2 - 3000ulava(=2000+1000) and 500uibc + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + + afterMonthExpectedResults := expectedResults[1:] + afterMonthExpectedResults[0].SpecFunds = []rewardstypes.Specfund{ + {Spec: ts.specs[0].Index, Fund: sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000)))}, + {Spec: ts.specs[1].Index, Fund: sdk.NewCoins( + sdk.NewCoin(ts.BondDenom(), sdk.NewInt(3000)), + sdk.NewCoin(ibcDenom, sdk.NewInt(500)), + )}, + } + res, err = ts.QueryRewardsIprpcSpecReward("") + require.NoError(t, err) + require.Len(t, res.IprpcRewards, len(afterMonthExpectedResults)) + for i := range res.IprpcRewards { + require.Equal(t, afterMonthExpectedResults[i].Id, res.IprpcRewards[i].Id) + require.ElementsMatch(t, afterMonthExpectedResults[i].SpecFunds, res.IprpcRewards[i].SpecFunds) + } + + // make a provider provide some service to an IPRPC eligible subscription + c1Acc, _ := ts.GetAccount(common.CONSUMER, 0) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + relay := ts.SendRelay(p1, c1Acc, []string{ts.specs[1].Index}, 100) + _, err = ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &relay) + require.NoError(t, err) + + // advance month to distribute monthly rewards + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + + // check that the latest iprpc object has been deleted + afterProviderServiceExpectedResults := afterMonthExpectedResults[1:] + res, err = ts.QueryRewardsIprpcSpecReward("") + require.NoError(t, err) + require.ElementsMatch(t, afterProviderServiceExpectedResults, res.IprpcRewards) +} + +// TestIprpcRewardObjectsUpdate tests that the IPRPC reward objects' management works as expected: +// Scenarios: +// 0. fund iprpc pool for 2 months, current should be 0 and first iprpc reward should be with id=1 (fund is always for the next month) +// 1. there is no service to eligible subscriptions, month passes -> current shouldn't increment and there should be no IPRPC object +// 2. provider provides service for eligible subscription, month passes -> current should increment by 1 and a new IPRPC reward should be created with id=current +func TestIprpcRewardObjectsUpdate(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(false) + consumerAcc, consumer := ts.GetAccount(common.CONSUMER, 0) + + // fund iprpc pool + duration := uint64(2) + iprpcCost := sdk.NewCoin(ts.BondDenom(), minIprpcCost.Amount.MulRaw(int64(duration))) + fundForIprpc := iprpcFunds + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, fundForIprpc) + require.NoError(ts.T, err) + _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, duration, iprpcFunds) + require.NoError(ts.T, err) + + // check there are 2 iprpc reward object, and the first one is with id=1 + currentIprpcRewardId := ts.Keepers.Rewards.GetIprpcRewardsCurrent(ts.Ctx) + require.Equal(t, uint64(0), currentIprpcRewardId) + res, err := ts.QueryRewardsIprpcSpecReward(mockSpec2) + require.NoError(t, err) + require.Len(t, res.IprpcRewards, 2) + require.Equal(t, uint64(0), res.CurrentMonthId) + for i := range res.IprpcRewards { + require.Equal(t, uint64(i+1), res.IprpcRewards[i].Id) + require.True(t, fundForIprpc.Sub(iprpcCost).IsEqual(res.IprpcRewards[i].SpecFunds[0].Fund)) + } + + // advance month to reach the first iprpc reward (first object is with id=1) + // there should still be the exact two objects as before + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + currentIprpcRewardId = ts.Keepers.Rewards.GetIprpcRewardsCurrent(ts.Ctx) + require.Equal(t, uint64(1), currentIprpcRewardId) + res, err = ts.QueryRewardsIprpcSpecReward(mockSpec2) + require.NoError(t, err) + require.Len(t, res.IprpcRewards, 2) + require.Equal(t, uint64(1), res.CurrentMonthId) + for i := range res.IprpcRewards { + require.Equal(t, uint64(i+1), res.IprpcRewards[i].Id) + require.True(t, fundForIprpc.Sub(iprpcCost).IsEqual(res.IprpcRewards[i].SpecFunds[0].Fund)) + } + + // advance month without any provider service, there should be one IPRPC object with combined reward + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + currentIprpcRewardId = ts.Keepers.Rewards.GetIprpcRewardsCurrent(ts.Ctx) + require.Equal(t, uint64(2), currentIprpcRewardId) + res, err = ts.QueryRewardsIprpcSpecReward(mockSpec2) + require.NoError(t, err) + require.Len(t, res.IprpcRewards, 1) + require.Equal(t, uint64(2), res.CurrentMonthId) + require.True(t, fundForIprpc.Sub(iprpcCost).MulInt(sdk.NewInt(2)).IsEqual(res.IprpcRewards[0].SpecFunds[0].Fund)) + + // make a provider service an IPRPC eligible consumer and advance a month + // there should be no iprpc rewards objects + c1Acc, _ := ts.GetAccount(common.CONSUMER, 0) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + relay := ts.SendRelay(p1, c1Acc, []string{ts.specs[1].Index}, 100) + _, err = ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &relay) + require.NoError(t, err) + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + res, err = ts.QueryRewardsIprpcSpecReward(mockSpec2) + require.NoError(t, err) + require.Len(t, res.IprpcRewards, 0) + require.Equal(t, uint64(3), res.CurrentMonthId) +} + +// TestIprpcMinCost tests that a fund TX fails if it doesn't have enough tokens to cover for the minimum IPRPC costs +// Scenarios: +// 1. fund TX with the minimum cost available -> TX success +// 2. assume min cost = 100ulava, fund TX with 50ulava and 200ibc -> TX fails (ibc "has enough funds") +// 3. fund TX without the minimum cost available -> TX fails +// 4. fund TX with the minimum cost but creator doesn't have enough balance for the funding -> TX fails +func TestIprpcMinCost(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(false) + consumerAcc, consumer := ts.GetAccount(common.CONSUMER, 0) + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, sdk.NewCoins(sdk.NewCoin(ibcDenom, sdk.NewInt(500)))) + + _, poorConsumer := ts.AddAccount(common.CONSUMER, 1, minIprpcCost.Amount.Int64()-10) + + testCases := []struct { + name string + creator string + fund sdk.Coins + success bool + }{ + { + name: "Happy flow - creator with enough funds and above min iprpc cost", + creator: consumer, + fund: sdk.NewCoins(minIprpcCost.AddAmount(sdk.NewInt(10))), + success: true, + }, + { + name: "fund without min iprpc cost", + creator: consumer, + fund: sdk.NewCoins(minIprpcCost.SubAmount(sdk.NewInt(10))), + success: false, + }, + { + name: "fund with other denom above min iprpc cost", + creator: consumer, + fund: sdk.NewCoins(sdk.NewCoin(ibcDenom, minIprpcCost.Amount.AddRaw(10))), + success: false, + }, + { + name: "insufficient balance for fund", + creator: poorConsumer, + fund: sdk.NewCoins(minIprpcCost.AddAmount(sdk.NewInt(10))), + success: false, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + _, err = ts.TxRewardsFundIprpc(tt.creator, mockSpec2, 1, tt.fund) + if tt.success { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} + +// TestIprpcEligibleSubscriptions tests that IPRPC CU is counted only if serviced an eligible subscription +// Scenarios: +// 0. assume two providers: p1, p2 and two consumers: c1, c2. Only c1 is IPRPC eligible +// 1. p1 provides service for both consumers, p2 provides service for c1 -> IPRPC reward should divide equally between p1 and p2 +// 2. both providers provide service for c2 -> No IPRPC rewards should be given +func TestIprpcEligibleSubscriptions(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(true) // setup creates consumers and providers and funds IPRPC pool for mock2 spec + + c1Acc, c1 := ts.GetAccount(common.CONSUMER, 0) + c2Acc, _ := ts.GetAccount(common.CONSUMER, 1) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + _, p2 := ts.GetAccount(common.PROVIDER, 1) + + // p1 provides service for both consumers, p2 provides service for c1 + msg := ts.SendRelay(p1, c1Acc, []string{mockSpec2}, 100) + _, err := ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + msg = ts.SendRelay(p1, c2Acc, []string{mockSpec2}, 100) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + msg = ts.SendRelay(p2, c1Acc, []string{mockSpec2}, 100) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + // check expected reward for each provider, it should be equal (the service for c1 was equal) + res1, err := ts.QueryRewardsIprpcProviderReward(p1) + require.NoError(t, err) + res2, err := ts.QueryRewardsIprpcProviderReward(p2) + require.NoError(t, err) + require.True(t, res1.SpecFunds[0].Fund.IsEqual(res2.SpecFunds[0].Fund)) + require.True(t, iprpcFunds.Sub(minIprpcCost).QuoInt(sdk.NewInt(2)).IsEqual(res1.SpecFunds[0].Fund)) + + // fund the pool again (advance month to apply) + _, err = ts.TxRewardsFundIprpc(c1, mockSpec2, 1, sdk.NewCoins(minIprpcCost.AddAmount(sdk.NewInt(10)))) + require.NoError(ts.T, err) + ts.AdvanceMonths(1).AdvanceEpoch() + + // provide service only for c2 + msg = ts.SendRelay(p1, c2Acc, []string{mockSpec2}, 100) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + msg = ts.SendRelay(p2, c2Acc, []string{mockSpec2}, 100) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + // check none of the providers should get rewards + res1, err = ts.QueryRewardsIprpcProviderReward(p1) + require.NoError(t, err) + res2, err = ts.QueryRewardsIprpcProviderReward(p2) + require.NoError(t, err) + require.Len(t, res1.SpecFunds, 0) + require.Len(t, res2.SpecFunds, 0) +} + +// TestMultipleIprpcSpec checks that rewards are distributed correctly when multiple specs are configured in the IPRPC pool +// Scenarios: +// 0. IPRPC pool is funded for two specs for different periods and different denom (some are the same) +// 1. two providers provide service for consumer on 3 specs, two of them are the IPRPC ones -> they get rewarded relative to their serviced CU on each spec +func TestMultipleIprpcSpec(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(false) // creates consumers and providers staked on two stakes + + c1Acc, c1 := ts.GetAccount(common.CONSUMER, 0) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + _, p2 := ts.GetAccount(common.PROVIDER, 1) + + // add another spec and stake the providers + mockSpec3 := "mock3" + spec3 := common.CreateMockSpec() + spec3.Index = mockSpec3 + spec3.Name = mockSpec3 + ts.specs = append(ts.specs, ts.AddSpec(mockSpec3, spec3).Spec(mockSpec3)) + err := ts.StakeProvider(p1, ts.specs[2], testStake) + require.NoError(ts.T, err) + err = ts.StakeProvider(p2, ts.specs[2], testStake) + require.NoError(ts.T, err) + + // fund iprpc pool for mock2 spec for 1 months + duration := uint64(1) + iprpcCost := sdk.NewCoin(ts.BondDenom(), minIprpcCost.Amount.MulRaw(int64(duration))) + mock2Fund := sdk.NewCoin(ts.BondDenom(), sdk.NewInt(1700)) + _, err = ts.TxRewardsFundIprpc(c1, mockSpec2, duration, sdk.NewCoins(mock2Fund.Add(iprpcCost))) + require.NoError(t, err) + + // fund iprpc pool for mock3 spec for 3 months + duration = uint64(3) + iprpcCost = sdk.NewCoin(ts.BondDenom(), minIprpcCost.Amount.MulRaw(int64(duration))) + mock3Fund := sdk.NewCoin(ts.BondDenom(), sdk.NewInt(400)) + _, err = ts.TxRewardsFundIprpc(c1, mockSpec3, duration, sdk.NewCoins(mock3Fund.Add(iprpcCost))) + require.NoError(t, err) + + // advance month and epoch to apply pairing and iprpc fund + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + + // make both providers service the consumer on 3 specs, only 2 are funded by IPRPC + nonIprpcSpec := ts.specs[0].Index + type relayData struct { + provider string + spec string + cu uint64 + } + relaysData := []relayData{ + {provider: p1, spec: nonIprpcSpec, cu: 100}, + {provider: p1, spec: mockSpec2, cu: 200}, + {provider: p1, spec: mockSpec3, cu: 300}, + {provider: p2, spec: nonIprpcSpec, cu: 700}, + {provider: p2, spec: mockSpec2, cu: 200}, + {provider: p2, spec: mockSpec3, cu: 300}, + } + for _, rd := range relaysData { + msg := ts.SendRelay(rd.provider, c1Acc, []string{rd.spec}, rd.cu) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + } + + // p1 total CU: 600, p2 total CU: 1200 -> if the rewards were divided by total CU (wrong) the rewards ratio should've been 1:2 + // p1 total iprpc CU: 500, p2 total iprpc CU: 500 -> if the rewards were divided by total iprpc CU the rewards should be equal + res1, err := ts.QueryRewardsIprpcProviderReward(p1) + require.NoError(t, err) + res2, err := ts.QueryRewardsIprpcProviderReward(p2) + require.NoError(t, err) + require.Equal(t, len(res1.SpecFunds), len(res2.SpecFunds)) + responses := []*rewardstypes.QueryIprpcProviderRewardResponse{res1, res2} + for _, res := range responses { + for _, sf := range res.SpecFunds { + switch sf.Spec { + case mockSpec2: + expectedReward := sdk.NewCoins(mock2Fund).QuoInt(sdk.NewInt(2)) + require.True(t, expectedReward.IsEqual(sf.Fund)) + case mockSpec3: + expectedReward := sdk.NewCoins(mock3Fund).QuoInt(sdk.NewInt(2)) + require.True(t, expectedReward.IsEqual(sf.Fund)) + } + } + } +} + +// TestIprpcRewardWithZeroSubRewards checks that even if a subscription is free (providers won't get paid for their service) +// if the providers service an IPRPC eligible subscription, they get IPRPC rewards +// Scenarios: +// 0. consumer is IPRPC eligible and community tax = 100% -> provider won't get paid for its service +// 1. two providers provide service -> they get IPRPC reward relative to their serviced CU +func TestIprpcRewardWithZeroSubRewards(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(true) // create a consumer and buys subscription + funds iprpc + + c1Acc, _ := ts.GetAccount(common.CONSUMER, 0) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + _, p2 := ts.GetAccount(common.PROVIDER, 1) + + // make community participation percentage to be 100% to make the provider not get rewarded for its service later + distParams := distributiontypes.DefaultParams() + distParams.CommunityTax = sdk.OneDec() + err := ts.Keepers.Distribution.SetParams(ts.Ctx, distParams) + require.NoError(t, err) + + // make providers service the IPRPC eligible consumer + msg := ts.SendRelay(p1, c1Acc, []string{mockSpec2}, 100) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + msg = ts.SendRelay(p2, c1Acc, []string{mockSpec2}, 400) + _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) + require.NoError(t, err) + + // advance month to trigger monthly iprpc reward + blocksToSave to trigger sub rewards + ts.AdvanceMonths(1) + ts.AdvanceEpoch() + ts.AdvanceBlocks(ts.BlocksToSave() + 1) + + // check provider rewards (should be only expected IPRPC rewards) + p1ExpectedReward := iprpcFunds.Sub(minIprpcCost).QuoInt(sdk.NewInt(5)) + res1, err := ts.QueryDualstakingDelegatorRewards(p1, p1, mockSpec2) + require.NoError(t, err) + require.True(t, p1ExpectedReward.IsEqual(res1.Rewards[0].Amount)) + + p2ExpectedReward := p1ExpectedReward.MulInt(sdk.NewInt(4)) + res2, err := ts.QueryDualstakingDelegatorRewards(p2, p2, mockSpec2) + require.NoError(t, err) + require.True(t, p2ExpectedReward.IsEqual(res2.Rewards[0].Amount)) +} diff --git a/x/rewards/keeper/providers_test.go b/x/rewards/keeper/providers_test.go index c2ed44c47d..abbeba4e41 100644 --- a/x/rewards/keeper/providers_test.go +++ b/x/rewards/keeper/providers_test.go @@ -18,7 +18,7 @@ func TestZeroProvidersRewards(t *testing.T) { ts := newTester(t, true) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -51,7 +51,7 @@ func TestBasicBoostProvidersRewards(t *testing.T) { ts := newTester(t, true) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -62,7 +62,7 @@ func TestBasicBoostProvidersRewards(t *testing.T) { baserewards := uint64(100) // the rewards by the subscription will be limited by LIMIT_TOKEN_PER_CU - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, baserewards) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, baserewards) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -96,7 +96,7 @@ func TestSpecAllocationProvidersRewards(t *testing.T) { ts := newTester(t, true) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -105,7 +105,7 @@ func TestSpecAllocationProvidersRewards(t *testing.T) { _, err = ts.TxSubscriptionBuy(consumerAcc.Addr.String(), consumerAcc.Addr.String(), ts.plan.Index, 1, false, false) require.NoError(t, err) - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -140,7 +140,7 @@ func TestProvidersDiminishingRewards(t *testing.T) { ts := newTester(t, true) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -150,7 +150,7 @@ func TestProvidersDiminishingRewards(t *testing.T) { _, err = ts.TxSubscriptionBuy(consumerAcc.Addr.String(), consumerAcc.Addr.String(), ts.plan.Index, 1, false, false) require.NoError(t, err) - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) } @@ -189,7 +189,7 @@ func TestProvidersEndRewards(t *testing.T) { ts := newTester(t, true) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -199,7 +199,7 @@ func TestProvidersEndRewards(t *testing.T) { _, err = ts.TxSubscriptionBuy(consumerAcc.Addr.String(), consumerAcc.Addr.String(), ts.plan.Index, 1, false, false) require.NoError(t, err) - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) } @@ -233,14 +233,14 @@ func TestProvidersEndRewards(t *testing.T) { // this means that no matter how much rewards the providers in this spec will get, they will get 0 bonus rewards func Test2SpecsZeroShares(t *testing.T) { ts := newTester(t, true) - spec2 := ts.spec + spec2 := ts.specs[0] spec2.Index = "mock2" spec2.Name = spec2.Index spec2.Shares = 0 ts.AddSpec(spec2.Index, spec2) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, 2*testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) err = ts.StakeProvider(providerAcc.Addr.String(), spec2, testBalance) @@ -252,7 +252,7 @@ func Test2SpecsZeroShares(t *testing.T) { _, err = ts.TxSubscriptionBuy(consumerAcc.Addr.String(), consumerAcc.Addr.String(), ts.plan.Index, 1, false, false) require.NoError(t, err) - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -287,7 +287,7 @@ func Test2SpecsZeroShares(t *testing.T) { require.NoError(t, err) require.Len(t, res.Rewards, 1) require.Equal(t, distBalance.QuoRaw(int64(ts.Keepers.Rewards.MaxRewardBoost(ts.Ctx))), res.Rewards[0].Amount.AmountOf(ts.BondDenom())) - require.Equal(t, res.Rewards[0].ChainId, ts.spec.Index) + require.Equal(t, res.Rewards[0].ChainId, ts.specs[0].Index) _, err = ts.TxDualstakingClaimRewards(providerAcc.Addr.String(), providerAcc.Addr.String()) require.NoError(t, err) } @@ -297,14 +297,14 @@ func Test2SpecsZeroShares(t *testing.T) { // the bonus for the provider with double the shares should be double than the other provider func Test2SpecsDoubleShares(t *testing.T) { ts := newTester(t, true) - spec2 := ts.spec + spec2 := ts.specs[0] spec2.Index = "mock2" spec2.Name = spec2.Index spec2.Shares *= 2 ts.AddSpec(spec2.Index, spec2) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, 2*testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) err = ts.StakeProvider(providerAcc.Addr.String(), spec2, testBalance) @@ -316,7 +316,7 @@ func Test2SpecsDoubleShares(t *testing.T) { _, err = ts.TxSubscriptionBuy(consumerAcc.Addr.String(), consumerAcc.Addr.String(), ts.plan.Index, 1, false, false) require.NoError(t, err) - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -360,15 +360,15 @@ func TestBonusRewards3Providers(t *testing.T) { ts := newTester(t, true) providerAcc1, _ := ts.AddAccount(common.PROVIDER, 1, 2*testBalance) - err := ts.StakeProvider(providerAcc1.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc1.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) providerAcc2, _ := ts.AddAccount(common.PROVIDER, 2, 2*testBalance) - err = ts.StakeProvider(providerAcc2.Addr.String(), ts.spec, 2*testBalance) + err = ts.StakeProvider(providerAcc2.Addr.String(), ts.specs[0], 2*testBalance) require.NoError(t, err) providerAcc3, _ := ts.AddAccount(common.PROVIDER, 3, 3*testBalance) - err = ts.StakeProvider(providerAcc3.Addr.String(), ts.spec, 3*testBalance) + err = ts.StakeProvider(providerAcc3.Addr.String(), ts.specs[0], 3*testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -377,15 +377,15 @@ func TestBonusRewards3Providers(t *testing.T) { _, err = ts.TxSubscriptionBuy(consumerAcc.Addr.String(), consumerAcc.Addr.String(), ts.plan.Index, 1, false, false) require.NoError(t, err) - msg := ts.SendRelay(providerAcc1.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()/2) + msg := ts.SendRelay(providerAcc1.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()/2) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) - msg = ts.SendRelay(providerAcc2.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()) + msg = ts.SendRelay(providerAcc2.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) - msg = ts.SendRelay(providerAcc3.Addr.String(), consumerAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()*2) + msg = ts.SendRelay(providerAcc3.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()*2) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -464,7 +464,7 @@ func TestValidatorsAndCommunityParticipation(t *testing.T) { // create provider+comsumer, send relay and send relay payment TX providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err = ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err = ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -475,7 +475,7 @@ func TestValidatorsAndCommunityParticipation(t *testing.T) { baserewards := uint64(100) // the rewards by the subscription will be limited by LIMIT_TOKEN_PER_CU - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, baserewards) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, baserewards) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -509,7 +509,7 @@ func TestValidatorsAndCommunityParticipation(t *testing.T) { func TestBonusReward49months(t *testing.T) { ts := newTester(t, true) providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -525,7 +525,7 @@ func TestBonusReward49months(t *testing.T) { baserewards := uint64(100) // the rewards by the subscription will be limited by LIMIT_TOKEN_PER_CU - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, baserewards) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, baserewards) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) @@ -559,7 +559,7 @@ func TestBonusRewardsEquall5Providers(t *testing.T) { for i := 0; i < count; i++ { providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) providerAccs = append(providerAccs, providerAcc) require.NoError(t, err) @@ -574,7 +574,7 @@ func TestBonusRewardsEquall5Providers(t *testing.T) { for _, providerAcc := range providerAccs { for _, consAcc := range consAccs { - msg := ts.SendRelay(providerAcc.Addr.String(), consAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()/uint64(count)/1000) + msg := ts.SendRelay(providerAcc.Addr.String(), consAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()/uint64(count)/1000) _, err := ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) } @@ -622,7 +622,7 @@ func TestBonusRewards5Providers(t *testing.T) { for i := 0; i < count; i++ { providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err := ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err := ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) providerAccs = append(providerAccs, providerAcc) require.NoError(t, err) @@ -635,13 +635,13 @@ func TestBonusRewards5Providers(t *testing.T) { for i := 1; i < 10; i++ { ts.AdvanceEpoch() - msg := ts.SendRelay(providerAccs[0].Addr.String(), consAccs[0], []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()/100) + msg := ts.SendRelay(providerAccs[0].Addr.String(), consAccs[0], []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()/100) _, err := ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) for _, providerAcc := range providerAccs[1:] { for _, consAcc := range consAccs[1:] { - msg := ts.SendRelay(providerAcc.Addr.String(), consAcc, []string{ts.spec.Index}, ts.plan.Price.Amount.Uint64()/uint64(count)/100) + msg := ts.SendRelay(providerAcc.Addr.String(), consAcc, []string{ts.specs[0].Index}, ts.plan.Price.Amount.Uint64()/uint64(count)/100) _, err := ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) } @@ -708,7 +708,7 @@ func TestCommunityTaxOne(t *testing.T) { // create provider+comsumer, send relay and send relay payment TX providerAcc, _ := ts.AddAccount(common.PROVIDER, 1, testBalance) - err = ts.StakeProvider(providerAcc.Addr.String(), ts.spec, testBalance) + err = ts.StakeProvider(providerAcc.Addr.String(), ts.specs[0], testBalance) require.NoError(t, err) ts.AdvanceEpoch() @@ -719,7 +719,7 @@ func TestCommunityTaxOne(t *testing.T) { baserewards := uint64(100) // the rewards by the subscription will be limited by LIMIT_TOKEN_PER_CU - msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.spec.Index}, baserewards) + msg := ts.SendRelay(providerAcc.Addr.String(), consumerAcc, []string{ts.specs[0].Index}, baserewards) _, err = ts.TxPairingRelayPayment(msg.Creator, msg.Relays...) require.NoError(t, err) From 52e4a1576ae044e84c9cec9c7d7c9557f8fa3b0a Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 21 Feb 2024 16:20:37 +0200 Subject: [PATCH 39/64] CNS-870: fix lint --- x/rewards/keeper/providers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 7e86a49090..99e25b7756 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -135,7 +135,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } k.SetIprpcReward(ctx, nextMonthIprpcReward) details := map[string]string{ - "transfered_funds": iprpcReward.String(), + "transferred_funds": iprpcReward.String(), "next_month_updated_funds": nextMonthIprpcReward.String(), } utils.LogLavaEvent(ctx, k.Logger(ctx), types.TransferIprpcRewardToNextMonth, details, From 481457792caa2bf6d4ee574d247b63344ff29307 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 21 Feb 2024 18:34:47 +0200 Subject: [PATCH 40/64] CNS-872: fix mock bank keeper --- testutil/keeper/mock_keepers.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/testutil/keeper/mock_keepers.go b/testutil/keeper/mock_keepers.go index ab465c0e22..d8512793d1 100644 --- a/testutil/keeper/mock_keepers.go +++ b/testutil/keeper/mock_keepers.go @@ -94,7 +94,14 @@ func (k mockBankKeeper) UndelegateCoinsFromModuleToAccount(ctx sdk.Context, send func (k mockBankKeeper) SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error { moduleAcc := GetModuleAddress(senderModule) - return k.SendCoinsFromAccountToModule(ctx, moduleAcc, recipientAddr.String(), amt) + accountCoins := k.GetAllBalances(ctx, moduleAcc) + if !accountCoins.IsAllGTE(amt) { + return fmt.Errorf("not enough coins") + } + + k.SubFromBalance(moduleAcc, amt) + k.AddToBalance(recipientAddr, amt) + return nil } func (k mockBankKeeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error { From 129211e0b7a83e40ba871f4bf3eb748d0e2e73c0 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 11:03:42 +0200 Subject: [PATCH 41/64] CNS-868: small PR fixes --- x/rewards/genesis.go | 4 ---- x/rewards/types/genesis.go | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index 74c4bd3a1a..df779754ca 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -19,10 +19,6 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) if len(genState.RefillRewardsTS.TimeEntries) == 0 { k.RefillRewardsPools(ctx, nil, nil) } - - for _, sub := range genState.IprpcSubscriptions { - k.SetIprpcSubscription(ctx, sub) - } k.SetIprpcData(ctx, genState.MinIprpcCost, genState.IprpcSubscriptions) } diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index e066aaba9f..7a3a7f2c6a 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -48,7 +48,7 @@ func (gs GenesisState) Validate() error { unique[sub] = struct{}{} } - if gs.MinIprpcCost.Denom != "ulava" { + if commontypes.TokenDenom != "ulava" { return fmt.Errorf("invalid min iprpc cost denom. MinIprpcCost: %s", gs.MinIprpcCost.String()) } From 2a0f469e9a10c54367dbd0ecfdaa09dc8370ee1e Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 11:09:38 +0200 Subject: [PATCH 42/64] CNS-870: small PR fixes --- x/rewards/keeper/providers.go | 4 ++-- x/subscription/keeper/cu_tracker.go | 4 ++-- x/subscription/types/expected_keepers.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 99e25b7756..6244791962 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -14,7 +14,7 @@ import ( const DAY_SECONDS = 60 * 60 * 24 -func (k Keeper) AddIprpcCu(ctx sdk.Context, provider string, chainID string, cu uint64) { +func (k Keeper) AggregateCU(ctx sdk.Context, provider string, chainID string, cu uint64) { index := types.BasePayIndex{Provider: provider, ChainID: chainID} basepay, found := k.getBasePay(ctx, index) if !found { @@ -25,7 +25,7 @@ func (k Keeper) AddIprpcCu(ctx sdk.Context, provider string, chainID string, cu k.setBasePay(ctx, index, basepay) } -func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int, sub string, cu uint64) { +func (k Keeper) AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int) { index := types.BasePayIndex{Provider: provider, ChainID: chainid} basepay, found := k.getBasePay(ctx, index) adjustedPay := adjustment.MulInt(rewards) diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index edf380bd68..4ddd1b69a7 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -31,7 +31,7 @@ func (k Keeper) GetTrackedCu(ctx sdk.Context, sub string, provider string, chain // Also, it counts the IPRPC CU if the subscription is IPRPC eligible func (k Keeper) AddTrackedCu(ctx sdk.Context, sub string, provider string, chainID string, cuToAdd uint64, block uint64) error { if k.rewardsKeeper.IsIprpcSubscription(ctx, sub) { - k.rewardsKeeper.AddIprpcCu(ctx, provider, chainID, cuToAdd) + k.rewardsKeeper.AggregateCU(ctx, provider, chainID, cuToAdd) } cu, found, key := k.GetTrackedCu(ctx, sub, provider, chainID, block) @@ -194,7 +194,7 @@ func (k Keeper) RewardAndResetCuTracker(ctx sdk.Context, cuTrackerTimerKeyBytes totalTokenRewarded = totalTokenRewarded.Add(totalMonthlyRewardAmount) // aggregate the reward for the provider - k.rewardsKeeper.AggregateRewards(ctx, provider, chainID, providerAdjustment, totalMonthlyRewardAmount, sub, trackedCu) + k.rewardsKeeper.AggregateRewards(ctx, provider, chainID, providerAdjustment, totalMonthlyRewardAmount) // Transfer some of the total monthly reward to validators contribution and community pool creditToSub, err = k.rewardsKeeper.ContributeToValidatorsAndCommunityPool(ctx, creditToSub, types.ModuleName) diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index e58ab3b675..78790b4b1a 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -64,12 +64,12 @@ type DualStakingKeeper interface { } type RewardsKeeper interface { - AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int, sub string, cu uint64) + AggregateRewards(ctx sdk.Context, provider, chainid string, adjustment sdk.Dec, rewards math.Int) MaxRewardBoost(ctx sdk.Context) (res uint64) ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward sdk.Coin, senderModule string) (updatedReward sdk.Coin, err error) FundCommunityPoolFromModule(ctx sdk.Context, amount sdk.Coins, senderModule string) error IsIprpcSubscription(ctx sdk.Context, address string) bool - AddIprpcCu(ctx sdk.Context, provider string, chainID string, cu uint64) + AggregateCU(ctx sdk.Context, provider string, chainID string, cu uint64) } type StakingKeeper interface { From 5cca4e2ee138e807c14c67d30d113e3310eb4898 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 11:35:54 +0200 Subject: [PATCH 43/64] CNS-870: move IPRPC functionality to different file and divide to functions --- x/rewards/keeper/iprpc.go | 170 +++++++++++++++++++++++++++++++ x/rewards/keeper/iprpc_reward.go | 60 ----------- x/rewards/keeper/providers.go | 93 +---------------- 3 files changed, 174 insertions(+), 149 deletions(-) create mode 100644 x/rewards/keeper/iprpc.go diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go new file mode 100644 index 0000000000..fd2d5bebe0 --- /dev/null +++ b/x/rewards/keeper/iprpc.go @@ -0,0 +1,170 @@ +package keeper + +import ( + "fmt" + "sort" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/utils" + "github.com/lavanet/lava/x/rewards/types" +) + +// handleNoIprpcRewardToProviders handles the situation in which there are no providers to send IPRPC rewards to +// so the IPRPC rewards transfer to the next month +func (k Keeper) handleNoIprpcRewardToProviders(ctx sdk.Context, iprpcReward types.IprpcReward) { + nextMonthIprpcReward, found := k.PopIprpcReward(ctx, false) + nextMonthId := k.GetIprpcRewardsCurrent(ctx) + if !found { + nextMonthIprpcReward = types.IprpcReward{Id: nextMonthId, SpecFunds: iprpcReward.SpecFunds} + } else { + nextMonthIprpcReward.SpecFunds = k.transferSpecFundsToNextMonth(iprpcReward.SpecFunds, nextMonthIprpcReward.SpecFunds) + } + k.SetIprpcReward(ctx, nextMonthIprpcReward) + details := map[string]string{ + "transferred_funds": iprpcReward.String(), + "next_month_updated_funds": nextMonthIprpcReward.String(), + } + utils.LogLavaEvent(ctx, k.Logger(ctx), types.TransferIprpcRewardToNextMonth, details, + "No provider serviced an IPRPC eligible subscription, transferring current month IPRPC funds to next month") +} + +// countIprpcCu updates the specCuMap which keeps records of spec->SpecCuType (which holds the IPRPC CU per provider) +func (k Keeper) countIprpcCu(specCuMap map[string]types.SpecCuType, iprpcCu uint64, spec string, provider string) { + if iprpcCu != 0 { + specCu, ok := specCuMap[spec] + if !ok { + specCuMap[spec] = types.SpecCuType{ + ProvidersCu: map[string]uint64{provider: iprpcCu}, + TotalCu: iprpcCu, + } + } else { + _, ok := specCu.ProvidersCu[provider] + if !ok { + specCu.ProvidersCu[provider] = iprpcCu + } else { + specCu.ProvidersCu[provider] += iprpcCu + } + specCu.TotalCu += iprpcCu + specCuMap[spec] = specCu + } + } +} + +// AddSpecFunds adds funds for a specific spec for of months. +// This function is used by the fund-iprpc TX. +func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { + startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for months + for i := startID; i < startID+duration; i++ { + iprpcReward, found := k.GetIprpcReward(ctx, i) + if found { + // found IPRPC reward, find if spec exists + specIndex := -1 + for i := 0; i < len(iprpcReward.SpecFunds); i++ { + if iprpcReward.SpecFunds[i].Spec == spec { + specIndex = i + } + } + // update spec funds + if specIndex >= 0 { + iprpcReward.SpecFunds[specIndex].Fund = iprpcReward.SpecFunds[specIndex].Fund.Add(fund...) + } else { + iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) + } + } else { + // did not find IPRPC reward -> create a new one + iprpcReward.Id = i + iprpcReward.SpecFunds = []types.Specfund{{Spec: spec, Fund: fund}} + } + k.SetIprpcReward(ctx, iprpcReward) + } +} + +// transferSpecFundsToNextMonth transfer the specFunds to the next month's IPRPC funds +// this function is used when there are no providers that should get the monthly IPRPC reward, +// so the reward transfers to the next month +func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMonthSpecFunds []types.Specfund) []types.Specfund { + mergedMap := make(map[string]sdk.Coins) + + // populate map with current spec funds + for i, obj := range specFunds { + mergedMap[obj.Spec] = specFunds[i].Fund + } + + // update the merged map with the next month spec funds + for i, obj := range nextMonthSpecFunds { + if fund, ok := mergedMap[obj.Spec]; ok { + mergedMap[obj.Spec] = fund.Add(nextMonthSpecFunds[i].Fund...) + } else { + mergedMap[obj.Spec] = obj.Fund + } + } + + // Convert map back to list and sort + var mergedList []types.Specfund + for spec, fund := range mergedMap { + mergedList = append(mergedList, types.Specfund{Spec: spec, Fund: fund}) + } + sort.Slice(mergedList, func(i, j int) bool { return mergedList[i].Spec < mergedList[j].Spec }) + + return mergedList +} + +// distributeIprpcRewards is distributing the IPRPC rewards for providers according to their serviced CU +func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcReward, specCuMap map[string]types.SpecCuType) { + for _, specFund := range iprpcReward.SpecFunds { + // collect details + details := map[string]string{"spec": specFund.Spec} + rewardsStr := []string{} + for _, reward := range specFund.Fund { + rewardsStr = append(rewardsStr, reward.String()) + } + details["rewards"] = strings.Join(rewardsStr, ",") + + // verify specCuMap holds an entry for the relevant spec + specCu, ok := specCuMap[specFund.Spec] + if !ok { + utils.LavaFormatError("did not distribute iprpc rewards to providers in spec", fmt.Errorf("specCU not found"), + utils.LogAttr("spec", details["spec"]), + utils.LogAttr("rewards", details["rewards"]), + ) + continue + } + + // collect providers details + providers := []string{} + for provider := range specCu.ProvidersCu { + providers = append(providers, provider) + } + sort.Strings(providers) + details["providers"] = strings.Join(providers, ",") + + // distribute IPRPC reward for spec + usedReward := sdk.NewCoins() + for _, provider := range providers { + providerAddr, err := sdk.AccAddressFromBech32(provider) + if err != nil { + continue + } + // calculate provider IPRPC reward + providerIprpcReward := specFund.Fund.MulInt(sdk.NewIntFromUint64(specCu.ProvidersCu[provider])).QuoInt(sdk.NewIntFromUint64(specCu.TotalCu)) + + // reward the provider + _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, specFund.Spec, providerIprpcReward, string(types.IprpcPoolName), false, false, false) + if err != nil { + utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", provider)) + } + + usedReward = usedReward.Add(providerIprpcReward...) + } + + // handle leftovers + usedReward = specFund.Fund.Sub(usedReward...) + err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) + if err != nil { + utils.LavaFormatError("could not send iprpc leftover to community pool", err) + } + + utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, details, "IPRPC monthly rewards distributed successfully") + } +} diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 46b27183b6..4db13f6b88 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -2,7 +2,6 @@ package keeper import ( "encoding/binary" - "sort" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -93,62 +92,3 @@ func (k Keeper) PopIprpcReward(ctx sdk.Context, advanceCurrent bool) (types.Iprp } return k.GetIprpcReward(ctx, current) } - -// AddSpecFunds adds funds for a specific spec for of months. -// This function is used by the fund-iprpc TX. -func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { - startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for months - for i := startID; i < startID+duration; i++ { - iprpcReward, found := k.GetIprpcReward(ctx, i) - if found { - // found IPRPC reward, find if spec exists - specIndex := -1 - for i := 0; i < len(iprpcReward.SpecFunds); i++ { - if iprpcReward.SpecFunds[i].Spec == spec { - specIndex = i - } - } - // update spec funds - if specIndex >= 0 { - iprpcReward.SpecFunds[specIndex].Fund = iprpcReward.SpecFunds[specIndex].Fund.Add(fund...) - } else { - iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) - } - } else { - // did not find IPRPC reward -> create a new one - iprpcReward.Id = i - iprpcReward.SpecFunds = []types.Specfund{{Spec: spec, Fund: fund}} - } - k.SetIprpcReward(ctx, iprpcReward) - } -} - -// transferSpecFundsToNextMonth transfer the specFunds to the next month's IPRPC funds -// this function is used when there are no providers that should get the monthly IPRPC reward, -// so the reward transfers to the next month -func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMonthSpecFunds []types.Specfund) []types.Specfund { - mergedMap := make(map[string]sdk.Coins) - - // populate map with current spec funds - for i, obj := range specFunds { - mergedMap[obj.Spec] = specFunds[i].Fund - } - - // update the merged map with the next month spec funds - for i, obj := range nextMonthSpecFunds { - if fund, ok := mergedMap[obj.Spec]; ok { - mergedMap[obj.Spec] = fund.Add(nextMonthSpecFunds[i].Fund...) - } else { - mergedMap[obj.Spec] = obj.Fund - } - } - - // Convert map back to list and sort - var mergedList []types.Specfund - for spec, fund := range mergedMap { - mergedList = append(mergedList, types.Specfund{Spec: spec, Fund: fund}) - } - sort.Slice(mergedList, func(i, j int) bool { return mergedList[i].Spec < mergedList[j].Spec }) - - return mergedList -} diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 6244791962..1ef5260092 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -2,8 +2,6 @@ package keeper import ( "fmt" - "sort" - "strings" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -95,24 +93,7 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } // count iprpc cu - if basepay.IprpcCu != 0 { - specCu, ok := specCuMap[spec.ChainID] - if !ok { - specCuMap[spec.ChainID] = types.SpecCuType{ - ProvidersCu: map[string]uint64{basepay.Provider: basepay.IprpcCu}, - TotalCu: basepay.IprpcCu, - } - } else { - _, ok := specCu.ProvidersCu[basepay.Provider] - if !ok { - specCu.ProvidersCu[basepay.Provider] = basepay.IprpcCu - } else { - specCu.ProvidersCu[basepay.Provider] += basepay.IprpcCu - } - specCu.TotalCu += basepay.IprpcCu - specCuMap[spec.ChainID] = specCu - } - } + k.countIprpcCu(specCuMap, basepay.IprpcCu, spec.ChainID, basepay.Provider) } } @@ -126,78 +107,12 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { // none of the providers will get the IPRPC reward this month, transfer the funds to the next month if len(specCuMap) == 0 { - nextMonthIprpcReward, found := k.PopIprpcReward(ctx, false) - nextMonthId := k.GetIprpcRewardsCurrent(ctx) - if !found { - nextMonthIprpcReward = types.IprpcReward{Id: nextMonthId, SpecFunds: iprpcReward.SpecFunds} - } else { - nextMonthIprpcReward.SpecFunds = k.transferSpecFundsToNextMonth(iprpcReward.SpecFunds, nextMonthIprpcReward.SpecFunds) - } - k.SetIprpcReward(ctx, nextMonthIprpcReward) - details := map[string]string{ - "transferred_funds": iprpcReward.String(), - "next_month_updated_funds": nextMonthIprpcReward.String(), - } - utils.LogLavaEvent(ctx, k.Logger(ctx), types.TransferIprpcRewardToNextMonth, details, - "No provider serviced an IPRPC eligible subscription, transferring current month IPRPC funds to next month") + k.handleNoIprpcRewardToProviders(ctx, iprpcReward) return } - for _, specFund := range iprpcReward.SpecFunds { - // collect details - details := map[string]string{"spec": specFund.Spec} - rewardsStr := []string{} - for _, reward := range specFund.Fund { - rewardsStr = append(rewardsStr, reward.String()) - } - details["rewards"] = strings.Join(rewardsStr, ",") - - // verify specCuMap holds an entry for the relevant spec - specCu, ok := specCuMap[specFund.Spec] - if !ok { - utils.LavaFormatError("did not distribute iprpc rewards to providers in spec", fmt.Errorf("specCU not found"), - utils.LogAttr("spec", details["spec"]), - utils.LogAttr("rewards", details["rewards"]), - ) - continue - } - - // collect providers details - providers := []string{} - for provider := range specCu.ProvidersCu { - providers = append(providers, provider) - } - sort.Strings(providers) - details["providers"] = strings.Join(providers, ",") - - // distribute IPRPC reward for spec - usedReward := sdk.NewCoins() - for _, provider := range providers { - providerAddr, err := sdk.AccAddressFromBech32(provider) - if err != nil { - continue - } - // calculate provider IPRPC reward - providerIprpcReward := specFund.Fund.MulInt(sdk.NewIntFromUint64(specCu.ProvidersCu[provider])).QuoInt(sdk.NewIntFromUint64(specCu.TotalCu)) - - // reward the provider - _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, specFund.Spec, providerIprpcReward, string(types.IprpcPoolName), false, false, false) - if err != nil { - utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", provider)) - } - - usedReward = usedReward.Add(providerIprpcReward...) - } - - // handle leftovers - usedReward = specFund.Fund.Sub(usedReward...) - err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) - if err != nil { - utils.LavaFormatError("could not send iprpc leftover to community pool", err) - } - - utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, details, "IPRPC monthly rewards distributed successfully") - } + // distribute IPRPC rewards + k.distributeIprpcRewards(ctx, iprpcReward, specCuMap) } // specTotalPayout calculates the total bonus for a specific spec From 374d197d5a0720e773a828b0c6a03f7dca7d4ef8 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 14:11:44 +0200 Subject: [PATCH 44/64] CNS-871: change query name --- proto/lavanet/lava/rewards/query.proto | 12 +- testutil/common/tester.go | 6 +- x/rewards/client/cli/query.go | 2 +- ...query_iprpc_provider_reward_estimation.go} | 10 +- .../grpc_query_iprpc_provider_reward.go | 4 +- x/rewards/types/query.pb.go | 256 +++++++++--------- x/rewards/types/query.pb.gw.go | 28 +- 7 files changed, 163 insertions(+), 155 deletions(-) rename x/rewards/client/cli/{query_iprpc_provider_reward.go => query_iprpc_provider_reward_estimation.go} (65%) diff --git a/proto/lavanet/lava/rewards/query.proto b/proto/lavanet/lava/rewards/query.proto index d4c6d9e89f..6173e0c7d5 100644 --- a/proto/lavanet/lava/rewards/query.proto +++ b/proto/lavanet/lava/rewards/query.proto @@ -33,8 +33,8 @@ service Query { option (google.api.http).get = "/lavanet/lava/rewards/show_iprpc_data"; } - // IprpcProviderReward queries for a provider's current IPRPC reward (relative to its serviced CU) - rpc IprpcProviderReward(QueryIprpcProviderRewardRequest) returns (QueryIprpcProviderRewardResponse) { + // IprpcProviderRewardEstimation queries for a provider's current IPRPC reward (relative to its serviced CU) + rpc IprpcProviderRewardEstimation(QueryIprpcProviderRewardEstimationRequest) returns (QueryIprpcProviderRewardEstimationResponse) { option (google.api.http).get = "/lavanet/lava/rewards/iprpc_provider_reward/{provider}"; } @@ -91,13 +91,13 @@ message QueryShowIprpcDataResponse { repeated string iprpc_subscriptions = 2; } -// QueryIprpcProviderRewardRequest is request type for the Query/IprpcProviderReward RPC method. -message QueryIprpcProviderRewardRequest { +// QueryIprpcProviderRewardEstimationRequest is request type for the Query/IprpcProviderRewardEstimation RPC method. +message QueryIprpcProviderRewardEstimationRequest { string provider = 1; } -// QueryIprpcProviderRewardResponse is response type for the Query/IprpcProviderReward RPC method. -message QueryIprpcProviderRewardResponse { +// QueryIprpcProviderRewardEstimationResponse is response type for the Query/IprpcProviderRewardEstimation RPC method. +message QueryIprpcProviderRewardEstimationResponse { repeated Specfund spec_funds = 1 [(gogoproto.nullable) = false]; } diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 8b0f5807a3..4cae38c747 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -864,11 +864,11 @@ func (ts *Tester) QueryRewardsShowIprpcData() (*rewardstypes.QueryShowIprpcDataR return ts.Keepers.Rewards.ShowIprpcData(ts.GoCtx, msg) } -func (ts *Tester) QueryRewardsIprpcProviderReward(provider string) (*rewardstypes.QueryIprpcProviderRewardResponse, error) { - msg := &rewardstypes.QueryIprpcProviderRewardRequest{ +func (ts *Tester) QueryRewardsIprpcProviderRewardEstimation(provider string) (*rewardstypes.QueryIprpcProviderRewardEstimationResponse, error) { + msg := &rewardstypes.QueryIprpcProviderRewardEstimationRequest{ Provider: provider, } - return ts.Keepers.Rewards.IprpcProviderReward(ts.GoCtx, msg) + return ts.Keepers.Rewards.IprpcProviderRewardEstimation(ts.GoCtx, msg) } func (ts *Tester) QueryRewardsIprpcSpecReward(spec string) (*rewardstypes.QueryIprpcSpecRewardResponse, error) { diff --git a/x/rewards/client/cli/query.go b/x/rewards/client/cli/query.go index b68b7c316c..cf8b46c50d 100644 --- a/x/rewards/client/cli/query.go +++ b/x/rewards/client/cli/query.go @@ -28,7 +28,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdQueryPools()) cmd.AddCommand(CmdQueryBlockReward()) cmd.AddCommand(CmdQueryShowIprpcData()) - cmd.AddCommand(CmdQueryIprpcProviderReward()) + cmd.AddCommand(CmdQueryIprpcProviderRewardEstimation()) cmd.AddCommand(CmdQueryIprpcSpecReward()) // this line is used by starport scaffolding # 1 diff --git a/x/rewards/client/cli/query_iprpc_provider_reward.go b/x/rewards/client/cli/query_iprpc_provider_reward_estimation.go similarity index 65% rename from x/rewards/client/cli/query_iprpc_provider_reward.go rename to x/rewards/client/cli/query_iprpc_provider_reward_estimation.go index 56e83ddaf4..09b7771a49 100644 --- a/x/rewards/client/cli/query_iprpc_provider_reward.go +++ b/x/rewards/client/cli/query_iprpc_provider_reward_estimation.go @@ -11,10 +11,10 @@ import ( var _ = strconv.Itoa(0) -func CmdQueryIprpcProviderReward() *cobra.Command { +func CmdQueryIprpcProviderRewardEstimation() *cobra.Command { cmd := &cobra.Command{ - Use: "iprpc-provider-reward [provider]", - Short: "Query for current IPRPC reward for a specific provider", + Use: "iprpc-provider-reward-estimation [provider]", + Short: "Query for current estimation of IPRPC reward for a specific provider", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { clientCtx, err := client.GetClientQueryContext(cmd) @@ -24,11 +24,11 @@ func CmdQueryIprpcProviderReward() *cobra.Command { queryClient := types.NewQueryClient(clientCtx) - params := &types.QueryIprpcProviderRewardRequest{ + params := &types.QueryIprpcProviderRewardEstimationRequest{ Provider: args[0], } - res, err := queryClient.IprpcProviderReward(cmd.Context(), params) + res, err := queryClient.IprpcProviderRewardEstimation(cmd.Context(), params) if err != nil { return err } diff --git a/x/rewards/keeper/grpc_query_iprpc_provider_reward.go b/x/rewards/keeper/grpc_query_iprpc_provider_reward.go index 03e3aa8d6c..633638d937 100644 --- a/x/rewards/keeper/grpc_query_iprpc_provider_reward.go +++ b/x/rewards/keeper/grpc_query_iprpc_provider_reward.go @@ -10,7 +10,7 @@ import ( "google.golang.org/grpc/status" ) -func (k Keeper) IprpcProviderReward(goCtx context.Context, req *types.QueryIprpcProviderRewardRequest) (*types.QueryIprpcProviderRewardResponse, error) { +func (k Keeper) IprpcProviderRewardEstimation(goCtx context.Context, req *types.QueryIprpcProviderRewardEstimationRequest) (*types.QueryIprpcProviderRewardEstimationResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -53,5 +53,5 @@ func (k Keeper) IprpcProviderReward(goCtx context.Context, req *types.QueryIprpc providerSpecFunds = append(providerSpecFunds, types.Specfund{Spec: specFund.Spec, Fund: providerFund}) } - return &types.QueryIprpcProviderRewardResponse{SpecFunds: providerSpecFunds}, nil + return &types.QueryIprpcProviderRewardEstimationResponse{SpecFunds: providerSpecFunds}, nil } diff --git a/x/rewards/types/query.pb.go b/x/rewards/types/query.pb.go index d404dd214a..25737a1aca 100644 --- a/x/rewards/types/query.pb.go +++ b/x/rewards/types/query.pb.go @@ -446,23 +446,27 @@ func (m *QueryShowIprpcDataResponse) GetIprpcSubscriptions() []string { return nil } -// QueryIprpcProviderRewardRequest is request type for the Query/IprpcProviderReward RPC method. -type QueryIprpcProviderRewardRequest struct { +// QueryIprpcProviderRewardEstimationRequest is request type for the Query/IprpcProviderRewardEstimation RPC method. +type QueryIprpcProviderRewardEstimationRequest struct { Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` } -func (m *QueryIprpcProviderRewardRequest) Reset() { *m = QueryIprpcProviderRewardRequest{} } -func (m *QueryIprpcProviderRewardRequest) String() string { return proto.CompactTextString(m) } -func (*QueryIprpcProviderRewardRequest) ProtoMessage() {} -func (*QueryIprpcProviderRewardRequest) Descriptor() ([]byte, []int) { +func (m *QueryIprpcProviderRewardEstimationRequest) Reset() { + *m = QueryIprpcProviderRewardEstimationRequest{} +} +func (m *QueryIprpcProviderRewardEstimationRequest) String() string { + return proto.CompactTextString(m) +} +func (*QueryIprpcProviderRewardEstimationRequest) ProtoMessage() {} +func (*QueryIprpcProviderRewardEstimationRequest) Descriptor() ([]byte, []int) { return fileDescriptor_15bce9a904340007, []int{9} } -func (m *QueryIprpcProviderRewardRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryIprpcProviderRewardEstimationRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryIprpcProviderRewardRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryIprpcProviderRewardEstimationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryIprpcProviderRewardRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryIprpcProviderRewardEstimationRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -472,42 +476,46 @@ func (m *QueryIprpcProviderRewardRequest) XXX_Marshal(b []byte, deterministic bo return b[:n], nil } } -func (m *QueryIprpcProviderRewardRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryIprpcProviderRewardRequest.Merge(m, src) +func (m *QueryIprpcProviderRewardEstimationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIprpcProviderRewardEstimationRequest.Merge(m, src) } -func (m *QueryIprpcProviderRewardRequest) XXX_Size() int { +func (m *QueryIprpcProviderRewardEstimationRequest) XXX_Size() int { return m.Size() } -func (m *QueryIprpcProviderRewardRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryIprpcProviderRewardRequest.DiscardUnknown(m) +func (m *QueryIprpcProviderRewardEstimationRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIprpcProviderRewardEstimationRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryIprpcProviderRewardRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryIprpcProviderRewardEstimationRequest proto.InternalMessageInfo -func (m *QueryIprpcProviderRewardRequest) GetProvider() string { +func (m *QueryIprpcProviderRewardEstimationRequest) GetProvider() string { if m != nil { return m.Provider } return "" } -// QueryIprpcProviderRewardResponse is response type for the Query/IprpcProviderReward RPC method. -type QueryIprpcProviderRewardResponse struct { +// QueryIprpcProviderRewardEstimationResponse is response type for the Query/IprpcProviderRewardEstimation RPC method. +type QueryIprpcProviderRewardEstimationResponse struct { SpecFunds []Specfund `protobuf:"bytes,1,rep,name=spec_funds,json=specFunds,proto3" json:"spec_funds"` } -func (m *QueryIprpcProviderRewardResponse) Reset() { *m = QueryIprpcProviderRewardResponse{} } -func (m *QueryIprpcProviderRewardResponse) String() string { return proto.CompactTextString(m) } -func (*QueryIprpcProviderRewardResponse) ProtoMessage() {} -func (*QueryIprpcProviderRewardResponse) Descriptor() ([]byte, []int) { +func (m *QueryIprpcProviderRewardEstimationResponse) Reset() { + *m = QueryIprpcProviderRewardEstimationResponse{} +} +func (m *QueryIprpcProviderRewardEstimationResponse) String() string { + return proto.CompactTextString(m) +} +func (*QueryIprpcProviderRewardEstimationResponse) ProtoMessage() {} +func (*QueryIprpcProviderRewardEstimationResponse) Descriptor() ([]byte, []int) { return fileDescriptor_15bce9a904340007, []int{10} } -func (m *QueryIprpcProviderRewardResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryIprpcProviderRewardEstimationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryIprpcProviderRewardResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryIprpcProviderRewardEstimationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryIprpcProviderRewardResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryIprpcProviderRewardEstimationResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -517,19 +525,19 @@ func (m *QueryIprpcProviderRewardResponse) XXX_Marshal(b []byte, deterministic b return b[:n], nil } } -func (m *QueryIprpcProviderRewardResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryIprpcProviderRewardResponse.Merge(m, src) +func (m *QueryIprpcProviderRewardEstimationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryIprpcProviderRewardEstimationResponse.Merge(m, src) } -func (m *QueryIprpcProviderRewardResponse) XXX_Size() int { +func (m *QueryIprpcProviderRewardEstimationResponse) XXX_Size() int { return m.Size() } -func (m *QueryIprpcProviderRewardResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryIprpcProviderRewardResponse.DiscardUnknown(m) +func (m *QueryIprpcProviderRewardEstimationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryIprpcProviderRewardEstimationResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryIprpcProviderRewardResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryIprpcProviderRewardEstimationResponse proto.InternalMessageInfo -func (m *QueryIprpcProviderRewardResponse) GetSpecFunds() []Specfund { +func (m *QueryIprpcProviderRewardEstimationResponse) GetSpecFunds() []Specfund { if m != nil { return m.SpecFunds } @@ -644,8 +652,8 @@ func init() { proto.RegisterType((*QueryBlockRewardResponse)(nil), "lavanet.lava.rewards.QueryBlockRewardResponse") proto.RegisterType((*QueryShowIprpcDataRequest)(nil), "lavanet.lava.rewards.QueryShowIprpcDataRequest") proto.RegisterType((*QueryShowIprpcDataResponse)(nil), "lavanet.lava.rewards.QueryShowIprpcDataResponse") - proto.RegisterType((*QueryIprpcProviderRewardRequest)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardRequest") - proto.RegisterType((*QueryIprpcProviderRewardResponse)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardResponse") + proto.RegisterType((*QueryIprpcProviderRewardEstimationRequest)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardEstimationRequest") + proto.RegisterType((*QueryIprpcProviderRewardEstimationResponse)(nil), "lavanet.lava.rewards.QueryIprpcProviderRewardEstimationResponse") proto.RegisterType((*QueryIprpcSpecRewardRequest)(nil), "lavanet.lava.rewards.QueryIprpcSpecRewardRequest") proto.RegisterType((*QueryIprpcSpecRewardResponse)(nil), "lavanet.lava.rewards.QueryIprpcSpecRewardResponse") } @@ -653,66 +661,66 @@ func init() { func init() { proto.RegisterFile("lavanet/lava/rewards/query.proto", fileDescriptor_15bce9a904340007) } var fileDescriptor_15bce9a904340007 = []byte{ - // 936 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6f, 0xdc, 0x44, - 0x14, 0x8e, 0x93, 0xcd, 0xaf, 0x97, 0xb6, 0xc0, 0x24, 0x52, 0x37, 0x4e, 0x70, 0xb6, 0x26, 0x28, - 0x4b, 0xa5, 0xd8, 0x49, 0x10, 0x01, 0x81, 0x8a, 0x44, 0x82, 0x90, 0x22, 0x15, 0xa9, 0x75, 0x38, - 0x71, 0xb1, 0x66, 0xbd, 0xb3, 0x1b, 0xab, 0xb6, 0xc7, 0xf5, 0xcc, 0x26, 0x54, 0xa8, 0x42, 0x02, - 0x71, 0xe0, 0x86, 0x84, 0x84, 0xb8, 0x72, 0xe5, 0xc4, 0x1f, 0x81, 0x44, 0x8f, 0x95, 0xb8, 0x70, - 0x02, 0x94, 0xf0, 0x17, 0xf0, 0x17, 0xa0, 0x79, 0x33, 0xde, 0xec, 0x36, 0xde, 0xcd, 0xf6, 0x64, - 0xef, 0xcc, 0xf7, 0xbd, 0xef, 0x7b, 0xe3, 0xf7, 0xde, 0x2c, 0x34, 0x12, 0x7a, 0x4a, 0x33, 0x26, - 0x7d, 0xf5, 0xf4, 0x0b, 0x76, 0x46, 0x8b, 0xb6, 0xf0, 0x1f, 0xf7, 0x58, 0xf1, 0xc4, 0xcb, 0x0b, - 0x2e, 0x39, 0x59, 0x31, 0x08, 0x4f, 0x3d, 0x3d, 0x83, 0xb0, 0x57, 0xba, 0xbc, 0xcb, 0x11, 0xe0, - 0xab, 0x37, 0x8d, 0xb5, 0xd7, 0xbb, 0x9c, 0x77, 0x13, 0xe6, 0xd3, 0x3c, 0xf6, 0x69, 0x96, 0x71, - 0x49, 0x65, 0xcc, 0x33, 0x61, 0x76, 0xef, 0x46, 0x5c, 0xa4, 0x5c, 0xf8, 0x2d, 0x2a, 0x98, 0x96, - 0xf0, 0x4f, 0x77, 0x5b, 0x4c, 0xd2, 0x5d, 0x3f, 0xa7, 0xdd, 0x38, 0x43, 0xb0, 0xc1, 0xde, 0xa9, - 0xf4, 0x95, 0xd3, 0x82, 0xa6, 0x65, 0xb8, 0x6a, 0xeb, 0x71, 0x5e, 0xe4, 0x91, 0x41, 0x38, 0x83, - 0x82, 0xa5, 0x54, 0xc4, 0x63, 0x23, 0xe2, 0xae, 0x00, 0x79, 0xa8, 0x6c, 0x3c, 0xc0, 0xb0, 0x01, - 0x7b, 0xdc, 0x63, 0x42, 0xba, 0x0f, 0x61, 0x79, 0x68, 0x55, 0xe4, 0x3c, 0x13, 0x8c, 0xbc, 0x0f, - 0x73, 0x5a, 0xbe, 0x6e, 0x35, 0xac, 0xe6, 0xd2, 0xde, 0xba, 0x57, 0x75, 0x30, 0x9e, 0x66, 0x1d, - 0xd4, 0x9e, 0xfd, 0xb5, 0x31, 0x15, 0x18, 0x86, 0xbb, 0x0c, 0xaf, 0xe9, 0x90, 0x9c, 0x27, 0x7d, - 0x9d, 0x6f, 0x2d, 0x58, 0x50, 0x0b, 0x47, 0x59, 0x87, 0x13, 0x02, 0xb5, 0x8c, 0xa6, 0x0c, 0x63, - 0x2f, 0x06, 0xf8, 0x4e, 0x18, 0xcc, 0xb7, 0x68, 0x42, 0xb3, 0x88, 0xd5, 0xa7, 0x1b, 0x33, 0xcd, - 0xa5, 0xbd, 0x55, 0x4f, 0x27, 0xe4, 0xa9, 0x84, 0x3c, 0x93, 0x90, 0x77, 0xc8, 0xe3, 0xec, 0x60, - 0x47, 0xe9, 0xfd, 0xf2, 0xf7, 0x46, 0xb3, 0x1b, 0xcb, 0x93, 0x5e, 0xcb, 0x8b, 0x78, 0xea, 0x9b, - 0xec, 0xf5, 0x63, 0x5b, 0xb4, 0x1f, 0xf9, 0xf2, 0x49, 0xce, 0x04, 0x12, 0x44, 0x50, 0xc6, 0x76, - 0xff, 0xb3, 0xca, 0x63, 0xd0, 0xee, 0xfa, 0xf9, 0xce, 0xe6, 0x6a, 0xa1, 0x6e, 0xa1, 0xb6, 0x33, - 0x22, 0x5d, 0x93, 0x80, 0x49, 0x58, 0x53, 0xc8, 0x26, 0xdc, 0x92, 0x71, 0xca, 0x42, 0xc9, 0xc3, - 0x82, 0x75, 0xe2, 0x24, 0xa9, 0x4f, 0x37, 0xac, 0xe6, 0x4c, 0x70, 0x43, 0xad, 0x7e, 0xc6, 0x03, - 0x5c, 0x23, 0x1f, 0x80, 0xcd, 0x84, 0x8c, 0x53, 0x2a, 0x59, 0x3b, 0x6c, 0x25, 0x3c, 0x7a, 0x24, - 0x06, 0x18, 0x33, 0xc8, 0xb8, 0xdd, 0x47, 0x1c, 0x20, 0xa0, 0x4f, 0xbe, 0x07, 0x6b, 0x34, 0x49, - 0x78, 0x84, 0x45, 0x13, 0x2a, 0xd9, 0x30, 0xe5, 0x99, 0x3c, 0x11, 0x61, 0xc2, 0x3a, 0xb2, 0x5e, - 0x43, 0x76, 0xfd, 0x12, 0xa2, 0x8c, 0x7e, 0x8a, 0x80, 0xfb, 0xac, 0x23, 0xdd, 0x55, 0xb8, 0x8d, - 0x39, 0x63, 0xd4, 0x00, 0x93, 0x29, 0xbf, 0xcb, 0x31, 0xd4, 0xaf, 0x6e, 0x99, 0x43, 0x79, 0x17, - 0xe6, 0x74, 0xe6, 0xa6, 0x08, 0xc6, 0x7c, 0x11, 0x53, 0x01, 0x1a, 0xee, 0xae, 0xc1, 0x2a, 0x06, - 0x3d, 0x3e, 0xe1, 0x67, 0x47, 0xaa, 0x44, 0x3f, 0xa6, 0x92, 0x96, 0x8a, 0xdf, 0x59, 0x60, 0x57, - 0xed, 0xf6, 0xbf, 0xc4, 0x42, 0x1a, 0x67, 0x61, 0xc4, 0x85, 0x9c, 0x54, 0x76, 0x3e, 0x8d, 0xb3, - 0x43, 0x2e, 0x24, 0xf1, 0x61, 0x19, 0x3b, 0x22, 0x14, 0xbd, 0x96, 0x88, 0x8a, 0x38, 0xc7, 0x86, - 0xc4, 0x7a, 0x5a, 0x0c, 0x08, 0x6e, 0x1d, 0x0f, 0xee, 0xb8, 0xf7, 0x60, 0x03, 0xad, 0xa0, 0x8d, - 0x07, 0x05, 0x3f, 0x8d, 0xdb, 0xac, 0x18, 0x3a, 0x20, 0x62, 0xc3, 0x42, 0x6e, 0x36, 0x4c, 0xbd, - 0xf6, 0x7f, 0xbb, 0x5d, 0x68, 0x8c, 0xa6, 0x9b, 0x7c, 0x0e, 0x01, 0x44, 0xce, 0xa2, 0xb0, 0xd3, - 0xcb, 0xda, 0xd7, 0x94, 0xd7, 0x71, 0xce, 0x22, 0x05, 0x33, 0x69, 0x2d, 0x2a, 0xde, 0x27, 0x8a, - 0xe6, 0xee, 0xc2, 0xda, 0xa5, 0x90, 0x82, 0x0d, 0x7b, 0x24, 0x50, 0x53, 0xd8, 0xb2, 0x9f, 0xd4, - 0xbb, 0xfb, 0xa3, 0x05, 0xeb, 0xd5, 0x1c, 0x63, 0xec, 0x3e, 0xdc, 0xd4, 0x87, 0x65, 0xe4, 0x8d, - 0xb7, 0x3b, 0xd5, 0xde, 0x30, 0x8a, 0x8e, 0x60, 0xec, 0xdd, 0x88, 0x2f, 0x97, 0x04, 0x69, 0xc2, - 0xab, 0x51, 0xaf, 0x28, 0x58, 0x26, 0x75, 0x65, 0x86, 0x71, 0x1b, 0xdb, 0xa0, 0x16, 0xdc, 0x32, - 0xeb, 0x58, 0x8f, 0x47, 0xed, 0xbd, 0xdf, 0xe7, 0x61, 0x16, 0x8d, 0x91, 0x6f, 0x2c, 0x98, 0xd3, - 0x13, 0x84, 0x34, 0xab, 0x55, 0xaf, 0x0e, 0x2c, 0xfb, 0xad, 0x09, 0x90, 0x3a, 0x43, 0x77, 0xf3, - 0xeb, 0x3f, 0xfe, 0xfd, 0x61, 0xda, 0x21, 0xeb, 0xfe, 0x98, 0xf9, 0x4a, 0xbe, 0x82, 0x59, 0x9c, - 0x05, 0x64, 0x6b, 0x5c, 0xe4, 0x81, 0x59, 0x66, 0x37, 0xaf, 0x07, 0x1a, 0x07, 0x6f, 0xa0, 0x83, - 0xd7, 0xc9, 0xda, 0x08, 0x07, 0xa8, 0xfb, 0x93, 0x05, 0x4b, 0x03, 0xed, 0x47, 0xb6, 0xc7, 0x84, - 0xbf, 0xda, 0xc1, 0xb6, 0x37, 0x29, 0xdc, 0x78, 0xba, 0x8b, 0x9e, 0x36, 0x89, 0x5b, 0xed, 0x09, - 0x47, 0x93, 0xa9, 0x09, 0xf2, 0xb3, 0x05, 0x37, 0x87, 0xda, 0x94, 0xf8, 0x63, 0xd4, 0xaa, 0xda, - 0xdd, 0xde, 0x99, 0x9c, 0x60, 0x0c, 0x6e, 0xa3, 0xc1, 0x2d, 0xf2, 0x66, 0xb5, 0x41, 0x71, 0xc2, - 0xcf, 0x42, 0x5d, 0xb9, 0x6d, 0xe5, 0xe8, 0x37, 0x0b, 0x96, 0x2b, 0x1a, 0x90, 0xbc, 0x33, 0x46, - 0x78, 0x74, 0xbf, 0xdb, 0xfb, 0x2f, 0x4b, 0x33, 0xae, 0x3f, 0x44, 0xd7, 0xef, 0x91, 0x7d, 0x7f, - 0xf4, 0x4d, 0x1d, 0x96, 0x93, 0xc3, 0x9c, 0xaf, 0xff, 0x65, 0xb9, 0xf0, 0x94, 0xfc, 0x6a, 0xc1, - 0x2b, 0x2f, 0xb4, 0x2a, 0xd9, 0xbd, 0xce, 0xcb, 0x95, 0x51, 0x60, 0xef, 0xbd, 0x0c, 0xc5, 0x58, - 0xdf, 0x47, 0xeb, 0x3b, 0xc4, 0x1b, 0x67, 0x1d, 0x87, 0x58, 0x69, 0x5b, 0xfd, 0x78, 0x7a, 0xf0, - 0xd1, 0xb3, 0x73, 0xc7, 0x7a, 0x7e, 0xee, 0x58, 0xff, 0x9c, 0x3b, 0xd6, 0xf7, 0x17, 0xce, 0xd4, - 0xf3, 0x0b, 0x67, 0xea, 0xcf, 0x0b, 0x67, 0xea, 0xf3, 0xad, 0x81, 0x8b, 0x79, 0x28, 0xe6, 0x17, - 0xfd, 0xa8, 0x78, 0x3b, 0xb7, 0xe6, 0xf0, 0xbf, 0xc9, 0xdb, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, - 0x0c, 0x25, 0x99, 0x21, 0x9a, 0x09, 0x00, 0x00, + // 944 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcf, 0x6f, 0xdc, 0x44, + 0x14, 0x8e, 0x9b, 0xdf, 0x2f, 0x6d, 0x81, 0x49, 0xa4, 0x6e, 0x9c, 0xd4, 0x4d, 0x4d, 0x50, 0xb6, + 0x91, 0x62, 0x27, 0x41, 0x2a, 0x08, 0xc4, 0xaf, 0x84, 0x1f, 0x8a, 0x54, 0xa4, 0xd6, 0xe1, 0xc4, + 0xc5, 0x9a, 0xf5, 0xce, 0x6e, 0x46, 0xb5, 0x3d, 0x8e, 0x67, 0x36, 0xa1, 0x42, 0x15, 0x12, 0x88, + 0x03, 0x37, 0x24, 0x24, 0xc4, 0x95, 0x2b, 0x27, 0xfe, 0x8c, 0x1e, 0x2b, 0x71, 0xe1, 0x04, 0x28, + 0x81, 0x7f, 0x80, 0xbf, 0x00, 0xcd, 0x9b, 0xf1, 0x66, 0x43, 0x9c, 0xcd, 0xc2, 0xc9, 0xde, 0x99, + 0xef, 0xbd, 0xef, 0xfb, 0x66, 0xde, 0x7b, 0x5e, 0x58, 0x49, 0xe9, 0x11, 0xcd, 0x99, 0x0a, 0xf5, + 0x33, 0x2c, 0xd9, 0x31, 0x2d, 0xdb, 0x32, 0x3c, 0xec, 0xb1, 0xf2, 0x49, 0x50, 0x94, 0x42, 0x09, + 0xb2, 0x60, 0x11, 0x81, 0x7e, 0x06, 0x16, 0xe1, 0x2e, 0x74, 0x45, 0x57, 0x20, 0x20, 0xd4, 0x6f, + 0x06, 0xeb, 0x2e, 0x77, 0x85, 0xe8, 0xa6, 0x2c, 0xa4, 0x05, 0x0f, 0x69, 0x9e, 0x0b, 0x45, 0x15, + 0x17, 0xb9, 0xb4, 0xbb, 0xeb, 0x89, 0x90, 0x99, 0x90, 0x61, 0x8b, 0x4a, 0x66, 0x28, 0xc2, 0xa3, + 0xad, 0x16, 0x53, 0x74, 0x2b, 0x2c, 0x68, 0x97, 0xe7, 0x08, 0xb6, 0xd8, 0xbb, 0xb5, 0xba, 0x0a, + 0x5a, 0xd2, 0xac, 0x4a, 0x57, 0x2f, 0x9d, 0x17, 0x65, 0x91, 0x58, 0x84, 0x37, 0x48, 0x58, 0x51, + 0x25, 0x82, 0x5b, 0x12, 0x7f, 0x01, 0xc8, 0x23, 0x2d, 0xe3, 0x21, 0xa6, 0x8d, 0xd8, 0x61, 0x8f, + 0x49, 0xe5, 0x3f, 0x82, 0xf9, 0x73, 0xab, 0xb2, 0x10, 0xb9, 0x64, 0xe4, 0x0d, 0x98, 0x32, 0xf4, + 0x0d, 0x67, 0xc5, 0x69, 0xce, 0x6d, 0x2f, 0x07, 0x75, 0x07, 0x13, 0x98, 0xa8, 0x9d, 0x89, 0x67, + 0xbf, 0xdd, 0x19, 0x8b, 0x6c, 0x84, 0x3f, 0x0f, 0x2f, 0x99, 0x94, 0x42, 0xa4, 0x7d, 0x9e, 0xaf, + 0x1d, 0x98, 0xd1, 0x0b, 0x7b, 0x79, 0x47, 0x10, 0x02, 0x13, 0x39, 0xcd, 0x18, 0xe6, 0x9e, 0x8d, + 0xf0, 0x9d, 0x30, 0x98, 0x6e, 0xd1, 0x94, 0xe6, 0x09, 0x6b, 0x5c, 0x5b, 0x19, 0x6f, 0xce, 0x6d, + 0x2f, 0x06, 0xc6, 0x50, 0xa0, 0x0d, 0x05, 0xd6, 0x50, 0xb0, 0x2b, 0x78, 0xbe, 0xb3, 0xa9, 0xf9, + 0x7e, 0xfa, 0xfd, 0x4e, 0xb3, 0xcb, 0xd5, 0x41, 0xaf, 0x15, 0x24, 0x22, 0x0b, 0xad, 0x7b, 0xf3, + 0xd8, 0x90, 0xed, 0xc7, 0xa1, 0x7a, 0x52, 0x30, 0x89, 0x01, 0x32, 0xaa, 0x72, 0xfb, 0x7f, 0x3b, + 0xd5, 0x31, 0x18, 0x75, 0x7d, 0xbf, 0x93, 0x85, 0x5e, 0x68, 0x38, 0xc8, 0xed, 0x5d, 0x62, 0xd7, + 0x1a, 0xb0, 0x86, 0x4d, 0x08, 0x59, 0x85, 0x9b, 0x8a, 0x67, 0x2c, 0x56, 0x22, 0x2e, 0x59, 0x87, + 0xa7, 0x69, 0xe3, 0xda, 0x8a, 0xd3, 0x1c, 0x8f, 0xae, 0xeb, 0xd5, 0x4f, 0x44, 0x84, 0x6b, 0xe4, + 0x4d, 0x70, 0x99, 0x54, 0x3c, 0xa3, 0x8a, 0xb5, 0xe3, 0x56, 0x2a, 0x92, 0xc7, 0x72, 0x20, 0x62, + 0x1c, 0x23, 0x6e, 0xf5, 0x11, 0x3b, 0x08, 0xe8, 0x07, 0xbf, 0x05, 0x4b, 0x34, 0x4d, 0x45, 0x82, + 0x45, 0x13, 0x6b, 0xda, 0x38, 0x13, 0xb9, 0x3a, 0x90, 0x71, 0xca, 0x3a, 0xaa, 0x31, 0x81, 0xd1, + 0x8d, 0x33, 0x88, 0x16, 0xfa, 0x31, 0x02, 0x1e, 0xb0, 0x8e, 0xf2, 0x17, 0xe1, 0x16, 0x7a, 0xc6, + 0xac, 0x11, 0x9a, 0xa9, 0xee, 0x65, 0x1f, 0x1a, 0x17, 0xb7, 0xec, 0xa1, 0xbc, 0x06, 0x53, 0xc6, + 0xb9, 0x2d, 0x82, 0x21, 0x37, 0x62, 0x2b, 0xc0, 0xc0, 0xfd, 0x25, 0x58, 0xc4, 0xa4, 0xfb, 0x07, + 0xe2, 0x78, 0x4f, 0x97, 0xe8, 0xfb, 0x54, 0xd1, 0x8a, 0xf1, 0x1b, 0x07, 0xdc, 0xba, 0xdd, 0xfe, + 0x4d, 0xcc, 0x64, 0x3c, 0x8f, 0x13, 0x21, 0xd5, 0xa8, 0xb4, 0xd3, 0x19, 0xcf, 0x77, 0x85, 0x54, + 0x24, 0x84, 0x79, 0xec, 0x88, 0x58, 0xf6, 0x5a, 0x32, 0x29, 0x79, 0x81, 0x0d, 0x89, 0xf5, 0x34, + 0x1b, 0x11, 0xdc, 0xda, 0x1f, 0xdc, 0xf1, 0x3f, 0x82, 0x7b, 0x28, 0x05, 0x65, 0x3c, 0x2c, 0xc5, + 0x11, 0x6f, 0xb3, 0xd2, 0x9c, 0xc2, 0x07, 0xe6, 0x2a, 0xb8, 0xc8, 0xad, 0x70, 0xe2, 0xc2, 0x4c, + 0x61, 0x21, 0xb6, 0x72, 0xfb, 0xbf, 0xfd, 0x43, 0x58, 0x1f, 0x25, 0x91, 0xf5, 0xb8, 0x0b, 0x20, + 0x0b, 0x96, 0xc4, 0x9d, 0x5e, 0xde, 0xbe, 0xa2, 0xe4, 0xf6, 0x0b, 0x96, 0x68, 0x98, 0xb5, 0x3a, + 0xab, 0xe3, 0x3e, 0xd4, 0x61, 0xfe, 0x16, 0x2c, 0x9d, 0x51, 0x6a, 0xd8, 0xb9, 0x8b, 0xd5, 0x3d, + 0xa6, 0xb1, 0x55, 0x8f, 0xe9, 0x77, 0xff, 0x7b, 0x07, 0x96, 0xeb, 0x63, 0xac, 0xb0, 0x07, 0x70, + 0xc3, 0x1c, 0xa0, 0xa5, 0xb7, 0xda, 0xee, 0xd6, 0x6b, 0xc3, 0x2c, 0x26, 0x83, 0x95, 0x77, 0x9d, + 0x9f, 0x2d, 0x49, 0xd2, 0x84, 0x17, 0x93, 0x5e, 0x59, 0xb2, 0x5c, 0x99, 0x6a, 0x8d, 0x79, 0x1b, + 0x5b, 0x63, 0x22, 0xba, 0x69, 0xd7, 0xb1, 0x46, 0xf7, 0xda, 0xdb, 0x7f, 0x4d, 0xc3, 0x24, 0x0a, + 0x23, 0x5f, 0x39, 0x30, 0x65, 0xa6, 0x0a, 0x69, 0xd6, 0xb3, 0x5e, 0x1c, 0x62, 0xee, 0xbd, 0x11, + 0x90, 0xc6, 0xa1, 0xbf, 0xfa, 0xe5, 0x2f, 0x7f, 0x7e, 0x77, 0xcd, 0x23, 0xcb, 0xe1, 0x90, 0x99, + 0x4b, 0xbe, 0x80, 0x49, 0x9c, 0x0f, 0x64, 0x6d, 0x58, 0xe6, 0x81, 0xf9, 0xe6, 0x36, 0xaf, 0x06, + 0x5a, 0x05, 0x2f, 0xa3, 0x82, 0xdb, 0x64, 0xe9, 0x12, 0x05, 0xc8, 0xfb, 0x83, 0x03, 0x73, 0x03, + 0x2d, 0x49, 0x36, 0x86, 0xa4, 0xbf, 0xd8, 0xd5, 0x6e, 0x30, 0x2a, 0xdc, 0x6a, 0x5a, 0x47, 0x4d, + 0xab, 0xc4, 0xaf, 0xd7, 0x84, 0xe3, 0xca, 0xd6, 0x04, 0xf9, 0xd1, 0x81, 0x1b, 0xe7, 0x5a, 0x97, + 0x84, 0x43, 0xd8, 0xea, 0x46, 0x80, 0xbb, 0x39, 0x7a, 0x80, 0x15, 0xb8, 0x81, 0x02, 0xd7, 0xc8, + 0x2b, 0xf5, 0x02, 0xe5, 0x81, 0x38, 0x8e, 0x4d, 0xe5, 0xb6, 0xb5, 0xa2, 0x13, 0x07, 0x6e, 0x0f, + 0x6d, 0x45, 0xf2, 0xce, 0x10, 0x09, 0xa3, 0x4c, 0x03, 0xf7, 0xdd, 0xff, 0x9f, 0xc0, 0x7a, 0x7a, + 0x1b, 0x3d, 0xbd, 0x4e, 0xee, 0x87, 0x97, 0x7f, 0xdb, 0xe3, 0x6a, 0xc2, 0xd8, 0xd3, 0x0f, 0x3f, + 0xaf, 0x16, 0x9e, 0x92, 0x9f, 0x1d, 0x78, 0xe1, 0x5f, 0x8d, 0x4c, 0xb6, 0xae, 0x52, 0x75, 0x61, + 0x50, 0xb8, 0xdb, 0xff, 0x25, 0xc4, 0x4a, 0xbf, 0x8f, 0xd2, 0x37, 0x49, 0x30, 0x4c, 0x3a, 0x8e, + 0xb8, 0x4a, 0xb6, 0xfe, 0xf1, 0x74, 0xe7, 0xbd, 0x67, 0x27, 0x9e, 0xf3, 0xfc, 0xc4, 0x73, 0xfe, + 0x38, 0xf1, 0x9c, 0x6f, 0x4f, 0xbd, 0xb1, 0xe7, 0xa7, 0xde, 0xd8, 0xaf, 0xa7, 0xde, 0xd8, 0xa7, + 0x6b, 0x03, 0x9f, 0xf2, 0x73, 0x39, 0x3f, 0xeb, 0x67, 0xc5, 0xef, 0x79, 0x6b, 0x0a, 0xff, 0xcd, + 0xbc, 0xfa, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x31, 0x49, 0xcb, 0x61, 0xcc, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -735,8 +743,8 @@ type QueryClient interface { BlockReward(ctx context.Context, in *QueryBlockRewardRequest, opts ...grpc.CallOption) (*QueryBlockRewardResponse, error) // ShowIprpcData queries for the iprpc data ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataRequest, opts ...grpc.CallOption) (*QueryShowIprpcDataResponse, error) - // IprpcProviderReward queries for a provider's current IPRPC reward (relative to its serviced CU) - IprpcProviderReward(ctx context.Context, in *QueryIprpcProviderRewardRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardResponse, error) + // IprpcProviderRewardEstimation queries for a provider's current IPRPC reward (relative to its serviced CU) + IprpcProviderRewardEstimation(ctx context.Context, in *QueryIprpcProviderRewardEstimationRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardEstimationResponse, error) // IprpcSpecReward queries for a spec's IPRPC reward IprpcSpecReward(ctx context.Context, in *QueryIprpcSpecRewardRequest, opts ...grpc.CallOption) (*QueryIprpcSpecRewardResponse, error) } @@ -785,9 +793,9 @@ func (c *queryClient) ShowIprpcData(ctx context.Context, in *QueryShowIprpcDataR return out, nil } -func (c *queryClient) IprpcProviderReward(ctx context.Context, in *QueryIprpcProviderRewardRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardResponse, error) { - out := new(QueryIprpcProviderRewardResponse) - err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Query/IprpcProviderReward", in, out, opts...) +func (c *queryClient) IprpcProviderRewardEstimation(ctx context.Context, in *QueryIprpcProviderRewardEstimationRequest, opts ...grpc.CallOption) (*QueryIprpcProviderRewardEstimationResponse, error) { + out := new(QueryIprpcProviderRewardEstimationResponse) + err := c.cc.Invoke(ctx, "/lavanet.lava.rewards.Query/IprpcProviderRewardEstimation", in, out, opts...) if err != nil { return nil, err } @@ -813,8 +821,8 @@ type QueryServer interface { BlockReward(context.Context, *QueryBlockRewardRequest) (*QueryBlockRewardResponse, error) // ShowIprpcData queries for the iprpc data ShowIprpcData(context.Context, *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) - // IprpcProviderReward queries for a provider's current IPRPC reward (relative to its serviced CU) - IprpcProviderReward(context.Context, *QueryIprpcProviderRewardRequest) (*QueryIprpcProviderRewardResponse, error) + // IprpcProviderRewardEstimation queries for a provider's current IPRPC reward (relative to its serviced CU) + IprpcProviderRewardEstimation(context.Context, *QueryIprpcProviderRewardEstimationRequest) (*QueryIprpcProviderRewardEstimationResponse, error) // IprpcSpecReward queries for a spec's IPRPC reward IprpcSpecReward(context.Context, *QueryIprpcSpecRewardRequest) (*QueryIprpcSpecRewardResponse, error) } @@ -835,8 +843,8 @@ func (*UnimplementedQueryServer) BlockReward(ctx context.Context, req *QueryBloc func (*UnimplementedQueryServer) ShowIprpcData(ctx context.Context, req *QueryShowIprpcDataRequest) (*QueryShowIprpcDataResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ShowIprpcData not implemented") } -func (*UnimplementedQueryServer) IprpcProviderReward(ctx context.Context, req *QueryIprpcProviderRewardRequest) (*QueryIprpcProviderRewardResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method IprpcProviderReward not implemented") +func (*UnimplementedQueryServer) IprpcProviderRewardEstimation(ctx context.Context, req *QueryIprpcProviderRewardEstimationRequest) (*QueryIprpcProviderRewardEstimationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IprpcProviderRewardEstimation not implemented") } func (*UnimplementedQueryServer) IprpcSpecReward(ctx context.Context, req *QueryIprpcSpecRewardRequest) (*QueryIprpcSpecRewardResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method IprpcSpecReward not implemented") @@ -918,20 +926,20 @@ func _Query_ShowIprpcData_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } -func _Query_IprpcProviderReward_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryIprpcProviderRewardRequest) +func _Query_IprpcProviderRewardEstimation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryIprpcProviderRewardEstimationRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).IprpcProviderReward(ctx, in) + return srv.(QueryServer).IprpcProviderRewardEstimation(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/lavanet.lava.rewards.Query/IprpcProviderReward", + FullMethod: "/lavanet.lava.rewards.Query/IprpcProviderRewardEstimation", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).IprpcProviderReward(ctx, req.(*QueryIprpcProviderRewardRequest)) + return srv.(QueryServer).IprpcProviderRewardEstimation(ctx, req.(*QueryIprpcProviderRewardEstimationRequest)) } return interceptor(ctx, in, info, handler) } @@ -975,8 +983,8 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_ShowIprpcData_Handler, }, { - MethodName: "IprpcProviderReward", - Handler: _Query_IprpcProviderReward_Handler, + MethodName: "IprpcProviderRewardEstimation", + Handler: _Query_IprpcProviderRewardEstimation_Handler, }, { MethodName: "IprpcSpecReward", @@ -1283,7 +1291,7 @@ func (m *QueryShowIprpcDataResponse) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } -func (m *QueryIprpcProviderRewardRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryIprpcProviderRewardEstimationRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1293,12 +1301,12 @@ func (m *QueryIprpcProviderRewardRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryIprpcProviderRewardRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryIprpcProviderRewardEstimationRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryIprpcProviderRewardRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryIprpcProviderRewardEstimationRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1313,7 +1321,7 @@ func (m *QueryIprpcProviderRewardRequest) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } -func (m *QueryIprpcProviderRewardResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryIprpcProviderRewardEstimationResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1323,12 +1331,12 @@ func (m *QueryIprpcProviderRewardResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryIprpcProviderRewardResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryIprpcProviderRewardEstimationResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryIprpcProviderRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryIprpcProviderRewardEstimationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1551,7 +1559,7 @@ func (m *QueryShowIprpcDataResponse) Size() (n int) { return n } -func (m *QueryIprpcProviderRewardRequest) Size() (n int) { +func (m *QueryIprpcProviderRewardEstimationRequest) Size() (n int) { if m == nil { return 0 } @@ -1564,7 +1572,7 @@ func (m *QueryIprpcProviderRewardRequest) Size() (n int) { return n } -func (m *QueryIprpcProviderRewardResponse) Size() (n int) { +func (m *QueryIprpcProviderRewardEstimationResponse) Size() (n int) { if m == nil { return 0 } @@ -2354,7 +2362,7 @@ func (m *QueryShowIprpcDataResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryIprpcProviderRewardRequest) Unmarshal(dAtA []byte) error { +func (m *QueryIprpcProviderRewardEstimationRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2377,10 +2385,10 @@ func (m *QueryIprpcProviderRewardRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryIprpcProviderRewardRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryIprpcProviderRewardEstimationRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryIprpcProviderRewardRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryIprpcProviderRewardEstimationRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2436,7 +2444,7 @@ func (m *QueryIprpcProviderRewardRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryIprpcProviderRewardResponse) Unmarshal(dAtA []byte) error { +func (m *QueryIprpcProviderRewardEstimationResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2459,10 +2467,10 @@ func (m *QueryIprpcProviderRewardResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryIprpcProviderRewardResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryIprpcProviderRewardEstimationResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryIprpcProviderRewardResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryIprpcProviderRewardEstimationResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/x/rewards/types/query.pb.gw.go b/x/rewards/types/query.pb.gw.go index 2054cc9331..f2d9d119e7 100644 --- a/x/rewards/types/query.pb.gw.go +++ b/x/rewards/types/query.pb.gw.go @@ -105,8 +105,8 @@ func local_request_Query_ShowIprpcData_0(ctx context.Context, marshaler runtime. } -func request_Query_IprpcProviderReward_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryIprpcProviderRewardRequest +func request_Query_IprpcProviderRewardEstimation_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIprpcProviderRewardEstimationRequest var metadata runtime.ServerMetadata var ( @@ -127,13 +127,13 @@ func request_Query_IprpcProviderReward_0(ctx context.Context, marshaler runtime. return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider", err) } - msg, err := client.IprpcProviderReward(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.IprpcProviderRewardEstimation(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_IprpcProviderReward_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryIprpcProviderRewardRequest +func local_request_Query_IprpcProviderRewardEstimation_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryIprpcProviderRewardEstimationRequest var metadata runtime.ServerMetadata var ( @@ -154,7 +154,7 @@ func local_request_Query_IprpcProviderReward_0(ctx context.Context, marshaler ru return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider", err) } - msg, err := server.IprpcProviderReward(ctx, &protoReq) + msg, err := server.IprpcProviderRewardEstimation(ctx, &protoReq) return msg, metadata, err } @@ -311,7 +311,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_IprpcProviderReward_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_IprpcProviderRewardEstimation_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -322,7 +322,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_IprpcProviderReward_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_IprpcProviderRewardEstimation_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 { @@ -330,7 +330,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_IprpcProviderReward_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_IprpcProviderRewardEstimation_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -478,7 +478,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_IprpcProviderReward_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_IprpcProviderRewardEstimation_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) @@ -487,14 +487,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_IprpcProviderReward_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_IprpcProviderRewardEstimation_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_IprpcProviderReward_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_IprpcProviderRewardEstimation_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -530,7 +530,7 @@ var ( pattern_Query_ShowIprpcData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"lavanet", "lava", "rewards", "show_iprpc_data"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_IprpcProviderReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"lavanet", "lava", "rewards", "iprpc_provider_reward", "provider"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_IprpcProviderRewardEstimation_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"lavanet", "lava", "rewards", "iprpc_provider_reward", "provider"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_IprpcSpecReward_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"lavanet", "lava", "rewards", "iprpc_spec_reward", "spec"}, "", runtime.AssumeColonVerbOpt(false))) ) @@ -544,7 +544,7 @@ var ( forward_Query_ShowIprpcData_0 = runtime.ForwardResponseMessage - forward_Query_IprpcProviderReward_0 = runtime.ForwardResponseMessage + forward_Query_IprpcProviderRewardEstimation_0 = runtime.ForwardResponseMessage forward_Query_IprpcSpecReward_0 = runtime.ForwardResponseMessage ) From 42ab2dfe1d44e07f5a6ce2bbe3904fc7b1638c1f Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 14:19:29 +0200 Subject: [PATCH 45/64] CNS-870: change zero coins --- x/dualstaking/keeper/delegator_reward.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x/dualstaking/keeper/delegator_reward.go b/x/dualstaking/keeper/delegator_reward.go index a04e41dc3e..fe08c7fac7 100644 --- a/x/dualstaking/keeper/delegator_reward.go +++ b/x/dualstaking/keeper/delegator_reward.go @@ -83,12 +83,12 @@ func (k Keeper) GetAllDelegatorReward(ctx sdk.Context) (list []types.DelegatorRe // providerReward = totalReward * ((effectiveDelegations*commission + providerStake) / effectiveStake) // delegatorsReward = totalReward - providerReward func (k Keeper) CalcRewards(ctx sdk.Context, stakeEntry epochstoragetypes.StakeEntry, totalReward sdk.Coins, delegations []types.Delegation) (providerReward sdk.Coins, delegatorsReward sdk.Coins) { - zeroCoin := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) + zeroCoins := sdk.NewCoins() effectiveDelegations, effectiveStake := k.CalcEffectiveDelegationsAndStake(stakeEntry, delegations) // Sanity check - effectiveStake != 0 if effectiveStake.IsZero() { - return zeroCoin, zeroCoin + return zeroCoins, zeroCoins } providerReward = totalReward.MulInt(stakeEntry.Stake.Amount).QuoInt(effectiveStake) if !effectiveDelegations.IsZero() && stakeEntry.DelegateCommission != 0 { @@ -119,7 +119,7 @@ func (k Keeper) CalcEffectiveDelegationsAndStake(stakeEntry epochstoragetypes.St func (k Keeper) CalcDelegatorReward(ctx sdk.Context, delegatorsReward sdk.Coins, totalDelegations math.Int, delegation types.Delegation) sdk.Coins { // Sanity check - totalDelegations != 0 if totalDelegations.IsZero() { - return sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) + return sdk.NewCoins() } return delegatorsReward.MulInt(delegation.Amount.Amount).QuoInt(totalDelegations) } @@ -166,21 +166,21 @@ func (k Keeper) ClaimRewards(ctx sdk.Context, delegator string, provider string) // it returns the provider reward amount and updates the delegatorReward map with the reward portion for each delegator func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.AccAddress, chainID string, totalReward sdk.Coins, senderModule string, calcOnlyProvider bool, calcOnlyDelegators bool, calcOnlyContributer bool) (providerReward sdk.Coins, claimableRewards sdk.Coins, err error) { block := uint64(ctx.BlockHeight()) - zeroCoin := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), math.ZeroInt())) + zeroCoins := sdk.NewCoins() epoch, _, err := k.epochstorageKeeper.GetEpochStartForBlock(ctx, block) if err != nil { - return zeroCoin, zeroCoin, utils.LavaFormatError(types.ErrCalculatingProviderReward.Error(), err, + return zeroCoins, zeroCoins, utils.LavaFormatError(types.ErrCalculatingProviderReward.Error(), err, utils.Attribute{Key: "block", Value: block}, ) } stakeEntry, err := k.epochstorageKeeper.GetStakeEntryForProviderEpoch(ctx, chainID, providerAddr, epoch) if err != nil { - return zeroCoin, zeroCoin, err + return zeroCoins, zeroCoins, err } delegations, err := k.GetProviderDelegators(ctx, providerAddr.String(), epoch) if err != nil { - return zeroCoin, zeroCoin, utils.LavaFormatError("cannot get provider's delegators", err) + return zeroCoins, zeroCoins, utils.LavaFormatError("cannot get provider's delegators", err) } claimableRewards = totalReward // make sure this is post boost when rewards pool is introduced @@ -194,7 +194,7 @@ func (k Keeper) RewardProvidersAndDelegators(ctx sdk.Context, providerAddr sdk.A if !calcOnlyContributer { err = k.PayContributors(ctx, senderModule, contributorAddresses, contributorReward, chainID) if err != nil { - return zeroCoin, zeroCoin, err + return zeroCoins, zeroCoins, err } } } From 80e3986929c5d425d7fa24b3fb0cd674062a52cd Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 15:44:39 +0200 Subject: [PATCH 46/64] CNS-870: small PR fixes --- x/rewards/keeper/iprpc.go | 40 +++++++++++++---------------------- x/rewards/keeper/providers.go | 10 ++++----- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index fd2d5bebe0..03141c03f3 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -3,7 +3,6 @@ package keeper import ( "fmt" "sort" - "strings" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/lavanet/lava/utils" @@ -59,16 +58,14 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat iprpcReward, found := k.GetIprpcReward(ctx, i) if found { // found IPRPC reward, find if spec exists - specIndex := -1 + specFound := false for i := 0; i < len(iprpcReward.SpecFunds); i++ { if iprpcReward.SpecFunds[i].Spec == spec { - specIndex = i + specFound = true + iprpcReward.SpecFunds[i].Fund = iprpcReward.SpecFunds[i].Fund.Add(fund...) } } - // update spec funds - if specIndex >= 0 { - iprpcReward.SpecFunds[specIndex].Fund = iprpcReward.SpecFunds[specIndex].Fund.Add(fund...) - } else { + if !specFound { iprpcReward.SpecFunds = append(iprpcReward.SpecFunds, types.Specfund{Spec: spec, Fund: fund}) } } else { @@ -112,21 +109,14 @@ func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMon // distributeIprpcRewards is distributing the IPRPC rewards for providers according to their serviced CU func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcReward, specCuMap map[string]types.SpecCuType) { + usedReward := sdk.NewCoins() for _, specFund := range iprpcReward.SpecFunds { - // collect details - details := map[string]string{"spec": specFund.Spec} - rewardsStr := []string{} - for _, reward := range specFund.Fund { - rewardsStr = append(rewardsStr, reward.String()) - } - details["rewards"] = strings.Join(rewardsStr, ",") - // verify specCuMap holds an entry for the relevant spec specCu, ok := specCuMap[specFund.Spec] if !ok { utils.LavaFormatError("did not distribute iprpc rewards to providers in spec", fmt.Errorf("specCU not found"), - utils.LogAttr("spec", details["spec"]), - utils.LogAttr("rewards", details["rewards"]), + utils.LogAttr("spec", specFund.Spec), + utils.LogAttr("rewards", specFund.Fund.String()), ) continue } @@ -137,10 +127,8 @@ func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcR providers = append(providers, provider) } sort.Strings(providers) - details["providers"] = strings.Join(providers, ",") // distribute IPRPC reward for spec - usedReward := sdk.NewCoins() for _, provider := range providers { providerAddr, err := sdk.AccAddressFromBech32(provider) if err != nil { @@ -158,13 +146,15 @@ func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcR usedReward = usedReward.Add(providerIprpcReward...) } - // handle leftovers + // count used rewards usedReward = specFund.Fund.Sub(usedReward...) - err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) - if err != nil { - utils.LavaFormatError("could not send iprpc leftover to community pool", err) - } + } - utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, details, "IPRPC monthly rewards distributed successfully") + // handle leftovers + err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) + if err != nil { + utils.LavaFormatError("could not send iprpc leftover to community pool", err) } + + utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, map[string]string{"iprpc_rewards_leftovers": usedReward.String()}, "IPRPC monthly rewards distributed successfully") } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 1ef5260092..890004dadf 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -67,8 +67,8 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { specTotalPayout = k.specTotalPayout(ctx, total, sdk.NewDecFromInt(totalbasepay), spec) } // distribute the rewards to all providers - for _, basepay := range basepays { - if !specTotalPayout.IsZero() { + if !specTotalPayout.IsZero() { + for _, basepay := range basepays { // calculate the providers bonus base on adjusted base pay reward := specTotalPayout.Mul(basepay.TotalAdjusted).QuoInt(totalbasepay).TruncateInt() totalRewarded = totalRewarded.Add(reward) @@ -90,10 +90,10 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } details[providerAddr.String()+" "+spec.ChainID] = reward.String() - } - // count iprpc cu - k.countIprpcCu(specCuMap, basepay.IprpcCu, spec.ChainID, basepay.Provider) + // count iprpc cu + k.countIprpcCu(specCuMap, basepay.IprpcCu, spec.ChainID, basepay.Provider) + } } } From e1da79c790caf2ae562891f9ef3b974b1c009986 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 15:54:41 +0200 Subject: [PATCH 47/64] CNS-870: simplify transferSpecFundsToNextMonth --- x/rewards/keeper/iprpc.go | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index 03141c03f3..f6dd513d78 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -81,27 +81,34 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat // this function is used when there are no providers that should get the monthly IPRPC reward, // so the reward transfers to the next month func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMonthSpecFunds []types.Specfund) []types.Specfund { - mergedMap := make(map[string]sdk.Coins) + // Create a slice to store merged spec funds + var mergedList []types.Specfund - // populate map with current spec funds - for i, obj := range specFunds { - mergedMap[obj.Spec] = specFunds[i].Fund - } + // Loop through current spec funds + for _, current := range specFunds { + found := false + + // Loop through next month spec funds + for i, next := range nextMonthSpecFunds { + // If the spec is found in next month spec funds, merge the funds + if current.Spec == next.Spec { + // Add current month's fund to next month's fund + nextMonthSpecFunds[i].Fund = nextMonthSpecFunds[i].Fund.Add(current.Fund...) + found = true + break + } + } - // update the merged map with the next month spec funds - for i, obj := range nextMonthSpecFunds { - if fund, ok := mergedMap[obj.Spec]; ok { - mergedMap[obj.Spec] = fund.Add(nextMonthSpecFunds[i].Fund...) - } else { - mergedMap[obj.Spec] = obj.Fund + // If spec is not found in next month spec funds, add it to the merged list + if !found { + mergedList = append(mergedList, current) } } - // Convert map back to list and sort - var mergedList []types.Specfund - for spec, fund := range mergedMap { - mergedList = append(mergedList, types.Specfund{Spec: spec, Fund: fund}) - } + // Append any remaining spec funds from next month that were not merged + mergedList = append(mergedList, nextMonthSpecFunds...) + + // Sort the merged list by spec sort.Slice(mergedList, func(i, j int) bool { return mergedList[i].Spec < mergedList[j].Spec }) return mergedList From ce6e04119c4e5af6461872e00b727eaa23a5d43b Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 15:59:44 +0200 Subject: [PATCH 48/64] CNS-872: fix lint --- x/rewards/keeper/iprpc_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index 5d85a1abf6..1150b29581 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -187,7 +187,7 @@ func TestIprpcProviderRewardQuery(t *testing.T) { {provider: p2, fund: iprpcFunds.Sub(minIprpcCost).MulInt(sdk.NewInt(4)).QuoInt(sdk.NewInt(5))}, } for _, expectedProviderReward := range expectedProviderRewards { - res, err := ts.QueryRewardsIprpcProviderReward(expectedProviderReward.provider) + res, err := ts.QueryRewardsIprpcProviderRewardEstimation(expectedProviderReward.provider) require.NoError(t, err) require.ElementsMatch(t, expectedProviderReward.fund, res.SpecFunds[0].Fund) // taking 0 index because there's a single spec } @@ -482,9 +482,9 @@ func TestIprpcEligibleSubscriptions(t *testing.T) { require.NoError(t, err) // check expected reward for each provider, it should be equal (the service for c1 was equal) - res1, err := ts.QueryRewardsIprpcProviderReward(p1) + res1, err := ts.QueryRewardsIprpcProviderRewardEstimation(p1) require.NoError(t, err) - res2, err := ts.QueryRewardsIprpcProviderReward(p2) + res2, err := ts.QueryRewardsIprpcProviderRewardEstimation(p2) require.NoError(t, err) require.True(t, res1.SpecFunds[0].Fund.IsEqual(res2.SpecFunds[0].Fund)) require.True(t, iprpcFunds.Sub(minIprpcCost).QuoInt(sdk.NewInt(2)).IsEqual(res1.SpecFunds[0].Fund)) @@ -504,9 +504,9 @@ func TestIprpcEligibleSubscriptions(t *testing.T) { require.NoError(t, err) // check none of the providers should get rewards - res1, err = ts.QueryRewardsIprpcProviderReward(p1) + res1, err = ts.QueryRewardsIprpcProviderRewardEstimation(p1) require.NoError(t, err) - res2, err = ts.QueryRewardsIprpcProviderReward(p2) + res2, err = ts.QueryRewardsIprpcProviderRewardEstimation(p2) require.NoError(t, err) require.Len(t, res1.SpecFunds, 0) require.Len(t, res2.SpecFunds, 0) @@ -576,12 +576,12 @@ func TestMultipleIprpcSpec(t *testing.T) { // p1 total CU: 600, p2 total CU: 1200 -> if the rewards were divided by total CU (wrong) the rewards ratio should've been 1:2 // p1 total iprpc CU: 500, p2 total iprpc CU: 500 -> if the rewards were divided by total iprpc CU the rewards should be equal - res1, err := ts.QueryRewardsIprpcProviderReward(p1) + res1, err := ts.QueryRewardsIprpcProviderRewardEstimation(p1) require.NoError(t, err) - res2, err := ts.QueryRewardsIprpcProviderReward(p2) + res2, err := ts.QueryRewardsIprpcProviderRewardEstimation(p2) require.NoError(t, err) require.Equal(t, len(res1.SpecFunds), len(res2.SpecFunds)) - responses := []*rewardstypes.QueryIprpcProviderRewardResponse{res1, res2} + responses := []*rewardstypes.QueryIprpcProviderRewardEstimationResponse{res1, res2} for _, res := range responses { for _, sf := range res.SpecFunds { switch sf.Spec { From a4062fe82fd2857e9d5683481942b811982870ca Mon Sep 17 00:00:00 2001 From: oren-lava Date: Mon, 26 Feb 2024 16:25:52 +0200 Subject: [PATCH 49/64] CNS-870: small fixes --- x/rewards/keeper/iprpc.go | 1 + x/rewards/keeper/providers.go | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index f6dd513d78..b511bc9d90 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -63,6 +63,7 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat if iprpcReward.SpecFunds[i].Spec == spec { specFound = true iprpcReward.SpecFunds[i].Fund = iprpcReward.SpecFunds[i].Fund.Add(fund...) + break } } if !specFound { diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 890004dadf..1ef5260092 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -67,8 +67,8 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { specTotalPayout = k.specTotalPayout(ctx, total, sdk.NewDecFromInt(totalbasepay), spec) } // distribute the rewards to all providers - if !specTotalPayout.IsZero() { - for _, basepay := range basepays { + for _, basepay := range basepays { + if !specTotalPayout.IsZero() { // calculate the providers bonus base on adjusted base pay reward := specTotalPayout.Mul(basepay.TotalAdjusted).QuoInt(totalbasepay).TruncateInt() totalRewarded = totalRewarded.Add(reward) @@ -90,10 +90,10 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } details[providerAddr.String()+" "+spec.ChainID] = reward.String() - - // count iprpc cu - k.countIprpcCu(specCuMap, basepay.IprpcCu, spec.ChainID, basepay.Provider) } + + // count iprpc cu + k.countIprpcCu(specCuMap, basepay.IprpcCu, spec.ChainID, basepay.Provider) } } From e67137f9616e131734fa8dc0e0ecafcd4944ef25 Mon Sep 17 00:00:00 2001 From: Yaroms Date: Mon, 26 Feb 2024 20:09:04 +0200 Subject: [PATCH 50/64] pr changes --- x/rewards/keeper/iprpc.go | 19 ++++++++++--------- x/rewards/keeper/providers.go | 6 ------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index b511bc9d90..a8e32f35c8 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -82,8 +82,8 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat // this function is used when there are no providers that should get the monthly IPRPC reward, // so the reward transfers to the next month func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMonthSpecFunds []types.Specfund) []types.Specfund { - // Create a slice to store merged spec funds - var mergedList []types.Specfund + // Create a slice to store leftover spec funds + var leftoverList []types.Specfund // Loop through current spec funds for _, current := range specFunds { @@ -102,21 +102,22 @@ func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMon // If spec is not found in next month spec funds, add it to the merged list if !found { - mergedList = append(mergedList, current) + leftoverList = append(leftoverList, current) } } // Append any remaining spec funds from next month that were not merged - mergedList = append(mergedList, nextMonthSpecFunds...) - - // Sort the merged list by spec - sort.Slice(mergedList, func(i, j int) bool { return mergedList[i].Spec < mergedList[j].Spec }) - - return mergedList + return append(nextMonthSpecFunds, leftoverList...) } // distributeIprpcRewards is distributing the IPRPC rewards for providers according to their serviced CU func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcReward, specCuMap map[string]types.SpecCuType) { + // none of the providers will get the IPRPC reward this month, transfer the funds to the next month + if len(specCuMap) == 0 { + k.handleNoIprpcRewardToProviders(ctx, iprpcReward) + return + } + usedReward := sdk.NewCoins() for _, specFund := range iprpcReward.SpecFunds { // verify specCuMap holds an entry for the relevant spec diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 1ef5260092..ef1ba844cd 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -105,12 +105,6 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } k.RemoveIprpcReward(ctx, iprpcReward.Id) - // none of the providers will get the IPRPC reward this month, transfer the funds to the next month - if len(specCuMap) == 0 { - k.handleNoIprpcRewardToProviders(ctx, iprpcReward) - return - } - // distribute IPRPC rewards k.distributeIprpcRewards(ctx, iprpcReward, specCuMap) } From f06d3aee77f67c5848da4cf99270f2d60ed94d9a Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Wed, 28 Feb 2024 16:34:46 +0200 Subject: [PATCH 51/64] other changes --- x/dualstaking/keeper/msg_server_unbond.go | 18 ++++++++---------- x/rewards/types/iprpc_data.go | 9 --------- 2 files changed, 8 insertions(+), 19 deletions(-) delete mode 100644 x/rewards/types/iprpc_data.go diff --git a/x/dualstaking/keeper/msg_server_unbond.go b/x/dualstaking/keeper/msg_server_unbond.go index 92b27214b8..96c2b71eaa 100644 --- a/x/dualstaking/keeper/msg_server_unbond.go +++ b/x/dualstaking/keeper/msg_server_unbond.go @@ -56,16 +56,14 @@ func (k Keeper) UnbondFull(ctx sdk.Context, delegator string, validator string, return err } - if err == nil { - logger := k.Logger(ctx) - details := map[string]string{ - "delegator": delegator, - "provider": provider, - "chainID": chainID, - "amount": amount.String(), - } - utils.LogLavaEvent(ctx, logger, types.UnbondingEventName, details, "Unbond") + logger := k.Logger(ctx) + details := map[string]string{ + "delegator": delegator, + "provider": provider, + "chainID": chainID, + "amount": amount.String(), } + utils.LogLavaEvent(ctx, logger, types.UnbondingEventName, details, "Unbond") - return err + return nil } diff --git a/x/rewards/types/iprpc_data.go b/x/rewards/types/iprpc_data.go deleted file mode 100644 index c757d6d0c8..0000000000 --- a/x/rewards/types/iprpc_data.go +++ /dev/null @@ -1,9 +0,0 @@ -package types - -const ( - // IprpcSubscriptionPrefix is the prefix to retrieve all IprpcSubscription - IprpcSubscriptionPrefix = "IprpcSubscription/" - - // MinIprpcCostPrefix is the prefix to retrieve all MinIprpcCost - MinIprpcCostPrefix = "MinIprpcCost/" -) From 07f4dff3487d2a91ac7d1f4966eb87ab2bbc0651 Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Sun, 3 Mar 2024 17:28:55 +0200 Subject: [PATCH 52/64] pr changes --- proto/lavanet/lava/rewards/iprpc.proto | 4 +- .../keeper/pairing_next_epoch_time_block.go | 4 +- x/pairing/keeper/staking.go | 4 +- x/pairing/keeper/unresponsive_provider.go | 4 +- x/rewards/genesis.go | 4 +- x/rewards/keeper/iprpc.go | 97 ++++++------------- x/rewards/keeper/iprpc_reward.go | 23 +++-- x/rewards/keeper/providers.go | 9 +- x/rewards/types/genesis.go | 13 +-- x/rewards/types/genesis_test.go | 13 +-- x/rewards/types/types.go | 17 ++-- x/subscription/keeper/cu_tracker.go | 4 +- x/subscription/types/expected_keepers.go | 2 +- 13 files changed, 84 insertions(+), 114 deletions(-) diff --git a/proto/lavanet/lava/rewards/iprpc.proto b/proto/lavanet/lava/rewards/iprpc.proto index 749fd1cb54..151ba86bb4 100644 --- a/proto/lavanet/lava/rewards/iprpc.proto +++ b/proto/lavanet/lava/rewards/iprpc.proto @@ -5,9 +5,9 @@ option go_package = "github.com/lavanet/lava/x/rewards/types"; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -// list object that holds the +// object that holds the list for iprpc funcs for a specific month id message IprpcReward { - uint64 id = 1; + uint64 id = 1; // month id repeated Specfund spec_funds = 2 [(gogoproto.nullable) = false]; } diff --git a/x/pairing/keeper/pairing_next_epoch_time_block.go b/x/pairing/keeper/pairing_next_epoch_time_block.go index 039f7284e7..b5d192d317 100644 --- a/x/pairing/keeper/pairing_next_epoch_time_block.go +++ b/x/pairing/keeper/pairing_next_epoch_time_block.go @@ -78,7 +78,7 @@ func (k Keeper) calculateAverageBlockTime(ctx sdk.Context, epoch uint64) (uint64 } // Calculate the average block time from prevEpochTimestampAndHeightList - averageBlockTime, err := calculateAverageBlockTimeFromList(ctx, prevEpochTimestampAndHeightList, sampleStep) + averageBlockTime, err := calculateAverageBlockTimeFromList(prevEpochTimestampAndHeightList, sampleStep) if pairingtypes.NotEnoughBlocksToCalculateAverageBlockTimeError.Is(err) || pairingtypes.AverageBlockTimeIsLessOrEqualToZeroError.Is(err) { // we shouldn't fail the get-pairing query because the average block time calculation failed (to indicate the fail, we return 0) return 0, nil @@ -126,7 +126,7 @@ func (k Keeper) getPreviousEpochTimestampsByHeight(ctx sdk.Context, epoch, sampl return prevEpochTimestampAndHeightList, nil } -func calculateAverageBlockTimeFromList(ctx sdk.Context, blockHeightAndTimeList []blockHeightAndTime, sampleStep uint64) (uint64, error) { +func calculateAverageBlockTimeFromList(blockHeightAndTimeList []blockHeightAndTime, sampleStep uint64) (uint64, error) { if len(blockHeightAndTimeList) <= 1 { return 0, utils.LavaFormatError("There isn't enough blockHeight structs in the previous epoch to calculate average block time", pairingtypes.NotEnoughBlocksToCalculateAverageBlockTimeError) } diff --git a/x/pairing/keeper/staking.go b/x/pairing/keeper/staking.go index 66d17271b6..3d908cbb4f 100644 --- a/x/pairing/keeper/staking.go +++ b/x/pairing/keeper/staking.go @@ -47,7 +47,7 @@ func (k Keeper) StakeNewEntry(ctx sdk.Context, validator, creator, chainID strin ) } - endpointsVerified, err := k.validateGeoLocationAndApiInterfaces(ctx, endpoints, geolocation, spec) + endpointsVerified, err := k.validateGeoLocationAndApiInterfaces(endpoints, geolocation, spec) if err != nil { return utils.LavaFormatWarning("invalid endpoints implementation for the given spec", err, utils.Attribute{Key: "provider", Value: creator}, @@ -201,7 +201,7 @@ func (k Keeper) StakeNewEntry(ctx sdk.Context, validator, creator, chainID strin return err } -func (k Keeper) validateGeoLocationAndApiInterfaces(ctx sdk.Context, endpoints []epochstoragetypes.Endpoint, geolocation int32, spec spectypes.Spec) (endpointsFormatted []epochstoragetypes.Endpoint, err error) { +func (k Keeper) validateGeoLocationAndApiInterfaces(endpoints []epochstoragetypes.Endpoint, geolocation int32, spec spectypes.Spec) (endpointsFormatted []epochstoragetypes.Endpoint, err error) { expectedInterfaces := k.specKeeper.GetExpectedServicesForExpandedSpec(spec, true) allowedInterfaces := k.specKeeper.GetExpectedServicesForExpandedSpec(spec, false) diff --git a/x/pairing/keeper/unresponsive_provider.go b/x/pairing/keeper/unresponsive_provider.go index 60dcb12cb6..bb7fa00600 100644 --- a/x/pairing/keeper/unresponsive_provider.go +++ b/x/pairing/keeper/unresponsive_provider.go @@ -102,7 +102,7 @@ func (k Keeper) UnstakeUnresponsiveProviders(ctx sdk.Context, epochsNumToCheckCU // providerPaymentStorageKeyList is not empty -> provider should be punished if len(providerPaymentStorageKeyList) != 0 && existingProviders[providerStakeEntry.GetChain()] > minProviders { - err = k.punishUnresponsiveProvider(ctx, minPaymentBlock, providerPaymentStorageKeyList, providerStakeEntry.GetAddress(), providerStakeEntry.GetChain(), complaintCU, servicedCU) + err = k.punishUnresponsiveProvider(ctx, providerPaymentStorageKeyList, providerStakeEntry.GetAddress(), providerStakeEntry.GetChain(), complaintCU, servicedCU) existingProviders[providerStakeEntry.GetChain()]-- if err != nil { utils.LavaFormatError("unstake unresponsive providers failed to punish provider", err, @@ -212,7 +212,7 @@ func (k Keeper) getCurrentProviderStakeStorageList(ctx sdk.Context) []epochstora } // Function that punishes providers. Current punishment is freeze -func (k Keeper) punishUnresponsiveProvider(ctx sdk.Context, epoch uint64, providerPaymentStorageKeyList []string, providerAddress, chainID string, complaintCU uint64, servicedCU uint64) error { +func (k Keeper) punishUnresponsiveProvider(ctx sdk.Context, providerPaymentStorageKeyList []string, providerAddress, chainID string, complaintCU uint64, servicedCU uint64) error { // freeze the unresponsive provider err := k.FreezeProvider(ctx, providerAddress, []string{chainID}, "unresponsiveness") if err != nil { diff --git a/x/rewards/genesis.go b/x/rewards/genesis.go index caf95b8f2b..bfe82663a5 100644 --- a/x/rewards/genesis.go +++ b/x/rewards/genesis.go @@ -22,7 +22,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) for _, iprpcReward := range genState.IprpcRewards { k.SetIprpcReward(ctx, iprpcReward) } - k.SetIprpcRewardsCurrent(ctx, genState.IprpcRewardsCurrent) + k.SetIprpcRewardsCurrentId(ctx, genState.IprpcRewardsCurrent) k.SetIprpcData(ctx, genState.MinIprpcCost, genState.IprpcSubscriptions) } @@ -35,7 +35,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.IprpcSubscriptions = k.GetAllIprpcSubscription(ctx) genesis.MinIprpcCost = k.GetMinIprpcCost(ctx) genesis.IprpcRewards = k.GetAllIprpcReward(ctx) - genesis.IprpcRewardsCurrent = k.GetIprpcRewardsCurrent(ctx) + genesis.IprpcRewardsCurrent = k.GetIprpcRewardsCurrentId(ctx) // this line is used by starport scaffolding # genesis/module/export return genesis diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index a8e32f35c8..c0d57f4ce8 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -2,7 +2,6 @@ package keeper import ( "fmt" - "sort" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/lavanet/lava/utils" @@ -11,20 +10,15 @@ import ( // handleNoIprpcRewardToProviders handles the situation in which there are no providers to send IPRPC rewards to // so the IPRPC rewards transfer to the next month -func (k Keeper) handleNoIprpcRewardToProviders(ctx sdk.Context, iprpcReward types.IprpcReward) { - nextMonthIprpcReward, found := k.PopIprpcReward(ctx, false) - nextMonthId := k.GetIprpcRewardsCurrent(ctx) - if !found { - nextMonthIprpcReward = types.IprpcReward{Id: nextMonthId, SpecFunds: iprpcReward.SpecFunds} - } else { - nextMonthIprpcReward.SpecFunds = k.transferSpecFundsToNextMonth(iprpcReward.SpecFunds, nextMonthIprpcReward.SpecFunds) +func (k Keeper) handleNoIprpcRewardToProviders(ctx sdk.Context, iprpcFunds []types.Specfund) { + for _, fund := range iprpcFunds { + k.addSpecFunds(ctx, fund.Spec, fund.Fund, 1) } - k.SetIprpcReward(ctx, nextMonthIprpcReward) + details := map[string]string{ - "transferred_funds": iprpcReward.String(), - "next_month_updated_funds": nextMonthIprpcReward.String(), + "transferred_funds": fmt.Sprint(iprpcFunds), } - utils.LogLavaEvent(ctx, k.Logger(ctx), types.TransferIprpcRewardToNextMonth, details, + utils.LogLavaEvent(ctx, k.Logger(ctx), types.TransferIprpcRewardToNextMonthEventName, details, "No provider serviced an IPRPC eligible subscription, transferring current month IPRPC funds to next month") } @@ -34,16 +28,11 @@ func (k Keeper) countIprpcCu(specCuMap map[string]types.SpecCuType, iprpcCu uint specCu, ok := specCuMap[spec] if !ok { specCuMap[spec] = types.SpecCuType{ - ProvidersCu: map[string]uint64{provider: iprpcCu}, + ProvidersCu: []types.ProviderCuType{{Provider: provider, CU: iprpcCu}}, TotalCu: iprpcCu, } } else { - _, ok := specCu.ProvidersCu[provider] - if !ok { - specCu.ProvidersCu[provider] = iprpcCu - } else { - specCu.ProvidersCu[provider] += iprpcCu - } + specCu.ProvidersCu = append(specCu.ProvidersCu, types.ProviderCuType{Provider: provider, CU: iprpcCu}) specCu.TotalCu += iprpcCu specCuMap[spec] = specCu } @@ -53,7 +42,7 @@ func (k Keeper) countIprpcCu(specCuMap map[string]types.SpecCuType, iprpcCu uint // AddSpecFunds adds funds for a specific spec for of months. // This function is used by the fund-iprpc TX. func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { - startID := k.GetIprpcRewardsCurrent(ctx) + 1 // fund IPRPC only from the next month for months + startID := k.GetIprpcRewardsCurrentId(ctx) + 1 // fund IPRPC only from the next month for months for i := startID; i < startID+duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) if found { @@ -78,51 +67,20 @@ func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, durat } } -// transferSpecFundsToNextMonth transfer the specFunds to the next month's IPRPC funds -// this function is used when there are no providers that should get the monthly IPRPC reward, -// so the reward transfers to the next month -func (k Keeper) transferSpecFundsToNextMonth(specFunds []types.Specfund, nextMonthSpecFunds []types.Specfund) []types.Specfund { - // Create a slice to store leftover spec funds - var leftoverList []types.Specfund - - // Loop through current spec funds - for _, current := range specFunds { - found := false - - // Loop through next month spec funds - for i, next := range nextMonthSpecFunds { - // If the spec is found in next month spec funds, merge the funds - if current.Spec == next.Spec { - // Add current month's fund to next month's fund - nextMonthSpecFunds[i].Fund = nextMonthSpecFunds[i].Fund.Add(current.Fund...) - found = true - break - } - } - - // If spec is not found in next month spec funds, add it to the merged list - if !found { - leftoverList = append(leftoverList, current) - } - } - - // Append any remaining spec funds from next month that were not merged - return append(nextMonthSpecFunds, leftoverList...) -} - // distributeIprpcRewards is distributing the IPRPC rewards for providers according to their serviced CU func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcReward, specCuMap map[string]types.SpecCuType) { // none of the providers will get the IPRPC reward this month, transfer the funds to the next month if len(specCuMap) == 0 { - k.handleNoIprpcRewardToProviders(ctx, iprpcReward) + k.handleNoIprpcRewardToProviders(ctx, iprpcReward.SpecFunds) return } - usedReward := sdk.NewCoins() + leftovers := sdk.NewCoins() for _, specFund := range iprpcReward.SpecFunds { // verify specCuMap holds an entry for the relevant spec specCu, ok := specCuMap[specFund.Spec] if !ok { + k.handleNoIprpcRewardToProviders(ctx, []types.Specfund{specFund}) utils.LavaFormatError("did not distribute iprpc rewards to providers in spec", fmt.Errorf("specCU not found"), utils.LogAttr("spec", specFund.Spec), utils.LogAttr("rewards", specFund.Fund.String()), @@ -130,40 +88,39 @@ func (k Keeper) distributeIprpcRewards(ctx sdk.Context, iprpcReward types.IprpcR continue } - // collect providers details - providers := []string{} - for provider := range specCu.ProvidersCu { - providers = append(providers, provider) - } - sort.Strings(providers) - + UsedReward := sdk.NewCoins() // distribute IPRPC reward for spec - for _, provider := range providers { - providerAddr, err := sdk.AccAddressFromBech32(provider) + for _, providerCU := range specCu.ProvidersCu { + providerAddr, err := sdk.AccAddressFromBech32(providerCU.Provider) if err != nil { continue } // calculate provider IPRPC reward - providerIprpcReward := specFund.Fund.MulInt(sdk.NewIntFromUint64(specCu.ProvidersCu[provider])).QuoInt(sdk.NewIntFromUint64(specCu.TotalCu)) + providerIprpcReward := specFund.Fund.MulInt(sdk.NewIntFromUint64(providerCU.CU)).QuoInt(sdk.NewIntFromUint64(specCu.TotalCu)) + + UsedRewardTemp := UsedReward.Add(providerIprpcReward...) + if UsedReward.IsAnyGT(specFund.Fund) { + utils.LavaFormatError("failed to send iprpc rewards to provider", fmt.Errorf("tried to send more rewards than funded"), utils.LogAttr("provider", providerCU)) + break + } + UsedReward = UsedRewardTemp // reward the provider _, _, err = k.dualstakingKeeper.RewardProvidersAndDelegators(ctx, providerAddr, specFund.Spec, providerIprpcReward, string(types.IprpcPoolName), false, false, false) if err != nil { - utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", provider)) + utils.LavaFormatError("failed to send iprpc rewards to provider", err, utils.LogAttr("provider", providerCU)) } - - usedReward = usedReward.Add(providerIprpcReward...) } // count used rewards - usedReward = specFund.Fund.Sub(usedReward...) + leftovers = leftovers.Add(specFund.Fund.Sub(UsedReward...)...) } // handle leftovers - err := k.FundCommunityPoolFromModule(ctx, usedReward, string(types.IprpcPoolName)) + err := k.FundCommunityPoolFromModule(ctx, leftovers, string(types.IprpcPoolName)) if err != nil { utils.LavaFormatError("could not send iprpc leftover to community pool", err) } - utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, map[string]string{"iprpc_rewards_leftovers": usedReward.String()}, "IPRPC monthly rewards distributed successfully") + utils.LogLavaEvent(ctx, k.Logger(ctx), types.IprpcPoolEmissionEventName, map[string]string{"iprpc_rewards_leftovers": leftovers.String()}, "IPRPC monthly rewards distributed successfully") } diff --git a/x/rewards/keeper/iprpc_reward.go b/x/rewards/keeper/iprpc_reward.go index 4db13f6b88..4df6b9c713 100644 --- a/x/rewards/keeper/iprpc_reward.go +++ b/x/rewards/keeper/iprpc_reward.go @@ -8,8 +8,8 @@ import ( "github.com/lavanet/lava/x/rewards/types" ) -// GetIprpcRewardsCurrent get the total number of IprpcReward -func (k Keeper) GetIprpcRewardsCurrent(ctx sdk.Context) uint64 { +// GetIprpcRewardsCurrentId get the total number of IprpcReward +func (k Keeper) GetIprpcRewardsCurrentId(ctx sdk.Context) uint64 { store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{}) byteKey := types.KeyPrefix(types.IprpcRewardsCurrentPrefix) bz := store.Get(byteKey) @@ -23,8 +23,8 @@ func (k Keeper) GetIprpcRewardsCurrent(ctx sdk.Context) uint64 { return binary.BigEndian.Uint64(bz) } -// SetIprpcRewardsCurrent set the total number of IprpcReward -func (k Keeper) SetIprpcRewardsCurrent(ctx sdk.Context, current uint64) { +// SetIprpcRewardsCurrentId set the total number of IprpcReward +func (k Keeper) SetIprpcRewardsCurrentId(ctx sdk.Context, current uint64) { store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{}) byteKey := types.KeyPrefix(types.IprpcRewardsCurrentPrefix) bz := make([]byte, 8) @@ -85,10 +85,15 @@ func GetIprpcRewardIDFromBytes(bz []byte) uint64 { } // PopIprpcReward gets the lowest id IprpcReward object and removes it -func (k Keeper) PopIprpcReward(ctx sdk.Context, advanceCurrent bool) (types.IprpcReward, bool) { - current := k.GetIprpcRewardsCurrent(ctx) - if advanceCurrent { - k.SetIprpcRewardsCurrent(ctx, current+1) - } +func (k Keeper) PopIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { + current := k.GetIprpcRewardsCurrentId(ctx) + k.SetIprpcRewardsCurrentId(ctx, current+1) + defer k.RemoveIprpcReward(ctx, current) + return k.GetIprpcReward(ctx, current) +} + +// GetCurrentIprpcReward gets the lowest id IprpcReward object +func (k Keeper) GetCurrentIprpcReward(ctx sdk.Context) (types.IprpcReward, bool) { + current := k.GetIprpcRewardsCurrentId(ctx) return k.GetIprpcReward(ctx, current) } diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 6acd975bf7..cc22684c6b 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -12,7 +12,11 @@ import ( const DAY_SECONDS = 60 * 60 * 24 -func (k Keeper) AggregateCU(ctx sdk.Context, provider string, chainID string, cu uint64) { +func (k Keeper) AggregateCU(ctx sdk.Context, subscription, provider string, chainID string, cu uint64) { + if !k.IsIprpcSubscription(ctx, subscription) { + return + } + index := types.BasePayIndex{Provider: provider, ChainID: chainID} basepay, found := k.getBasePay(ctx, index) if !found { @@ -98,12 +102,11 @@ func (k Keeper) distributeMonthlyBonusRewards(ctx sdk.Context) { } // Get current month IprpcReward and use it to distribute rewards - iprpcReward, found := k.PopIprpcReward(ctx, true) + iprpcReward, found := k.PopIprpcReward(ctx) if !found { utils.LavaFormatError("current month iprpc reward not found", fmt.Errorf("did not reward providers IPRPC bonus")) return } - k.RemoveIprpcReward(ctx, iprpcReward.Id) // distribute IPRPC rewards k.distributeIprpcRewards(ctx, iprpcReward, specCuMap) diff --git a/x/rewards/types/genesis.go b/x/rewards/types/genesis.go index 41929c2435..67850a259c 100644 --- a/x/rewards/types/genesis.go +++ b/x/rewards/types/genesis.go @@ -17,12 +17,13 @@ const DefaultIndex uint64 = 1 func DefaultGenesis() *GenesisState { return &GenesisState{ // this line is used by starport scaffolding # genesis/types/default - Params: DefaultParams(), - RefillRewardsTS: *types.DefaultGenesis(), - BasePays: []BasePayGenesis{}, - IprpcSubscriptions: []string{}, - MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, sdk.ZeroInt()), - IprpcRewards: []IprpcReward{}, + Params: DefaultParams(), + RefillRewardsTS: *types.DefaultGenesis(), + BasePays: []BasePayGenesis{}, + IprpcSubscriptions: []string{}, + MinIprpcCost: sdk.NewCoin(commontypes.TokenDenom, sdk.ZeroInt()), + IprpcRewards: []IprpcReward{}, + IprpcRewardsCurrent: 0, } } diff --git a/x/rewards/types/genesis_test.go b/x/rewards/types/genesis_test.go index faadd5ac5f..e7745ca5ad 100644 --- a/x/rewards/types/genesis_test.go +++ b/x/rewards/types/genesis_test.go @@ -21,12 +21,13 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "invalid iprpc subscriptions", genState: &types.GenesisState{ - Params: types.DefaultParams(), - RefillRewardsTS: types.DefaultGenesis().RefillRewardsTS, - BasePays: types.DefaultGenesis().BasePays, - IprpcSubscriptions: []string{"invalidAddress"}, - MinIprpcCost: types.DefaultGenesis().MinIprpcCost, - IprpcRewards: types.DefaultGenesis().IprpcRewards, + Params: types.DefaultParams(), + RefillRewardsTS: types.DefaultGenesis().RefillRewardsTS, + BasePays: types.DefaultGenesis().BasePays, + IprpcSubscriptions: []string{"invalidAddress"}, + MinIprpcCost: types.DefaultGenesis().MinIprpcCost, + IprpcRewards: types.DefaultGenesis().IprpcRewards, + IprpcRewardsCurrent: types.DefaultGenesis().GetIprpcRewardsCurrent(), }, valid: false, }, diff --git a/x/rewards/types/types.go b/x/rewards/types/types.go index c3134beb44..537d3ea288 100644 --- a/x/rewards/types/types.go +++ b/x/rewards/types/types.go @@ -48,15 +48,20 @@ const ( // provide service on specific specs. The rewards from this pool are distributed on a monthly // basis const ( - IprpcPoolName Pool = "iprpc_pool" - IprpcPoolEmissionEventName string = "iprpc-pool-emmission" - SetIprpcDataEventName = "set-iprpc-data" - FundIprpcEventName = "fund-iprpc" - TransferIprpcRewardToNextMonth = "transfer-iprpc-reward-to-next-month" + IprpcPoolName Pool = "iprpc_pool" + IprpcPoolEmissionEventName string = "iprpc-pool-emmission" + SetIprpcDataEventName = "set-iprpc-data" + FundIprpcEventName = "fund-iprpc" + TransferIprpcRewardToNextMonthEventName = "transfer-iprpc-reward-to-next-month" ) // helper struct to track the serviced IPRPC CU for each spec+provider type SpecCuType struct { - ProvidersCu map[string]uint64 // provider -> cu + ProvidersCu []ProviderCuType TotalCu uint64 } + +type ProviderCuType struct { + Provider string + CU uint64 +} diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index 7081345ec4..2feae44f69 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -31,9 +31,7 @@ func (k Keeper) GetTrackedCu(ctx sdk.Context, sub string, provider string, chain // AddTrackedCu adds CU to the CU counters in relevant trackedCu entry // Also, it counts the IPRPC CU if the subscription is IPRPC eligible func (k Keeper) AddTrackedCu(ctx sdk.Context, sub string, provider string, chainID string, cuToAdd uint64, block uint64) error { - if k.rewardsKeeper.IsIprpcSubscription(ctx, sub) { - k.rewardsKeeper.AggregateCU(ctx, provider, chainID, cuToAdd) - } + k.rewardsKeeper.AggregateCU(ctx, sub, provider, chainID, cuToAdd) cu, found, key := k.GetTrackedCu(ctx, sub, provider, chainID, block) diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index effaf444be..8ee53de62d 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -70,7 +70,7 @@ type RewardsKeeper interface { ContributeToValidatorsAndCommunityPool(ctx sdk.Context, reward sdk.Coin, senderModule string) (updatedReward sdk.Coin, err error) FundCommunityPoolFromModule(ctx sdk.Context, amount sdk.Coins, senderModule string) error IsIprpcSubscription(ctx sdk.Context, address string) bool - AggregateCU(ctx sdk.Context, provider string, chainID string, cu uint64) + AggregateCU(ctx sdk.Context, subscription, provider string, chainID string, cu uint64) } type StakingKeeper interface { From 4dbcc1d090abe085eaaa6a6b31dc9cf185c40222 Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Tue, 5 Mar 2024 18:32:46 +0200 Subject: [PATCH 53/64] pr change --- x/rewards/keeper/iprpc.go | 16 ++++------------ x/subscription/keeper/cu_tracker.go | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index 75bd755a5b..12006885a9 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -16,9 +16,9 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund return utils.LavaFormatWarning("spec not found or disabled", types.ErrFundIprpc) } - // check fund consists of minimum amount of ulava (duration * min_iprpc_cost) - minIprpcFundCost := k.GetMinIprpcCost(ctx).Amount.MulRaw(int64(duration)) - if fund.AmountOf(k.stakingKeeper.BondDenom(ctx)).LT(minIprpcFundCost) { + // check fund consists of minimum amount of ulava (min_iprpc_cost) + minIprpcFundCost := k.GetMinIprpcCost(ctx) + if fund.AmountOf(k.stakingKeeper.BondDenom(ctx)).LT(minIprpcFundCost.Amount) { return utils.LavaFormatWarning("insufficient ulava tokens in fund. should be at least min iprpc cost * duration", types.ErrFundIprpc, utils.LogAttr("min_iprpc_cost", k.GetMinIprpcCost(ctx).String()), utils.LogAttr("duration", strconv.FormatUint(duration, 10)), @@ -31,17 +31,9 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund if err != nil { return utils.LavaFormatWarning("invalid creator address", types.ErrFundIprpc) } - creatorUlavaBalance := k.bankKeeper.GetBalance(ctx, addr, k.stakingKeeper.BondDenom(ctx)) - if creatorUlavaBalance.Amount.LT(minIprpcFundCost) { - return utils.LavaFormatWarning("insufficient ulava tokens in fund. should be at least min iprpc cost * duration", types.ErrFundIprpc, - utils.LogAttr("min_iprpc_cost", k.GetMinIprpcCost(ctx).String()), - utils.LogAttr("duration", strconv.FormatUint(duration, 10)), - utils.LogAttr("creator_ulava_balance", creatorUlavaBalance.String()), - ) - } // send the minimum cost to the validators allocation pool (and subtract them from the fund) - minIprpcFundCostCoins := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), minIprpcFundCost)) + minIprpcFundCostCoins := sdk.NewCoins(minIprpcFundCost).MulInt(sdk.NewIntFromUint64(duration)) err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, addr, string(types.ValidatorsRewardsAllocationPoolName), minIprpcFundCostCoins) if err != nil { return utils.LavaFormatError(types.ErrFundIprpc.Error()+"for funding validator allocation pool", err, diff --git a/x/subscription/keeper/cu_tracker.go b/x/subscription/keeper/cu_tracker.go index 2feae44f69..7622fdcd78 100644 --- a/x/subscription/keeper/cu_tracker.go +++ b/x/subscription/keeper/cu_tracker.go @@ -253,7 +253,7 @@ func (k Keeper) RewardAndResetCuTracker(ctx sdk.Context, cuTrackerTimerKeyBytes } else if rewardsRemainder.IsPositive() { { // sub expired (no need to update credit), send rewards remainder to the validators - pool := rewardstypes.ValidatorsRewardsDistributionPoolName + pool := rewardstypes.ValidatorsRewardsAllocationPoolName err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, string(pool), sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), rewardsRemainder))) if err != nil { utils.LavaFormatError("failed sending remainder of rewards to the community pool", err, From c73d48a27ac107815436d788293aa22307627574 Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Tue, 5 Mar 2024 18:38:21 +0200 Subject: [PATCH 54/64] pr changes --- x/rewards/keeper/base_pay.go | 21 +++++++++++++++++---- x/rewards/keeper/providers.go | 10 ++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/x/rewards/keeper/base_pay.go b/x/rewards/keeper/base_pay.go index 76c5ebfd50..3e8d49d215 100644 --- a/x/rewards/keeper/base_pay.go +++ b/x/rewards/keeper/base_pay.go @@ -54,7 +54,7 @@ func (k Keeper) SetAllBasePay(ctx sdk.Context, list []types.BasePayGenesis) { } } -func (k Keeper) popAllBasePayForChain(ctx sdk.Context, chainID string, removeAfterPop bool) (list []types.BasePayWithIndex) { +func (k Keeper) getAllBasePayForChain(ctx sdk.Context, chainID string) (list []types.BasePayWithIndex) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BasePayPrefix)) iterator := sdk.KVStorePrefixIterator(store, []byte(chainID)) @@ -64,9 +64,22 @@ func (k Keeper) popAllBasePayForChain(ctx sdk.Context, chainID string, removeAft var val types.BasePay k.cdc.MustUnmarshal(iterator.Value(), &val) list = append(list, types.BasePayWithIndex{BasePayIndex: types.BasePayKeyRecover(string(iterator.Key())), BasePay: val}) - if removeAfterPop { - store.Delete(iterator.Key()) - } + } + + return +} + +func (k Keeper) popAllBasePayForChain(ctx sdk.Context, chainID string) (list []types.BasePayWithIndex) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BasePayPrefix)) + iterator := sdk.KVStorePrefixIterator(store, []byte(chainID)) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.BasePay + k.cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, types.BasePayWithIndex{BasePayIndex: types.BasePayKeyRecover(string(iterator.Key())), BasePay: val}) + store.Delete(iterator.Key()) } return diff --git a/x/rewards/keeper/providers.go b/x/rewards/keeper/providers.go index 27118f9023..c0cca764c8 100644 --- a/x/rewards/keeper/providers.go +++ b/x/rewards/keeper/providers.go @@ -170,8 +170,14 @@ func (k Keeper) specEmissionParts(ctx sdk.Context) (emissions []types.SpecEmissi return emissions } -func (k Keeper) specProvidersBasePay(ctx sdk.Context, chainID string, removeAfterPop bool) ([]types.BasePayWithIndex, math.Int) { - basepays := k.popAllBasePayForChain(ctx, chainID, removeAfterPop) +func (k Keeper) specProvidersBasePay(ctx sdk.Context, chainID string, pop bool) ([]types.BasePayWithIndex, math.Int) { + var basepays []types.BasePayWithIndex + if pop { + basepays = k.popAllBasePayForChain(ctx, chainID) + } else { + basepays = k.getAllBasePayForChain(ctx, chainID) + } + totalBasePay := math.ZeroInt() for _, basepay := range basepays { totalBasePay = totalBasePay.Add(basepay.Total) From 617a02df4b277921ff212c233d04022dff646e6b Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 11:55:21 +0200 Subject: [PATCH 55/64] CNS-872: small fix --- x/rewards/keeper/iprpc_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index 1150b29581..f41c26bcb0 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -344,7 +344,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { require.NoError(ts.T, err) // check there are 2 iprpc reward object, and the first one is with id=1 - currentIprpcRewardId := ts.Keepers.Rewards.GetIprpcRewardsCurrent(ts.Ctx) + currentIprpcRewardId := ts.Keepers.Rewards.GetIprpcRewardsCurrentId(ts.Ctx) require.Equal(t, uint64(0), currentIprpcRewardId) res, err := ts.QueryRewardsIprpcSpecReward(mockSpec2) require.NoError(t, err) @@ -359,7 +359,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { // there should still be the exact two objects as before ts.AdvanceMonths(1) ts.AdvanceEpoch() - currentIprpcRewardId = ts.Keepers.Rewards.GetIprpcRewardsCurrent(ts.Ctx) + currentIprpcRewardId = ts.Keepers.Rewards.GetIprpcRewardsCurrentId(ts.Ctx) require.Equal(t, uint64(1), currentIprpcRewardId) res, err = ts.QueryRewardsIprpcSpecReward(mockSpec2) require.NoError(t, err) @@ -373,7 +373,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { // advance month without any provider service, there should be one IPRPC object with combined reward ts.AdvanceMonths(1) ts.AdvanceEpoch() - currentIprpcRewardId = ts.Keepers.Rewards.GetIprpcRewardsCurrent(ts.Ctx) + currentIprpcRewardId = ts.Keepers.Rewards.GetIprpcRewardsCurrentId(ts.Ctx) require.Equal(t, uint64(2), currentIprpcRewardId) res, err = ts.QueryRewardsIprpcSpecReward(mockSpec2) require.NoError(t, err) From 7f71d5db718bbd3f1e2fd8d662737223f3734ea0 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 12:24:11 +0200 Subject: [PATCH 56/64] CNS-872: unit test fix --- x/rewards/keeper/iprpc.go | 14 ++++++++++---- x/rewards/keeper/iprpc_test.go | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index 12006885a9..35c2a2fcb5 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -53,7 +53,7 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund } // add spec funds to next month IPRPC reward object - k.addSpecFunds(ctx, spec, fund, duration) + k.addSpecFunds(ctx, spec, fund, duration, true) return nil } @@ -62,7 +62,7 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund // so the IPRPC rewards transfer to the next month func (k Keeper) handleNoIprpcRewardToProviders(ctx sdk.Context, iprpcFunds []types.Specfund) { for _, fund := range iprpcFunds { - k.addSpecFunds(ctx, fund.Spec, fund.Fund, 1) + k.addSpecFunds(ctx, fund.Spec, fund.Fund, 1, false) } details := map[string]string{ @@ -91,8 +91,14 @@ func (k Keeper) countIprpcCu(specCuMap map[string]types.SpecCuType, iprpcCu uint // AddSpecFunds adds funds for a specific spec for of months. // This function is used by the fund-iprpc TX. -func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64) { - startID := k.GetIprpcRewardsCurrentId(ctx) + 1 // fund IPRPC only from the next month for months +// use fromNextMonth=true for normal IPRPC fund (should always start from next month) +// use fromNextMonth=false for IPRPC reward transfer for next month (when no providers are eligible for IPRPC rewards) +func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64, fromNextMonth bool) { + startID := k.GetIprpcRewardsCurrentId(ctx) + if fromNextMonth { + startID = startID + 1 // fund IPRPC only from the next month for months + } + for i := startID; i < startID+duration; i++ { iprpcReward, found := k.GetIprpcReward(ctx, i) if found { diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index f41c26bcb0..510d88d7fa 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -312,6 +312,9 @@ func TestIprpcSpecRewardQuery(t *testing.T) { relay := ts.SendRelay(p1, c1Acc, []string{ts.specs[1].Index}, 100) _, err = ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &relay) require.NoError(t, err) + relay = ts.SendRelay(p1, c1Acc, []string{ts.specs[0].Index}, 100) + _, err = ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &relay) + require.NoError(t, err) // advance month to distribute monthly rewards ts.AdvanceMonths(1) From 63298c12ad3dd0405fecba6b9b339c6ff9b7a735 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 12:29:18 +0200 Subject: [PATCH 57/64] CNS-872L lint fix --- x/rewards/keeper/iprpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index 35c2a2fcb5..812b00da10 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -96,7 +96,7 @@ func (k Keeper) countIprpcCu(specCuMap map[string]types.SpecCuType, iprpcCu uint func (k Keeper) addSpecFunds(ctx sdk.Context, spec string, fund sdk.Coins, duration uint64, fromNextMonth bool) { startID := k.GetIprpcRewardsCurrentId(ctx) if fromNextMonth { - startID = startID + 1 // fund IPRPC only from the next month for months + startID++ // fund IPRPC only from the next month for months } for i := startID; i < startID+duration; i++ { From ef79aefe46c794cc8635ee6e26cb68e7724cbdbd Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 12:33:43 +0200 Subject: [PATCH 58/64] CNS-869: fix min iprpc cost charge bug --- x/rewards/keeper/iprpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index 12006885a9..00c790d2b7 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -41,7 +41,7 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund utils.LogAttr("min_iprpc_fund_cost", minIprpcFundCost.String()), ) } - fund = fund.Sub(minIprpcFundCostCoins...) + fund = fund.Sub(minIprpcFundCost) // send the funds to the iprpc pool err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, addr, string(types.IprpcPoolName), fund) From 31124f597c84dd30ad7dd741dc939b332ea02370 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 12:47:01 +0200 Subject: [PATCH 59/64] CNS-872: fix unit tests --- x/rewards/keeper/iprpc_test.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index 510d88d7fa..044249f0b2 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "fmt" "testing" "cosmossdk.io/math" @@ -45,15 +46,15 @@ func TestFundIprpcTX(t *testing.T) { sdk.NewCoin(ibcDenom, math.NewInt(50)), )}, {spec: ts.specs[1].Index, duration: 3, fund: sdk.NewCoins( - sdk.NewCoin(ts.BondDenom(), math.NewInt(90+minIprpcCost.Amount.Int64()*3)), + sdk.NewCoin(ts.BondDenom(), math.NewInt(90+minIprpcCost.Amount.Int64())), sdk.NewCoin(ibcDenom, math.NewInt(30)), )}, {spec: ts.specs[0].Index, duration: 3, fund: sdk.NewCoins( - sdk.NewCoin(ts.BondDenom(), math.NewInt(minIprpcCost.Amount.Int64()*3)), + sdk.NewCoin(ts.BondDenom(), math.NewInt(minIprpcCost.Amount.Int64())), sdk.NewCoin(ibcDenom, math.NewInt(130)), )}, {spec: ts.specs[1].Index, duration: 12, fund: sdk.NewCoins( - sdk.NewCoin(ts.BondDenom(), math.NewInt(10+minIprpcCost.Amount.Int64()*12)), + sdk.NewCoin(ts.BondDenom(), math.NewInt(10+minIprpcCost.Amount.Int64())), sdk.NewCoin(ibcDenom, math.NewInt(120)), )}, } @@ -222,13 +223,12 @@ func TestIprpcSpecRewardQuery(t *testing.T) { // first month: mock2 - 500uibc + 3000ulava, mockspec - 100000ulava // second + third month: mock2 - 2000ulava, mockspec - 100000ulava duration := int64(3) - minIprpcCostForFund := minIprpcCost.Amount.MulRaw(duration) _, err := ts.TxRewardsFundIprpc(consumer, ts.specs[0].Index, uint64(duration), - sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000).Add(minIprpcCostForFund)))) + sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(100000).Add(minIprpcCost.Amount)))) require.NoError(ts.T, err) _, err = ts.TxRewardsFundIprpc(consumer, ts.specs[1].Index, uint64(duration), - sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(2000).Add(minIprpcCostForFund)))) + sdk.NewCoins(sdk.NewCoin(ts.BondDenom(), sdk.NewInt(2000).Add(minIprpcCost.Amount)))) require.NoError(ts.T, err) expectedResults := []rewardstypes.IprpcReward{ @@ -261,6 +261,8 @@ func TestIprpcSpecRewardQuery(t *testing.T) { // query with no args res, err := ts.QueryRewardsIprpcSpecReward("") require.NoError(t, err) + fmt.Printf("expectedResults: %v\n", expectedResults) + fmt.Printf("res.IprpcRewards: %v\n", res.IprpcRewards) require.ElementsMatch(t, expectedResults, res.IprpcRewards) // query with arg = mockspec @@ -339,9 +341,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { // fund iprpc pool duration := uint64(2) - iprpcCost := sdk.NewCoin(ts.BondDenom(), minIprpcCost.Amount.MulRaw(int64(duration))) - fundForIprpc := iprpcFunds - err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, fundForIprpc) + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds) require.NoError(ts.T, err) _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, duration, iprpcFunds) require.NoError(ts.T, err) @@ -355,7 +355,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { require.Equal(t, uint64(0), res.CurrentMonthId) for i := range res.IprpcRewards { require.Equal(t, uint64(i+1), res.IprpcRewards[i].Id) - require.True(t, fundForIprpc.Sub(iprpcCost).IsEqual(res.IprpcRewards[i].SpecFunds[0].Fund)) + require.True(t, iprpcFunds.Sub(minIprpcCost).IsEqual(res.IprpcRewards[i].SpecFunds[0].Fund)) } // advance month to reach the first iprpc reward (first object is with id=1) @@ -370,7 +370,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { require.Equal(t, uint64(1), res.CurrentMonthId) for i := range res.IprpcRewards { require.Equal(t, uint64(i+1), res.IprpcRewards[i].Id) - require.True(t, fundForIprpc.Sub(iprpcCost).IsEqual(res.IprpcRewards[i].SpecFunds[0].Fund)) + require.True(t, iprpcFunds.Sub(minIprpcCost).IsEqual(res.IprpcRewards[i].SpecFunds[0].Fund)) } // advance month without any provider service, there should be one IPRPC object with combined reward @@ -382,7 +382,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { require.NoError(t, err) require.Len(t, res.IprpcRewards, 1) require.Equal(t, uint64(2), res.CurrentMonthId) - require.True(t, fundForIprpc.Sub(iprpcCost).MulInt(sdk.NewInt(2)).IsEqual(res.IprpcRewards[0].SpecFunds[0].Fund)) + require.True(t, iprpcFunds.Sub(minIprpcCost).MulInt(sdk.NewInt(2)).IsEqual(res.IprpcRewards[0].SpecFunds[0].Fund)) // make a provider service an IPRPC eligible consumer and advance a month // there should be no iprpc rewards objects @@ -540,16 +540,14 @@ func TestMultipleIprpcSpec(t *testing.T) { // fund iprpc pool for mock2 spec for 1 months duration := uint64(1) - iprpcCost := sdk.NewCoin(ts.BondDenom(), minIprpcCost.Amount.MulRaw(int64(duration))) mock2Fund := sdk.NewCoin(ts.BondDenom(), sdk.NewInt(1700)) - _, err = ts.TxRewardsFundIprpc(c1, mockSpec2, duration, sdk.NewCoins(mock2Fund.Add(iprpcCost))) + _, err = ts.TxRewardsFundIprpc(c1, mockSpec2, duration, sdk.NewCoins(mock2Fund.Add(minIprpcCost))) require.NoError(t, err) // fund iprpc pool for mock3 spec for 3 months duration = uint64(3) - iprpcCost = sdk.NewCoin(ts.BondDenom(), minIprpcCost.Amount.MulRaw(int64(duration))) mock3Fund := sdk.NewCoin(ts.BondDenom(), sdk.NewInt(400)) - _, err = ts.TxRewardsFundIprpc(c1, mockSpec3, duration, sdk.NewCoins(mock3Fund.Add(iprpcCost))) + _, err = ts.TxRewardsFundIprpc(c1, mockSpec3, duration, sdk.NewCoins(mock3Fund.Add(minIprpcCost))) require.NoError(t, err) // advance month and epoch to apply pairing and iprpc fund From b246353ec1cfede2baf29fb3d348c469e56ee936 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 13:42:57 +0200 Subject: [PATCH 60/64] CNS-869: iprpc pool fund fix --- x/rewards/keeper/iprpc.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x/rewards/keeper/iprpc.go b/x/rewards/keeper/iprpc.go index 00c790d2b7..5a25ce96ad 100644 --- a/x/rewards/keeper/iprpc.go +++ b/x/rewards/keeper/iprpc.go @@ -4,6 +4,7 @@ import ( "fmt" "strconv" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/lavanet/lava/utils" "github.com/lavanet/lava/x/rewards/types" @@ -42,9 +43,10 @@ func (k Keeper) FundIprpc(ctx sdk.Context, creator string, duration uint64, fund ) } fund = fund.Sub(minIprpcFundCost) + allFunds := fund.MulInt(math.NewIntFromUint64(duration)) // send the funds to the iprpc pool - err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, addr, string(types.IprpcPoolName), fund) + err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, addr, string(types.IprpcPoolName), allFunds) if err != nil { return utils.LavaFormatError(types.ErrFundIprpc.Error()+"for funding iprpc pool", err, utils.LogAttr("creator", creator), From 38f4d486fe4d93846a44c5b356fa6345c0734a7c Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 13:43:48 +0200 Subject: [PATCH 61/64] CNS-872: iprpc unit tests fix --- x/rewards/keeper/iprpc_test.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index 044249f0b2..4a357954b2 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -22,7 +22,7 @@ func TestFundIprpcTX(t *testing.T) { ts.setupForIprpcTests(false) consumerAcc, consumer := ts.GetAccount(common.CONSUMER, 0) - err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds) + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(math.NewInt(12))) require.NoError(ts.T, err) type fundIprpcData struct { @@ -64,11 +64,17 @@ func TestFundIprpcTX(t *testing.T) { require.NoError(t, err) } - // Expected total IPRPC pool balance: 110ulava (=10+90+10) and 330uibc + // Expected total IPRPC pool balance (by TXs): + // 1. 10ulava + // 2. 50uibc + // 3. (90ulava + 30uibc) * 3 = 270ulava + 90uibc + // 4. 130uibc * 3 = 390uibc + // 5. (10ulava + 120uibc) * 12 = 120ulava + 1440uibc + // Total: 400ulava + 1970uibc iprpcTotalBalance := ts.Keepers.Rewards.TotalPoolTokens(ts.Ctx, rewardstypes.IprpcPoolName) expectedIprpcTotalBalance := sdk.NewCoins( - sdk.NewCoin(ts.BondDenom(), math.NewInt(110)), - sdk.NewCoin(ibcDenom, math.NewInt(330)), + sdk.NewCoin(ts.BondDenom(), math.NewInt(400)), + sdk.NewCoin(ibcDenom, math.NewInt(1970)), ) require.True(t, expectedIprpcTotalBalance.IsEqual(iprpcTotalBalance)) @@ -341,7 +347,7 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { // fund iprpc pool duration := uint64(2) - err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds) + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(math.NewInt(2))) require.NoError(ts.T, err) _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, duration, iprpcFunds) require.NoError(ts.T, err) From 85ba6891d7cb69e895c6500e8115b27858e3a3cb Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 14:51:44 +0200 Subject: [PATCH 62/64] CNS-872: PR fix --- testutil/common/tester.go | 4 ++++ x/rewards/keeper/helpers_test.go | 3 +++ x/rewards/keeper/iprpc_test.go | 9 +++++++++ 3 files changed, 16 insertions(+) diff --git a/testutil/common/tester.go b/testutil/common/tester.go index 02fea69170..d3e775421e 100644 --- a/testutil/common/tester.go +++ b/testutil/common/tester.go @@ -307,6 +307,10 @@ func (ts *Tester) GetBalance(accAddr sdk.AccAddress) int64 { return ts.Keepers.BankKeeper.GetBalance(ts.Ctx, accAddr, denom).Amount.Int64() } +func (ts *Tester) GetBalances(accAddr sdk.AccAddress) sdk.Coins { + return ts.Keepers.BankKeeper.GetAllBalances(ts.Ctx, accAddr) +} + func (ts *Tester) FindPlan(index string, block uint64) (planstypes.Plan, bool) { return ts.Keepers.Plans.FindPlan(ts.Ctx, index, block) } diff --git a/x/rewards/keeper/helpers_test.go b/x/rewards/keeper/helpers_test.go index 05aaea3234..6c9be49dfb 100644 --- a/x/rewards/keeper/helpers_test.go +++ b/x/rewards/keeper/helpers_test.go @@ -129,8 +129,11 @@ func (ts *tester) setupForIprpcTests(fundIprpcPool bool) { duration := uint64(1) err = ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(sdk.NewIntFromUint64(duration))) require.NoError(ts.T, err) + balanceBeforeFund := ts.GetBalances(consumerAcc.Addr) _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, duration, iprpcFunds) require.NoError(ts.T, err) + expectedBalanceAfterFund := balanceBeforeFund.Sub(iprpcFunds.MulInt(math.NewIntFromUint64(duration))...) + require.True(ts.T, ts.GetBalances(consumerAcc.Addr).IsEqual(expectedBalanceAfterFund)) ts.AdvanceMonths(1).AdvanceEpoch() // fund only fund for next month, so advance a month } } diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index 4a357954b2..0d7c9e78b8 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -519,6 +519,15 @@ func TestIprpcEligibleSubscriptions(t *testing.T) { require.NoError(t, err) require.Len(t, res1.SpecFunds, 0) require.Len(t, res2.SpecFunds, 0) + + // advance another month and see there are still no rewards + ts.AdvanceMonths(1).AdvanceEpoch() + res1, err = ts.QueryRewardsIprpcProviderRewardEstimation(p1) + require.NoError(t, err) + res2, err = ts.QueryRewardsIprpcProviderRewardEstimation(p2) + require.NoError(t, err) + require.Len(t, res1.SpecFunds, 0) + require.Len(t, res2.SpecFunds, 0) } // TestMultipleIprpcSpec checks that rewards are distributed correctly when multiple specs are configured in the IPRPC pool From d24e2b9b06ce7e85d048887903e734174a6a55b2 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 16:58:46 +0200 Subject: [PATCH 63/64] CNS-872: added unit test --- x/rewards/keeper/iprpc_test.go | 51 ++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index 0d7c9e78b8..c4b2f7b3bd 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "fmt" "testing" "cosmossdk.io/math" @@ -267,8 +266,6 @@ func TestIprpcSpecRewardQuery(t *testing.T) { // query with no args res, err := ts.QueryRewardsIprpcSpecReward("") require.NoError(t, err) - fmt.Printf("expectedResults: %v\n", expectedResults) - fmt.Printf("res.IprpcRewards: %v\n", res.IprpcRewards) require.ElementsMatch(t, expectedResults, res.IprpcRewards) // query with arg = mockspec @@ -405,6 +402,54 @@ func TestIprpcRewardObjectsUpdate(t *testing.T) { require.Equal(t, uint64(3), res.CurrentMonthId) } +// TestFundIprpcTwice tests the following scenario: +// IPRPC is funded for two months, advance month and fund again +// during this month, let provider serve and advance month again -> reward should be as the original funding +// advance again and serve -> reward should be from both funds (funding only starts from the next month) +func TestFundIprpcTwice(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(false) + consumerAcc, consumer := ts.GetAccount(common.CONSUMER, 0) + _, p1 := ts.GetAccount(common.PROVIDER, 0) + + // fund iprpc pool + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(math.NewInt(2))) + require.NoError(ts.T, err) + _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, 2, iprpcFunds) + require.NoError(ts.T, err) + + // advance month and fund again + ts.AdvanceMonths(1).AdvanceEpoch() + err = ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(math.NewInt(2))) + require.NoError(ts.T, err) + _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, 2, iprpcFunds) + require.NoError(ts.T, err) + + // make a provider service an IPRPC eligible consumer and advance month + relay := ts.SendRelay(p1, consumerAcc, []string{ts.specs[1].Index}, 100) + _, err = ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &relay) + ts.AdvanceEpoch() + require.NoError(t, err) + ts.AdvanceMonths(1).AdvanceEpoch() + + // check rewards - should be only from first funding (=iprpcFunds) + res, err := ts.QueryDualstakingDelegatorRewards(p1, p1, mockSpec2) + require.NoError(t, err) + require.True(t, iprpcFunds.Sub(minIprpcCost).IsEqual(res.Rewards[0].Amount)) + + // make a provider service an IPRPC eligible consumer and advance month again + relay = ts.SendRelay(p1, consumerAcc, []string{ts.specs[1].Index}, 100) + _, err = ts.Servers.PairingServer.RelayPayment(ts.GoCtx, &relay) + ts.AdvanceEpoch() + require.NoError(t, err) + ts.AdvanceMonths(1).AdvanceEpoch() + + // check rewards - should be only from first + second funding (=iprpcFunds*3) + res, err = ts.QueryDualstakingDelegatorRewards(p1, p1, mockSpec2) + require.NoError(t, err) + require.True(t, iprpcFunds.Sub(minIprpcCost).MulInt(math.NewInt(3)).IsEqual(res.Rewards[0].Amount)) +} + // TestIprpcMinCost tests that a fund TX fails if it doesn't have enough tokens to cover for the minimum IPRPC costs // Scenarios: // 1. fund TX with the minimum cost available -> TX success From 1a0e230004c9aa514fa8de5ebdd7b2bf5399c5d2 Mon Sep 17 00:00:00 2001 From: oren-lava Date: Wed, 6 Mar 2024 17:06:28 +0200 Subject: [PATCH 64/64] CNS-872: added min cost unit test --- x/rewards/keeper/iprpc_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/x/rewards/keeper/iprpc_test.go b/x/rewards/keeper/iprpc_test.go index c4b2f7b3bd..07486ddaf6 100644 --- a/x/rewards/keeper/iprpc_test.go +++ b/x/rewards/keeper/iprpc_test.go @@ -701,3 +701,17 @@ func TestIprpcRewardWithZeroSubRewards(t *testing.T) { require.NoError(t, err) require.True(t, p2ExpectedReward.IsEqual(res2.Rewards[0].Amount)) } + +// TestMinIprpcCostForSeveralMonths checks that if a user sends fund=1.1*minIprpcCost with duration=2 +// the TX succeeds (checks that the min iprpc cost check that per month there is enough funds) +func TestMinIprpcCostForSeveralMonths(t *testing.T) { + ts := newTester(t, true) + ts.setupForIprpcTests(false) + consumerAcc, consumer := ts.GetAccount(common.CONSUMER, 0) + + // fund iprpc pool + err := ts.Keepers.BankKeeper.AddToBalance(consumerAcc.Addr, iprpcFunds.MulInt(math.NewInt(3))) + require.NoError(ts.T, err) + _, err = ts.TxRewardsFundIprpc(consumer, mockSpec2, 2, iprpcFunds.MulInt(math.NewInt(110)).QuoInt(math.NewInt(100))) + require.NoError(ts.T, err) +}