diff --git a/app/app.go b/app/app.go index 880375b3..13838e47 100644 --- a/app/app.go +++ b/app/app.go @@ -142,6 +142,7 @@ var ( ibcclientclient.UpgradeProposalHandler, dfractclient.UpdateParamsProposalHandler, millionsclient.RegisterPoolProposalHandler, + millionsclient.ClosePoolProposalHandler, millionsclient.UpdatePoolProposalHandler, millionsclient.UpdateParamsProposalHandler, }, @@ -781,18 +782,6 @@ func (app *App) registerUpgradeHandlers() { return app.mm.RunMigrations(ctx, app.configurator, fromVM) }) - app.UpgradeKeeper.SetUpgradeHandler("v1.4.5", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // Kill the first pool that shouldn't be used anymore after that upgrade - _, err := app.MillionsKeeper.UnsafeKillPool(ctx, 1) - if err != nil { - return fromVM, err - } - - // Continue normal upgrade processing - app.Logger().Info("Pool killed. v1.4.5 upgrade applied") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) - app.UpgradeKeeper.SetUpgradeHandler("v1.5.0", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { app.Logger().Info("Starting v1.5.0 upgrade") @@ -919,6 +908,11 @@ func (app *App) registerUpgradeHandlers() { return app.mm.RunMigrations(ctx, app.configurator, fromVM) }) + app.UpgradeKeeper.SetUpgradeHandler("v1.6.5", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + app.Logger().Info("Starting v1.6.5 upgrade") + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() if err != nil { panic(fmt.Sprintf("failed to read upgrade info from disk %s", err)) @@ -1020,4 +1014,9 @@ func (app *App) registerUpgradeHandlers() { storeUpgrades := storetypes.StoreUpgrades{} app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } + + if upgradeInfo.Name == "v1.6.5" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := storetypes.StoreUpgrades{} + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } } diff --git a/proto/lum/network/millions/gov.proto b/proto/lum/network/millions/gov.proto index 0711d67d..00e7c2b8 100644 --- a/proto/lum/network/millions/gov.proto +++ b/proto/lum/network/millions/gov.proto @@ -64,6 +64,15 @@ message ProposalUpdatePool { repeated FeeTaker fee_takers = 11 [ (gogoproto.nullable) = false ]; } +message ProposalClosePool { + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + + uint64 pool_id = 3; +} + message ProposalUpdateParams { option (gogoproto.goproto_stringer) = false; diff --git a/proto/lum/network/millions/pool.proto b/proto/lum/network/millions/pool.proto index 496b6461..f415ffab 100644 --- a/proto/lum/network/millions/pool.proto +++ b/proto/lum/network/millions/pool.proto @@ -30,7 +30,8 @@ enum PoolState { POOL_STATE_CREATED = 1 [ (gogoproto.enumvalue_customname) = "Created" ]; POOL_STATE_READY = 2 [ (gogoproto.enumvalue_customname) = "Ready" ]; POOL_STATE_PAUSED = 3 [ (gogoproto.enumvalue_customname) = "Paused" ]; - POOL_STATE_KILLED = 4 [ (gogoproto.enumvalue_customname) = "Killed" ]; + POOL_STATE_CLOSING = 4 [ (gogoproto.enumvalue_customname) = "Closing" ]; + POOL_STATE_CLOSED = 5 [ (gogoproto.enumvalue_customname) = "Closed" ]; } // PoolType the type of Pool @@ -119,8 +120,8 @@ message Pool { cosmos.base.v1beta1.Coin available_prize_pool = 29 [ (gogoproto.nullable) = false ]; repeated FeeTaker fee_takers = 30 [ (gogoproto.nullable) = false ]; - reserved 31; + reserved 31; PoolState state = 32; int64 created_at_height = 33; diff --git a/readme.md b/readme.md index f79401c4..466aaa6f 100644 --- a/readme.md +++ b/readme.md @@ -39,6 +39,10 @@ Please also make sure to have a look to the [contributing guidelines](https://gi Information related to the Lum Network mainnet `lum-network-1` can be found in the [mainnet repository](https://github.com/lum-network/mainnet). +### v1.6.4 - `TODO` - Block `TODO` + +`TODO` + ### v1.6.4 - 2024-02-01 - Block 11390000 CosmosMillions: Make ICA channel restoration unlock all entities and revamp the fee system to allow for more than one fee taker. diff --git a/x/millions/client/cli/proposal.go b/x/millions/client/cli/proposal.go index 65eee953..e7e1106f 100644 --- a/x/millions/client/cli/proposal.go +++ b/x/millions/client/cli/proposal.go @@ -17,6 +17,18 @@ import ( "github.com/lum-network/chain/x/millions/types" ) +func parseClosePoolProposalFile(cdc codec.JSONCodec, proposalFile string) (proposal types.ProposalClosePool, err error) { + contents, err := os.ReadFile(proposalFile) + if err != nil { + return proposal, err + } + + if err = cdc.UnmarshalJSON(contents, &proposal); err != nil { + return proposal, err + } + return proposal, nil +} + func parseRegisterPoolProposalFile(cdc codec.JSONCodec, proposalFile string) (proposal types.ProposalRegisterPool, err error) { contents, err := os.ReadFile(proposalFile) if err != nil { @@ -235,6 +247,78 @@ Where proposal.json contains: return cmd } +func CmdProposalClosePool() *cobra.Command { + cmd := &cobra.Command{ + Use: "millions-close-pool [proposal-file]", + Short: "Submit a millions close pool proposal", + Long: strings.TrimSpace( + fmt.Sprintf(`Submit a ClosePool proposal along with an initial deposit. +The proposal details must be supplied via a JSON file. + +Example: +$ %s tx gov submit-legacy-proposal millions-close-pool --from= + +Where proposal.json contains: +{ + "title": "Close my pool", + "description": "This is my close pool", + "pool_id": 1 +} +`, version.AppName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + // Acquire the client context + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + // Parse the proposal file + proposal, err := parseClosePoolProposalFile(clientCtx.Codec, args[0]) + if err != nil { + return err + } + + if err := proposal.ValidateBasic(); err != nil { + return err + } + + // Grab the parameters + from := clientCtx.GetFromAddress() + + // Grab the deposit + depositStr, err := cmd.Flags().GetString(govcli.FlagDeposit) + if err != nil { + return err + } + + deposit, err := sdk.ParseCoinsNormalized(depositStr) + if err != nil { + return err + } + + msg, err := govtypes.NewMsgSubmitProposal(&proposal, deposit, from) + if err != nil { + return err + } + + if err := msg.ValidateBasic(); err != nil { + return err + } + + // Generate the transaction + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(govcli.FlagDeposit, "1ulum", "deposit of proposal") + if err := cmd.MarkFlagRequired(govcli.FlagDeposit); err != nil { + panic(err) + } + return cmd +} + func CmdProposalUpdateParams() *cobra.Command { cmd := &cobra.Command{ Use: "millions-update-params [proposal-file]", diff --git a/x/millions/client/proposal_handler.go b/x/millions/client/proposal_handler.go index dcbe7eec..a9d24ec5 100644 --- a/x/millions/client/proposal_handler.go +++ b/x/millions/client/proposal_handler.go @@ -9,5 +9,6 @@ import ( var ( RegisterPoolProposalHandler = govclient.NewProposalHandler(cli.CmdProposalRegisterPool) UpdatePoolProposalHandler = govclient.NewProposalHandler(cli.CmdProposalUpdatePool) + ClosePoolProposalHandler = govclient.NewProposalHandler(cli.CmdProposalClosePool) UpdateParamsProposalHandler = govclient.NewProposalHandler(cli.CmdProposalUpdateParams) ) diff --git a/x/millions/genesis_test.go b/x/millions/genesis_test.go index dbe514f4..69d90647 100644 --- a/x/millions/genesis_test.go +++ b/x/millions/genesis_test.go @@ -71,7 +71,7 @@ var testGenesis = millionstypes.GenesisState{ {PoolId: 3, PoolType: millionstypes.PoolType_Staking, TvlAmount: sdk.NewInt(601), DepositorsCount: 1, SponsorshipAmount: sdk.ZeroInt(), Denom: "denom-3", NativeDenom: "denom-3", NextDrawId: 1, ChainId: "c1", Validators: defaultValidators, MinDepositAmount: sdk.NewInt(1_000_000), UnbondingDuration: time.Duration(millionstypes.DefaultUnbondingDuration), MaxUnbondingEntries: sdk.NewInt(millionstypes.DefaultMaxUnbondingEntries), AvailablePrizePool: sdk.NewCoin("denom-3", sdk.ZeroInt()), DrawSchedule: defaultSchedule, PrizeStrategy: defaultPrizeStrat, - State: millionstypes.PoolState_Killed, Bech32PrefixAccAddr: "lum", Bech32PrefixValAddr: "lumvaloper", + State: millionstypes.PoolState_Closed, Bech32PrefixAccAddr: "lum", Bech32PrefixValAddr: "lumvaloper", FeeTakers: []millionstypes.FeeTaker{ {Destination: authtypes.FeeCollectorName, Amount: sdk.NewDecWithPrec(millionstypes.DefaultFeeTakerAmount, 2), Type: millionstypes.FeeTakerType_LocalModuleAccount}, }, @@ -87,7 +87,7 @@ var testGenesis = millionstypes.GenesisState{ {PoolId: 5, PoolType: millionstypes.PoolType_Staking, TvlAmount: sdk.NewInt(0), DepositorsCount: 0, SponsorshipAmount: sdk.ZeroInt(), Denom: "denom-5", NativeDenom: "denom-5", NextDrawId: 1, ChainId: "c1", Validators: defaultValidators, MinDepositAmount: sdk.NewInt(1_000_000), UnbondingDuration: time.Duration(millionstypes.DefaultUnbondingDuration), MaxUnbondingEntries: sdk.NewInt(millionstypes.DefaultMaxUnbondingEntries), AvailablePrizePool: sdk.NewCoin("denom-5", sdk.ZeroInt()), DrawSchedule: defaultSchedule, PrizeStrategy: defaultPrizeStrat, - State: millionstypes.PoolState_Killed, Bech32PrefixAccAddr: "lum", Bech32PrefixValAddr: "lumvaloper", + State: millionstypes.PoolState_Closed, Bech32PrefixAccAddr: "lum", Bech32PrefixValAddr: "lumvaloper", FeeTakers: []millionstypes.FeeTaker{ {Destination: authtypes.FeeCollectorName, Amount: sdk.NewDecWithPrec(millionstypes.DefaultFeeTakerAmount, 2), Type: millionstypes.FeeTakerType_LocalModuleAccount}, }, diff --git a/x/millions/handler_proposal.go b/x/millions/handler_proposal.go index 61212375..cf96b090 100644 --- a/x/millions/handler_proposal.go +++ b/x/millions/handler_proposal.go @@ -13,6 +13,10 @@ import ( func NewMillionsProposalHandler(k keeper.Keeper) govtypes.Handler { return func(ctx sdk.Context, content govtypes.Content) error { switch c := content.(type) { + case *types.ProposalClosePool: + { + return k.ClosePool(ctx, c.PoolId) + } case *types.ProposalUpdatePool: { return k.UpdatePool(ctx, c.PoolId, c.Validators, c.MinDepositAmount, c.UnbondingDuration, c.MaxUnbondingEntries, c.DrawSchedule, c.PrizeStrategy, c.State, c.FeeTakers) diff --git a/x/millions/keeper/callbacks_bank_send.go b/x/millions/keeper/callbacks_bank_send.go index 9a2903e2..6ddc6088 100644 --- a/x/millions/keeper/callbacks_bank_send.go +++ b/x/millions/keeper/callbacks_bank_send.go @@ -44,6 +44,9 @@ func BankSendCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, ack return err } + // Scenarios: + // - Timeout: Does nothing, handled when restoring the ICA channel + // - Error: Put entity in error state to allow users to retry if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a bank send to native packet") } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { diff --git a/x/millions/keeper/callbacks_claim.go b/x/millions/keeper/callbacks_claim.go index 8b47dd0a..64f96371 100644 --- a/x/millions/keeper/callbacks_claim.go +++ b/x/millions/keeper/callbacks_claim.go @@ -39,8 +39,9 @@ func ClaimCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, ackRes return errorsmod.Wrapf(types.ErrUnmarshalFailure, fmt.Sprintf("Unable to unmarshal claim callback args: %s", err.Error())) } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // - Timeout: Does nothing, handled when restoring the ICA channel + // - Error: Put entity in error state to allow users to retry if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a claim packet") } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { diff --git a/x/millions/keeper/callbacks_delegate.go b/x/millions/keeper/callbacks_delegate.go index 3841c21b..41edfceb 100644 --- a/x/millions/keeper/callbacks_delegate.go +++ b/x/millions/keeper/callbacks_delegate.go @@ -39,8 +39,9 @@ func DelegateCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, ack return errorsmod.Wrapf(types.ErrUnmarshalFailure, fmt.Sprintf("Unable to unmarshal delegate callback args: %s", err.Error())) } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // - Timeout: Does nothing, handled when restoring the ICA channel + // - Error: Put entity in error state to allow users to retry if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a delegate packet") } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { diff --git a/x/millions/keeper/callbacks_redelegate.go b/x/millions/keeper/callbacks_redelegate.go index e17f1142..3a7794fc 100644 --- a/x/millions/keeper/callbacks_redelegate.go +++ b/x/millions/keeper/callbacks_redelegate.go @@ -45,10 +45,12 @@ func RedelegateCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, a return err } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // - Timeout: Treated as an error (see below) + // - Error: Revert Pool validator set known split if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a redelegate packet") + return k.OnRedelegateToActiveValidatorsOnRemoteZoneCompleted(ctx, redelegateCallback.GetPoolId(), redelegateCallback.GetOperatorAddress(), redelegateCallback.GetSplitDelegations(), true) } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { k.Logger(ctx).Debug("Received failure for a redelegate packet") return k.OnRedelegateToActiveValidatorsOnRemoteZoneCompleted(ctx, redelegateCallback.GetPoolId(), redelegateCallback.GetOperatorAddress(), redelegateCallback.GetSplitDelegations(), true) diff --git a/x/millions/keeper/callbacks_set_withdraw_address.go b/x/millions/keeper/callbacks_set_withdraw_address.go index ab319718..ec08ab1d 100644 --- a/x/millions/keeper/callbacks_set_withdraw_address.go +++ b/x/millions/keeper/callbacks_set_withdraw_address.go @@ -45,8 +45,10 @@ func SetWithdrawAddressCallback(k Keeper, ctx sdk.Context, packet channeltypes.P return err } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // This operation is done right after the ICA channel open procedure + // - Timeout: Does nothing - fix may be needed manually + // - Error: Does nothing - fix may be needed manually if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a set withdraw address packet") } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { diff --git a/x/millions/keeper/callbacks_transfer_from_native.go b/x/millions/keeper/callbacks_transfer_from_native.go index 928747ca..889ebafb 100644 --- a/x/millions/keeper/callbacks_transfer_from_native.go +++ b/x/millions/keeper/callbacks_transfer_from_native.go @@ -45,8 +45,9 @@ func TransferFromNativeCallback(k Keeper, ctx sdk.Context, packet channeltypes.P return err } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // - Timeout: Does nothing, handled when restoring the ICA channel + // - Error: Put entity in error state to allow users to retry if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a transfer from native packet") } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { diff --git a/x/millions/keeper/callbacks_transfer_to_native.go b/x/millions/keeper/callbacks_transfer_to_native.go index 2e4421c2..ed602a92 100644 --- a/x/millions/keeper/callbacks_transfer_to_native.go +++ b/x/millions/keeper/callbacks_transfer_to_native.go @@ -39,10 +39,12 @@ func TransferToNativeCallback(k Keeper, ctx sdk.Context, packet channeltypes.Pac return errorsmod.Wrapf(types.ErrUnmarshalFailure, fmt.Sprintf("Unable to unmarshal transfer to native callback args: %s", err.Error())) } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // - Timeout: Treated as an error (see below) + // - Error: Put entity in error state to allow users to retry if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for a transfer to native packet") + return k.OnTransferDepositToRemoteZoneCompleted(ctx, transferCallback.GetPoolId(), transferCallback.GetDepositId(), true) } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { k.Logger(ctx).Debug("Received failure for a transfer to native packet") return k.OnTransferDepositToRemoteZoneCompleted(ctx, transferCallback.GetPoolId(), transferCallback.GetDepositId(), true) diff --git a/x/millions/keeper/callbacks_undelegate.go b/x/millions/keeper/callbacks_undelegate.go index fe1d4141..e90b1a75 100644 --- a/x/millions/keeper/callbacks_undelegate.go +++ b/x/millions/keeper/callbacks_undelegate.go @@ -69,13 +69,13 @@ func UndelegateCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, a return err } - // If the response status is a timeout, that's not an "error" since the relayer will retry then fail or succeed. - // We just log it out and return no error + // Scenarios: + // - Timeout: Does nothing, handled when restoring the ICA channel + // - Error: Put back entities in the queue automatically if ackResponse.Status == icacallbackstypes.AckResponseStatus_TIMEOUT { k.Logger(ctx).Debug("Received timeout for an undelegate packet") } else if ackResponse.Status == icacallbackstypes.AckResponseStatus_FAILURE { k.Logger(ctx).Debug("Received failure for an undelegate packet") - // Failed OnUndelegateEpochUnbondingOnRemoteZoneCompleted return k.OnUndelegateWithdrawalsOnRemoteZoneCompleted( ctx, undelegateCallback.PoolId, diff --git a/x/millions/keeper/keeper_deposit.go b/x/millions/keeper/keeper_deposit.go index 085f12a9..e1def476 100644 --- a/x/millions/keeper/keeper_deposit.go +++ b/x/millions/keeper/keeper_deposit.go @@ -120,6 +120,15 @@ func (k Keeper) OnDelegateDepositOnRemoteZoneCompleted(ctx sdk.Context, poolID u pool.ApplySplitDelegate(ctx, splits) k.updatePool(ctx, &pool) k.UpdateDepositStatus(ctx, poolID, depositID, types.DepositState_Success, false) + + if pool.State == types.PoolState_Closing { + // Continue closing procedure + // voluntary ignore errors + if err := k.ClosePool(ctx, poolID); err != nil { + k.Logger(ctx).With("ctx", "deposit_completed", "pool_id", poolID).Error("Silently failed to continue close pool procedure: %v", err) + } + } + return nil } diff --git a/x/millions/keeper/keeper_draw.go b/x/millions/keeper/keeper_draw.go index cae8aa02..04016a18 100644 --- a/x/millions/keeper/keeper_draw.go +++ b/x/millions/keeper/keeper_draw.go @@ -83,6 +83,7 @@ func (k Keeper) ClaimYieldOnRemoteZone(ctx sdk.Context, poolID uint64, drawID ui if err != nil { return nil, err } + // Acquire Draw draw, err := k.GetPoolDraw(ctx, poolID, drawID) if err != nil { @@ -407,11 +408,23 @@ func (k Keeper) ExecuteDraw(ctx sdk.Context, poolID uint64, drawID uint64) (*typ draw.PrizePoolRemainsAmount = pool.AvailablePrizePool.Amount draw.PrizePool = draw.PrizePool.Add(pool.AvailablePrizePool) + prizeStrat := pool.PrizeStrategy + + if pool.State == types.PoolState_Closing { + // Pool is unfortunately closing but some people will be lucky + // Modify prize distribution to distribute the full prize pool in one draw + // which is equal to making all batches not unique and with a 100% draw probability + for i := range prizeStrat.PrizeBatches { + prizeStrat.PrizeBatches[i].IsUnique = false + prizeStrat.PrizeBatches[i].DrawProbability = sdk.OneDec() + } + } + // Draw prizes dRes, err := k.RunDrawPrizes( ctx, draw.PrizePool, - pool.PrizeStrategy, + prizeStrat, depositorsTWB, draw.RandSeed, ) @@ -493,6 +506,7 @@ func (k Keeper) OnExecuteDrawCompleted(ctx sdk.Context, pool *types.Pool, draw * k.updatePool(ctx, pool) return draw, err } + draw.State = types.DrawState_Success draw.ErrorState = types.DrawState_Unspecified draw.UpdatedAtHeight = ctx.BlockHeight() @@ -500,11 +514,19 @@ func (k Keeper) OnExecuteDrawCompleted(ctx sdk.Context, pool *types.Pool, draw * k.SetPoolDraw(ctx, *draw) pool.LastDrawState = draw.State k.updatePool(ctx, pool) + + if pool.State == types.PoolState_Closing { + // Continue closing procedure + // voluntary ignore errors + if err := k.ClosePool(ctx, pool.GetPoolId()); err != nil { + k.Logger(ctx).With("ctx", "draw_completed", "pool_id", pool.GetPoolId()).Error("Silently failed to continue close pool procedure: %v", err) + } + } return draw, err } // ComputeDepositsTWB takes deposits and computes the weight based on their deposit time and the draw duration -// It essentially compute the Time Weighted Balance of each deposit for the DrawPrizes phase +// It essentially computes the Time Weighted Balance of each deposit for the DrawPrizes phase func (k Keeper) ComputeDepositsTWB(ctx sdk.Context, depositStartAt time.Time, drawAt time.Time, deposits []types.Deposit) []DepositTWB { params := k.GetParams(ctx) diff --git a/x/millions/keeper/keeper_pool.go b/x/millions/keeper/keeper_pool.go index 0a77a36d..853247b8 100644 --- a/x/millions/keeper/keeper_pool.go +++ b/x/millions/keeper/keeper_pool.go @@ -479,6 +479,125 @@ func (k Keeper) UpdatePool( return nil } +// ClosePool iterate through many stages to close a Pool based on its local state, deposits and withdrawals +// +// Closing procedure steps: +// 1. Move pool into state Closing +// 2. Launch the final Draw +// 3. Launch the withdrawal of all the deposits +// 4. Wait for all withdrawals to complete +func (k Keeper) ClosePool(ctx sdk.Context, poolID uint64) error { + logger := k.Logger(ctx).With("ctx", "close_pool", "pool_id", poolID) + + // Make sure we always have a valid pool entity + pool, err := k.GetPool(ctx, poolID) + if err != nil { + return err + } + + // Make sure the pool can be closed or is already closing + if pool.State != types.PoolState_Ready && + pool.State != types.PoolState_Paused && + pool.State != types.PoolState_Closing { + logger.Error(fmt.Sprintf("Impossible state change requested due to pool state %s", pool.State)) + return types.ErrPoolStateChangeNotAllowed + } + + // Step 1: Pool is not yet in closing state - launch closing procedure + if pool.State != types.PoolState_Closing { + logger.Info("Update pool to state closing") + pool.State = types.PoolState_Closing + pool.UpdatedAt = ctx.BlockTime() + pool.UpdatedAtHeight = ctx.BlockHeight() + k.updatePool(ctx, &pool) + + // Launch step 2 final draw + logger.Info("Launch final draw") + if _, err := k.LaunchNewDraw(ctx, poolID); err != nil { + logger.Error(fmt.Sprintf("Error while launching final draw: %v", err)) + return err + } + } + + // Step 2: Wait for final draw completion + if pool.LastDrawState != types.DrawState_Success { + return nil + } + + // Step 3: Initiate the withdrawal of all the deposits + deposits := k.ListPoolDeposits(ctx, poolID) + if len(deposits) > 0 { + logger.Info("Initiate the withdrawal of all deposits") + // As long as we have deposits we will keep trying to withdraw them before moving forward + serv := msgServer{Keeper: k} + for _, deposit := range deposits { + if deposit.State == types.DepositState_Failure { + // Force retry deposits in error states + logger.Info(fmt.Sprintf("Retrying deposit with ID %d in error state %s", deposit.GetDepositId(), deposit.GetErrorState().String())) + _, err := serv.DepositRetry(sdk.WrapSDKContext(ctx), &types.MsgDepositRetry{ + PoolId: deposit.GetPoolId(), + DepositId: deposit.GetDepositId(), + DepositorAddress: deposit.GetDepositorAddress(), + }) + if err != nil { + logger.Error(fmt.Sprintf("Error while forcing retry for deposit %d: %v", deposit.GetDepositId(), err)) + return err + } + } else if deposit.State == types.DepositState_Success { + // Withdraw deposits in success state + logger.Info(fmt.Sprintf("Withdrawing deposit with ID %d", deposit.GetDepositId())) + _, err := serv.WithdrawDeposit(sdk.WrapSDKContext(ctx), types.NewMsgWithdrawDeposit( + deposit.GetDepositorAddress(), + deposit.GetDepositorAddress(), + deposit.GetPoolId(), + deposit.GetDepositId(), + )) + if err != nil { + logger.Error(fmt.Sprintf("Error while launching withdrawal for deposit with ID %d: %v", deposit.GetDepositId(), err)) + return err + } + } + } + return nil + } + + // Step 4: Wait for all withdrawals to complete + withdrawals := k.ListPoolWithdrawals(ctx, poolID) + if len(withdrawals) > 0 { + serv := msgServer{Keeper: k} + for _, withdrawal := range withdrawals { + if withdrawal.State == types.WithdrawalState_Failure { + // Force retry withdrawals in error state + logger.Info(fmt.Sprintf("Retrying withdrawal with ID %d in error state %s", withdrawal.GetWithdrawalId(), withdrawal.GetErrorState().String())) + _, err := serv.WithdrawDepositRetry(sdk.WrapSDKContext(ctx), &types.MsgWithdrawDepositRetry{ + PoolId: withdrawal.GetPoolId(), + WithdrawalId: withdrawal.GetWithdrawalId(), + DepositorAddress: withdrawal.GetDepositorAddress(), + }) + if err != nil { + logger.Error(fmt.Sprintf("Error while forcing retry for withdrawal with ID %d: %v", withdrawal.GetWithdrawalId(), err)) + return err + } + } + } + return nil + } + + // Step 5: Clear module dust and close Pool + balance := k.BankKeeper.GetBalance(ctx, sdk.MustAccAddressFromBech32(pool.LocalAddress), pool.Denom) + if balance.IsPositive() { + if err := k.BankKeeper.SendCoinsFromAccountToModule(ctx, sdk.MustAccAddressFromBech32(pool.GetLocalAddress()), authtypes.FeeCollectorName, sdk.NewCoins(balance)); err != nil { + logger.Error(fmt.Sprintf("Failed to transfer dust from pool with ID %d local account to fee collector: %v", poolID, err)) + } + } + logger.Info("Update pool to state closed") + pool.State = types.PoolState_Closed + pool.UpdatedAt = ctx.BlockTime() + pool.UpdatedAtHeight = ctx.BlockHeight() + k.updatePool(ctx, &pool) + return nil +} + // RebalanceValidatorsBondings allows rebalancing of validators bonded assets // Current implementation: // - Initiate an even redelegate distribution from inactive bonded validators to active validators @@ -489,7 +608,7 @@ func (k Keeper) RebalanceValidatorsBondings(ctx sdk.Context, poolID uint64) erro } // Make sure pool is ready - if pool.State == types.PoolState_Created || pool.State == types.PoolState_Unspecified { + if pool.State != types.PoolState_Ready && pool.State != types.PoolState_Paused { return types.ErrPoolNotReady } @@ -514,7 +633,7 @@ func (k Keeper) RedelegateToActiveValidatorsOnRemoteZone(ctx sdk.Context, poolID } // Make sure pool is ready - if pool.State == types.PoolState_Created || pool.State == types.PoolState_Unspecified { + if pool.State != types.PoolState_Ready && pool.State != types.PoolState_Paused { return types.ErrPoolNotReady } @@ -565,11 +684,6 @@ func (k Keeper) OnRedelegateToActiveValidatorsOnRemoteZoneCompleted(ctx sdk.Cont return err } - // Make sure pool is ready - if pool.State == types.PoolState_Created || pool.State == types.PoolState_Unspecified { - return types.ErrPoolNotReady - } - // Get the validator valIdx := pool.GetValidatorsMapIndex() index, found := valIdx[valSrcAddr] @@ -600,26 +714,6 @@ func (k Keeper) OnRedelegateToActiveValidatorsOnRemoteZoneCompleted(ctx sdk.Cont return nil } -// UnsafeKillPool This method switches the provided pool state but does not handle any withdrawal or deposit. -// It shouldn't be used and is very specific to UNUSED and EMPTY pools -func (k Keeper) UnsafeKillPool(ctx sdk.Context, poolID uint64) (types.Pool, error) { - // Grab our pool instance - pool, err := k.GetPool(ctx, poolID) - if err != nil { - return types.Pool{}, err - } - - // Make sure the pool isn't killed yet - if pool.GetState() == types.PoolState_Killed { - return pool, errorsmod.Wrapf(types.ErrPoolKilled, "%d", poolID) - } - - // Kill the pool - pool.State = types.PoolState_Killed - k.updatePool(ctx, &pool) - return pool, nil -} - // UnsafeUpdatePoolPortIds This method raw update the provided pool port ids. // It's heavily unsafe and could break the ICA implementation. It should only be used by store migrations. func (k Keeper) UnsafeUpdatePoolPortIds(ctx sdk.Context, poolID uint64, icaDepositPortId, icaPrizePoolPortId string) (types.Pool, error) { diff --git a/x/millions/keeper/keeper_pool_test.go b/x/millions/keeper/keeper_pool_test.go index 5d68c9a6..62940930 100644 --- a/x/millions/keeper/keeper_pool_test.go +++ b/x/millions/keeper/keeper_pool_test.go @@ -207,7 +207,7 @@ func (suite *KeeperTestSuite) TestPool_DrawScheduleBasics() { suite.Require().True(pool.ShouldDraw(ctx.WithBlockTime((*pool.LastDrawCreatedAt).Add(48 * time.Hour)))) // Test pool not ready states which should not allow any draw - pool.State = millionstypes.PoolState_Killed + pool.State = millionstypes.PoolState_Closed suite.Require().False(pool.ShouldDraw(ctx.WithBlockTime(now.Add(48 * time.Hour)))) pool.State = millionstypes.PoolState_Created @@ -955,6 +955,173 @@ func (suite *KeeperTestSuite) TestPool_ValidatorsSplitConsistency() { suite.Require().Equal(sdk.ZeroInt(), pool.Validators[0].BondedAmount) } +func (suite *KeeperTestSuite) TestPool_ClosePool() { + app := suite.app + ctx := suite.ctx + goCtx := sdk.WrapSDKContext(ctx) + msgServer := millionskeeper.NewMsgServerImpl(*app.MillionsKeeper) + var now = time.Now().UTC() + + // Set up the base pool + poolID, err := app.MillionsKeeper.RegisterPool(ctx, + millionstypes.PoolType_Staking, + "ulum", + "ulum", + testChainID, + "", + "", + []string{suite.valAddrs[0].String()}, + "lum", + "lumvaloper", + app.MillionsKeeper.GetParams(ctx).MinDepositAmount, + time.Duration(millionstypes.DefaultUnbondingDuration), + sdk.NewInt(millionstypes.DefaultMaxUnbondingEntries), + millionstypes.DrawSchedule{DrawDelta: 24 * time.Hour, InitialDrawAt: ctx.BlockTime().Add(24 * time.Hour)}, + millionstypes.PrizeStrategy{PrizeBatches: []millionstypes.PrizeBatch{{PoolPercent: 100, Quantity: 100, DrawProbability: sdk.NewDec(1)}}}, + []millionstypes.FeeTaker{ + {Destination: authtypes.FeeCollectorName, Amount: sdk.NewDecWithPrec(millionstypes.DefaultFeeTakerAmount, 2), Type: millionstypes.FeeTakerType_LocalModuleAccount}, + }, + ) + suite.Require().NoError(err) + + // Initialize the balance + balanceBefore := app.BankKeeper.GetBalance(ctx, suite.addrs[0], localPoolDenom) + suite.Require().Equal(int64(1_000_000_000_0), balanceBefore.Amount.Int64()) + + // Make sure the pool is in the ready state + pool, err := app.MillionsKeeper.GetPool(ctx, poolID) + suite.Require().NoError(err) + suite.Require().Equal(millionstypes.PoolState_Ready, pool.State) + withdrawalsBefore := app.MillionsKeeper.ListAccountWithdrawals(ctx, suite.addrs[0]) + suite.Require().Len(withdrawalsBefore, 0) + withdrawals := app.MillionsKeeper.ListAccountWithdrawals(ctx, suite.addrs[0]) + suite.Require().Len(withdrawals, 0) + + // Add 3 deposits + for i := 0; i < 3; i++ { + // Create a new deposit and add it to the state + _, err := msgServer.Deposit(goCtx, &millionstypes.MsgDeposit{ + PoolId: poolID, + Amount: sdk.NewCoin(localPoolDenom, sdk.NewInt(1_100_000_000)), + DepositorAddress: suite.addrs[0].String(), + WinnerAddress: suite.addrs[0].String(), + IsSponsor: false, + }) + suite.Require().NoError(err) + } + + // Pool should have 3 active deposits + deposits := app.MillionsKeeper.ListDeposits(ctx) + suite.Require().Len(deposits, 3) + for _, d := range deposits { + suite.Require().Equal(millionstypes.DepositState_Success, d.State) + } + + // Pool should have no withdrawals for now + withdrawals = app.MillionsKeeper.ListWithdrawals(ctx) + suite.Require().Len(withdrawals, 0) + + // Run the first step of closing the pool + err = app.MillionsKeeper.ClosePool(ctx, poolID) + suite.Require().NoError(err) + + // Pool should be in state closing, and have a succeeded draw + pool, err = app.MillionsKeeper.GetPool(ctx, poolID) + suite.Require().NoError(err) + suite.Require().Equal(millionstypes.PoolState_Closing, pool.State) + suite.Require().Equal(millionstypes.DrawState_Success, pool.LastDrawState) + + // Pool should have 3 withdrawals, and no deposits + withdrawals = app.MillionsKeeper.ListWithdrawals(ctx) + suite.Require().Len(withdrawals, 3) + for _, w := range withdrawals { + suite.Require().Equal(millionstypes.WithdrawalState_Pending, w.State) + } + deposits = app.MillionsKeeper.ListDeposits(ctx) + suite.Require().Len(deposits, 0) + + // Calling ClosePool should have no effect untill withdrawals finish their unbonding + err = app.MillionsKeeper.ClosePool(ctx, poolID) + suite.Require().NoError(err) + pool, err = app.MillionsKeeper.GetPool(ctx, poolID) + suite.Require().NoError(err) + suite.Require().Equal(millionstypes.PoolState_Closing, pool.State) + + // Launch withdrawal unbonding + epochTracker, err := app.MillionsKeeper.GetEpochTracker(ctx, epochstypes.DAY_EPOCH, millionstypes.WithdrawalTrackerType) + suite.Require().NoError(err) + nextEpochUnbonding := pool.GetNextEpochUnbonding(epochTracker) + epochUnbondings := app.MillionsKeeper.GetEpochUnbondings(ctx, nextEpochUnbonding) + for _, e := range epochUnbondings { + err = app.MillionsKeeper.UndelegateWithdrawalsOnRemoteZone(ctx, e) + suite.Require().NoError(err) + } + withdrawals = app.MillionsKeeper.ListWithdrawals(ctx) + suite.Require().Len(withdrawals, 3) + for _, w := range withdrawals { + suite.Require().Equal(millionstypes.WithdrawalState_IcaUnbonding, w.State) + } + + // Calling ClosePool should have no effect untill withdrawals finish their unbonding + err = app.MillionsKeeper.ClosePool(ctx, poolID) + suite.Require().NoError(err) + pool, err = app.MillionsKeeper.GetPool(ctx, poolID) + suite.Require().NoError(err) + suite.Require().Equal(millionstypes.PoolState_Closing, pool.State) + + // Test that the balance should remain unchanged + balance := app.BankKeeper.GetBalance(ctx, suite.addrs[0], localPoolDenom) + suite.Require().Equal(balanceBefore.Amount.Int64()-3_300_000_000, balance.Amount.Int64()) + + ctx = ctx.WithBlockTime(now.Add(21 * 24 * time.Hour)) + _, err = app.StakingKeeper.CompleteUnbonding(ctx, sdk.MustAccAddressFromBech32(pool.IcaDepositAddress), suite.valAddrs[0]) + suite.Require().NoError(err) + + // Dequeue matured withdrawals and trigger the transfer to the local chain + s, e := app.MillionsKeeper.BlockWithdrawalUpdates(ctx) + suite.Require().Equal(3, s) + suite.Require().Equal(0, e) + + // Test that there should be no matured withdrawal left + s, e = app.MillionsKeeper.BlockWithdrawalUpdates(ctx) + suite.Require().Equal(0, s) + suite.Require().Equal(0, e) + + // Test that the balance should compensate 3 deposits transfered back + balance = app.BankKeeper.GetBalance(ctx, suite.addrs[0], localPoolDenom) + suite.Require().Equal(balanceBefore.Amount.Int64(), balance.Amount.Int64()) + + // Get the pool and make sure it's in the closed state + pool, err = app.MillionsKeeper.GetPool(ctx, poolID) + suite.Require().NoError(err) + suite.Require().Equal(millionstypes.PoolState_Closed, pool.State) + + // Close pool again - It shouldn't work + err = app.MillionsKeeper.ClosePool(ctx, poolID) + suite.Require().Error(err, millionstypes.ErrPoolStateChangeNotAllowed) + + // Try to make a deposit - It shouldn't work + _, err = msgServer.Deposit(goCtx, &millionstypes.MsgDeposit{ + PoolId: poolID, + Amount: sdk.NewCoin(localPoolDenom, sdk.NewInt(1_100_000_000)), + DepositorAddress: suite.addrs[0].String(), + WinnerAddress: suite.addrs[0].String(), + IsSponsor: false, + }) + suite.Require().Error(err) + + // Try to claim the prizes - It should work even with a closed pool + prizes := app.MillionsKeeper.ListAccountPrizes(ctx, suite.addrs[0]) + for _, p := range prizes { + _, err = msgServer.ClaimPrize(goCtx, &millionstypes.MsgClaimPrize{ + PoolId: poolID, + DrawId: p.DrawId, + PrizeId: p.PrizeId, + }) + suite.Require().NoError(err) + } +} + // TestPool_UpdatePool tests the different conditions for a proposal pool update func (suite *KeeperTestSuite) TestPool_UpdatePool() { app := suite.app @@ -1095,7 +1262,7 @@ func (suite *KeeperTestSuite) TestPool_UpdatePool() { suite.Require().Equal(len(newFees), len(pool.FeeTakers)) // UpdatePool with invalid pool_state -> PoolState_Killed - err = app.MillionsKeeper.UpdatePool(ctx, pool.PoolId, nil, &newDepositAmount, &UnbondingDuration, &maxUnbondingEntries, &newDrawSchedule, &newPrizeStrategy, millionstypes.PoolState_Killed, newFees) + err = app.MillionsKeeper.UpdatePool(ctx, pool.PoolId, nil, &newDepositAmount, &UnbondingDuration, &maxUnbondingEntries, &newDrawSchedule, &newPrizeStrategy, millionstypes.PoolState_Closed, newFees) suite.Require().ErrorIs(err, millionstypes.ErrPoolStateChangeNotAllowed) // Grab fresh pool instance pool, err = app.MillionsKeeper.GetPool(ctx, 1) diff --git a/x/millions/keeper/keeper_prize.go b/x/millions/keeper/keeper_prize.go index 1bfe8038..71b6b0eb 100644 --- a/x/millions/keeper/keeper_prize.go +++ b/x/millions/keeper/keeper_prize.go @@ -14,21 +14,36 @@ import ( // ClawBackPrize claw backs a prize by adding its amount to the clawback prize pool func (k Keeper) ClawBackPrize(ctx sdk.Context, poolID uint64, drawID uint64, prizeID uint64) error { + // Acquire the pool instance pool, err := k.GetPool(ctx, poolID) if err != nil { return err } + + // If the pool is in closing or closed state, we do not process any prize clawback + // We want all user to be able to claim their prize, no matter the state + if pool.State == types.PoolState_Closing || pool.State == types.PoolState_Closed { + // Since clawback is triggered by a queue we simulate a successful clawback and the queue will never retry it + // = infinite prize claim duration + return nil + } + + // Acquire the prize instance prize, err := k.GetPoolDrawPrize(ctx, poolID, drawID, prizeID) if err != nil { return err } + + // If the prize is not in pending state, we do not process any prize clawback if prize.State != types.PrizeState_Pending { return errorsmod.Wrapf(types.ErrIllegalStateOperation, "expecting %s but state is %s", types.PrizeState_Pending, prize.State) } + // Add the prize amount to the clawback prize pool pool.AvailablePrizePool = pool.AvailablePrizePool.Add(prize.Amount) k.updatePool(ctx, &pool) + // Remove the prize from the prize queue if err := k.RemovePrize(ctx, prize); err != nil { return err } diff --git a/x/millions/keeper/keeper_withdrawal.go b/x/millions/keeper/keeper_withdrawal.go index f78fefe9..81cc9706 100644 --- a/x/millions/keeper/keeper_withdrawal.go +++ b/x/millions/keeper/keeper_withdrawal.go @@ -133,10 +133,14 @@ func (k Keeper) TransferWithdrawalToRecipient(ctx sdk.Context, poolID uint64, wi return nil } -// OnTransferWithdrawalToRecipientCompleted Acknowledge the withdraw IBC transfer -// - To to the local chain response if it's a transfer to local chain +// OnTransferWithdrawalToRecipientCompleted Acknowledge the withdrawal IBC transfer +// - To the local chain response if it's a transfer to local chain // - To the native chain if it's BankSend for a native pool with a native destination address func (k Keeper) OnTransferWithdrawalToRecipientCompleted(ctx sdk.Context, poolID uint64, withdrawalID uint64, isError bool) error { + pool, err := k.GetPool(ctx, poolID) + if err != nil { + return err + } withdrawal, err := k.GetPoolWithdrawal(ctx, poolID, withdrawalID) if err != nil { return err @@ -154,6 +158,15 @@ func (k Keeper) OnTransferWithdrawalToRecipientCompleted(ctx sdk.Context, poolID if err := k.RemoveWithdrawal(ctx, withdrawal); err != nil { return err } + + if pool.State == types.PoolState_Closing { + // Continue closing procedure + // voluntary ignore errors + if err := k.ClosePool(ctx, poolID); err != nil { + k.Logger(ctx).With("ctx", "withdrawal_completed", "pool_id", poolID).Error("Silently failed to continue close pool procedure: %v", err) + } + } + return nil } diff --git a/x/millions/keeper/msg_server_deposit.go b/x/millions/keeper/msg_server_deposit.go index 52fbd284..3ac29b96 100644 --- a/x/millions/keeper/msg_server_deposit.go +++ b/x/millions/keeper/msg_server_deposit.go @@ -126,18 +126,9 @@ func (k msgServer) DepositRetry(goCtx context.Context, msg *types.MsgDepositRetr return nil, types.ErrInvalidDepositorAddress } - // State should be set to failure in order to retry something - if deposit.State != types.DepositState_Failure { - return nil, errorsmod.Wrapf( - types.ErrInvalidDepositState, - "state is %s instead of %s", - deposit.State.String(), types.DepositState_Failure.String(), - ) - } - newState := types.DepositState_Unspecified - if deposit.State == types.DepositState_IbcTransfer && ctx.BlockTime().After(deposit.UpdatedAt.Add(2*types.IBCTimeoutNanos*time.Nanosecond)) { - // Handle IBC stucked operation for more than twice the specified IBC timeout + if deposit.State == types.DepositState_IbcTransfer && ctx.BlockTime().After(deposit.UpdatedAt.Add(types.IBCForceRetryNanos*time.Nanosecond)) { + // Handle IBC stucked operation for more than 3 days (no timeout received) newState = types.DepositState_IbcTransfer if err := k.TransferDepositToRemoteZone(ctx, deposit.PoolId, deposit.DepositId); err != nil { return nil, err @@ -157,8 +148,8 @@ func (k msgServer) DepositRetry(goCtx context.Context, msg *types.MsgDepositRetr } else { return nil, errorsmod.Wrapf( types.ErrInvalidDepositState, - "error_state is %s instead of %s or %s", - deposit.ErrorState.String(), types.DepositState_IbcTransfer.String(), types.DepositState_IcaDelegate.String(), + "state is %s instead of %s", + deposit.State.String(), types.DepositState_Failure.String(), ) } diff --git a/x/millions/keeper/msg_server_pool.go b/x/millions/keeper/msg_server_pool.go index 45bbdc8a..07f519d9 100644 --- a/x/millions/keeper/msg_server_pool.go +++ b/x/millions/keeper/msg_server_pool.go @@ -20,7 +20,7 @@ func (k msgServer) RestoreInterchainAccounts(goCtx context.Context, msg *types.M } // We always want our pool to be ready - if pool.State == types.PoolState_Created { + if pool.State == types.PoolState_Created || pool.State == types.PoolState_Unspecified { return nil, types.ErrPoolNotReady } @@ -88,7 +88,7 @@ func (k msgServer) restoreICADepositEntities(ctx sdk.Context, poolID uint64) { // Restore withdrawals ICA locked operations on ICADeposit account withdrawals := k.Keeper.ListPoolWithdrawals(ctx, poolID) for _, w := range withdrawals { - if w.State == types.WithdrawalState_IcaUndelegate { + if w.State == types.WithdrawalState_IcaUndelegate || w.State == types.WithdrawalState_IbcTransfer { w.ErrorState = w.State w.State = types.WithdrawalState_Failure k.Keeper.setPoolWithdrawal(ctx, w) @@ -98,7 +98,7 @@ func (k msgServer) restoreICADepositEntities(ctx sdk.Context, poolID uint64) { // Restore draws ICA locked operations on ICADeposit account draws := k.Keeper.ListPoolDraws(ctx, poolID) for _, d := range draws { - if d.State == types.DrawState_IcaWithdrawRewards { + if d.State == types.DrawState_IcaWithdrawRewards || d.State == types.DrawState_IbcTransfer { d.ErrorState = d.State d.State = types.DrawState_Failure k.Keeper.SetPoolDraw(ctx, d) diff --git a/x/millions/keeper/queries_balance.go b/x/millions/keeper/queries_balance.go index 1676fc8c..3bdcad5d 100644 --- a/x/millions/keeper/queries_balance.go +++ b/x/millions/keeper/queries_balance.go @@ -39,7 +39,9 @@ func BalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icqueriestype return errorsmod.Wrapf(types.ErrPoolNotFound, "no registered draw %d for pool %d", drawID, poolID) } - // Based on type, we want different processing + // Scenarios: + // - Timeout: Treated as an error (see below) + // - Error: Put entity in error state to allow users to retry if status == icqueriestypes.QueryResponseStatus_TIMEOUT { k.Logger(ctx).Error(fmt.Sprintf("QUERY TIMEOUT - QueryId: %s, TTL: %d, BlockTime: %d", query.Id, query.TimeoutTimestamp, ctx.BlockHeader().Time.UnixNano())) _, err := k.OnQueryFreshPrizePoolCoinsOnRemoteZoneCompleted(ctx, pool.GetPoolId(), draw.GetDrawId(), sdk.NewCoins(), true) diff --git a/x/millions/types/codec.go b/x/millions/types/codec.go index 4819b579..0c0aadb5 100644 --- a/x/millions/types/codec.go +++ b/x/millions/types/codec.go @@ -32,6 +32,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&ProposalUpdateParams{}, "lum-network/millions/ProposalUpdateParams", nil) cdc.RegisterConcrete(&ProposalRegisterPool{}, "lum-network/millions/ProposalRegisterPool", nil) cdc.RegisterConcrete(&ProposalUpdatePool{}, "lum-network/millions/ProposalUpdatePool", nil) + cdc.RegisterConcrete(&ProposalClosePool{}, "lum-network/millions/ProposalClosePool", nil) } // RegisterInterfaces Register the implementations for the given codecs @@ -51,6 +52,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { registry.RegisterImplementations((*govtypesv1beta1.Content)(nil), &ProposalUpdateParams{}) registry.RegisterImplementations((*govtypesv1beta1.Content)(nil), &ProposalRegisterPool{}) registry.RegisterImplementations((*govtypesv1beta1.Content)(nil), &ProposalUpdatePool{}) + registry.RegisterImplementations((*govtypesv1beta1.Content)(nil), &ProposalClosePool{}) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/millions/types/errors.go b/x/millions/types/errors.go index cabb6bf5..a8034060 100644 --- a/x/millions/types/errors.go +++ b/x/millions/types/errors.go @@ -25,6 +25,9 @@ var ( ErrValidatorNotFound = errorsmod.Register(ModuleName, 1112, "Validator not found in pool validator set") ErrInvalidValidatorEnablementStatus = errorsmod.Register(ModuleName, 1113, "Invalid validator enablement status") ErrInvalidPoolType = errorsmod.Register(ModuleName, 1114, "Invalid pool type") + ErrPoolNotClosing = errorsmod.Register(ModuleName, 1115, "Pool is not closing") + ErrPoolClosed = errorsmod.Register(ModuleName, 1116, "Pool is closed") + ErrPoolWithdrawalsInProgress = errorsmod.Register(ModuleName, 1117, "Pool has withdrawals in progress") ErrInvalidDepositAmount = errorsmod.Register(ModuleName, 1200, "Deposit amount must be positive") ErrInvalidDepositDenom = errorsmod.Register(ModuleName, 1201, "Invalid deposit denom") ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 1202, "Invalid depositor address") diff --git a/x/millions/types/gov.pb.go b/x/millions/types/gov.pb.go index 813d1d74..1681949c 100644 --- a/x/millions/types/gov.pb.go +++ b/x/millions/types/gov.pb.go @@ -295,6 +295,65 @@ func (m *ProposalUpdatePool) GetFeeTakers() []FeeTaker { return nil } +type ProposalClosePool struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + PoolId uint64 `protobuf:"varint,3,opt,name=pool_id,json=poolId,proto3" json:"pool_id,omitempty"` +} + +func (m *ProposalClosePool) Reset() { *m = ProposalClosePool{} } +func (*ProposalClosePool) ProtoMessage() {} +func (*ProposalClosePool) Descriptor() ([]byte, []int) { + return fileDescriptor_f51755d1062ffc9e, []int{2} +} +func (m *ProposalClosePool) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ProposalClosePool) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ProposalClosePool.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 *ProposalClosePool) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProposalClosePool.Merge(m, src) +} +func (m *ProposalClosePool) XXX_Size() int { + return m.Size() +} +func (m *ProposalClosePool) XXX_DiscardUnknown() { + xxx_messageInfo_ProposalClosePool.DiscardUnknown(m) +} + +var xxx_messageInfo_ProposalClosePool proto.InternalMessageInfo + +func (m *ProposalClosePool) GetTitle() string { + if m != nil { + return m.Title + } + return "" +} + +func (m *ProposalClosePool) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *ProposalClosePool) GetPoolId() uint64 { + if m != nil { + return m.PoolId + } + return 0 +} + type ProposalUpdateParams struct { Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` @@ -310,7 +369,7 @@ type ProposalUpdateParams struct { func (m *ProposalUpdateParams) Reset() { *m = ProposalUpdateParams{} } func (*ProposalUpdateParams) ProtoMessage() {} func (*ProposalUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_f51755d1062ffc9e, []int{2} + return fileDescriptor_f51755d1062ffc9e, []int{3} } func (m *ProposalUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -384,73 +443,75 @@ func (m *ProposalUpdateParams) GetMinDepositDrawDelta() *time.Duration { func init() { proto.RegisterType((*ProposalRegisterPool)(nil), "lum.network.millions.ProposalRegisterPool") proto.RegisterType((*ProposalUpdatePool)(nil), "lum.network.millions.ProposalUpdatePool") + proto.RegisterType((*ProposalClosePool)(nil), "lum.network.millions.ProposalClosePool") proto.RegisterType((*ProposalUpdateParams)(nil), "lum.network.millions.ProposalUpdateParams") } func init() { proto.RegisterFile("lum/network/millions/gov.proto", fileDescriptor_f51755d1062ffc9e) } var fileDescriptor_f51755d1062ffc9e = []byte{ - // 948 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xcf, 0x6f, 0x23, 0x35, - 0x14, 0xc7, 0x3b, 0x34, 0x69, 0x12, 0xf7, 0x07, 0xad, 0x9b, 0x6d, 0x67, 0x7b, 0x98, 0x84, 0x2e, - 0x42, 0xe1, 0xd0, 0x89, 0xd4, 0x8a, 0x0b, 0x9c, 0xda, 0xcd, 0x82, 0x82, 0x84, 0x14, 0xa6, 0xbb, - 0x08, 0x56, 0x48, 0x23, 0x67, 0xec, 0x4c, 0xac, 0xce, 0xd8, 0x83, 0xed, 0x69, 0x53, 0xfe, 0x0a, - 0x8e, 0x7b, 0xe4, 0x4f, 0xe1, 0xc0, 0x61, 0x8f, 0x7b, 0x44, 0x1c, 0x16, 0xd4, 0xfe, 0x19, 0x5c, - 0x90, 0xed, 0x49, 0x93, 0xd0, 0x54, 0x34, 0xdd, 0x3d, 0x35, 0xf6, 0xfb, 0xbe, 0xcf, 0xf3, 0xf8, - 0xbd, 0x6f, 0x67, 0x80, 0x97, 0xe4, 0x69, 0x9b, 0x11, 0x75, 0xc1, 0xc5, 0x59, 0x3b, 0xa5, 0x49, - 0x42, 0x39, 0x93, 0xed, 0x98, 0x9f, 0xfb, 0x99, 0xe0, 0x8a, 0xc3, 0x7a, 0x92, 0xa7, 0x7e, 0x11, - 0xf7, 0xc7, 0xf1, 0xbd, 0x7a, 0xcc, 0x63, 0x6e, 0x04, 0x6d, 0xfd, 0xcb, 0x6a, 0xf7, 0xbc, 0x98, - 0xf3, 0x38, 0x21, 0x6d, 0xb3, 0xea, 0xe7, 0x83, 0x36, 0xce, 0x05, 0x52, 0x94, 0xb3, 0x22, 0xde, - 0x98, 0x5b, 0x2b, 0xe3, 0x3c, 0x29, 0x04, 0xad, 0xb9, 0x02, 0x2c, 0xd0, 0x45, 0x28, 0xa3, 0x21, - 0xc1, 0x79, 0x42, 0x0a, 0xe5, 0xa7, 0xf3, 0x51, 0x82, 0xfe, 0x4c, 0x42, 0xa9, 0x04, 0x52, 0x24, - 0xbe, 0xb4, 0xd2, 0xfd, 0xdf, 0x2a, 0xa0, 0xde, 0x13, 0x3c, 0xe3, 0x12, 0x25, 0x01, 0x89, 0xa9, - 0x54, 0x44, 0xf4, 0x38, 0x4f, 0x60, 0x1d, 0x94, 0x15, 0x55, 0x09, 0x71, 0x9d, 0xa6, 0xd3, 0xaa, - 0x05, 0x76, 0x01, 0x9b, 0x60, 0x15, 0x13, 0x19, 0x09, 0x9a, 0xe9, 0x93, 0xbb, 0x1f, 0x98, 0xd8, - 0xf4, 0x16, 0x7c, 0x0c, 0xaa, 0xd1, 0x10, 0x51, 0x16, 0x52, 0xec, 0x2e, 0x9b, 0x70, 0xc5, 0xac, - 0xbb, 0x58, 0x23, 0x31, 0x61, 0x3c, 0x75, 0x4b, 0x16, 0x69, 0x16, 0xf0, 0x23, 0xb0, 0xc6, 0x90, - 0xa2, 0xe7, 0x24, 0xb4, 0xc1, 0xb2, 0x65, 0xda, 0xbd, 0x8e, 0x91, 0x3c, 0x01, 0xeb, 0x11, 0x67, - 0x8c, 0x44, 0xba, 0x82, 0x06, 0xaf, 0x18, 0xcd, 0xda, 0x64, 0xb3, 0x8b, 0xa1, 0x07, 0xc0, 0x39, - 0x4a, 0x28, 0x46, 0x8a, 0x0b, 0xe9, 0x56, 0x9a, 0xcb, 0xad, 0x5a, 0x30, 0xb5, 0x03, 0x7f, 0x04, - 0x30, 0xa5, 0x2c, 0xc4, 0x24, 0xe3, 0x92, 0xaa, 0x10, 0xa5, 0x3c, 0x67, 0xca, 0xad, 0x6a, 0xd2, - 0x89, 0xff, 0xfa, 0x6d, 0x63, 0xe9, 0xcf, 0xb7, 0x8d, 0x4f, 0x62, 0xaa, 0x86, 0x79, 0xdf, 0x8f, - 0x78, 0xda, 0x8e, 0xb8, 0x4c, 0xb9, 0x2c, 0xfe, 0x1c, 0x48, 0x7c, 0xd6, 0x56, 0x97, 0x19, 0x91, - 0x7e, 0x97, 0xa9, 0x60, 0x33, 0xa5, 0xac, 0x63, 0x41, 0xc7, 0x86, 0x03, 0xbf, 0x01, 0xeb, 0x33, - 0x9d, 0x70, 0x6b, 0x4d, 0xa7, 0xb5, 0x7a, 0xb8, 0xef, 0xcf, 0x9b, 0x10, 0xbf, 0x23, 0xd0, 0xc5, - 0x69, 0xa1, 0x3c, 0x29, 0xe9, 0xe2, 0xc1, 0x1a, 0x9e, 0xda, 0x83, 0x3d, 0xb0, 0x31, 0xdb, 0x2e, - 0x17, 0x18, 0xde, 0x93, 0xf9, 0xbc, 0x9e, 0xd6, 0x9e, 0x16, 0xd2, 0x02, 0xb8, 0x9e, 0x4d, 0x6f, - 0xc2, 0x23, 0xb0, 0xd3, 0x27, 0xd1, 0xf0, 0xe8, 0x30, 0xcc, 0x04, 0x19, 0xd0, 0x51, 0x88, 0xa2, - 0x28, 0x44, 0x18, 0x0b, 0x77, 0xd5, 0x5c, 0xe6, 0xb6, 0x8d, 0xf6, 0x4c, 0xf0, 0x38, 0x8a, 0x8e, - 0x31, 0x16, 0xb7, 0x93, 0xce, 0x51, 0x62, 0x93, 0xd6, 0x6e, 0x27, 0x7d, 0x87, 0x12, 0x93, 0xe4, - 0x83, 0x6d, 0x25, 0x10, 0x93, 0x03, 0x22, 0xc2, 0x68, 0x88, 0x18, 0x23, 0x89, 0xee, 0xd9, 0xba, - 0xc9, 0xd8, 0x1a, 0x87, 0x9e, 0xda, 0x48, 0x17, 0xc3, 0x00, 0xc0, 0x9c, 0xf5, 0x39, 0xc3, 0x94, - 0xc5, 0xe1, 0xd8, 0x14, 0xee, 0x86, 0x79, 0xde, 0xc7, 0xbe, 0x75, 0x8d, 0x3f, 0x76, 0x8d, 0xdf, - 0x29, 0x04, 0x27, 0x55, 0xfd, 0x94, 0xaf, 0xfe, 0x6a, 0x38, 0xc1, 0xd6, 0x4d, 0xfa, 0x38, 0x08, - 0xfb, 0xe0, 0x51, 0x8a, 0x46, 0xe1, 0x84, 0x4b, 0x98, 0x12, 0x94, 0x48, 0xf7, 0xc3, 0x07, 0xf5, - 0x7b, 0x3b, 0x45, 0xa3, 0x17, 0x63, 0xd6, 0x33, 0x8b, 0x82, 0x5f, 0x80, 0x9a, 0x76, 0x67, 0xa8, - 0x65, 0xee, 0x66, 0xd3, 0x69, 0x6d, 0x1c, 0x7a, 0x77, 0xb4, 0x87, 0xf3, 0xe4, 0xf9, 0x65, 0x46, - 0x82, 0x6a, 0x56, 0xfc, 0x82, 0x4f, 0x01, 0x18, 0x10, 0x12, 0x2a, 0x74, 0x46, 0x84, 0x74, 0xb7, - 0x9a, 0xcb, 0xad, 0xd5, 0xbb, 0xb2, 0xbf, 0x24, 0xe4, 0xb9, 0x96, 0x15, 0x7d, 0xad, 0x0d, 0x8a, - 0xb5, 0xfc, 0xbc, 0xf4, 0xea, 0xd7, 0xc6, 0xd2, 0xfe, 0xef, 0x65, 0x00, 0xc7, 0x16, 0x7e, 0x91, - 0x61, 0xa4, 0xc8, 0x3b, 0x19, 0x78, 0x17, 0x54, 0xcc, 0x63, 0x15, 0xfe, 0x2d, 0x05, 0x2b, 0x7a, - 0xd9, 0xc5, 0xf0, 0xe3, 0x19, 0x83, 0x95, 0xb4, 0xc1, 0xcc, 0x91, 0x9c, 0x7b, 0xd8, 0xac, 0x7c, - 0x73, 0xed, 0xce, 0xfb, 0xb5, 0xd9, 0xca, 0x42, 0x36, 0x73, 0xfe, 0xd7, 0x66, 0x95, 0xc5, 0x6c, - 0xe6, 0xfc, 0xd7, 0x66, 0x9f, 0x81, 0xb2, 0x54, 0x48, 0x11, 0xf3, 0x8f, 0x65, 0xe3, 0xb0, 0x71, - 0xf7, 0x40, 0x9c, 0x6a, 0x59, 0x60, 0xd5, 0x77, 0x78, 0xa0, 0x76, 0x1f, 0x0f, 0x38, 0x0b, 0x7b, - 0x00, 0x3c, 0xa8, 0x19, 0x73, 0x3d, 0x30, 0x3b, 0xc6, 0xab, 0xef, 0x32, 0xc6, 0xff, 0x94, 0x27, - 0x6f, 0xa2, 0x62, 0x8c, 0x91, 0x40, 0xa9, 0x7c, 0xf0, 0x20, 0xcf, 0x9f, 0xc4, 0xe5, 0xf7, 0x34, - 0x89, 0x67, 0x60, 0x4f, 0xdf, 0xee, 0xec, 0xf8, 0x84, 0x7d, 0xa4, 0xa2, 0x21, 0x91, 0xf6, 0x0d, - 0xb7, 0x70, 0x95, 0xdd, 0x14, 0x8d, 0x66, 0x67, 0xcc, 0xe2, 0x60, 0x0c, 0xdc, 0x49, 0x31, 0x53, - 0x23, 0xfc, 0x29, 0x47, 0x4c, 0x51, 0x75, 0xf9, 0x40, 0x6b, 0x3d, 0x1a, 0x97, 0x32, 0x25, 0xbe, - 0x2d, 0x60, 0xf0, 0x25, 0xd8, 0x35, 0x77, 0x36, 0xed, 0xb1, 0x10, 0x93, 0x44, 0xa1, 0xc2, 0x69, - 0xf7, 0x1a, 0xc6, 0xba, 0xbe, 0xad, 0x29, 0x9f, 0x75, 0x34, 0xc0, 0xb0, 0xd1, 0x68, 0x2e, 0xbb, - 0xb2, 0x08, 0x1b, 0x8d, 0x6e, 0xb3, 0x7f, 0x00, 0x3b, 0xf6, 0x72, 0xc8, 0x28, 0xa3, 0x36, 0xa7, - 0x40, 0x57, 0x17, 0x40, 0x1b, 0xc4, 0xb3, 0x1b, 0x82, 0x45, 0x7f, 0x0f, 0x76, 0xa6, 0xc7, 0xc8, - 0x1c, 0xdf, 0xa2, 0xc1, 0xfd, 0xd1, 0xdb, 0x93, 0xf9, 0xd1, 0x87, 0x37, 0x64, 0x3b, 0xf7, 0x5f, - 0x97, 0xaa, 0xb5, 0x4d, 0x70, 0xf2, 0xd5, 0xeb, 0x2b, 0xcf, 0x79, 0x73, 0xe5, 0x39, 0x7f, 0x5f, - 0x79, 0xce, 0x2f, 0xd7, 0xde, 0xd2, 0x9b, 0x6b, 0x6f, 0xe9, 0x8f, 0x6b, 0x6f, 0xe9, 0xe5, 0xc1, - 0x54, 0x47, 0x93, 0x3c, 0x3d, 0x18, 0x7f, 0xd7, 0x99, 0xaf, 0xaa, 0xf6, 0x68, 0xf2, 0x7d, 0x67, - 0x9a, 0xdb, 0x5f, 0x31, 0xc7, 0x38, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xbc, 0xfd, 0x77, - 0xbb, 0x0a, 0x00, 0x00, + // 961 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x96, 0x41, 0x6f, 0xe3, 0x44, + 0x14, 0xc7, 0x6b, 0x9a, 0x34, 0xc9, 0xa4, 0x2d, 0xed, 0x34, 0xdb, 0x7a, 0x7b, 0x70, 0x42, 0x17, + 0xa1, 0x70, 0xa8, 0x23, 0xb5, 0xe2, 0x02, 0xa7, 0xb6, 0x59, 0x50, 0x90, 0x90, 0x82, 0xbb, 0x8b, + 0x60, 0x85, 0x64, 0x4d, 0x3c, 0x13, 0x67, 0xa8, 0x3d, 0x63, 0x3c, 0xe3, 0x36, 0xe5, 0x53, 0x70, + 0xdc, 0x23, 0x1f, 0x85, 0x03, 0x87, 0x3d, 0xee, 0x11, 0x71, 0x58, 0x50, 0xfb, 0x31, 0xb8, 0xa0, + 0x99, 0xb1, 0x9b, 0x84, 0xa6, 0xa2, 0xe9, 0x2e, 0xa7, 0x66, 0xe6, 0xfd, 0xdf, 0xef, 0x8d, 0xe7, + 0xbd, 0x7f, 0x6d, 0xe0, 0x44, 0x59, 0xdc, 0x61, 0x44, 0x5e, 0xf0, 0xf4, 0xac, 0x13, 0xd3, 0x28, + 0xa2, 0x9c, 0x89, 0x4e, 0xc8, 0xcf, 0xdd, 0x24, 0xe5, 0x92, 0xc3, 0x46, 0x94, 0xc5, 0x6e, 0x1e, + 0x77, 0x8b, 0xf8, 0x6e, 0x23, 0xe4, 0x21, 0xd7, 0x82, 0x8e, 0xfa, 0x65, 0xb4, 0xbb, 0x4e, 0xc8, + 0x79, 0x18, 0x91, 0x8e, 0x5e, 0x0d, 0xb2, 0x61, 0x07, 0x67, 0x29, 0x92, 0x94, 0xb3, 0x3c, 0xde, + 0x9c, 0x5b, 0x2b, 0xe1, 0x3c, 0xca, 0x05, 0xed, 0xb9, 0x02, 0x9c, 0xa2, 0x0b, 0x5f, 0x04, 0x23, + 0x82, 0xb3, 0x88, 0xe4, 0xca, 0x8f, 0xe7, 0xa3, 0x52, 0xfa, 0x13, 0xf1, 0x85, 0x4c, 0x91, 0x24, + 0xe1, 0xa5, 0x91, 0xee, 0xfd, 0x5a, 0x01, 0x8d, 0x7e, 0xca, 0x13, 0x2e, 0x50, 0xe4, 0x91, 0x90, + 0x0a, 0x49, 0xd2, 0x3e, 0xe7, 0x11, 0x6c, 0x80, 0xb2, 0xa4, 0x32, 0x22, 0xb6, 0xd5, 0xb2, 0xda, + 0x35, 0xcf, 0x2c, 0x60, 0x0b, 0xd4, 0x31, 0x11, 0x41, 0x4a, 0x13, 0x75, 0x72, 0xfb, 0x3d, 0x1d, + 0x9b, 0xde, 0x82, 0x8f, 0x41, 0x35, 0x18, 0x21, 0xca, 0x7c, 0x8a, 0xed, 0x65, 0x1d, 0xae, 0xe8, + 0x75, 0x0f, 0x2b, 0x24, 0x26, 0x8c, 0xc7, 0x76, 0xc9, 0x20, 0xf5, 0x02, 0x7e, 0x00, 0x56, 0x19, + 0x92, 0xf4, 0x9c, 0xf8, 0x26, 0x58, 0x36, 0x4c, 0xb3, 0xd7, 0xd5, 0x92, 0x27, 0x60, 0x2d, 0xe0, + 0x8c, 0x91, 0x40, 0x55, 0x50, 0xe0, 0x15, 0xad, 0x59, 0x9d, 0x6c, 0xf6, 0x30, 0x74, 0x00, 0x38, + 0x47, 0x11, 0xc5, 0x48, 0xf2, 0x54, 0xd8, 0x95, 0xd6, 0x72, 0xbb, 0xe6, 0x4d, 0xed, 0xc0, 0xef, + 0x01, 0x8c, 0x29, 0xf3, 0x31, 0x49, 0xb8, 0xa0, 0xd2, 0x47, 0x31, 0xcf, 0x98, 0xb4, 0xab, 0x8a, + 0x74, 0xec, 0xbe, 0x7a, 0xd3, 0x5c, 0xfa, 0xe3, 0x4d, 0xf3, 0xa3, 0x90, 0xca, 0x51, 0x36, 0x70, + 0x03, 0x1e, 0x77, 0x02, 0x2e, 0x62, 0x2e, 0xf2, 0x3f, 0xfb, 0x02, 0x9f, 0x75, 0xe4, 0x65, 0x42, + 0x84, 0xdb, 0x63, 0xd2, 0xdb, 0x88, 0x29, 0xeb, 0x1a, 0xd0, 0x91, 0xe6, 0xc0, 0xaf, 0xc0, 0xda, + 0x4c, 0x27, 0xec, 0x5a, 0xcb, 0x6a, 0xd7, 0x0f, 0xf6, 0xdc, 0x79, 0x13, 0xe2, 0x76, 0x53, 0x74, + 0x71, 0x9a, 0x2b, 0x8f, 0x4b, 0xaa, 0xb8, 0xb7, 0x8a, 0xa7, 0xf6, 0x60, 0x1f, 0xac, 0xcf, 0xb6, + 0xcb, 0x06, 0x9a, 0xf7, 0x64, 0x3e, 0xaf, 0xaf, 0xb4, 0xa7, 0xb9, 0x34, 0x07, 0xae, 0x25, 0xd3, + 0x9b, 0xf0, 0x10, 0x6c, 0x0f, 0x48, 0x30, 0x3a, 0x3c, 0xf0, 0x93, 0x94, 0x0c, 0xe9, 0xd8, 0x47, + 0x41, 0xe0, 0x23, 0x8c, 0x53, 0xbb, 0xae, 0x2f, 0x73, 0xcb, 0x44, 0xfb, 0x3a, 0x78, 0x14, 0x04, + 0x47, 0x18, 0xa7, 0xb7, 0x93, 0xce, 0x51, 0x64, 0x92, 0x56, 0x6f, 0x27, 0x7d, 0x83, 0x22, 0x9d, + 0xe4, 0x82, 0x2d, 0x99, 0x22, 0x26, 0x86, 0x24, 0xf5, 0x83, 0x11, 0x62, 0x8c, 0x44, 0xaa, 0x67, + 0x6b, 0x3a, 0x63, 0xb3, 0x08, 0x9d, 0x98, 0x48, 0x0f, 0x43, 0x0f, 0xc0, 0x8c, 0x0d, 0x38, 0xc3, + 0x94, 0x85, 0x7e, 0x61, 0x0a, 0x7b, 0x5d, 0x3f, 0xef, 0x63, 0xd7, 0xb8, 0xc6, 0x2d, 0x5c, 0xe3, + 0x76, 0x73, 0xc1, 0x71, 0x55, 0x3d, 0xe5, 0xcb, 0x3f, 0x9b, 0x96, 0xb7, 0x79, 0x93, 0x5e, 0x04, + 0xe1, 0x00, 0x3c, 0x8a, 0xd1, 0xd8, 0x9f, 0x70, 0x09, 0x93, 0x29, 0x25, 0xc2, 0x7e, 0xff, 0x41, + 0xfd, 0xde, 0x8a, 0xd1, 0xf8, 0x79, 0xc1, 0x7a, 0x6a, 0x50, 0xf0, 0x33, 0x50, 0x53, 0xee, 0xf4, + 0x95, 0xcc, 0xde, 0x68, 0x59, 0xed, 0xf5, 0x03, 0xe7, 0x8e, 0xf6, 0x70, 0x1e, 0x3d, 0xbb, 0x4c, + 0x88, 0x57, 0x4d, 0xf2, 0x5f, 0xf0, 0x04, 0x80, 0x21, 0x21, 0xbe, 0x44, 0x67, 0x24, 0x15, 0xf6, + 0x66, 0x6b, 0xb9, 0x5d, 0xbf, 0x2b, 0xfb, 0x73, 0x42, 0x9e, 0x29, 0x59, 0xde, 0xd7, 0xda, 0x30, + 0x5f, 0x8b, 0x4f, 0x4b, 0x2f, 0x7f, 0x69, 0x2e, 0xed, 0xfd, 0x56, 0x06, 0xb0, 0xb0, 0xf0, 0xf3, + 0x04, 0x23, 0x49, 0xde, 0xca, 0xc0, 0x3b, 0xa0, 0xa2, 0x1f, 0x2b, 0xf7, 0x6f, 0xc9, 0x5b, 0x51, + 0xcb, 0x1e, 0x86, 0x1f, 0xce, 0x18, 0xac, 0xa4, 0x0c, 0xa6, 0x8f, 0x64, 0xdd, 0xc3, 0x66, 0xe5, + 0x9b, 0x6b, 0xb7, 0xde, 0xad, 0xcd, 0x56, 0x16, 0xb2, 0x99, 0xf5, 0x9f, 0x36, 0xab, 0x2c, 0x66, + 0x33, 0xeb, 0xdf, 0x36, 0xfb, 0x04, 0x94, 0x85, 0x44, 0x92, 0xe8, 0x7f, 0x2c, 0xeb, 0x07, 0xcd, + 0xbb, 0x07, 0xe2, 0x54, 0xc9, 0x3c, 0xa3, 0xbe, 0xc3, 0x03, 0xb5, 0xfb, 0x78, 0xc0, 0x5a, 0xd8, + 0x03, 0xe0, 0x41, 0xcd, 0x98, 0xeb, 0x81, 0xd9, 0x31, 0xae, 0xbf, 0xcd, 0x18, 0xff, 0x00, 0x36, + 0x8b, 0x29, 0x3e, 0x89, 0xb8, 0xf8, 0x7f, 0x86, 0x38, 0xaf, 0xf5, 0x77, 0x79, 0xf2, 0xd6, 0xcb, + 0x2d, 0x83, 0x52, 0x14, 0x8b, 0x07, 0xd7, 0x9b, 0x3f, 0xf5, 0xcb, 0xef, 0x68, 0xea, 0xcf, 0xc0, + 0xae, 0xea, 0xe4, 0xec, 0xa8, 0xfa, 0x03, 0x24, 0x83, 0x11, 0x11, 0xe6, 0x6d, 0xba, 0x70, 0x95, + 0x9d, 0x18, 0x8d, 0x67, 0xe7, 0xd9, 0xe0, 0x60, 0x08, 0xec, 0x49, 0x31, 0x5d, 0xc3, 0xff, 0x31, + 0x43, 0x4c, 0x52, 0x79, 0xf9, 0x40, 0x1b, 0x3f, 0x2a, 0x4a, 0xe9, 0x12, 0x5f, 0xe7, 0x30, 0xf8, + 0x02, 0xec, 0xe8, 0x3b, 0x9b, 0xf6, 0xb3, 0x8f, 0x49, 0x24, 0x51, 0xee, 0xea, 0x7b, 0x0d, 0x7e, + 0x43, 0xdd, 0xd6, 0x94, 0xa7, 0xbb, 0x0a, 0xa0, 0xd9, 0x68, 0x3c, 0x97, 0x5d, 0x59, 0x84, 0x8d, + 0xc6, 0xb7, 0xd9, 0xdf, 0x81, 0x6d, 0x73, 0x39, 0x64, 0x9c, 0x50, 0x93, 0x93, 0xa3, 0xab, 0x0b, + 0xa0, 0x35, 0xe2, 0xe9, 0x0d, 0xc1, 0xa0, 0xbf, 0x05, 0xdb, 0xd3, 0x63, 0xa4, 0x8f, 0x6f, 0xd0, + 0xe0, 0xfe, 0xe8, 0xad, 0xc9, 0xfc, 0xa8, 0xc3, 0x6b, 0xb2, 0x99, 0xfb, 0x2f, 0x4b, 0xd5, 0xda, + 0x06, 0x38, 0xfe, 0xe2, 0xd5, 0x95, 0x63, 0xbd, 0xbe, 0x72, 0xac, 0xbf, 0xae, 0x1c, 0xeb, 0xe7, + 0x6b, 0x67, 0xe9, 0xf5, 0xb5, 0xb3, 0xf4, 0xfb, 0xb5, 0xb3, 0xf4, 0x62, 0x7f, 0xaa, 0xa3, 0x51, + 0x16, 0xef, 0x17, 0xdf, 0x90, 0xfa, 0x0b, 0xae, 0x33, 0x9e, 0x7c, 0x4b, 0xea, 0xe6, 0x0e, 0x56, + 0xf4, 0x31, 0x0e, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x7a, 0x9b, 0x23, 0x27, 0x0b, 0x00, + 0x00, } func (m *ProposalRegisterPool) Marshal() (dAtA []byte, err error) { @@ -747,6 +808,48 @@ func (m *ProposalUpdatePool) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ProposalClosePool) 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 *ProposalClosePool) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProposalClosePool) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PoolId != 0 { + i = encodeVarintGov(dAtA, i, uint64(m.PoolId)) + i-- + dAtA[i] = 0x18 + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintGov(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintGov(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ProposalUpdateParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -996,6 +1099,26 @@ func (m *ProposalUpdatePool) Size() (n int) { return n } +func (m *ProposalClosePool) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + if m.PoolId != 0 { + n += 1 + sovGov(uint64(m.PoolId)) + } + return n +} + func (m *ProposalUpdateParams) Size() (n int) { if m == nil { return 0 @@ -2035,6 +2158,139 @@ func (m *ProposalUpdatePool) Unmarshal(dAtA []byte) error { } return nil } +func (m *ProposalClosePool) 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 ErrIntOverflowGov + } + 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: ProposalClosePool: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProposalClosePool: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PoolId", wireType) + } + m.PoolId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PoolId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGov(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGov + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ProposalUpdateParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/millions/types/keys.go b/x/millions/types/keys.go index 8e7bab32..f3578bdc 100644 --- a/x/millions/types/keys.go +++ b/x/millions/types/keys.go @@ -24,7 +24,8 @@ const ( ) const ( - IBCTimeoutNanos = 1_800_000_000_000 // 30 minutes + IBCTimeoutNanos = 1_800_000_000_000 // 30 minutes + IBCForceRetryNanos = 259_200_000_000_000 // 3 days ) const ( diff --git a/x/millions/types/pool.pb.go b/x/millions/types/pool.pb.go index 881eb256..020dff28 100644 --- a/x/millions/types/pool.pb.go +++ b/x/millions/types/pool.pb.go @@ -46,7 +46,8 @@ const ( PoolState_Created PoolState = 1 PoolState_Ready PoolState = 2 PoolState_Paused PoolState = 3 - PoolState_Killed PoolState = 4 + PoolState_Closing PoolState = 4 + PoolState_Closed PoolState = 5 ) var PoolState_name = map[int32]string{ @@ -54,7 +55,8 @@ var PoolState_name = map[int32]string{ 1: "POOL_STATE_CREATED", 2: "POOL_STATE_READY", 3: "POOL_STATE_PAUSED", - 4: "POOL_STATE_KILLED", + 4: "POOL_STATE_CLOSING", + 5: "POOL_STATE_CLOSED", } var PoolState_value = map[string]int32{ @@ -62,7 +64,8 @@ var PoolState_value = map[string]int32{ "POOL_STATE_CREATED": 1, "POOL_STATE_READY": 2, "POOL_STATE_PAUSED": 3, - "POOL_STATE_KILLED": 4, + "POOL_STATE_CLOSING": 4, + "POOL_STATE_CLOSED": 5, } func (x PoolState) String() string { @@ -522,99 +525,100 @@ func init() { func init() { proto.RegisterFile("lum/network/millions/pool.proto", fileDescriptor_c1401529e8cac8ff) } var fileDescriptor_c1401529e8cac8ff = []byte{ - // 1468 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4d, 0x6f, 0xdb, 0x46, - 0x1a, 0x36, 0x63, 0xd9, 0x96, 0xc6, 0x92, 0x4d, 0x8f, 0x3f, 0x42, 0x2b, 0x1b, 0x89, 0xb1, 0x17, - 0x0b, 0xc7, 0xbb, 0x96, 0x90, 0x04, 0xbb, 0x97, 0x45, 0x51, 0xc8, 0x12, 0x9d, 0x28, 0x96, 0x63, - 0x95, 0x92, 0x03, 0xa4, 0x68, 0xc1, 0x8e, 0xc8, 0xb1, 0x34, 0x30, 0xc5, 0x11, 0xc8, 0x91, 0x63, - 0xf7, 0x17, 0x04, 0x3e, 0xe5, 0xd8, 0x8b, 0x4f, 0xbd, 0xf6, 0xd8, 0x1f, 0x11, 0xf4, 0x14, 0xf4, - 0x54, 0xf4, 0x90, 0x16, 0x49, 0x7f, 0x48, 0x31, 0x1f, 0x94, 0xe4, 0xaf, 0x38, 0xf1, 0x89, 0x9c, - 0xf7, 0x7d, 0xde, 0x67, 0xde, 0xcf, 0x99, 0x01, 0x79, 0xbf, 0xdf, 0x2d, 0x06, 0x98, 0xbd, 0xa4, - 0xe1, 0x41, 0xb1, 0x4b, 0x7c, 0x9f, 0xd0, 0x20, 0x2a, 0xf6, 0x28, 0xf5, 0x0b, 0xbd, 0x90, 0x32, - 0x0a, 0x17, 0xfc, 0x7e, 0xb7, 0xa0, 0x00, 0x85, 0x18, 0x90, 0x5d, 0x68, 0xd3, 0x36, 0x15, 0x80, - 0x22, 0xff, 0x93, 0xd8, 0x6c, 0xae, 0x4d, 0x69, 0xdb, 0xc7, 0x45, 0xb1, 0x6a, 0xf5, 0xf7, 0x8b, - 0x5e, 0x3f, 0x44, 0x8c, 0xd0, 0x40, 0xe9, 0xf3, 0xe7, 0xf5, 0x8c, 0x74, 0x71, 0xc4, 0x50, 0xb7, - 0x17, 0x13, 0xb8, 0x34, 0xea, 0xd2, 0xa8, 0xd8, 0x42, 0x11, 0x2e, 0x1e, 0x3e, 0x68, 0x61, 0x86, - 0x1e, 0x14, 0x5d, 0x4a, 0x62, 0x82, 0x65, 0xa9, 0x77, 0xe4, 0xce, 0x72, 0x11, 0x73, 0x5f, 0x1a, - 0x88, 0x17, 0xa2, 0x97, 0x0a, 0xb0, 0x76, 0x25, 0xc0, 0x89, 0xdc, 0x0e, 0xf6, 0xfa, 0x3e, 0x56, - 0xc8, 0xfb, 0x97, 0xe7, 0x24, 0x24, 0xdf, 0x63, 0x27, 0x62, 0x21, 0x62, 0xb8, 0x7d, 0x2c, 0xa1, - 0x2b, 0x3f, 0x69, 0x20, 0xb9, 0x85, 0x71, 0x13, 0x1d, 0xe0, 0x10, 0x9a, 0x60, 0xda, 0xc3, 0x11, - 0x23, 0x81, 0x88, 0xd9, 0xd0, 0x4c, 0x6d, 0x2d, 0x65, 0x8f, 0x8a, 0xe0, 0x16, 0x98, 0x44, 0x5d, - 0xda, 0x0f, 0x98, 0x71, 0x8b, 0x2b, 0x37, 0x0b, 0x6f, 0xde, 0xe5, 0xc7, 0x7e, 0x7f, 0x97, 0xff, - 0x57, 0x9b, 0xb0, 0x4e, 0xbf, 0x55, 0x70, 0x69, 0x57, 0x45, 0xa5, 0x3e, 0x1b, 0x91, 0x77, 0x50, - 0x64, 0xc7, 0x3d, 0x1c, 0x15, 0x2a, 0xd8, 0xb5, 0x95, 0x35, 0xfc, 0x1f, 0x48, 0x70, 0xa1, 0x31, - 0x6e, 0x6a, 0x6b, 0x33, 0x0f, 0x57, 0x0a, 0x97, 0xd5, 0xa8, 0x10, 0xfb, 0xd5, 0x3c, 0xee, 0x61, - 0x5b, 0xe0, 0x57, 0x5e, 0xe9, 0x20, 0x51, 0xa7, 0xd4, 0x87, 0xb7, 0xc1, 0x14, 0xaf, 0xb1, 0x43, - 0x3c, 0xe1, 0x66, 0xc2, 0x9e, 0xe4, 0xcb, 0xaa, 0x07, 0x17, 0xc0, 0x84, 0x87, 0x03, 0xda, 0x95, - 0x0e, 0xda, 0x72, 0x01, 0xef, 0x81, 0x34, 0x8f, 0xe0, 0x10, 0x3b, 0x52, 0x39, 0x2e, 0x43, 0x93, - 0xb2, 0x8a, 0x80, 0x2c, 0x83, 0xa4, 0xdb, 0x41, 0x24, 0xe0, 0x94, 0x09, 0xa1, 0x9e, 0x12, 0xeb, - 0xaa, 0x07, 0x57, 0x41, 0xc6, 0xa5, 0x41, 0x80, 0x5d, 0x9e, 0x03, 0xae, 0x9f, 0x10, 0xfa, 0xf4, - 0x50, 0x58, 0xf5, 0x60, 0x01, 0xcc, 0xb3, 0x10, 0x05, 0xd1, 0x3e, 0x0e, 0x1d, 0xb7, 0x83, 0x82, - 0x00, 0x0b, 0xef, 0x26, 0x05, 0x74, 0x2e, 0x56, 0x95, 0xa5, 0xa6, 0xea, 0xc1, 0x0d, 0x30, 0x4f, - 0x5c, 0xe4, 0x78, 0xb8, 0x47, 0x23, 0xc2, 0x9c, 0x1e, 0x0d, 0x19, 0xc7, 0x4f, 0x09, 0xbc, 0x4e, - 0x5c, 0x54, 0x91, 0x9a, 0x3a, 0x0d, 0x59, 0xd5, 0x83, 0x0f, 0xc0, 0x22, 0x87, 0x8b, 0x22, 0x8a, - 0xc8, 0x63, 0x83, 0xa4, 0x30, 0x80, 0xc4, 0x45, 0xf5, 0x58, 0xa7, 0x4c, 0xfe, 0x0f, 0x52, 0x02, - 0x29, 0x32, 0x9d, 0x12, 0x99, 0xce, 0x5d, 0x9e, 0x69, 0x9e, 0x52, 0x91, 0xe5, 0x64, 0x4f, 0xfd, - 0xc1, 0x2a, 0x00, 0x87, 0xc8, 0x27, 0x1e, 0x62, 0x34, 0x8c, 0x0c, 0x60, 0x8e, 0xaf, 0x4d, 0x3f, - 0x5c, 0xbd, 0xda, 0xfa, 0x79, 0x8c, 0xdd, 0x4c, 0xf0, 0x96, 0xb0, 0x47, 0x8c, 0xe1, 0x23, 0xb0, - 0xd4, 0xc2, 0x6e, 0xe7, 0xd1, 0x43, 0xa7, 0x17, 0xe2, 0x7d, 0x72, 0xe4, 0x20, 0xd7, 0x75, 0x90, - 0xe7, 0x85, 0xc6, 0xb4, 0xf0, 0x7d, 0x5e, 0x6a, 0xeb, 0x42, 0x59, 0x72, 0xdd, 0x92, 0xe7, 0x85, - 0x17, 0x8d, 0x0e, 0x91, 0x2f, 0x8d, 0xd2, 0x17, 0x8d, 0x9e, 0x23, 0x5f, 0x18, 0x7d, 0x03, 0x60, - 0x97, 0x04, 0x83, 0x9c, 0xaa, 0x56, 0xcd, 0x7c, 0x76, 0xab, 0x56, 0x03, 0x66, 0xeb, 0x5d, 0x12, - 0xa8, 0x12, 0x94, 0x64, 0xd3, 0xee, 0x80, 0xcc, 0x99, 0x69, 0x33, 0x66, 0x4c, 0x6d, 0x6d, 0xfa, - 0xaa, 0xee, 0xad, 0x84, 0xe8, 0x65, 0x43, 0x21, 0x55, 0x52, 0xd2, 0xde, 0x88, 0x0c, 0xd6, 0xc1, - 0xcc, 0xd9, 0x91, 0x34, 0x66, 0x05, 0xdf, 0x55, 0x59, 0xe6, 0xd8, 0x86, 0x82, 0x2a, 0xc2, 0x4c, - 0x6f, 0x54, 0x08, 0x6d, 0x00, 0xfb, 0x41, 0x8b, 0x06, 0x1e, 0x09, 0xda, 0x4e, 0x7c, 0x74, 0x19, - 0xba, 0x60, 0x5d, 0x2e, 0xc8, 0xb3, 0xab, 0x10, 0x9f, 0x5d, 0x85, 0x8a, 0x02, 0x6c, 0x26, 0x39, - 0xd7, 0x0f, 0x7f, 0xe4, 0x35, 0x7b, 0x6e, 0x60, 0x1e, 0x2b, 0x61, 0x0b, 0x2c, 0x76, 0xd1, 0x91, - 0x33, 0xe4, 0xc5, 0x01, 0x0b, 0x09, 0x8e, 0x8c, 0xb9, 0x1b, 0x65, 0x75, 0xbe, 0x8b, 0x8e, 0xf6, - 0x62, 0x2e, 0x4b, 0x52, 0xc1, 0x2f, 0x40, 0xc6, 0xa7, 0xae, 0xaa, 0x2f, 0x8e, 0x22, 0x03, 0x0a, - 0x6e, 0xe3, 0xd7, 0x9f, 0x37, 0x16, 0xd4, 0x19, 0x59, 0x92, 0x9a, 0x06, 0x0b, 0x49, 0xd0, 0xb6, - 0xd3, 0x02, 0xae, 0x64, 0xf0, 0xc9, 0xd9, 0x49, 0x8a, 0x49, 0xe6, 0xaf, 0x21, 0x99, 0x1b, 0xce, - 0x58, 0xcc, 0x54, 0x3b, 0x3f, 0x64, 0x31, 0xd7, 0xc2, 0x35, 0x5c, 0xf3, 0xa3, 0xe3, 0x17, 0xb3, - 0x99, 0x20, 0x1d, 0xe0, 0x23, 0xe6, 0x88, 0xa6, 0x21, 0x9e, 0xb1, 0x24, 0x0e, 0x2a, 0xc0, 0x65, - 0xbc, 0x39, 0xaa, 0x1e, 0xdc, 0x01, 0x80, 0x1d, 0xfa, 0x71, 0x9f, 0xde, 0xbe, 0x51, 0x46, 0x53, - 0xec, 0xd0, 0x57, 0x0d, 0x7a, 0x1f, 0xe8, 0x2a, 0x09, 0x34, 0x8c, 0x1c, 0x57, 0x90, 0x1a, 0x62, - 0xd3, 0xd9, 0xa1, 0xbc, 0x2c, 0xa0, 0xdf, 0x02, 0x18, 0xf5, 0x68, 0x10, 0xd1, 0x30, 0xea, 0x90, - 0x5e, 0xec, 0xc1, 0xf2, 0x8d, 0x3c, 0x98, 0x1b, 0x61, 0x52, 0x9e, 0xec, 0x81, 0x05, 0x1f, 0x45, - 0x2a, 0x74, 0x37, 0xc4, 0x88, 0x61, 0xcf, 0x41, 0xcc, 0xb8, 0x23, 0x7a, 0x31, 0x7b, 0xa1, 0x17, - 0x9b, 0xf1, 0x3d, 0x2a, 0x9a, 0x51, 0x7b, 0x2d, 0x9a, 0x91, 0x33, 0xf0, 0x44, 0x95, 0xa5, 0x7d, - 0x89, 0xc1, 0xc7, 0x60, 0x76, 0x48, 0x1b, 0x31, 0xc4, 0xb0, 0xf1, 0x0f, 0x71, 0xae, 0xe5, 0x3f, - 0x32, 0x83, 0x1c, 0x66, 0x67, 0x62, 0x32, 0xb1, 0x84, 0x5f, 0x81, 0x05, 0x74, 0x88, 0x88, 0x8f, - 0x5a, 0x3e, 0x96, 0xe5, 0x76, 0x78, 0xe5, 0x8c, 0xbb, 0x6a, 0x56, 0x54, 0x91, 0xf9, 0x35, 0x5e, - 0x50, 0xd7, 0x78, 0xa1, 0x4c, 0x49, 0xa0, 0xe6, 0x0e, 0x0e, 0x8c, 0x45, 0xd1, 0xc5, 0x8d, 0x54, - 0x06, 0x60, 0x1f, 0x63, 0x87, 0xf1, 0x1b, 0x2b, 0x32, 0x72, 0xe2, 0xc0, 0xcc, 0x7d, 0xfc, 0x62, - 0x53, 0x6c, 0xa9, 0x7d, 0xb5, 0x8e, 0xe0, 0x7f, 0xc1, 0x84, 0x0c, 0xcb, 0xfc, 0x58, 0x58, 0x7c, - 0x3f, 0x19, 0x96, 0x44, 0xc3, 0x75, 0x30, 0x37, 0x4c, 0xb2, 0xd3, 0xc1, 0xa4, 0xdd, 0x61, 0xc6, - 0x3d, 0x53, 0x5b, 0x1b, 0xb7, 0x67, 0xdd, 0x38, 0x7b, 0x4f, 0x84, 0x98, 0x63, 0xfb, 0x3d, 0xef, - 0x1c, 0x76, 0x45, 0x62, 0x95, 0x62, 0x80, 0x2d, 0x03, 0x30, 0x52, 0xbc, 0xd5, 0x4f, 0x2a, 0xde, - 0x98, 0x28, 0x5e, 0x6a, 0xb0, 0x2d, 0x27, 0x19, 0x6e, 0x68, 0xfc, 0xf3, 0x73, 0x48, 0x06, 0xfe, - 0x3c, 0x4d, 0x24, 0x17, 0xf5, 0xa5, 0xa7, 0x89, 0x64, 0x56, 0xbf, 0xf3, 0x34, 0x91, 0xcc, 0xeb, - 0xe6, 0xca, 0x1b, 0x0d, 0x64, 0xce, 0xdc, 0x3c, 0xb0, 0x0c, 0x74, 0xda, 0xc3, 0x21, 0xff, 0x1f, - 0x0c, 0xae, 0x76, 0xcd, 0xe0, 0xce, 0xc6, 0x16, 0xf1, 0xd0, 0xde, 0x05, 0x80, 0x44, 0x0e, 0x0e, - 0x78, 0x71, 0x3d, 0xf1, 0x88, 0x48, 0xda, 0x29, 0x12, 0x59, 0x52, 0x00, 0x1b, 0x20, 0xc3, 0x0f, - 0x2f, 0x1e, 0x8b, 0x1c, 0x99, 0xf1, 0x1b, 0x8d, 0x4c, 0x5a, 0x92, 0xc8, 0x69, 0x59, 0xff, 0x45, - 0x03, 0xa9, 0x41, 0x4d, 0xe1, 0xbf, 0xc1, 0x52, 0x7d, 0x77, 0xb7, 0xe6, 0x34, 0x9a, 0xa5, 0xa6, - 0xe5, 0xec, 0x3d, 0x6b, 0xd4, 0xad, 0x72, 0x75, 0xab, 0x6a, 0x55, 0xf4, 0xb1, 0xec, 0xec, 0xc9, - 0xa9, 0x39, 0xbd, 0x17, 0x44, 0x3d, 0xec, 0x92, 0x7d, 0x82, 0xf9, 0xd3, 0x04, 0x8e, 0x80, 0xcb, - 0xb6, 0x55, 0x6a, 0x5a, 0x15, 0x5d, 0xcb, 0x4e, 0x9f, 0x9c, 0x9a, 0x53, 0x6a, 0x70, 0x60, 0x1e, - 0xe8, 0x23, 0x20, 0xdb, 0x2a, 0x55, 0x5e, 0xe8, 0xb7, 0xb2, 0xa9, 0x93, 0x53, 0x73, 0xc2, 0xc6, - 0xc8, 0x3b, 0x86, 0xf7, 0xc0, 0xdc, 0x08, 0xa0, 0x5e, 0xda, 0x6b, 0x58, 0x15, 0x7d, 0x3c, 0x0b, - 0x4e, 0x4e, 0xcd, 0xc9, 0x3a, 0xea, 0x47, 0xd8, 0x3b, 0x07, 0xd9, 0xae, 0xd6, 0x6a, 0x56, 0x45, - 0x4f, 0x48, 0xc8, 0x36, 0xf1, 0x7d, 0xec, 0x65, 0x13, 0xaf, 0x7e, 0xcc, 0x69, 0xeb, 0xdf, 0x81, - 0x64, 0xfc, 0x9c, 0x80, 0xeb, 0x60, 0x51, 0x18, 0x35, 0x5f, 0xd4, 0xaf, 0x8d, 0x64, 0x45, 0x6d, - 0x20, 0xb0, 0x8d, 0x66, 0x69, 0xbb, 0xfa, 0xec, 0x71, 0x1c, 0x48, 0x83, 0xa1, 0x03, 0x12, 0xb4, - 0xd5, 0x0e, 0x7f, 0x69, 0x20, 0x3d, 0xfa, 0x36, 0x84, 0x45, 0x90, 0xdd, 0xb2, 0x2c, 0xa7, 0x59, - 0xda, 0xb6, 0xec, 0x4f, 0xda, 0xeb, 0x3f, 0x60, 0xf9, 0x9c, 0x41, 0x6d, 0xb7, 0x5c, 0xaa, 0x39, - 0xa5, 0x4a, 0xc5, 0xd6, 0xb5, 0x6c, 0xe6, 0xe4, 0xd4, 0x4c, 0xd5, 0xe2, 0x2b, 0x06, 0x7e, 0x09, - 0x56, 0x2f, 0x45, 0xef, 0xec, 0x56, 0xf6, 0x6a, 0x96, 0x53, 0x2a, 0x97, 0x77, 0xf7, 0x9e, 0x35, - 0xf5, 0x5b, 0xd9, 0xa5, 0x93, 0x53, 0x13, 0x0a, 0xbb, 0x1d, 0xca, 0xaf, 0xf8, 0x92, 0x2b, 0xce, - 0x60, 0x58, 0xb8, 0xe0, 0x9f, 0x6d, 0xed, 0xec, 0x36, 0x2d, 0xb9, 0xdf, 0x78, 0x76, 0xe6, 0xe4, - 0xd4, 0x04, 0x36, 0xee, 0x52, 0x86, 0xf9, 0x86, 0x32, 0xcc, 0xcd, 0xc7, 0x6f, 0xde, 0xe7, 0xb4, - 0xb7, 0xef, 0x73, 0xda, 0x9f, 0xef, 0x73, 0xda, 0xeb, 0x0f, 0xb9, 0xb1, 0xb7, 0x1f, 0x72, 0x63, - 0xbf, 0x7d, 0xc8, 0x8d, 0x7d, 0xbd, 0x31, 0xd2, 0x65, 0x7e, 0xbf, 0xbb, 0x11, 0x3f, 0xf5, 0xc5, - 0x7b, 0xb5, 0x78, 0x34, 0x7c, 0xf2, 0x8b, 0x86, 0x6b, 0x4d, 0x8a, 0x21, 0x7b, 0xf4, 0x77, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xf3, 0xe3, 0x56, 0x3f, 0x2b, 0x0d, 0x00, 0x00, + // 1479 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4d, 0x4f, 0x1b, 0x49, + 0x1a, 0xa6, 0x83, 0x01, 0xbb, 0xb0, 0xa1, 0x29, 0x3e, 0xd2, 0x38, 0x1b, 0xbb, 0x03, 0xab, 0x15, + 0x61, 0x17, 0x5b, 0x49, 0xb4, 0x7b, 0x59, 0xad, 0x56, 0xc6, 0x6e, 0x12, 0x27, 0x10, 0xbc, 0x6d, + 0x13, 0x29, 0xab, 0x19, 0xf5, 0x94, 0xbb, 0x0b, 0xbb, 0x44, 0xbb, 0xab, 0xd5, 0x5d, 0x26, 0x30, + 0xbf, 0x20, 0xe2, 0x94, 0xe3, 0x5c, 0x38, 0xcd, 0x75, 0x8e, 0xf3, 0x23, 0x72, 0x8c, 0xe6, 0x34, + 0x9a, 0x43, 0x66, 0x94, 0xcc, 0x7d, 0xfe, 0xc2, 0xa8, 0x3e, 0xda, 0x36, 0x5f, 0x21, 0xe1, 0xe4, + 0xae, 0x7a, 0x9f, 0xf7, 0x79, 0xbf, 0xab, 0xca, 0xa0, 0xe8, 0xf7, 0x7b, 0xe5, 0x00, 0xb3, 0x57, + 0x34, 0x3a, 0x28, 0xf7, 0x88, 0xef, 0x13, 0x1a, 0xc4, 0xe5, 0x90, 0x52, 0xbf, 0x14, 0x46, 0x94, + 0x51, 0xb8, 0xe0, 0xf7, 0x7b, 0x25, 0x05, 0x28, 0x25, 0x80, 0xfc, 0x42, 0x87, 0x76, 0xa8, 0x00, + 0x94, 0xf9, 0x97, 0xc4, 0xe6, 0x0b, 0x1d, 0x4a, 0x3b, 0x3e, 0x2e, 0x8b, 0x55, 0xbb, 0xbf, 0x5f, + 0xf6, 0xfa, 0x11, 0x62, 0x84, 0x06, 0x4a, 0x5e, 0x3c, 0x2f, 0x67, 0xa4, 0x87, 0x63, 0x86, 0x7a, + 0x61, 0x42, 0xe0, 0xd2, 0xb8, 0x47, 0xe3, 0x72, 0x1b, 0xc5, 0xb8, 0x7c, 0xf8, 0xa0, 0x8d, 0x19, + 0x7a, 0x50, 0x76, 0x29, 0x49, 0x08, 0x96, 0xa5, 0xdc, 0x91, 0x96, 0xe5, 0x22, 0xe1, 0xbe, 0x34, + 0x10, 0x2f, 0x42, 0xaf, 0x14, 0x60, 0xed, 0x4a, 0x80, 0x13, 0xbb, 0x5d, 0xec, 0xf5, 0x7d, 0xac, + 0x90, 0xf7, 0x2f, 0xcf, 0x49, 0x44, 0xbe, 0xc5, 0x4e, 0xcc, 0x22, 0xc4, 0x70, 0xe7, 0x58, 0x42, + 0x57, 0x7e, 0xd0, 0x40, 0x7a, 0x0b, 0xe3, 0x16, 0x3a, 0xc0, 0x11, 0x34, 0xc1, 0xb4, 0x87, 0x63, + 0x46, 0x02, 0x11, 0xb3, 0xa1, 0x99, 0xda, 0x5a, 0xc6, 0x1e, 0xdd, 0x82, 0x5b, 0x60, 0x12, 0xf5, + 0x68, 0x3f, 0x60, 0xc6, 0x2d, 0x2e, 0xdc, 0x2c, 0xbd, 0x7d, 0x5f, 0x1c, 0xfb, 0xe5, 0x7d, 0xf1, + 0x6f, 0x1d, 0xc2, 0xba, 0xfd, 0x76, 0xc9, 0xa5, 0x3d, 0x15, 0x95, 0xfa, 0xd9, 0x88, 0xbd, 0x83, + 0x32, 0x3b, 0x0e, 0x71, 0x5c, 0xaa, 0x61, 0xd7, 0x56, 0xda, 0xf0, 0x5f, 0x20, 0xc5, 0x37, 0x8d, + 0x71, 0x53, 0x5b, 0x9b, 0x79, 0xb8, 0x52, 0xba, 0xac, 0x46, 0xa5, 0xc4, 0xaf, 0xd6, 0x71, 0x88, + 0x6d, 0x81, 0x5f, 0x79, 0xad, 0x83, 0x54, 0x83, 0x52, 0x1f, 0xde, 0x06, 0x53, 0xbc, 0xc6, 0x0e, + 0xf1, 0x84, 0x9b, 0x29, 0x7b, 0x92, 0x2f, 0xeb, 0x1e, 0x5c, 0x00, 0x13, 0x1e, 0x0e, 0x68, 0x4f, + 0x3a, 0x68, 0xcb, 0x05, 0xbc, 0x07, 0xb2, 0x3c, 0x82, 0x43, 0xec, 0x48, 0xe1, 0xb8, 0x0c, 0x4d, + 0xee, 0xd5, 0x04, 0x64, 0x19, 0xa4, 0xdd, 0x2e, 0x22, 0x01, 0xa7, 0x4c, 0x09, 0xf1, 0x94, 0x58, + 0xd7, 0x3d, 0xb8, 0x0a, 0x72, 0x2e, 0x0d, 0x02, 0xec, 0xf2, 0x1c, 0x70, 0xf9, 0x84, 0x90, 0x67, + 0x87, 0x9b, 0x75, 0x0f, 0x96, 0xc0, 0x3c, 0x8b, 0x50, 0x10, 0xef, 0xe3, 0xc8, 0x71, 0xbb, 0x28, + 0x08, 0xb0, 0xf0, 0x6e, 0x52, 0x40, 0xe7, 0x12, 0x51, 0x55, 0x4a, 0xea, 0x1e, 0xdc, 0x00, 0xf3, + 0xc4, 0x45, 0x8e, 0x87, 0x43, 0x1a, 0x13, 0xe6, 0x84, 0x34, 0x62, 0x1c, 0x3f, 0x25, 0xf0, 0x3a, + 0x71, 0x51, 0x4d, 0x4a, 0x1a, 0x34, 0x62, 0x75, 0x0f, 0x3e, 0x00, 0x8b, 0x1c, 0x2e, 0x8a, 0x28, + 0x22, 0x4f, 0x14, 0xd2, 0x42, 0x01, 0x12, 0x17, 0x35, 0x12, 0x99, 0x52, 0xf9, 0x37, 0xc8, 0x08, + 0xa4, 0xc8, 0x74, 0x46, 0x64, 0xba, 0x70, 0x79, 0xa6, 0x79, 0x4a, 0x45, 0x96, 0xd3, 0xa1, 0xfa, + 0x82, 0x75, 0x00, 0x0e, 0x91, 0x4f, 0x3c, 0xc4, 0x68, 0x14, 0x1b, 0xc0, 0x1c, 0x5f, 0x9b, 0x7e, + 0xb8, 0x7a, 0xb5, 0xf6, 0x8b, 0x04, 0xbb, 0x99, 0xe2, 0x2d, 0x61, 0x8f, 0x28, 0xc3, 0x47, 0x60, + 0xa9, 0x8d, 0xdd, 0xee, 0xa3, 0x87, 0x4e, 0x18, 0xe1, 0x7d, 0x72, 0xe4, 0x20, 0xd7, 0x75, 0x90, + 0xe7, 0x45, 0xc6, 0xb4, 0xf0, 0x7d, 0x5e, 0x4a, 0x1b, 0x42, 0x58, 0x71, 0xdd, 0x8a, 0xe7, 0x45, + 0x17, 0x95, 0x0e, 0x91, 0x2f, 0x95, 0xb2, 0x17, 0x95, 0x5e, 0x20, 0x5f, 0x28, 0x7d, 0x05, 0x60, + 0x8f, 0x04, 0x83, 0x9c, 0xaa, 0x56, 0xcd, 0x7d, 0x71, 0xab, 0xd6, 0x03, 0x66, 0xeb, 0x3d, 0x12, + 0xa8, 0x12, 0x54, 0x64, 0xd3, 0xee, 0x80, 0xdc, 0x99, 0x69, 0x33, 0x66, 0x4c, 0x6d, 0x6d, 0xfa, + 0xaa, 0xee, 0xad, 0x45, 0xe8, 0x55, 0x53, 0x21, 0x55, 0x52, 0xb2, 0xde, 0xc8, 0x1e, 0x6c, 0x80, + 0x99, 0xb3, 0x23, 0x69, 0xcc, 0x0a, 0xbe, 0xab, 0xb2, 0xcc, 0xb1, 0x4d, 0x05, 0x55, 0x84, 0xb9, + 0x70, 0x74, 0x13, 0xda, 0x00, 0xf6, 0x83, 0x36, 0x0d, 0x3c, 0x12, 0x74, 0x9c, 0xe4, 0xe8, 0x32, + 0x74, 0xc1, 0xba, 0x5c, 0x92, 0x67, 0x57, 0x29, 0x39, 0xbb, 0x4a, 0x35, 0x05, 0xd8, 0x4c, 0x73, + 0xae, 0xef, 0x7e, 0x2d, 0x6a, 0xf6, 0xdc, 0x40, 0x3d, 0x11, 0xc2, 0x36, 0x58, 0xec, 0xa1, 0x23, + 0x67, 0xc8, 0x8b, 0x03, 0x16, 0x11, 0x1c, 0x1b, 0x73, 0x37, 0xca, 0xea, 0x7c, 0x0f, 0x1d, 0xed, + 0x25, 0x5c, 0x96, 0xa4, 0x82, 0xff, 0x01, 0x39, 0x9f, 0xba, 0xaa, 0xbe, 0x38, 0x8e, 0x0d, 0x28, + 0xb8, 0x8d, 0x9f, 0x7e, 0xdc, 0x58, 0x50, 0x67, 0x64, 0x45, 0x4a, 0x9a, 0x2c, 0x22, 0x41, 0xc7, + 0xce, 0x0a, 0xb8, 0xda, 0x83, 0x4f, 0xce, 0x4e, 0x52, 0x42, 0x32, 0x7f, 0x0d, 0xc9, 0xdc, 0x70, + 0xc6, 0x12, 0xa6, 0xed, 0xf3, 0x43, 0x96, 0x70, 0x2d, 0x5c, 0xc3, 0x35, 0x3f, 0x3a, 0x7e, 0x09, + 0x9b, 0x09, 0xb2, 0x01, 0x3e, 0x62, 0x8e, 0x68, 0x1a, 0xe2, 0x19, 0x4b, 0xe2, 0xa0, 0x02, 0x7c, + 0x8f, 0x37, 0x47, 0xdd, 0x83, 0x3b, 0x00, 0xb0, 0x43, 0x3f, 0xe9, 0xd3, 0xdb, 0x37, 0xca, 0x68, + 0x86, 0x1d, 0xfa, 0xaa, 0x41, 0xef, 0x03, 0x5d, 0x25, 0x81, 0x46, 0xb1, 0xe3, 0x0a, 0x52, 0x43, + 0x18, 0x9d, 0x1d, 0xee, 0x57, 0x05, 0xf4, 0x6b, 0x00, 0xe3, 0x90, 0x06, 0x31, 0x8d, 0xe2, 0x2e, + 0x09, 0x13, 0x0f, 0x96, 0x6f, 0xe4, 0xc1, 0xdc, 0x08, 0x93, 0xf2, 0x64, 0x0f, 0x2c, 0xf8, 0x28, + 0x56, 0xa1, 0xbb, 0x11, 0x46, 0x0c, 0x7b, 0x0e, 0x62, 0xc6, 0x1d, 0xd1, 0x8b, 0xf9, 0x0b, 0xbd, + 0xd8, 0x4a, 0xee, 0x51, 0xd1, 0x8c, 0xda, 0x1b, 0xd1, 0x8c, 0x9c, 0x81, 0x27, 0xaa, 0x2a, 0xf5, + 0x2b, 0x0c, 0x3e, 0x06, 0xb3, 0x43, 0xda, 0x98, 0x21, 0x86, 0x8d, 0xbf, 0x88, 0x73, 0xad, 0xf8, + 0x89, 0x19, 0xe4, 0x30, 0x3b, 0x97, 0x90, 0x89, 0x25, 0xfc, 0x1f, 0x58, 0x40, 0x87, 0x88, 0xf8, + 0xa8, 0xed, 0x63, 0x59, 0x6e, 0x87, 0x57, 0xce, 0xb8, 0xab, 0x66, 0x45, 0x15, 0x99, 0x5f, 0xe3, + 0x25, 0x75, 0x8d, 0x97, 0xaa, 0x94, 0x04, 0x6a, 0xee, 0xe0, 0x40, 0x59, 0x14, 0x5d, 0xdc, 0x48, + 0x55, 0x00, 0xf6, 0x31, 0x76, 0x18, 0xbf, 0xb1, 0x62, 0xa3, 0x20, 0x0e, 0xcc, 0xc2, 0xa7, 0x2f, + 0x36, 0xc5, 0x96, 0xd9, 0x57, 0xeb, 0x18, 0xfe, 0x13, 0x4c, 0xc8, 0xb0, 0xcc, 0x4f, 0x85, 0xc5, + 0xed, 0xc9, 0xb0, 0x24, 0x1a, 0xae, 0x83, 0xb9, 0x61, 0x92, 0x9d, 0x2e, 0x26, 0x9d, 0x2e, 0x33, + 0xee, 0x99, 0xda, 0xda, 0xb8, 0x3d, 0xeb, 0x26, 0xd9, 0x7b, 0x22, 0xb6, 0x39, 0xb6, 0x1f, 0x7a, + 0xe7, 0xb0, 0x2b, 0x12, 0xab, 0x04, 0x03, 0x6c, 0x15, 0x80, 0x91, 0xe2, 0xad, 0x7e, 0x56, 0xf1, + 0xc6, 0x44, 0xf1, 0x32, 0x03, 0xb3, 0x9c, 0x64, 0x68, 0xd0, 0xf8, 0xeb, 0x97, 0x90, 0x0c, 0xfc, + 0x79, 0x9a, 0x4a, 0x2f, 0xea, 0x4b, 0x4f, 0x53, 0xe9, 0xbc, 0x7e, 0xe7, 0x69, 0x2a, 0x5d, 0xd4, + 0xcd, 0x95, 0xb7, 0x1a, 0xc8, 0x9d, 0xb9, 0x79, 0x60, 0x15, 0xe8, 0x34, 0xc4, 0x11, 0xff, 0x1e, + 0x0c, 0xae, 0x76, 0xcd, 0xe0, 0xce, 0x26, 0x1a, 0xc9, 0xd0, 0xde, 0x05, 0x80, 0xc4, 0x0e, 0x0e, + 0x78, 0x71, 0x3d, 0xf1, 0x88, 0x48, 0xdb, 0x19, 0x12, 0x5b, 0x72, 0x03, 0x36, 0x41, 0x8e, 0x1f, + 0x5e, 0x3c, 0x16, 0x39, 0x32, 0xe3, 0x37, 0x1a, 0x99, 0xac, 0x24, 0x91, 0xd3, 0xb2, 0xfe, 0x87, + 0x06, 0x32, 0x83, 0x9a, 0xc2, 0xbf, 0x83, 0xa5, 0xc6, 0xee, 0xee, 0xb6, 0xd3, 0x6c, 0x55, 0x5a, + 0x96, 0xb3, 0xf7, 0xbc, 0xd9, 0xb0, 0xaa, 0xf5, 0xad, 0xba, 0x55, 0xd3, 0xc7, 0xf2, 0xb3, 0x27, + 0xa7, 0xe6, 0xf4, 0x5e, 0x10, 0x87, 0xd8, 0x25, 0xfb, 0x04, 0xf3, 0xa7, 0x09, 0x1c, 0x01, 0x57, + 0x6d, 0xab, 0xd2, 0xb2, 0x6a, 0xba, 0x96, 0x9f, 0x3e, 0x39, 0x35, 0xa7, 0xd4, 0xe0, 0xc0, 0x22, + 0xd0, 0x47, 0x40, 0xb6, 0x55, 0xa9, 0xbd, 0xd4, 0x6f, 0xe5, 0x33, 0x27, 0xa7, 0xe6, 0x84, 0x8d, + 0x91, 0x77, 0x0c, 0xef, 0x81, 0xb9, 0x11, 0x40, 0xa3, 0xb2, 0xd7, 0xb4, 0x6a, 0xfa, 0x78, 0x1e, + 0x9c, 0x9c, 0x9a, 0x93, 0x0d, 0xd4, 0x8f, 0x2f, 0x1a, 0xda, 0xde, 0x6d, 0xd6, 0x9f, 0x3f, 0xd6, + 0x53, 0xca, 0x90, 0x4f, 0x63, 0x12, 0x74, 0xce, 0xf1, 0x70, 0x90, 0x55, 0xd3, 0x27, 0x24, 0x0f, + 0xc7, 0x60, 0x2f, 0x9f, 0x7a, 0xfd, 0x7d, 0x41, 0x5b, 0xff, 0x06, 0xa4, 0x93, 0x37, 0x07, 0x5c, + 0x07, 0x8b, 0x42, 0xa9, 0xf5, 0xb2, 0x71, 0x6d, 0xb8, 0x2b, 0xca, 0x80, 0xc0, 0x36, 0x5b, 0x95, + 0x67, 0xdc, 0x09, 0x15, 0x6d, 0x93, 0xa1, 0x03, 0x12, 0x74, 0x94, 0x85, 0xdf, 0x35, 0x90, 0x1d, + 0x7d, 0x40, 0xc2, 0x32, 0xc8, 0x6f, 0x59, 0x96, 0xd3, 0xaa, 0x3c, 0xb3, 0xec, 0xcf, 0xb2, 0xf5, + 0x0f, 0xb0, 0x7c, 0x4e, 0x61, 0x7b, 0xb7, 0x5a, 0xd9, 0x76, 0x2a, 0xb5, 0x9a, 0xad, 0x6b, 0xf9, + 0xdc, 0xc9, 0xa9, 0x99, 0xd9, 0x4e, 0xee, 0x21, 0xf8, 0x5f, 0xb0, 0x7a, 0x29, 0x7a, 0x67, 0xb7, + 0xb6, 0xb7, 0x6d, 0x39, 0x95, 0x6a, 0x75, 0x77, 0xef, 0x79, 0x4b, 0xbf, 0x95, 0x5f, 0x3a, 0x39, + 0x35, 0xa1, 0xd0, 0xdb, 0xa1, 0xfc, 0x1d, 0x50, 0x71, 0xc5, 0x41, 0x0d, 0x4b, 0x17, 0xfc, 0xb3, + 0xad, 0x9d, 0xdd, 0x96, 0x25, 0xed, 0x8d, 0xe7, 0x67, 0x4e, 0x4e, 0x4d, 0x60, 0xe3, 0x1e, 0x65, + 0x98, 0x1b, 0x94, 0x61, 0x6e, 0x3e, 0x7e, 0xfb, 0xa1, 0xa0, 0xbd, 0xfb, 0x50, 0xd0, 0x7e, 0xfb, + 0x50, 0xd0, 0xde, 0x7c, 0x2c, 0x8c, 0xbd, 0xfb, 0x58, 0x18, 0xfb, 0xf9, 0x63, 0x61, 0xec, 0xff, + 0x1b, 0x23, 0xad, 0xe8, 0xf7, 0x7b, 0x1b, 0xc9, 0xff, 0x01, 0xf1, 0xa8, 0x2d, 0x1f, 0x0d, 0xff, + 0x17, 0x88, 0xae, 0x6c, 0x4f, 0x8a, 0x49, 0x7c, 0xf4, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x23, + 0xc8, 0xba, 0xa1, 0x50, 0x0d, 0x00, 0x00, } func (m *FeeTaker) Marshal() (dAtA []byte, err error) { diff --git a/x/millions/types/proposal_close_pool.go b/x/millions/types/proposal_close_pool.go new file mode 100644 index 00000000..62613434 --- /dev/null +++ b/x/millions/types/proposal_close_pool.go @@ -0,0 +1,54 @@ +package types + +import ( + "fmt" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" +) + +const ( + ProposalTypeClosePool = "ClosePool" +) + +var ( + _ govtypes.Content = &ProposalClosePool{} +) + +func init() { + govtypes.RegisterProposalType(ProposalTypeClosePool) +} + +func NewClosePoolProposal(title string, description string, poolID uint64) govtypes.Content { + return &ProposalClosePool{ + Title: title, + Description: description, + PoolId: poolID, + } +} + +func (p *ProposalClosePool) ProposalRoute() string { return RouterKey } + +func (p *ProposalClosePool) ProposalType() string { + return ProposalTypeClosePool +} + +func (p *ProposalClosePool) ValidateBasic() error { + // Validate root proposal content + err := govtypes.ValidateAbstract(p) + if err != nil { + return err + } + + return nil +} + +func (p ProposalClosePool) String() string { + // Return the string + return fmt.Sprintf(`Register Pool Proposal: + Title: %s + Description: %s + PoolID: %d + `, + p.Title, p.Description, p.PoolId, + ) +}