From 8c09d6d8fc8047de1a7513d4a22d512806552c34 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Wed, 25 Oct 2023 16:51:53 -0700 Subject: [PATCH 1/8] Update validator min commission in upgrade --- app/upgrades.go | 64 ++++++++++++++++++++++++++ app/upgrades_test.go | 104 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) diff --git a/app/upgrades.go b/app/upgrades.go index bd2f6cc142..56c046f8f5 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -8,6 +8,7 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" communitytypes "github.com/kava-labs/kava/x/community/types" @@ -52,6 +53,9 @@ var ( sdkmath.LegacyNewDec(0), // stakingRewardsPerSecond sdkmath.LegacyNewDec(1000), // upgradeTimeSetstakingRewardsPerSecond ) + + // ValidatorMinimumCommission is the new 5% minimum commission rate for validators + ValidatorMinimumCommission = sdk.NewDecWithPrec(5, 2) ) // RegisterUpgradeHandlers registers the upgrade handlers for the app. @@ -109,6 +113,8 @@ func upgradeHandler( return toVM, err } + UpdateValidatorMinimumCommission(ctx, app) + app.communityKeeper.SetParams(ctx, communityParams) app.Logger().Info( "initialized x/community params", @@ -120,3 +126,61 @@ func upgradeHandler( return toVM, nil } } + +// UpdateValidatorMinimumCommission updates the commission rate for all +// validators to be at least the new min commission rate, and sets the minimum +// commission rate in the staking params. +func UpdateValidatorMinimumCommission( + ctx sdk.Context, + app App, +) { + resultCount := make(map[stakingtypes.BondStatus]int) + + // Iterate over *all* validators including inactive + app.stakingKeeper.IterateValidators( + ctx, + func(index int64, validator stakingtypes.ValidatorI) (stop bool) { + // Skip if validator commission is already >= 5% + if validator.GetCommission().GTE(ValidatorMinimumCommission) { + return false + } + + val, ok := validator.(stakingtypes.Validator) + if !ok { + panic("expected stakingtypes.Validator") + } + + // Set minimum commission rate to 5%, when commission is < 5% + val.Commission.Rate = ValidatorMinimumCommission + app.stakingKeeper.SetValidator(ctx, val) + + // Keep track of counts just for logging purposes + switch val.GetStatus() { + case stakingtypes.Bonded: + resultCount[stakingtypes.Bonded]++ + case stakingtypes.Unbonded: + resultCount[stakingtypes.Unbonded]++ + case stakingtypes.Unbonding: + resultCount[stakingtypes.Unbonding]++ + } + + return false + }, + ) + + app.Logger().Info( + "updated validator minimum commission rate for all existing validators", + stakingtypes.BondStatusBonded, resultCount[stakingtypes.Bonded], + stakingtypes.BondStatusUnbonded, resultCount[stakingtypes.Unbonded], + stakingtypes.BondStatusUnbonding, resultCount[stakingtypes.Unbonding], + ) + + stakingParams := app.stakingKeeper.GetParams(ctx) + stakingParams.MinCommissionRate = ValidatorMinimumCommission + app.stakingKeeper.SetParams(ctx, stakingParams) + + app.Logger().Info( + "updated x/staking params minimum commission rate", + "MinCommissionRate", stakingParams.MinCommissionRate, + ) +} diff --git a/app/upgrades_test.go b/app/upgrades_test.go index 804fe6e47a..d8ba8de13f 100644 --- a/app/upgrades_test.go +++ b/app/upgrades_test.go @@ -4,8 +4,13 @@ import ( "testing" sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/evmos/ethermint/crypto/ethsecp256k1" "github.com/kava-labs/kava/app" "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtime "github.com/tendermint/tendermint/types/time" ) func TestUpgradeCommunityParams_Mainnet(t *testing.T) { @@ -39,3 +44,102 @@ func TestUpgradeCommunityParams_Testnet(t *testing.T) { "testnet kava per second should be correct", ) } + +func TestUpdateValidatorMinimumCommission(t *testing.T) { + tApp := app.NewTestApp() + tApp.InitializeFromGenesisStates() + ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()}) + + sk := tApp.GetStakingKeeper() + stakingParams := sk.GetParams(ctx) + stakingParams.MinCommissionRate = sdk.ZeroDec() + sk.SetParams(ctx, stakingParams) + + // Set some validators with varying commission rates + + vals := []struct { + operatorAddr sdk.ValAddress + consPriv *ethsecp256k1.PrivKey + commissionRate sdk.Dec + }{ + { + operatorAddr: sdk.ValAddress("val0"), + consPriv: generateConsKey(t), + commissionRate: sdk.ZeroDec(), + }, + { + operatorAddr: sdk.ValAddress("val1"), + consPriv: generateConsKey(t), + commissionRate: sdk.MustNewDecFromStr("0.01"), + }, + { + operatorAddr: sdk.ValAddress("val2"), + consPriv: generateConsKey(t), + commissionRate: sdk.MustNewDecFromStr("0.05"), + }, + { + operatorAddr: sdk.ValAddress("val3"), + consPriv: generateConsKey(t), + commissionRate: sdk.MustNewDecFromStr("0.06"), + }, + { + operatorAddr: sdk.ValAddress("val4"), + consPriv: generateConsKey(t), + commissionRate: sdk.MustNewDecFromStr("0.5"), + }, + } + + for _, v := range vals { + val, err := stakingtypes.NewValidator( + v.operatorAddr, + v.consPriv.PubKey(), + stakingtypes.Description{}, + ) + require.NoError(t, err) + val.Commission.Rate = v.commissionRate + + err = sk.SetValidatorByConsAddr(ctx, val) + require.NoError(t, err) + sk.SetValidator(ctx, val) + } + + require.NotPanics( + t, func() { + app.UpdateValidatorMinimumCommission(ctx, tApp.App) + }, + ) + + stakingParamsAfter := sk.GetParams(ctx) + require.Equal(t, stakingParamsAfter.MinCommissionRate, app.ValidatorMinimumCommission) + + // Check that all validators have a commission rate >= 5% + count := 0 + sk.IterateValidators(ctx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) { + require.True( + t, + validator.GetCommission().GTE(app.ValidatorMinimumCommission), + "commission rate should be >= 5%", + ) + + count++ + return false + }) + + require.Equal( + t, + len(vals)+1, // InitializeFromGenesisStates adds a validator + count, + "validator count should match test validators", + ) +} + +func generateConsKey( + t *testing.T, +) *ethsecp256k1.PrivKey { + t.Helper() + + key, err := ethsecp256k1.GenerateKey() + require.NoError(t, err) + + return key +} From 3c042933232de5fb52e17cee60fa0f39868cb9ae Mon Sep 17 00:00:00 2001 From: drklee3 Date: Wed, 25 Oct 2023 16:52:28 -0700 Subject: [PATCH 2/8] Add min commission upgrade test --- tests/e2e/e2e_upgrade_min_commission_test.go | 68 ++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/e2e/e2e_upgrade_min_commission_test.go diff --git a/tests/e2e/e2e_upgrade_min_commission_test.go b/tests/e2e/e2e_upgrade_min_commission_test.go new file mode 100644 index 0000000000..30653fbee6 --- /dev/null +++ b/tests/e2e/e2e_upgrade_min_commission_test.go @@ -0,0 +1,68 @@ +package e2e_test + +import ( + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/kava-labs/kava/tests/util" +) + +func (suite *IntegrationTestSuite) TestValMinCommission() { + suite.SkipIfUpgradeDisabled() + + beforeUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight - 1) + afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight) + + suite.Run("before upgrade", func() { + // Before params + beforeParams, err := suite.Kava.Staking.Params(beforeUpgradeCtx, &types.QueryParamsRequest{}) + suite.Require().NoError(err) + + suite.Require().Equal( + sdkmath.LegacyZeroDec().String(), + beforeParams.Params.MinCommissionRate.String(), + "min commission rate should be 0%% before upgrade", + ) + + // Before validators + beforeValidators, err := suite.Kava.Staking.Validators(beforeUpgradeCtx, &types.QueryValidatorsRequest{}) + suite.Require().NoError(err) + + for _, val := range beforeValidators.Validators { + expectedRate := sdkmath.LegacyMustNewDecFromStr("0.1") + + suite.Require().Equalf( + expectedRate.String(), + val.Commission.CommissionRates.Rate.String(), + "validator %s should have commission rate of %s before upgrade", + val.OperatorAddress, + expectedRate, + ) + } + }) + + suite.Run("after upgrade", func() { + // After params + afterParams, err := suite.Kava.Staking.Params(afterUpgradeCtx, &types.QueryParamsRequest{}) + suite.Require().NoError(err) + + suite.Require().Equal( + sdkmath.LegacyMustNewDecFromStr("0.05").String(), + afterParams.Params.MinCommissionRate.String(), + "min commission rate should be 5%% after upgrade", + ) + + // After validators + afterValidators, err := suite.Kava.Staking.Validators(afterUpgradeCtx, &types.QueryValidatorsRequest{}) + suite.Require().NoError(err) + + for _, val := range afterValidators.Validators { + suite.Require().Truef( + val.Commission.CommissionRates.Rate.GTE(sdk.MustNewDecFromStr("0.05")), + "validator %s should have commission rate of at least 5%%", + val.OperatorAddress, + ) + } + }) +} From 5d62dbc12debcb9d26af824ed448611724b511a1 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Wed, 25 Oct 2023 17:10:00 -0700 Subject: [PATCH 3/8] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8faef1437..f5574fd4d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ - (community) [#1706] Add disable inflation upgrade to begin blocker that updates x/mint and x/kavadist params - (community) [#1729] Consolidate community funds from `x/distribution` and `x/kavadist` to `x/community` - (community) [#1752] Set `x/distribution` CommunityTax to zero on inflation disable upgrade +- (staking) [#1761] Set validator minimum commission to 5% for all validators under 5% ## [v0.24.0] @@ -295,6 +296,7 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md). - [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run large-scale simulations remotely using aws-batch +[#1761]: https://github.com/Kava-Labs/kava/pull/1761 [#1752]: https://github.com/Kava-Labs/kava/pull/1752 [#1729]: https://github.com/Kava-Labs/kava/pull/1729 [#1745]: https://github.com/Kava-Labs/kava/pull/1745 From 4040fb0862239d3ac6d5c85d98e652e79a523f87 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Thu, 26 Oct 2023 12:28:01 -0700 Subject: [PATCH 4/8] Set validator MaxRate, call BeforeValidatorModified hook --- app/upgrades.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/upgrades.go b/app/upgrades.go index 56c046f8f5..3c5b4f5b45 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -152,6 +152,16 @@ func UpdateValidatorMinimumCommission( // Set minimum commission rate to 5%, when commission is < 5% val.Commission.Rate = ValidatorMinimumCommission + val.Commission.UpdateTime = ctx.BlockTime() + + // Update MaxRate if necessary + if val.Commission.MaxRate.LT(ValidatorMinimumCommission) { + val.Commission.MaxRate = ValidatorMinimumCommission + } + + if err := app.stakingKeeper.BeforeValidatorModified(ctx, val.GetOperator()); err != nil { + panic(fmt.Sprintf("failed to call BeforeValidatorModified: %s", err)) + } app.stakingKeeper.SetValidator(ctx, val) // Keep track of counts just for logging purposes From a60542de0c10b9267f83c1886830db2858f40791 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Thu, 26 Oct 2023 12:28:44 -0700 Subject: [PATCH 5/8] Check max commission and update time in tests --- app/upgrades_test.go | 111 ++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 37 deletions(-) diff --git a/app/upgrades_test.go b/app/upgrades_test.go index d8ba8de13f..e66b530d47 100644 --- a/app/upgrades_test.go +++ b/app/upgrades_test.go @@ -2,6 +2,7 @@ package app_test import ( "testing" + "time" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -58,34 +59,52 @@ func TestUpdateValidatorMinimumCommission(t *testing.T) { // Set some validators with varying commission rates vals := []struct { - operatorAddr sdk.ValAddress - consPriv *ethsecp256k1.PrivKey - commissionRate sdk.Dec + name string + operatorAddr sdk.ValAddress + consPriv *ethsecp256k1.PrivKey + commissionRateMin sdk.Dec + commissionRateMax sdk.Dec + shouldBeUpdated bool }{ { - operatorAddr: sdk.ValAddress("val0"), - consPriv: generateConsKey(t), - commissionRate: sdk.ZeroDec(), + name: "zero commission rate", + operatorAddr: sdk.ValAddress("val0"), + consPriv: generateConsKey(t), + commissionRateMin: sdk.ZeroDec(), + commissionRateMax: sdk.ZeroDec(), + shouldBeUpdated: true, }, { - operatorAddr: sdk.ValAddress("val1"), - consPriv: generateConsKey(t), - commissionRate: sdk.MustNewDecFromStr("0.01"), + name: "0.01 commission rate", + operatorAddr: sdk.ValAddress("val1"), + consPriv: generateConsKey(t), + commissionRateMin: sdk.MustNewDecFromStr("0.01"), + commissionRateMax: sdk.MustNewDecFromStr("0.01"), + shouldBeUpdated: true, }, { - operatorAddr: sdk.ValAddress("val2"), - consPriv: generateConsKey(t), - commissionRate: sdk.MustNewDecFromStr("0.05"), + name: "0.05 commission rate", + operatorAddr: sdk.ValAddress("val2"), + consPriv: generateConsKey(t), + commissionRateMin: sdk.MustNewDecFromStr("0.05"), + commissionRateMax: sdk.MustNewDecFromStr("0.05"), + shouldBeUpdated: false, }, { - operatorAddr: sdk.ValAddress("val3"), - consPriv: generateConsKey(t), - commissionRate: sdk.MustNewDecFromStr("0.06"), + name: "0.06 commission rate", + operatorAddr: sdk.ValAddress("val3"), + consPriv: generateConsKey(t), + commissionRateMin: sdk.MustNewDecFromStr("0.06"), + commissionRateMax: sdk.MustNewDecFromStr("0.06"), + shouldBeUpdated: false, }, { - operatorAddr: sdk.ValAddress("val4"), - consPriv: generateConsKey(t), - commissionRate: sdk.MustNewDecFromStr("0.5"), + name: "0.5 commission rate", + operatorAddr: sdk.ValAddress("val4"), + consPriv: generateConsKey(t), + commissionRateMin: sdk.MustNewDecFromStr("0.5"), + commissionRateMax: sdk.MustNewDecFromStr("0.5"), + shouldBeUpdated: false, }, } @@ -96,7 +115,8 @@ func TestUpdateValidatorMinimumCommission(t *testing.T) { stakingtypes.Description{}, ) require.NoError(t, err) - val.Commission.Rate = v.commissionRate + val.Commission.Rate = v.commissionRateMin + val.Commission.MaxRate = v.commissionRateMax err = sk.SetValidatorByConsAddr(ctx, val) require.NoError(t, err) @@ -113,24 +133,41 @@ func TestUpdateValidatorMinimumCommission(t *testing.T) { require.Equal(t, stakingParamsAfter.MinCommissionRate, app.ValidatorMinimumCommission) // Check that all validators have a commission rate >= 5% - count := 0 - sk.IterateValidators(ctx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) { - require.True( - t, - validator.GetCommission().GTE(app.ValidatorMinimumCommission), - "commission rate should be >= 5%", - ) - - count++ - return false - }) - - require.Equal( - t, - len(vals)+1, // InitializeFromGenesisStates adds a validator - count, - "validator count should match test validators", - ) + for _, val := range vals { + t.Run(val.name, func(t *testing.T) { + validator, found := sk.GetValidator(ctx, val.operatorAddr) + require.True(t, found, "validator should be found") + + require.True( + t, + validator.GetCommission().GTE(app.ValidatorMinimumCommission), + "commission rate should be >= 5%", + ) + + require.True( + t, + validator.Commission.MaxRate.GTE(app.ValidatorMinimumCommission), + "commission rate max should be >= 5%, got %s", + validator.Commission.MaxRate, + ) + + if val.shouldBeUpdated { + require.Equal( + t, + ctx.BlockTime(), + validator.Commission.UpdateTime, + "commission update time should be set to block time", + ) + } else { + require.Equal( + t, + time.Unix(0, 0).UTC(), + validator.Commission.UpdateTime, + "commission update time should not be changed -- default value is 0", + ) + } + }) + } } func generateConsKey( From 22ef53b50a44e55a73dd584d652b9a75bef3ac33 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Thu, 26 Oct 2023 13:03:20 -0700 Subject: [PATCH 6/8] Update e2e test for max rate --- tests/e2e/e2e_upgrade_min_commission_test.go | 25 +++++++++++++++++--- tests/e2e/kvtool | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/e2e/e2e_upgrade_min_commission_test.go b/tests/e2e/e2e_upgrade_min_commission_test.go index 30653fbee6..fa969d3c50 100644 --- a/tests/e2e/e2e_upgrade_min_commission_test.go +++ b/tests/e2e/e2e_upgrade_min_commission_test.go @@ -30,7 +30,9 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { suite.Require().NoError(err) for _, val := range beforeValidators.Validators { - expectedRate := sdkmath.LegacyMustNewDecFromStr("0.1") + // In kvtool gentx, the commission rate is set to 0, with max of 0.01 + expectedRate := sdkmath.LegacyZeroDec() + expectedRateMax := sdkmath.LegacyMustNewDecFromStr("0.01") suite.Require().Equalf( expectedRate.String(), @@ -39,6 +41,14 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { val.OperatorAddress, expectedRate, ) + + suite.Require().Equalf( + expectedRateMax.String(), + val.Commission.CommissionRates.MaxRate.String(), + "validator %s should have max commission rate of %s before upgrade", + val.OperatorAddress, + expectedRateMax, + ) } }) @@ -47,8 +57,10 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { afterParams, err := suite.Kava.Staking.Params(afterUpgradeCtx, &types.QueryParamsRequest{}) suite.Require().NoError(err) + expectedMinRate := sdk.MustNewDecFromStr("0.05") + suite.Require().Equal( - sdkmath.LegacyMustNewDecFromStr("0.05").String(), + expectedMinRate.String(), afterParams.Params.MinCommissionRate.String(), "min commission rate should be 5%% after upgrade", ) @@ -58,11 +70,18 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { suite.Require().NoError(err) for _, val := range afterValidators.Validators { + suite.Require().Truef( - val.Commission.CommissionRates.Rate.GTE(sdk.MustNewDecFromStr("0.05")), + val.Commission.CommissionRates.Rate.GTE(expectedMinRate), "validator %s should have commission rate of at least 5%%", val.OperatorAddress, ) + + suite.Require().Truef( + val.Commission.CommissionRates.MaxRate.GTE(expectedMinRate), + "validator %s should have max commission rate of at least 5%%", + val.OperatorAddress, + ) } }) } diff --git a/tests/e2e/kvtool b/tests/e2e/kvtool index bec8a8d82d..b7948a9acf 160000 --- a/tests/e2e/kvtool +++ b/tests/e2e/kvtool @@ -1 +1 @@ -Subproject commit bec8a8d82d1b0a2336724c428dbb472a6dd0411e +Subproject commit b7948a9acf002b41b9b730b23bd625f30a9a0902 From 18b4a5c26c906d5deb23c94c1a53a8e3423e7ea9 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Thu, 26 Oct 2023 13:06:22 -0700 Subject: [PATCH 7/8] Test val update time --- tests/e2e/e2e_upgrade_min_commission_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/e2e/e2e_upgrade_min_commission_test.go b/tests/e2e/e2e_upgrade_min_commission_test.go index fa969d3c50..e0e2407279 100644 --- a/tests/e2e/e2e_upgrade_min_commission_test.go +++ b/tests/e2e/e2e_upgrade_min_commission_test.go @@ -1,7 +1,10 @@ package e2e_test import ( + "context" + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -53,6 +56,11 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { }) suite.Run("after upgrade", func() { + block, err := suite.Kava.Tm.GetBlockByHeight(context.Background(), &tmservice.GetBlockByHeightRequest{ + Height: suite.UpgradeHeight, + }) + suite.Require().NoError(err) + // After params afterParams, err := suite.Kava.Staking.Params(afterUpgradeCtx, &types.QueryParamsRequest{}) suite.Require().NoError(err) @@ -82,6 +90,14 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { "validator %s should have max commission rate of at least 5%%", val.OperatorAddress, ) + + suite.Require().Truef( + val.Commission.UpdateTime.Equal(block.Block.Header.Time), + "validator %s should have commission update time set to block time, expected %s, got %s", + val.OperatorAddress, + block.Block.Header.Time, + val.Commission.UpdateTime, + ) } }) } From 798fb0a2b2f4ee541b81c71a8397652d8e7ca1c8 Mon Sep 17 00:00:00 2001 From: drklee3 Date: Thu, 26 Oct 2023 13:13:34 -0700 Subject: [PATCH 8/8] Use SdkBlock instead of Block --- tests/e2e/e2e_upgrade_min_commission_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/e2e_upgrade_min_commission_test.go b/tests/e2e/e2e_upgrade_min_commission_test.go index e0e2407279..38455a9518 100644 --- a/tests/e2e/e2e_upgrade_min_commission_test.go +++ b/tests/e2e/e2e_upgrade_min_commission_test.go @@ -92,10 +92,10 @@ func (suite *IntegrationTestSuite) TestValMinCommission() { ) suite.Require().Truef( - val.Commission.UpdateTime.Equal(block.Block.Header.Time), + val.Commission.UpdateTime.Equal(block.SdkBlock.Header.Time), "validator %s should have commission update time set to block time, expected %s, got %s", val.OperatorAddress, - block.Block.Header.Time, + block.SdkBlock.Header.Time, val.Commission.UpdateTime, ) }