diff --git a/Makefile b/Makefile index 5fa3aa0ce..922f6a15b 100644 --- a/Makefile +++ b/Makefile @@ -430,7 +430,7 @@ proto-download-deps: git remote add origin "https://github.com/cosmos/cosmos-sdk.git" && \ git config core.sparseCheckout true && \ printf "proto\nthird_party\n" > .git/info/sparse-checkout && \ - git pull origin main && \ + git pull origin release/v0.47.x && \ rm -f ./proto/buf.* && \ mv ./proto/* .. rm -rf "$(THIRD_PARTY_DIR)/cosmos_tmp" @@ -441,7 +441,7 @@ proto-download-deps: git remote add origin "https://github.com/cosmos/ibc-go.git" && \ git config core.sparseCheckout true && \ printf "proto\n" > .git/info/sparse-checkout && \ - git pull origin main && \ + git pull origin release/v7.2.x && \ rm -f ./proto/buf.* && \ mv ./proto/* .. rm -rf "$(THIRD_PARTY_DIR)/ibc_tmp" @@ -452,7 +452,8 @@ proto-download-deps: git remote add origin "https://github.com/cosmos/cosmos-proto.git" && \ git config core.sparseCheckout true && \ printf "proto\n" > .git/info/sparse-checkout && \ - git pull origin main && \ + git fetch origin tags/v1.0.0-beta.3 && \ + git checkout -b my_branch FETCH_HEAD && \ rm -f ./proto/buf.* && \ mv ./proto/* .. rm -rf "$(THIRD_PARTY_DIR)/cosmos_proto_tmp" diff --git a/proto/exocore/operator/v1/tx.proto b/proto/exocore/operator/v1/tx.proto index ce386e4b0..d8ca11588 100644 --- a/proto/exocore/operator/v1/tx.proto +++ b/proto/exocore/operator/v1/tx.proto @@ -3,6 +3,7 @@ package exocore.operator.v1; import "amino/amino.proto"; import "cosmos/msg/v1/msg.proto"; +import "cosmos/staking/v1beta1/staking.proto"; import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; @@ -45,6 +46,8 @@ message OperatorInfo { string operator_meta_info = 3; // client_chain_earning_addr_list is the client chain earning address list. ClientChainEarningAddrList client_chain_earnings_addr = 4; + // commission defines the commission parameters. + cosmos.staking.v1beta1.Commission commission = 5 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; } // OptedInfo is the opted information about operator @@ -55,6 +58,8 @@ message OptedInfo { uint64 opted_in_height = 2; // opted_out_height is the exocore block height at which the operator opted out uint64 opted_out_height = 3; + // jailed defined whether the operator has been jailed from bonded status or not. + bool jailed = 4; } // OptedInAssetState is the state of opted-in asset diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index 7c7b517ea..ab913abf5 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -51,8 +51,8 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { prev := k.getKeyPowerMapping(ctx).List res := make([]abci.ValidatorUpdate, 0, len(prev)) operators, keys := k.operatorKeeper.GetActiveOperatorsForChainID(ctx, ctx.ChainID()) - powers, err := k.restakingKeeper.GetAvgDelegatedValue( - ctx, operators, k.GetAssetIDs(ctx), k.GetEpochIdentifier(ctx), + powers, err := k.operatorKeeper.GetAvgDelegatedValue( + ctx, operators, ctx.ChainID(), k.GetEpochIdentifier(ctx), ) if err != nil { return []abci.ValidatorUpdate{} diff --git a/x/dogfood/keeper/impl_sdk.go b/x/dogfood/keeper/impl_sdk.go index 78a44aafd..7986c2950 100644 --- a/x/dogfood/keeper/impl_sdk.go +++ b/x/dogfood/keeper/impl_sdk.go @@ -62,15 +62,8 @@ func (k Keeper) ValidatorByConsAddr( ctx sdk.Context, addr sdk.ConsAddress, ) stakingtypes.ValidatorI { - found, accAddr := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, ctx.ChainID(), addr, - ) - if !found { - // replicate the behavior of the SDK's staking module; do not panic. - return nil - } return stakingtypes.Validator{ - Jailed: k.operatorKeeper.IsOperatorJailedForChainID(ctx, accAddr, ctx.ChainID()), + Jailed: k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, ctx.ChainID()), } } @@ -104,7 +97,7 @@ func (k Keeper) SlashWithInfractionReason( } // TODO(mm): add list of assets to be slashed (and not just all of them). // based on yet to be finalized slashing design. - return k.slashingKeeper.SlashWithInfractionReason( + return k.operatorKeeper.SlashWithInfractionReason( ctx, accAddress, infractionHeight, power, slashFactor, infraction, ) @@ -124,8 +117,8 @@ func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { // The function is called by the slashing module only when it receives a request from the // operator to do so. TODO(mm): We need to use the SDK's slashing module to allow for downtime // slashing but somehow we need to prevent its Unjail function from being called by anyone. -func (k Keeper) Unjail(sdk.Context, sdk.ConsAddress) { - panic("unimplemented on this keeper") +func (k Keeper) Unjail(ctx sdk.Context, addr sdk.ConsAddress) { + k.operatorKeeper.Unjail(ctx, addr, ctx.ChainID()) } // Delegation is an implementation of the staking interface expected by the SDK's slashing @@ -155,14 +148,7 @@ func (k Keeper) GetAllValidators(sdk.Context) (validators []stakingtypes.Validat // slashing module. It is called by the slashing module to record validator signatures // for downtime tracking. We delegate the call to the operator keeper. func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool { - found, accAddr := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, ctx.ChainID(), addr, - ) - if !found { - // replicate the behavior of the SDK's staking module - return false - } - return k.operatorKeeper.IsOperatorJailedForChainID(ctx, accAddr, ctx.ChainID()) + return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, ctx.ChainID()) } // ApplyAndReturnValidatorSetUpdates is an implementation of the staking interface expected diff --git a/x/dogfood/types/expected_keepers.go b/x/dogfood/types/expected_keepers.go index a14789775..8b7412685 100644 --- a/x/dogfood/types/expected_keepers.go +++ b/x/dogfood/types/expected_keepers.go @@ -53,14 +53,22 @@ type OperatorKeeper interface { GetOperatorAddressForChainIDAndConsAddr( sdk.Context, string, sdk.ConsAddress, ) (bool, sdk.AccAddress) - IsOperatorJailedForChainID(sdk.Context, sdk.AccAddress, string) bool + IsOperatorJailedForChainID(sdk.Context, sdk.ConsAddress, string) bool Jail(sdk.Context, sdk.ConsAddress, string) + Unjail(sdk.Context, sdk.ConsAddress, string) // GetActiveOperatorsForChainID should return a list of operators and their public keys. - // These operators should not be in the process of opting our, and should not be jailed + // These operators should not be in the process of opting out, and should not be jailed // whether permanently or temporarily. GetActiveOperatorsForChainID( sdk.Context, string, ) ([]sdk.AccAddress, []tmprotocrypto.PublicKey) + GetAvgDelegatedValue( + sdk.Context, []sdk.AccAddress, string, string, + ) ([]int64, error) + SlashWithInfractionReason( + sdk.Context, sdk.AccAddress, int64, + int64, sdk.Dec, stakingtypes.Infraction, + ) math.Int } // DelegationKeeper represents the expected keeper interface for the delegation module. @@ -77,17 +85,8 @@ type EpochsHooks interface { // AssetsKeeper represents the expected keeper interface for the assets module. type AssetsKeeper interface { - GetOperatorAssetValue(sdk.Context, sdk.AccAddress) (int64, error) IsStakingAsset(sdk.Context, string) bool - GetAvgDelegatedValue( - sdk.Context, []sdk.AccAddress, []string, string, - ) ([]int64, error) } // SlashingKeeper represents the expected keeper interface for the (exo-)slashing module. -type SlashingKeeper interface { - SlashWithInfractionReason( - sdk.Context, sdk.AccAddress, int64, - int64, sdk.Dec, stakingtypes.Infraction, - ) math.Int -} +type SlashingKeeper interface{} diff --git a/x/operator/keeper/avs_operator_shares.go b/x/operator/keeper/avs_operator_shares.go index a2ae08356..a846a1971 100644 --- a/x/operator/keeper/avs_operator_shares.go +++ b/x/operator/keeper/avs_operator_shares.go @@ -335,3 +335,35 @@ func (k *Keeper) GetStakerShare(ctx sdk.Context, avsAddr, stakerID, operatorAddr return ret.Amount, nil } + +func (k *Keeper) GetAvgDelegatedValue( + ctx sdk.Context, operators []sdk.AccAddress, chainID, _ string, +) ([]int64, error) { + avsAddr, err := k.avsKeeper.GetAvsAddrByChainID(ctx, chainID) + if err != nil { + return nil, err + } + ret := make([]int64, 0) + for _, operator := range operators { + share, err := k.GetOperatorShare(ctx, operator.String(), avsAddr) + if err != nil { + return nil, err + } + // truncate the USD value to int64 + ret = append(ret, share.TruncateInt64()) + } + return ret, nil +} + +func (k *Keeper) GetOperatorAssetValue(ctx sdk.Context, operator sdk.AccAddress, chainID string) (int64, error) { + avsAddr, err := k.avsKeeper.GetAvsAddrByChainID(ctx, chainID) + if err != nil { + return 0, err + } + share, err := k.GetOperatorShare(ctx, operator.String(), avsAddr) + if err != nil { + return 0, err + } + // truncate the USD value to int64 + return share.TruncateInt64(), nil +} diff --git a/x/operator/keeper/consensus_keys.go b/x/operator/keeper/consensus_keys.go index 2701744e9..5472898a8 100644 --- a/x/operator/keeper/consensus_keys.go +++ b/x/operator/keeper/consensus_keys.go @@ -435,12 +435,6 @@ func (k *Keeper) CompleteOperatorOptOutFromChainID( store.Delete(types.KeyForOperatorOptOutFromChainID(opAccAddr, chainID)) } -// IsOperatorJailedForChainID add for dogfood -func (k *Keeper) IsOperatorJailedForChainID(sdk.Context, sdk.AccAddress, string) bool { - return false -} -func (k *Keeper) Jail(sdk.Context, sdk.ConsAddress, string) {} - func (k *Keeper) GetActiveOperatorsForChainID( sdk.Context, string, ) ([]sdk.AccAddress, []*tmprotocrypto.PublicKey) { diff --git a/x/operator/keeper/msg_server.go b/x/operator/keeper/msg_server.go index e7ae588b6..6eceba5f6 100644 --- a/x/operator/keeper/msg_server.go +++ b/x/operator/keeper/msg_server.go @@ -41,6 +41,15 @@ func (k *Keeper) OptInToCosmosChain( if err != nil { return nil, err } + // call the basic OptIn + avsAddr, err := k.avsKeeper.GetAvsAddrByChainID(ctx, req.ChainId) + if err != nil { + return nil, err + } + err = k.OptIn(ctx, addr, avsAddr) + if err != nil { + return nil, err + } return &types.OptInToCosmosChainResponse{}, nil } diff --git a/x/operator/keeper/operator.go b/x/operator/keeper/operator.go index 8d366d5e6..ebad2d5f3 100644 --- a/x/operator/keeper/operator.go +++ b/x/operator/keeper/operator.go @@ -19,7 +19,6 @@ func (k *Keeper) SetOperatorInfo(ctx sdk.Context, addr string, info *operatortyp if err != nil { return errorsmod.Wrap(err, "SetOperatorInfo: error occurred when parse acc address from Bech32") } - // todo: to check the validation of input info store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorInfo) // todo: think about the difference between init and update in future @@ -49,12 +48,49 @@ func (k *Keeper) OperatorInfo(ctx sdk.Context, addr string) (info *operatortypes return &ret, nil } +// AllOperators return the address list of all operators +func (k *Keeper) AllOperators(ctx sdk.Context) []string { + store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorInfo) + iterator := sdk.KVStorePrefixIterator(store, nil) + defer iterator.Close() + + ret := make([]string, 0) + for ; iterator.Valid(); iterator.Next() { + accAddr := sdk.AccAddress(iterator.Key()) + ret = append(ret, accAddr.String()) + } + return ret +} + func (k *Keeper) IsOperator(ctx sdk.Context, addr sdk.AccAddress) bool { store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorInfo) return store.Has(addr) } -func (k *Keeper) UpdateOptedInfo(ctx sdk.Context, operatorAddr, avsAddr string, info *operatortypes.OptedInfo) error { +func (k *Keeper) HandleOptedInfo(ctx sdk.Context, operatorAddr, avsAddr string, handleFunc func(info *operatortypes.OptedInfo)) error { + opAccAddr, err := sdk.AccAddressFromBech32(operatorAddr) + if err != nil { + return errorsmod.Wrap(err, "HandleOptedInfo: error occurred when parse acc address from Bech32") + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) + infoKey := assetstype.GetJoinedStoreKey(operatorAddr, avsAddr) + ifExist := store.Has(infoKey) + if !ifExist { + return errorsmod.Wrap(operatortypes.ErrNoKeyInTheStore, fmt.Sprintf("HandleOptedInfo: key is %suite", opAccAddr)) + } + // get info from the store + value := store.Get(infoKey) + info := &operatortypes.OptedInfo{} + k.cdc.MustUnmarshal(value, info) + // call the handleFunc + handleFunc(info) + // restore the info after handling + bz := k.cdc.MustMarshal(info) + store.Set(infoKey, bz) + return nil +} + +func (k *Keeper) SetOptedInfo(ctx sdk.Context, operatorAddr, avsAddr string, info *operatortypes.OptedInfo) error { store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) // check operator address validation @@ -99,6 +135,20 @@ func (k *Keeper) IsOptedIn(ctx sdk.Context, operatorAddr, avsAddr string) bool { return true } +func (k *Keeper) IsActive(ctx sdk.Context, operatorAddr, avsAddr string) bool { + optedInfo, err := k.GetOptedInfo(ctx, operatorAddr, avsAddr) + if err != nil { + return false + } + if optedInfo.OptedOutHeight != operatortypes.DefaultOptedOutHeight { + return false + } + if optedInfo.Jailed { + return false + } + return true +} + func (k *Keeper) GetOptedInAVSForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { // get all opted-in info store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) diff --git a/x/operator/keeper/operator_info_test.go b/x/operator/keeper/operator_info_test.go index 6c4109d35..e83e6053c 100644 --- a/x/operator/keeper/operator_info_test.go +++ b/x/operator/keeper/operator_info_test.go @@ -1,8 +1,10 @@ package keeper_test import ( + "cosmossdk.io/math" "github.com/ExocoreNetwork/exocore/x/assets/types" operatortype "github.com/ExocoreNetwork/exocore/x/operator/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) func (suite *OperatorTestSuite) TestOperatorInfo() { @@ -15,6 +17,7 @@ func (suite *OperatorTestSuite) TestOperatorInfo() { {101, "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"}, }, }, + Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()), } err := suite.App.OperatorKeeper.SetOperatorInfo(suite.Ctx, suite.AccAddress.String(), info) suite.NoError(err) @@ -24,6 +27,17 @@ func (suite *OperatorTestSuite) TestOperatorInfo() { suite.Equal(*info, *getOperatorInfo) } +func (suite *OperatorTestSuite) TestAllOperators() { + suite.prepare() + operators := []string{suite.operatorAddr.String(), suite.AccAddress.String()} + info := &operatortype.OperatorInfo{} + err := suite.App.OperatorKeeper.SetOperatorInfo(suite.Ctx, suite.AccAddress.String(), info) + suite.NoError(err) + + getOperators := suite.App.OperatorKeeper.AllOperators(suite.Ctx) + suite.Equal(operators, getOperators) +} + func (suite *OperatorTestSuite) TestHistoricalOperatorInfo() { height := suite.Ctx.BlockHeight() info := &operatortype.OperatorInfo{ diff --git a/x/operator/keeper/opt.go b/x/operator/keeper/opt.go new file mode 100644 index 000000000..75c1fd9cf --- /dev/null +++ b/x/operator/keeper/opt.go @@ -0,0 +1,280 @@ +package keeper + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + errorsmod "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" + + "github.com/ExocoreNetwork/exocore/x/operator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type AssetPriceAndDecimal struct { + Price sdkmath.Int + PriceDecimal uint8 + Decimal uint32 +} + +type slashAmounts struct { + AmountFromUnbonding sdkmath.Int + AmountFromOptedIn sdkmath.Int +} +type SlashAssets struct { + slashStakerInfo map[string]map[string]*slashAmounts + slashOperatorInfo map[string]*slashAmounts +} + +// UpdateOptedInAssetsState will update the USD share state related to asset, operator and AVS when +// the asset amount changes caused by delegation, undelegation, slashStaker and slashOperator. +func (k *Keeper) UpdateOptedInAssetsState(ctx sdk.Context, stakerID, assetID, operatorAddr string, opAmount sdkmath.Int) error { + // get the AVS opted-in by the operator + avsList, err := k.GetOptedInAVSForOperator(ctx, operatorAddr) + if err != nil { + return err + } + // get price and priceDecimal from oracle + price, decimal, err := k.oracleKeeper.GetSpecifiedAssetsPrice(ctx, assetID) + if err != nil { + return err + } + + // get the decimal of asset + assetInfo, err := k.assetsKeeper.GetStakingAssetInfo(ctx, assetID) + if err != nil { + return err + } + opUSDValue := CalculateShare(opAmount, price, assetInfo.AssetBasicInfo.Decimals, decimal) + for _, avs := range avsList { + // get the assets supported by the AVS + avsSupportedAssets, err := k.avsKeeper.GetAvsSupportedAssets(ctx, avs) + if err != nil { + return err + } + + if _, ok := avsSupportedAssets[assetID]; ok { + // UpdateStakerShare + err = k.UpdateStakerShare(ctx, avs, stakerID, operatorAddr, opUSDValue) + if err != nil { + return err + } + + // UpdateStateForAsset + changeState := types.OptedInAssetStateChange{ + Amount: opAmount, + Value: opUSDValue, + } + err = k.UpdateStateForAsset(ctx, assetID, avs, operatorAddr, changeState) + if err != nil { + return err + } + + // UpdateOperatorShare + err = k.UpdateOperatorShare(ctx, avs, operatorAddr, opUSDValue) + if err != nil { + return err + } + + // UpdateAVSShare + err = k.UpdateAVSShare(ctx, avs, opUSDValue) + if err != nil { + return err + } + } + } + return nil +} + +// OptIn call this function to opt in AVS +func (k *Keeper) OptIn(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string) error { + // avsAddr should be an evm contract address + if common.IsHexAddress(avsAddr) { + return types.ErrInvalidAvsAddr + } + // check optedIn info + if k.IsOptedIn(ctx, operatorAddress.String(), avsAddr) { + return types.ErrAlreadyOptedIn + } + // get the assets supported by the AVS + avsSupportedAssets, err := k.avsKeeper.GetAvsSupportedAssets(ctx, avsAddr) + if err != nil { + return err + } + + // get the Assets opted in the operator + operatorAssets, err := k.assetsKeeper.GetOperatorAssetInfos(ctx, operatorAddress, avsSupportedAssets) + if err != nil { + return err + } + + totalAssetUSDValue := sdkmath.LegacyNewDec(0) + operatorOwnAssetUSDValue := sdkmath.LegacyNewDec(0) + assetFilter := make(map[string]interface{}) + assetInfoRecord := make(map[string]*AssetPriceAndDecimal) + + for assetID, operatorAssetState := range operatorAssets { + // get price and priceDecimal from oracle + price, decimal, err := k.oracleKeeper.GetSpecifiedAssetsPrice(ctx, assetID) + if err != nil { + return err + } + + // get the decimal of asset + assetInfo, err := k.assetsKeeper.GetStakingAssetInfo(ctx, assetID) + if err != nil { + return err + } + assetInfoRecord[assetID] = &AssetPriceAndDecimal{ + Price: price, + PriceDecimal: decimal, + Decimal: assetInfo.AssetBasicInfo.Decimals, + } + assetUSDValue := CalculateShare(operatorAssetState.TotalAmount, price, assetInfo.AssetBasicInfo.Decimals, decimal) + operatorUSDValue := CalculateShare(operatorAssetState.OperatorAmount, price, assetInfo.AssetBasicInfo.Decimals, decimal) + operatorOwnAssetUSDValue = operatorOwnAssetUSDValue.Add(operatorUSDValue) + + // UpdateStateForAsset + changeState := types.OptedInAssetStateChange{ + Amount: operatorAssetState.TotalAmount, + Value: assetUSDValue, + } + err = k.UpdateStateForAsset(ctx, assetID, avsAddr, operatorAddress.String(), changeState) + if err != nil { + return err + } + totalAssetUSDValue = totalAssetUSDValue.Add(assetUSDValue) + assetFilter[assetID] = nil + } + + // update the share value of operator itself, the input stakerID should be empty + err = k.UpdateStakerShare(ctx, avsAddr, "", operatorAddress.String(), operatorOwnAssetUSDValue) + if err != nil { + return err + } + + // UpdateAVSShare + err = k.UpdateAVSShare(ctx, avsAddr, totalAssetUSDValue) + if err != nil { + return err + } + // UpdateOperatorShare + err = k.UpdateOperatorShare(ctx, avsAddr, operatorAddress.String(), totalAssetUSDValue) + if err != nil { + return err + } + + // UpdateStakerShare + relatedAssetsState, err := k.delegationKeeper.DelegationStateByOperatorAssets(ctx, operatorAddress.String(), assetFilter) + if err != nil { + return err + } + + for stakerID, assetState := range relatedAssetsState { + stakerAssetsUSDValue := sdkmath.LegacyNewDec(0) + for assetID, amount := range assetState { + singleAssetUSDValue := CalculateShare(amount.UndelegatableAmount, assetInfoRecord[assetID].Price, assetInfoRecord[assetID].Decimal, assetInfoRecord[assetID].PriceDecimal) + stakerAssetsUSDValue = stakerAssetsUSDValue.Add(singleAssetUSDValue) + } + + err = k.UpdateStakerShare(ctx, avsAddr, stakerID, operatorAddress.String(), stakerAssetsUSDValue) + if err != nil { + return err + } + } + + // update opted-in info + slashContract, err := k.avsKeeper.GetAvsSlashContract(ctx, avsAddr) + if err != nil { + return err + } + optedInfo := &types.OptedInfo{ + SlashContract: slashContract, + // #nosec G701 + OptedInHeight: uint64(ctx.BlockHeight()), + OptedOutHeight: types.DefaultOptedOutHeight, + } + err = k.SetOptedInfo(ctx, operatorAddress.String(), avsAddr, optedInfo) + if err != nil { + return err + } + return nil +} + +// OptOut call this function to opt out of AVS +func (k *Keeper) OptOut(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string) error { + // check optedIn info + if !k.IsOptedIn(ctx, operatorAddress.String(), avsAddr) { + return types.ErrNotOptedIn + } + + // get the assets supported by the AVS + avsSupportedAssets, err := k.avsKeeper.GetAvsSupportedAssets(ctx, avsAddr) + if err != nil { + return err + } + // get the Assets opted in the operator + operatorAssets, err := k.assetsKeeper.GetOperatorAssetInfos(ctx, operatorAddress, avsSupportedAssets) + if err != nil { + return err + } + + assetFilter := make(map[string]interface{}) + + for assetID := range operatorAssets { + err = k.DeleteAssetState(ctx, assetID, avsAddr, operatorAddress.String()) + if err != nil { + return err + } + assetFilter[assetID] = nil + } + + avsOperatorTotalValue, err := k.GetOperatorShare(ctx, avsAddr, operatorAddress.String()) + if err != nil { + return err + } + if avsOperatorTotalValue.IsNegative() { + return errorsmod.Wrap(types.ErrTheValueIsNegative, fmt.Sprintf("OptOut,avsOperatorTotalValue:%suite", avsOperatorTotalValue)) + } + + // delete the share value of operator itself, the input stakerID should be empty + err = k.DeleteStakerShare(ctx, avsAddr, "", operatorAddress.String()) + if err != nil { + return err + } + + // UpdateAVSShare + err = k.UpdateAVSShare(ctx, avsAddr, avsOperatorTotalValue.Neg()) + if err != nil { + return err + } + // DeleteOperatorShare + err = k.DeleteOperatorShare(ctx, avsAddr, operatorAddress.String()) + if err != nil { + return err + } + + // DeleteStakerShare + relatedAssetsState, err := k.delegationKeeper.DelegationStateByOperatorAssets(ctx, operatorAddress.String(), assetFilter) + if err != nil { + return err + } + for stakerID := range relatedAssetsState { + err = k.DeleteStakerShare(ctx, avsAddr, stakerID, operatorAddress.String()) + if err != nil { + return err + } + } + + // set opted-out height + handleFunc := func(info *types.OptedInfo) { + // #nosec G701 + info.OptedOutHeight = uint64(ctx.BlockHeight()) + } + err = k.HandleOptedInfo(ctx, operatorAddress.String(), avsAddr, handleFunc) + if err != nil { + return err + } + return nil +} diff --git a/x/operator/keeper/state_update.go b/x/operator/keeper/slash.go similarity index 54% rename from x/operator/keeper/state_update.go rename to x/operator/keeper/slash.go index e047ebb6e..e70c86006 100644 --- a/x/operator/keeper/state_update.go +++ b/x/operator/keeper/slash.go @@ -3,278 +3,22 @@ package keeper import ( "fmt" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/ethereum/go-ethereum/common/hexutil" + errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - types2 "github.com/ExocoreNetwork/exocore/x/assets/types" + assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) -type AssetPriceAndDecimal struct { - Price sdkmath.Int - PriceDecimal uint8 - Decimal uint32 -} - -type slashAmounts struct { - AmountFromUnbonding sdkmath.Int - AmountFromOptedIn sdkmath.Int -} -type SlashAssets struct { - slashStakerInfo map[string]map[string]*slashAmounts - slashOperatorInfo map[string]*slashAmounts -} - -// UpdateOptedInAssetsState will update the USD share state related to asset, operator and AVS when -// the asset amount changes caused by delegation, undelegation, slashStaker and slashOperator. -func (k *Keeper) UpdateOptedInAssetsState(ctx sdk.Context, stakerID, assetID, operatorAddr string, opAmount sdkmath.Int) error { - // get the AVS opted-in by the operator - avsList, err := k.GetOptedInAVSForOperator(ctx, operatorAddr) - if err != nil { - return err - } - // get price and priceDecimal from oracle - price, decimal, err := k.oracleKeeper.GetSpecifiedAssetsPrice(ctx, assetID) - if err != nil { - return err - } - - // get the decimal of asset - assetInfo, err := k.assetsKeeper.GetStakingAssetInfo(ctx, assetID) - if err != nil { - return err - } - opUSDValue := CalculateShare(opAmount, price, assetInfo.AssetBasicInfo.Decimals, decimal) - for _, avs := range avsList { - // get the assets supported by the AVS - avsSupportedAssets, err := k.avsKeeper.GetAvsSupportedAssets(ctx, avs) - if err != nil { - return err - } - - if _, ok := avsSupportedAssets[assetID]; ok { - // UpdateStakerShare - err = k.UpdateStakerShare(ctx, avs, stakerID, operatorAddr, opUSDValue) - if err != nil { - return err - } - - // UpdateStateForAsset - changeState := types.OptedInAssetStateChange{ - Amount: opAmount, - Value: opUSDValue, - } - err = k.UpdateStateForAsset(ctx, assetID, avs, operatorAddr, changeState) - if err != nil { - return err - } - - // UpdateOperatorShare - err = k.UpdateOperatorShare(ctx, avs, operatorAddr, opUSDValue) - if err != nil { - return err - } - - // UpdateAVSShare - err = k.UpdateAVSShare(ctx, avs, opUSDValue) - if err != nil { - return err - } - } - } - return nil -} - -// OptIn call this function to opt in AVS -func (k *Keeper) OptIn(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string) error { - // check optedIn info - if k.IsOptedIn(ctx, operatorAddress.String(), avsAddr) { - return types.ErrAlreadyOptedIn - } - // get the assets supported by the AVS - avsSupportedAssets, err := k.avsKeeper.GetAvsSupportedAssets(ctx, avsAddr) - if err != nil { - return err - } - - // get the Assets opted in the operator - operatorAssets, err := k.assetsKeeper.GetOperatorAssetInfos(ctx, operatorAddress, avsSupportedAssets) - if err != nil { - return err - } - - totalAssetUSDValue := sdkmath.LegacyNewDec(0) - operatorOwnAssetUSDValue := sdkmath.LegacyNewDec(0) - assetFilter := make(map[string]interface{}) - assetInfoRecord := make(map[string]*AssetPriceAndDecimal) - - for assetID, operatorAssetState := range operatorAssets { - // get price and priceDecimal from oracle - price, decimal, err := k.oracleKeeper.GetSpecifiedAssetsPrice(ctx, assetID) - if err != nil { - return err - } - - // get the decimal of asset - assetInfo, err := k.assetsKeeper.GetStakingAssetInfo(ctx, assetID) - if err != nil { - return err - } - assetInfoRecord[assetID] = &AssetPriceAndDecimal{ - Price: price, - PriceDecimal: decimal, - Decimal: assetInfo.AssetBasicInfo.Decimals, - } - assetUSDValue := CalculateShare(operatorAssetState.TotalAmount, price, assetInfo.AssetBasicInfo.Decimals, decimal) - operatorUSDValue := CalculateShare(operatorAssetState.OperatorAmount, price, assetInfo.AssetBasicInfo.Decimals, decimal) - operatorOwnAssetUSDValue = operatorOwnAssetUSDValue.Add(operatorUSDValue) - - // UpdateStateForAsset - changeState := types.OptedInAssetStateChange{ - Amount: operatorAssetState.TotalAmount, - Value: assetUSDValue, - } - err = k.UpdateStateForAsset(ctx, assetID, avsAddr, operatorAddress.String(), changeState) - if err != nil { - return err - } - totalAssetUSDValue = totalAssetUSDValue.Add(assetUSDValue) - assetFilter[assetID] = nil - } - - // update the share value of operator itself, the input stakerID should be empty - err = k.UpdateStakerShare(ctx, avsAddr, "", operatorAddress.String(), operatorOwnAssetUSDValue) - if err != nil { - return err - } - - // UpdateAVSShare - err = k.UpdateAVSShare(ctx, avsAddr, totalAssetUSDValue) - if err != nil { - return err - } - // UpdateOperatorShare - err = k.UpdateOperatorShare(ctx, avsAddr, operatorAddress.String(), totalAssetUSDValue) - if err != nil { - return err - } - - // UpdateStakerShare - relatedAssetsState, err := k.delegationKeeper.DelegationStateByOperatorAssets(ctx, operatorAddress.String(), assetFilter) - if err != nil { - return err - } - - for stakerID, assetState := range relatedAssetsState { - stakerAssetsUSDValue := sdkmath.LegacyNewDec(0) - for assetID, amount := range assetState { - singleAssetUSDValue := CalculateShare(amount.UndelegatableAmount, assetInfoRecord[assetID].Price, assetInfoRecord[assetID].Decimal, assetInfoRecord[assetID].PriceDecimal) - stakerAssetsUSDValue = stakerAssetsUSDValue.Add(singleAssetUSDValue) - } - - err = k.UpdateStakerShare(ctx, avsAddr, stakerID, operatorAddress.String(), stakerAssetsUSDValue) - if err != nil { - return err - } - } - - // update opted-in info - slashContract, err := k.avsKeeper.GetAvsSlashContract(ctx, avsAddr) - if err != nil { - return err - } - optedInfo := &types.OptedInfo{ - SlashContract: slashContract, - // #nosec G701 - OptedInHeight: uint64(ctx.BlockHeight()), - OptedOutHeight: types.DefaultOptedOutHeight, - } - err = k.UpdateOptedInfo(ctx, operatorAddress.String(), avsAddr, optedInfo) - if err != nil { - return err - } - return nil -} - -// OptOut call this function to opt out of AVS -func (k *Keeper) OptOut(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string) error { - // check optedIn info - if !k.IsOptedIn(ctx, operatorAddress.String(), avsAddr) { - return types.ErrNotOptedIn - } - - // get the assets supported by the AVS - avsSupportedAssets, err := k.avsKeeper.GetAvsSupportedAssets(ctx, avsAddr) - if err != nil { - return err - } - // get the Assets opted in the operator - operatorAssets, err := k.assetsKeeper.GetOperatorAssetInfos(ctx, operatorAddress, avsSupportedAssets) - if err != nil { - return err - } - - assetFilter := make(map[string]interface{}) - - for assetID := range operatorAssets { - err = k.DeleteAssetState(ctx, assetID, avsAddr, operatorAddress.String()) - if err != nil { - return err - } - assetFilter[assetID] = nil - } - - avsOperatorTotalValue, err := k.GetOperatorShare(ctx, avsAddr, operatorAddress.String()) - if err != nil { - return err - } - if avsOperatorTotalValue.IsNegative() { - return errorsmod.Wrap(types.ErrTheValueIsNegative, fmt.Sprintf("OptOut,avsOperatorTotalValue:%suite", avsOperatorTotalValue)) - } - - // delete the share value of operator itself, the input stakerID should be empty - err = k.DeleteStakerShare(ctx, avsAddr, "", operatorAddress.String()) - if err != nil { - return err - } - - // UpdateAVSShare - err = k.UpdateAVSShare(ctx, avsAddr, avsOperatorTotalValue.Neg()) - if err != nil { - return err - } - // DeleteOperatorShare - err = k.DeleteOperatorShare(ctx, avsAddr, operatorAddress.String()) - if err != nil { - return err - } - - // DeleteStakerShare - relatedAssetsState, err := k.delegationKeeper.DelegationStateByOperatorAssets(ctx, operatorAddress.String(), assetFilter) - if err != nil { - return err - } - for stakerID := range relatedAssetsState { - err = k.DeleteStakerShare(ctx, avsAddr, stakerID, operatorAddress.String()) - if err != nil { - return err - } - } - - // set opted-out height - optedInfo, err := k.GetOptedInfo(ctx, operatorAddress.String(), avsAddr) - if err != nil { - return err - } +// GetSlashIDForDogfood It use infractionType+'/'+'infractionHeight' as the slashID, because the slash event occurs in dogfood doesn't have a TxID. It isn't submitted through an external transaction. +func GetSlashIDForDogfood(infraction stakingtypes.Infraction, infractionHeight int64) string { // #nosec G701 - optedInfo.OptedOutHeight = uint64(ctx.BlockHeight()) - err = k.UpdateOptedInfo(ctx, operatorAddress.String(), avsAddr, optedInfo) - if err != nil { - return err - } - return nil + return string(assetstype.GetJoinedStoreKey(hexutil.EncodeUint64(uint64(infraction)), hexutil.EncodeUint64(uint64(infractionHeight)))) } // GetAssetsAmountToSlash It will slash the assets that are opting into AVS first, and if there isn't enough to slash, then it will slash the assets that have requested to undelegate but still locked. @@ -285,7 +29,7 @@ func (k *Keeper) GetAssetsAmountToSlash(ctx sdk.Context, operatorAddress sdk.Acc } // get the state when the slash occurred - historicalStateCtx, err := types2.ContextForHistoricalState(ctx, slashEventHeight) + historicalStateCtx, err := assetstype.ContextForHistoricalState(ctx, slashEventHeight) if err != nil { return nil, err } @@ -382,7 +126,7 @@ func (k *Keeper) SlashStaker(ctx sdk.Context, operatorAddress sdk.AccAddress, sl slashSumValue := slashInfo.AmountFromUnbonding.Add(slashInfo.AmountFromOptedIn) // update staker and operator assets state - err = k.assetsKeeper.UpdateStakerAssetState(ctx, stakerID, assetID, types2.StakerSingleAssetChangeInfo{ + err = k.assetsKeeper.UpdateStakerAssetState(ctx, stakerID, assetID, assetstype.StakerSingleAssetChangeInfo{ TotalDepositAmount: slashSumValue.Neg(), }) if err != nil { @@ -396,7 +140,7 @@ func (k *Keeper) SlashStaker(ctx sdk.Context, operatorAddress sdk.AccAddress, sl } // handle the state that needs to be updated when slashing opted-in assets - err = k.assetsKeeper.UpdateOperatorAssetState(ctx, operatorAddress, assetID, types2.OperatorSingleAssetChangeInfo{ + err = k.assetsKeeper.UpdateOperatorAssetState(ctx, operatorAddress, assetID, assetstype.OperatorSingleAssetChangeInfo{ TotalAmount: slashInfo.AmountFromOptedIn.Neg(), }) if err != nil { @@ -416,7 +160,7 @@ func (k *Keeper) SlashOperator(ctx sdk.Context, operatorAddress sdk.AccAddress, for assetID, slashInfo := range slashOperatorInfo { slashSumValue := slashInfo.AmountFromUnbonding.Add(slashInfo.AmountFromOptedIn) // handle the state that needs to be updated when slashing both opted-in and unbonding assets - err := k.assetsKeeper.UpdateOperatorAssetState(ctx, operatorAddress, assetID, types2.OperatorSingleAssetChangeInfo{ + err := k.assetsKeeper.UpdateOperatorAssetState(ctx, operatorAddress, assetID, assetstype.OperatorSingleAssetChangeInfo{ TotalAmount: slashSumValue.Neg(), OperatorAmount: slashInfo.AmountFromOptedIn.Neg(), OperatorUnbondableAmountAfterSlash: slashInfo.AmountFromUnbonding.Neg(), @@ -449,7 +193,7 @@ func (k *Keeper) Slash(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr, // get the state when the slash occurred // get the opted-in info - historicalSateCtx, err := types2.ContextForHistoricalState(ctx, slashEventHeight) + historicalSateCtx, err := assetstype.ContextForHistoricalState(ctx, slashEventHeight) if err != nil { return err } @@ -494,3 +238,84 @@ func (k *Keeper) Slash(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr, } return nil } + +// SlashWithInfractionReason is an expected slash interface for the dogfood module. +func (k *Keeper) SlashWithInfractionReason( + ctx sdk.Context, addr sdk.AccAddress, infractionHeight, _ int64, + slashFactor sdk.Dec, infraction stakingtypes.Infraction, +) sdkmath.Int { + chainID := ctx.ChainID() + avsAddr, err := k.avsKeeper.GetAvsAddrByChainID(ctx, chainID) + if err != nil { + k.Logger(ctx).Error(err.Error(), chainID) + return sdkmath.NewInt(0) + } + slashContract, err := k.avsKeeper.GetAvsSlashContract(ctx, avsAddr) + if err != nil { + k.Logger(ctx).Error(err.Error(), avsAddr) + return sdkmath.NewInt(0) + } + slashID := GetSlashIDForDogfood(infraction, infractionHeight) + err = k.Slash(ctx, addr, avsAddr, slashContract, slashID, infractionHeight, slashFactor) + if err != nil { + k.Logger(ctx).Error(err.Error(), avsAddr) + return sdkmath.NewInt(0) + } + // 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) +} + +// IsOperatorJailedForChainID add for dogfood +func (k *Keeper) IsOperatorJailedForChainID(ctx sdk.Context, consAddr sdk.ConsAddress, chainID string) bool { + found, operatorAddr := k.GetOperatorAddressForChainIDAndConsAddr(ctx, chainID, consAddr) + if !found { + k.Logger(ctx).Info("couldn't find operator by consensus address and chainID", consAddr, chainID) + return false + } + + avsAddr, err := k.avsKeeper.GetAvsAddrByChainID(ctx, chainID) + if err != nil { + k.Logger(ctx).Error(err.Error(), chainID) + return false + } + + optInfo, err := k.GetOptedInfo(ctx, operatorAddr.String(), avsAddr) + if err != nil { + k.Logger(ctx).Error(err.Error(), operatorAddr, avsAddr) + return false + } + return optInfo.Jailed +} + +func (k *Keeper) SetJailedState(ctx sdk.Context, consAddr sdk.ConsAddress, chainID string, jailed bool) { + found, operatorAddr := k.GetOperatorAddressForChainIDAndConsAddr(ctx, chainID, consAddr) + if !found { + k.Logger(ctx).Info("couldn't find operator by consensus address and chainID", consAddr, chainID) + return + } + + avsAddr, err := k.avsKeeper.GetAvsAddrByChainID(ctx, chainID) + if err != nil { + k.Logger(ctx).Error(err.Error(), chainID) + return + } + + handleFunc := func(info *types.OptedInfo) { + info.Jailed = jailed + } + err = k.HandleOptedInfo(ctx, operatorAddr.String(), avsAddr, handleFunc) + if err != nil { + k.Logger(ctx).Error(err.Error(), chainID) + } +} + +// Jail an operator +func (k *Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress, chainID string) { + k.SetJailedState(ctx, consAddr, chainID, true) +} + +// Unjail an operator +func (k *Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress, chainID string) { + k.SetJailedState(ctx, consAddr, chainID, true) +} diff --git a/x/operator/types/errors.go b/x/operator/types/errors.go index 26196776c..70ec83d8d 100644 --- a/x/operator/types/errors.go +++ b/x/operator/types/errors.go @@ -71,4 +71,9 @@ var ( ModuleName, 13, "the genesis data supplied is invalid", ) + + ErrInvalidAvsAddr = errorsmod.Register( + ModuleName, 14, + "avs address should be a hex evm contract address", + ) ) diff --git a/x/operator/types/expected_keepers.go b/x/operator/types/expected_keepers.go index 3ef6791bf..03020079c 100644 --- a/x/operator/types/expected_keepers.go +++ b/x/operator/types/expected_keepers.go @@ -108,6 +108,14 @@ func (MockAvs) GetAvsSlashContract(_ sdk.Context, _ string) (string, error) { return "", nil } +func (MockAvs) GetAvsAddrByChainID(_ sdk.Context, chainID string) (string, error) { + return chainID, nil +} + +func (MockAvs) GetOperatorsByAvs(_ sdk.Context, _ string) ([]string, error) { + return nil, nil +} + type AvsKeeper interface { // GetAvsSupportedAssets The ctx can be historical or current, depending on the state you // wish to retrieve. If the caller want to retrieve a historical assets info supported by @@ -115,6 +123,10 @@ type AvsKeeper interface { // `ContextForHistoricalState` implemented in x/assets/types/general.go GetAvsSupportedAssets(ctx sdk.Context, avsAddr string) (map[string]interface{}, error) GetAvsSlashContract(ctx sdk.Context, avsAddr string) (string, error) + // GetAvsAddrByChainID get the general Avs address for dogfood module. + GetAvsAddrByChainID(ctx sdk.Context, chainID string) (string, error) + // GetOperatorsByAvs get all opted-in operators by the avs address + GetOperatorsByAvs(ctx sdk.Context, avsAddr string) ([]string, error) } // add for dogfood diff --git a/x/operator/types/tx.pb.go b/x/operator/types/tx.pb.go index b162bfb3b..d61b10486 100644 --- a/x/operator/types/tx.pb.go +++ b/x/operator/types/tx.pb.go @@ -10,6 +10,7 @@ import ( github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -184,6 +185,8 @@ type OperatorInfo struct { OperatorMetaInfo string `protobuf:"bytes,3,opt,name=operator_meta_info,json=operatorMetaInfo,proto3" json:"operator_meta_info,omitempty"` // client_chain_earning_addr_list is the client chain earning address list. ClientChainEarningsAddr *ClientChainEarningAddrList `protobuf:"bytes,4,opt,name=client_chain_earnings_addr,json=clientChainEarningsAddr,proto3" json:"client_chain_earnings_addr,omitempty"` + // commission defines the commission parameters. + Commission types.Commission `protobuf:"bytes,5,opt,name=commission,proto3" json:"commission"` } func (m *OperatorInfo) Reset() { *m = OperatorInfo{} } @@ -247,6 +250,13 @@ func (m *OperatorInfo) GetClientChainEarningsAddr() *ClientChainEarningAddrList return nil } +func (m *OperatorInfo) GetCommission() types.Commission { + if m != nil { + return m.Commission + } + return types.Commission{} +} + // OptedInfo is the opted information about operator type OptedInfo struct { // slash_contract is the slash contract address of AVS opted-in by the operator @@ -255,6 +265,8 @@ type OptedInfo struct { OptedInHeight uint64 `protobuf:"varint,2,opt,name=opted_in_height,json=optedInHeight,proto3" json:"opted_in_height,omitempty"` // opted_out_height is the exocore block height at which the operator opted out OptedOutHeight uint64 `protobuf:"varint,3,opt,name=opted_out_height,json=optedOutHeight,proto3" json:"opted_out_height,omitempty"` + // jailed defined whether the operator has been jailed from bonded status or not. + Jailed bool `protobuf:"varint,4,opt,name=jailed,proto3" json:"jailed,omitempty"` } func (m *OptedInfo) Reset() { *m = OptedInfo{} } @@ -311,6 +323,13 @@ func (m *OptedInfo) GetOptedOutHeight() uint64 { return 0 } +func (m *OptedInfo) GetJailed() bool { + if m != nil { + return m.Jailed + } + return false +} + // OptedInAssetState is the state of opted-in asset type OptedInAssetState struct { // amount of the opted-in asset @@ -729,69 +748,73 @@ func init() { func init() { proto.RegisterFile("exocore/operator/v1/tx.proto", fileDescriptor_b229d5663e4df167) } var fileDescriptor_b229d5663e4df167 = []byte{ - // 985 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xf6, 0xc6, 0x4e, 0x9a, 0x3c, 0x3b, 0xb5, 0x33, 0xa9, 0x88, 0xbd, 0x14, 0x3b, 0xd9, 0x8a, - 0xca, 0x8d, 0x88, 0x57, 0x0d, 0x14, 0x89, 0xc2, 0x81, 0xfc, 0x68, 0x85, 0x45, 0x8a, 0xd1, 0xa6, - 0xea, 0x01, 0x0e, 0xab, 0xcd, 0xee, 0x64, 0x3d, 0x8a, 0xbd, 0xb3, 0xdd, 0x19, 0xbb, 0x49, 0x25, - 0x24, 0x40, 0x1c, 0x10, 0xe2, 0xc0, 0x95, 0x5b, 0xff, 0x84, 0x1c, 0x7a, 0xe1, 0x80, 0xb8, 0xf6, - 0x58, 0xf5, 0x84, 0x38, 0x44, 0x28, 0x39, 0x84, 0x33, 0x7f, 0x01, 0x9a, 0x1f, 0x9b, 0x38, 0x8d, - 0x43, 0x1b, 0x35, 0x97, 0xc4, 0xf3, 0xe6, 0x7b, 0xdf, 0x7b, 0xef, 0x7b, 0xef, 0x8d, 0x16, 0xae, - 0xe2, 0x6d, 0xea, 0xd3, 0x04, 0xdb, 0x34, 0xc6, 0x89, 0xc7, 0x69, 0x62, 0xf7, 0x6f, 0xda, 0x7c, - 0xbb, 0x11, 0x27, 0x94, 0x53, 0x34, 0xad, 0x6f, 0x1b, 0xe9, 0x6d, 0xa3, 0x7f, 0xd3, 0x9c, 0xf2, - 0xba, 0x24, 0xa2, 0xb6, 0xfc, 0xab, 0x70, 0xe6, 0x8c, 0x4f, 0x59, 0x97, 0x32, 0xbb, 0xcb, 0x42, - 0xe1, 0xdf, 0x65, 0xa1, 0xbe, 0xa8, 0xa8, 0x0b, 0x57, 0x9e, 0x6c, 0x75, 0xd0, 0x57, 0x57, 0x42, - 0x1a, 0x52, 0x65, 0x17, 0xbf, 0x94, 0xd5, 0xc2, 0x30, 0xb9, 0x8a, 0xfd, 0x07, 0x5e, 0xa7, 0x87, - 0xef, 0x12, 0xdc, 0x09, 0xd0, 0x7d, 0x18, 0xf3, 0xba, 0xb4, 0x17, 0xf1, 0xb2, 0x31, 0x6b, 0xd4, - 0x27, 0x96, 0x3f, 0x79, 0xb6, 0x57, 0xcb, 0xfc, 0xb5, 0x57, 0xbb, 0x1e, 0x12, 0xde, 0xee, 0x6d, - 0x34, 0x7c, 0xda, 0xd5, 0xbc, 0xfa, 0xdf, 0x02, 0x0b, 0xb6, 0x6c, 0xbe, 0x13, 0x63, 0xd6, 0x58, - 0xc5, 0xfe, 0x8b, 0xa7, 0x0b, 0xa0, 0xc3, 0xae, 0x62, 0xdf, 0xd1, 0x5c, 0xd6, 0x0e, 0x98, 0x2b, - 0x1d, 0x82, 0x23, 0xbe, 0xd2, 0xf6, 0x48, 0x74, 0xc7, 0x4b, 0x22, 0x12, 0x85, 0x4b, 0x41, 0x90, - 0xac, 0x11, 0xc6, 0xd1, 0xd7, 0x30, 0x85, 0x95, 0xc9, 0x25, 0xd1, 0x26, 0x75, 0x3b, 0x84, 0x89, - 0xf0, 0xd9, 0x7a, 0x7e, 0xd1, 0x6e, 0x0c, 0x91, 0xa4, 0x31, 0x9c, 0xab, 0x19, 0x6d, 0x52, 0xa7, - 0xa8, 0x99, 0xc4, 0x41, 0x90, 0x5b, 0xbf, 0x1a, 0x67, 0xc5, 0x16, 0x10, 0xf4, 0x29, 0xa0, 0xce, - 0x63, 0xd7, 0x97, 0x00, 0xd7, 0x17, 0x08, 0x97, 0x04, 0xb2, 0xf6, 0xdc, 0xf2, 0xf4, 0xfe, 0x5e, - 0xad, 0xb8, 0xf6, 0x78, 0xc0, 0xbb, 0xb9, 0xea, 0x14, 0x3b, 0x27, 0x0c, 0x01, 0xfa, 0x08, 0x2a, - 0x27, 0xdc, 0xd3, 0x52, 0xbc, 0x20, 0x48, 0xca, 0x23, 0x42, 0x44, 0xe7, 0x2d, 0x7f, 0x68, 0x02, - 0xd6, 0xbf, 0x06, 0x14, 0x5a, 0xba, 0x2e, 0x99, 0xcd, 0x35, 0x98, 0xd4, 0xee, 0x4c, 0xf9, 0xcb, - 0x26, 0x38, 0x85, 0xd4, 0x28, 0xbc, 0xd0, 0x1c, 0x14, 0xbc, 0x38, 0x4e, 0x68, 0x1f, 0x0f, 0xc6, - 0xc8, 0x6b, 0x9b, 0x84, 0xbc, 0x07, 0x28, 0xd5, 0xcb, 0xed, 0x62, 0xee, 0x49, 0x5d, 0xcb, 0x59, - 0x09, 0x2c, 0xa5, 0x37, 0xf7, 0x30, 0xf7, 0x64, 0xd4, 0x0e, 0x98, 0xc3, 0x2a, 0xd0, 0x29, 0xe4, - 0x66, 0x8d, 0x73, 0x36, 0x42, 0xe8, 0xee, 0xcc, 0x9c, 0xae, 0x59, 0xa6, 0x6f, 0xfd, 0x60, 0xc0, - 0x44, 0x2b, 0xe6, 0x38, 0x90, 0xb1, 0xdf, 0x85, 0xcb, 0xac, 0xe3, 0xb1, 0xb6, 0xeb, 0xd3, 0x88, - 0x27, 0x9e, 0xaf, 0xe7, 0xce, 0x99, 0x94, 0xd6, 0x15, 0x6d, 0x44, 0xd7, 0xa1, 0x48, 0x85, 0x8f, - 0x4b, 0x22, 0xb7, 0x8d, 0x49, 0xd8, 0xe6, 0xb2, 0xec, 0x9c, 0x33, 0x49, 0x15, 0xd5, 0x67, 0xd2, - 0x88, 0xea, 0x50, 0x52, 0x38, 0xda, 0xe3, 0x29, 0x30, 0x2b, 0x81, 0x97, 0xa5, 0xbd, 0xd5, 0xe3, - 0x0a, 0x69, 0xfd, 0x6e, 0xc0, 0x94, 0x4e, 0x63, 0x89, 0x31, 0xcc, 0xd7, 0xb9, 0xc7, 0xf1, 0x1b, - 0x8d, 0x7f, 0x33, 0xe2, 0x03, 0xe3, 0xdf, 0x8c, 0x78, 0x3a, 0xfe, 0xc8, 0x81, 0xd1, 0xbe, 0x58, - 0x31, 0xd5, 0xaa, 0x37, 0xdc, 0x29, 0x45, 0x65, 0xfd, 0x36, 0x22, 0xf2, 0x57, 0xad, 0x58, 0x17, - 0x5a, 0x9d, 0x47, 0xce, 0x1b, 0x50, 0x62, 0xbd, 0x8d, 0x2e, 0xe1, 0x42, 0xaa, 0x01, 0x3d, 0xb3, - 0x4e, 0xf1, 0xc8, 0xae, 0x15, 0x9d, 0x83, 0x02, 0xee, 0x8b, 0xd9, 0x18, 0x50, 0x33, 0xeb, 0xe4, - 0xa5, 0x4d, 0x43, 0x6e, 0x40, 0x29, 0x4e, 0xa8, 0x8f, 0x19, 0x3b, 0x66, 0xcb, 0x29, 0xb6, 0x23, - 0xbb, 0x86, 0xbe, 0x0d, 0x13, 0x84, 0xb9, 0x7d, 0xcc, 0x29, 0x0e, 0xca, 0xa3, 0xb3, 0x46, 0x7d, - 0xdc, 0x19, 0x27, 0xec, 0x81, 0x3c, 0xa3, 0x10, 0x4a, 0x2a, 0xf9, 0x38, 0xa1, 0x31, 0x4d, 0x38, - 0xa1, 0x51, 0x79, 0xec, 0x02, 0x14, 0x2b, 0x4a, 0xd6, 0x2f, 0x8f, 0x48, 0xad, 0x3f, 0x0c, 0x98, - 0x76, 0x70, 0x48, 0x18, 0xc7, 0x49, 0xaa, 0xa1, 0x83, 0x1f, 0xa2, 0x8f, 0xa1, 0xb0, 0x99, 0xd0, - 0xae, 0x9c, 0x7b, 0xcc, 0x98, 0x9e, 0x81, 0xf2, 0x8b, 0xa7, 0x0b, 0x57, 0x34, 0xdd, 0x92, 0xba, - 0x59, 0xe7, 0x09, 0x89, 0x42, 0x27, 0x2f, 0xd0, 0xda, 0x84, 0x6e, 0x41, 0x4e, 0x6e, 0xd9, 0x88, - 0xdc, 0x97, 0xb9, 0xa1, 0xfb, 0x32, 0xb8, 0xec, 0x8e, 0x84, 0xdf, 0xfe, 0xe0, 0xc7, 0x27, 0xb5, - 0xcc, 0x3f, 0x4f, 0x6a, 0x99, 0xef, 0x0f, 0x77, 0xe7, 0xf3, 0x77, 0x8f, 0x09, 0x7f, 0x3a, 0xdc, - 0x9d, 0x9f, 0x19, 0xa8, 0x6e, 0xd0, 0xd7, 0x32, 0xa1, 0x7c, 0xba, 0x00, 0x16, 0xd3, 0x88, 0x61, - 0xeb, 0x1b, 0xa8, 0xb4, 0x62, 0xde, 0x8c, 0xee, 0xd3, 0x15, 0xe9, 0x2d, 0x57, 0xd0, 0xc1, 0x0f, - 0x7b, 0x98, 0x71, 0x54, 0x86, 0x4b, 0x27, 0xaa, 0x73, 0xd2, 0x23, 0xaa, 0xc0, 0xf8, 0xd1, 0xfb, - 0xa7, 0x9e, 0x94, 0x4b, 0xbe, 0x7e, 0xe2, 0xde, 0x01, 0x88, 0x7b, 0x1b, 0x1d, 0xe2, 0xbb, 0x5b, - 0x78, 0x47, 0x3f, 0x23, 0x13, 0xca, 0xf2, 0x39, 0xde, 0xb9, 0x5d, 0x10, 0xa9, 0xa7, 0x3c, 0xd6, - 0x55, 0x30, 0x87, 0x85, 0xd7, 0xc9, 0x61, 0x98, 0x6d, 0x46, 0x84, 0xb7, 0x62, 0xde, 0xea, 0x71, - 0x51, 0xed, 0x05, 0xe5, 0xf8, 0x52, 0x12, 0xd7, 0x60, 0xee, 0x7f, 0xc2, 0xa8, 0x5c, 0x16, 0xbf, - 0xcb, 0x42, 0xf6, 0x1e, 0x0b, 0xd1, 0x16, 0x94, 0x5e, 0x16, 0x13, 0xd5, 0x87, 0xf6, 0x6f, 0xc8, - 0xd0, 0x98, 0x0b, 0xaf, 0x89, 0x54, 0x41, 0xd1, 0x23, 0x40, 0xa7, 0xe5, 0x41, 0x8d, 0x33, 0xc6, - 0xe5, 0x8c, 0x36, 0x9a, 0xf6, 0x6b, 0xe3, 0xb5, 0xee, 0x19, 0xf4, 0xb3, 0x01, 0x95, 0x33, 0x35, - 0x41, 0xb7, 0x86, 0x12, 0xbe, 0xaa, 0x55, 0xe6, 0x87, 0xe7, 0x75, 0x4b, 0xd3, 0x31, 0x47, 0xbf, - 0x3d, 0xdc, 0x9d, 0x37, 0x96, 0xd7, 0x9e, 0xed, 0x57, 0x8d, 0xe7, 0xfb, 0x55, 0xe3, 0xef, 0xfd, - 0xaa, 0xf1, 0xcb, 0x41, 0x35, 0xf3, 0xfc, 0xa0, 0x9a, 0xf9, 0xf3, 0xa0, 0x9a, 0xf9, 0x6a, 0x71, - 0x60, 0xd7, 0xef, 0xa8, 0x20, 0x5f, 0x60, 0xfe, 0x88, 0x26, 0x5b, 0x76, 0xfa, 0x11, 0xb5, 0x7d, - 0xfc, 0x19, 0x25, 0x77, 0x7f, 0x63, 0x4c, 0x7e, 0xd5, 0xbc, 0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xde, 0x35, 0xd8, 0x13, 0x67, 0x09, 0x00, 0x00, + // 1047 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xbf, 0x4f, 0x1c, 0xc7, + 0x17, 0xbf, 0xe5, 0x00, 0xc3, 0xe3, 0xf0, 0x1d, 0x83, 0x65, 0x8e, 0xfb, 0xfa, 0x7b, 0xc0, 0x3a, + 0xb1, 0x30, 0x0a, 0x77, 0x82, 0xc4, 0x91, 0xe2, 0xa4, 0x08, 0x3f, 0x6c, 0xe5, 0x14, 0xc8, 0x45, + 0x83, 0xe5, 0x22, 0x29, 0x56, 0xcb, 0xee, 0xb0, 0x4c, 0xb8, 0xdd, 0x59, 0xef, 0xcc, 0x9d, 0xc1, + 0x52, 0xa4, 0x24, 0x55, 0x14, 0xa5, 0x48, 0x1b, 0x29, 0x85, 0xcb, 0x94, 0x14, 0x6e, 0x52, 0x44, + 0x51, 0x3a, 0x97, 0x96, 0xab, 0x28, 0x05, 0x8a, 0xa0, 0x20, 0x7f, 0x46, 0x34, 0x3f, 0xf6, 0x58, + 0xcc, 0x91, 0x18, 0xd9, 0x0d, 0x30, 0xef, 0x7d, 0xde, 0xe7, 0xbd, 0xf7, 0x99, 0xf7, 0x86, 0x85, + 0x6b, 0x64, 0x97, 0x79, 0x2c, 0x21, 0x75, 0x16, 0x93, 0xc4, 0x15, 0x2c, 0xa9, 0x77, 0x16, 0xea, + 0x62, 0xb7, 0x16, 0x27, 0x4c, 0x30, 0x34, 0x6e, 0xbc, 0xb5, 0xd4, 0x5b, 0xeb, 0x2c, 0x54, 0xc6, + 0xdc, 0x90, 0x46, 0xac, 0xae, 0x7e, 0x6a, 0x5c, 0x65, 0xc2, 0x63, 0x3c, 0x64, 0xbc, 0x1e, 0xf2, + 0x40, 0xc6, 0x87, 0x3c, 0x30, 0x8e, 0x37, 0x8c, 0x83, 0x0b, 0x77, 0x87, 0x46, 0xd2, 0xb9, 0x49, + 0x84, 0xbb, 0x90, 0x9e, 0x0d, 0x6a, 0x52, 0xa3, 0x1c, 0x75, 0xaa, 0xeb, 0x83, 0x71, 0x5d, 0x09, + 0x58, 0xc0, 0xb4, 0x5d, 0xfe, 0xa5, 0xad, 0x36, 0x81, 0xd1, 0x55, 0xe2, 0xdd, 0x77, 0x5b, 0x6d, + 0x72, 0x97, 0x92, 0x96, 0x8f, 0xee, 0xc1, 0xa0, 0x1b, 0xb2, 0x76, 0x24, 0xca, 0xd6, 0xb4, 0x35, + 0x3b, 0xbc, 0xfc, 0xc1, 0xd3, 0x83, 0xa9, 0xdc, 0x9f, 0x07, 0x53, 0x37, 0x02, 0x2a, 0xb6, 0xdb, + 0x9b, 0x35, 0x8f, 0x85, 0x86, 0xd7, 0xfc, 0x9a, 0xe7, 0xfe, 0x4e, 0x5d, 0xec, 0xc5, 0x84, 0xd7, + 0x56, 0x89, 0xf7, 0xfc, 0xc9, 0x3c, 0x98, 0xb4, 0xab, 0xc4, 0xc3, 0x86, 0xcb, 0xde, 0x83, 0xca, + 0x4a, 0x8b, 0x92, 0x48, 0xac, 0x6c, 0xbb, 0x34, 0xba, 0xe3, 0x26, 0x11, 0x8d, 0x82, 0x25, 0xdf, + 0x4f, 0xd6, 0x28, 0x17, 0xe8, 0x73, 0x18, 0x23, 0xda, 0xe4, 0xd0, 0x68, 0x8b, 0x39, 0x2d, 0xca, + 0x65, 0xfa, 0xfc, 0xec, 0xc8, 0x62, 0xbd, 0xd6, 0x43, 0xb8, 0x5a, 0x6f, 0xae, 0x46, 0xb4, 0xc5, + 0x70, 0xd1, 0x30, 0xc9, 0x83, 0x24, 0xb7, 0x7f, 0xb4, 0xce, 0xcb, 0x2d, 0x21, 0xe8, 0x43, 0x40, + 0xad, 0x47, 0x8e, 0xa7, 0x00, 0x8e, 0x27, 0x11, 0x0e, 0xf5, 0x55, 0xef, 0xfd, 0xcb, 0xe3, 0x87, + 0x07, 0x53, 0xc5, 0xb5, 0x47, 0x99, 0xe8, 0xc6, 0x2a, 0x2e, 0xb6, 0x4e, 0x19, 0x7c, 0xf4, 0x1e, + 0x4c, 0x9e, 0x0a, 0x4f, 0x5b, 0x71, 0x7d, 0x3f, 0x29, 0xf7, 0x49, 0x11, 0xf1, 0x55, 0xaf, 0x67, + 0x01, 0xf6, 0xef, 0x7d, 0x50, 0x68, 0x9a, 0xbe, 0x54, 0x35, 0xd7, 0x61, 0xd4, 0x84, 0x73, 0x1d, + 0xaf, 0x2e, 0x01, 0x17, 0x52, 0xa3, 0x8c, 0x42, 0x33, 0x50, 0x70, 0xe3, 0x38, 0x61, 0x1d, 0x92, + 0xcd, 0x31, 0x62, 0x6c, 0x0a, 0xf2, 0x16, 0xa0, 0x54, 0x2f, 0x27, 0x24, 0xc2, 0x55, 0xba, 0x96, + 0xf3, 0x0a, 0x58, 0x4a, 0x3d, 0xeb, 0x44, 0xb8, 0x2a, 0x6b, 0x0b, 0x2a, 0xbd, 0x3a, 0x30, 0x25, + 0xf4, 0x4f, 0x5b, 0x17, 0xbc, 0x08, 0xa9, 0x3b, 0x9e, 0x38, 0xdb, 0xb3, 0x2e, 0x7f, 0x1d, 0xc0, + 0x63, 0x61, 0x48, 0x39, 0xa7, 0x2c, 0x2a, 0x0f, 0x28, 0x76, 0xbb, 0x66, 0x86, 0x26, 0x1d, 0x67, + 0x33, 0xde, 0xb5, 0x95, 0x2e, 0x72, 0x79, 0x58, 0x4e, 0xe2, 0xcf, 0xc7, 0xfb, 0x73, 0x16, 0xce, + 0x10, 0xd8, 0x3f, 0x59, 0x30, 0xdc, 0x8c, 0x05, 0xf1, 0x55, 0x2b, 0x6f, 0xc2, 0x65, 0xde, 0x72, + 0xf9, 0xb6, 0xe3, 0xb1, 0x48, 0x24, 0xae, 0x67, 0xc6, 0x18, 0x8f, 0x2a, 0xeb, 0x8a, 0x31, 0xa2, + 0x1b, 0x50, 0x64, 0x32, 0xc6, 0xa1, 0x91, 0xb3, 0x4d, 0x68, 0xb0, 0x2d, 0x94, 0x8a, 0xfd, 0x78, + 0x94, 0x69, 0xaa, 0x8f, 0x94, 0x11, 0xcd, 0x42, 0x49, 0xe3, 0x58, 0x5b, 0xa4, 0xc0, 0xbc, 0x02, + 0x5e, 0x56, 0xf6, 0x66, 0x5b, 0x18, 0xe4, 0x55, 0x18, 0xfc, 0xc2, 0xa5, 0x2d, 0xe2, 0x2b, 0xbd, + 0x86, 0xb0, 0x39, 0xd9, 0xbf, 0x5a, 0x30, 0x66, 0xca, 0x5b, 0xe2, 0x9c, 0x88, 0x0d, 0xe1, 0x0a, + 0xf2, 0x4a, 0x5b, 0xd6, 0x88, 0x44, 0x66, 0xcb, 0x1a, 0x91, 0x48, 0xb7, 0x0c, 0x61, 0x18, 0xe8, + 0xc8, 0x4d, 0xd6, 0x13, 0xf1, 0x8a, 0xab, 0xab, 0xa9, 0xec, 0x5f, 0xfa, 0x64, 0xfd, 0xfa, 0xc6, + 0x37, 0xa4, 0x86, 0x17, 0x91, 0xf9, 0x26, 0x94, 0x78, 0x7b, 0x33, 0xa4, 0x42, 0x4a, 0x98, 0xd1, + 0x39, 0x8f, 0x8b, 0x5d, 0xbb, 0xd1, 0x6f, 0x06, 0x0a, 0xa4, 0x23, 0x47, 0x30, 0xa3, 0x72, 0x1e, + 0x8f, 0x28, 0x9b, 0x81, 0xdc, 0x84, 0x52, 0x9c, 0x30, 0x8f, 0x70, 0x7e, 0xc2, 0xd6, 0xaf, 0xd9, + 0xba, 0x76, 0x03, 0xfd, 0x1f, 0x0c, 0x53, 0xee, 0x74, 0x88, 0x60, 0xc4, 0x57, 0x23, 0x36, 0x84, + 0x87, 0x28, 0xbf, 0xaf, 0xce, 0x28, 0x80, 0x92, 0x2e, 0x3e, 0x4e, 0x58, 0xcc, 0x12, 0x21, 0xc7, + 0x70, 0xf0, 0x35, 0x28, 0x56, 0x54, 0xac, 0x9f, 0x76, 0x49, 0xed, 0xdf, 0x2c, 0x18, 0xc7, 0x24, + 0xa0, 0x5c, 0x90, 0x24, 0xd5, 0x10, 0x93, 0x07, 0xe8, 0x7d, 0x28, 0x6c, 0x25, 0x2c, 0x54, 0xeb, + 0x45, 0x38, 0x37, 0x33, 0x50, 0x7e, 0xfe, 0x64, 0xfe, 0x8a, 0xa1, 0x5b, 0xd2, 0x9e, 0x0d, 0x91, + 0xd0, 0x28, 0xc0, 0x23, 0x12, 0x6d, 0x4c, 0xe8, 0x16, 0xf4, 0xab, 0x65, 0xee, 0x53, 0x8b, 0x33, + 0xd3, 0x73, 0x2d, 0xb3, 0x6f, 0x0a, 0x56, 0xf0, 0xdb, 0xef, 0x7c, 0xfb, 0x78, 0x2a, 0xf7, 0xf7, + 0xe3, 0xa9, 0xdc, 0x37, 0xc7, 0xfb, 0x73, 0x23, 0x77, 0x4f, 0x08, 0xbf, 0x3b, 0xde, 0x9f, 0x9b, + 0xc8, 0x74, 0x97, 0x8d, 0xb5, 0x2b, 0x50, 0x3e, 0xdb, 0x00, 0x8f, 0x59, 0xc4, 0x89, 0xfd, 0x25, + 0x4c, 0x36, 0x63, 0xd1, 0x88, 0xee, 0xb1, 0x15, 0x15, 0xad, 0x36, 0x1d, 0x93, 0x07, 0x6d, 0xc2, + 0x05, 0x2a, 0xc3, 0xa5, 0x53, 0xdd, 0xe1, 0xf4, 0x88, 0x26, 0x61, 0xa8, 0xfb, 0xcc, 0xea, 0x97, + 0xeb, 0x92, 0x67, 0x5e, 0xd2, 0xff, 0x03, 0xc4, 0xed, 0xcd, 0x16, 0xf5, 0x9c, 0x1d, 0xb2, 0x67, + 0x5e, 0xab, 0x61, 0x6d, 0xf9, 0x98, 0xec, 0xdd, 0x2e, 0xc8, 0xd2, 0x53, 0x1e, 0xfb, 0x1a, 0x54, + 0x7a, 0xa5, 0x37, 0xc5, 0x11, 0x98, 0x6e, 0x44, 0x54, 0x34, 0x63, 0xd1, 0x6c, 0x0b, 0xd9, 0xed, + 0x6b, 0xaa, 0xf1, 0x85, 0x22, 0xae, 0xc3, 0xcc, 0xbf, 0xa4, 0xd1, 0xb5, 0x2c, 0x7e, 0x9d, 0x87, + 0xfc, 0x3a, 0x0f, 0xd0, 0x0e, 0x94, 0x5e, 0x14, 0x13, 0xcd, 0xf6, 0xbc, 0xbf, 0x1e, 0x43, 0x53, + 0x99, 0x7f, 0x49, 0xa4, 0x4e, 0x8a, 0x1e, 0x02, 0x3a, 0x2b, 0x0f, 0xaa, 0x9d, 0x33, 0x2e, 0xe7, + 0x5c, 0x63, 0xa5, 0xfe, 0xd2, 0x78, 0xa3, 0x7b, 0x0e, 0x7d, 0x6f, 0xc1, 0xe4, 0xb9, 0x9a, 0xa0, + 0x5b, 0x3d, 0x09, 0xff, 0xeb, 0xaa, 0x2a, 0xef, 0x5e, 0x34, 0x2c, 0x2d, 0xa7, 0x32, 0xf0, 0x95, + 0xfc, 0x8f, 0xb1, 0xbc, 0xf6, 0xf4, 0xb0, 0x6a, 0x3d, 0x3b, 0xac, 0x5a, 0x7f, 0x1d, 0x56, 0xad, + 0x1f, 0x8e, 0xaa, 0xb9, 0x67, 0x47, 0xd5, 0xdc, 0x1f, 0x47, 0xd5, 0xdc, 0x67, 0x8b, 0x99, 0x5d, + 0xbf, 0xa3, 0x93, 0x7c, 0x42, 0xc4, 0x43, 0x96, 0xec, 0xd4, 0xd3, 0x2f, 0xba, 0xdd, 0x93, 0x6f, + 0x3a, 0xb5, 0xfb, 0x9b, 0x83, 0xea, 0xe3, 0xe9, 0xed, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x6a, 0xe8, 0x69, 0xf4, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1091,6 +1114,16 @@ func (m *OperatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Commission.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a if m.ClientChainEarningsAddr != nil { { size, err := m.ClientChainEarningsAddr.MarshalToSizedBuffer(dAtA[:i]) @@ -1147,6 +1180,16 @@ func (m *OptedInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Jailed { + i-- + if m.Jailed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } if m.OptedOutHeight != 0 { i = encodeVarintTx(dAtA, i, uint64(m.OptedOutHeight)) i-- @@ -1542,6 +1585,8 @@ func (m *OperatorInfo) Size() (n int) { l = m.ClientChainEarningsAddr.Size() n += 1 + l + sovTx(uint64(l)) } + l = m.Commission.Size() + n += 1 + l + sovTx(uint64(l)) return n } @@ -1561,6 +1606,9 @@ func (m *OptedInfo) Size() (n int) { if m.OptedOutHeight != 0 { n += 1 + sovTx(uint64(m.OptedOutHeight)) } + if m.Jailed { + n += 2 + } return n } @@ -2122,6 +2170,39 @@ func (m *OperatorInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commission", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Commission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2242,6 +2323,26 @@ func (m *OptedInfo) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Jailed", 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.Jailed = bool(v != 0) default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:])