diff --git a/app/ante/cosmos/min_price_test.go b/app/ante/cosmos/min_price_test.go index 500596d66..438861f96 100644 --- a/app/ante/cosmos/min_price_test.go +++ b/app/ante/cosmos/min_price_test.go @@ -51,7 +51,7 @@ func (suite *AnteTestSuite) TestMinGasPriceDecorator() { err := suite.app.FeeMarketKeeper.SetParams(suite.ctx, params) suite.Require().NoError(err) - txBuilder := suite.CreateTestCosmosTxBuilder(sdkmath.NewInt(0), denom, &testMsg) + txBuilder := suite.CreateTestCosmosTxBuilder(sdkmath.ZeroInt(), denom, &testMsg) return txBuilder.GetTx() }, true, @@ -96,7 +96,7 @@ func (suite *AnteTestSuite) TestMinGasPriceDecorator() { err := suite.app.FeeMarketKeeper.SetParams(suite.ctx, params) suite.Require().NoError(err) - txBuilder := suite.CreateTestCosmosTxBuilder(sdkmath.NewInt(0), denom, &testMsg) + txBuilder := suite.CreateTestCosmosTxBuilder(sdkmath.ZeroInt(), denom, &testMsg) return txBuilder.GetTx() }, false, diff --git a/app/ante/evm/fees_test.go b/app/ante/evm/fees_test.go index 540f9a13c..cf998e47f 100644 --- a/app/ante/evm/fees_test.go +++ b/app/ante/evm/fees_test.go @@ -60,7 +60,7 @@ func (suite *AnteTestSuite) TestEthMinGasPriceDecorator() { ToAddress: "evmos1dx67l23hz9l0k9hcher8xz04uj7wf3yu26l2yn", Amount: sdk.Coins{sdk.Coin{Amount: sdkmath.NewInt(10), Denom: denom}}, } - txBuilder := suite.CreateTestCosmosTxBuilder(sdkmath.NewInt(0), denom, &testMsg) + txBuilder := suite.CreateTestCosmosTxBuilder(sdkmath.ZeroInt(), denom, &testMsg) return txBuilder.GetTx() }, false, diff --git a/app/app.go b/app/app.go index f84763c36..ee395d6d8 100644 --- a/app/app.go +++ b/app/app.go @@ -1179,7 +1179,6 @@ func (app *ExocoreApp) InitChainer( if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) } - app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap()) return app.mm.InitGenesis(ctx, app.appCodec, genesisState) diff --git a/precompiles/assets/assets_test.go b/precompiles/assets/assets_test.go index e42083492..e40bc1332 100644 --- a/precompiles/assets/assets_test.go +++ b/precompiles/assets/assets_test.go @@ -376,7 +376,6 @@ func (s *AssetsPrecompileSuite) TestRunWithdrawPrincipal() { readOnly: false, expPass: true, extra: func() { - stakerID, assetID := assetstype.GetStakerIDAndAssetID(s.ClientChains[0].LayerZeroChainID, s.Address.Bytes(), NSTAddress) // check depositNST successfully updated stakerAssetInfo in assets_module stakerAssetInfo, _ := s.App.AssetsKeeper.GetStakerSpecifiedAssetInfo(s.Ctx, stakerID, assetID) diff --git a/precompiles/assets/tx.go b/precompiles/assets/tx.go index 622577837..d86075636 100644 --- a/precompiles/assets/tx.go +++ b/precompiles/assets/tx.go @@ -156,7 +156,7 @@ func (p Precompile) RegisterToken( stakingAsset := &assetstypes.StakingAssetInfo{ AssetBasicInfo: asset, - StakingTotalAmount: sdkmath.NewInt(0), + StakingTotalAmount: sdkmath.ZeroInt(), } if err := p.assetsKeeper.RegisterNewTokenAndSetTokenFeeder(ctx, &oInfo); err != nil { diff --git a/precompiles/avs/avs_test.go b/precompiles/avs/avs_test.go index e634f59c3..939315d19 100644 --- a/precompiles/avs/avs_test.go +++ b/precompiles/avs/avs_test.go @@ -1,13 +1,14 @@ package avs_test import ( - "cosmossdk.io/math" - assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" - "github.com/ExocoreNetwork/exocore/x/avs/types" "math/big" "strconv" "time" + "cosmossdk.io/math" + assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" + "github.com/ExocoreNetwork/exocore/x/avs/types" + sdkmath "cosmossdk.io/math" operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper" @@ -650,7 +651,6 @@ func (suite *AVSManagerPrecompileSuite) TestRegisterOperatorToAVS() { } func (suite *AVSManagerPrecompileSuite) TestDeregisterOperatorFromAVS() { - // from := s.Address operatorAddress := sdk.AccAddress(suite.Address.Bytes()) assetID := suite.AssetIDs @@ -835,7 +835,7 @@ func (suite *AVSManagerPrecompileSuite) TestRunRegTaskInfo() { suite.Ctx, &assetstypes.StakingAssetInfo{ AssetBasicInfo: usdcClientChainAsset, - StakingTotalAmount: sdkmath.NewInt(0), + StakingTotalAmount: sdkmath.ZeroInt(), }, ) suite.NoError(err) diff --git a/precompiles/avs/query_test.go b/precompiles/avs/query_test.go index 4cf9206db..b712b0831 100644 --- a/precompiles/avs/query_test.go +++ b/precompiles/avs/query_test.go @@ -2,11 +2,12 @@ package avs_test import ( "fmt" + "math/big" + "time" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/prysmaticlabs/prysm/v4/crypto/bls/blst" - "math/big" - "time" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" @@ -144,7 +145,7 @@ func (suite *AVSManagerPrecompileSuite) TestGetOptedInOperatorAccAddrs() { func (suite *AVSManagerPrecompileSuite) TestAVSUSDValue() { method := s.precompile.Methods[avsManagerPrecompile.MethodGetAVSUSDValue] - expectedUSDvalue := sdkmath.LegacyNewDec(0) + expectedUSDvalue := sdkmath.LegacyZeroDec() setUp := func() { suite.prepare() @@ -162,7 +163,7 @@ func (suite *AVSManagerPrecompileSuite) TestAVSUSDValue() { suite.Ctx, &assetstype.StakingAssetInfo{ AssetBasicInfo: usdcClientChainAsset, - StakingTotalAmount: sdkmath.NewInt(0), + StakingTotalAmount: sdkmath.ZeroInt(), }, ) suite.NoError(err) @@ -232,7 +233,7 @@ func (suite *AVSManagerPrecompileSuite) TestAVSUSDValue() { func (suite *AVSManagerPrecompileSuite) TestGetOperatorOptedUSDValue() { method := s.precompile.Methods[avsManagerPrecompile.MethodGetOperatorOptedUSDValue] - expectedUSDvalue := sdkmath.LegacyNewDec(0) + expectedUSDvalue := sdkmath.LegacyZeroDec() setUp := func() { suite.prepare() @@ -250,7 +251,7 @@ func (suite *AVSManagerPrecompileSuite) TestGetOperatorOptedUSDValue() { suite.Ctx, &assetstype.StakingAssetInfo{ AssetBasicInfo: usdcClientChainAsset, - StakingTotalAmount: sdkmath.NewInt(0), + StakingTotalAmount: sdkmath.ZeroInt(), }, ) suite.NoError(err) @@ -494,6 +495,7 @@ func (suite *AVSManagerPrecompileSuite) TestIsoperator() { }) } } + func (suite *AVSManagerPrecompileSuite) TestGetTaskInfo() { method := suite.precompile.Methods[avsManagerPrecompile.MethodGetTaskInfo] taskAddress := "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" @@ -507,7 +509,7 @@ func (suite *AVSManagerPrecompileSuite) TestGetTaskInfo() { TaskResponsePeriod: 10, StartingEpoch: 5, TaskStatisticalPeriod: 60, - TaskTotalPower: sdk.Dec(sdkmath.NewInt(0)), + TaskTotalPower: sdk.Dec(sdkmath.ZeroInt()), } err := suite.App.AVSManagerKeeper.SetTaskInfo(suite.Ctx, info) suite.NoError(err) @@ -553,6 +555,7 @@ func (suite *AVSManagerPrecompileSuite) TestGetTaskInfo() { }) } } + func (suite *AVSManagerPrecompileSuite) TestGetCurrentEpoch() { method := suite.precompile.Methods[avsManagerPrecompile.MethodGetCurrentEpoch] testCases := []avsTestCases{ diff --git a/precompiles/avs/utils_test.go b/precompiles/avs/utils_test.go index 5f52298d8..161316d81 100644 --- a/precompiles/avs/utils_test.go +++ b/precompiles/avs/utils_test.go @@ -202,8 +202,8 @@ func (suite *AVSManagerPrecompileSuite) TestOptOut() { OptedInHeight: uint64(optInHeight), OptedOutHeight: uint64(suite.Ctx.BlockHeight()), }, - AVSTotalShare: sdkmath.LegacyNewDec(0), - AVSOperatorShare: sdkmath.LegacyNewDec(0), + AVSTotalShare: sdkmath.LegacyZeroDec(), + AVSOperatorShare: sdkmath.LegacyZeroDec(), AssetState: nil, OperatorShare: sdkmath.LegacyDec{}, StakerShare: sdkmath.LegacyDec{}, diff --git a/proto/exocore/operator/v1/genesis.proto b/proto/exocore/operator/v1/genesis.proto index 92e61121d..fa8299d2b 100644 --- a/proto/exocore/operator/v1/genesis.proto +++ b/proto/exocore/operator/v1/genesis.proto @@ -70,7 +70,7 @@ message AVSUSDValue { // it's corresponding to the kvStore `KeyPrefixUSDValueForOperator` message OperatorUSDValue { // key is used for storing the voting power of specified operator and AVS, - // which is the combination of operator and AVS address. + // which is the combination of AVS and operator address. string key = 1; // value is the USD value states for the AVS address OperatorOptedUSDValue opted_usd_value = 2 [(gogoproto.nullable) = false, (gogoproto.customname) = "OptedUSDValue"]; diff --git a/proto/exocore/operator/v1/query.proto b/proto/exocore/operator/v1/query.proto index 09f5afa23..9a2064d85 100644 --- a/proto/exocore/operator/v1/query.proto +++ b/proto/exocore/operator/v1/query.proto @@ -19,7 +19,8 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/operator/types"; // QueryOperatorInfoReq is the request to obtain the operator information. message GetOperatorInfoReq { // operator_addr is the operator address,its type should be a sdk.AccAddress - string operator_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string operator_addr = 1 + [(cosmos_proto.scalar) = "cosmos.AddressString"]; } // QueryAllOperatorsRequest is the request to obtain all operators. @@ -53,13 +54,15 @@ message QueryOperatorUSDValueRequest { // QueryOperatorUSDValueResponse is the response to obtain the USD value for operator. message QueryOperatorUSDValueResponse { // usd_info includes the self and total staking for the operator and AVS - OperatorOptedUSDValue usd_values = 1 [(gogoproto.customname) = "USDValues"]; + OperatorOptedUSDValue usd_values = 1 + [(gogoproto.customname) = "USDValues"]; } // QueryAVSUSDValueRequest is the request to obtain the USD value for AVS. message QueryAVSUSDValueRequest { // avs_address is the AVS address opted-in by the operator - string avs_address = 1 [(gogoproto.customname) = "AVSAddress"]; + string avs_address = 1 + [(gogoproto.customname) = "AVSAddress"]; } // QueryOperatorSlashInfoRequest is the request to obtain the slash information for the specified @@ -223,6 +226,55 @@ message QueryOptInfoRequest { OperatorAVSAddress operator_and_avs = 1 [(gogoproto.embed) = true]; } +// QuerySnapshotHelperRequest is the request to obtain the voting power snapshot +// helper information. +message QuerySnapshotHelperRequest { + // avs address + string avs = 1; +} + +// QuerySpecifiedSnapshotRequest is the request to obtain the voting power snapshot +// at the specified height. +message QuerySpecifiedSnapshotRequest { + // avs address + string avs = 1; + // height is used to specify the snapshot height you want to query. + int64 height = 2; +} + +// VotingPowerSnapshotKeyHeight is used in the response of QuerySpecifiedSnapshot +// and QueryAllSnapshot +message VotingPowerSnapshotKeyHeight { + // snapshot_key_height when it is used in QuerySpecifiedSnapshot, it's the latest + // height with a snapshot key found based on the input height; this height is typically + // the start height of the epoch in which the input height is located. + // when it is used in QueryAllSnapshot, it's the height in the current snapshot key. + int64 snapshot_key_height =1; + // snapshot when it is used in QuerySpecifiedSnapshot, it is the final retrieved information + // containing the voting power set. + // when it is used in QueryAllSnapshot, It is the snapshot stored under `snapshot_key_height`, + // and its voting power set may be nil. + VotingPowerSnapshot snapshot = 2; +} + +// QueryAllSnapshotRequest is the request to obtain all voting power snapshot +// for the specified AVS +message QueryAllSnapshotRequest { + // avs address + string avs = 1; + // pagination related options. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllSnapshotResponse is the response to obtain all voting power snapshot +// for the specified AVS +message QueryAllSnapshotResponse { + // snapshots is a list of all snapshots for the specified AVS. + repeated VotingPowerSnapshotKeyHeight snapshots = 1; + // pagination related response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + // Query defines the gRPC querier service. service Query { // QueryOperatorInfo queries the operator information. @@ -261,20 +313,22 @@ service Query { } // QueryOperatorUSDValue queries the opted-in USD value for the operator - rpc QueryOperatorUSDValue(QueryOperatorUSDValueRequest) returns (QueryOperatorUSDValueResponse) { - option (google.api.http).get = "/exocore/operator/v1/query_operator_usd_value/{operator_and_avs.operator_addr}/" - "{operator_and_avs.avs_address}"; + rpc QueryOperatorUSDValue(QueryOperatorUSDValueRequest) returns(QueryOperatorUSDValueResponse){ + option (google.api.http).get = + "/exocore/operator/v1/operator_usd_value/{operator_and_avs.operator_addr}/" + "{operator_and_avs.avs_address}"; } // QueryAVSUSDValue queries the USD value for the AVS - rpc QueryAVSUSDValue(QueryAVSUSDValueRequest) returns (DecValueField) { - option (google.api.http).get = "/exocore/operator/v1/QueryAVSUSDValue"; + rpc QueryAVSUSDValue(QueryAVSUSDValueRequest) returns(DecValueField){ + option (google.api.http).get = "/exocore/operator/v1/avs_usd_value"; } // QueryOperatorSlashInfo queries the slash information for the specified operator and AVS - rpc QueryOperatorSlashInfo(QueryOperatorSlashInfoRequest) returns (QueryOperatorSlashInfoResponse) { - option (google.api.http).get = "/exocore/operator/v1/query_operator_slash_info/{operator_and_avs.operator_addr}/" - "{operator_and_avs.avs_address}"; + rpc QueryOperatorSlashInfo(QueryOperatorSlashInfoRequest) returns(QueryOperatorSlashInfoResponse){ + option (google.api.http).get = + "/exocore/operator/v1/operator_slash_info/{operator_and_avs.operator_addr}/" + "{operator_and_avs.avs_address}"; } // QueryAllOperatorConsAddrsByChainID queries all operators and their consensus addresses @@ -287,7 +341,8 @@ service Query { } // QueryAllOperatorsWithOptInAVS queries operator list by avs. - rpc QueryAllOperatorsWithOptInAVS(QueryAllOperatorsByOptInAVSRequest) returns (QueryAllOperatorsByOptInAVSResponse) { + rpc QueryAllOperatorsWithOptInAVS(QueryAllOperatorsByOptInAVSRequest) returns ( + QueryAllOperatorsByOptInAVSResponse) { option (google.api.http) = { get: "/exocore/operator/v1/opt/operator_list/{avs}" }; @@ -307,6 +362,21 @@ service Query { }; } + // QuerySnapshotHelper queries the snapshot helper of the AVS + rpc QuerySnapshotHelper(QuerySnapshotHelperRequest) returns (SnapshotHelper) { + option (google.api.http).get = "/exocore/operator/v1/snapshot_helper/{avs}"; + } + + // QuerySpecifiedSnapshot queries the voting power snapshot of specified AVS and height + rpc QuerySpecifiedSnapshot(QuerySpecifiedSnapshotRequest) returns (VotingPowerSnapshotKeyHeight) { + option (google.api.http).get = "/exocore/operator/v1/snapshot/{avs}/{height}"; + } + + // QueryAllSnapshot queries all voting power snapshot for the specified AVS + rpc QueryAllSnapshot(QueryAllSnapshotRequest) returns (QueryAllSnapshotResponse) { + option (google.api.http).get = "/exocore/operator/v1/all_snapshot/{avs}"; + } + // Validators queries all validators that match the given status. // When called from another module, this query might consume a high amount of // gas if the pagination field is incorrectly set. diff --git a/proto/exocore/operator/v1/tx.proto b/proto/exocore/operator/v1/tx.proto index 0be9ee8ce..2d1c7c26a 100644 --- a/proto/exocore/operator/v1/tx.proto +++ b/proto/exocore/operator/v1/tx.proto @@ -47,6 +47,63 @@ message OperatorOptedUSDValue { ]; } +// OperatorVotingPower represents the voting power for the specified operator address +message OperatorVotingPower { + // operator_addr is the operator address,its type should be a sdk.AccAddress + string operator_addr = 1 + [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // voting_power is the active voting power for the above operator address + string voting_power = 2 + [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// VotingPowerSnapshot records historical voting power for AVSs at specific epochs +// or after slashing events.These snapshots are created at the end of each epoch and +// when slashing occurs, enabling historical queries of operator voting power at +// specific points in time. +message VotingPowerSnapshot { + // total_voting_power is the total voting power of specified AVS + string total_voting_power = 1 + [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // operator_voting_powers records the active voting power of all operators + // for the specified AVS + repeated OperatorVotingPower operator_voting_powers = 2; + // last_changed_height is used to indicate the height of most recent change when + // the operator_voting_powers is nil, which can help to fall back to the correct epoch height. + int64 last_changed_height = 3; + // epoch_identifier record the epoch info + string epoch_identifier = 4; + // epoch_number indicates which epoch this snapshot serve for + int64 epoch_number = 5; +} + +// SnapshotHelper is used to record the helper information for voting power snapshot update +message SnapshotHelper { + // last_changed_height indicates the height of the most recent change. + // It is used to set the `last_changed_height` field in `VotingPowerSnapshot`. + int64 last_changed_height = 1; + + // has_opt_out is used to indicate whether there has been any opt-out operation from + // the most recently saved snapshot to the current height. This is because, + // when an opt-out operation occurs, the related AVS validator information changes, + // and the snapshot needs to be updated. + // Currently, a boolean variable is used instead of an operator list + // because the snapshot is set by default to store all operator information related to AVS. + // Therefore, as long as any operator has opted out, the snapshot needs to be updated. + // If we later introduce a limit on the maximum number of validators in AVS, + // similar to the MaxValidatorNumber in Dogfood, this may need to be changed to an operator list + // to track all operators that have opted out, thereby assisting with the correct snapshot update. + bool has_opt_out = 2; +} + // ClientChainEarningAddrList is the list of client chain earning addresses. // Because the reward token provide by the AVS might be located at different client chain, the operator need to // provide the different client chain address to receive the token rewards. @@ -161,6 +218,8 @@ message SlashExecutionInfo { repeated SlashFromUndelegation slash_undelegations = 3 [(gogoproto.nullable) = false]; // SlashFromAssetsPool records all slash info related to the assets pool repeated SlashFromAssetsPool slash_assets_pool = 4 [(gogoproto.nullable) = false]; + // undelegation_filter_height records the height before which undelegations are not slashed + int64 undelegation_filter_height = 5; } // OperatorSlashInfo is the slash info of operator diff --git a/testutil/utils.go b/testutil/utils.go index 52c189c7f..563eed3b9 100644 --- a/testutil/utils.go +++ b/testutil/utils.go @@ -395,15 +395,13 @@ func (suite *BaseTestSuite) SetupWithGenesisValSet(genAccs []authtypes.GenesisAc // init chain will set the validator set and initialize the genesis accounts suite.InitTime = time.Now().UTC() - app.InitChain( - abci.RequestInitChain{ - Time: suite.InitTime, - ChainId: utils.DefaultChainID, - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: exocoreapp.DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) + app.InitChain(abci.RequestInitChain{ + Time: suite.InitTime, + ChainId: utils.DefaultChainID, + Validators: []abci.ValidatorUpdate{}, + ConsensusParams: exocoreapp.DefaultConsensusParams, + AppStateBytes: stateBytes, + }) // committing the chain now is not required. doing so will skip the first block. // instantiate new header diff --git a/types/int.go b/types/int.go index 4a736d3ef..1b1f78b0c 100644 --- a/types/int.go +++ b/types/int.go @@ -24,7 +24,7 @@ func SafeInt64(value uint64) (int64, error) { // SafeNewIntFromBigInt constructs Int from big.Int, return error if more than 256bits func SafeNewIntFromBigInt(i *big.Int) (sdkmath.Int, error) { if !IsValidInt256(i) { - return sdkmath.NewInt(0), fmt.Errorf("big int out of bound: %s", i) + return sdkmath.ZeroInt(), fmt.Errorf("big int out of bound: %s", i) } return sdkmath.NewIntFromBigInt(i), nil } diff --git a/x/avs/keeper/avs.go b/x/avs/keeper/avs.go index a87868902..4862b9af3 100644 --- a/x/avs/keeper/avs.go +++ b/x/avs/keeper/avs.go @@ -58,12 +58,20 @@ func (k *Keeper) GetAVSSlashContract(ctx sdk.Context, avsAddr string) (string, e func (k *Keeper) GetAVSMinimumSelfDelegation(ctx sdk.Context, avsAddr string) (sdkmath.LegacyDec, error) { avsInfo, err := k.GetAVSInfo(ctx, avsAddr) if err != nil { - return sdkmath.LegacyNewDec(0), errorsmod.Wrap(err, fmt.Sprintf("GetAVSMinimumSelfDelegation: key is %s", avsAddr)) + return sdkmath.LegacyZeroDec(), errorsmod.Wrap(err, fmt.Sprintf("GetAVSMinimumSelfDelegation: key is %s", avsAddr)) } // #nosec G115 return sdkmath.LegacyNewDec(int64(avsInfo.Info.MinSelfDelegation)), nil } +func (k *Keeper) GetAVSUnbondingDuration(ctx sdk.Context, avsAddr string) (uint64, error) { + avsInfo, err := k.GetAVSInfo(ctx, avsAddr) + if err != nil { + return 0, errorsmod.Wrap(err, fmt.Sprintf("GetAVSUnbondingDuration: key is %s", avsAddr)) + } + return avsInfo.Info.AvsUnbondingPeriod, nil +} + // GetEpochEndAVSs returns a list of hex AVS addresses for AVSs which are scheduled to start at the end of the // current epoch, or the beginning of the next one. The address format returned is hex. func (k *Keeper) GetEpochEndAVSs(ctx sdk.Context, epochIdentifier string, endingEpochNumber int64) []string { diff --git a/x/avs/keeper/avs_test.go b/x/avs/keeper/avs_test.go index 3ab1ed807..1b7dddbca 100644 --- a/x/avs/keeper/avs_test.go +++ b/x/avs/keeper/avs_test.go @@ -1,13 +1,14 @@ package keeper_test import ( - "cosmossdk.io/math" - assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" - "github.com/ethereum/go-ethereum/common" "math/big" "strings" "time" + "cosmossdk.io/math" + assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ExocoreNetwork/exocore/x/avs/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" diff --git a/x/avs/keeper/impl_epoch_hook.go b/x/avs/keeper/impl_epoch_hook.go index 73d619b86..986d2d4f7 100644 --- a/x/avs/keeper/impl_epoch_hook.go +++ b/x/avs/keeper/impl_epoch_hook.go @@ -41,7 +41,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( var taskAddr string var avsAddr string var operatorPowers []*types.OperatorActivePowerInfo - operatorPowerTotal := sdkmath.LegacyNewDec(0) + operatorPowerTotal := sdkmath.LegacyZeroDec() for _, res := range value { // Find signed operators if res.BlsSignature != nil { diff --git a/x/avs/keeper/keeper.go b/x/avs/keeper/keeper.go index 4c7d2e88c..4e0e0fce4 100644 --- a/x/avs/keeper/keeper.go +++ b/x/avs/keeper/keeper.go @@ -8,6 +8,8 @@ import ( "strconv" "strings" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/prysmaticlabs/prysm/v4/crypto/bls" @@ -382,6 +384,18 @@ func (k Keeper) IterateAVSInfo(ctx sdk.Context, fn func(index int64, avsInfo typ } } +func (k Keeper) GetAVSEpochInfo(ctx sdk.Context, addr string) (*epochstypes.EpochInfo, error) { + avsInfoResp, err := k.GetAVSInfo(ctx, addr) + if err != nil { + return nil, err + } + avsInfo := avsInfoResp.Info + // Epoch information must be available because it is checked when setting AVS information. + // Therefore, we don’t need to check it here. + epochInfo, _ := k.epochsKeeper.GetEpochInfo(ctx, avsInfo.EpochIdentifier) + return &epochInfo, nil +} + func (k Keeper) RaiseAndResolveChallenge(ctx sdk.Context, params *types.ChallengeParams) error { taskInfo, err := k.GetTaskInfo(ctx, strconv.FormatUint(params.TaskID, 10), params.TaskContractAddress.String()) if err != nil { diff --git a/x/avs/keeper/submit_task_test.go b/x/avs/keeper/submit_task_test.go index 7abda46b9..bdcb3550e 100644 --- a/x/avs/keeper/submit_task_test.go +++ b/x/avs/keeper/submit_task_test.go @@ -138,7 +138,7 @@ func (suite *AVSTestSuite) prepareTaskInfo() { StartingEpoch: uint64(epoch.CurrentEpoch + 1), ActualThreshold: 0, OptInOperators: operatorList, - TaskTotalPower: sdk.Dec(sdkmath.NewInt(0)), + TaskTotalPower: sdk.Dec(sdkmath.ZeroInt()), } err = suite.App.AVSManagerKeeper.SetTaskInfo(suite.Ctx, info) suite.NoError(err) diff --git a/x/avs/keeper/task_test.go b/x/avs/keeper/task_test.go index 5d6216a8f..65acd57de 100644 --- a/x/avs/keeper/task_test.go +++ b/x/avs/keeper/task_test.go @@ -3,7 +3,6 @@ package keeper_test import ( "strconv" - sdkmath "cosmossdk.io/math" types "github.com/ExocoreNetwork/exocore/x/avs/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" @@ -18,7 +17,7 @@ func (suite *AVSTestSuite) TestTaskInfo() { TaskResponsePeriod: 10000, TaskChallengePeriod: 5000, ThresholdPercentage: 60, - TaskTotalPower: sdk.Dec(sdkmath.NewInt(0)), + TaskTotalPower: sdk.ZeroDec(), } err := suite.App.AVSManagerKeeper.SetTaskInfo(suite.Ctx, info) suite.NoError(err) diff --git a/x/delegation/keeper/delegation_op_test.go b/x/delegation/keeper/delegation_op_test.go index c0f94cc31..c8ab2befd 100644 --- a/x/delegation/keeper/delegation_op_test.go +++ b/x/delegation/keeper/delegation_op_test.go @@ -119,23 +119,23 @@ func (suite *DelegationTestSuite) TestDelegateTo() { suite.Equal(types.StakerAssetInfo{ TotalDepositAmount: suite.depositAmount, WithdrawableAmount: suite.depositAmount.Sub(delegationParams.OpAmount), - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), }, *restakerState) operatorState, err := suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, opAccAddr, assetID) suite.NoError(err) suite.Equal(types.OperatorAssetInfo{ TotalAmount: delegationParams.OpAmount, - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), TotalShare: sdkmath.LegacyNewDecFromBigInt(delegationParams.OpAmount.BigInt()), - OperatorShare: sdkmath.LegacyNewDec(0), + OperatorShare: sdkmath.LegacyZeroDec(), }, *operatorState) specifiedDelegationAmount, err := suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, opAccAddr.String()) suite.NoError(err) suite.Equal(delegationtype.DelegationAmounts{ UndelegatableShare: sdkmath.LegacyNewDecFromBigInt(delegationParams.OpAmount.BigInt()), - WaitUndelegationAmount: sdkmath.NewInt(0), + WaitUndelegationAmount: sdkmath.ZeroInt(), }, *specifiedDelegationAmount) totalDelegationAmount, err := suite.App.DelegationKeeper.TotalDelegatedAmountForStakerAsset(suite.Ctx, stakerID, assetID) @@ -163,22 +163,22 @@ func (suite *DelegationTestSuite) TestDelegateTo() { suite.Equal(types.StakerAssetInfo{ TotalDepositAmount: balance.Amount.Add(delegationParams.OpAmount), WithdrawableAmount: balance.Amount, - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), }, *restakerState) operatorState, err = suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, opAccAddr, assetID) suite.NoError(err) suite.Equal(types.OperatorAssetInfo{ TotalAmount: delegationParams.OpAmount, - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), TotalShare: sdkmath.LegacyNewDecFromBigInt(delegationParams.OpAmount.BigInt()), - OperatorShare: sdkmath.LegacyNewDec(0), + OperatorShare: sdkmath.LegacyZeroDec(), }, *operatorState) specifiedDelegationAmount, err = suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, opAccAddr.String()) suite.NoError(err) suite.Equal(delegationtype.DelegationAmounts{ UndelegatableShare: sdkmath.LegacyNewDecFromBigInt(delegationParams.OpAmount.BigInt()), - WaitUndelegationAmount: sdkmath.NewInt(0), + WaitUndelegationAmount: sdkmath.ZeroInt(), }, *specifiedDelegationAmount) totalDelegationAmount, err = suite.App.DelegationKeeper.TotalDelegatedAmountForStakerAsset(suite.Ctx, stakerID, assetID) @@ -208,22 +208,22 @@ func (suite *DelegationTestSuite) TestUndelegateFrom() { operatorState, err := suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, delegationEvent.OperatorAddress, assetID) suite.NoError(err) suite.Equal(types.OperatorAssetInfo{ - TotalAmount: sdkmath.NewInt(0), + TotalAmount: sdkmath.ZeroInt(), PendingUndelegationAmount: delegationEvent.OpAmount, - TotalShare: sdkmath.LegacyNewDec(0), - OperatorShare: sdkmath.LegacyNewDec(0), + TotalShare: sdkmath.LegacyZeroDec(), + OperatorShare: sdkmath.LegacyZeroDec(), }, *operatorState) specifiedDelegationAmount, err := suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, delegationEvent.OperatorAddress.String()) suite.NoError(err) suite.Equal(delegationtype.DelegationAmounts{ WaitUndelegationAmount: delegationEvent.OpAmount, - UndelegatableShare: sdkmath.LegacyNewDec(0), + UndelegatableShare: sdkmath.LegacyZeroDec(), }, *specifiedDelegationAmount) totalDelegationAmount, err := suite.App.DelegationKeeper.TotalDelegatedAmountForStakerAsset(suite.Ctx, stakerID, assetID) suite.NoError(err) - suite.Equal(sdkmath.NewInt(0), totalDelegationAmount) + suite.Equal(sdkmath.ZeroInt(), totalDelegationAmount) records, err := suite.App.DelegationKeeper.GetStakerUndelegationRecords(suite.Ctx, stakerID, assetID) suite.NoError(err) @@ -267,22 +267,22 @@ func (suite *DelegationTestSuite) TestUndelegateFrom() { operatorState, err = suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, delegationEvent.OperatorAddress, assetID) suite.NoError(err) suite.Equal(types.OperatorAssetInfo{ - TotalAmount: sdkmath.NewInt(0), + TotalAmount: sdkmath.ZeroInt(), PendingUndelegationAmount: delegationEvent.OpAmount, - TotalShare: sdkmath.LegacyNewDec(0), - OperatorShare: sdkmath.LegacyNewDec(0), + TotalShare: sdkmath.LegacyZeroDec(), + OperatorShare: sdkmath.LegacyZeroDec(), }, *operatorState) specifiedDelegationAmount, err = suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, delegationEvent.OperatorAddress.String()) suite.NoError(err) suite.Equal(delegationtype.DelegationAmounts{ WaitUndelegationAmount: delegationEvent.OpAmount, - UndelegatableShare: sdkmath.LegacyNewDec(0), + UndelegatableShare: sdkmath.LegacyZeroDec(), }, *specifiedDelegationAmount) totalDelegationAmount, err = suite.App.DelegationKeeper.TotalDelegatedAmountForStakerAsset(suite.Ctx, stakerID, assetID) suite.NoError(err) - suite.Equal(sdkmath.NewInt(0), totalDelegationAmount) + suite.Equal(sdkmath.ZeroInt(), totalDelegationAmount) records, err = suite.App.DelegationKeeper.GetStakerUndelegationRecords(suite.Ctx, stakerID, assetID) suite.NoError(err) @@ -351,28 +351,28 @@ func (suite *DelegationTestSuite) TestCompleteUndelegation() { suite.Equal(types.StakerAssetInfo{ TotalDepositAmount: suite.depositAmount, WithdrawableAmount: suite.depositAmount, - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), }, *restakerState) operatorState, err := suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, delegationEvent.OperatorAddress, assetID) suite.NoError(err) suite.Equal(types.OperatorAssetInfo{ - TotalAmount: sdkmath.NewInt(0), - PendingUndelegationAmount: sdkmath.NewInt(0), - TotalShare: sdkmath.LegacyNewDec(0), - OperatorShare: sdkmath.LegacyNewDec(0), + TotalAmount: sdkmath.ZeroInt(), + PendingUndelegationAmount: sdkmath.ZeroInt(), + TotalShare: sdkmath.LegacyZeroDec(), + OperatorShare: sdkmath.LegacyZeroDec(), }, *operatorState) specifiedDelegationAmount, err := suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, delegationEvent.OperatorAddress.String()) suite.NoError(err) suite.Equal(delegationtype.DelegationAmounts{ - UndelegatableShare: sdkmath.LegacyNewDec(0), - WaitUndelegationAmount: sdkmath.NewInt(0), + UndelegatableShare: sdkmath.LegacyZeroDec(), + WaitUndelegationAmount: sdkmath.ZeroInt(), }, *specifiedDelegationAmount) totalDelegationAmount, err := suite.App.DelegationKeeper.TotalDelegatedAmountForStakerAsset(suite.Ctx, stakerID, assetID) suite.NoError(err) - suite.Equal(sdkmath.NewInt(0), totalDelegationAmount) + suite.Equal(sdkmath.ZeroInt(), totalDelegationAmount) records, err := suite.App.DelegationKeeper.GetStakerUndelegationRecords(suite.Ctx, stakerID, assetID) suite.NoError(err) @@ -419,28 +419,28 @@ func (suite *DelegationTestSuite) TestCompleteUndelegation() { suite.Equal(types.StakerAssetInfo{ TotalDepositAmount: balance.Amount, WithdrawableAmount: balance.Amount, - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), }, *restakerState) operatorState, err = suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, delegationEvent.OperatorAddress, assetID) suite.NoError(err) suite.Equal(types.OperatorAssetInfo{ - TotalAmount: sdkmath.NewInt(0), - PendingUndelegationAmount: sdkmath.NewInt(0), - TotalShare: sdkmath.LegacyNewDec(0), - OperatorShare: sdkmath.LegacyNewDec(0), + TotalAmount: sdkmath.ZeroInt(), + PendingUndelegationAmount: sdkmath.ZeroInt(), + TotalShare: sdkmath.LegacyZeroDec(), + OperatorShare: sdkmath.LegacyZeroDec(), }, *operatorState) specifiedDelegationAmount, err = suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, delegationEvent.OperatorAddress.String()) suite.NoError(err) suite.Equal(delegationtype.DelegationAmounts{ - UndelegatableShare: sdkmath.LegacyNewDec(0), - WaitUndelegationAmount: sdkmath.NewInt(0), + UndelegatableShare: sdkmath.LegacyZeroDec(), + WaitUndelegationAmount: sdkmath.ZeroInt(), }, *specifiedDelegationAmount) totalDelegationAmount, err = suite.App.DelegationKeeper.TotalDelegatedAmountForStakerAsset(suite.Ctx, stakerID, assetID) suite.NoError(err) - suite.Equal(sdkmath.NewInt(0), totalDelegationAmount) + suite.Equal(sdkmath.ZeroInt(), totalDelegationAmount) records, err = suite.App.DelegationKeeper.GetStakerUndelegationRecords(suite.Ctx, stakerID, assetID) suite.NoError(err) diff --git a/x/delegation/keeper/delegation_state.go b/x/delegation/keeper/delegation_state.go index 340d585dd..ce04b35c9 100644 --- a/x/delegation/keeper/delegation_state.go +++ b/x/delegation/keeper/delegation_state.go @@ -77,7 +77,7 @@ func (k Keeper) IterateDelegationsForStaker(ctx sdk.Context, stakerID string, op // TotalDelegatedAmountForStakerAsset query the total delegation amount of the specified staker and asset. // It needs to be calculated from the share and amount of the asset pool. func (k Keeper) TotalDelegatedAmountForStakerAsset(ctx sdk.Context, stakerID string, assetID string) (amount sdkmath.Int, err error) { - amount = sdkmath.NewInt(0) + amount = sdkmath.ZeroInt() opFunc := func(keys *delegationtype.SingleDelegationInfoReq, amounts *delegationtype.DelegationAmounts) (bool, error) { if amounts.UndelegatableShare.IsZero() { return false, nil @@ -143,8 +143,8 @@ func (k Keeper) UpdateDelegationState(ctx sdk.Context, stakerID, assetID, opAddr } singleStateKey := assetstype.GetJoinedStoreKey(stakerID, assetID, opAddr) delegationState := delegationtype.DelegationAmounts{ - WaitUndelegationAmount: sdkmath.NewInt(0), - UndelegatableShare: sdkmath.LegacyNewDec(0), + WaitUndelegationAmount: sdkmath.ZeroInt(), + UndelegatableShare: sdkmath.LegacyZeroDec(), } value := store.Get(singleStateKey) @@ -305,7 +305,7 @@ func (k *Keeper) SetStakerShareToZero(ctx sdk.Context, operator, assetID string, if value != nil { delegationState := delegationtype.DelegationAmounts{} k.cdc.MustUnmarshal(value, &delegationState) - delegationState.UndelegatableShare = sdkmath.LegacyNewDec(0) + delegationState.UndelegatableShare = sdkmath.LegacyZeroDec() bz := k.cdc.MustMarshal(&delegationState) store.Set(singleStateKey, bz) } diff --git a/x/delegation/keeper/share.go b/x/delegation/keeper/share.go index d0cc7c64a..3e3c64905 100644 --- a/x/delegation/keeper/share.go +++ b/x/delegation/keeper/share.go @@ -18,14 +18,14 @@ import ( // caused by the bankers rounding. func TokensFromShares(stakerShare, totalShare sdkmath.LegacyDec, totalAmount sdkmath.Int) (sdkmath.Int, error) { if stakerShare.GT(totalShare) { - return sdkmath.NewInt(0), errorsmod.Wrapf(delegationtypes.ErrInsufficientShares, "the stakerShare is:%v the totalShare is:%v", stakerShare, totalShare) + return sdkmath.ZeroInt(), errorsmod.Wrapf(delegationtypes.ErrInsufficientShares, "the stakerShare is:%v the totalShare is:%v", stakerShare, totalShare) } if totalShare.IsZero() { if totalAmount.IsZero() { // this can happen if everyone exits. - return sdkmath.NewInt(0), nil + return sdkmath.ZeroInt(), nil } - return sdkmath.NewInt(0), delegationtypes.ErrDivisorIsZero + return sdkmath.ZeroInt(), delegationtypes.ErrDivisorIsZero } return (stakerShare.MulInt(totalAmount)).Quo(totalShare).TruncateInt(), nil } diff --git a/x/delegation/keeper/share_test.go b/x/delegation/keeper/share_test.go index 5f9034d21..2e87a7657 100644 --- a/x/delegation/keeper/share_test.go +++ b/x/delegation/keeper/share_test.go @@ -23,23 +23,23 @@ func (suite *DelegationTestSuite) TestTokensFromShares() { totalAmount: sdkmath.NewInt(50), stakerShare: sdkmath.LegacyNewDec(51), innerError: delegationtypes.ErrInsufficientShares, - stakerAmount: sdkmath.NewInt(0), + stakerAmount: sdkmath.ZeroInt(), }, { - totalShare: sdkmath.LegacyNewDec(0), + totalShare: sdkmath.LegacyZeroDec(), totalAmount: sdkmath.NewInt(50), - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), innerError: delegationtypes.ErrDivisorIsZero, - stakerAmount: sdkmath.NewInt(0), + stakerAmount: sdkmath.ZeroInt(), }, // the share will be equal to the amount if there isn't a slash event { totalShare: sdkmath.LegacyNewDec(50), totalAmount: sdkmath.NewInt(50), - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), innerError: nil, - stakerAmount: sdkmath.NewInt(0), + stakerAmount: sdkmath.ZeroInt(), }, { totalShare: sdkmath.LegacyNewDec(50), @@ -60,9 +60,9 @@ func (suite *DelegationTestSuite) TestTokensFromShares() { { totalShare: sdkmath.LegacyNewDec(70), totalAmount: sdkmath.NewInt(50), - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), innerError: nil, - stakerAmount: sdkmath.NewInt(0), + stakerAmount: sdkmath.ZeroInt(), }, { totalShare: sdkmath.LegacyNewDec(70), @@ -81,10 +81,10 @@ func (suite *DelegationTestSuite) TestTokensFromShares() { // all exit { - totalShare: sdkmath.LegacyNewDec(0), - stakerShare: sdkmath.LegacyNewDec(0), - totalAmount: sdkmath.NewInt(0), - stakerAmount: sdkmath.NewInt(0), + totalShare: sdkmath.LegacyZeroDec(), + stakerShare: sdkmath.LegacyZeroDec(), + totalAmount: sdkmath.ZeroInt(), + stakerAmount: sdkmath.ZeroInt(), innerError: nil, }, } @@ -114,19 +114,19 @@ func (suite *DelegationTestSuite) TestSharesFromTokens() { // error cases { totalShare: sdkmath.LegacyNewDec(50), - totalAmount: sdkmath.NewInt(0), - stakerAmount: sdkmath.NewInt(0), + totalAmount: sdkmath.ZeroInt(), + stakerAmount: sdkmath.ZeroInt(), innerError: delegationtypes.ErrDivisorIsZero, - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), }, // the share will be equal to the amount if there isn't a slash event { totalShare: sdkmath.LegacyNewDec(50), totalAmount: sdkmath.NewInt(50), - stakerAmount: sdkmath.NewInt(0), + stakerAmount: sdkmath.ZeroInt(), innerError: nil, - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), }, { totalShare: sdkmath.LegacyNewDec(50), @@ -154,9 +154,9 @@ func (suite *DelegationTestSuite) TestSharesFromTokens() { { totalShare: sdkmath.LegacyNewDec(70), totalAmount: sdkmath.NewInt(50), - stakerAmount: sdkmath.NewInt(0), + stakerAmount: sdkmath.ZeroInt(), innerError: nil, - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), }, { totalShare: sdkmath.LegacyNewDec(70), @@ -175,11 +175,11 @@ func (suite *DelegationTestSuite) TestSharesFromTokens() { // all exit { - totalShare: sdkmath.LegacyNewDec(0), - totalAmount: sdkmath.NewInt(0), - stakerAmount: sdkmath.NewInt(0), + totalShare: sdkmath.LegacyZeroDec(), + totalAmount: sdkmath.ZeroInt(), + stakerAmount: sdkmath.ZeroInt(), innerError: nil, - stakerShare: sdkmath.LegacyNewDec(0), + stakerShare: sdkmath.LegacyZeroDec(), }, } @@ -204,8 +204,8 @@ func (suite *DelegationTestSuite) TestCalculateShare() { // test the case that the asset amount of operator is zero err = suite.App.AssetsKeeper.UpdateOperatorAssetState(suite.Ctx, suite.opAccAddr, assetID, assetstype.DeltaOperatorSingleAsset{ - TotalAmount: sdkmath.NewInt(0), - TotalShare: sdkmath.LegacyNewDec(0), + TotalAmount: sdkmath.ZeroInt(), + TotalShare: sdkmath.LegacyZeroDec(), }) suite.NoError(err) share, err = suite.App.DelegationKeeper.CalculateShare(suite.Ctx, suite.opAccAddr, assetID, assetAmount) @@ -229,7 +229,7 @@ func (suite *DelegationTestSuite) TestValidateUndelegationAmount() { suite.prepareDelegation(suite.delegationAmount, suite.opAccAddr) stakerID, assetID := assetstype.GetStakerIDAndAssetID(suite.clientChainLzID, suite.Address[:], suite.assetAddr[:]) - undelegationAmount := sdkmath.NewInt(0) + undelegationAmount := sdkmath.ZeroInt() _, err := suite.App.DelegationKeeper.ValidateUndelegationAmount(suite.Ctx, suite.opAccAddr, stakerID, assetID, undelegationAmount) suite.Error(err, delegationtypes.ErrAmountIsNotPositive) @@ -249,7 +249,7 @@ func (suite *DelegationTestSuite) TestCalculateSlashShare() { suite.prepareDeposit(suite.depositAmount) suite.prepareDelegation(suite.delegationAmount, suite.opAccAddr) stakerID, assetID := assetstype.GetStakerIDAndAssetID(suite.clientChainLzID, suite.Address[:], suite.assetAddr[:]) - slashAmount := sdkmath.NewInt(0) + slashAmount := sdkmath.ZeroInt() _, err := suite.App.DelegationKeeper.CalculateSlashShare(suite.Ctx, suite.opAccAddr, stakerID, assetID, slashAmount) suite.Error(err, delegationtypes.ErrAmountIsNotPositive) @@ -327,7 +327,7 @@ func (suite *DelegationTestSuite) TestRemoveShare() { suite.Equal(removeShare.TruncateInt(), removeToken) delegationInfo, err = suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, suite.opAccAddr.String()) suite.NoError(err) - suite.Equal(sdkmath.LegacyNewDec(0), delegationInfo.UndelegatableShare) + suite.Equal(sdkmath.LegacyZeroDec(), delegationInfo.UndelegatableShare) suite.Equal(removeShare.TruncateInt(), delegationInfo.WaitUndelegationAmount) stakerAssetInfo, err := suite.App.AssetsKeeper.GetStakerSpecifiedAssetInfo(suite.Ctx, stakerID, assetID) suite.NoError(err) diff --git a/x/delegation/keeper/update_native_restaking_balance_test.go b/x/delegation/keeper/update_native_restaking_balance_test.go index 7a2bf81c9..b646d9527 100644 --- a/x/delegation/keeper/update_native_restaking_balance_test.go +++ b/x/delegation/keeper/update_native_restaking_balance_test.go @@ -43,7 +43,7 @@ func (suite *DelegationTestSuite) TestUpdateNSTBalance() { suite.NoError(err) expectAssetInfo := assettypes.StakerAssetInfo{ TotalDepositAmount: depositAmount.Sub(actualSlashAmount), - WithdrawableAmount: sdkmath.NewInt(0), + WithdrawableAmount: sdkmath.ZeroInt(), // it will be decreased when the undelegation is completed. PendingUndelegationAmount: undelegateAmountFromDefaultOperator, } @@ -52,7 +52,7 @@ func (suite *DelegationTestSuite) TestUpdateNSTBalance() { // check the undelegation state after slashing records, err := suite.App.DelegationKeeper.GetStakerUndelegationRecords(suite.Ctx, stakerID, assetID) suite.NoError(err) - suite.Equal(sdkmath.NewInt(0), records[0].ActualCompletedAmount) + suite.Equal(sdkmath.ZeroInt(), records[0].ActualCompletedAmount) // check the delegated share for two operators delegationForDefaultOperator, err := suite.App.DelegationKeeper.GetSingleDelegationInfo(suite.Ctx, stakerID, assetID, suite.opAccAddr.String()) diff --git a/x/delegation/types/expected_keepers.go b/x/delegation/types/expected_keepers.go index 8fd5fb42b..27dacad0c 100644 --- a/x/delegation/types/expected_keepers.go +++ b/x/delegation/types/expected_keepers.go @@ -23,7 +23,7 @@ func (VirtualSlashKeeper) IsOperatorFrozen(_ sdk.Context, _ sdk.AccAddress) bool } func (VirtualSlashKeeper) OperatorAssetSlashedProportion(_ sdk.Context, _ sdk.AccAddress, _ string, _, _ uint64) sdkmath.LegacyDec { - return sdkmath.LegacyNewDec(0) + return sdkmath.LegacyZeroDec() } // DelegationHooks are event hooks triggered by the delegation module diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index f09480ae3..aa6ee3d76 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -15,13 +15,14 @@ func (k Keeper) BeginBlock(ctx sdk.Context) { } func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { - if !k.IsEpochEnd(ctx) { + if !k.ShouldUpdateValidatorSet(ctx) { k.SetValidatorUpdates(ctx, []abci.ValidatorUpdate{}) return []abci.ValidatorUpdate{} } - defer k.ClearEpochEnd(ctx) + defer k.ClearValidatorSetUpdateFlag(ctx) logger := k.Logger(ctx) chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(ctx.ChainID()) + // start by clearing the previous consensus keys for the chain. // each AVS can have a separate epoch and hence this function is a part of this module // and not the operator module. @@ -31,10 +32,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { for _, undelegation := range undelegations.GetList() { err := k.delegationKeeper.DecrementUndelegationHoldCount(ctx, undelegation) if err != nil { - logger.Error( - "error decrementing undelegation hold count", - "error", err, - ) + logger.Error("error decrementing undelegation hold count", "error", err) } k.ClearUndelegationMaturityEpoch(ctx, undelegation) } @@ -46,10 +44,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { ctx, addr, chainIDWithoutRevision, ) if err != nil { - logger.Error( - "error completing operator key removal", - "error", err, - ) + logger.Error("error completing operator key removal", "error", err) } } k.ClearPendingOptOuts(ctx) @@ -80,10 +75,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { pubKey, err := validator.ConsPubKey() if err != nil { // indicates an error in deserialization, and should never happen. - logger.Error( - "error deserializing consensus public key", - "error", err, - ) + logger.Error("error deserializing consensus public key", "error", err) continue } addressString := sdk.GetConsAddress(pubKey).String() @@ -94,10 +86,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { ctx, operators, chainIDWithoutRevision, ) if err != nil { - logger.Error( - "error getting vote power for chain", - "error", err, - ) + logger.Error("error getting vote power for chain", "error", err) return []abci.ValidatorUpdate{} } operators, keys, powers = utils.SortByPower(operators, keys, powers) diff --git a/x/dogfood/keeper/genesis.go b/x/dogfood/keeper/genesis.go index bf6889cb5..5534c0d5b 100644 --- a/x/dogfood/keeper/genesis.go +++ b/x/dogfood/keeper/genesis.go @@ -110,6 +110,16 @@ func (k Keeper) InitGenesis( // ApplyValidatorChanges only gets changes and hence the vote power must be set here. k.SetLastTotalPower(ctx, genState.LastTotalPower) + // init the voting power snapshot for all default opting-in AVSs + // todo: It was originally intended to be called in the initGenesis function of the operator module, + // but since the dogfood AVS is currently initialized in this module,and this function depends on the + // AVS epoch configuration, it is temporarily called here. Once the initialization of dogfood + // AVS is implemented in the initGenesis function of the AVS module, it can be moved back to + // the operator module. + err = k.operatorKeeper.InitGenesisVPSnapshot(ctx) + if err != nil { + panic(fmt.Sprintf("cant init genesis voting power snapshot,err: %s", err)) + } // ApplyValidatorChanges will sort it internally return k.ApplyValidatorChanges( ctx, out, diff --git a/x/dogfood/keeper/impl_epochs_hooks.go b/x/dogfood/keeper/impl_epochs_hooks.go index cff81133c..03351d19b 100644 --- a/x/dogfood/keeper/impl_epochs_hooks.go +++ b/x/dogfood/keeper/impl_epochs_hooks.go @@ -33,7 +33,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( // note that this hook is called during BeginBlock, and the "pending" operations will be // applied within this block. however, for clarity, it is highlighted that unbonding // takes N epochs + 1 block to complete. - wrapper.keeper.MarkEpochEnd(ctx) + wrapper.keeper.MarkUpdateValidatorSetFlag(ctx) ctx.Logger().Info("mark epoch end", "height", ctx.BlockHeight(), "identifier", identifier, "epoch", epoch) // find the opt outs that mature when this epoch ends, and move them to pending. optOuts := wrapper.keeper.GetOptOutsToFinish(ctx, epoch) diff --git a/x/dogfood/keeper/impl_operator_hooks.go b/x/dogfood/keeper/impl_operator_hooks.go index 7a9d284d8..715a4e632 100644 --- a/x/dogfood/keeper/impl_operator_hooks.go +++ b/x/dogfood/keeper/impl_operator_hooks.go @@ -91,3 +91,29 @@ func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( } } } + +func (h OperatorHooksWrapper) AfterSlash( + ctx sdk.Context, operator sdk.AccAddress, affectedAVSList []string, +) { + chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(ctx.ChainID()) + dogfoodAVSAddr := avstypes.GenerateAVSAddr(chainIDWithoutRevision) + for i := range affectedAVSList { + if affectedAVSList[i] == dogfoodAVSAddr { + // check if the operator is in the current validator set. + found, wrappedKey, err := h.keeper.operatorKeeper.GetOperatorConsKeyForChainID(ctx, operator, chainIDWithoutRevision) + if !found || err != nil { + ctx.Logger().Error("AfterSlash the consensus key isn't found by the chainIDWithoutRevision and operator address", "operatorAddr", operator, "chainIDWithoutRevision", chainIDWithoutRevision, "err", err) + return + } + // check if the key is active yet + isValidator := false + _, isValidator = h.keeper.GetExocoreValidator( + ctx, wrappedKey.ToConsAddr(), + ) + if isValidator { + h.keeper.MarkUpdateValidatorSetFlag(ctx) + } + break + } + } +} diff --git a/x/dogfood/keeper/keeper.go b/x/dogfood/keeper/keeper.go index 7198320fa..42941549c 100644 --- a/x/dogfood/keeper/keeper.go +++ b/x/dogfood/keeper/keeper.go @@ -86,27 +86,27 @@ func (k Keeper) Hooks() types.DogfoodHooks { return types.MultiDogfoodHooks{} } -// MarkEpochEnd marks the end of the epoch. It is called within the BeginBlocker to inform -// the module to apply the validator updates at the end of this block. -func (k Keeper) MarkEpochEnd(ctx sdk.Context) { +// MarkUpdateValidatorSetFlag marks that the validator set needs to be updated at the end of this block. +// Mostly, these updates occur in response to the epoch ending. In other cases, they are the result of slashing. +func (k Keeper) MarkUpdateValidatorSetFlag(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) - key := types.EpochEndKey() + key := types.ShouldUpdateValidatorSetByteKey() store.Set(key, []byte{1}) } -// IsEpochEnd returns true if the epoch ended in the beginning of this block, or the end of the +// ShouldUpdateValidatorSet returns true if the epoch ended in the beginning of this block, or the end of the // previous block. -func (k Keeper) IsEpochEnd(ctx sdk.Context) bool { +func (k Keeper) ShouldUpdateValidatorSet(ctx sdk.Context) bool { store := ctx.KVStore(k.storeKey) - key := types.EpochEndKey() + key := types.ShouldUpdateValidatorSetByteKey() return store.Has(key) } -// ClearEpochEnd clears the epoch end marker. It is called after the epoch end operations are +// ClearValidatorSetUpdateFlag clears the epoch end marker. It is called after the epoch end operations are // applied. -func (k Keeper) ClearEpochEnd(ctx sdk.Context) { +func (k Keeper) ClearValidatorSetUpdateFlag(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) - key := types.EpochEndKey() + key := types.ShouldUpdateValidatorSetByteKey() store.Delete(key) } diff --git a/x/dogfood/types/expected_keepers.go b/x/dogfood/types/expected_keepers.go index f8732969f..454aebddf 100644 --- a/x/dogfood/types/expected_keepers.go +++ b/x/dogfood/types/expected_keepers.go @@ -83,6 +83,7 @@ type OperatorKeeper interface { GetOptedInAVSForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) CalculateUSDValueForStaker(ctx sdk.Context, stakerID, avsAddr string, operator sdk.AccAddress) (math.LegacyDec, error) OperatorInfo(ctx sdk.Context, addr string) (info *operatortypes.OperatorInfo, err error) + InitGenesisVPSnapshot(ctx sdk.Context) error } // DelegationKeeper represents the expected keeper interface for the delegation module. diff --git a/x/dogfood/types/keys.go b/x/dogfood/types/keys.go index 0f73db7d9..20528d2c4 100644 --- a/x/dogfood/types/keys.go +++ b/x/dogfood/types/keys.go @@ -58,8 +58,8 @@ const ( // mature at the end of the current block. PendingUndelegationsByte - // EpochEndByte is the byte key for the epoch end store. - EpochEndByte + // ShouldUpdateValidatorSetByte is the byte key for the epoch end store. + ShouldUpdateValidatorSetByte // HistoricalInfoBytePrefix is the byte prefix for the historical info store. HistoricalInfoBytePrefix @@ -143,9 +143,9 @@ func PendingUndelegationsKey() []byte { return []byte{PendingUndelegationsByte} } -// EpochEndKey returns the key for the epoch end store. -func EpochEndKey() []byte { - return []byte{EpochEndByte} +// ShouldUpdateValidatorSetByteKey returns the key for the epoch end store. +func ShouldUpdateValidatorSetByteKey() []byte { + return []byte{ShouldUpdateValidatorSetByte} } // UndelegationMaturityEpochKey returns the key for the undelegation maturity epoch store. diff --git a/x/epochs/keeper/abci.go b/x/epochs/keeper/abci.go index b2590e518..6a4f7770c 100644 --- a/x/epochs/keeper/abci.go +++ b/x/epochs/keeper/abci.go @@ -63,6 +63,7 @@ func (k Keeper) BeginBlocker(ctx sdk.Context) { "ending epoch", "identifier", epochInfo.Identifier, "number", epochInfo.CurrentEpoch, + "height", ctx.BlockHeight(), ) ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/x/exomint/keeper/impl_epochs_hooks_test.go b/x/exomint/keeper/impl_epochs_hooks_test.go index 7a33dbb01..ebff588a1 100644 --- a/x/exomint/keeper/impl_epochs_hooks_test.go +++ b/x/exomint/keeper/impl_epochs_hooks_test.go @@ -23,7 +23,7 @@ func (suite *KeeperTestSuite) TestEpochHooks() { suite.Ctx, feeCollector, params.MintDenom, - ).Amount.Equal(sdkmath.NewInt(0)), + ).Amount.Equal(sdkmath.ZeroInt()), ) // now go to one day diff --git a/x/exomint/types/params_test.go b/x/exomint/types/params_test.go index a875d2861..d1adee2df 100644 --- a/x/exomint/types/params_test.go +++ b/x/exomint/types/params_test.go @@ -59,7 +59,7 @@ func TestValidate(t *testing.T) { name: "zero reward", params: types.Params{ MintDenom: "aevmos", - EpochReward: sdkmath.NewInt(0), + EpochReward: sdkmath.ZeroInt(), EpochIdentifier: "day", }, expResult: true, @@ -150,11 +150,11 @@ func TestOverrideIfRequired(t *testing.T) { next: types.DefaultParams(), over: types.NewParams( types.DefaultMintDenom, - sdkmath.NewInt(0), // 0 is not overridden + sdkmath.ZeroInt(), // 0 is not overridden types.DefaultEpochIdentifier, ), malleate: func(next *types.Params) { - next.EpochReward = sdkmath.NewInt(0) + next.EpochReward = sdkmath.ZeroInt() }, }, { diff --git a/x/operator/client/cli/query.go b/x/operator/client/cli/query.go index 4d273d784..4cfa3c168 100644 --- a/x/operator/client/cli/query.go +++ b/x/operator/client/cli/query.go @@ -2,6 +2,7 @@ package cli import ( "context" + "strconv" "strings" "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -63,6 +64,9 @@ func GetQueryCmd() *cobra.Command { QueryAllOperatorsWithOptInAVS(), QueryAllAVSsByOperator(), GetOptInfo(), + QuerySnapshotHelper(), + QueryAllSnapshot(), + QuerySpecifiedSnapshot(), ) return cmd } @@ -456,3 +460,111 @@ func GetOptInfo() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd } + +func QuerySnapshotHelper() *cobra.Command { + cmd := &cobra.Command{ + Use: "query-snapshot-helper ", + Short: "Get the voting power snapshot helper for the avs", + Long: "Get the voting power snapshot helper for the avs", + Example: "exocored query operator query-snapshot-helper 0xaa089ba103f765fcea44808bd3d4073523254c57", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if !common.IsHexAddress(args[0]) { + return xerrors.Errorf("invalid avs address,err:%s", types.ErrInvalidAddr) + } + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := operatortypes.NewQueryClient(clientCtx) + req := &operatortypes.QuerySnapshotHelperRequest{ + Avs: strings.ToLower(args[0]), + } + res, err := queryClient.QuerySnapshotHelper(context.Background(), req) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func QueryAllSnapshot() *cobra.Command { + cmd := &cobra.Command{ + Use: "query-all-snapshot ", + Short: "Get the all voting power snapshots for the avs", + Long: "Get all voting power snapshots for the AVS. " + + "The number of stored snapshots should be the unbonding duration plus one.", + Example: "exocored query operator query-all-snapshot 0xaa089ba103f765fcea44808bd3d4073523254c57", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + if !common.IsHexAddress(args[0]) { + return xerrors.Errorf("invalid avs address,err:%s", types.ErrInvalidAddr) + } + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := operatortypes.NewQueryClient(clientCtx) + req := &operatortypes.QueryAllSnapshotRequest{ + Avs: strings.ToLower(args[0]), + Pagination: pageReq, + } + res, err := queryClient.QueryAllSnapshot(context.Background(), req) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func QuerySpecifiedSnapshot() *cobra.Command { + cmd := &cobra.Command{ + Use: "query-specified-snapshot ", + Short: "Get the AVS voting power snapshot at specified height", + Long: "Get the AVS voting power snapshot at specified height" + + "The number of stored snapshots should be the unbonding duration plus one.", + Example: "exocored query operator query-specified-snapshot 0xaa089ba103f765fcea44808bd3d4073523254c57 3", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + if !common.IsHexAddress(args[0]) { + return xerrors.Errorf("invalid avs address,err:%s", types.ErrInvalidAddr) + } + height, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + if height < 0 { + return xerrors.Errorf("negative height,height:%s", args[1]) + } + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := operatortypes.NewQueryClient(clientCtx) + req := &operatortypes.QuerySpecifiedSnapshotRequest{ + Avs: strings.ToLower(args[0]), + Height: height, + } + res, err := queryClient.QuerySpecifiedSnapshot(context.Background(), req) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/operator/keeper/abci.go b/x/operator/keeper/abci.go index b5a16b4ba..e7aa81108 100644 --- a/x/operator/keeper/abci.go +++ b/x/operator/keeper/abci.go @@ -3,6 +3,8 @@ package keeper import ( "errors" + "github.com/ethereum/go-ethereum/common" + sdkmath "cosmossdk.io/math" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" oracletypes "github.com/ExocoreNetwork/exocore/x/oracle/types" @@ -12,23 +14,28 @@ import ( // UpdateVotingPower update the voting power of the specified AVS and its operators at // the end of epoch. -func (k *Keeper) UpdateVotingPower(ctx sdk.Context, avsAddr string) error { +func (k *Keeper) UpdateVotingPower(ctx sdk.Context, avsAddr, epochIdentifier string, epochNumber int64, isForSlash bool) error { // get assets supported by the AVS // the mock keeper returns all registered assets. - assets, err := k.avsKeeper.GetAVSSupportedAssets(ctx, avsAddr) + assets, getAssetsErr := k.avsKeeper.GetAVSSupportedAssets(ctx, avsAddr) + // check if self USD value is more than the minimum self delegation. + minimumSelfDelegation, getSelfDelegationErr := k.avsKeeper.GetAVSMinimumSelfDelegation(ctx, avsAddr) // set the voting power to zero if an error is returned, which may prevent malicious behavior // where errors are intentionally triggered to avoid updating the voting power. - if err != nil || assets == nil { - ctx.Logger().Info("UpdateVotingPower the assets list supported by AVS is nil or can't get the assets list", "error", err) + if getAssetsErr != nil || assets == nil || getSelfDelegationErr != nil { + ctx.Logger().Error("UpdateVotingPower the assets list supported by AVS is nil or can't get AVS info", "getAssetsErr", getAssetsErr, "getSelfDelegationErr", getSelfDelegationErr) + // using cache context to ensure the atomicity of the operation. + cc, writeFunc := ctx.CacheContext() // clear the voting power regarding this AVS if there isn't any assets supported by it. - err = k.DeleteAllOperatorsUSDValueForAVS(ctx, avsAddr) + err := k.DeleteAllOperatorsUSDValueForAVS(cc, avsAddr) if err != nil { return err } - err = k.DeleteAVSUSDValue(ctx, avsAddr) + err = k.DeleteAVSUSDValue(cc, avsAddr) if err != nil { return err } + writeFunc() return nil } @@ -47,22 +54,22 @@ func (k *Keeper) UpdateVotingPower(ctx sdk.Context, avsAddr string) error { } // TODO: for now, we ignore the error when the price round is not found and set the price to 1 to avoid panic } - // update the voting power of operators and AVS - avsVotingPower := sdkmath.LegacyNewDec(0) - // check if self USD value is more than the minimum self delegation. - minimumSelfDelegation, err := k.avsKeeper.GetAVSMinimumSelfDelegation(ctx, avsAddr) - if err != nil { - // this error is handled earlier when calling `GetAVSSupportedAssets`, - // so we don't set the voting power to zero here. - return err - } + // update the voting power of operators and AVS + isSnapshotChanged := false + votingPowerSet := make([]*operatortypes.OperatorVotingPower, 0) + avsVotingPower := sdkmath.LegacyZeroDec() + hasOptedOperator := false opFunc := func(operator string, optedUSDValues *operatortypes.OperatorOptedUSDValue) error { + if !hasOptedOperator { + hasOptedOperator = true + } // clear the old voting power for the operator + lastOptedUSDValue := *optedUSDValues *optedUSDValues = operatortypes.OperatorOptedUSDValue{ - TotalUSDValue: sdkmath.LegacyNewDec(0), - SelfUSDValue: sdkmath.LegacyNewDec(0), - ActiveUSDValue: sdkmath.LegacyNewDec(0), + TotalUSDValue: sdkmath.LegacyZeroDec(), + SelfUSDValue: sdkmath.LegacyZeroDec(), + ActiveUSDValue: sdkmath.LegacyZeroDec(), } stakingInfo, err := k.CalculateUSDValueForOperator(ctx, false, operator, assets, decimals, prices) if err != nil { @@ -74,9 +81,21 @@ func (k *Keeper) UpdateVotingPower(ctx sdk.Context, avsAddr string) error { optedUSDValues.ActiveUSDValue = stakingInfo.Staking avsVotingPower = avsVotingPower.Add(optedUSDValues.TotalUSDValue) } + + // prepare the voting power set in advance + if optedUSDValues.ActiveUSDValue.IsPositive() { + votingPowerSet = append(votingPowerSet, &operatortypes.OperatorVotingPower{ + OperatorAddr: operator, + VotingPower: optedUSDValues.ActiveUSDValue, + }) + } + // check whether the voting power snapshot should be changed + // The snapshot will be updated even if only one operator's active voting power changes. + if !isSnapshotChanged && !lastOptedUSDValue.ActiveUSDValue.Equal(optedUSDValues.ActiveUSDValue) { + isSnapshotChanged = true + } return nil } - // using cache context to ensure the atomicity of the operation. cc, writeFunc := ctx.CacheContext() // iterate all operators of the AVS to update their voting power @@ -90,10 +109,96 @@ func (k *Keeper) UpdateVotingPower(ctx sdk.Context, avsAddr string) error { if err != nil { return err } + + // TODO: Consider not addressing the dogfood AVS, as its historical voting power + // has already been stored by CometBFT. + + // set voting power snapshot + // When the snapshot helper does not exist, it represents the initial state of AVS, + // where no snapshot information has been stored. Therefore, it is necessary to store + // both the snapshot and the helper information. + snapshotHelper := operatortypes.SnapshotHelper{} + if !k.HasSnapshotHelper(cc, avsAddr) { + isSnapshotChanged = true + } else { + snapshotHelper, err = k.GetSnapshotHelper(cc, avsAddr) + if err != nil { + return err + } + } + votingPowerSnapshot := operatortypes.VotingPowerSnapshot{ + EpochIdentifier: epochIdentifier, + EpochNumber: epochNumber, + } + + // The voting power calculated at the end of the current epoch will be applied + // to the next epoch. Therefore, when storing the voting power snapshot, we use + // the `start_height` of the next epoch as the key. This ensures that during the + // slashing process, there is no need to account for voting power activation delay; + // it can be used directly. + // Use the current height as the snapshot height when handling snapshots triggered + // by slashing. This prevents stakers from escaping slashes through backrunning + // undelegation. + // Use the start height of the next epoch as the snapshot key. + // The start height of the next epoch should be the current height, + // as the `AfterEpochEnd` is called in the beginBlock of next epoch's start height. + snapshotHeight := ctx.BlockHeight() + if !isForSlash { + // the epoch number should plus 1, as it's updated after the hook `AfterEpochEnd` is called + votingPowerSnapshot.EpochNumber++ + } + isSetSnapshot := true + if snapshotHelper.HasOptOut || isSnapshotChanged { + votingPowerSnapshot.TotalVotingPower = avsVotingPower + votingPowerSnapshot.OperatorVotingPowers = votingPowerSet + snapshotHelper.LastChangedHeight = snapshotHeight + // clear the hasOptOut flag if it's certain that the snapshot will be updated + snapshotHelper.HasOptOut = false + } else if !hasOptedOperator { + // don’t set the snapshot if no operator has opted into the AVS, + // except for the first epoch after all operators have opted out of this AVS. + isSetSnapshot = false + } + votingPowerSnapshot.LastChangedHeight = snapshotHelper.LastChangedHeight + + err = k.SetSnapshotHelper(cc, avsAddr, snapshotHelper) + if err != nil { + return err + } + + if isSetSnapshot { + snapshotKey := operatortypes.KeyForVotingPowerSnapshot(common.HexToAddress(avsAddr), snapshotHeight) + err = k.SetVotingPowerSnapshot(cc, snapshotKey, &votingPowerSnapshot) + if err != nil { + return err + } + } writeFunc() return nil } +func (k *Keeper) ClearVotingPowerSnapshot(ctx sdk.Context, avs string) error { + // calculate the time before which the snapshot should be cleared. + unbondingDuration, err := k.avsKeeper.GetAVSUnbondingDuration(ctx, avs) + if err != nil { + return operatortypes.ErrFailToClearVPSnapshot.Wrapf("ClearVotingPowerSnapshot: failed to get the avs unbonding duration, err:%s, avs:%s", err, avs) + } + epochInfo, err := k.avsKeeper.GetAVSEpochInfo(ctx, avs) + if err != nil { + return operatortypes.ErrFailToClearVPSnapshot.Wrapf("ClearVotingPowerSnapshot: failed to get the avs epoch information, err:%s, avs:%s", err, avs) + } + clearEpochNumber := epochInfo.CurrentEpoch - int64(unbondingDuration) // #nosec G115 + if clearEpochNumber < 0 { + return nil + } + err = k.RemoveVotingPowerSnapshot(ctx, avs, clearEpochNumber) + if err != nil { + ctx.Logger().Error("Failed to remove voting power snapshot", "avs", avs, "error", err) + return operatortypes.ErrFailToClearVPSnapshot.Wrapf("ClearVotingPowerSnapshot: failed to remove voting power snapshot, err:%s, avs:%s", err, avs) + } + return nil +} + // EndBlock : update the assets' share when their prices change func (k *Keeper) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index c0444b60a..8cef55b3d 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -2,11 +2,17 @@ package keeper import ( "context" + "encoding/binary" "errors" + "fmt" + "math" "strings" - keytypes "github.com/ExocoreNetwork/exocore/types/keys" + "github.com/ethereum/go-ethereum/common" + assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" + + keytypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -338,3 +344,58 @@ func (k *Keeper) Validator(c context.Context, req *types.QueryValidatorRequest) return &types.QueryValidatorResponse{Validator: val}, nil } + +func (k *Keeper) QuerySnapshotHelper(goCtx context.Context, req *types.QuerySnapshotHelperRequest) (*types.SnapshotHelper, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + snapshotHelper, err := k.GetSnapshotHelper(ctx, strings.ToLower(req.Avs)) + if err != nil { + return nil, err + } + return &snapshotHelper, nil +} + +func (k *Keeper) QuerySpecifiedSnapshot(goCtx context.Context, req *types.QuerySpecifiedSnapshotRequest) (*types.VotingPowerSnapshotKeyHeight, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + findHeight, snapshot, err := k.LoadVotingPowerSnapshot(ctx, strings.ToLower(req.Avs), req.Height) + if err != nil { + return nil, err + } + return &types.VotingPowerSnapshotKeyHeight{ + SnapshotKeyHeight: findHeight, + Snapshot: snapshot, + }, nil +} + +func (k *Keeper) QueryAllSnapshot(goCtx context.Context, req *types.QueryAllSnapshotRequest) (*types.QueryAllSnapshotResponse, error) { + if !common.IsHexAddress(req.Avs) { + return nil, fmt.Errorf("invalid AVS address format: %s", req.Avs) + } + ctx := sdk.UnwrapSDKContext(goCtx) + res := make([]*types.VotingPowerSnapshotKeyHeight, 0) + + snapshotPrefix := types.AppendMany(types.KeyPrefixVotingPowerSnapshot, common.HexToAddress(req.Avs).Bytes()) + store := prefix.NewStore(ctx.KVStore(k.storeKey), snapshotPrefix) + pageRes, err := query.Paginate(store, req.Pagination, func(key []byte, value []byte) error { + ret := &types.VotingPowerSnapshot{} + // don't use MustUnmarshal to not panic for queries + if err := ret.Unmarshal(value); err != nil { + return err + } + height := binary.BigEndian.Uint64(key) + if height > math.MaxInt64 { + return fmt.Errorf("height exceeds int64 max value: %d", height) + } + res = append(res, &types.VotingPowerSnapshotKeyHeight{ + SnapshotKeyHeight: int64(height), + Snapshot: ret, + }) + return nil + }) + if err != nil { + return nil, err + } + return &types.QueryAllSnapshotResponse{ + Snapshots: res, + Pagination: pageRes, + }, nil +} diff --git a/x/operator/keeper/impl_epoch_hook.go b/x/operator/keeper/impl_epoch_hook.go index 432b6333f..c25279ee4 100644 --- a/x/operator/keeper/impl_epoch_hook.go +++ b/x/operator/keeper/impl_epoch_hook.go @@ -30,12 +30,19 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( avsList := wrapper.keeper.avsKeeper.GetEpochEndAVSs(ctx, epochIdentifier, epochNumber) for _, avs := range avsList { // avs address is checksummed hex, we should convert it to lowercase - err := wrapper.keeper.UpdateVotingPower(ctx, avs) + err := wrapper.keeper.UpdateVotingPower(ctx, avs, epochIdentifier, epochNumber, false) if err != nil { ctx.Logger().Error("Failed to update voting power", "avs", avs, "error", err) // Handle the error gracefully, continue to the next AVS continue } + // clear the expired voting power snapshot. + err = wrapper.keeper.ClearVotingPowerSnapshot(ctx, avs) + if err != nil { + ctx.Logger().Error("Failed to clear voting power snapshot", "avs", avs, "error", err) + // Handle the error gracefully, continue to the next AVS + continue + } } } diff --git a/x/operator/keeper/operator.go b/x/operator/keeper/operator.go index 3e8f65196..cefba2219 100644 --- a/x/operator/keeper/operator.go +++ b/x/operator/keeper/operator.go @@ -180,21 +180,83 @@ func (k *Keeper) IsActive(ctx sdk.Context, operatorAddr sdk.AccAddress, avsAddr return true } -func (k *Keeper) GetOptedInAVSForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { +func (k *Keeper) IterateOptInfo(ctx sdk.Context, isUpdate bool, iteratePrefix []byte, opFunc func(key []byte, optedInfo *operatortypes.OptedInfo) error) error { // get all opted-in info store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) - iterator := sdk.KVStorePrefixIterator(store, []byte(operatorAddr)) + iterator := sdk.KVStorePrefixIterator(store, iteratePrefix) defer iterator.Close() - avsList := make([]string, 0) for ; iterator.Valid(); iterator.Next() { - keys, err := assetstype.ParseJoinedStoreKey(iterator.Key(), 2) + var optedInfo operatortypes.OptedInfo + k.cdc.MustUnmarshal(iterator.Value(), &optedInfo) + err := opFunc(iterator.Key(), &optedInfo) if err != nil { - return nil, err + return err + } + if isUpdate { + bz := k.cdc.MustMarshal(&optedInfo) + store.Set(iterator.Key(), bz) } - if k.IsOptedIn(ctx, keys[0], keys[1]) { + } + return nil +} + +func (k *Keeper) GetOptedInAVSForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { + avsList := make([]string, 0) + opFunc := func(key []byte, optedInfo *operatortypes.OptedInfo) error { + if optedInfo.OptedOutHeight == operatortypes.DefaultOptedOutHeight { + keys, err := assetstype.ParseJoinedStoreKey(key, 2) + if err != nil { + return err + } avsList = append(avsList, keys[1]) } + return nil + } + err := k.IterateOptInfo(ctx, false, []byte(operatorAddr), opFunc) + if err != nil { + return nil, err + } + return avsList, nil +} + +func (k *Keeper) GetImpactfulAVSForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { + avsList := make([]string, 0) + opFunc := func(key []byte, optedInfo *operatortypes.OptedInfo) error { + keys, err := assetstype.ParseJoinedStoreKey(key, 2) + avsAddr := keys[1] + if err != nil { + return err + } + // add AVS currently opting in to the operator's list. + if optedInfo.OptedOutHeight == operatortypes.DefaultOptedOutHeight { + avsList = append(avsList, avsAddr) + } else { + // Add AVS that have opted out but are still within the unbonding duration, + // and therefore still affect the operator, to the list. + // #nosec G115 + epochNumber, err := k.GetEpochNumberByOptOutHeight(ctx, avsAddr, int64(optedInfo.OptedOutHeight)) + if err != nil { + return err + } + epochInfo, err := k.avsKeeper.GetAVSEpochInfo(ctx, avsAddr) + if err != nil { + return err + } + unbondingDuration, err := k.avsKeeper.GetAVSUnbondingDuration(ctx, avsAddr) + if err != nil { + return err + } + // #nosec G115 + if epochNumber >= epochInfo.CurrentEpoch-int64(unbondingDuration) { + avsList = append(avsList, avsAddr) + } + } + return nil + } + err := k.IterateOptInfo(ctx, false, []byte(operatorAddr), opFunc) + if err != nil { + return nil, err } return avsList, nil } @@ -210,37 +272,38 @@ func (k *Keeper) SetAllOptedInfo(ctx sdk.Context, optedStates []operatortypes.Op } func (k *Keeper) GetAllOptedInfo(ctx sdk.Context) ([]operatortypes.OptedState, error) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) - iterator := sdk.KVStorePrefixIterator(store, []byte{}) - defer iterator.Close() - ret := make([]operatortypes.OptedState, 0) - for ; iterator.Valid(); iterator.Next() { - var optedInfo operatortypes.OptedInfo - k.cdc.MustUnmarshal(iterator.Value(), &optedInfo) + opFunc := func(key []byte, optedInfo *operatortypes.OptedInfo) error { ret = append(ret, operatortypes.OptedState{ - Key: string(iterator.Key()), - OptInfo: optedInfo, + Key: string(key), + OptInfo: *optedInfo, }) + return nil + } + err := k.IterateOptInfo(ctx, false, []byte{}, opFunc) + if err != nil { + return nil, err } return ret, nil } func (k *Keeper) GetOptedInOperatorListByAVS(ctx sdk.Context, avsAddr string) ([]string, error) { - // get all opted-in info - store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) - iterator := sdk.KVStorePrefixIterator(store, nil) - defer iterator.Close() - operatorList := make([]string, 0) - for ; iterator.Valid(); iterator.Next() { - keys, err := assetstype.ParseJoinedStoreKey(iterator.Key(), 2) - if err != nil { - return nil, err - } - if strings.ToLower(avsAddr) == keys[1] && k.IsOptedIn(ctx, keys[0], keys[1]) { - operatorList = append(operatorList, keys[0]) + opFunc := func(key []byte, optedInfo *operatortypes.OptedInfo) error { + if optedInfo.OptedOutHeight == operatortypes.DefaultOptedOutHeight { + keys, err := assetstype.ParseJoinedStoreKey(key, 2) + if err != nil { + return err + } + if strings.ToLower(avsAddr) == keys[1] { + operatorList = append(operatorList, keys[0]) + } } + return nil + } + err := k.IterateOptInfo(ctx, false, []byte{}, opFunc) + if err != nil { + return nil, err } return operatorList, nil } diff --git a/x/operator/keeper/operator_info_test.go b/x/operator/keeper/operator_info_test.go index 8570181a6..8ec37b4bb 100644 --- a/x/operator/keeper/operator_info_test.go +++ b/x/operator/keeper/operator_info_test.go @@ -1,8 +1,6 @@ package keeper_test import ( - "fmt" - "cosmossdk.io/math" operatortype "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -17,13 +15,12 @@ func (suite *OperatorTestSuite) TestOperatorInfo() { OperatorMetaInfo: "test operator", ClientChainEarningsAddr: &operatortype.ClientChainEarningAddrList{ EarningInfoList: []*operatortype.ClientChainEarningAddrInfo{ - {101, "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"}, + {defaultClientChainID, "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"}, }, }, Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()), } suite.Equal(operatortype.AccAddressLength, len(suite.AccAddress)) - fmt.Println("the acc address length is:", len(suite.AccAddress)) err := suite.App.OperatorKeeper.SetOperatorInfo(suite.Ctx, suite.AccAddress.String(), info) suite.NoError(err) diff --git a/x/operator/keeper/operator_slash_state.go b/x/operator/keeper/operator_slash_state.go index 72296f7c7..467a1702b 100644 --- a/x/operator/keeper/operator_slash_state.go +++ b/x/operator/keeper/operator_slash_state.go @@ -107,7 +107,7 @@ func (k *Keeper) UpdateSlashAssetsState(ctx sdk.Context, assetID, stakerOrOperat } key = assetstype.GetJoinedStoreKey(hexutil.EncodeUint64(processedHeight), assetID, stakerOrOperator) - slashAmount := assetstype.ValueField{Amount: sdkmath.NewInt(0)} + slashAmount := assetstype.ValueField{Amount: sdkmath.ZeroInt()} value := store.Get(key) if value != nil { k.cdc.MustUnmarshal(value, &slashAmount) @@ -121,7 +121,7 @@ func (k *Keeper) UpdateSlashAssetsState(ctx sdk.Context, assetID, stakerOrOperat store.Set(key, bz) key = assetstype.GetJoinedStoreKey(hexutil.EncodeUint64(processedHeight), assetID) - totalSlashAmount := assetstype.ValueField{Amount: sdkmath.NewInt(0)} + totalSlashAmount := assetstype.ValueField{Amount: sdkmath.ZeroInt()} value = store.Get(key) if value != nil { k.cdc.MustUnmarshal(value, &totalSlashAmount) diff --git a/x/operator/keeper/opt.go b/x/operator/keeper/opt.go index 9128a9ad6..9a4989435 100644 --- a/x/operator/keeper/opt.go +++ b/x/operator/keeper/opt.go @@ -145,5 +145,11 @@ func (k *Keeper) OptOut(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr if err != nil { return err } + + // mark opt out in the snapshot helper + err = k.SetOptOutFlag(ctx, avsAddr, true) + if err != nil { + return err + } return nil } diff --git a/x/operator/keeper/opt_test.go b/x/operator/keeper/opt_test.go index 56e54a175..ec79e0305 100644 --- a/x/operator/keeper/opt_test.go +++ b/x/operator/keeper/opt_test.go @@ -4,12 +4,12 @@ import ( "strings" "time" - assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" - epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + "github.com/ExocoreNetwork/exocore/x/epochs/types" sdkmath "cosmossdk.io/math" + assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" + avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper" operatorTypes "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -26,49 +26,51 @@ type StateForCheck struct { StakerShare sdkmath.LegacyDec } -func (suite *OperatorTestSuite) prepareOperator() { - opAccAddr, err := sdk.AccAddressFromBech32("exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkjr") - suite.operatorAddr = opAccAddr - suite.NoError(err) +func (suite *OperatorTestSuite) registerOperator(operator string) { // register operator registerReq := &operatorTypes.RegisterOperatorReq{ - FromAddress: suite.operatorAddr.String(), + FromAddress: operator, Info: &operatorTypes.OperatorInfo{ - EarningsAddr: suite.operatorAddr.String(), + EarningsAddr: operator, }, } - _, err = s.OperatorMsgServer.RegisterOperator(s.Ctx, registerReq) + _, err := s.OperatorMsgServer.RegisterOperator(s.Ctx, registerReq) suite.NoError(err) } -func (suite *OperatorTestSuite) prepareDeposit(assetAddr common.Address, amount sdkmath.Int) { - clientChainLzID := uint64(101) - suite.avsAddr = common.BytesToAddress([]byte("avsTestAddr")).String() +func (suite *OperatorTestSuite) prepareOperator() { + operator := "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkjr" + opAccAddr, err := sdk.AccAddressFromBech32(operator) + suite.operatorAddr = opAccAddr + suite.NoError(err) + // register operator + suite.registerOperator(operator) +} + +func (suite *OperatorTestSuite) prepareDeposit(stakerAddr, assetAddr common.Address, amount sdkmath.Int) { suite.assetAddr = assetAddr - suite.assetDecimal = 6 - suite.clientChainLzID = clientChainLzID - suite.depositAmount = amount - suite.updatedAmountForOptIn = sdkmath.NewInt(20) - suite.stakerID, suite.assetID = assetstypes.GetStakerIDAndAssetID(suite.clientChainLzID, suite.Address[:], suite.assetAddr[:]) + suite.assetDecimal = uint32(assetDecimal) + suite.clientChainLzID = defaultClientChainID + suite.stakerID, suite.assetID = assetstypes.GetStakerIDAndAssetID(suite.clientChainLzID, stakerAddr[:], assetAddr[:]) // staking assets depositParam := &assetskeeper.DepositWithdrawParams{ ClientChainLzID: suite.clientChainLzID, Action: assetstypes.DepositLST, - StakerAddress: suite.Address[:], - OpAmount: suite.depositAmount, + StakerAddress: stakerAddr[:], + OpAmount: amount, AssetsAddress: assetAddr[:], } err := suite.App.AssetsKeeper.PerformDepositOrWithdraw(suite.Ctx, depositParam) suite.NoError(err) } -func (suite *OperatorTestSuite) prepareDelegation(isDelegation bool, assetAddr common.Address, amount sdkmath.Int) { +func (suite *OperatorTestSuite) prepareDelegation(isDelegation bool, staker, assetAddr common.Address, operator sdk.AccAddress, amount sdkmath.Int) { suite.delegationAmount = amount param := &delegationtype.DelegationOrUndelegationParams{ ClientChainID: suite.clientChainLzID, AssetsAddress: assetAddr[:], - OperatorAddress: suite.operatorAddr, - StakerAddress: suite.Address[:], + OperatorAddress: operator, + StakerAddress: staker[:], OpAmount: amount, LzNonce: 0, TxHash: common.HexToHash("0x24c4a315d757249c12a7a1d7b6fb96261d49deee26f06a3e1787d008b445c3ac"), @@ -83,20 +85,21 @@ func (suite *OperatorTestSuite) prepareDelegation(isDelegation bool, assetAddr c } func (suite *OperatorTestSuite) prepare() { - usdtAddress := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7") depositAmount := sdkmath.NewInt(100) delegationAmount := sdkmath.NewInt(50) suite.prepareOperator() - suite.prepareDeposit(usdtAddress, depositAmount) - suite.prepareDelegation(true, usdtAddress, delegationAmount) + suite.prepareDeposit(suite.Address, usdtAddr, depositAmount) + suite.prepareDelegation(true, suite.Address, usdtAddr, suite.operatorAddr, delegationAmount) } -func (suite *OperatorTestSuite) prepareAvs(assetIDs []string) { +func (suite *OperatorTestSuite) prepareAvs(assetIDs []string, epochIdentifier string) { + suite.avsAddr = common.BytesToAddress([]byte("avsTestAddr")).String() err := suite.App.AVSManagerKeeper.UpdateAVSInfo(suite.Ctx, &avstypes.AVSRegisterOrDeregisterParams{ Action: avstypes.RegisterAction, - EpochIdentifier: epochstypes.HourEpochID, + EpochIdentifier: epochIdentifier, AvsAddress: common.HexToAddress(suite.avsAddr), AssetID: assetIDs, + UnbondingPeriod: 5, }) suite.NoError(err) } @@ -130,7 +133,7 @@ func (suite *OperatorTestSuite) CheckState(expectedState *StateForCheck) { func (suite *OperatorTestSuite) TestOptIn() { suite.prepare() - suite.prepareAvs([]string{"0xdac17f958d2ee523a2206206994597c13d831ec7_0x65"}) + suite.prepareAvs([]string{usdtAssetID}, types.HourEpochID) err := suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, suite.avsAddr) suite.NoError(err) // check if the related state is correct @@ -158,7 +161,7 @@ func (suite *OperatorTestSuite) TestOptIn() { func (suite *OperatorTestSuite) TestOptInList() { suite.prepare() - suite.prepareAvs([]string{"0xdac17f958d2ee523a2206206994597c13d831ec7_0x65"}) + suite.prepareAvs([]string{usdtAssetID}, types.HourEpochID) err := suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, suite.avsAddr) suite.NoError(err) // check if the related state is correct @@ -174,7 +177,7 @@ func (suite *OperatorTestSuite) TestOptInList() { func (suite *OperatorTestSuite) TestOptOut() { suite.prepare() - suite.prepareAvs([]string{"0xdac17f958d2ee523a2206206994597c13d831ec7_0x65"}) + suite.prepareAvs([]string{usdtAssetID}, types.HourEpochID) err := suite.App.OperatorKeeper.OptOut(suite.Ctx, suite.operatorAddr, suite.avsAddr) suite.EqualError(err, operatorTypes.ErrNotOptedIn.Error()) @@ -191,8 +194,8 @@ func (suite *OperatorTestSuite) TestOptOut() { OptedInHeight: uint64(optInHeight), OptedOutHeight: uint64(suite.Ctx.BlockHeight()), }, - AVSTotalShare: sdkmath.LegacyNewDec(0), - AVSOperatorShare: sdkmath.LegacyNewDec(0), + AVSTotalShare: sdkmath.LegacyZeroDec(), + AVSOperatorShare: sdkmath.LegacyZeroDec(), AssetState: nil, OperatorShare: sdkmath.LegacyDec{}, StakerShare: sdkmath.LegacyDec{}, diff --git a/x/operator/keeper/setup_test.go b/x/operator/keeper/setup_test.go index efb6ca9d3..8474f0251 100644 --- a/x/operator/keeper/setup_test.go +++ b/x/operator/keeper/setup_test.go @@ -18,16 +18,14 @@ type OperatorTestSuite struct { testutil.BaseTestSuite // needed by test - operatorAddr sdk.AccAddress - avsAddr string - assetID string - stakerID string - assetAddr common.Address - assetDecimal uint32 - clientChainLzID uint64 - depositAmount sdkmath.Int - delegationAmount sdkmath.Int - updatedAmountForOptIn sdkmath.Int + operatorAddr sdk.AccAddress + avsAddr string + assetID string + stakerID string + assetAddr common.Address + assetDecimal uint32 + clientChainLzID uint64 + delegationAmount sdkmath.Int } func TestOperatorTestSuite(t *testing.T) { diff --git a/x/operator/keeper/slash.go b/x/operator/keeper/slash.go index 1f1c6a58d..ab6188f06 100644 --- a/x/operator/keeper/slash.go +++ b/x/operator/keeper/slash.go @@ -7,7 +7,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/ethereum/go-ethereum/common/hexutil" - errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" @@ -32,7 +31,7 @@ func SlashFromUndelegation(undelegation *delegationtype.UndelegationRecord, slas // reduce the actual_completed_amount in the record if slashAmount.GTE(undelegation.ActualCompletedAmount) { slashAmount = undelegation.ActualCompletedAmount - undelegation.ActualCompletedAmount = sdkmath.NewInt(0) + undelegation.ActualCompletedAmount = sdkmath.ZeroInt() } else { undelegation.ActualCompletedAmount = undelegation.ActualCompletedAmount.Sub(slashAmount) } @@ -46,22 +45,21 @@ func SlashFromUndelegation(undelegation *delegationtype.UndelegationRecord, slas func (k *Keeper) CheckSlashParameter(ctx sdk.Context, parameter *types.SlashInputInfo) error { if parameter.SlashProportion.IsNil() || parameter.SlashProportion.IsNegative() { - return errorsmod.Wrapf(types.ErrValueIsNilOrZero, "Invalid SlashProportion; expected non-nil and non-negative, got: %+v", parameter.SlashProportion) + return types.ErrValueIsNilOrZero.Wrapf("Invalid SlashProportion; expected non-nil and non-negative, got: %+v", parameter.SlashProportion) } height := ctx.BlockHeight() if parameter.SlashEventHeight > height { - return errorsmod.Wrapf(types.ErrSlashOccurredHeight, "slashEventHeight:%d,curHeight:%d", parameter.SlashEventHeight, height) + return types.ErrSlashOccurredHeight.Wrapf("slashEventHeight:%d,curHeight:%d", parameter.SlashEventHeight, height) } if parameter.IsDogFood { if parameter.Power <= 0 { - return errorsmod.Wrapf(types.ErrInvalidSlashPower, "slash for dogfood, the power is:%v", parameter.Power) + return types.ErrInvalidSlashPower.Wrapf("slash for dogfood, the power is:%v", parameter.Power) } } else { if parameter.Power != 0 { - return errorsmod.Wrapf(types.ErrInvalidSlashPower, "slash for other AVSs, the power is:%v", parameter.Power) + return types.ErrInvalidSlashPower.Wrapf("slash for other AVSs, the input power should be zero, power:%v", parameter.Power) } - // todo: get the historical voting power from the snapshot for the other AVSs } return nil } @@ -71,7 +69,7 @@ func (k *Keeper) CheckSlashParameter(ctx sdk.Context, parameter *types.SlashInpu // If the remaining amount of the assets pool after slash is zero, the share of related // stakers should be cleared, because the divisor will be zero when calculating the share // of new delegation after the slash. -func (k *Keeper) SlashAssets(ctx sdk.Context, parameter *types.SlashInputInfo) (*types.SlashExecutionInfo, error) { +func (k *Keeper) SlashAssets(ctx sdk.Context, snapshotHeight int64, parameter *types.SlashInputInfo) (*types.SlashExecutionInfo, error) { // calculate the new slash proportion according to the historical power and current assets state slashUSDValue := sdkmath.LegacyNewDec(parameter.Power).Mul(parameter.SlashProportion) // calculate the current usd value of all assets pool for the operator @@ -84,10 +82,11 @@ func (k *Keeper) SlashAssets(ctx sdk.Context, parameter *types.SlashInputInfo) ( newSlashProportion = sdkmath.LegacyMinDec(sdkmath.LegacyNewDec(1), newSlashProportion) executionInfo := &types.SlashExecutionInfo{ - SlashProportion: newSlashProportion, - SlashValue: slashUSDValue, - SlashUndelegations: make([]types.SlashFromUndelegation, 0), - SlashAssetsPool: make([]types.SlashFromAssetsPool, 0), + SlashProportion: newSlashProportion, + SlashValue: slashUSDValue, + SlashUndelegations: make([]types.SlashFromUndelegation, 0), + SlashAssetsPool: make([]types.SlashFromAssetsPool, 0), + UndelegationFilterHeight: snapshotHeight, } // slash from the unbonding stakers if parameter.SlashEventHeight < ctx.BlockHeight() { @@ -100,7 +99,7 @@ func (k *Keeper) SlashAssets(ctx sdk.Context, parameter *types.SlashInputInfo) ( return nil } // #nosec G701 - heightFilter := uint64(parameter.SlashEventHeight) + heightFilter := uint64(snapshotHeight) err = k.delegationKeeper.IterateUndelegationsByOperator(ctx, parameter.Operator.String(), &heightFilter, true, opFunc) if err != nil { return nil, err @@ -132,8 +131,8 @@ func (k *Keeper) SlashAssets(ctx sdk.Context, parameter *types.SlashInputInfo) ( if err != nil { return err } - state.TotalShare = sdkmath.LegacyNewDec(0) - state.OperatorShare = sdkmath.LegacyNewDec(0) + state.TotalShare = sdkmath.LegacyZeroDec() + state.OperatorShare = sdkmath.LegacyZeroDec() } state.TotalAmount = remainingAmount executionInfo.SlashAssetsPool = append(executionInfo.SlashAssetsPool, types.SlashFromAssetsPool{ @@ -155,11 +154,30 @@ func (k *Keeper) Slash(ctx sdk.Context, parameter *types.SlashInputInfo) error { if err != nil { return err } + snapshotKeyLastHeight, snapshot, err := k.LoadVotingPowerSnapshot(ctx, parameter.AVSAddr, parameter.SlashEventHeight) + if err != nil { + return err + } + // get the historical voting power from the snapshot for the other AVSs + if !parameter.IsDogFood { + votingPower := types.GetSpecifiedVotingPower(parameter.Operator.String(), snapshot.OperatorVotingPowers) + if votingPower == nil { + return types.ErrFailToGetHistoricalVP.Wrapf("slash: the operator isn't in the voting power set, addr:%s", parameter.Operator) + } + parameter.Power = votingPower.VotingPower.TruncateInt64() + if parameter.Power < 0 { + return types.ErrInvalidSlashPower.Wrapf("slash: invalid voting power, power:%v", parameter.Power) + } + } + if parameter.Power == 0 { + k.Logger(ctx).Info("don't execute the slash if the historical voting power is zero") + return nil + } // slash assets according to the input information // using cache context to ensure the atomicity of slash execution. cc, writeFunc := ctx.CacheContext() - executionInfo, err := k.SlashAssets(cc, parameter) + executionInfo, err := k.SlashAssets(cc, snapshotKeyLastHeight, parameter) if err != nil { return err } @@ -178,6 +196,24 @@ func (k *Keeper) Slash(ctx sdk.Context, parameter *types.SlashInputInfo) error { if err != nil { return err } + + // update the voting power and save the snapshot for all affected AVSs + affectedAVSList, err := k.GetImpactfulAVSForOperator(ctx, parameter.Operator.String()) + if err != nil { + return err + } + for i := range affectedAVSList { + avs := affectedAVSList[i] + epochInfo, err := k.avsKeeper.GetAVSEpochInfo(ctx, avs) + if err != nil { + return err + } + err = k.UpdateVotingPower(ctx, avs, epochInfo.Identifier, epochInfo.CurrentEpoch, true) + if err != nil { + return err + } + } + k.hooks.AfterSlash(ctx, parameter.Operator, affectedAVSList) return nil } @@ -190,7 +226,7 @@ func (k Keeper) SlashWithInfractionReason( isAvs, avsAddr := k.avsKeeper.IsAVSByChainID(ctx, chainID) if !isAvs { k.Logger(ctx).Error("the chainID is not supported by AVS", "chainID", chainID) - return sdkmath.NewInt(0) + return sdkmath.ZeroInt() } slashID := GetSlashIDForDogfood(infraction, infractionHeight) slashParam := &types.SlashInputInfo{ @@ -206,11 +242,11 @@ func (k Keeper) SlashWithInfractionReason( err := k.Slash(ctx, slashParam) if err != nil { k.Logger(ctx).Error("error when executing slash", "error", err, "avsAddr", avsAddr) - return sdkmath.NewInt(0) + return sdkmath.ZeroInt() } // todo: The returned value should be the amount of burned Exo if we considering a slash from the reward // Now it doesn't slash from the reward, so just return 0 - return sdkmath.NewInt(0) + return sdkmath.ZeroInt() } // IsOperatorJailedForChainID returns whether an operator is jailed for a specific chainID. diff --git a/x/operator/keeper/slash_test.go b/x/operator/keeper/slash_test.go index afef3db5b..cc66f7ee8 100644 --- a/x/operator/keeper/slash_test.go +++ b/x/operator/keeper/slash_test.go @@ -9,18 +9,16 @@ import ( "github.com/ExocoreNetwork/exocore/x/operator/types" abci "github.com/cometbft/cometbft/abci/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/common" ) func (suite *OperatorTestSuite) TestSlashWithInfractionReason() { + // current height: 1 epoch: 1 // prepare the deposit and delegation suite.prepareOperator() - usdtAddress := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7") - assetDecimal := 6 depositAmount := sdkmath.NewIntWithDecimal(200, assetDecimal) - suite.prepareDeposit(usdtAddress, depositAmount) + suite.prepareDeposit(suite.Address, usdtAddr, depositAmount) delegationAmount := sdkmath.NewIntWithDecimal(100, assetDecimal) - suite.prepareDelegation(true, suite.assetAddr, delegationAmount) + suite.prepareDelegation(true, suite.Address, suite.assetAddr, suite.operatorAddr, delegationAmount) err := suite.App.DelegationKeeper.AssociateOperatorWithStaker(suite.Ctx, suite.clientChainLzID, suite.operatorAddr, suite.Address[:]) suite.NoError(err) @@ -28,35 +26,46 @@ func (suite *OperatorTestSuite) TestSlashWithInfractionReason() { avsAddr := avstypes.GenerateAVSAddr(avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID())) err = suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, avsAddr) suite.NoError(err) + // call the EndBlock to update the voting power suite.CommitAfter(time.Hour*24 + time.Nanosecond) - infractionHeight := suite.Ctx.BlockHeight() + + // current height: 2 epoch: 2 optedUSDValues, err := suite.App.OperatorKeeper.GetOperatorOptedUSDValue(suite.Ctx, avsAddr, suite.operatorAddr.String()) suite.NoError(err) // get the historical voting power power := optedUSDValues.TotalUSDValue.TruncateInt64() // run to next block suite.NextBlock() + // current height: 3 epoch: 2 + infractionHeight := suite.Ctx.BlockHeight() + // undelegationFilterHeight should be the first height of this epoch, it should be 2 + undelegationFilterHeight := infractionHeight - 1 + suite.Equal(int64(3), infractionHeight) // delegates new amount to the operator newDelegateAmount := sdkmath.NewIntWithDecimal(20, assetDecimal) - suite.prepareDelegation(true, suite.assetAddr, newDelegateAmount) + suite.prepareDelegation(true, suite.Address, suite.assetAddr, suite.operatorAddr, newDelegateAmount) // updating the voting power suite.CommitAfter(time.Hour*24 + time.Nanosecond) + // current height: 4 epoch: 3 newOptedUSDValues, err := suite.App.OperatorKeeper.GetOperatorOptedUSDValue(suite.Ctx, avsAddr, suite.operatorAddr.String()) suite.NoError(err) // submits an undelegation to test the slashFromUndelegation undelegationAmount := sdkmath.NewIntWithDecimal(10, assetDecimal) - suite.prepareDelegation(false, suite.assetAddr, undelegationAmount) + suite.prepareDelegation(false, suite.Address, suite.assetAddr, suite.operatorAddr, undelegationAmount) delegationRemaining := delegationAmount.Add(newDelegateAmount).Sub(undelegationAmount) startHeight := uint64(suite.Ctx.BlockHeight()) completedHeight := suite.App.OperatorKeeper.GetUnbondingExpirationBlockNumber(suite.Ctx, suite.operatorAddr, startHeight) // trigger the slash with a downtime event + // run to next block + suite.CommitAfter(time.Hour + time.Nanosecond) + // current height: 5 epoch: 3 slashFactor := suite.App.SlashingKeeper.SlashFractionDowntime(suite.Ctx) slashType := stakingtypes.Infraction_INFRACTION_DOWNTIME exoSlashValue := suite.App.OperatorKeeper.SlashWithInfractionReason(suite.Ctx, suite.operatorAddr, infractionHeight, power, slashFactor, slashType) - suite.Equal(sdkmath.NewInt(0), exoSlashValue) + suite.Equal(sdkmath.ZeroInt(), exoSlashValue) // verify the state after the slash slashID := keeper.GetSlashIDForDogfood(slashType, infractionHeight) @@ -79,6 +88,7 @@ func (suite *OperatorTestSuite) TestSlashWithInfractionReason() { AssetID: suite.assetID, Amount: newSlashProportion.MulInt(delegationRemaining).TruncateInt(), }, slashInfo.ExecutionInfo.SlashAssetsPool[0]) + suite.Equal(undelegationFilterHeight, slashInfo.ExecutionInfo.UndelegationFilterHeight) // check the assets state of undelegation and assets pool assetsInfo, err := suite.App.AssetsKeeper.GetOperatorSpecifiedAssetInfo(suite.Ctx, suite.operatorAddr, suite.assetID) diff --git a/x/operator/keeper/usd_value.go b/x/operator/keeper/usd_value.go index 16fb42e44..b277bec05 100644 --- a/x/operator/keeper/usd_value.go +++ b/x/operator/keeper/usd_value.go @@ -31,9 +31,9 @@ func (k *Keeper) UpdateOperatorUSDValue(ctx sdk.Context, avsAddr, operatorAddr s key = assetstype.GetJoinedStoreKey(strings.ToLower(avsAddr), operatorAddr) usdInfo := operatortypes.OperatorOptedUSDValue{ - SelfUSDValue: sdkmath.LegacyNewDec(0), - TotalUSDValue: sdkmath.LegacyNewDec(0), - ActiveUSDValue: sdkmath.LegacyNewDec(0), + SelfUSDValue: sdkmath.LegacyZeroDec(), + TotalUSDValue: sdkmath.LegacyZeroDec(), + ActiveUSDValue: sdkmath.LegacyZeroDec(), } value := store.Get(key) if value != nil { @@ -68,9 +68,9 @@ func (k *Keeper) InitOperatorUSDValue(ctx sdk.Context, avsAddr, operatorAddr str return errorsmod.Wrap(operatortypes.ErrKeyAlreadyExist, fmt.Sprintf("avsAddr operatorAddr is: %s, %s", avsAddr, operatorAddr)) } initValue := operatortypes.OperatorOptedUSDValue{ - SelfUSDValue: sdkmath.LegacyNewDec(0), - TotalUSDValue: sdkmath.LegacyNewDec(0), - ActiveUSDValue: sdkmath.LegacyNewDec(0), + SelfUSDValue: sdkmath.LegacyZeroDec(), + TotalUSDValue: sdkmath.LegacyZeroDec(), + ActiveUSDValue: sdkmath.LegacyZeroDec(), } bz := k.cdc.MustMarshal(&initValue) store.Set(key, bz) @@ -115,9 +115,9 @@ func (k *Keeper) GetOperatorOptedUSDValue(ctx sdk.Context, avsAddr, operatorAddr // return zero if the operator has opted-out of the AVS if !k.IsOptedIn(ctx, operatorAddr, avsAddr) { return operatortypes.OperatorOptedUSDValue{ - SelfUSDValue: sdkmath.LegacyNewDec(0), - TotalUSDValue: sdkmath.LegacyNewDec(0), - ActiveUSDValue: sdkmath.LegacyNewDec(0), + SelfUSDValue: sdkmath.LegacyZeroDec(), + TotalUSDValue: sdkmath.LegacyZeroDec(), + ActiveUSDValue: sdkmath.LegacyZeroDec(), }, nil } @@ -149,7 +149,7 @@ func (k *Keeper) UpdateAVSUSDValue(ctx sdk.Context, avsAddr string, opAmount sdk } store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixUSDValueForAVS) key := []byte(strings.ToLower(avsAddr)) - totalValue := operatortypes.DecValueField{Amount: sdkmath.LegacyNewDec(0)} + totalValue := operatortypes.DecValueField{Amount: sdkmath.LegacyZeroDec()} value := store.Get(key) if value != nil { k.cdc.MustUnmarshal(value, &totalValue) @@ -270,7 +270,7 @@ func (k *Keeper) SetAllOperatorUSDValues(ctx sdk.Context, usdValues []operatorty for i := range usdValues { usdValue := usdValues[i] bz := k.cdc.MustMarshal(&usdValue.OptedUSDValue) - store.Set([]byte(usdValue.Key), bz) + store.Set([]byte(strings.ToLower(usdValue.Key)), bz) } return nil } @@ -302,19 +302,42 @@ func (k *Keeper) SetAllAVSUSDValues(ctx sdk.Context, usdValues []operatortypes.A return nil } -func (k *Keeper) GetAllAVSUSDValues(ctx sdk.Context) ([]operatortypes.AVSUSDValue, error) { +func (k *Keeper) IterateAVSUSDValues(ctx sdk.Context, isUpdate bool, opFunc func(avsAddr string, avsUSDValue *operatortypes.DecValueField) error) error { store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixUSDValueForAVS) iterator := sdk.KVStorePrefixIterator(store, []byte{}) defer iterator.Close() - ret := make([]operatortypes.AVSUSDValue, 0) for ; iterator.Valid(); iterator.Next() { var usdValue operatortypes.DecValueField k.cdc.MustUnmarshal(iterator.Value(), &usdValue) + err := opFunc(string(iterator.Key()), &usdValue) + if err != nil { + return err + } + if isUpdate { + bz := k.cdc.MustMarshal(&usdValue) + store.Set(iterator.Key(), bz) + } + } + return nil +} + +func (k *Keeper) GetAllAVSUSDValues(ctx sdk.Context) ([]operatortypes.AVSUSDValue, error) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixUSDValueForAVS) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + ret := make([]operatortypes.AVSUSDValue, 0) + opFunc := func(avsAddr string, avsUSDValue *operatortypes.DecValueField) error { ret = append(ret, operatortypes.AVSUSDValue{ - AVSAddr: string(iterator.Key()), - Value: usdValue, + AVSAddr: avsAddr, + Value: *avsUSDValue, }) + return nil + } + err := k.IterateAVSUSDValues(ctx, false, opFunc) + if err != nil { + return nil, err } return ret, nil } @@ -343,9 +366,9 @@ func (k *Keeper) CalculateUSDValueForOperator( ) (operatortypes.OperatorStakingInfo, error) { var err error ret := operatortypes.OperatorStakingInfo{ - Staking: sdkmath.LegacyNewDec(0), - SelfStaking: sdkmath.LegacyNewDec(0), - StakingAndWaitUnbonding: sdkmath.LegacyNewDec(0), + Staking: sdkmath.LegacyZeroDec(), + SelfStaking: sdkmath.LegacyZeroDec(), + StakingAndWaitUnbonding: sdkmath.LegacyZeroDec(), } // iterate all assets owned by the operator to calculate its voting power opFuncToIterateAssets := func(assetID string, state *assetstype.OperatorAssetInfo) error { @@ -440,14 +463,14 @@ func (k Keeper) GetOrCalculateOperatorUSDValues( func (k *Keeper) CalculateUSDValueForStaker(ctx sdk.Context, stakerID, avsAddr string, operator sdk.AccAddress) (sdkmath.LegacyDec, error) { if !k.IsActive(ctx, operator, avsAddr) { - return sdkmath.LegacyNewDec(0), nil + return sdkmath.LegacyZeroDec(), nil } optedUSDValues, err := k.GetOperatorOptedUSDValue(ctx, avsAddr, operator.String()) if err != nil { return sdkmath.LegacyDec{}, err } if optedUSDValues.ActiveUSDValue.IsZero() { - return sdkmath.LegacyNewDec(0), err + return sdkmath.LegacyZeroDec(), nil } // calculate the active voting power for staker @@ -456,7 +479,7 @@ func (k *Keeper) CalculateUSDValueForStaker(ctx sdk.Context, stakerID, avsAddr s return sdkmath.LegacyDec{}, err } if assets == nil { - return sdkmath.LegacyNewDec(0), nil + return sdkmath.LegacyZeroDec(), nil } prices, err := k.oracleKeeper.GetMultipleAssetsPrices(ctx, assets) // we don't ignore the error regarding the price round not found here, because it's used to @@ -467,7 +490,7 @@ func (k *Keeper) CalculateUSDValueForStaker(ctx sdk.Context, stakerID, avsAddr s if prices == nil { return sdkmath.LegacyDec{}, errorsmod.Wrap(operatortypes.ErrValueIsNilOrZero, "CalculateUSDValueForStaker prices map is nil") } - totalUSDValue := sdkmath.LegacyNewDec(0) + totalUSDValue := sdkmath.LegacyZeroDec() opFunc := func(keys *delegationtype.SingleDelegationInfoReq, amounts *delegationtype.DelegationAmounts) (bool, error) { // Return true to stop iteration, false to continue iterating if keys.OperatorAddr == operator.String() { diff --git a/x/operator/keeper/usd_value_test.go b/x/operator/keeper/usd_value_test.go index 116f3c6b4..9790379f6 100644 --- a/x/operator/keeper/usd_value_test.go +++ b/x/operator/keeper/usd_value_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "time" + "github.com/ExocoreNetwork/exocore/x/epochs/types" + sdkmath "cosmossdk.io/math" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -14,7 +16,15 @@ const ( MaxDecForTotalSupply = 38 ) -var MaxAssetTotalSupply = sdkmath.NewIntWithDecimal(1, MaxDecForTotalSupply) +var ( + MaxAssetTotalSupply = sdkmath.NewIntWithDecimal(1, MaxDecForTotalSupply) + defaultClientChainID = uint64(101) + assetDecimal = 6 + usdcAddr = common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48") + usdcAssetID = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48_0x65" + usdtAddr = common.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7") + usdtAssetID = "0xdac17f958d2ee523a2206206994597c13d831ec7_0x65" +) func (suite *OperatorTestSuite) TestCalculateUSDValue() { suite.prepare() @@ -49,7 +59,7 @@ func (suite *OperatorTestSuite) TestCalculatedUSDValueOverflow() { amount = sdkmath.NewInt(1) assetDecimal = uint32(assetstype.MaxDecimal) usdValue = operatorKeeper.CalculateUSDValue(amount, price, assetDecimal, priceDecimal) - expectedValue = sdkmath.LegacyNewDec(0) + expectedValue = sdkmath.LegacyZeroDec() suite.Equal(expectedValue.String(), usdValue.String()) price = sdkmath.NewInt(1) @@ -67,25 +77,24 @@ func (suite *OperatorTestSuite) TestCalculatedUSDValueOverflow() { func (suite *OperatorTestSuite) TestAVSUSDValue() { suite.prepare() // register the new token - usdcAddr := common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48") usdcClientChainAsset := assetstype.AssetInfo{ Name: "USD coin", Symbol: "USDC", Address: usdcAddr.String(), - Decimals: 6, - LayerZeroChainID: 101, + Decimals: uint32(assetDecimal), + LayerZeroChainID: defaultClientChainID, MetaInfo: "USDC", } err := suite.App.AssetsKeeper.SetStakingAssetInfo( suite.Ctx, &assetstype.StakingAssetInfo{ AssetBasicInfo: usdcClientChainAsset, - StakingTotalAmount: sdkmath.NewInt(0), + StakingTotalAmount: sdkmath.ZeroInt(), }, ) suite.NoError(err) // register the new AVS - suite.prepareAvs([]string{"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48_0x65", "0xdac17f958d2ee523a2206206994597c13d831ec7_0x65"}) + suite.prepareAvs([]string{usdcAssetID, usdtAssetID}, types.HourEpochID) // opt in err = suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, suite.avsAddr) suite.NoError(err) @@ -94,11 +103,11 @@ func (suite *OperatorTestSuite) TestAVSUSDValue() { usdtValue := operatorKeeper.CalculateUSDValue(suite.delegationAmount, usdtPrice.Value, suite.assetDecimal, usdtPrice.Decimal) // deposit and delegate another asset to the operator suite.NoError(err) - suite.prepareDeposit(usdcAddr, sdkmath.NewInt(1e8)) + suite.prepareDeposit(suite.Address, usdcAddr, sdkmath.NewInt(1e8)) usdcPrice, err := suite.App.OperatorKeeper.OracleInterface().GetSpecifiedAssetsPrice(suite.Ctx, suite.assetID) suite.NoError(err) delegatedAmount := sdkmath.NewIntWithDecimal(8, 7) - suite.prepareDelegation(true, usdcAddr, delegatedAmount) + suite.prepareDelegation(true, suite.Address, usdcAddr, suite.operatorAddr, delegatedAmount) // updating the new voting power usdcValue := operatorKeeper.CalculateUSDValue(suite.delegationAmount, usdcPrice.Value, suite.assetDecimal, usdcPrice.Decimal) @@ -143,14 +152,14 @@ func (suite *OperatorTestSuite) TestVotingPowerForDogFood() { assetAddr := common.HexToAddress(asset.Address) depositAmount := sdkmath.NewIntWithDecimal(2, int(asset.Decimals)) delegationAmount := sdkmath.NewIntWithDecimal(int64(addPower), int(asset.Decimals)) - suite.prepareDeposit(assetAddr, depositAmount) + suite.prepareDeposit(suite.Address, assetAddr, depositAmount) // the order here is unknown, so we need to check which operator has the highest power if powers[0] > powers[1] { suite.operatorAddr = operators[0] } else { suite.operatorAddr = operators[1] } - suite.prepareDelegation(true, assetAddr, delegationAmount) + suite.prepareDelegation(true, suite.Address, assetAddr, suite.operatorAddr, delegationAmount) optedUSDValues, err := suite.App.OperatorKeeper.GetOperatorOptedUSDValue(suite.Ctx, avsAddress, suite.operatorAddr.String()) suite.NoError(err) initialOperatorUSDValue := optedUSDValues.TotalUSDValue @@ -167,7 +176,7 @@ func (suite *OperatorTestSuite) TestVotingPowerForDogFood() { suite.NoError(err) suite.True(found) - suite.App.StakingKeeper.MarkEpochEnd(suite.Ctx) + suite.App.StakingKeeper.MarkUpdateValidatorSetFlag(suite.Ctx) validatorUpdates := suite.App.StakingKeeper.EndBlock(suite.Ctx) suite.Equal(1, len(validatorUpdates)) for i, update := range validatorUpdates { diff --git a/x/operator/keeper/voting_power_snapshot.go b/x/operator/keeper/voting_power_snapshot.go new file mode 100644 index 000000000..bd7f5f9c0 --- /dev/null +++ b/x/operator/keeper/voting_power_snapshot.go @@ -0,0 +1,285 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/operator/types" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" +) + +const InitialEpochNumber int64 = 1 + +func (k *Keeper) SetVotingPowerSnapshot(ctx sdk.Context, key []byte, snapshot *types.VotingPowerSnapshot) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + bz := k.cdc.MustMarshal(snapshot) + store.Set(key, bz) + return nil +} + +func (k *Keeper) GetVotingPowerSnapshot(ctx sdk.Context, key []byte) (*types.VotingPowerSnapshot, error) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + var ret types.VotingPowerSnapshot + value := store.Get(key) + if value == nil { + avsAddr, height, err := types.ParseVotingPowerSnapshotKey(key) + if err != nil { + return nil, err + } + return nil, types.ErrNoKeyInTheStore.Wrapf("GetVotingPowerSnapshot: invalid key, avs:%s height:%v", avsAddr, height) + } + k.cdc.MustUnmarshal(value, &ret) + return &ret, nil +} + +func (k *Keeper) IterateVotingPowerSnapshot(ctx sdk.Context, avsAddr string, isUpdate bool, opFunc func(height int64, snapshot *types.VotingPowerSnapshot) error) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + iterator := sdk.KVStorePrefixIterator(store, common.HexToAddress(avsAddr).Bytes()) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var snapshot types.VotingPowerSnapshot + k.cdc.MustUnmarshal(iterator.Value(), &snapshot) + _, height, err := types.ParseVotingPowerSnapshotKey(iterator.Key()) + if err != nil { + return err + } + err = opFunc(height, &snapshot) + if err != nil { + return err + } + if isUpdate { + bz := k.cdc.MustMarshal(&snapshot) + store.Set(iterator.Key(), bz) + } + } + return nil +} + +func (k *Keeper) GetSnapshotHeightAndKey(ctx sdk.Context, avsAddr string, height int64) (int64, []byte, error) { + if !common.IsHexAddress(avsAddr) { + return 0, nil, types.ErrParameterInvalid.Wrapf("invalid AVS address format: %s", avsAddr) + } + if height < 0 { + return 0, nil, types.ErrParameterInvalid.Wrapf("the input height is negative, height:%v", height) + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + // If there is no snapshot for the input height, we need to find the correct key. + // The snapshot closest to the input height is the one used for its voting + // power information. The correct snapshot key can be found by taking advantage + // of the ascending order of data returned when using an iterator range. + avsEthAddr := common.HexToAddress(avsAddr) + findKey := types.KeyForVotingPowerSnapshot(avsEthAddr, height) + findHeight := height + if !store.Has(findKey) { + iterator := sdk.KVStorePrefixIterator(store, avsEthAddr.Bytes()) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + _, keyHeight, err := types.ParseVotingPowerSnapshotKey(iterator.Key()) + if err != nil { + return 0, nil, err + } + if keyHeight <= height { + findKey = iterator.Key() + findHeight = keyHeight + } else { + break + } + } + } + return findHeight, findKey, nil +} + +func (k *Keeper) GetEpochNumberByOptOutHeight(ctx sdk.Context, avsAddr string, optOutHeight int64) (int64, error) { + if optOutHeight < 0 { + return 0, types.ErrParameterInvalid.Wrapf("the opt out height is negative, optOutHeight:%v", optOutHeight) + } + findHeight, findKey, err := k.GetSnapshotHeightAndKey(ctx, avsAddr, optOutHeight) + if err != nil { + return 0, err + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + value := store.Get(findKey) + if value == nil { + return 0, types.ErrNoKeyInTheStore.Wrapf("GetEpochNumberByOptOutHeight: findHeight:%v, optOutHeight:%v", findHeight, optOutHeight) + } + var ret types.VotingPowerSnapshot + k.cdc.MustUnmarshal(value, &ret) + return ret.EpochNumber, nil +} + +// LoadVotingPowerSnapshot loads the voting power snapshot information for the provided height, +// returning the height of the first block in the epoch the snapshot serves, along with the specific +// voting power data. The start height will be used to filter pending undelegations during slashing. +func (k *Keeper) LoadVotingPowerSnapshot(ctx sdk.Context, avsAddr string, height int64) (int64, *types.VotingPowerSnapshot, error) { + findHeight, findKey, err := k.GetSnapshotHeightAndKey(ctx, avsAddr, height) + if err != nil { + return 0, nil, err + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + value := store.Get(findKey) + if value == nil { + avs, keyHeight, _ := types.ParseVotingPowerSnapshotKey(findKey) + return 0, nil, types.ErrNoKeyInTheStore.Wrapf("LoadVotingPowerSnapshot: findHeight is %v, avs:%s ,keyHeight:%v", findHeight, avs, keyHeight) + } + var ret types.VotingPowerSnapshot + k.cdc.MustUnmarshal(value, &ret) + + // fall back to get the snapshot if the key height doesn't equal to the `LastChangedHeight` + if findHeight != ret.LastChangedHeight { + value = store.Get(types.KeyForVotingPowerSnapshot(common.HexToAddress(avsAddr), ret.LastChangedHeight)) + if value == nil { + return 0, nil, types.ErrNoKeyInTheStore.Wrapf("LoadVotingPowerSnapshot: fall back to the height %v", ret.LastChangedHeight) + } + k.cdc.MustUnmarshal(value, &ret) + } + return findHeight, &ret, nil +} + +// RemoveVotingPowerSnapshot remove all snapshots older than the input epoch number. +func (k *Keeper) RemoveVotingPowerSnapshot(ctx sdk.Context, avsAddr string, epochNumber int64) error { + if epochNumber < 0 { + return types.ErrParameterInvalid.Wrapf("the input epoch number is negative, epochNumber:%v", epochNumber) + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + iterator := sdk.KVStorePrefixIterator(store, common.HexToAddress(avsAddr).Bytes()) + defer iterator.Close() + // the retained key is used to record the snapshot that will be fallen back to + // by snapshots earlier than the input time. + var retainedKey []byte + for ; iterator.Valid(); iterator.Next() { + var snapshot types.VotingPowerSnapshot + k.cdc.MustUnmarshal(iterator.Value(), &snapshot) + _, height, _ := types.ParseVotingPowerSnapshotKey(iterator.Key()) + if snapshot.EpochNumber > epochNumber { + // delete the retained key, because the snapshots that is earlier than the input time + // don't need to retain any old snapshot key. + if height == snapshot.LastChangedHeight && retainedKey != nil { + store.Delete(retainedKey) + } + break + } + // When height == snapshot.LastChangedHeight, it indicates that the current snapshot + // contains the current voting power set, so there is no need to fall back to other keys. + if height == snapshot.LastChangedHeight { + // delete the old retained key, because the key currently holding the voting power set + // will become the latest retained key. + if retainedKey != nil { + store.Delete(retainedKey) + } + retainedKey = iterator.Key() + } else { + store.Delete(iterator.Key()) + } + } + return nil +} + +func (k *Keeper) UpdateSnapshotHelper(ctx sdk.Context, avsAddr string, opFunc func(helper *types.SnapshotHelper) error) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixSnapshotHelper) + var snapshotHelper types.SnapshotHelper + value := store.Get([]byte(avsAddr)) + if value != nil { + k.cdc.MustUnmarshal(value, &snapshotHelper) + } + err := opFunc(&snapshotHelper) + if err != nil { + return err + } + bz := k.cdc.MustMarshal(&snapshotHelper) + store.Set([]byte(avsAddr), bz) + return nil +} + +func (k *Keeper) SetOptOutFlag(ctx sdk.Context, avsAddr string, hasOptOut bool) error { + opFunc := func(helper *types.SnapshotHelper) error { + helper.HasOptOut = hasOptOut + return nil // Reserve for future error handling + } + return k.UpdateSnapshotHelper(ctx, avsAddr, opFunc) +} + +func (k *Keeper) SetLastChangedHeight(ctx sdk.Context, avsAddr string, lastChangeHeight int64) error { + opFunc := func(helper *types.SnapshotHelper) error { + helper.LastChangedHeight = lastChangeHeight + return nil // Reserve for future error handling + } + return k.UpdateSnapshotHelper(ctx, avsAddr, opFunc) +} + +func (k *Keeper) SetSnapshotHelper(ctx sdk.Context, avsAddr string, snapshotHelper types.SnapshotHelper) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixSnapshotHelper) + bz := k.cdc.MustMarshal(&snapshotHelper) + store.Set([]byte(avsAddr), bz) + return nil +} + +func (k *Keeper) GetSnapshotHelper(ctx sdk.Context, avsAddr string) (types.SnapshotHelper, error) { + var ret types.SnapshotHelper + if !common.IsHexAddress(avsAddr) { + return ret, types.ErrParameterInvalid.Wrapf("invalid AVS address format: %s", avsAddr) + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixSnapshotHelper) + value := store.Get([]byte(avsAddr)) + if value == nil { + return ret, types.ErrNoKeyInTheStore.Wrapf("GetSnapshotHelper: the key is %s", avsAddr) + } + k.cdc.MustUnmarshal(value, &ret) + return ret, nil +} + +func (k *Keeper) HasSnapshotHelper(ctx sdk.Context, avsAddr string) bool { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixSnapshotHelper) + return store.Has([]byte(avsAddr)) +} + +func (k *Keeper) InitGenesisVPSnapshot(ctx sdk.Context) error { + snapshotStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixVotingPowerSnapshot) + snapshotHelperStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixSnapshotHelper) + opFunc := func(avsAddr string, avsUSDValue *types.DecValueField) error { + votingPowerSet := make([]*types.OperatorVotingPower, 0) + opFunc := func(operator string, optedUSDValues *types.OperatorOptedUSDValue) error { + if optedUSDValues.ActiveUSDValue.IsPositive() { + votingPowerSet = append(votingPowerSet, &types.OperatorVotingPower{ + OperatorAddr: operator, + VotingPower: optedUSDValues.ActiveUSDValue, + }) + } + return nil + } + err := k.IterateOperatorsForAVS(ctx, avsAddr, false, opFunc) + if err != nil { + return err + } + epochInfo, err := k.avsKeeper.GetAVSEpochInfo(ctx, avsAddr) + if err != nil { + return err + } + genesisSnapshotHeight := ctx.BlockHeight() + 1 + epochNumber := epochInfo.CurrentEpoch + // set the epoch number to 1 when epoch start for the first time. + if !epochInfo.EpochCountingStarted { + epochNumber = InitialEpochNumber + } + bz := k.cdc.MustMarshal(&types.VotingPowerSnapshot{ + TotalVotingPower: avsUSDValue.Amount, + OperatorVotingPowers: votingPowerSet, + LastChangedHeight: genesisSnapshotHeight, + EpochIdentifier: epochInfo.Identifier, + EpochNumber: epochNumber, + }) + snapshotKey := types.KeyForVotingPowerSnapshot(common.HexToAddress(avsAddr), genesisSnapshotHeight) + snapshotStore.Set(snapshotKey, bz) + + bz = k.cdc.MustMarshal(&types.SnapshotHelper{ + LastChangedHeight: genesisSnapshotHeight, + HasOptOut: false, + }) + snapshotHelperStore.Set([]byte(avsAddr), bz) + return nil + } + err := k.IterateAVSUSDValues(ctx, false, opFunc) + if err != nil { + return err + } + return nil +} diff --git a/x/operator/keeper/voting_power_snapshot_test.go b/x/operator/keeper/voting_power_snapshot_test.go new file mode 100644 index 000000000..10d2fcfcd --- /dev/null +++ b/x/operator/keeper/voting_power_snapshot_test.go @@ -0,0 +1,354 @@ +package keeper_test + +import ( + "encoding/json" + "fmt" + "math/big" + "sort" + "time" + + avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + + sdkmath "cosmossdk.io/math" + + testutiltx "github.com/ExocoreNetwork/exocore/testutil/tx" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + "github.com/ExocoreNetwork/exocore/x/operator/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" +) + +var ( + operatorNumber = 3 + blockNumberPerEpoch = int64(3) +) + +type testHelperInfo struct { + depositAmount sdkmath.Int + delegateAmount sdkmath.Int + operators []sdk.AccAddress + stakers []common.Address +} + +func (suite *OperatorTestSuite) prepareForSnapshotTesting(operatorNumber int) testHelperInfo { + // set default client chainID and asset + suite.clientChainLzID = defaultClientChainID + // prepare AVS + suite.prepareAvs([]string{usdtAssetID}, epochstypes.DayEpochID) + // prepare stakers and operators + operators := make([]sdk.AccAddress, operatorNumber) + stakers := make([]common.Address, operatorNumber) + + decimalAmount := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(assetDecimal)), nil) + depositAmount := sdkmath.NewInt(10000).Mul(sdkmath.NewIntFromBigInt(decimalAmount)) + delegateAmount := sdkmath.NewInt(1000).Mul(sdkmath.NewIntFromBigInt(decimalAmount)) + for i := 0; i < operatorNumber; i++ { + ethAddr := testutiltx.GenerateAddress() + stakers[i] = ethAddr + operators[i] = ethAddr.Bytes() + // register operator + suite.registerOperator(operators[i].String()) + // associate the stakers with operators + err := suite.App.DelegationKeeper.AssociateOperatorWithStaker(suite.Ctx, suite.clientChainLzID, operators[i], stakers[i].Bytes()) + suite.NoError(err) + // deposit assets + suite.prepareDeposit(stakers[i], usdtAddr, depositAmount) + // delegate assets + suite.prepareDelegation(true, stakers[i], usdtAddr, operators[i], delegateAmount) + // opt in the test AVS + err = suite.App.OperatorKeeper.OptIn(suite.Ctx, operators[i], suite.avsAddr) + suite.NoError(err) + // opt in the dogfood AVS + chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + dogfoodAVSAddr := avstypes.GenerateAVSAddr(chainIDWithoutRevision) + pubKey := testutiltx.GenerateConsensusKey() + suite.Require().NotNil(pubKey) + err = suite.App.OperatorKeeper.OptInWithConsKey(suite.Ctx, operators[i], dogfoodAVSAddr, pubKey) + suite.NoError(err) + } + sort.Slice(stakers, func(i, j int) bool { + return operators[i].String() < operators[j].String() + }) + sort.Slice(operators, func(i, j int) bool { + return operators[i].String() < operators[j].String() + }) + + return testHelperInfo{ + depositAmount: depositAmount, + delegateAmount: delegateAmount, + operators: operators, + stakers: stakers, + } +} + +func (suite *OperatorTestSuite) runToEpochEnd() { + // the default AVS epoch identifier is day + // Configure 3 blocks per epoch for testing, so the block duration is 8 hours + // so starting from the initial block of the epoch, it takes three blocks to + // reach the epoch’s end block. + for i := int64(0); i < blockNumberPerEpoch; i++ { + suite.CommitAfter(8 * time.Hour) + } +} + +func (suite *OperatorTestSuite) printAllSnapshot(avs string) { + epochInfo, found := suite.App.EpochsKeeper.GetEpochInfo(suite.Ctx, epochstypes.DayEpochID) + suite.True(found) + fmt.Println("epoch", epochInfo.CurrentEpoch, "startHeight", epochInfo.CurrentEpochStartHeight) + opFunc := func(height int64, snapshot *types.VotingPowerSnapshot) error { + fmt.Println("snapshot height is:", height) + bytes, err := json.MarshalIndent(snapshot, " ", " ") + suite.NoError(err) + fmt.Println(string(bytes)) + return nil + } + err := suite.App.OperatorKeeper.IterateVotingPowerSnapshot(suite.Ctx, avs, false, opFunc) + suite.NoError(err) +} + +func (suite *OperatorTestSuite) TestInitializeSnapshot() { + helperInfo := suite.prepareForSnapshotTesting(operatorNumber) + suite.runToEpochEnd() + epochInfo, found := suite.App.EpochsKeeper.GetEpochInfo(suite.Ctx, epochstypes.DayEpochID) + suite.True(found) + // the height in the snapshot key should be the start height of next epoch. + snapshotHeight, snapshot, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, epochInfo.CurrentEpochStartHeight) + suite.NoError(err) + suite.Equal(epochInfo.CurrentEpochStartHeight, snapshotHeight) + avsUSDValue, err := suite.App.OperatorKeeper.GetAVSUSDValue(suite.Ctx, suite.avsAddr) + suite.NoError(err) + suite.Equal(avsUSDValue, snapshot.TotalVotingPower) + + expectedVotingPowerSet := make([]*types.OperatorVotingPower, operatorNumber) + for i := 0; i < operatorNumber; i++ { + expectedVotingPowerSet[i] = &types.OperatorVotingPower{ + OperatorAddr: helperInfo.operators[i].String(), + VotingPower: avsUSDValue.Quo(sdkmath.LegacyNewDec(int64(operatorNumber))), + } + } + expectedSnapshot := types.VotingPowerSnapshot{ + TotalVotingPower: avsUSDValue, + OperatorVotingPowers: expectedVotingPowerSet, + LastChangedHeight: epochInfo.CurrentEpochStartHeight, + EpochIdentifier: epochInfo.Identifier, + EpochNumber: epochInfo.CurrentEpoch, + } + suite.Equal(expectedSnapshot, *snapshot) + + snapshotHelper, err := suite.App.OperatorKeeper.GetSnapshotHelper(suite.Ctx, suite.avsAddr) + suite.NoError(err) + suite.Equal(types.SnapshotHelper{ + LastChangedHeight: snapshot.LastChangedHeight, + }, snapshotHelper) + + _, _, err = suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, epochInfo.CurrentEpochStartHeight-1) + suite.Error(err) +} + +func (suite *OperatorTestSuite) TestSnapshotVPUnchanged() { + suite.prepareForSnapshotTesting(operatorNumber) + suite.runToEpochEnd() + lastChangeHeight := suite.Ctx.BlockHeight() + _, initialSnapshot, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, lastChangeHeight) + suite.NoError(err) + runToEpochNumber := 2 + + for i := 0; i < runToEpochNumber; i++ { + suite.runToEpochEnd() + epochInfo, found := suite.App.EpochsKeeper.GetEpochInfo(suite.Ctx, epochstypes.DayEpochID) + suite.True(found) + startHeight := epochInfo.CurrentEpochStartHeight + endHeight := startHeight + blockNumberPerEpoch - 1 + for j := startHeight; j <= endHeight; j++ { + snapshotKeyLastHeight, snapshot, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, j) + suite.NoError(err) + suite.Equal(startHeight, snapshotKeyLastHeight) + suite.Equal(initialSnapshot, snapshot) + + snapshotHelper, err := suite.App.OperatorKeeper.GetSnapshotHelper(suite.Ctx, suite.avsAddr) + suite.NoError(err) + suite.Equal(types.SnapshotHelper{ + LastChangedHeight: snapshot.LastChangedHeight, + }, snapshotHelper) + + if j != startHeight { + key := types.KeyForVotingPowerSnapshot(suite.assetAddr, j) + _, err = suite.App.OperatorKeeper.GetVotingPowerSnapshot(suite.Ctx, key) + suite.Error(err) + } + } + } +} + +func (suite *OperatorTestSuite) TestSnapshotVPChanged() { + testHelper := suite.prepareForSnapshotTesting(operatorNumber) + suite.runToEpochEnd() + _, initialSnapshot, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + + // change the voting power of the operator at index 0. + index := 0 + suite.prepareDelegation(true, testHelper.stakers[index], usdtAddr, testHelper.operators[index], testHelper.delegateAmount) + suite.runToEpochEnd() + _, snapshotAfterUpdate, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + + addVotingPower := initialSnapshot.OperatorVotingPowers[index].VotingPower + expectedTotalVotingPower := initialSnapshot.TotalVotingPower.Add(addVotingPower) + expectedVotingPowerSet := initialSnapshot.OperatorVotingPowers + expectedVotingPowerSet[index].VotingPower = expectedVotingPowerSet[index].VotingPower.Add(addVotingPower) + suite.Equal(expectedTotalVotingPower, snapshotAfterUpdate.TotalVotingPower) + suite.Equal(expectedVotingPowerSet, snapshotAfterUpdate.OperatorVotingPowers) + suite.Equal(initialSnapshot.EpochNumber+1, snapshotAfterUpdate.EpochNumber) +} + +func (suite *OperatorTestSuite) TestSnapshotWithOptOut() { + testHelper := suite.prepareForSnapshotTesting(operatorNumber) + suite.runToEpochEnd() + + // opt out if the index of operator is 0. + index := 0 + err := suite.App.OperatorKeeper.OptOut(suite.Ctx, testHelper.operators[index], suite.avsAddr) + suite.NoError(err) + snapshotHelper, err := suite.App.OperatorKeeper.GetSnapshotHelper(suite.Ctx, suite.avsAddr) + suite.NoError(err) + suite.True(snapshotHelper.HasOptOut) + + suite.runToEpochEnd() + _, snapshot, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + suite.Equal(operatorNumber-1, len(snapshot.OperatorVotingPowers)) + votingPower := types.GetSpecifiedVotingPower(testHelper.operators[index].String(), snapshot.OperatorVotingPowers) + suite.Nil(votingPower) + + snapshotHelper, err = suite.App.OperatorKeeper.GetSnapshotHelper(suite.Ctx, suite.avsAddr) + suite.NoError(err) + suite.False(snapshotHelper.HasOptOut) + + // opt all operators out of the AVS. + for i := index + 1; i < operatorNumber; i++ { + err = suite.App.OperatorKeeper.OptOut(suite.Ctx, testHelper.operators[i], suite.avsAddr) + suite.NoError(err) + } + suite.runToEpochEnd() + _, snapshot, err = suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + suite.Equal(suite.Ctx.BlockHeight(), snapshot.LastChangedHeight) + suite.Equal(0, len(snapshot.OperatorVotingPowers)) + for i := 0; i < operatorNumber; i++ { + votingPower = types.GetSpecifiedVotingPower(testHelper.operators[i].String(), snapshot.OperatorVotingPowers) + suite.Nil(votingPower) + } + suite.runToEpochEnd() + key := types.KeyForVotingPowerSnapshot(common.HexToAddress(suite.avsAddr), suite.Ctx.BlockHeight()) + _, err = suite.App.OperatorKeeper.GetVotingPowerSnapshot(suite.Ctx, key) + suite.Error(err) +} + +func (suite *OperatorTestSuite) TestSnapshotWithSlash() { + testHelper := suite.prepareForSnapshotTesting(operatorNumber) + suite.runToEpochEnd() + _, snapshotBeforeSlash, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + // run to next block to execute slashing + index := 0 + suite.CommitAfter(8 * time.Hour) + slashProportion := sdkmath.LegacyMustNewDecFromStr("0.1") + remainingProportion := sdkmath.LegacyNewDec(1).Sub(slashProportion) + slashParam := &types.SlashInputInfo{ + IsDogFood: false, + Power: 0, + SlashType: 0, + Operator: testHelper.operators[index], + AVSAddr: suite.avsAddr, + SlashID: "testSlashID", + SlashEventHeight: suite.Ctx.BlockHeight(), + SlashProportion: slashProportion, + } + err = suite.App.OperatorKeeper.Slash(suite.Ctx, slashParam) + suite.NoError(err) + _, snapshotAfterSlash, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + suite.Equal(suite.Ctx.BlockHeight(), snapshotAfterSlash.LastChangedHeight) + operatorVPBeforeSlash := types.GetSpecifiedVotingPower(testHelper.operators[index].String(), snapshotBeforeSlash.OperatorVotingPowers) + operatorVPAfterSlash := types.GetSpecifiedVotingPower(testHelper.operators[index].String(), snapshotAfterSlash.OperatorVotingPowers) + suite.Equal(operatorVPBeforeSlash.VotingPower.Mul(remainingProportion), operatorVPAfterSlash.VotingPower) + + snapshotHelper, err := suite.App.OperatorKeeper.GetSnapshotHelper(suite.Ctx, suite.avsAddr) + suite.NoError(err) + suite.Equal(suite.Ctx.BlockHeight(), snapshotHelper.LastChangedHeight) + + shouldUpdateValidatorSet := suite.App.StakingKeeper.ShouldUpdateValidatorSet(suite.Ctx) + suite.True(shouldUpdateValidatorSet) +} + +func (suite *OperatorTestSuite) TestGenesisSnapshot() { + suite.prepareForSnapshotTesting(operatorNumber) + firstBlockHeight := suite.Ctx.BlockHeight() + chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + dogfoodAVSAddr := avstypes.GenerateAVSAddr(chainIDWithoutRevision) + for i := int64(0); i < blockNumberPerEpoch; i++ { + height, snapshot, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, dogfoodAVSAddr, firstBlockHeight) + suite.NoError(err) + suite.Equal(firstBlockHeight, height) + suite.Equal(firstBlockHeight, snapshot.LastChangedHeight) + snapshotHelper, err := suite.App.OperatorKeeper.GetSnapshotHelper(suite.Ctx, dogfoodAVSAddr) + suite.NoError(err) + suite.Equal(firstBlockHeight, snapshotHelper.LastChangedHeight) + } +} + +func (suite *OperatorTestSuite) TestSnapshotPruning() { + testHelper := suite.prepareForSnapshotTesting(operatorNumber) + suite.runToEpochEnd() + firstSnapshotHeight := suite.Ctx.BlockHeight() + + avsUnbondingDuration, err := suite.App.AVSManagerKeeper.GetAVSUnbondingDuration(suite.Ctx, suite.avsAddr) + suite.NoError(err) + + runEpochNumber := avsUnbondingDuration + 2 + for i := uint64(0); i < runEpochNumber; i++ { + suite.runToEpochEnd() + } + _, _, err = suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, firstSnapshotHeight) + suite.NoError(err) + + key := types.KeyForVotingPowerSnapshot(common.HexToAddress(suite.avsAddr), firstSnapshotHeight+blockNumberPerEpoch) + _, err = suite.App.OperatorKeeper.GetVotingPowerSnapshot(suite.Ctx, key) + suite.Error(err) + + // change the voting power of the operator at index 0. + index := 0 + suite.prepareDelegation(true, testHelper.stakers[index], usdtAddr, testHelper.operators[index], testHelper.delegateAmount) + for i := uint64(0); i < runEpochNumber; i++ { + suite.runToEpochEnd() + } + key = types.KeyForVotingPowerSnapshot(common.HexToAddress(suite.avsAddr), firstSnapshotHeight) + _, err = suite.App.OperatorKeeper.GetVotingPowerSnapshot(suite.Ctx, key) + suite.Error(err) + + // Test pruning of slash-created snapshots + slashParam := &types.SlashInputInfo{ + IsDogFood: false, + Power: 0, + SlashType: 0, + Operator: testHelper.operators[index], + AVSAddr: suite.avsAddr, + SlashID: "testSlashID", + SlashEventHeight: suite.Ctx.BlockHeight(), + SlashProportion: sdkmath.LegacyMustNewDecFromStr("0.1"), + } + err = suite.App.OperatorKeeper.Slash(suite.Ctx, slashParam) + suite.NoError(err) + _, snapshotAfterSlash, err := suite.App.OperatorKeeper.LoadVotingPowerSnapshot(suite.Ctx, suite.avsAddr, suite.Ctx.BlockHeight()) + suite.NoError(err) + suite.Equal(suite.Ctx.BlockHeight(), snapshotAfterSlash.LastChangedHeight) + suite.runToEpochEnd() + suite.prepareDelegation(true, testHelper.stakers[index], usdtAddr, testHelper.operators[index], testHelper.delegateAmount) + for i := uint64(0); i < runEpochNumber; i++ { + suite.runToEpochEnd() + } + key = types.KeyForVotingPowerSnapshot(common.HexToAddress(suite.avsAddr), snapshotAfterSlash.LastChangedHeight) + _, err = suite.App.OperatorKeeper.GetVotingPowerSnapshot(suite.Ctx, key) + suite.Error(err) +} diff --git a/x/operator/types/errors.go b/x/operator/types/errors.go index 0e0ad8827..00ef07315 100644 --- a/x/operator/types/errors.go +++ b/x/operator/types/errors.go @@ -111,4 +111,14 @@ var ( ModuleName, 24, "the operator USD value is less than the minimum self delegation", ) + + ErrFailToGetHistoricalVP = errorsmod.Register( + ModuleName, 25, + "failed to get the historical voting power", + ) + + ErrFailToClearVPSnapshot = errorsmod.Register( + ModuleName, 26, + "failed to clear voting power snapshot", + ) ) diff --git a/x/operator/types/expected_keepers.go b/x/operator/types/expected_keepers.go index 2604e3d20..7844c3344 100644 --- a/x/operator/types/expected_keepers.go +++ b/x/operator/types/expected_keepers.go @@ -6,6 +6,7 @@ import ( assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationkeeper "github.com/ExocoreNetwork/exocore/x/delegation/keeper" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" oracletype "github.com/ExocoreNetwork/exocore/x/oracle/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -110,6 +111,8 @@ type AVSKeeper interface { // IsAVS returns true if the address is a registered AVS address. IsAVS(ctx sdk.Context, addr string) (bool, error) IsAVSByChainID(ctx sdk.Context, chainID string) (bool, string) + GetAVSEpochInfo(ctx sdk.Context, addr string) (*epochstypes.EpochInfo, error) + GetAVSUnbondingDuration(ctx sdk.Context, avsAddr string) (uint64, error) } type SlashKeeper interface { @@ -117,19 +120,23 @@ type SlashKeeper interface { } type OperatorHooks interface { - // This hook is called when an operator declares the consensus key for the provided chain. + // AfterOperatorKeySet This hook is called when an operator declares the consensus key for the provided chain. AfterOperatorKeySet( ctx sdk.Context, addr sdk.AccAddress, chainID string, pubKey keytypes.WrappedConsKey, ) - // This hook is called when an operator's consensus key is replaced for a chain. + // AfterOperatorKeyReplaced This hook is called when an operator's consensus key is replaced for a chain. AfterOperatorKeyReplaced( ctx sdk.Context, addr sdk.AccAddress, oldKey keytypes.WrappedConsKey, newKey keytypes.WrappedConsKey, chainID string, ) - // This hook is called when an operator initiates the removal of a consensus key for a + // AfterOperatorKeyRemovalInitiated This hook is called when an operator initiates the removal of a consensus key for a // chain. AfterOperatorKeyRemovalInitiated( ctx sdk.Context, addr sdk.AccAddress, chainID string, key keytypes.WrappedConsKey, ) + // AfterSlash This hook is called when an operator is slashed + AfterSlash( + ctx sdk.Context, addr sdk.AccAddress, affectedAVSList []string, + ) } diff --git a/x/operator/types/genesis.go b/x/operator/types/genesis.go index 9da5ae127..8a1aa311b 100644 --- a/x/operator/types/genesis.go +++ b/x/operator/types/genesis.go @@ -364,7 +364,7 @@ func (gs GenesisState) ValidateSlashStates(operators, avs map[string]struct{}) e slash, ) } - if slash.Info.SlashProportion.IsNil() || slash.Info.SlashProportion.LTE(sdkmath.LegacyNewDec(0)) { + if slash.Info.SlashProportion.IsNil() || slash.Info.SlashProportion.LTE(sdkmath.LegacyZeroDec()) { return errorsmod.Wrapf( ErrInvalidGenesisData, "invalid slash proportion, it's nil, zero, or negative: %+v", @@ -390,7 +390,7 @@ func (gs GenesisState) ValidateSlashStates(operators, avs map[string]struct{}) e } // validate the slashing record regarding undelegation SlashFromUndelegationVal := func(_ int, slashFromUndelegation SlashFromUndelegation) error { - if slashFromUndelegation.Amount.IsNil() || slashFromUndelegation.Amount.LTE(sdkmath.NewInt(0)) { + if slashFromUndelegation.Amount.IsNil() || slashFromUndelegation.Amount.LTE(sdkmath.ZeroInt()) { return errorsmod.Wrapf( ErrInvalidGenesisData, "invalid slashing amount from the undelegation, it's nil, zero, or negative: %+v", @@ -409,7 +409,7 @@ func (gs GenesisState) ValidateSlashStates(operators, avs map[string]struct{}) e } // validate the slashing record regarding assets pool SlashFromAssetsPoolVal := func(_ int, slashFromAssetsPool SlashFromAssetsPool) error { - if slashFromAssetsPool.Amount.IsNil() || slashFromAssetsPool.Amount.LTE(sdkmath.NewInt(0)) { + if slashFromAssetsPool.Amount.IsNil() || slashFromAssetsPool.Amount.LTE(sdkmath.ZeroInt()) { return errorsmod.Wrapf( ErrInvalidGenesisData, "invalid slashing amount from the assets pool, it's nil, zero, or negative: %+v", diff --git a/x/operator/types/genesis.pb.go b/x/operator/types/genesis.pb.go index 0b55379ab..2c0c802cf 100644 --- a/x/operator/types/genesis.pb.go +++ b/x/operator/types/genesis.pb.go @@ -315,7 +315,7 @@ func (m *AVSUSDValue) GetValue() DecValueField { // it's corresponding to the kvStore `KeyPrefixUSDValueForOperator` type OperatorUSDValue struct { // key is used for storing the voting power of specified operator and AVS, - // which is the combination of operator and AVS address. + // which is the combination of AVS and operator address. Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // value is the USD value states for the AVS address OptedUSDValue OperatorOptedUSDValue `protobuf:"bytes,2,opt,name=opted_usd_value,json=optedUsdValue,proto3" json:"opted_usd_value"` diff --git a/x/operator/types/hooks.go b/x/operator/types/hooks.go index 2ade6e5f1..61cf6e4c2 100644 --- a/x/operator/types/hooks.go +++ b/x/operator/types/hooks.go @@ -43,3 +43,11 @@ func (hooks MultiOperatorHooks) AfterOperatorKeyRemovalInitiated( hook.AfterOperatorKeyRemovalInitiated(ctx, addr, chainID, key) } } + +func (hooks MultiOperatorHooks) AfterSlash( + ctx sdk.Context, addr sdk.AccAddress, affectedAVSList []string, +) { + for _, hook := range hooks { + hook.AfterSlash(ctx, addr, affectedAVSList) + } +} diff --git a/x/operator/types/keys.go b/x/operator/types/keys.go index 1033799af..1239ff735 100644 --- a/x/operator/types/keys.go +++ b/x/operator/types/keys.go @@ -1,6 +1,7 @@ package types import ( + "encoding/binary" "math" "golang.org/x/xerrors" @@ -67,6 +68,13 @@ const ( // BytePrefixForOperatorKeyRemovalForChainID is the prefix to store that the operator with // the given address is in the process of unbonding their key for the given chainID. BytePrefixForOperatorKeyRemovalForChainID + + // BytePrefixForVotingPowerSnapshot is the prefix to store the voting power snapshot for all AVSs + BytePrefixForVotingPowerSnapshot + + // BytePrefixForSnapshotHelper is the prefix used to store helper information + // for voting power snapshot updates. + BytePrefixForSnapshotHelper ) var ( @@ -94,6 +102,22 @@ var ( // processedSlashHeight + '/' + assetID + '/' + stakerID -> SlashAmount // processedSlashHeight + '/' + assetID + '/' + operatorAddr -> SlashAmount KeyPrefixSlashAssetsState = []byte{prefixSlashAssetsState} + + // KeyPrefixVotingPowerSnapshot key-value: + // In general, the key used to store the voting power snapshot is based on the epoch number as + // the smallest unit, since our voting power is updated once per epoch. When saving the snapshot, we use + // the `start_height` of current epoch to represent the whole epoch. Therefore, when in use, + // you only need to find the largest height that is less than or equal to the input height, + // which will be the correct snapshot key. + // Additionally, when a slash event occurs, + // the voting power needs to be updated immediately to ensure the slash takes effect for the relevant operator. + // In this case, we need to store an additional snapshot at the height where the slash is executed. + // AVSAddr+ '/' + Height -> VotingPowerSnapshot + KeyPrefixVotingPowerSnapshot = []byte{BytePrefixForVotingPowerSnapshot} + + // KeyPrefixSnapshotHelper key-value: + // avsAddr -> SnapshotHelper + KeyPrefixSnapshotHelper = []byte{BytePrefixForSnapshotHelper} ) // ModuleAddress is the native module address for EVM @@ -135,6 +159,24 @@ func KeyForOperatorAndChainIDToConsKey(addr sdk.AccAddress, chainID string) []by ) } +func KeyForVotingPowerSnapshot(avs common.Address, height int64) []byte { + return AppendMany( + avs.Bytes(), + // Append the height + sdk.Uint64ToBigEndian(uint64(height)), + ) +} + +func ParseVotingPowerSnapshotKey(key []byte) (string, int64, error) { + if len(key) != common.AddressLength+ByteLengthForUint64 { + return "", 0, xerrors.Errorf("invalid snapshot key length,expected:%d,got:%d", common.AddressLength+ByteLengthForUint64, len(key)) + } + avsAddr := common.Address(key[:common.AddressLength]) + height := binary.BigEndian.Uint64(key[common.AddressLength:]) + // #nosec G115 + return avsAddr.String(), int64(height), nil +} + func ParseKeyForOperatorAndChainIDToConsKey(key []byte) (addr sdk.AccAddress, chainID string, err error) { if len(key) < AccAddressLength+ByteLengthForUint64 { return nil, "", xerrors.New("key length is too short to contain address and chainID length") diff --git a/x/operator/types/query.pb.go b/x/operator/types/query.pb.go index 9e6cacd68..207da483f 100644 --- a/x/operator/types/query.pb.go +++ b/x/operator/types/query.pb.go @@ -1354,6 +1354,283 @@ func (m *QueryOptInfoRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryOptInfoRequest proto.InternalMessageInfo +// QuerySnapshotHelperRequest is the request to obtain the voting power snapshot +// helper information. +type QuerySnapshotHelperRequest struct { + // avs address + Avs string `protobuf:"bytes,1,opt,name=avs,proto3" json:"avs,omitempty"` +} + +func (m *QuerySnapshotHelperRequest) Reset() { *m = QuerySnapshotHelperRequest{} } +func (m *QuerySnapshotHelperRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySnapshotHelperRequest) ProtoMessage() {} +func (*QuerySnapshotHelperRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f91e795a3cecbdbf, []int{25} +} +func (m *QuerySnapshotHelperRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySnapshotHelperRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySnapshotHelperRequest.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 *QuerySnapshotHelperRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySnapshotHelperRequest.Merge(m, src) +} +func (m *QuerySnapshotHelperRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySnapshotHelperRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySnapshotHelperRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySnapshotHelperRequest proto.InternalMessageInfo + +func (m *QuerySnapshotHelperRequest) GetAvs() string { + if m != nil { + return m.Avs + } + return "" +} + +// QuerySpecifiedSnapshotRequest is the request to obtain the voting power snapshot +// at the specified height. +type QuerySpecifiedSnapshotRequest struct { + // avs address + Avs string `protobuf:"bytes,1,opt,name=avs,proto3" json:"avs,omitempty"` + // height is used to specify the snapshot height you want to query. + Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *QuerySpecifiedSnapshotRequest) Reset() { *m = QuerySpecifiedSnapshotRequest{} } +func (m *QuerySpecifiedSnapshotRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySpecifiedSnapshotRequest) ProtoMessage() {} +func (*QuerySpecifiedSnapshotRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f91e795a3cecbdbf, []int{26} +} +func (m *QuerySpecifiedSnapshotRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySpecifiedSnapshotRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySpecifiedSnapshotRequest.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 *QuerySpecifiedSnapshotRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySpecifiedSnapshotRequest.Merge(m, src) +} +func (m *QuerySpecifiedSnapshotRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySpecifiedSnapshotRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySpecifiedSnapshotRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySpecifiedSnapshotRequest proto.InternalMessageInfo + +func (m *QuerySpecifiedSnapshotRequest) GetAvs() string { + if m != nil { + return m.Avs + } + return "" +} + +func (m *QuerySpecifiedSnapshotRequest) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +// VotingPowerSnapshotKeyHeight is used in the response of QuerySpecifiedSnapshot +// and QueryAllSnapshot +type VotingPowerSnapshotKeyHeight struct { + // snapshot_key_height when it is used in QuerySpecifiedSnapshot, it's the latest + // height with a snapshot key found based on the input height; this height is typically + // the start height of the epoch in which the input height is located. + // when it is used in QueryAllSnapshot, it's the height in the current snapshot key. + SnapshotKeyHeight int64 `protobuf:"varint,1,opt,name=snapshot_key_height,json=snapshotKeyHeight,proto3" json:"snapshot_key_height,omitempty"` + // snapshot when it is used in QuerySpecifiedSnapshot, it is the final retrieved information + // containing the voting power set. + // when it is used in QueryAllSnapshot, It is the snapshot stored under `snapshot_key_height`, + // and its voting power set may be nil. + Snapshot *VotingPowerSnapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"` +} + +func (m *VotingPowerSnapshotKeyHeight) Reset() { *m = VotingPowerSnapshotKeyHeight{} } +func (m *VotingPowerSnapshotKeyHeight) String() string { return proto.CompactTextString(m) } +func (*VotingPowerSnapshotKeyHeight) ProtoMessage() {} +func (*VotingPowerSnapshotKeyHeight) Descriptor() ([]byte, []int) { + return fileDescriptor_f91e795a3cecbdbf, []int{27} +} +func (m *VotingPowerSnapshotKeyHeight) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VotingPowerSnapshotKeyHeight) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VotingPowerSnapshotKeyHeight.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 *VotingPowerSnapshotKeyHeight) XXX_Merge(src proto.Message) { + xxx_messageInfo_VotingPowerSnapshotKeyHeight.Merge(m, src) +} +func (m *VotingPowerSnapshotKeyHeight) XXX_Size() int { + return m.Size() +} +func (m *VotingPowerSnapshotKeyHeight) XXX_DiscardUnknown() { + xxx_messageInfo_VotingPowerSnapshotKeyHeight.DiscardUnknown(m) +} + +var xxx_messageInfo_VotingPowerSnapshotKeyHeight proto.InternalMessageInfo + +func (m *VotingPowerSnapshotKeyHeight) GetSnapshotKeyHeight() int64 { + if m != nil { + return m.SnapshotKeyHeight + } + return 0 +} + +func (m *VotingPowerSnapshotKeyHeight) GetSnapshot() *VotingPowerSnapshot { + if m != nil { + return m.Snapshot + } + return nil +} + +// QueryAllSnapshotRequest is the request to obtain all voting power snapshot +// for the specified AVS +type QueryAllSnapshotRequest struct { + // avs address + Avs string `protobuf:"bytes,1,opt,name=avs,proto3" json:"avs,omitempty"` + // pagination related options. + Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllSnapshotRequest) Reset() { *m = QueryAllSnapshotRequest{} } +func (m *QueryAllSnapshotRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAllSnapshotRequest) ProtoMessage() {} +func (*QueryAllSnapshotRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f91e795a3cecbdbf, []int{28} +} +func (m *QueryAllSnapshotRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllSnapshotRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllSnapshotRequest.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 *QueryAllSnapshotRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllSnapshotRequest.Merge(m, src) +} +func (m *QueryAllSnapshotRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAllSnapshotRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllSnapshotRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllSnapshotRequest proto.InternalMessageInfo + +func (m *QueryAllSnapshotRequest) GetAvs() string { + if m != nil { + return m.Avs + } + return "" +} + +func (m *QueryAllSnapshotRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryAllSnapshotResponse is the response to obtain all voting power snapshot +// for the specified AVS +type QueryAllSnapshotResponse struct { + // snapshots is a list of all snapshots for the specified AVS. + Snapshots []*VotingPowerSnapshotKeyHeight `protobuf:"bytes,1,rep,name=snapshots,proto3" json:"snapshots,omitempty"` + // pagination related response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllSnapshotResponse) Reset() { *m = QueryAllSnapshotResponse{} } +func (m *QueryAllSnapshotResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAllSnapshotResponse) ProtoMessage() {} +func (*QueryAllSnapshotResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f91e795a3cecbdbf, []int{29} +} +func (m *QueryAllSnapshotResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllSnapshotResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllSnapshotResponse.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 *QueryAllSnapshotResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllSnapshotResponse.Merge(m, src) +} +func (m *QueryAllSnapshotResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAllSnapshotResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllSnapshotResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllSnapshotResponse proto.InternalMessageInfo + +func (m *QueryAllSnapshotResponse) GetSnapshots() []*VotingPowerSnapshotKeyHeight { + if m != nil { + return m.Snapshots + } + return nil +} + +func (m *QueryAllSnapshotResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + // QueryValidatorsRequest is request type for Query/Validators RPC method. type QueryValidatorsRequest struct { // chain is the id of the chain served by the operator. here chain_id is not used since the @@ -1368,7 +1645,7 @@ func (m *QueryValidatorsRequest) Reset() { *m = QueryValidatorsRequest{} func (m *QueryValidatorsRequest) String() string { return proto.CompactTextString(m) } func (*QueryValidatorsRequest) ProtoMessage() {} func (*QueryValidatorsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f91e795a3cecbdbf, []int{25} + return fileDescriptor_f91e795a3cecbdbf, []int{30} } func (m *QueryValidatorsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1423,7 +1700,7 @@ func (m *QueryValidatorsResponse) Reset() { *m = QueryValidatorsResponse func (m *QueryValidatorsResponse) String() string { return proto.CompactTextString(m) } func (*QueryValidatorsResponse) ProtoMessage() {} func (*QueryValidatorsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f91e795a3cecbdbf, []int{26} + return fileDescriptor_f91e795a3cecbdbf, []int{31} } func (m *QueryValidatorsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1480,7 +1757,7 @@ func (m *QueryValidatorRequest) Reset() { *m = QueryValidatorRequest{} } func (m *QueryValidatorRequest) String() string { return proto.CompactTextString(m) } func (*QueryValidatorRequest) ProtoMessage() {} func (*QueryValidatorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f91e795a3cecbdbf, []int{27} + return fileDescriptor_f91e795a3cecbdbf, []int{32} } func (m *QueryValidatorRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1533,7 +1810,7 @@ func (m *QueryValidatorResponse) Reset() { *m = QueryValidatorResponse{} func (m *QueryValidatorResponse) String() string { return proto.CompactTextString(m) } func (*QueryValidatorResponse) ProtoMessage() {} func (*QueryValidatorResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f91e795a3cecbdbf, []int{28} + return fileDescriptor_f91e795a3cecbdbf, []int{33} } func (m *QueryValidatorResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1595,6 +1872,11 @@ func init() { proto.RegisterType((*QueryAllAVSsByOperatorRequest)(nil), "exocore.operator.v1.QueryAllAVSsByOperatorRequest") proto.RegisterType((*QueryAllAVSsByOperatorResponse)(nil), "exocore.operator.v1.QueryAllAVSsByOperatorResponse") proto.RegisterType((*QueryOptInfoRequest)(nil), "exocore.operator.v1.QueryOptInfoRequest") + proto.RegisterType((*QuerySnapshotHelperRequest)(nil), "exocore.operator.v1.QuerySnapshotHelperRequest") + proto.RegisterType((*QuerySpecifiedSnapshotRequest)(nil), "exocore.operator.v1.QuerySpecifiedSnapshotRequest") + proto.RegisterType((*VotingPowerSnapshotKeyHeight)(nil), "exocore.operator.v1.VotingPowerSnapshotKeyHeight") + proto.RegisterType((*QueryAllSnapshotRequest)(nil), "exocore.operator.v1.QueryAllSnapshotRequest") + proto.RegisterType((*QueryAllSnapshotResponse)(nil), "exocore.operator.v1.QueryAllSnapshotResponse") proto.RegisterType((*QueryValidatorsRequest)(nil), "exocore.operator.v1.QueryValidatorsRequest") proto.RegisterType((*QueryValidatorsResponse)(nil), "exocore.operator.v1.QueryValidatorsResponse") proto.RegisterType((*QueryValidatorRequest)(nil), "exocore.operator.v1.QueryValidatorRequest") @@ -1604,112 +1886,126 @@ func init() { func init() { proto.RegisterFile("exocore/operator/v1/query.proto", fileDescriptor_f91e795a3cecbdbf) } var fileDescriptor_f91e795a3cecbdbf = []byte{ - // 1678 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x73, 0x14, 0x45, - 0x14, 0xcf, 0x04, 0x90, 0xec, 0x0b, 0x60, 0xd2, 0x09, 0x1a, 0x06, 0xd8, 0x85, 0x41, 0x49, 0x08, - 0x61, 0xc7, 0x84, 0x80, 0x16, 0x11, 0xad, 0x5d, 0x02, 0x18, 0xa0, 0x4c, 0x9c, 0x2d, 0x83, 0x5a, - 0xa5, 0x5b, 0x93, 0x9d, 0x61, 0x33, 0xc5, 0x64, 0x66, 0xd9, 0x9e, 0x5d, 0xd8, 0x4a, 0xc5, 0xb2, - 0x3c, 0xe1, 0xcd, 0x92, 0xa3, 0x85, 0x67, 0x2f, 0x5a, 0x1e, 0xac, 0xf2, 0xe0, 0x41, 0x8f, 0x1c, - 0x3c, 0x44, 0xbd, 0x78, 0x8a, 0x56, 0xa2, 0xe5, 0x5f, 0xe0, 0xc1, 0x9b, 0x35, 0x3d, 0xdd, 0xf3, - 0x3d, 0x93, 0x59, 0x88, 0x5c, 0x52, 0x3b, 0xd3, 0xef, 0xf5, 0xfb, 0xbd, 0xaf, 0x7e, 0xbf, 0x9e, - 0x40, 0x41, 0xbd, 0x67, 0xd6, 0xcc, 0xa6, 0x2a, 0x9a, 0x0d, 0xb5, 0x29, 0x5b, 0x66, 0x53, 0x6c, - 0x4f, 0x8a, 0x77, 0x5a, 0x6a, 0xb3, 0x53, 0x6c, 0x34, 0x4d, 0xcb, 0x44, 0x43, 0x54, 0xa0, 0xc8, - 0x04, 0x8a, 0xed, 0x49, 0x7e, 0x50, 0x5e, 0xd1, 0x0c, 0x53, 0x24, 0x7f, 0x1d, 0x39, 0x7e, 0xbc, - 0x66, 0xe2, 0x15, 0x13, 0x8b, 0x4b, 0x32, 0x56, 0x9d, 0x0d, 0xc4, 0xf6, 0xe4, 0x92, 0x6a, 0xc9, - 0x93, 0x62, 0x43, 0xae, 0x6b, 0x86, 0x6c, 0x69, 0xa6, 0x41, 0x65, 0x0f, 0x53, 0x59, 0x26, 0xe6, - 0x37, 0xc8, 0x1f, 0x72, 0x16, 0xab, 0xe4, 0x49, 0x74, 0x1e, 0xe8, 0xd2, 0x91, 0x38, 0xb0, 0xd6, - 0x3d, 0xba, 0x7a, 0x22, 0x6e, 0xb5, 0x2d, 0xeb, 0x9a, 0x42, 0x60, 0x3b, 0x42, 0xc3, 0x75, 0xb3, - 0x6e, 0x3a, 0x5b, 0xdb, 0xbf, 0xd8, 0xc6, 0x75, 0xd3, 0xac, 0xeb, 0xaa, 0x28, 0x37, 0x34, 0x51, - 0x36, 0x0c, 0xd3, 0x22, 0x68, 0x5d, 0xb3, 0x96, 0x6a, 0x28, 0x6a, 0x73, 0x45, 0x33, 0x2c, 0xb1, - 0xd6, 0xec, 0x34, 0x2c, 0x53, 0xbc, 0xad, 0x76, 0xe8, 0xaa, 0x50, 0x01, 0x74, 0x55, 0xb5, 0xe6, - 0xa9, 0xcd, 0x39, 0xe3, 0x96, 0x29, 0xa9, 0x77, 0xd0, 0x45, 0xd8, 0xcf, 0x60, 0x54, 0x65, 0x45, - 0x69, 0x8e, 0x70, 0xc7, 0xb8, 0xb1, 0x5c, 0x79, 0xe4, 0x97, 0x6f, 0xcf, 0x0c, 0x53, 0x9f, 0x4a, - 0x8a, 0xd2, 0x54, 0x31, 0xae, 0x58, 0x4d, 0xcd, 0xa8, 0x4b, 0xfb, 0x98, 0xb8, 0xfd, 0x5a, 0x58, - 0x82, 0x91, 0xb7, 0xec, 0x98, 0x94, 0x74, 0x9d, 0xed, 0x8c, 0x25, 0xf5, 0x4e, 0x4b, 0xc5, 0x16, - 0xba, 0x02, 0xe0, 0x45, 0x94, 0xec, 0xdb, 0x3f, 0x75, 0xb2, 0x48, 0x37, 0xb5, 0xc3, 0x5f, 0x74, - 0xc2, 0x49, 0xc3, 0x5f, 0x5c, 0x90, 0xeb, 0x2a, 0xd5, 0x95, 0x7c, 0x9a, 0xc2, 0x67, 0x1c, 0x1c, - 0x8a, 0x31, 0x82, 0x1b, 0xa6, 0x81, 0x55, 0x34, 0x01, 0xc8, 0x73, 0xa0, 0x56, 0x23, 0x4e, 0xe0, - 0x11, 0xee, 0xd8, 0xae, 0xb1, 0x9c, 0x34, 0xe0, 0x62, 0xad, 0xd5, 0x6c, 0xb8, 0x18, 0x5d, 0x0d, - 0x60, 0xea, 0x25, 0x98, 0x46, 0xb7, 0xc5, 0xe4, 0x98, 0x0a, 0x80, 0xb2, 0x00, 0x31, 0x2c, 0xa5, - 0xc5, 0x0a, 0x0d, 0xd1, 0x13, 0x46, 0x13, 0x15, 0xa0, 0x5f, 0x6e, 0x63, 0xa2, 0xa9, 0x62, 0x4c, - 0xe0, 0xe5, 0x24, 0x90, 0xdb, 0x98, 0x2a, 0x09, 0x77, 0xe1, 0x08, 0x89, 0x04, 0x33, 0xfd, 0x76, - 0x65, 0x76, 0x51, 0xd6, 0x5b, 0x2c, 0x6c, 0xe8, 0x26, 0x0c, 0x78, 0xf6, 0x0d, 0xa5, 0x2a, 0xb7, - 0x31, 0x0d, 0xfc, 0x68, 0x31, 0xa6, 0x3f, 0x8a, 0x51, 0x17, 0xca, 0xbb, 0xd7, 0x37, 0x0a, 0x9c, - 0x74, 0xc0, 0xc5, 0x65, 0x28, 0xa5, 0x36, 0x16, 0x3a, 0x70, 0x34, 0xc1, 0x30, 0x4d, 0xc3, 0x3b, - 0x00, 0x2d, 0xac, 0x54, 0xdb, 0xf6, 0x4b, 0x66, 0x73, 0x3c, 0xd5, 0xe6, 0x7c, 0xc3, 0x52, 0x15, - 0xb6, 0x4f, 0x79, 0xff, 0xe6, 0x46, 0x21, 0xc7, 0x9e, 0xb0, 0x94, 0x6b, 0x61, 0xc5, 0xf9, 0x29, - 0x5c, 0x83, 0xe7, 0x9d, 0xec, 0x2f, 0x56, 0xc2, 0xee, 0x8a, 0xc1, 0x78, 0x39, 0xc1, 0x3e, 0xb0, - 0xb9, 0x51, 0x00, 0xcf, 0xa1, 0x40, 0xfc, 0x7e, 0xe4, 0x42, 0x7e, 0x54, 0x74, 0x19, 0x2f, 0xd3, - 0x5e, 0xf8, 0x5f, 0x23, 0x18, 0xea, 0x86, 0xde, 0xc7, 0xee, 0x86, 0x55, 0x38, 0x18, 0x01, 0x5f, - 0xee, 0xcc, 0xcd, 0xa2, 0x93, 0xd0, 0x87, 0xed, 0x17, 0x55, 0x4d, 0xa1, 0x91, 0xe8, 0xdf, 0xdc, - 0x28, 0xec, 0x75, 0x84, 0x66, 0xa5, 0xbd, 0x64, 0x71, 0x4e, 0x41, 0x17, 0x60, 0xb7, 0x66, 0xdc, - 0x32, 0x5d, 0x08, 0x69, 0x5e, 0x79, 0xe1, 0x21, 0x3a, 0xc2, 0xf7, 0x1c, 0xe4, 0x93, 0xe2, 0x47, - 0x0b, 0x61, 0x01, 0x0e, 0xc8, 0xba, 0x5e, 0xa5, 0x50, 0x6c, 0x43, 0x76, 0x2f, 0x6e, 0x57, 0x0c, - 0x01, 0x57, 0xa4, 0x7d, 0xb2, 0xae, 0xbb, 0x6f, 0x76, 0xae, 0x67, 0xab, 0x70, 0x38, 0x00, 0xfe, - 0x92, 0x69, 0xe0, 0xeb, 0x6a, 0x87, 0xa5, 0x7e, 0x1c, 0x06, 0x23, 0x27, 0x89, 0x13, 0x49, 0xe9, - 0xd9, 0xd0, 0x41, 0x82, 0x86, 0x61, 0x4f, 0x6d, 0x59, 0xd6, 0x0c, 0xda, 0xa3, 0xce, 0x83, 0xf0, - 0x11, 0x17, 0xea, 0x4f, 0xd7, 0x02, 0x0d, 0x4e, 0x09, 0xa0, 0xd1, 0x5a, 0xd2, 0xb5, 0x5a, 0xf5, - 0xb6, 0xda, 0xa1, 0x75, 0x75, 0xa4, 0xe8, 0x1d, 0xdb, 0x45, 0xe7, 0xd8, 0x2e, 0x2e, 0x10, 0xa1, - 0xeb, 0x6a, 0xa7, 0xbc, 0xfb, 0xd1, 0x46, 0xa1, 0x47, 0xca, 0x35, 0xd8, 0x0b, 0x74, 0x14, 0xc0, - 0x6c, 0x58, 0x9a, 0x51, 0xaf, 0x9a, 0x2d, 0x8b, 0x98, 0xef, 0x93, 0x72, 0xce, 0x9b, 0xf9, 0x96, - 0x25, 0xd4, 0xa0, 0x10, 0x41, 0xc0, 0x3a, 0x61, 0xc7, 0xfc, 0xfc, 0x00, 0x8e, 0x25, 0x1b, 0xa1, - 0xae, 0x1e, 0x86, 0x5c, 0xcd, 0x34, 0xb0, 0x7f, 0xf7, 0xbe, 0x1a, 0x95, 0xdb, 0xce, 0x89, 0xfb, - 0x1c, 0x8c, 0x85, 0x4f, 0x7c, 0x1a, 0x4a, 0x5c, 0xee, 0x5c, 0xb2, 0x31, 0xcc, 0xcd, 0x32, 0x77, - 0x5c, 0x88, 0x9c, 0x0f, 0xe2, 0x8e, 0xb5, 0xdb, 0x4f, 0x1c, 0x9c, 0xca, 0x00, 0x85, 0x3a, 0xbd, - 0xe8, 0x1b, 0x46, 0xc4, 0x7b, 0x7b, 0xfe, 0xd2, 0x06, 0x18, 0x4b, 0x6d, 0x00, 0xba, 0xe7, 0x82, - 0xac, 0x35, 0xbd, 0xb1, 0xc5, 0x0c, 0xed, 0x5c, 0x0b, 0x3c, 0xe4, 0x60, 0x28, 0xc6, 0x64, 0x57, - 0x35, 0x31, 0x13, 0x28, 0xe2, 0xde, 0xed, 0x8b, 0x38, 0xb9, 0x7c, 0x77, 0x85, 0x33, 0xff, 0x49, - 0x42, 0xb8, 0xc9, 0xf4, 0x7e, 0xca, 0xa9, 0x5f, 0xe7, 0x60, 0x3c, 0x0b, 0x16, 0x9a, 0xfb, 0x77, - 0x61, 0x28, 0x98, 0x7b, 0x8f, 0x89, 0xf4, 0x4f, 0x9d, 0xda, 0x36, 0xf9, 0xf6, 0xae, 0x24, 0xfb, - 0x83, 0x66, 0xd8, 0xd6, 0xce, 0xa5, 0xff, 0x43, 0x18, 0x8e, 0xb3, 0xd9, 0x55, 0xfa, 0x03, 0x8d, - 0xdd, 0x9b, 0xda, 0xd8, 0x91, 0xf4, 0x9e, 0x07, 0x21, 0xc2, 0xe4, 0xca, 0x9d, 0xf9, 0x86, 0x35, - 0x67, 0x94, 0x16, 0x2b, 0x2c, 0xad, 0x03, 0xb0, 0x8b, 0x8d, 0xdd, 0x9c, 0x64, 0xff, 0x14, 0xae, - 0xc1, 0x89, 0x54, 0x3d, 0x9a, 0x82, 0x13, 0x3e, 0xfa, 0xa5, 0x6b, 0xd8, 0xa2, 0x34, 0xd0, 0x25, - 0x59, 0x37, 0x34, 0x6c, 0x09, 0x33, 0x94, 0x02, 0x94, 0x74, 0xbd, 0xb4, 0x58, 0x21, 0xdb, 0x38, - 0xab, 0xcc, 0x3c, 0x0f, 0x7d, 0x4c, 0x81, 0x1d, 0x5c, 0xec, 0x59, 0x98, 0xa1, 0xf3, 0x2f, 0x46, - 0x99, 0x62, 0x38, 0x04, 0x7d, 0x36, 0x27, 0xf1, 0x99, 0xdf, 0x2b, 0xb7, 0x31, 0xb1, 0x6c, 0xc0, - 0x10, 0x3d, 0x36, 0xad, 0xa7, 0x41, 0x39, 0x84, 0x36, 0x3c, 0x47, 0xec, 0x2d, 0xb2, 0xbb, 0x05, - 0x7e, 0x3a, 0x8d, 0xf3, 0x15, 0x47, 0x29, 0x9b, 0xdf, 0x30, 0x0d, 0xcf, 0x1c, 0x80, 0x7b, 0xd5, - 0x61, 0xcd, 0x91, 0x8f, 0x75, 0xd3, 0x55, 0x2e, 0xe7, 0xec, 0x19, 0xf8, 0xe5, 0xdf, 0xdf, 0x8c, - 0x73, 0x92, 0x4f, 0x79, 0xe7, 0xba, 0xa2, 0x05, 0x07, 0x83, 0x70, 0xbd, 0x1b, 0x0c, 0x72, 0xed, - 0x85, 0xfa, 0x22, 0x85, 0xd3, 0x0f, 0xb8, 0x3a, 0xe9, 0x53, 0x54, 0x0e, 0xa7, 0xc7, 0x0d, 0xd2, - 0x55, 0xc8, 0xb9, 0x7b, 0xd0, 0x52, 0xe8, 0x22, 0x46, 0x9e, 0xee, 0xd4, 0x5f, 0x07, 0x61, 0x0f, - 0xb1, 0x81, 0x3e, 0xe7, 0x60, 0x30, 0x30, 0xb3, 0x09, 0xb5, 0x8a, 0x2f, 0xb0, 0xe8, 0x35, 0x91, - 0x3f, 0x9e, 0x5a, 0x89, 0xb6, 0x94, 0x70, 0xe1, 0xe3, 0x5f, 0xff, 0x7c, 0xd0, 0x3b, 0x8d, 0xa6, - 0xc4, 0xb8, 0xfb, 0xad, 0x5b, 0xe1, 0x36, 0x25, 0x14, 0x57, 0x03, 0xb7, 0xa4, 0x35, 0xf4, 0x05, - 0x43, 0xe7, 0x6f, 0x70, 0x74, 0x26, 0xd6, 0x68, 0xd2, 0x7d, 0x93, 0x2f, 0x66, 0x15, 0x77, 0xa2, - 0x2c, 0x8c, 0x13, 0xc0, 0x2f, 0x20, 0x21, 0x16, 0xb0, 0x4d, 0x62, 0x4d, 0x17, 0xca, 0xcf, 0x61, - 0xe2, 0x4b, 0x87, 0xe7, 0x15, 0xb3, 0x49, 0xe7, 0x00, 0x7a, 0x29, 0xd9, 0x7c, 0x3c, 0xe1, 0xe4, - 0x27, 0xbb, 0xd0, 0xa0, 0x98, 0xaf, 0x11, 0xcc, 0xb3, 0xa8, 0x9c, 0x1e, 0x64, 0xc6, 0x3d, 0xfc, - 0x81, 0xa6, 0xe5, 0xbb, 0x26, 0xae, 0x92, 0xf2, 0x5b, 0x43, 0x1b, 0x1c, 0x3d, 0x8d, 0x63, 0x68, - 0x9c, 0xcf, 0xaf, 0xe9, 0x6c, 0x28, 0x83, 0x24, 0x93, 0x3f, 0xd7, 0xa5, 0x16, 0xf5, 0xef, 0x3a, - 0xf1, 0xef, 0x32, 0xba, 0x94, 0xc1, 0x3f, 0xdb, 0x9b, 0x54, 0x07, 0x7f, 0xe7, 0xe0, 0xf8, 0xb6, - 0xdc, 0x0d, 0x5d, 0xcc, 0x54, 0x36, 0x49, 0xf4, 0x93, 0x7f, 0xed, 0x71, 0xd5, 0xa9, 0xc7, 0x33, - 0xc4, 0xe3, 0x73, 0xe8, 0xec, 0xb6, 0x55, 0xe8, 0x31, 0x4a, 0xd7, 0xc3, 0x7f, 0x38, 0x7a, 0x74, - 0x85, 0xef, 0xe5, 0x28, 0x43, 0x6d, 0x85, 0x6e, 0xd3, 0xfc, 0x54, 0x37, 0x2a, 0x14, 0x7d, 0x8b, - 0xa0, 0x37, 0xd1, 0x8a, 0x98, 0xf8, 0x7d, 0xce, 0xc3, 0xef, 0x7e, 0x20, 0xf0, 0x67, 0xcd, 0x19, - 0x78, 0xc5, 0xe0, 0x81, 0x10, 0x23, 0xe0, 0xbb, 0xe8, 0xaf, 0xa1, 0x07, 0x1c, 0x0c, 0x84, 0x3f, - 0x0a, 0xa0, 0x89, 0x94, 0x4c, 0x44, 0xbe, 0x1d, 0xf0, 0x42, 0xac, 0xf4, 0xac, 0x5a, 0x23, 0x52, - 0x57, 0x34, 0x55, 0x57, 0x84, 0x33, 0xc4, 0xbb, 0x51, 0xf4, 0x62, 0xac, 0x77, 0x11, 0x00, 0xff, - 0x72, 0xf4, 0x44, 0x8f, 0xdc, 0x6a, 0x51, 0x86, 0xd8, 0x86, 0x3f, 0x45, 0xf0, 0x67, 0xbb, 0xd2, - 0xa1, 0x09, 0x69, 0x13, 0xc8, 0x0d, 0x64, 0x64, 0x49, 0x88, 0x77, 0x49, 0x7f, 0xe2, 0x8c, 0x6c, - 0x71, 0x51, 0x6a, 0x17, 0x25, 0xcb, 0x28, 0x7b, 0xb7, 0xc4, 0x32, 0x7e, 0xfe, 0xf5, 0xc7, 0xd6, - 0xa7, 0xf1, 0x79, 0x95, 0xc4, 0xe7, 0x3c, 0x9a, 0xce, 0xd8, 0x6e, 0x84, 0xc4, 0xbb, 0xfd, 0xf6, - 0x88, 0xf3, 0xc8, 0xa3, 0x3b, 0x50, 0x6e, 0x6a, 0xd6, 0x32, 0xa3, 0xa2, 0xe8, 0xe5, 0x6c, 0x43, - 0x28, 0x42, 0x7a, 0xf9, 0x57, 0xba, 0x57, 0xa4, 0x2e, 0x4d, 0x13, 0x97, 0x8a, 0x68, 0x22, 0xe1, - 0xcc, 0xb4, 0xc4, 0x00, 0x29, 0x16, 0x57, 0xe5, 0x36, 0x5e, 0x43, 0xdf, 0xb1, 0x62, 0x8d, 0x50, - 0xd9, 0xb4, 0x62, 0x4d, 0x22, 0xcd, 0x69, 0xc5, 0x9a, 0xc8, 0x95, 0x33, 0x20, 0x67, 0x54, 0xda, - 0x2b, 0xbf, 0x35, 0xf4, 0x03, 0x07, 0xfb, 0xfc, 0x3c, 0x1a, 0x8d, 0xa5, 0x35, 0x8a, 0x9f, 0x6a, - 0xf3, 0xf9, 0x04, 0x1a, 0x63, 0xa9, 0x0a, 0xe1, 0x30, 0x2a, 0x01, 0x54, 0x45, 0xef, 0x27, 0x01, - 0xda, 0x99, 0x66, 0x79, 0xc8, 0x01, 0x78, 0xdc, 0x18, 0x9d, 0x4e, 0xc6, 0x1f, 0xa1, 0xee, 0xfc, - 0x44, 0x36, 0x61, 0x16, 0xe1, 0xfb, 0x36, 0x25, 0x24, 0x5e, 0x9d, 0x42, 0xa3, 0x62, 0xea, 0x7f, - 0x1e, 0xbc, 0x32, 0xff, 0x9a, 0x83, 0x9c, 0xbb, 0x19, 0x1a, 0xcf, 0x60, 0x91, 0xa1, 0x3b, 0x9d, - 0x49, 0x96, 0x82, 0x7b, 0xc3, 0x03, 0x77, 0x11, 0xcd, 0xa4, 0x83, 0x13, 0x57, 0xa3, 0x4c, 0xdc, - 0x9d, 0xf4, 0xe5, 0x1b, 0x8f, 0x36, 0xf3, 0xdc, 0xfa, 0x66, 0x9e, 0xfb, 0x63, 0x33, 0xcf, 0x7d, - 0xba, 0x95, 0xef, 0x59, 0xdf, 0xca, 0xf7, 0xfc, 0xb6, 0x95, 0xef, 0x79, 0x6f, 0xaa, 0xae, 0x59, - 0xcb, 0xad, 0xa5, 0x62, 0xcd, 0x5c, 0x11, 0x2f, 0x3b, 0x06, 0xde, 0x54, 0xad, 0xbb, 0x66, 0xf3, - 0xb6, 0x6b, 0xef, 0x9e, 0x67, 0xd1, 0xea, 0x34, 0x54, 0xbc, 0xf4, 0x0c, 0xf9, 0x87, 0xc9, 0xd9, - 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x83, 0xae, 0xb1, 0x74, 0x1a, 0x00, 0x00, + // 1902 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x73, 0x1c, 0x47, + 0x15, 0x77, 0xcb, 0x4e, 0xac, 0x7d, 0x76, 0x8c, 0xd4, 0x72, 0x82, 0x3d, 0x76, 0x56, 0xce, 0x98, + 0x8a, 0x65, 0x45, 0x9e, 0x41, 0xb2, 0x13, 0xa8, 0x08, 0x43, 0x69, 0xad, 0xd8, 0x96, 0x9d, 0x42, + 0x62, 0xb6, 0xd8, 0x00, 0x55, 0xb0, 0x35, 0xda, 0x6d, 0xef, 0x0e, 0x1e, 0x4f, 0x8f, 0xb7, 0x67, + 0xd7, 0xde, 0x52, 0x89, 0xa2, 0x38, 0x85, 0x5b, 0x0a, 0xb8, 0x51, 0x01, 0x8e, 0x5c, 0xa0, 0x38, + 0x84, 0xe2, 0xc0, 0x01, 0x8e, 0x3e, 0x70, 0x30, 0xe4, 0xc2, 0x49, 0x50, 0x32, 0x55, 0x1c, 0x39, + 0xf0, 0x0f, 0x50, 0xd3, 0xd3, 0x3d, 0x1f, 0x3b, 0x1f, 0x3b, 0xeb, 0x2c, 0xbe, 0xa8, 0x76, 0x66, + 0xde, 0xeb, 0xf7, 0x7b, 0x9f, 0xdd, 0xbf, 0x16, 0x2c, 0x92, 0xc7, 0xb4, 0x45, 0x7b, 0x44, 0xa7, + 0x2e, 0xe9, 0x99, 0x1e, 0xed, 0xe9, 0x83, 0x55, 0xfd, 0x61, 0x9f, 0xf4, 0x86, 0x9a, 0xdb, 0xa3, + 0x1e, 0xc5, 0x0b, 0x42, 0x40, 0x93, 0x02, 0xda, 0x60, 0x55, 0x99, 0x37, 0x1f, 0x58, 0x0e, 0xd5, + 0xf9, 0xdf, 0x40, 0x4e, 0x59, 0x6e, 0x51, 0xf6, 0x80, 0x32, 0x7d, 0xd7, 0x64, 0x24, 0x58, 0x40, + 0x1f, 0xac, 0xee, 0x12, 0xcf, 0x5c, 0xd5, 0x5d, 0xb3, 0x63, 0x39, 0xa6, 0x67, 0x51, 0x47, 0xc8, + 0x9e, 0x13, 0xb2, 0x52, 0x2c, 0x6e, 0x50, 0x39, 0x1b, 0x7c, 0x6c, 0xf2, 0x27, 0x3d, 0x78, 0x10, + 0x9f, 0xce, 0x67, 0x81, 0xf5, 0x1e, 0x8b, 0xaf, 0x17, 0xb3, 0xbe, 0x0e, 0x4c, 0xdb, 0x6a, 0x73, + 0xd8, 0x81, 0xd0, 0xe9, 0x0e, 0xed, 0xd0, 0x60, 0x69, 0xff, 0x97, 0x5c, 0xb8, 0x43, 0x69, 0xc7, + 0x26, 0xba, 0xe9, 0x5a, 0xba, 0xe9, 0x38, 0xd4, 0xe3, 0x68, 0x43, 0xb3, 0x1e, 0x71, 0xda, 0xa4, + 0xf7, 0xc0, 0x72, 0x3c, 0xbd, 0xd5, 0x1b, 0xba, 0x1e, 0xd5, 0xef, 0x93, 0xa1, 0xf8, 0xaa, 0xd6, + 0x01, 0xdf, 0x22, 0xde, 0xb6, 0xb0, 0xb9, 0xe5, 0xdc, 0xa3, 0x06, 0x79, 0x88, 0xaf, 0xc3, 0x2b, + 0x12, 0x46, 0xd3, 0x6c, 0xb7, 0x7b, 0x67, 0xd0, 0x05, 0xb4, 0x54, 0xa9, 0x9d, 0xf9, 0xdb, 0x27, + 0x57, 0x4e, 0x0b, 0x9f, 0x36, 0xda, 0xed, 0x1e, 0x61, 0xac, 0xee, 0xf5, 0x2c, 0xa7, 0x63, 0x9c, + 0x94, 0xe2, 0xfe, 0x6b, 0x75, 0x17, 0xce, 0x7c, 0xc3, 0x8f, 0xc9, 0x86, 0x6d, 0xcb, 0x95, 0x99, + 0x41, 0x1e, 0xf6, 0x09, 0xf3, 0xf0, 0x4d, 0x80, 0x28, 0xa2, 0x7c, 0xdd, 0x13, 0x6b, 0x6f, 0x6a, + 0x62, 0x51, 0x3f, 0xfc, 0x5a, 0x10, 0x4e, 0x11, 0x7e, 0x6d, 0xc7, 0xec, 0x10, 0xa1, 0x6b, 0xc4, + 0x34, 0xd5, 0x9f, 0x20, 0x38, 0x9b, 0x61, 0x84, 0xb9, 0xd4, 0x61, 0x04, 0xaf, 0x00, 0x8e, 0x1c, + 0x68, 0xb5, 0xb8, 0x13, 0xec, 0x0c, 0xba, 0x70, 0x74, 0xa9, 0x62, 0xcc, 0x85, 0x58, 0x5b, 0x2d, + 0x1f, 0x2e, 0xc3, 0xb7, 0x12, 0x98, 0x66, 0x38, 0xa6, 0x4b, 0x63, 0x31, 0x05, 0xa6, 0x12, 0xa0, + 0x3c, 0xc0, 0x12, 0xcb, 0x46, 0xa3, 0x2e, 0x42, 0xf4, 0x19, 0xa3, 0x89, 0x17, 0xe1, 0x84, 0x39, + 0x60, 0x5c, 0x93, 0x30, 0xc6, 0xe1, 0x55, 0x0c, 0x30, 0x07, 0x4c, 0x28, 0xa9, 0x8f, 0xe0, 0x3c, + 0x8f, 0x84, 0x34, 0xfd, 0xcd, 0xfa, 0x66, 0xc3, 0xb4, 0xfb, 0x32, 0x6c, 0xf8, 0x03, 0x98, 0x8b, + 0xec, 0x3b, 0xed, 0xa6, 0x39, 0x60, 0x22, 0xf0, 0x97, 0xb4, 0x8c, 0xfe, 0xd0, 0xd2, 0x2e, 0xd4, + 0x8e, 0x3d, 0x3d, 0x58, 0x44, 0xc6, 0xa9, 0x10, 0x97, 0xd3, 0xde, 0x18, 0x30, 0x75, 0x08, 0xaf, + 0xe7, 0x18, 0x16, 0x69, 0xf8, 0x16, 0x40, 0x9f, 0xb5, 0x9b, 0x03, 0xff, 0xa5, 0xb4, 0xb9, 0x5c, + 0x68, 0x73, 0xdb, 0xf5, 0x48, 0x5b, 0xae, 0x53, 0x7b, 0xe5, 0xf0, 0x60, 0xb1, 0x22, 0x9f, 0x98, + 0x51, 0xe9, 0xb3, 0x76, 0xf0, 0x53, 0xbd, 0x03, 0x9f, 0x0f, 0xb2, 0xdf, 0xa8, 0x8f, 0xba, 0xab, + 0x27, 0xe3, 0x15, 0x04, 0xfb, 0xd4, 0xe1, 0xc1, 0x22, 0x44, 0x0e, 0x25, 0xe2, 0xf7, 0x67, 0x34, + 0xe2, 0x47, 0xdd, 0x36, 0x59, 0x57, 0xf4, 0xc2, 0xff, 0x35, 0x82, 0x23, 0xdd, 0x30, 0xf3, 0xdc, + 0xdd, 0xb0, 0x07, 0xaf, 0xa6, 0xc0, 0xd7, 0x86, 0x5b, 0x9b, 0xf8, 0x4d, 0x98, 0x65, 0xfe, 0x8b, + 0xa6, 0xd5, 0x16, 0x91, 0x38, 0x71, 0x78, 0xb0, 0x78, 0x3c, 0x10, 0xda, 0x34, 0x8e, 0xf3, 0x8f, + 0x5b, 0x6d, 0xfc, 0x2e, 0x1c, 0xb3, 0x9c, 0x7b, 0x34, 0x84, 0x50, 0xe4, 0x55, 0x14, 0x1e, 0xae, + 0xa3, 0xfe, 0x11, 0x41, 0x35, 0x2f, 0x7e, 0xa2, 0x10, 0x76, 0xe0, 0x94, 0x69, 0xdb, 0x4d, 0x01, + 0xc5, 0x37, 0xe4, 0xf7, 0xe2, 0xb8, 0x62, 0x48, 0xb8, 0x62, 0x9c, 0x34, 0x6d, 0x3b, 0x7c, 0x33, + 0xbd, 0x9e, 0x6d, 0xc2, 0xb9, 0x04, 0xf8, 0x1b, 0xd4, 0x61, 0x77, 0xc9, 0x50, 0xa6, 0x7e, 0x19, + 0xe6, 0x53, 0x93, 0x24, 0x88, 0xa4, 0xf1, 0xb9, 0x91, 0x41, 0x82, 0x4f, 0xc3, 0x4b, 0xad, 0xae, + 0x69, 0x39, 0xa2, 0x47, 0x83, 0x07, 0xf5, 0x87, 0x68, 0xa4, 0x3f, 0x43, 0x0b, 0x22, 0x38, 0x1b, + 0x00, 0x6e, 0x7f, 0xd7, 0xb6, 0x5a, 0xcd, 0xfb, 0x64, 0x28, 0xea, 0xea, 0xbc, 0x16, 0x8d, 0x6d, + 0x2d, 0x18, 0xdb, 0xda, 0x0e, 0x17, 0xba, 0x4b, 0x86, 0xb5, 0x63, 0x4f, 0x0e, 0x16, 0x8f, 0x18, + 0x15, 0x57, 0xbe, 0xc0, 0xaf, 0x03, 0x50, 0xd7, 0xb3, 0x9c, 0x4e, 0x93, 0xf6, 0x3d, 0x6e, 0x7e, + 0xd6, 0xa8, 0x04, 0x6f, 0xb6, 0xfb, 0x9e, 0xda, 0x82, 0xc5, 0x14, 0x02, 0xd9, 0x09, 0x53, 0xf3, + 0xf3, 0x7b, 0x70, 0x21, 0xdf, 0x88, 0x70, 0xf5, 0x1c, 0x54, 0x5a, 0xd4, 0x61, 0xf1, 0xd5, 0x67, + 0x5b, 0x42, 0x6e, 0x9c, 0x13, 0x1f, 0x22, 0x58, 0x1a, 0x9d, 0xf8, 0x22, 0x94, 0xac, 0x36, 0xbc, + 0xe1, 0x63, 0xd8, 0xda, 0x94, 0xee, 0x84, 0x10, 0x51, 0x0c, 0xe2, 0xd4, 0xda, 0xed, 0x2f, 0x08, + 0x2e, 0x97, 0x80, 0x22, 0x9c, 0x6e, 0xc4, 0x36, 0x23, 0xee, 0xbd, 0xbf, 0xff, 0x8a, 0x06, 0x58, + 0x2a, 0x6c, 0x00, 0xb1, 0xe6, 0x8e, 0x69, 0xf5, 0xa2, 0x6d, 0x4b, 0x1a, 0x9a, 0x5e, 0x0b, 0x7c, + 0x8c, 0x60, 0x21, 0xc3, 0xe4, 0x44, 0x35, 0xb1, 0x9e, 0x28, 0xe2, 0x99, 0xf1, 0x45, 0x9c, 0x5f, + 0xbe, 0x47, 0x47, 0x33, 0xff, 0xe3, 0x9c, 0x70, 0xf3, 0xdd, 0xfb, 0x05, 0xa7, 0xfe, 0x29, 0x82, + 0xe5, 0x32, 0x58, 0x44, 0xee, 0xbf, 0x0d, 0x0b, 0xc9, 0xdc, 0x47, 0x27, 0x91, 0x13, 0x6b, 0x97, + 0xc7, 0x26, 0xdf, 0x5f, 0x95, 0x67, 0x7f, 0x9e, 0x8e, 0xda, 0x9a, 0x5e, 0xfa, 0x7f, 0x00, 0xa7, + 0xb3, 0x6c, 0x4e, 0x94, 0xfe, 0x44, 0x63, 0xcf, 0x14, 0x36, 0x76, 0x2a, 0xbd, 0xef, 0x80, 0x9a, + 0x3a, 0xc9, 0xd5, 0x86, 0xdb, 0xae, 0xb7, 0xe5, 0x6c, 0x34, 0xea, 0x32, 0xad, 0x73, 0x70, 0x54, + 0x6e, 0xbb, 0x15, 0xc3, 0xff, 0xa9, 0xde, 0x81, 0x8b, 0x85, 0x7a, 0x22, 0x05, 0x17, 0x63, 0xc7, + 0x2f, 0xdb, 0x62, 0x9e, 0x38, 0x06, 0x86, 0x87, 0xac, 0xf7, 0x2d, 0xe6, 0xa9, 0xeb, 0xe2, 0x08, + 0xb0, 0x61, 0xdb, 0x1b, 0x8d, 0x3a, 0x5f, 0x26, 0xf8, 0x2a, 0xcd, 0x2b, 0x30, 0x2b, 0x15, 0xe4, + 0xe0, 0x92, 0xcf, 0xea, 0xba, 0xd8, 0xff, 0x32, 0x94, 0x05, 0x86, 0xb3, 0x30, 0xeb, 0x9f, 0x49, + 0x62, 0xe6, 0x8f, 0x9b, 0x03, 0xc6, 0x2d, 0x3b, 0xb0, 0x20, 0xc6, 0xa6, 0xf7, 0x22, 0x8e, 0x1c, + 0xaa, 0x06, 0x0a, 0xb7, 0x57, 0x77, 0x4c, 0x97, 0x75, 0xa9, 0x77, 0x9b, 0xd8, 0x2e, 0xe9, 0xe5, + 0x47, 0x79, 0x4b, 0x44, 0xa6, 0xee, 0x92, 0x96, 0x75, 0xcf, 0x22, 0x6d, 0xa9, 0x98, 0xab, 0x82, + 0x5f, 0x83, 0x97, 0xbb, 0xc4, 0xea, 0x74, 0x83, 0x21, 0x7e, 0xd4, 0x10, 0x4f, 0xea, 0xcf, 0x10, + 0x9c, 0x6f, 0x50, 0x3f, 0xed, 0x3b, 0xf4, 0x11, 0xe9, 0xc9, 0x85, 0xee, 0x92, 0xe1, 0x6d, 0x2e, + 0x80, 0x35, 0x58, 0x60, 0xe2, 0xa5, 0x3f, 0x46, 0x9a, 0x62, 0x15, 0xc4, 0x57, 0x99, 0x67, 0x29, + 0xf9, 0x4d, 0x98, 0x95, 0x2f, 0x45, 0x03, 0x64, 0xcf, 0xd3, 0x0c, 0xa3, 0x46, 0xa8, 0xa9, 0x32, + 0x79, 0x96, 0xb4, 0xed, 0xf1, 0xbe, 0x4d, 0x6b, 0x8e, 0x7c, 0x82, 0x22, 0x92, 0x14, 0x59, 0x15, + 0xe5, 0xb2, 0x0d, 0x15, 0x89, 0x4e, 0xce, 0x8a, 0xd5, 0xb2, 0x8e, 0x85, 0xd1, 0x31, 0xa2, 0x35, + 0xa6, 0x37, 0x2b, 0x06, 0xf0, 0x1a, 0x47, 0xdd, 0x90, 0xcc, 0x94, 0xbd, 0x98, 0xb1, 0xfb, 0x1b, + 0x24, 0x92, 0x14, 0x37, 0x2c, 0xa2, 0xb5, 0x05, 0x10, 0x12, 0x65, 0x19, 0xae, 0x6a, 0x76, 0xb8, + 0xa4, 0x58, 0xad, 0xe2, 0x9f, 0xa0, 0x7e, 0xfd, 0xef, 0xdf, 0x2d, 0x23, 0x23, 0xa6, 0x3c, 0xbd, + 0x38, 0xf5, 0xe1, 0xd5, 0x24, 0xdc, 0x88, 0xff, 0xe2, 0xd0, 0xde, 0xc8, 0x54, 0x2d, 0x60, 0x84, + 0x73, 0xa1, 0x4e, 0xf1, 0x19, 0xcc, 0x1c, 0x4d, 0x4f, 0x18, 0xa4, 0x5b, 0x50, 0x09, 0xd7, 0x10, + 0x83, 0x64, 0x82, 0x18, 0x45, 0xba, 0x6b, 0x9f, 0x9e, 0x85, 0x97, 0xb8, 0x0d, 0xfc, 0x73, 0x04, + 0xf3, 0x89, 0x13, 0x1f, 0x3f, 0x98, 0x67, 0x8f, 0xa7, 0xf4, 0x25, 0x83, 0xf2, 0x46, 0xe1, 0x1c, + 0xf3, 0xa5, 0xd4, 0x77, 0x7f, 0xf4, 0xe9, 0xbf, 0x7e, 0x3a, 0x73, 0x0d, 0xaf, 0xe9, 0x59, 0xb7, + 0x23, 0xe1, 0x7c, 0xf4, 0x09, 0x85, 0xbe, 0x97, 0xe0, 0xd8, 0xfb, 0xf8, 0x17, 0x12, 0x5d, 0x7c, + 0x7b, 0xc0, 0x57, 0x32, 0x8d, 0xe6, 0xdd, 0x56, 0x28, 0x5a, 0x59, 0xf1, 0x20, 0xca, 0xea, 0x32, + 0x07, 0xfc, 0x05, 0xac, 0x66, 0x02, 0xf6, 0x29, 0x10, 0x0d, 0xa1, 0xfc, 0x75, 0x94, 0x36, 0x89, + 0xa3, 0xd7, 0x4d, 0xda, 0x13, 0xa7, 0x08, 0xfc, 0xc5, 0x7c, 0xf3, 0xd9, 0x74, 0x45, 0x59, 0x9d, + 0x40, 0x43, 0x60, 0xbe, 0xc3, 0x31, 0x6f, 0xe2, 0x5a, 0x71, 0x90, 0xe5, 0xc9, 0x35, 0x1e, 0x68, + 0x51, 0xbe, 0xfb, 0xfa, 0x1e, 0x2f, 0xbf, 0x7d, 0x7c, 0x80, 0xc4, 0x5e, 0x9e, 0x41, 0x02, 0x62, + 0x7e, 0x5d, 0x2b, 0x87, 0x32, 0x49, 0x51, 0x94, 0xb7, 0x27, 0xd4, 0x12, 0xfe, 0xdd, 0xe5, 0xfe, + 0xbd, 0x87, 0x6f, 0x94, 0xf0, 0xcf, 0xf7, 0xa6, 0xd0, 0xc1, 0x7f, 0x20, 0x78, 0x63, 0xec, 0xc9, + 0x1f, 0x5f, 0x2f, 0x55, 0x36, 0x79, 0xe4, 0x45, 0xf9, 0xea, 0xf3, 0xaa, 0x0b, 0x8f, 0xd7, 0xb9, + 0xc7, 0x6f, 0xe3, 0xab, 0x63, 0xab, 0x30, 0xe2, 0x23, 0xa1, 0x87, 0xff, 0x41, 0x62, 0x74, 0x8d, + 0xde, 0xea, 0xe0, 0x12, 0xb5, 0x35, 0x72, 0x17, 0xa3, 0xac, 0x4d, 0xa2, 0x22, 0xd0, 0x53, 0x8e, + 0xde, 0xc2, 0x9d, 0xe2, 0x7c, 0x85, 0x17, 0x4b, 0xf1, 0x7c, 0x05, 0x07, 0x25, 0x2d, 0x39, 0x0a, + 0x32, 0x04, 0x62, 0x17, 0x44, 0xfb, 0xf8, 0x23, 0x04, 0x73, 0xa3, 0x97, 0x49, 0x78, 0xa5, 0x20, + 0x07, 0xa9, 0x3b, 0x27, 0x45, 0xcd, 0x94, 0xde, 0x24, 0x2d, 0x2e, 0x75, 0xd3, 0x22, 0x76, 0x7b, + 0xdc, 0x6c, 0x18, 0xb0, 0xc8, 0x25, 0xfc, 0x5f, 0x24, 0x06, 0x79, 0xea, 0x2a, 0x04, 0x97, 0x08, + 0xe9, 0xe8, 0xfd, 0x95, 0x72, 0x75, 0x22, 0x1d, 0x91, 0x07, 0x97, 0xe3, 0xfd, 0x3e, 0xee, 0x16, + 0xe7, 0x21, 0xba, 0xd3, 0xf9, 0xcc, 0x89, 0x78, 0x86, 0xd2, 0x4c, 0x20, 0xcd, 0xad, 0x70, 0xf9, + 0xf6, 0xc8, 0x24, 0x88, 0xca, 0xd7, 0x9e, 0x5b, 0x5f, 0x44, 0xe6, 0x2b, 0x3c, 0x32, 0xef, 0xe0, + 0x6b, 0x25, 0xfb, 0x8b, 0x73, 0xbe, 0xb0, 0xc1, 0x9e, 0xa0, 0x88, 0x6b, 0x84, 0x3b, 0xc8, 0x07, + 0x96, 0xd7, 0x95, 0xcc, 0x05, 0x7f, 0xa9, 0xdc, 0xae, 0x93, 0xe2, 0x48, 0xca, 0x97, 0x27, 0x57, + 0x14, 0x2e, 0x5d, 0xe3, 0x2e, 0x69, 0x78, 0x25, 0x27, 0xd9, 0x9e, 0x9e, 0xe0, 0x50, 0xfa, 0x9e, + 0x39, 0x60, 0xfb, 0xf8, 0x0f, 0xb2, 0x4c, 0x53, 0xcc, 0xa7, 0xa8, 0x4c, 0xf3, 0x38, 0x56, 0x51, + 0x99, 0xe6, 0x52, 0xab, 0x12, 0xc8, 0x25, 0xf3, 0x8a, 0xca, 0x6f, 0x1f, 0xff, 0x09, 0xc1, 0xc9, + 0x38, 0xed, 0xc2, 0x4b, 0x45, 0x2d, 0x12, 0x67, 0x66, 0x4a, 0x35, 0xe7, 0xdc, 0xe2, 0x91, 0x36, + 0x3f, 0xb4, 0x10, 0x0e, 0xa8, 0x89, 0xbf, 0x9b, 0x07, 0x68, 0x3a, 0xcd, 0xf2, 0x4b, 0x24, 0x88, + 0x63, 0x92, 0xc8, 0x61, 0x3d, 0xdf, 0x91, 0x4c, 0xca, 0xa7, 0x5c, 0xcc, 0x54, 0x48, 0xca, 0xaa, + 0x6b, 0xdc, 0xa9, 0x15, 0xbc, 0x9c, 0xe9, 0x54, 0x48, 0xda, 0xba, 0x5c, 0x5a, 0x54, 0xc7, 0xef, + 0x65, 0x75, 0xa4, 0xa8, 0x63, 0x51, 0x75, 0xe4, 0xf1, 0x4c, 0x65, 0x72, 0x06, 0x34, 0xa6, 0x36, + 0x24, 0xea, 0x00, 0xae, 0xbe, 0x17, 0xb0, 0xcd, 0x7d, 0xfc, 0xab, 0x70, 0x3f, 0x88, 0xa8, 0x59, + 0xe1, 0x7e, 0x90, 0xe2, 0x8d, 0xca, 0x95, 0x92, 0xd2, 0xa2, 0x86, 0x75, 0x8e, 0xf3, 0x32, 0xbe, + 0x94, 0x3b, 0x50, 0x92, 0x58, 0xf1, 0xc7, 0x08, 0x20, 0x62, 0x42, 0xf8, 0xad, 0x7c, 0x73, 0x29, + 0xa2, 0xa6, 0xac, 0x94, 0x13, 0x96, 0xed, 0xf5, 0xa1, 0x4f, 0x00, 0x0a, 0xf1, 0x45, 0xfc, 0x29, + 0x9c, 0x71, 0xbf, 0x45, 0x50, 0x09, 0x17, 0xc3, 0xcb, 0x25, 0x2c, 0x4a, 0x74, 0x6f, 0x95, 0x92, + 0x15, 0xe0, 0x6e, 0x47, 0xe0, 0xae, 0xe3, 0xf5, 0x62, 0x70, 0xfa, 0x5e, 0x9a, 0x77, 0x85, 0xe7, + 0xba, 0xda, 0xfb, 0x4f, 0x0e, 0xab, 0xe8, 0xe9, 0x61, 0x15, 0xfd, 0xf3, 0xb0, 0x8a, 0x3e, 0x7a, + 0x56, 0x3d, 0xf2, 0xf4, 0x59, 0xf5, 0xc8, 0xdf, 0x9f, 0x55, 0x8f, 0x7c, 0x67, 0xad, 0x63, 0x79, + 0xdd, 0xfe, 0xae, 0xd6, 0xa2, 0x0f, 0xf4, 0xf7, 0x02, 0x03, 0x5f, 0x27, 0xde, 0x23, 0xda, 0xbb, + 0x1f, 0xda, 0x7b, 0x1c, 0x59, 0xf4, 0x86, 0x2e, 0x61, 0xbb, 0x2f, 0xf3, 0x7f, 0xae, 0x5e, 0xfd, + 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2e, 0xbe, 0xb3, 0x4f, 0xa0, 0x1e, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1750,6 +2046,12 @@ type QueryClient interface { QueryAllAVSsByOperator(ctx context.Context, in *QueryAllAVSsByOperatorRequest, opts ...grpc.CallOption) (*QueryAllAVSsByOperatorResponse, error) // QueryOptInfo queries specified opted information. QueryOptInfo(ctx context.Context, in *QueryOptInfoRequest, opts ...grpc.CallOption) (*OptedInfo, error) + // QuerySnapshotHelper queries the snapshot helper of the AVS + QuerySnapshotHelper(ctx context.Context, in *QuerySnapshotHelperRequest, opts ...grpc.CallOption) (*SnapshotHelper, error) + // QuerySpecifiedSnapshot queries the voting power snapshot of specified AVS and height + QuerySpecifiedSnapshot(ctx context.Context, in *QuerySpecifiedSnapshotRequest, opts ...grpc.CallOption) (*VotingPowerSnapshotKeyHeight, error) + // QueryAllSnapshot queries all voting power snapshot for the specified AVS + QueryAllSnapshot(ctx context.Context, in *QueryAllSnapshotRequest, opts ...grpc.CallOption) (*QueryAllSnapshotResponse, error) // Validators queries all validators that match the given status. // When called from another module, this query might consume a high amount of // gas if the pagination field is incorrectly set. @@ -1874,6 +2176,33 @@ func (c *queryClient) QueryOptInfo(ctx context.Context, in *QueryOptInfoRequest, return out, nil } +func (c *queryClient) QuerySnapshotHelper(ctx context.Context, in *QuerySnapshotHelperRequest, opts ...grpc.CallOption) (*SnapshotHelper, error) { + out := new(SnapshotHelper) + err := c.cc.Invoke(ctx, "/exocore.operator.v1.Query/QuerySnapshotHelper", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) QuerySpecifiedSnapshot(ctx context.Context, in *QuerySpecifiedSnapshotRequest, opts ...grpc.CallOption) (*VotingPowerSnapshotKeyHeight, error) { + out := new(VotingPowerSnapshotKeyHeight) + err := c.cc.Invoke(ctx, "/exocore.operator.v1.Query/QuerySpecifiedSnapshot", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) QueryAllSnapshot(ctx context.Context, in *QueryAllSnapshotRequest, opts ...grpc.CallOption) (*QueryAllSnapshotResponse, error) { + out := new(QueryAllSnapshotResponse) + err := c.cc.Invoke(ctx, "/exocore.operator.v1.Query/QueryAllSnapshot", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) Validators(ctx context.Context, in *QueryValidatorsRequest, opts ...grpc.CallOption) (*QueryValidatorsResponse, error) { out := new(QueryValidatorsResponse) err := c.cc.Invoke(ctx, "/exocore.operator.v1.Query/Validators", in, out, opts...) @@ -1920,6 +2249,12 @@ type QueryServer interface { QueryAllAVSsByOperator(context.Context, *QueryAllAVSsByOperatorRequest) (*QueryAllAVSsByOperatorResponse, error) // QueryOptInfo queries specified opted information. QueryOptInfo(context.Context, *QueryOptInfoRequest) (*OptedInfo, error) + // QuerySnapshotHelper queries the snapshot helper of the AVS + QuerySnapshotHelper(context.Context, *QuerySnapshotHelperRequest) (*SnapshotHelper, error) + // QuerySpecifiedSnapshot queries the voting power snapshot of specified AVS and height + QuerySpecifiedSnapshot(context.Context, *QuerySpecifiedSnapshotRequest) (*VotingPowerSnapshotKeyHeight, error) + // QueryAllSnapshot queries all voting power snapshot for the specified AVS + QueryAllSnapshot(context.Context, *QueryAllSnapshotRequest) (*QueryAllSnapshotResponse, error) // Validators queries all validators that match the given status. // When called from another module, this query might consume a high amount of // gas if the pagination field is incorrectly set. @@ -1968,6 +2303,15 @@ func (*UnimplementedQueryServer) QueryAllAVSsByOperator(ctx context.Context, req func (*UnimplementedQueryServer) QueryOptInfo(ctx context.Context, req *QueryOptInfoRequest) (*OptedInfo, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryOptInfo not implemented") } +func (*UnimplementedQueryServer) QuerySnapshotHelper(ctx context.Context, req *QuerySnapshotHelperRequest) (*SnapshotHelper, error) { + return nil, status.Errorf(codes.Unimplemented, "method QuerySnapshotHelper not implemented") +} +func (*UnimplementedQueryServer) QuerySpecifiedSnapshot(ctx context.Context, req *QuerySpecifiedSnapshotRequest) (*VotingPowerSnapshotKeyHeight, error) { + return nil, status.Errorf(codes.Unimplemented, "method QuerySpecifiedSnapshot not implemented") +} +func (*UnimplementedQueryServer) QueryAllSnapshot(ctx context.Context, req *QueryAllSnapshotRequest) (*QueryAllSnapshotResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAllSnapshot not implemented") +} func (*UnimplementedQueryServer) Validators(ctx context.Context, req *QueryValidatorsRequest) (*QueryValidatorsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Validators not implemented") } @@ -2195,6 +2539,60 @@ func _Query_QueryOptInfo_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Query_QuerySnapshotHelper_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySnapshotHelperRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QuerySnapshotHelper(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.operator.v1.Query/QuerySnapshotHelper", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QuerySnapshotHelper(ctx, req.(*QuerySnapshotHelperRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_QuerySpecifiedSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySpecifiedSnapshotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QuerySpecifiedSnapshot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.operator.v1.Query/QuerySpecifiedSnapshot", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QuerySpecifiedSnapshot(ctx, req.(*QuerySpecifiedSnapshotRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_QueryAllSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllSnapshotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryAllSnapshot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.operator.v1.Query/QueryAllSnapshot", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryAllSnapshot(ctx, req.(*QueryAllSnapshotRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_Validators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryValidatorsRequest) if err := dec(in); err != nil { @@ -2283,6 +2681,18 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryOptInfo", Handler: _Query_QueryOptInfo_Handler, }, + { + MethodName: "QuerySnapshotHelper", + Handler: _Query_QuerySnapshotHelper_Handler, + }, + { + MethodName: "QuerySpecifiedSnapshot", + Handler: _Query_QuerySpecifiedSnapshot_Handler, + }, + { + MethodName: "QueryAllSnapshot", + Handler: _Query_QueryAllSnapshot_Handler, + }, { MethodName: "Validators", Handler: _Query_Validators_Handler, @@ -3277,7 +3687,7 @@ func (m *QueryOptInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QueryValidatorsRequest) Marshal() (dAtA []byte, err error) { +func (m *QuerySnapshotHelperRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3287,39 +3697,235 @@ func (m *QueryValidatorsRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryValidatorsRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QuerySnapshotHelperRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryValidatorsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QuerySnapshotHelperRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Chain) > 0 { - i -= len(m.Chain) - copy(dAtA[i:], m.Chain) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Chain))) + if len(m.Avs) > 0 { + i -= len(m.Avs) + copy(dAtA[i:], m.Avs) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Avs))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *QueryValidatorsResponse) Marshal() (dAtA []byte, err error) { +func (m *QuerySpecifiedSnapshotRequest) 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 *QuerySpecifiedSnapshotRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySpecifiedSnapshotRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x10 + } + if len(m.Avs) > 0 { + i -= len(m.Avs) + copy(dAtA[i:], m.Avs) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Avs))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *VotingPowerSnapshotKeyHeight) 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 *VotingPowerSnapshotKeyHeight) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VotingPowerSnapshotKeyHeight) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Snapshot != nil { + { + size, err := m.Snapshot.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.SnapshotKeyHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SnapshotKeyHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryAllSnapshotRequest) 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 *QueryAllSnapshotRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllSnapshotRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Avs) > 0 { + i -= len(m.Avs) + copy(dAtA[i:], m.Avs) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Avs))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllSnapshotResponse) 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 *QueryAllSnapshotResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllSnapshotResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Snapshots) > 0 { + for iNdEx := len(m.Snapshots) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Snapshots[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 (m *QueryValidatorsRequest) 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 *QueryValidatorsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryValidatorsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Chain) > 0 { + i -= len(m.Chain) + copy(dAtA[i:], m.Chain) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Chain))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryValidatorsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3848,6 +4454,87 @@ func (m *QueryOptInfoRequest) Size() (n int) { return n } +func (m *QuerySnapshotHelperRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Avs) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySpecifiedSnapshotRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Avs) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + return n +} + +func (m *VotingPowerSnapshotKeyHeight) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SnapshotKeyHeight != 0 { + n += 1 + sovQuery(uint64(m.SnapshotKeyHeight)) + } + if m.Snapshot != nil { + l = m.Snapshot.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllSnapshotRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Avs) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllSnapshotResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Snapshots) > 0 { + for _, e := range m.Snapshots { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryValidatorsRequest) Size() (n int) { if m == nil { return 0 @@ -6527,6 +7214,532 @@ func (m *QueryOptInfoRequest) Unmarshal(dAtA []byte) error { } return nil } +func (m *QuerySnapshotHelperRequest) 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: QuerySnapshotHelperRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySnapshotHelperRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Avs", 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.Avs = 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 *QuerySpecifiedSnapshotRequest) 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: QuerySpecifiedSnapshotRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySpecifiedSnapshotRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Avs", 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.Avs = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(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 (m *VotingPowerSnapshotKeyHeight) 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: VotingPowerSnapshotKeyHeight: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VotingPowerSnapshotKeyHeight: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotKeyHeight", wireType) + } + m.SnapshotKeyHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SnapshotKeyHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Snapshot", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Snapshot == nil { + m.Snapshot = &VotingPowerSnapshot{} + } + if err := m.Snapshot.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 (m *QueryAllSnapshotRequest) 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: QueryAllSnapshotRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllSnapshotRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Avs", 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.Avs = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllSnapshotResponse) 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: QueryAllSnapshotResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllSnapshotResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Snapshots", 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.Snapshots = append(m.Snapshots, &VotingPowerSnapshotKeyHeight{}) + if err := m.Snapshots[len(m.Snapshots)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryValidatorsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/operator/types/query.pb.gw.go b/x/operator/types/query.pb.gw.go index b32be73fe..c291dd23e 100644 --- a/x/operator/types/query.pb.gw.go +++ b/x/operator/types/query.pb.gw.go @@ -845,6 +845,208 @@ func local_request_Query_QueryOptInfo_0(ctx context.Context, marshaler runtime.M } +func request_Query_QuerySnapshotHelper_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySnapshotHelperRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["avs"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "avs") + } + + protoReq.Avs, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "avs", err) + } + + msg, err := client.QuerySnapshotHelper(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QuerySnapshotHelper_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySnapshotHelperRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["avs"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "avs") + } + + protoReq.Avs, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "avs", err) + } + + msg, err := server.QuerySnapshotHelper(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_QuerySpecifiedSnapshot_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySpecifiedSnapshotRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["avs"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "avs") + } + + protoReq.Avs, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "avs", err) + } + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := client.QuerySpecifiedSnapshot(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QuerySpecifiedSnapshot_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySpecifiedSnapshotRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["avs"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "avs") + } + + protoReq.Avs, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "avs", err) + } + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := server.QuerySpecifiedSnapshot(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_QueryAllSnapshot_0 = &utilities.DoubleArray{Encoding: map[string]int{"avs": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_QueryAllSnapshot_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllSnapshotRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["avs"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "avs") + } + + protoReq.Avs, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "avs", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_QueryAllSnapshot_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.QueryAllSnapshot(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryAllSnapshot_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllSnapshotRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["avs"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "avs") + } + + protoReq.Avs, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "avs", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_QueryAllSnapshot_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.QueryAllSnapshot(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_Validators_0 = &utilities.DoubleArray{Encoding: map[string]int{"chain": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -1275,6 +1477,75 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_QuerySnapshotHelper_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_QuerySnapshotHelper_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_QuerySnapshotHelper_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QuerySpecifiedSnapshot_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_QuerySpecifiedSnapshot_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_QuerySpecifiedSnapshot_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryAllSnapshot_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_QueryAllSnapshot_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_QueryAllSnapshot_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Validators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1602,6 +1873,66 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_QuerySnapshotHelper_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_QuerySnapshotHelper_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_QuerySnapshotHelper_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QuerySpecifiedSnapshot_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_QuerySpecifiedSnapshot_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_QuerySpecifiedSnapshot_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryAllSnapshot_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_QueryAllSnapshot_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_QueryAllSnapshot_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Validators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1656,11 +1987,11 @@ var ( pattern_Query_QueryAllOperatorConsKeysByChainID_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"exocore", "operator", "v1", "all_operator_cons_keys", "chain"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_QueryOperatorUSDValue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "query_operator_usd_value", "operator_and_avs.operator_addr", "operator_and_avs.avs_address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryOperatorUSDValue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "operator_usd_value", "operator_and_avs.operator_addr", "operator_and_avs.avs_address"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_QueryAVSUSDValue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"exocore", "operator", "v1", "QueryAVSUSDValue"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryAVSUSDValue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"exocore", "operator", "v1", "avs_usd_value"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_QueryOperatorSlashInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "query_operator_slash_info", "operator_and_avs.operator_addr", "operator_and_avs.avs_address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryOperatorSlashInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "operator_slash_info", "operator_and_avs.operator_addr", "operator_and_avs.avs_address"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_QueryAllOperatorConsAddrsByChainID_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"exocore", "operator", "v1", "all_operator_cons_addrs", "chain"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1670,6 +2001,12 @@ var ( pattern_Query_QueryOptInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "opt_info", "operator_and_avs.operator_addr", "operator_and_avs.avs_address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QuerySnapshotHelper_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"exocore", "operator", "v1", "snapshot_helper", "avs"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QuerySpecifiedSnapshot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "snapshot", "avs", "height"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryAllSnapshot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"exocore", "operator", "v1", "all_snapshot", "avs"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Validators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"exocore", "operator", "v1", "validators", "chain"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Validator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "operator", "v1", "validator", "validator_acc_addr", "chain"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1700,6 +2037,12 @@ var ( forward_Query_QueryOptInfo_0 = runtime.ForwardResponseMessage + forward_Query_QuerySnapshotHelper_0 = runtime.ForwardResponseMessage + + forward_Query_QuerySpecifiedSnapshot_0 = runtime.ForwardResponseMessage + + forward_Query_QueryAllSnapshot_0 = runtime.ForwardResponseMessage + forward_Query_Validators_0 = runtime.ForwardResponseMessage forward_Query_Validator_0 = runtime.ForwardResponseMessage diff --git a/x/operator/types/tx.pb.go b/x/operator/types/tx.pb.go index 1f5a8c1ed..9e00f26ea 100644 --- a/x/operator/types/tx.pb.go +++ b/x/operator/types/tx.pb.go @@ -152,6 +152,199 @@ func (m *OperatorOptedUSDValue) XXX_DiscardUnknown() { var xxx_messageInfo_OperatorOptedUSDValue proto.InternalMessageInfo +// OperatorVotingPower represents the voting power for the specified operator address +type OperatorVotingPower struct { + // operator_addr is the operator address,its type should be a sdk.AccAddress + OperatorAddr string `protobuf:"bytes,1,opt,name=operator_addr,json=operatorAddr,proto3" json:"operator_addr,omitempty"` + // voting_power is the active voting power for the above operator address + VotingPower github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=voting_power,json=votingPower,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"voting_power"` +} + +func (m *OperatorVotingPower) Reset() { *m = OperatorVotingPower{} } +func (m *OperatorVotingPower) String() string { return proto.CompactTextString(m) } +func (*OperatorVotingPower) ProtoMessage() {} +func (*OperatorVotingPower) Descriptor() ([]byte, []int) { + return fileDescriptor_b229d5663e4df167, []int{2} +} +func (m *OperatorVotingPower) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OperatorVotingPower) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OperatorVotingPower.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 *OperatorVotingPower) XXX_Merge(src proto.Message) { + xxx_messageInfo_OperatorVotingPower.Merge(m, src) +} +func (m *OperatorVotingPower) XXX_Size() int { + return m.Size() +} +func (m *OperatorVotingPower) XXX_DiscardUnknown() { + xxx_messageInfo_OperatorVotingPower.DiscardUnknown(m) +} + +var xxx_messageInfo_OperatorVotingPower proto.InternalMessageInfo + +func (m *OperatorVotingPower) GetOperatorAddr() string { + if m != nil { + return m.OperatorAddr + } + return "" +} + +// VotingPowerSnapshot records historical voting power for AVSs at specific epochs +// or after slashing events.These snapshots are created at the end of each epoch and +// when slashing occurs, enabling historical queries of operator voting power at +// specific points in time. +type VotingPowerSnapshot struct { + // total_voting_power is the total voting power of specified AVS + TotalVotingPower github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=total_voting_power,json=totalVotingPower,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_voting_power"` + // operator_voting_powers records the active voting power of all operators + // for the specified AVS + OperatorVotingPowers []*OperatorVotingPower `protobuf:"bytes,2,rep,name=operator_voting_powers,json=operatorVotingPowers,proto3" json:"operator_voting_powers,omitempty"` + // last_changed_height is used to indicate the height of most recent change when + // the operator_voting_powers is nil, which can help to fall back to the correct epoch height. + LastChangedHeight int64 `protobuf:"varint,3,opt,name=last_changed_height,json=lastChangedHeight,proto3" json:"last_changed_height,omitempty"` + // epoch_identifier record the epoch info + EpochIdentifier string `protobuf:"bytes,4,opt,name=epoch_identifier,json=epochIdentifier,proto3" json:"epoch_identifier,omitempty"` + // epoch_number indicates which epoch this snapshot serve for + EpochNumber int64 `protobuf:"varint,5,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` +} + +func (m *VotingPowerSnapshot) Reset() { *m = VotingPowerSnapshot{} } +func (m *VotingPowerSnapshot) String() string { return proto.CompactTextString(m) } +func (*VotingPowerSnapshot) ProtoMessage() {} +func (*VotingPowerSnapshot) Descriptor() ([]byte, []int) { + return fileDescriptor_b229d5663e4df167, []int{3} +} +func (m *VotingPowerSnapshot) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VotingPowerSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VotingPowerSnapshot.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 *VotingPowerSnapshot) XXX_Merge(src proto.Message) { + xxx_messageInfo_VotingPowerSnapshot.Merge(m, src) +} +func (m *VotingPowerSnapshot) XXX_Size() int { + return m.Size() +} +func (m *VotingPowerSnapshot) XXX_DiscardUnknown() { + xxx_messageInfo_VotingPowerSnapshot.DiscardUnknown(m) +} + +var xxx_messageInfo_VotingPowerSnapshot proto.InternalMessageInfo + +func (m *VotingPowerSnapshot) GetOperatorVotingPowers() []*OperatorVotingPower { + if m != nil { + return m.OperatorVotingPowers + } + return nil +} + +func (m *VotingPowerSnapshot) GetLastChangedHeight() int64 { + if m != nil { + return m.LastChangedHeight + } + return 0 +} + +func (m *VotingPowerSnapshot) GetEpochIdentifier() string { + if m != nil { + return m.EpochIdentifier + } + return "" +} + +func (m *VotingPowerSnapshot) GetEpochNumber() int64 { + if m != nil { + return m.EpochNumber + } + return 0 +} + +// SnapshotHelper is used to record the helper information for voting power snapshot update +type SnapshotHelper struct { + // last_changed_height indicates the height of the most recent change. + // It is used to set the `last_changed_height` field in `VotingPowerSnapshot`. + LastChangedHeight int64 `protobuf:"varint,1,opt,name=last_changed_height,json=lastChangedHeight,proto3" json:"last_changed_height,omitempty"` + // has_opt_out is used to indicate whether there has been any opt-out operation from + // the most recently saved snapshot to the current height. This is because, + // when an opt-out operation occurs, the related AVS validator information changes, + // and the snapshot needs to be updated. + // Currently, a boolean variable is used instead of an operator list + // because the snapshot is set by default to store all operator information related to AVS. + // Therefore, as long as any operator has opted out, the snapshot needs to be updated. + // If we later introduce a limit on the maximum number of validators in AVS, + // similar to the MaxValidatorNumber in Dogfood, this may need to be changed to an operator list + // to track all operators that have opted out, thereby assisting with the correct snapshot update. + HasOptOut bool `protobuf:"varint,2,opt,name=has_opt_out,json=hasOptOut,proto3" json:"has_opt_out,omitempty"` +} + +func (m *SnapshotHelper) Reset() { *m = SnapshotHelper{} } +func (m *SnapshotHelper) String() string { return proto.CompactTextString(m) } +func (*SnapshotHelper) ProtoMessage() {} +func (*SnapshotHelper) Descriptor() ([]byte, []int) { + return fileDescriptor_b229d5663e4df167, []int{4} +} +func (m *SnapshotHelper) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotHelper) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotHelper.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 *SnapshotHelper) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotHelper.Merge(m, src) +} +func (m *SnapshotHelper) XXX_Size() int { + return m.Size() +} +func (m *SnapshotHelper) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotHelper.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotHelper proto.InternalMessageInfo + +func (m *SnapshotHelper) GetLastChangedHeight() int64 { + if m != nil { + return m.LastChangedHeight + } + return 0 +} + +func (m *SnapshotHelper) GetHasOptOut() bool { + if m != nil { + return m.HasOptOut + } + return false +} + // ClientChainEarningAddrList is the list of client chain earning addresses. // Because the reward token provide by the AVS might be located at different client chain, the operator need to // provide the different client chain address to receive the token rewards. @@ -164,7 +357,7 @@ func (m *ClientChainEarningAddrList) Reset() { *m = ClientChainEarningAd func (m *ClientChainEarningAddrList) String() string { return proto.CompactTextString(m) } func (*ClientChainEarningAddrList) ProtoMessage() {} func (*ClientChainEarningAddrList) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{2} + return fileDescriptor_b229d5663e4df167, []int{5} } func (m *ClientChainEarningAddrList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -212,7 +405,7 @@ func (m *ClientChainEarningAddrInfo) Reset() { *m = ClientChainEarningAd func (m *ClientChainEarningAddrInfo) String() string { return proto.CompactTextString(m) } func (*ClientChainEarningAddrInfo) ProtoMessage() {} func (*ClientChainEarningAddrInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{3} + return fileDescriptor_b229d5663e4df167, []int{6} } func (m *ClientChainEarningAddrInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -274,7 +467,7 @@ func (m *OperatorInfo) Reset() { *m = OperatorInfo{} } func (m *OperatorInfo) String() string { return proto.CompactTextString(m) } func (*OperatorInfo) ProtoMessage() {} func (*OperatorInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{4} + return fileDescriptor_b229d5663e4df167, []int{7} } func (m *OperatorInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -354,7 +547,7 @@ func (m *OptedInfo) Reset() { *m = OptedInfo{} } func (m *OptedInfo) String() string { return proto.CompactTextString(m) } func (*OptedInfo) ProtoMessage() {} func (*OptedInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{5} + return fileDescriptor_b229d5663e4df167, []int{8} } func (m *OptedInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -423,7 +616,7 @@ func (m *OptedInAssetState) Reset() { *m = OptedInAssetState{} } func (m *OptedInAssetState) String() string { return proto.CompactTextString(m) } func (*OptedInAssetState) ProtoMessage() {} func (*OptedInAssetState) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{6} + return fileDescriptor_b229d5663e4df167, []int{9} } func (m *OptedInAssetState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -466,7 +659,7 @@ func (m *SlashFromUndelegation) Reset() { *m = SlashFromUndelegation{} } func (m *SlashFromUndelegation) String() string { return proto.CompactTextString(m) } func (*SlashFromUndelegation) ProtoMessage() {} func (*SlashFromUndelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{7} + return fileDescriptor_b229d5663e4df167, []int{10} } func (m *SlashFromUndelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -521,7 +714,7 @@ func (m *SlashFromAssetsPool) Reset() { *m = SlashFromAssetsPool{} } func (m *SlashFromAssetsPool) String() string { return proto.CompactTextString(m) } func (*SlashFromAssetsPool) ProtoMessage() {} func (*SlashFromAssetsPool) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{8} + return fileDescriptor_b229d5663e4df167, []int{11} } func (m *SlashFromAssetsPool) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -567,13 +760,15 @@ type SlashExecutionInfo struct { SlashUndelegations []SlashFromUndelegation `protobuf:"bytes,3,rep,name=slash_undelegations,json=slashUndelegations,proto3" json:"slash_undelegations"` // SlashFromAssetsPool records all slash info related to the assets pool SlashAssetsPool []SlashFromAssetsPool `protobuf:"bytes,4,rep,name=slash_assets_pool,json=slashAssetsPool,proto3" json:"slash_assets_pool"` + // undelegation_filter_height records the height before which undelegations are not slashed + UndelegationFilterHeight int64 `protobuf:"varint,5,opt,name=undelegation_filter_height,json=undelegationFilterHeight,proto3" json:"undelegation_filter_height,omitempty"` } func (m *SlashExecutionInfo) Reset() { *m = SlashExecutionInfo{} } func (m *SlashExecutionInfo) String() string { return proto.CompactTextString(m) } func (*SlashExecutionInfo) ProtoMessage() {} func (*SlashExecutionInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{9} + return fileDescriptor_b229d5663e4df167, []int{12} } func (m *SlashExecutionInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -616,6 +811,13 @@ func (m *SlashExecutionInfo) GetSlashAssetsPool() []SlashFromAssetsPool { return nil } +func (m *SlashExecutionInfo) GetUndelegationFilterHeight() int64 { + if m != nil { + return m.UndelegationFilterHeight + } + return 0 +} + // OperatorSlashInfo is the slash info of operator type OperatorSlashInfo struct { // slash_contract is the address of slash contract @@ -638,7 +840,7 @@ func (m *OperatorSlashInfo) Reset() { *m = OperatorSlashInfo{} } func (m *OperatorSlashInfo) String() string { return proto.CompactTextString(m) } func (*OperatorSlashInfo) ProtoMessage() {} func (*OperatorSlashInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{10} + return fileDescriptor_b229d5663e4df167, []int{13} } func (m *OperatorSlashInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -721,7 +923,7 @@ func (m *RegisterOperatorReq) Reset() { *m = RegisterOperatorReq{} } func (m *RegisterOperatorReq) String() string { return proto.CompactTextString(m) } func (*RegisterOperatorReq) ProtoMessage() {} func (*RegisterOperatorReq) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{11} + return fileDescriptor_b229d5663e4df167, []int{14} } func (m *RegisterOperatorReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -758,7 +960,7 @@ func (m *RegisterOperatorResponse) Reset() { *m = RegisterOperatorRespon func (m *RegisterOperatorResponse) String() string { return proto.CompactTextString(m) } func (*RegisterOperatorResponse) ProtoMessage() {} func (*RegisterOperatorResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{12} + return fileDescriptor_b229d5663e4df167, []int{15} } func (m *RegisterOperatorResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -803,7 +1005,7 @@ func (m *OptIntoAVSReq) Reset() { *m = OptIntoAVSReq{} } func (m *OptIntoAVSReq) String() string { return proto.CompactTextString(m) } func (*OptIntoAVSReq) ProtoMessage() {} func (*OptIntoAVSReq) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{13} + return fileDescriptor_b229d5663e4df167, []int{16} } func (m *OptIntoAVSReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -840,7 +1042,7 @@ func (m *OptIntoAVSResponse) Reset() { *m = OptIntoAVSResponse{} } func (m *OptIntoAVSResponse) String() string { return proto.CompactTextString(m) } func (*OptIntoAVSResponse) ProtoMessage() {} func (*OptIntoAVSResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{14} + return fileDescriptor_b229d5663e4df167, []int{17} } func (m *OptIntoAVSResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -881,7 +1083,7 @@ func (m *OptOutOfAVSReq) Reset() { *m = OptOutOfAVSReq{} } func (m *OptOutOfAVSReq) String() string { return proto.CompactTextString(m) } func (*OptOutOfAVSReq) ProtoMessage() {} func (*OptOutOfAVSReq) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{15} + return fileDescriptor_b229d5663e4df167, []int{18} } func (m *OptOutOfAVSReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -918,7 +1120,7 @@ func (m *OptOutOfAVSResponse) Reset() { *m = OptOutOfAVSResponse{} } func (m *OptOutOfAVSResponse) String() string { return proto.CompactTextString(m) } func (*OptOutOfAVSResponse) ProtoMessage() {} func (*OptOutOfAVSResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{16} + return fileDescriptor_b229d5663e4df167, []int{19} } func (m *OptOutOfAVSResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -965,7 +1167,7 @@ func (m *SetConsKeyReq) Reset() { *m = SetConsKeyReq{} } func (m *SetConsKeyReq) String() string { return proto.CompactTextString(m) } func (*SetConsKeyReq) ProtoMessage() {} func (*SetConsKeyReq) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{17} + return fileDescriptor_b229d5663e4df167, []int{20} } func (m *SetConsKeyReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1002,7 +1204,7 @@ func (m *SetConsKeyResponse) Reset() { *m = SetConsKeyResponse{} } func (m *SetConsKeyResponse) String() string { return proto.CompactTextString(m) } func (*SetConsKeyResponse) ProtoMessage() {} func (*SetConsKeyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_b229d5663e4df167, []int{18} + return fileDescriptor_b229d5663e4df167, []int{21} } func (m *SetConsKeyResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1035,6 +1237,9 @@ func init() { proto.RegisterEnum("exocore.operator.v1.SlashType", SlashType_name, SlashType_value) proto.RegisterType((*DecValueField)(nil), "exocore.operator.v1.DecValueField") proto.RegisterType((*OperatorOptedUSDValue)(nil), "exocore.operator.v1.OperatorOptedUSDValue") + proto.RegisterType((*OperatorVotingPower)(nil), "exocore.operator.v1.OperatorVotingPower") + proto.RegisterType((*VotingPowerSnapshot)(nil), "exocore.operator.v1.VotingPowerSnapshot") + proto.RegisterType((*SnapshotHelper)(nil), "exocore.operator.v1.SnapshotHelper") proto.RegisterType((*ClientChainEarningAddrList)(nil), "exocore.operator.v1.ClientChainEarningAddrList") proto.RegisterType((*ClientChainEarningAddrInfo)(nil), "exocore.operator.v1.ClientChainEarningAddrInfo") proto.RegisterType((*OperatorInfo)(nil), "exocore.operator.v1.OperatorInfo") @@ -1057,104 +1262,118 @@ func init() { func init() { proto.RegisterFile("exocore/operator/v1/tx.proto", fileDescriptor_b229d5663e4df167) } var fileDescriptor_b229d5663e4df167 = []byte{ - // 1545 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x4f, 0x1b, 0xd7, - 0x1a, 0x67, 0x6c, 0x5e, 0xfe, 0x6c, 0x63, 0x33, 0xe4, 0xe1, 0xf8, 0xe6, 0xe2, 0x30, 0xb9, 0x21, - 0x84, 0x7b, 0xb1, 0x05, 0xb9, 0xb9, 0x52, 0x72, 0xef, 0xe2, 0x1a, 0x0c, 0x8a, 0x1b, 0xb0, 0xd1, - 0x0c, 0x44, 0x6a, 0xaa, 0x6a, 0x34, 0x8c, 0x0f, 0x66, 0xc2, 0x78, 0xce, 0x74, 0xce, 0xb1, 0x0b, - 0x59, 0x55, 0x59, 0x45, 0x55, 0x17, 0x95, 0xb2, 0xaa, 0xda, 0x45, 0x56, 0x55, 0x97, 0x59, 0x64, - 0x5b, 0xb5, 0xdd, 0x65, 0x19, 0xa5, 0x5d, 0x54, 0x5d, 0xd0, 0x8a, 0x54, 0x4a, 0xff, 0x88, 0x56, - 0xaa, 0xce, 0x99, 0x33, 0x66, 0x9c, 0xd8, 0x24, 0x28, 0xa4, 0x1b, 0xe0, 0x7c, 0xaf, 0xdf, 0xef, - 0x7b, 0x9c, 0xef, 0xd8, 0xc0, 0x59, 0xb4, 0x83, 0x4d, 0xec, 0xa1, 0x02, 0x76, 0x91, 0x67, 0x50, - 0xec, 0x15, 0x5a, 0xb3, 0x05, 0xba, 0x93, 0x77, 0x3d, 0x4c, 0xb1, 0x3c, 0x26, 0xb4, 0xf9, 0x40, - 0x9b, 0x6f, 0xcd, 0x66, 0x47, 0x8d, 0x86, 0xe5, 0xe0, 0x02, 0xff, 0xe9, 0xdb, 0x65, 0x4f, 0x9b, - 0x98, 0x34, 0x30, 0x29, 0x34, 0x48, 0x9d, 0xf9, 0x37, 0x48, 0x5d, 0x28, 0xfe, 0x21, 0x14, 0x84, - 0x1a, 0xdb, 0x96, 0xc3, 0x94, 0x1b, 0x88, 0x1a, 0xb3, 0xc1, 0x59, 0x58, 0x9d, 0xf1, 0xad, 0x74, - 0x7e, 0x2a, 0xf8, 0x07, 0xa1, 0x3a, 0x51, 0xc7, 0x75, 0xec, 0xcb, 0xd9, 0x5f, 0x42, 0x7a, 0xb6, - 0x8e, 0x71, 0xdd, 0x46, 0x05, 0xc3, 0xb5, 0x0a, 0x86, 0xe3, 0x60, 0x6a, 0x50, 0x0b, 0x3b, 0xc2, - 0x47, 0x41, 0x90, 0x2c, 0x21, 0xf3, 0xa6, 0x61, 0x37, 0xd1, 0x92, 0x85, 0xec, 0x9a, 0xbc, 0x06, - 0x83, 0x46, 0x03, 0x37, 0x1d, 0x9a, 0x91, 0xce, 0x49, 0x53, 0xb1, 0xf9, 0xff, 0x3d, 0xde, 0xcb, - 0xf5, 0xfd, 0xb4, 0x97, 0x9b, 0xac, 0x5b, 0x74, 0xab, 0xb9, 0x91, 0x37, 0x71, 0x43, 0xa0, 0x8a, - 0x5f, 0x33, 0xa4, 0xb6, 0x5d, 0xa0, 0xbb, 0x2e, 0x22, 0xf9, 0x12, 0x32, 0x9f, 0x3e, 0x9a, 0x01, - 0x41, 0xaa, 0x84, 0x4c, 0x55, 0xc4, 0x52, 0x7e, 0x8f, 0xc0, 0xc9, 0xaa, 0xa8, 0x4b, 0xd5, 0xa5, - 0xa8, 0xb6, 0xae, 0x95, 0x38, 0xa8, 0xec, 0xc1, 0x08, 0x41, 0xf6, 0xa6, 0xde, 0x24, 0x35, 0xbd, - 0xc5, 0x24, 0x02, 0x77, 0xf9, 0x68, 0xb8, 0xfb, 0x7b, 0xb9, 0x84, 0x86, 0xec, 0xcd, 0x20, 0xee, - 0x0b, 0x3c, 0x12, 0x0c, 0x63, 0x9d, 0xd4, 0x7c, 0xcc, 0x26, 0xa4, 0x28, 0xa6, 0x86, 0x1d, 0x02, - 0x8d, 0x70, 0xd0, 0x95, 0x23, 0x83, 0x26, 0xd7, 0x58, 0xa0, 0x1e, 0xa8, 0x49, 0x8e, 0xd2, 0x86, - 0xdd, 0x81, 0xb4, 0x61, 0x52, 0xab, 0x85, 0x42, 0xb8, 0x51, 0x8e, 0x5b, 0x39, 0x32, 0xee, 0x48, - 0x91, 0x47, 0xea, 0x01, 0x3c, 0xe2, 0xe3, 0x04, 0xc8, 0xca, 0x2e, 0x64, 0x17, 0x6c, 0x0b, 0x39, - 0x74, 0x61, 0xcb, 0xb0, 0x9c, 0x45, 0xc3, 0x73, 0x2c, 0xa7, 0x5e, 0xac, 0xd5, 0xbc, 0x65, 0x8b, - 0x50, 0xf9, 0x3d, 0x18, 0x45, 0xbe, 0x48, 0xb7, 0x9c, 0x4d, 0xac, 0xdb, 0x16, 0x61, 0xdd, 0x8f, - 0x4e, 0xc5, 0xe7, 0x0a, 0xf9, 0x2e, 0x53, 0x9d, 0xef, 0x1e, 0xab, 0xec, 0x6c, 0x62, 0x35, 0x25, - 0x22, 0xb1, 0x03, 0x0b, 0xae, 0x7c, 0x26, 0xf5, 0xc2, 0x66, 0x26, 0xf2, 0xff, 0x41, 0xb6, 0xef, - 0xe8, 0x26, 0x37, 0xd0, 0x4d, 0x66, 0xa1, 0x5b, 0x35, 0x3e, 0x02, 0xfd, 0xf3, 0x63, 0xfb, 0x7b, - 0xb9, 0xd4, 0xf2, 0x9d, 0x90, 0x77, 0xb9, 0xa4, 0xa6, 0xec, 0x0e, 0x41, 0x4d, 0xbe, 0x0a, 0x67, - 0x3a, 0xdc, 0x83, 0x54, 0x8c, 0x5a, 0xcd, 0xf3, 0xdb, 0xaa, 0x9e, 0x32, 0xbb, 0x12, 0x50, 0xbe, - 0x8b, 0x40, 0x22, 0x98, 0x4a, 0xce, 0xe6, 0x3c, 0x24, 0x85, 0x3b, 0xf1, 0xfd, 0xf9, 0x2c, 0xaa, - 0x89, 0x40, 0xc8, 0xbc, 0xe4, 0x09, 0x48, 0x18, 0xae, 0xeb, 0xe1, 0x16, 0x0a, 0x63, 0xc4, 0x85, - 0x8c, 0x9b, 0xfc, 0x0b, 0xe4, 0xa0, 0x5e, 0x7a, 0x03, 0x51, 0x83, 0xd7, 0xd5, 0xef, 0xb5, 0x9a, - 0x0e, 0x34, 0x2b, 0x88, 0x1a, 0x1c, 0xd5, 0x86, 0x6c, 0xb7, 0x0c, 0x04, 0x85, 0xfe, 0x73, 0xd2, - 0x11, 0x1b, 0xc1, 0xea, 0xae, 0x9e, 0x7e, 0x39, 0x67, 0x9f, 0xfe, 0x0a, 0x80, 0x89, 0x1b, 0x0d, - 0x8b, 0x10, 0x0b, 0x3b, 0x99, 0x01, 0x1e, 0x5d, 0xc9, 0x8b, 0xe1, 0x09, 0x76, 0x8d, 0xd8, 0x3d, - 0xf9, 0x85, 0xb6, 0xe5, 0x7c, 0x8c, 0xcd, 0xe8, 0x57, 0xcf, 0x1f, 0x4e, 0x4b, 0x6a, 0x28, 0x80, - 0xf2, 0x85, 0x04, 0x31, 0x7e, 0xa3, 0x79, 0x2a, 0x17, 0x60, 0x84, 0xd8, 0x06, 0xd9, 0xd2, 0x4d, - 0xec, 0x50, 0xcf, 0x30, 0xc5, 0x16, 0x51, 0x93, 0x5c, 0xba, 0x20, 0x84, 0xf2, 0x24, 0xa4, 0x30, - 0xf3, 0xd1, 0x2d, 0x47, 0xdf, 0x42, 0x56, 0x7d, 0x8b, 0xf2, 0x2a, 0xf6, 0xab, 0x49, 0xec, 0x87, - 0xba, 0xce, 0x85, 0xf2, 0x14, 0xa4, 0x7d, 0x3b, 0xdc, 0xa4, 0x81, 0x61, 0x94, 0x1b, 0x8e, 0x70, - 0x79, 0xb5, 0x49, 0x85, 0xe5, 0x29, 0x18, 0xbc, 0x6d, 0x58, 0x36, 0xaa, 0xf1, 0x7a, 0x0d, 0xab, - 0xe2, 0xa4, 0x7c, 0x2d, 0xc1, 0xa8, 0xa0, 0x57, 0x24, 0x04, 0x51, 0x8d, 0x1a, 0x14, 0xbd, 0xd1, - 0x92, 0x2b, 0x3b, 0x34, 0x74, 0xdb, 0xca, 0x0e, 0x0d, 0x96, 0x9c, 0xac, 0xc2, 0x40, 0x78, 0x99, - 0xbc, 0xd9, 0xe6, 0xf4, 0x43, 0x29, 0xdf, 0x4a, 0x70, 0x52, 0x63, 0xb5, 0x5b, 0xf2, 0x70, 0x63, - 0xdd, 0xa9, 0x21, 0x1b, 0xd5, 0xf9, 0x02, 0x97, 0x2f, 0x41, 0x8c, 0x75, 0x0b, 0x79, 0xc1, 0x85, - 0x89, 0xcd, 0x27, 0xf6, 0xf7, 0x72, 0xc3, 0x1a, 0x17, 0x96, 0x4b, 0xea, 0xb0, 0xaf, 0x2e, 0xd7, - 0xe4, 0x49, 0x18, 0x36, 0x58, 0xf2, 0xcc, 0xd2, 0xe7, 0x16, 0xdf, 0xdf, 0xcb, 0x0d, 0xf1, 0x82, - 0x94, 0x4b, 0xea, 0x10, 0x57, 0x96, 0xc3, 0xbb, 0x3f, 0x7a, 0x7c, 0x65, 0x51, 0xee, 0x4b, 0x30, - 0xd6, 0x4e, 0x81, 0x63, 0x92, 0x55, 0x8c, 0xed, 0x0e, 0x56, 0xd2, 0x6b, 0xb1, 0x8a, 0x1c, 0x23, - 0xab, 0xcf, 0xa3, 0x20, 0x73, 0x56, 0x8b, 0x3b, 0xc8, 0x6c, 0xb2, 0x8a, 0xf2, 0x01, 0xae, 0x43, - 0xda, 0x1f, 0x60, 0xd7, 0xc3, 0x2e, 0xf6, 0x98, 0xfc, 0x58, 0x1e, 0xc2, 0x14, 0x8f, 0xba, 0xda, - 0x0e, 0x2a, 0xbf, 0x0f, 0x71, 0x1f, 0xe8, 0xf8, 0x46, 0x06, 0x78, 0x40, 0xff, 0xad, 0x31, 0x60, - 0xcc, 0x0f, 0xdf, 0x0c, 0xcd, 0x0c, 0xc9, 0x44, 0xf9, 0x56, 0x9f, 0xee, 0xba, 0x4c, 0xba, 0x8e, - 0xd9, 0x7c, 0x3f, 0xa3, 0xa4, 0xca, 0x3c, 0x58, 0x58, 0x41, 0xe4, 0x5b, 0x30, 0xea, 0x43, 0xf0, - 0x46, 0x11, 0xdd, 0xc5, 0xd8, 0xce, 0xf4, 0x73, 0x80, 0xa9, 0xc3, 0x01, 0x0e, 0x86, 0x40, 0x84, - 0xf7, 0xab, 0x73, 0x20, 0x56, 0xfe, 0x88, 0xb0, 0x6b, 0xeb, 0xbb, 0x72, 0xb7, 0xa3, 0x6c, 0x97, - 0x4b, 0x90, 0x26, 0xcd, 0x8d, 0x86, 0x45, 0xd9, 0xe6, 0x08, 0xad, 0x97, 0xa8, 0x9a, 0x6a, 0xcb, - 0xc5, 0xda, 0x98, 0x80, 0x04, 0x6a, 0xb1, 0xcd, 0x1b, 0x5a, 0x2e, 0x51, 0x35, 0xce, 0x65, 0xc2, - 0xe4, 0x6f, 0x10, 0xb3, 0x88, 0xde, 0x42, 0x14, 0xb7, 0x97, 0xcb, 0xb0, 0x45, 0x6e, 0xf2, 0x73, - 0xd7, 0x71, 0x19, 0x78, 0x1b, 0xe3, 0xf2, 0x77, 0xf0, 0xbb, 0xab, 0x33, 0x8f, 0xcc, 0xe0, 0x39, - 0x69, 0x2a, 0xa9, 0xc6, 0xb8, 0x64, 0x6d, 0xd7, 0x45, 0x72, 0x05, 0x46, 0x50, 0x30, 0xc7, 0xfe, - 0x63, 0x33, 0xc4, 0x17, 0xfb, 0xc5, 0xde, 0x8d, 0xe8, 0x98, 0x7b, 0x35, 0x89, 0xc2, 0x47, 0xe5, - 0x1b, 0x09, 0xc6, 0x54, 0x54, 0xb7, 0x08, 0x45, 0x5e, 0xd0, 0x07, 0x15, 0x7d, 0x20, 0xff, 0x17, - 0x12, 0x9b, 0x1e, 0x6e, 0xf0, 0x97, 0x09, 0x11, 0x22, 0xae, 0x46, 0xe6, 0xe9, 0xa3, 0x99, 0x13, - 0x82, 0x7d, 0xd1, 0xd7, 0x68, 0xd4, 0xb3, 0x9c, 0xba, 0x1a, 0x67, 0xd6, 0x42, 0x24, 0x5f, 0x81, - 0x7e, 0x4e, 0x2d, 0xc2, 0xa9, 0x4d, 0x74, 0xa5, 0x16, 0x7e, 0x8e, 0x55, 0x6e, 0x7e, 0xed, 0xdf, - 0xf7, 0x1e, 0xe4, 0xfa, 0x7e, 0x7b, 0x90, 0xeb, 0xbb, 0xfb, 0xfc, 0xe1, 0x74, 0x7c, 0xe9, 0x20, - 0xe0, 0xc7, 0xcf, 0x1f, 0x4e, 0x9f, 0x0e, 0x15, 0x33, 0xec, 0xab, 0x64, 0x21, 0xf3, 0x72, 0x02, - 0xc4, 0xc5, 0x0e, 0x41, 0xca, 0xcf, 0x12, 0x24, 0xab, 0x2e, 0x2d, 0x3b, 0x14, 0x17, 0x6f, 0x6a, - 0x6f, 0x9c, 0x57, 0x0e, 0xe2, 0x46, 0x8b, 0xb4, 0x7d, 0xfd, 0xcf, 0x03, 0x60, 0xb4, 0x48, 0x60, - 0x70, 0x15, 0x52, 0x6e, 0x73, 0xc3, 0xb6, 0x4c, 0x7d, 0x1b, 0xed, 0xea, 0xb7, 0x09, 0x76, 0xc4, - 0x82, 0x1d, 0x65, 0x9f, 0x20, 0x57, 0xb9, 0xea, 0x06, 0xda, 0x7d, 0x47, 0xab, 0x56, 0xd4, 0xa4, - 0xdb, 0x3e, 0x12, 0xec, 0x5c, 0xbb, 0x72, 0x58, 0xf2, 0x99, 0x8e, 0xe4, 0x43, 0xf9, 0x28, 0x27, - 0x40, 0x0e, 0x0b, 0x44, 0xde, 0x5f, 0x4a, 0x30, 0x52, 0x75, 0x69, 0xb5, 0x49, 0xab, 0x9b, 0x7f, - 0x45, 0xe2, 0xd7, 0xfe, 0x73, 0x18, 0xfb, 0x33, 0x9d, 0xec, 0x43, 0xac, 0x94, 0x93, 0x30, 0xd6, - 0x21, 0x11, 0xfc, 0x9f, 0x4a, 0x90, 0xd4, 0x10, 0x5d, 0xc0, 0x0e, 0xb9, 0x81, 0x76, 0x19, 0xfd, - 0x39, 0x18, 0x7a, 0x5d, 0xe6, 0x81, 0xe1, 0x5b, 0x6d, 0xd7, 0x6c, 0x38, 0xe1, 0x00, 0xf1, 0xc5, - 0x56, 0x75, 0xa4, 0xc0, 0x5a, 0x15, 0x16, 0xf8, 0xa9, 0x4e, 0xdb, 0x10, 0xd3, 0xda, 0xb7, 0x3b, - 0x0b, 0xa7, 0xb4, 0xe5, 0xa2, 0x76, 0x5d, 0x5f, 0x7b, 0x77, 0x75, 0x51, 0x5f, 0xaf, 0x68, 0xab, - 0x8b, 0x0b, 0xe5, 0xa5, 0xf2, 0x62, 0x29, 0xdd, 0x27, 0x9f, 0x85, 0x4c, 0x48, 0x57, 0xae, 0x68, - 0x6b, 0xc5, 0xca, 0x9a, 0xce, 0x45, 0x69, 0x49, 0xbe, 0x00, 0x13, 0x21, 0x6d, 0xa5, 0x1a, 0x18, - 0x14, 0x2b, 0x8b, 0xd5, 0x75, 0x4d, 0x98, 0x45, 0xe6, 0x7e, 0xe8, 0x87, 0xe8, 0x0a, 0xa9, 0xcb, - 0x0f, 0x24, 0x48, 0xbf, 0x78, 0x6b, 0xe4, 0xee, 0xcb, 0xbc, 0xcb, 0x76, 0xc8, 0xce, 0xbc, 0xa6, - 0xa5, 0x68, 0xe7, 0xe5, 0xbb, 0xdf, 0xff, 0x7a, 0x3f, 0x32, 0xa3, 0xfc, 0xb3, 0xd0, 0xfd, 0x8b, - 0x75, 0xa1, 0xdb, 0x06, 0xba, 0x27, 0x01, 0x1c, 0xd4, 0x4b, 0x56, 0xba, 0x2f, 0xb8, 0x70, 0x85, - 0xb3, 0x17, 0x5f, 0x69, 0x23, 0x08, 0xcd, 0x70, 0x42, 0x17, 0x95, 0x0b, 0xbd, 0x08, 0x75, 0x0e, - 0x1f, 0xa3, 0x72, 0x70, 0xcb, 0x7a, 0x50, 0xe9, 0xb8, 0x97, 0x3d, 0xa8, 0x74, 0xb9, 0xaa, 0xaf, - 0xa4, 0xd2, 0xb9, 0xbf, 0x3e, 0x91, 0x20, 0x1e, 0xba, 0x31, 0xf2, 0xf9, 0x5e, 0x38, 0xa1, 0x5b, - 0x96, 0x9d, 0x7a, 0xb5, 0x91, 0x60, 0x93, 0xe7, 0x6c, 0xa6, 0x94, 0xc9, 0x43, 0xd8, 0x84, 0x23, - 0x0f, 0x7c, 0xc4, 0xbe, 0x27, 0xcc, 0x2f, 0x3f, 0xde, 0x1f, 0x97, 0x9e, 0xec, 0x8f, 0x4b, 0xbf, - 0xec, 0x8f, 0x4b, 0x9f, 0x3e, 0x1b, 0xef, 0x7b, 0xf2, 0x6c, 0xbc, 0xef, 0xc7, 0x67, 0xe3, 0x7d, - 0xb7, 0xe6, 0x42, 0xaf, 0xe2, 0xa2, 0x1f, 0xb2, 0x82, 0xe8, 0x87, 0xd8, 0xdb, 0x6e, 0x23, 0xec, - 0x1c, 0x60, 0xf0, 0x57, 0x72, 0x63, 0x90, 0xff, 0xc7, 0xe2, 0xf2, 0x9f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x0c, 0x47, 0x83, 0x3c, 0x87, 0x11, 0x00, 0x00, + // 1769 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xd7, 0x52, 0xb2, 0x2d, 0x3e, 0x92, 0x22, 0x35, 0xf2, 0x07, 0xcd, 0xba, 0xa2, 0xbd, 0xa9, + 0x6d, 0x59, 0xad, 0x48, 0x58, 0x69, 0x0a, 0xc4, 0x4d, 0x81, 0xea, 0x13, 0x66, 0x23, 0x93, 0xc2, + 0x52, 0x32, 0xd0, 0x14, 0xed, 0x76, 0x45, 0x8e, 0x96, 0x6b, 0x2f, 0x77, 0xb6, 0x3b, 0x43, 0x46, + 0xca, 0xa9, 0xc8, 0x29, 0x28, 0x7a, 0x28, 0x90, 0x53, 0x81, 0x1e, 0x7c, 0x2a, 0x7a, 0xf4, 0x21, + 0x3d, 0x16, 0x6d, 0x6f, 0x39, 0x06, 0x6e, 0x0f, 0x6d, 0x0f, 0x4a, 0x21, 0x17, 0x70, 0xff, 0x88, + 0x16, 0x28, 0xe6, 0x63, 0xa9, 0xa1, 0xbd, 0x94, 0x2d, 0x48, 0xe9, 0x25, 0xf1, 0xbe, 0xf7, 0xe6, + 0xfd, 0x7e, 0xef, 0xcd, 0xfb, 0x18, 0x0a, 0xae, 0xe1, 0x3d, 0xd2, 0x22, 0x11, 0xae, 0x92, 0x10, + 0x47, 0x0e, 0x23, 0x51, 0xb5, 0x7f, 0xb7, 0xca, 0xf6, 0x2a, 0x61, 0x44, 0x18, 0x41, 0x33, 0x4a, + 0x5b, 0x89, 0xb5, 0x95, 0xfe, 0xdd, 0xd2, 0xb4, 0xd3, 0xf5, 0x02, 0x52, 0x15, 0xff, 0x95, 0x76, + 0xa5, 0x2b, 0x2d, 0x42, 0xbb, 0x84, 0x56, 0xbb, 0xd4, 0xe5, 0xe7, 0xbb, 0xd4, 0x55, 0x8a, 0x6f, + 0x28, 0x05, 0x65, 0xce, 0x63, 0x2f, 0xe0, 0xca, 0x1d, 0xcc, 0x9c, 0xbb, 0xf1, 0xb7, 0xb2, 0xba, + 0x2a, 0xad, 0x6c, 0xf1, 0x55, 0x95, 0x1f, 0x4a, 0x75, 0xd1, 0x25, 0x2e, 0x91, 0x72, 0xfe, 0x2f, + 0x25, 0xbd, 0xe6, 0x12, 0xe2, 0xfa, 0xb8, 0xea, 0x84, 0x5e, 0xd5, 0x09, 0x02, 0xc2, 0x1c, 0xe6, + 0x91, 0x40, 0x9d, 0x31, 0x31, 0xe4, 0x56, 0x71, 0xeb, 0xa1, 0xe3, 0xf7, 0xf0, 0xba, 0x87, 0xfd, + 0x36, 0xda, 0x82, 0xf3, 0x4e, 0x97, 0xf4, 0x02, 0x56, 0x34, 0xae, 0x1b, 0x73, 0xe9, 0xe5, 0xf7, + 0x3e, 0x3f, 0x28, 0x8f, 0xfd, 0xe3, 0xa0, 0x7c, 0xcb, 0xf5, 0x58, 0xa7, 0xb7, 0x53, 0x69, 0x91, + 0xae, 0x42, 0x55, 0xff, 0x5b, 0xa0, 0xed, 0xc7, 0x55, 0xb6, 0x1f, 0x62, 0x5a, 0x59, 0xc5, 0xad, + 0x67, 0x9f, 0x2d, 0x80, 0x22, 0xb5, 0x8a, 0x5b, 0x96, 0xf2, 0x65, 0xfe, 0x27, 0x05, 0x97, 0x1a, + 0x2a, 0x2f, 0x8d, 0x90, 0xe1, 0xf6, 0x76, 0x73, 0x55, 0x80, 0xa2, 0x08, 0xa6, 0x28, 0xf6, 0x77, + 0xed, 0x1e, 0x6d, 0xdb, 0x7d, 0x2e, 0x51, 0xb8, 0x1b, 0x27, 0xc3, 0x3d, 0x3c, 0x28, 0x67, 0x9b, + 0xd8, 0xdf, 0x8d, 0xfd, 0xbe, 0xc4, 0x23, 0xcb, 0x31, 0xb6, 0x69, 0x5b, 0x62, 0xf6, 0x20, 0xcf, + 0x08, 0x73, 0x7c, 0x0d, 0x34, 0x25, 0x40, 0x1f, 0x9c, 0x18, 0x34, 0xb7, 0xc5, 0x1d, 0x8d, 0x40, + 0xcd, 0x09, 0x94, 0x01, 0xec, 0x1e, 0x14, 0x9c, 0x16, 0xf3, 0xfa, 0x58, 0xc3, 0x1d, 0x17, 0xb8, + 0xf5, 0x13, 0xe3, 0x4e, 0x2d, 0x09, 0x4f, 0x23, 0x80, 0xa7, 0x24, 0x4e, 0x8c, 0x6c, 0xfe, 0xde, + 0x80, 0x99, 0x38, 0xfd, 0x0f, 0x09, 0xf3, 0x02, 0x77, 0x93, 0x7c, 0x88, 0x23, 0xf4, 0x3d, 0xc8, + 0xc5, 0xd5, 0x6a, 0x3b, 0xed, 0x76, 0xa4, 0x72, 0x5f, 0x7c, 0xf6, 0xd9, 0xc2, 0x45, 0xe5, 0x6e, + 0xa9, 0xdd, 0x8e, 0x30, 0xa5, 0x4d, 0x16, 0x79, 0x81, 0x6b, 0x65, 0x63, 0x73, 0x2e, 0x46, 0x36, + 0x64, 0xfb, 0xc2, 0x9b, 0x1d, 0x72, 0x77, 0x2a, 0x89, 0xa7, 0xab, 0x98, 0x4c, 0xff, 0x88, 0x9f, + 0xf9, 0x65, 0x0a, 0x66, 0x34, 0xbe, 0xcd, 0xc0, 0x09, 0x69, 0x87, 0x30, 0xf4, 0x08, 0x90, 0xbc, + 0xc0, 0x21, 0xf8, 0xb3, 0x28, 0xd8, 0x82, 0xf0, 0xab, 0xe7, 0xe8, 0x27, 0x70, 0x79, 0x90, 0x23, + 0x1d, 0x8e, 0x16, 0x53, 0xd7, 0xc7, 0xe7, 0x32, 0x8b, 0x73, 0x95, 0x84, 0xc6, 0xaf, 0x24, 0x64, + 0xdb, 0xba, 0x48, 0x5e, 0x15, 0x52, 0x54, 0x81, 0x19, 0xdf, 0xa1, 0xcc, 0x6e, 0x75, 0x9c, 0xc0, + 0xc5, 0x6d, 0xbb, 0x83, 0x3d, 0xb7, 0xc3, 0x44, 0x61, 0x8c, 0x5b, 0xd3, 0x5c, 0xb5, 0x22, 0x35, + 0xf7, 0x85, 0x02, 0xdd, 0x81, 0x02, 0x0e, 0x49, 0xab, 0x63, 0x7b, 0x6d, 0x1c, 0x30, 0x6f, 0xd7, + 0xc3, 0x51, 0x71, 0x82, 0x47, 0x6e, 0xe5, 0x85, 0xbc, 0x36, 0x10, 0xa3, 0x1b, 0x90, 0x95, 0xa6, + 0x41, 0xaf, 0xbb, 0x83, 0xa3, 0xe2, 0x39, 0xe1, 0x33, 0x23, 0x64, 0x75, 0x21, 0x32, 0x7f, 0x0a, + 0x53, 0x71, 0x56, 0xef, 0x63, 0x3f, 0xc4, 0xd1, 0x28, 0x3e, 0xc6, 0x28, 0x3e, 0xb3, 0x90, 0xe9, + 0x38, 0xd4, 0x26, 0x21, 0xb3, 0x49, 0x8f, 0x89, 0x1a, 0x98, 0xb4, 0xd2, 0x1d, 0x87, 0x36, 0x42, + 0xd6, 0xe8, 0x31, 0x73, 0x1f, 0x4a, 0x2b, 0xbe, 0x87, 0x03, 0x7e, 0xcc, 0x0b, 0xd6, 0x9c, 0x28, + 0xf0, 0x02, 0x97, 0x97, 0xcf, 0x86, 0x47, 0x19, 0xfa, 0x11, 0x4c, 0x63, 0x29, 0xb2, 0xbd, 0x60, + 0x97, 0xd8, 0xbe, 0x47, 0x39, 0x16, 0x4f, 0x6c, 0x35, 0x31, 0xb1, 0xc9, 0xbe, 0x6a, 0xc1, 0x2e, + 0xb1, 0xf2, 0xca, 0x13, 0xff, 0xe0, 0xce, 0xcd, 0x5f, 0x1b, 0xa3, 0xb0, 0xb9, 0x09, 0xfa, 0x3e, + 0x20, 0xff, 0x23, 0xbb, 0x25, 0x0c, 0x78, 0xb8, 0x5e, 0x60, 0x7b, 0x6d, 0x11, 0xe8, 0xc4, 0xf2, + 0xcc, 0xe1, 0x41, 0x39, 0xbf, 0xf1, 0x91, 0x76, 0xba, 0xb6, 0x6a, 0xe5, 0xfd, 0x21, 0x41, 0x1b, + 0xbd, 0x0b, 0x57, 0x87, 0x8e, 0xc7, 0xa1, 0x88, 0x5e, 0x12, 0xdd, 0x60, 0x5d, 0x6e, 0x25, 0x12, + 0x30, 0xff, 0x9c, 0x82, 0x6c, 0x5c, 0x24, 0x82, 0xcd, 0x5b, 0x90, 0x53, 0xc7, 0xa9, 0xd6, 0x8b, + 0x56, 0x36, 0x16, 0x8a, 0x8e, 0xbb, 0x01, 0x59, 0x27, 0x0c, 0x23, 0xd2, 0xc7, 0x3a, 0x46, 0x46, + 0xc9, 0x84, 0xc9, 0xb7, 0x00, 0x0d, 0xea, 0xb5, 0x8b, 0x99, 0x23, 0xf2, 0x2a, 0xe7, 0x8c, 0x55, + 0x88, 0x35, 0x0f, 0x30, 0x73, 0x04, 0xaa, 0x0f, 0xa5, 0xa4, 0x08, 0x14, 0x05, 0x5e, 0x57, 0x27, + 0xbb, 0x08, 0x9e, 0x77, 0xeb, 0xca, 0xab, 0x31, 0x4b, 0xfa, 0x0f, 0x00, 0x5a, 0xa4, 0xdb, 0xf5, + 0x28, 0xf5, 0x48, 0x20, 0xca, 0x31, 0xb3, 0x68, 0x56, 0x54, 0xfb, 0xc5, 0x7b, 0x4e, 0xed, 0xbd, + 0xca, 0xca, 0xc0, 0x72, 0x39, 0xcd, 0x7b, 0xfa, 0x77, 0x2f, 0x9e, 0xce, 0x1b, 0x96, 0xe6, 0xc0, + 0xfc, 0x8d, 0x01, 0x69, 0xb1, 0x4d, 0x44, 0x28, 0x37, 0x61, 0x8a, 0xfa, 0x0e, 0xed, 0xd8, 0x2d, + 0x12, 0xb0, 0xc8, 0x69, 0xa9, 0x0d, 0x66, 0xe5, 0x84, 0x74, 0x45, 0x09, 0xd1, 0x2d, 0xc8, 0x13, + 0x7e, 0xc6, 0xf6, 0x82, 0xb8, 0xb6, 0x79, 0x16, 0x27, 0xac, 0x1c, 0x91, 0xae, 0x54, 0x5d, 0xcf, + 0x41, 0x41, 0xda, 0x91, 0x1e, 0xd3, 0x9b, 0x72, 0xc2, 0x9a, 0x12, 0xf2, 0x46, 0x8f, 0x29, 0xcb, + 0xcb, 0x70, 0xfe, 0x91, 0xe3, 0xf9, 0xb8, 0x2d, 0xf2, 0x35, 0x69, 0xa9, 0x2f, 0xf3, 0x0f, 0x06, + 0x4c, 0x2b, 0x7a, 0x4b, 0x94, 0x62, 0xd6, 0x64, 0x0e, 0xc3, 0xa7, 0x5a, 0xb0, 0xb5, 0x80, 0x69, + 0xf3, 0xaa, 0x16, 0xb0, 0x78, 0xc1, 0x22, 0x0b, 0xce, 0xe9, 0x8b, 0xec, 0x74, 0x43, 0x50, 0xba, + 0x32, 0xff, 0x64, 0xc0, 0xa5, 0x26, 0xcf, 0xdd, 0x7a, 0x44, 0xba, 0xdb, 0x41, 0x1b, 0xfb, 0xd8, + 0x15, 0x8f, 0x07, 0x74, 0x07, 0xd2, 0xfc, 0xb6, 0x70, 0x14, 0x37, 0x4c, 0x7a, 0x39, 0x7b, 0x78, + 0x50, 0x9e, 0x6c, 0x0a, 0x61, 0x6d, 0xd5, 0x9a, 0x94, 0xea, 0x5a, 0x1b, 0xdd, 0x82, 0x49, 0x87, + 0x07, 0xcf, 0x2d, 0x25, 0xb7, 0xcc, 0xe1, 0x41, 0xf9, 0x82, 0x48, 0x48, 0x6d, 0xd5, 0xba, 0x20, + 0x94, 0x35, 0xfd, 0xdd, 0x31, 0x7e, 0x76, 0x69, 0x31, 0x3f, 0x35, 0x60, 0x66, 0x10, 0x82, 0xc0, + 0xa4, 0x9b, 0x84, 0xf8, 0x43, 0xac, 0x8c, 0x37, 0x62, 0x95, 0x3a, 0x43, 0x56, 0x7f, 0x1f, 0x07, + 0x24, 0x58, 0xad, 0xed, 0xe1, 0x56, 0x8f, 0x67, 0x54, 0x14, 0xb0, 0x0b, 0x05, 0x59, 0xc0, 0x61, + 0x44, 0x42, 0x12, 0x71, 0xf9, 0x99, 0xec, 0xb4, 0xbc, 0xf0, 0xba, 0x39, 0x70, 0x8a, 0x7e, 0x0c, + 0x19, 0x09, 0x74, 0x76, 0x25, 0x03, 0xc2, 0xa1, 0x7c, 0xe7, 0x38, 0x30, 0x23, 0xdd, 0xf7, 0xb4, + 0x9a, 0xa1, 0xc5, 0x71, 0x31, 0xd5, 0xe7, 0x13, 0x87, 0x49, 0x62, 0x99, 0x2d, 0x4f, 0x70, 0x4a, + 0x16, 0x12, 0xce, 0x74, 0x05, 0x45, 0x1f, 0xc0, 0xb4, 0x84, 0x10, 0x17, 0x45, 0xed, 0x90, 0x10, + 0xbf, 0x38, 0x71, 0xcc, 0x3e, 0x4e, 0x28, 0x02, 0xe5, 0x5e, 0x66, 0x47, 0xab, 0x8d, 0xf7, 0xa0, + 0xa4, 0x13, 0xb7, 0x77, 0x3d, 0x9f, 0xe1, 0x28, 0x1e, 0x01, 0x72, 0x87, 0x16, 0x75, 0x8b, 0x75, + 0x61, 0x20, 0x87, 0x81, 0xf9, 0xdf, 0x14, 0x6f, 0x7a, 0x09, 0x2c, 0x40, 0x4f, 0x32, 0x9b, 0xee, + 0x40, 0x81, 0xf6, 0x76, 0xba, 0x1e, 0x63, 0x47, 0x8b, 0x37, 0x25, 0x00, 0xf3, 0x03, 0xb9, 0x1a, + 0x3a, 0x7c, 0xb7, 0xf7, 0xf9, 0xdc, 0x1e, 0x7a, 0x2f, 0x64, 0x84, 0x4c, 0x99, 0x7c, 0x0d, 0xd2, + 0x1e, 0xb5, 0xfb, 0x98, 0x91, 0xc1, 0x68, 0x9a, 0xf4, 0xe8, 0x43, 0xf1, 0x9d, 0x58, 0x6c, 0xe7, + 0xbe, 0x8a, 0x62, 0xfb, 0x3a, 0xc8, 0xda, 0xb0, 0xf9, 0x89, 0xe2, 0xf9, 0xeb, 0xc6, 0x5c, 0xce, + 0x4a, 0x0b, 0xc9, 0xd6, 0x7e, 0x88, 0x51, 0x1d, 0xa6, 0x70, 0xdc, 0x05, 0x72, 0x55, 0x5d, 0x10, + 0x6b, 0xe1, 0xf6, 0xe8, 0x6b, 0x1c, 0xea, 0x1a, 0x2b, 0x87, 0xf5, 0x4f, 0xf3, 0x8f, 0x06, 0xcc, + 0x58, 0xd8, 0xf5, 0x28, 0xc3, 0x51, 0x7c, 0x0f, 0x16, 0xfe, 0x19, 0xfa, 0x2e, 0x64, 0x77, 0x23, + 0xd2, 0x15, 0x7b, 0x0d, 0x53, 0xfa, 0xda, 0x97, 0x6e, 0x86, 0x5b, 0x2b, 0x11, 0x7a, 0x07, 0x26, + 0x04, 0xb5, 0x94, 0xa0, 0x76, 0xe3, 0xd8, 0x17, 0x9f, 0x20, 0x25, 0xcc, 0xef, 0x7d, 0xfb, 0x93, + 0x27, 0xe5, 0xb1, 0x7f, 0x3f, 0x29, 0x8f, 0x7d, 0xfc, 0xe2, 0xe9, 0x7c, 0x66, 0xfd, 0xc8, 0xe1, + 0x2f, 0x5e, 0x3c, 0x9d, 0xbf, 0xa2, 0x25, 0x53, 0x3f, 0x6b, 0x96, 0xa0, 0xf8, 0x6a, 0x00, 0x34, + 0x24, 0x01, 0xc5, 0xe6, 0x97, 0x06, 0xe4, 0x1a, 0x21, 0xab, 0x05, 0x8c, 0x2c, 0x3d, 0x6c, 0x9e, + 0x3a, 0xae, 0x32, 0x64, 0x9c, 0x3e, 0x1d, 0x9c, 0x95, 0xaf, 0x09, 0x70, 0xfa, 0x34, 0x36, 0x78, + 0x17, 0xf2, 0x61, 0x6f, 0xc7, 0xf7, 0x5a, 0xf6, 0x63, 0xbc, 0x6f, 0x3f, 0xa2, 0x24, 0x50, 0xe3, + 0x79, 0x9a, 0xff, 0xf6, 0xd9, 0x14, 0xaa, 0xf7, 0xf1, 0xfe, 0x0f, 0x9a, 0x8d, 0xba, 0x95, 0x0b, + 0x07, 0x9f, 0x94, 0x04, 0xf7, 0xde, 0x39, 0x2e, 0xf8, 0xe2, 0x50, 0xf0, 0x5a, 0x3c, 0xe6, 0x45, + 0x40, 0xba, 0x40, 0xc5, 0xfd, 0x5b, 0x03, 0xa6, 0xe4, 0x7b, 0xb2, 0xb1, 0xfb, 0xff, 0x08, 0xfc, + 0xde, 0x77, 0x8e, 0x63, 0x7f, 0x75, 0x98, 0xbd, 0xc6, 0xca, 0xbc, 0xc4, 0x7f, 0x68, 0x69, 0x12, + 0xc5, 0xff, 0x99, 0x01, 0xb9, 0x26, 0x66, 0x2b, 0x24, 0xa0, 0xef, 0xe3, 0x7d, 0x4e, 0x7f, 0x11, + 0x2e, 0xbc, 0x29, 0xf3, 0xd8, 0xf0, 0x2b, 0xbd, 0xae, 0xbb, 0x7a, 0xc0, 0x31, 0xe2, 0xcb, 0x57, + 0x35, 0x14, 0x02, 0xbf, 0x2a, 0x5d, 0x20, 0x43, 0x9d, 0xf7, 0x21, 0xdd, 0x1c, 0x74, 0x77, 0x09, + 0x2e, 0x37, 0x37, 0x96, 0x9a, 0xf7, 0xed, 0xad, 0x1f, 0x6e, 0xae, 0xd9, 0xdb, 0xf5, 0xe6, 0xe6, + 0xda, 0x4a, 0x6d, 0xbd, 0xb6, 0xb6, 0x5a, 0x18, 0x43, 0xd7, 0xa0, 0xa8, 0xe9, 0x6a, 0xf5, 0xe6, + 0xd6, 0x52, 0x7d, 0xcb, 0x16, 0xa2, 0x82, 0x81, 0x6e, 0xc2, 0x0d, 0x4d, 0x5b, 0x6f, 0xc4, 0x06, + 0x4b, 0xf5, 0xb5, 0xc6, 0x76, 0x53, 0x99, 0xa5, 0x16, 0xff, 0x3a, 0x01, 0xe3, 0x0f, 0xa8, 0x8b, + 0x9e, 0x18, 0x50, 0x78, 0xb9, 0x6b, 0x50, 0xf2, 0x2a, 0x48, 0x98, 0x0e, 0xa5, 0x85, 0x37, 0xb4, + 0x54, 0xd7, 0xf9, 0xf6, 0xc7, 0x7f, 0xf9, 0xd7, 0xa7, 0xa9, 0x05, 0xf3, 0x9b, 0xd5, 0xe4, 0x3f, + 0x09, 0x55, 0x93, 0x26, 0xd0, 0x27, 0x06, 0xc0, 0x51, 0xbe, 0x90, 0x99, 0x3c, 0xe0, 0xf4, 0x0c, + 0x97, 0x6e, 0xbf, 0xd6, 0x46, 0x11, 0x5a, 0x10, 0x84, 0x6e, 0x9b, 0x37, 0x47, 0x11, 0x1a, 0x2e, + 0x3e, 0x4e, 0xe5, 0xa8, 0xcb, 0x46, 0x50, 0x19, 0xea, 0xcb, 0x11, 0x54, 0x12, 0x5a, 0xf5, 0xb5, + 0x54, 0x86, 0xe7, 0xd7, 0x2f, 0x0d, 0xc8, 0x68, 0x1d, 0x83, 0xde, 0x1a, 0x85, 0xa3, 0x75, 0x59, + 0x69, 0xee, 0xf5, 0x46, 0x8a, 0x4d, 0x45, 0xb0, 0x99, 0x33, 0x6f, 0x1d, 0xc3, 0x46, 0xf7, 0x7c, + 0xee, 0xe7, 0xfc, 0x57, 0xc6, 0xf2, 0xc6, 0xe7, 0x87, 0xb3, 0xc6, 0x17, 0x87, 0xb3, 0xc6, 0x3f, + 0x0f, 0x67, 0x8d, 0x5f, 0x3d, 0x9f, 0x1d, 0xfb, 0xe2, 0xf9, 0xec, 0xd8, 0xdf, 0x9e, 0xcf, 0x8e, + 0x7d, 0xb0, 0xa8, 0x6d, 0xc5, 0x35, 0xe9, 0xb2, 0x8e, 0xd9, 0x87, 0x24, 0x7a, 0x3c, 0x40, 0xd8, + 0x3b, 0xc2, 0x10, 0x5b, 0x72, 0xe7, 0xbc, 0xf8, 0x5b, 0xdb, 0xdb, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0xff, 0x9d, 0x68, 0xf9, 0xb8, 0x41, 0x14, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1441,6 +1660,148 @@ func (m *OperatorOptedUSDValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *OperatorVotingPower) 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 *OperatorVotingPower) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OperatorVotingPower) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.VotingPower.Size() + i -= size + if _, err := m.VotingPower.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.OperatorAddr) > 0 { + i -= len(m.OperatorAddr) + copy(dAtA[i:], m.OperatorAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.OperatorAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *VotingPowerSnapshot) 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 *VotingPowerSnapshot) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VotingPowerSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.EpochNumber != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.EpochNumber)) + i-- + dAtA[i] = 0x28 + } + if len(m.EpochIdentifier) > 0 { + i -= len(m.EpochIdentifier) + copy(dAtA[i:], m.EpochIdentifier) + i = encodeVarintTx(dAtA, i, uint64(len(m.EpochIdentifier))) + i-- + dAtA[i] = 0x22 + } + if m.LastChangedHeight != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.LastChangedHeight)) + i-- + dAtA[i] = 0x18 + } + if len(m.OperatorVotingPowers) > 0 { + for iNdEx := len(m.OperatorVotingPowers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.OperatorVotingPowers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size := m.TotalVotingPower.Size() + i -= size + if _, err := m.TotalVotingPower.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *SnapshotHelper) 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 *SnapshotHelper) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotHelper) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.HasOptOut { + i-- + if m.HasOptOut { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.LastChangedHeight != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.LastChangedHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *ClientChainEarningAddrList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1779,6 +2140,11 @@ func (m *SlashExecutionInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.UndelegationFilterHeight != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.UndelegationFilterHeight)) + i-- + dAtA[i] = 0x28 + } if len(m.SlashAssetsPool) > 0 { for iNdEx := len(m.SlashAssetsPool) - 1; iNdEx >= 0; iNdEx-- { { @@ -2203,32 +2569,89 @@ func (m *OperatorOptedUSDValue) Size() (n int) { return n } -func (m *ClientChainEarningAddrList) Size() (n int) { +func (m *OperatorVotingPower) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.EarningInfoList) > 0 { - for _, e := range m.EarningInfoList { - l = e.Size() - n += 1 + l + sovTx(uint64(l)) - } + l = len(m.OperatorAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) } + l = m.VotingPower.Size() + n += 1 + l + sovTx(uint64(l)) return n } -func (m *ClientChainEarningAddrInfo) Size() (n int) { +func (m *VotingPowerSnapshot) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.LzClientChainID != 0 { - n += 1 + sovTx(uint64(m.LzClientChainID)) - } - l = len(m.ClientChainEarningAddr) - if l > 0 { + l = m.TotalVotingPower.Size() + n += 1 + l + sovTx(uint64(l)) + if len(m.OperatorVotingPowers) > 0 { + for _, e := range m.OperatorVotingPowers { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + if m.LastChangedHeight != 0 { + n += 1 + sovTx(uint64(m.LastChangedHeight)) + } + l = len(m.EpochIdentifier) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.EpochNumber != 0 { + n += 1 + sovTx(uint64(m.EpochNumber)) + } + return n +} + +func (m *SnapshotHelper) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.LastChangedHeight != 0 { + n += 1 + sovTx(uint64(m.LastChangedHeight)) + } + if m.HasOptOut { + n += 2 + } + return n +} + +func (m *ClientChainEarningAddrList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.EarningInfoList) > 0 { + for _, e := range m.EarningInfoList { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *ClientChainEarningAddrInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.LzClientChainID != 0 { + n += 1 + sovTx(uint64(m.LzClientChainID)) + } + l = len(m.ClientChainEarningAddr) + if l > 0 { n += 1 + l + sovTx(uint64(l)) } return n @@ -2352,6 +2775,9 @@ func (m *SlashExecutionInfo) Size() (n int) { n += 1 + l + sovTx(uint64(l)) } } + if m.UndelegationFilterHeight != 0 { + n += 1 + sovTx(uint64(m.UndelegationFilterHeight)) + } return n } @@ -2740,6 +3166,399 @@ func (m *OperatorOptedUSDValue) Unmarshal(dAtA []byte) error { } return nil } +func (m *OperatorVotingPower) 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: OperatorVotingPower: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OperatorVotingPower: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperatorAddr", 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.OperatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", 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 + } + if err := m.VotingPower.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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 *VotingPowerSnapshot) 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: VotingPowerSnapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VotingPowerSnapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalVotingPower", 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 + } + if err := m.TotalVotingPower.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperatorVotingPowers", 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.OperatorVotingPowers = append(m.OperatorVotingPowers, &OperatorVotingPower{}) + if err := m.OperatorVotingPowers[len(m.OperatorVotingPowers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastChangedHeight", wireType) + } + m.LastChangedHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastChangedHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochIdentifier", 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.EpochIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) + } + m.EpochNumber = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNumber |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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 *SnapshotHelper) 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: SnapshotHelper: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotHelper: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastChangedHeight", wireType) + } + m.LastChangedHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastChangedHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HasOptOut", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.HasOptOut = bool(v != 0) + 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 *ClientChainEarningAddrList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3827,6 +4646,25 @@ func (m *SlashExecutionInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UndelegationFilterHeight", wireType) + } + m.UndelegationFilterHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UndelegationFilterHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/operator/types/utils.go b/x/operator/types/utils.go index 6ec7351a9..c940bafec 100644 --- a/x/operator/types/utils.go +++ b/x/operator/types/utils.go @@ -25,3 +25,12 @@ func ChainIDWithLenKey(chainID string) []byte { []byte(chainID), ) } + +func GetSpecifiedVotingPower(operator string, votingPowerSet []*OperatorVotingPower) *OperatorVotingPower { + for _, vp := range votingPowerSet { + if vp.OperatorAddr == operator { + return vp + } + } + return nil +} diff --git a/x/oracle/keeper/native_token.go b/x/oracle/keeper/native_token.go index a2b5a8151..52e5d3b81 100644 --- a/x/oracle/keeper/native_token.go +++ b/x/oracle/keeper/native_token.go @@ -313,7 +313,7 @@ func (k Keeper) UpdateNSTByBalanceChange(ctx sdk.Context, assetID string, rawDat func (k Keeper) getDecimal(ctx sdk.Context, assetID string) (int, sdkmath.Int, error) { decimalMap, err := k.assetsKeeper.GetAssetsDecimal(ctx, map[string]interface{}{assetID: nil}) if err != nil { - return 0, sdkmath.NewInt(0), err + return 0, sdkmath.ZeroInt(), err } decimal := decimalMap[assetID] return int(decimal), sdkmath.NewIntWithDecimal(1, int(decimal)), nil diff --git a/x/reward/keeper/claim_reward_test.go b/x/reward/keeper/claim_reward_test.go index 04b7a9098..e3efed965 100644 --- a/x/reward/keeper/claim_reward_test.go +++ b/x/reward/keeper/claim_reward_test.go @@ -40,7 +40,7 @@ func (suite *RewardTestSuite) TestClaimWithdrawRequest() { // suite.Equal(types.StakerAssetInfo{ // TotalDepositAmount: sdkmath.NewInt(10), // WithdrawableAmount: sdkmath.NewInt(10), - // PendingUndelegationAmount: sdkmath.NewInt(0), + // PendingUndelegationAmount: sdkmath.ZeroInt(), // }, *info) // assetInfo, err := suite.App.AssetsKeeper.GetStakingAssetInfo(suite.Ctx, assetID) diff --git a/x/slash/keeper/execute_slash_test.go b/x/slash/keeper/execute_slash_test.go index c2f1cb086..d0a76f9fa 100644 --- a/x/slash/keeper/execute_slash_test.go +++ b/x/slash/keeper/execute_slash_test.go @@ -37,7 +37,7 @@ func (suite *SlashTestSuite) TestSlash() { suite.Equal(types.StakerAssetInfo{ TotalDepositAmount: depositEvent.OpAmount, WithdrawableAmount: depositEvent.OpAmount, - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), }, *info) // test the normal case @@ -52,7 +52,7 @@ func (suite *SlashTestSuite) TestSlash() { suite.Equal(types.StakerAssetInfo{ TotalDepositAmount: sdkmath.NewInt(10), WithdrawableAmount: sdkmath.NewInt(10), - PendingUndelegationAmount: sdkmath.NewInt(0), + PendingUndelegationAmount: sdkmath.ZeroInt(), }, *info) assetInfo, err := suite.App.AssetsKeeper.GetStakingAssetInfo(suite.Ctx, assetID)