Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PSS - Add minimum power in top N & power shaping params to consumer chain list #1863

Merged
merged 8 commits into from
May 13, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field.
([\#1863](https://github.com/cosmos/interchain-security/pull/1863))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a newline at the end of the file to conform to Unix text file standards.

+ 

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
([\#1863](https://github.com/cosmos/interchain-security/pull/1863))
([\#1863](https://github.com/cosmos/interchain-security/pull/1863))

3 changes: 3 additions & 0 deletions proto/interchain_security/ccv/provider/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ message Chain {
string client_id = 2;
// If chain with `chainID` is a Top-N chain, i.e., enforces at least one validator to validate chain `chainID`
uint32 top_N = 3;
// If the chain is a Top-N chain, this is the minimum power required to be in the top N.
// Otherwise, this is -1.
int64 min_power_in_top_N = 4;
}

message QueryValidatorConsumerAddrRequest {
Expand Down
22 changes: 18 additions & 4 deletions x/ccv/provider/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,26 @@ func (k Keeper) GetAllConsumerChains(ctx sdk.Context) (chains []types.Chain) {
chainID := string(iterator.Key()[1:])
clientID := string(iterator.Value())

topN, _ := k.GetTopN(ctx, chainID)
topN, found := k.GetTopN(ctx, chainID)

var minPowerInTopN int64
if found && topN > 0 {
res, err := k.ComputeMinPowerToOptIn(ctx, chainID, k.stakingKeeper.GetLastValidators(ctx), topN)
if err != nil {
k.Logger(ctx).Error("failed to compute min power to opt in for chain", "chain", chainID, "error", err)
p-offtermatt marked this conversation as resolved.
Show resolved Hide resolved
minPowerInTopN = -1
} else {
minPowerInTopN = res
}
} else {
minPowerInTopN = -1
}
p-offtermatt marked this conversation as resolved.
Show resolved Hide resolved

chains = append(chains, types.Chain{
ChainId: chainID,
ClientId: clientID,
Top_N: topN,
ChainId: chainID,
ClientId: clientID,
Top_N: topN,
MinPowerInTop_N: minPowerInTopN,
})
}

Expand Down
33 changes: 30 additions & 3 deletions x/ccv/provider/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

ibctesting "github.com/cosmos/ibc-go/v7/testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"

cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
Expand All @@ -20,6 +21,8 @@ import (
testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper"
"github.com/cosmos/interchain-security/v4/x/ccv/provider/types"
ccv "github.com/cosmos/interchain-security/v4/x/ccv/types"

stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

const consumer = "consumer"
Expand Down Expand Up @@ -395,17 +398,41 @@ func TestVscSendTimestamp(t *testing.T) {

// TestGetAllConsumerChains tests GetAllConsumerChains behaviour correctness
func TestGetAllConsumerChains(t *testing.T) {
pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

chainIDs := []string{"chain-2", "chain-1", "chain-4", "chain-3"}

// mock the validator set
vals := []stakingtypes.Validator{
{OperatorAddress: "cosmosvaloper1c4k24jzduc365kywrsvf5ujz4ya6mwympnc4en"}, // 50 power
{OperatorAddress: "cosmosvaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcvrj90c"}, // 150 power
{OperatorAddress: "cosmosvaloper1clpqr4nrk4khgkxj78fcwwh6dl3uw4epsluffn"}, // 300 power
{OperatorAddress: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3"}, // 500 power
}
powers := []int64{50, 150, 300, 500} // sum = 1000
mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Return(vals).AnyTimes()

for i, val := range vals {
mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), val.GetOperator()).Return(powers[i]).AnyTimes()
}

// set Top N parameters, client ids and expected result
topNs := []uint32{0, 70, 90, 100}
expectedMinPowerInTopNs := []int64{
-1, // Top N is 0, so not a Top N chain
300, // 500 and 300 are in Top 70%
150, // 150 is also in the top 90%,
50, // everyone is in the top 50
p-offtermatt marked this conversation as resolved.
Show resolved Hide resolved
}

expectedGetAllOrder := []types.Chain{}
for i, chainID := range chainIDs {
clientID := fmt.Sprintf("client-%d", len(chainIDs)-i)
topN := uint32(i)
topN := topNs[i]
pk.SetConsumerClientId(ctx, chainID, clientID)
pk.SetTopN(ctx, chainID, topN)
expectedGetAllOrder = append(expectedGetAllOrder, types.Chain{ChainId: chainID, ClientId: clientID, Top_N: topN})
expectedGetAllOrder = append(expectedGetAllOrder, types.Chain{ChainId: chainID, ClientId: clientID, Top_N: topN, MinPowerInTop_N: expectedMinPowerInTopNs[i]})
}
// sorting by chainID
sort.Slice(expectedGetAllOrder, func(i, j int) bool {
Expand Down
Loading
Loading