diff --git a/x/collector/client/cli/flags.go b/x/collector/client/cli/flags.go index 7e94d0d85..3d3365c18 100644 --- a/x/collector/client/cli/flags.go +++ b/x/collector/client/cli/flags.go @@ -1,10 +1,16 @@ package cli import ( + flag "github.com/spf13/pflag" "strconv" "strings" ) +const ( + FlagAddLookupParamsTable = "collector-lookup-table-file" + FlagAuctionControlParams = "auction-control-params-file" +) + func ParseStringFromString(s string, separator string) ([]string, error) { var parsedStrings []string for _, s := range strings.Split(s, separator) { @@ -42,3 +48,44 @@ func ParseUint64SliceFromString(s string, separator string) ([]uint64, error) { } return parsedInts, nil } + +func FlagSetCreateLookupTableParamsMapping() *flag.FlagSet { + fs := flag.NewFlagSet("", flag.ContinueOnError) + + fs.String(FlagAddLookupParamsTable, "", "create lookup table params json file path") + return fs +} + +func FlagSetAuctionControlParamsMapping() *flag.FlagSet { + fs := flag.NewFlagSet("", flag.ContinueOnError) + + fs.String(FlagAuctionControlParams, "", "auction control params json file path") + return fs +} + +type createLookupTableParamsInputs struct { + AppID string `json:"app_id"` + CollectorAssetID string `json:"collector_asset_id"` + SecondaryAssetID string `json:"secondary_asset_id"` + SurplusThreshold string `json:"surplus_threshold"` + DebtThreshold string `json:"debt_threshold"` + LockerSavingRate string `json:"locker_saving_rate"` + LotSize string `json:"lot_size"` + BidFactor string `json:"bid_factor"` + DebtLotSize string `json:"debt_lot_size"` + Title string + Description string + Deposit string +} + +type auctionControlParamsInputs struct { + AppID string `json:"app_id"` + AssetID string `json:"asset_id"` + SurplusAuction string `json:"surplus_auction"` + DebtAuction string `json:"debt_auction"` + AssetOutOraclePrice string `json:"asset_out_oracle_price"` + AssetOutPrice string `json:"asset_out_price"` + Title string + Description string + Deposit string +} diff --git a/x/collector/client/cli/parse.go b/x/collector/client/cli/parse.go new file mode 100644 index 000000000..324aaa28c --- /dev/null +++ b/x/collector/client/cli/parse.go @@ -0,0 +1,94 @@ +package cli + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/spf13/pflag" + "io/ioutil" +) + +type XCreateLookupTableParamsInputs createLookupTableParamsInputs +type XAuctionControlParamsInputs auctionControlParamsInputs + +type XCreateLookupTableParamsInputsExceptions struct { + XCreateLookupTableParamsInputs + Other *string // Other won't raise an error +} + +type XAuctionControlParamsInputsExceptions struct { + XAuctionControlParamsInputs + Other *string // Other won't raise an error +} + +// UnmarshalJSON should error if there are fields unexpected. +func (release *createLookupTableParamsInputs) UnmarshalJSON(data []byte) error { + var createLookupTableParamsE XCreateLookupTableParamsInputsExceptions + dec := json.NewDecoder(bytes.NewReader(data)) + dec.DisallowUnknownFields() // Force + + if err := dec.Decode(&createLookupTableParamsE); err != nil { + return err + } + + *release = createLookupTableParamsInputs(createLookupTableParamsE.XCreateLookupTableParamsInputs) + return nil +} + +// UnmarshalJSON should error if there are fields unexpected. +func (release *auctionControlParamsInputs) UnmarshalJSON(data []byte) error { + var createAuctionControlParamsE XAuctionControlParamsInputsExceptions + dec := json.NewDecoder(bytes.NewReader(data)) + dec.DisallowUnknownFields() // Force + + if err := dec.Decode(&createAuctionControlParamsE); err != nil { + return err + } + + *release = auctionControlParamsInputs(createAuctionControlParamsE.XAuctionControlParamsInputs) + return nil +} + +func parseLookupTableParamsFlags(fs *pflag.FlagSet) (*createLookupTableParamsInputs, error) { + lookupTableParams := &createLookupTableParamsInputs{} + lookupTableParamsFile, _ := fs.GetString(FlagAddLookupParamsTable) + + if lookupTableParamsFile == "" { + return nil, fmt.Errorf("must pass in a lookup table params json using the --%s flag", FlagAddLookupParamsTable) + } + + contents, err := ioutil.ReadFile(lookupTableParamsFile) + if err != nil { + return nil, err + } + + // make exception if unknown field exists + err = lookupTableParams.UnmarshalJSON(contents) + if err != nil { + return nil, err + } + + return lookupTableParams, nil +} + +func parseAuctionControlParamsFlags(fs *pflag.FlagSet) (*auctionControlParamsInputs, error) { + auctionControlParams := &auctionControlParamsInputs{} + auctionControlParamsFile, _ := fs.GetString(FlagAuctionControlParams) + + if auctionControlParamsFile == "" { + return nil, fmt.Errorf("must pass in a auction control params json using the --%s flag", FlagAuctionControlParams) + } + + contents, err := ioutil.ReadFile(auctionControlParamsFile) + if err != nil { + return nil, err + } + + // make exception if unknown field exists + err = auctionControlParams.UnmarshalJSON(contents) + if err != nil { + return nil, err + } + + return auctionControlParams, nil +} diff --git a/x/collector/client/cli/tx.go b/x/collector/client/cli/tx.go index 03bfa2aa2..5c794401e 100644 --- a/x/collector/client/cli/tx.go +++ b/x/collector/client/cli/tx.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov/client/cli" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + flag "github.com/spf13/pflag" "strconv" "time" @@ -35,235 +36,232 @@ func GetTxCmd() *cobra.Command { // NewCmdLookupTableParams cmd for lookup table param proposal updates func NewCmdLookupTableParams() *cobra.Command { cmd := &cobra.Command{ - Use: "collector-lookup-params [app-id] [collector_asset_id] [secondary_asset_id] [surplus_threshold] [debt_threshold] [locker_saving_rate] [lot_size] [bid_factor] [debt_lot_size]", - Args: cobra.ExactArgs(9), + Use: "collector-lookup-params [flags]", + Args: cobra.ExactArgs(0), Short: "Set collector lookup params for collector module", RunE: func(cmd *cobra.Command, args []string) error { - - appId, err := ParseUint64SliceFromString(args[0], ",") + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err } - collectorAssetId, err := ParseUint64SliceFromString(args[1], ",") - if err != nil { - return err - } + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - secondaryAssetId, err := ParseUint64SliceFromString(args[2], ",") + txf, msg, err := NewCreateLookupTableParams(clientCtx, txf, cmd.Flags()) if err != nil { return err } - surplusThreshold, err := ParseUint64SliceFromString(args[3], ",") - if err != nil { - return err - } + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } - debtThreshold, err := ParseUint64SliceFromString(args[4], ",") - if err != nil { - return err - } + cmd.Flags().AddFlagSet(FlagSetCreateLookupTableParamsMapping()) + cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)") + return cmd +} - lockerSavingRate, err := ParseStringFromString(args[5], ",") - if err != nil { - return err - } +func NewCreateLookupTableParams(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { + lookupTableParams, err := parseLookupTableParamsFlags(fs) - lotSize, err := ParseUint64SliceFromString(args[6], ",") - if err != nil { - return err - } + if err != nil { + return txf, nil, fmt.Errorf("failed to parse lookup table params: %w", err) + } - bidFactor, err := ParseStringFromString(args[7], ",") - if err != nil { - return err - } - debt_lot_size, err := ParseUint64SliceFromString(args[8], ",") - if err != nil { - return err - } + appID, err := ParseUint64SliceFromString(lookupTableParams.AppID, ",") + if err != nil { + return txf, nil, err + } - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } + collectorAssetID, err := ParseUint64SliceFromString(lookupTableParams.CollectorAssetID, ",") + if err != nil { + return txf, nil, err + } - var LookupTableRecords []types.CollectorLookupTable - for i := range appId { - newBidFactor, err := sdk.NewDecFromStr(bidFactor[i]) - if err != nil { - return err - } - - newLockerSavingRate, err := sdk.NewDecFromStr(lockerSavingRate[i]) - if err != nil { - return err - } - - LookupTableRecords = append(LookupTableRecords, types.CollectorLookupTable{ - AppId: appId[i], - CollectorAssetId: collectorAssetId[i], - SecondaryAssetId: secondaryAssetId[i], - SurplusThreshold: surplusThreshold[i], - DebtThreshold: debtThreshold[i], - LockerSavingRate: newLockerSavingRate, - LotSize: lotSize[i], - BidFactor: newBidFactor, - DebtLotSize: debt_lot_size[i], - }) - } + secondaryAssetID, err := ParseUint64SliceFromString(lookupTableParams.SecondaryAssetID, ",") + if err != nil { + return txf, nil, err + } - title, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return err - } + surplusThreshold, err := ParseUint64SliceFromString(lookupTableParams.SurplusThreshold, ",") + if err != nil { + return txf, nil, err + } - description, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return err - } + debtThreshold, err := ParseUint64SliceFromString(lookupTableParams.DebtThreshold, ",") + if err != nil { + return txf, nil, err + } - from := clientCtx.GetFromAddress() + lockerSavingRate, err := ParseStringFromString(lookupTableParams.LockerSavingRate, ",") + if err != nil { + return txf, nil, err + } - depositStr, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - deposit, err := sdk.ParseCoinsNormalized(depositStr) - if err != nil { - return err - } + lotSize, err := ParseUint64SliceFromString(lookupTableParams.LotSize, ",") + if err != nil { + return txf, nil, err + } - content := types.NewLookupTableParamsProposal(title, description, LookupTableRecords) + bidFactor, err := ParseStringFromString(lookupTableParams.BidFactor, ",") + if err != nil { + return txf, nil, err + } - msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) - if err != nil { - return err - } + debtLotSize, err := ParseUint64SliceFromString(lookupTableParams.DebtLotSize, ",") + if err != nil { + return txf, nil, err + } - if err = msg.ValidateBasic(); err != nil { - return err - } + var LookupTableRecords []types.CollectorLookupTable + for i := range appID { + newBidFactor, err := sdk.NewDecFromStr(bidFactor[i]) + if err != nil { + return txf, nil, err + } + + newLockerSavingRate, err := sdk.NewDecFromStr(lockerSavingRate[i]) + if err != nil { + return txf, nil, err + } + + LookupTableRecords = append(LookupTableRecords, types.CollectorLookupTable{ + AppId: appID[i], + CollectorAssetId: collectorAssetID[i], + SecondaryAssetId: secondaryAssetID[i], + SurplusThreshold: surplusThreshold[i], + DebtThreshold: debtThreshold[i], + LockerSavingRate: newLockerSavingRate, + LotSize: lotSize[i], + BidFactor: newBidFactor, + DebtLotSize: debtLotSize[i], + }) + } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, + from := clientCtx.GetFromAddress() + + deposit, err := sdk.ParseCoinsNormalized(lookupTableParams.Deposit) + if err != nil { + return txf, nil, err } - cmd.Flags().String(cli.FlagTitle, "", "title of proposal") - cmd.Flags().String(cli.FlagDescription, "", "description of proposal") - cmd.Flags().String(cli.FlagDeposit, "", "deposit of proposal") - _ = cmd.MarkFlagRequired(cli.FlagTitle) - _ = cmd.MarkFlagRequired(cli.FlagDescription) - return cmd + content := types.NewLookupTableParamsProposal(lookupTableParams.Title, lookupTableParams.Description, LookupTableRecords) + + msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) + if err != nil { + return txf, nil, err + } + + if err = msg.ValidateBasic(); err != nil { + return txf, nil, err + } + + return txf, msg, nil } // NewCmdAuctionControlProposal cmd to update controls for auction params func NewCmdAuctionControlProposal() *cobra.Command { cmd := &cobra.Command{ - Use: "auction-control [app-id] [asset_id] [surplus_auction] [debt_auction] [asset_out_oracle_price] [asset_out_price]", - Args: cobra.ExactArgs(6), + Use: "auction-control [flags]", + Args: cobra.ExactArgs(0), Short: "Set auction control", RunE: func(cmd *cobra.Command, args []string) error { - - appId, err := strconv.ParseUint(args[0], 10, 64) + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err } + txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) - assetId, err := ParseUint64SliceFromString(args[1], ",") + txf, msg, err := NewCreateAuctionControlParams(clientCtx, txf, cmd.Flags()) if err != nil { return err } - surplusAuction, err := ParseStringFromString(args[2], ",") - if err != nil { - return err - } - debtAuction, err := ParseStringFromString(args[3], ",") - if err != nil { - return err - } + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } - asset_out_oracle_price, err := ParseStringFromString(args[4], ",") - if err != nil { - return err - } + cmd.Flags().AddFlagSet(FlagSetAuctionControlParamsMapping()) + cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)") + return cmd +} - asset_out_price, err := ParseUint64SliceFromString(args[5], ",") - if err != nil { - return err - } +func NewCreateAuctionControlParams(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } + auctionControlParams, err := parseAuctionControlParamsFlags(fs) - var collectorAuctionLookupRecords types.CollectorAuctionLookupTable - for i := range assetId { - newSurplusAuction, err := strconv.ParseBool(surplusAuction[i]) - if err != nil { - return err - } - newDebtAuction, err := strconv.ParseBool(debtAuction[i]) - if err != nil { - return err - } - newasset_out_oracle_price, err := strconv.ParseBool(asset_out_oracle_price[i]) - if err != nil { - return err - } - collectorAuctionLookupRecords.AppId = appId - var AssetIdToAuctionLookup types.AssetIdToAuctionLookupTable - AssetIdToAuctionLookup.AssetId = assetId[i] - AssetIdToAuctionLookup.IsSurplusAuction = newSurplusAuction - AssetIdToAuctionLookup.IsDebtAuction = newDebtAuction - AssetIdToAuctionLookup.AssetOutOraclePrice = newasset_out_oracle_price - AssetIdToAuctionLookup.AssetOutPrice = asset_out_price[i] - collectorAuctionLookupRecords.AssetIdToAuctionLookup = append(collectorAuctionLookupRecords.AssetIdToAuctionLookup, AssetIdToAuctionLookup) - } + if err != nil { + return txf, nil, fmt.Errorf("failed to parse auction control params: %w", err) + } + appID, err := strconv.ParseUint(auctionControlParams.AppID, 10, 64) + if err != nil { + return txf, nil, err + } - title, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return err - } + assetID, err := ParseUint64SliceFromString(auctionControlParams.AssetID, ",") + if err != nil { + return txf, nil, err + } - description, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return err - } + surplusAuction, err := ParseStringFromString(auctionControlParams.SurplusAuction, ",") + if err != nil { + return txf, nil, err + } + debtAuction, err := ParseStringFromString(auctionControlParams.DebtAuction, ",") + if err != nil { + return txf, nil, err + } - from := clientCtx.GetFromAddress() + assetOutOraclePrice, err := ParseStringFromString(auctionControlParams.AssetOutOraclePrice, ",") + if err != nil { + return txf, nil, err + } - depositStr, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - deposit, err := sdk.ParseCoinsNormalized(depositStr) - if err != nil { - return err - } + assetOutPrice, err := ParseUint64SliceFromString(auctionControlParams.AssetOutPrice, ",") + if err != nil { + return txf, nil, err + } - content := types.NewAuctionLookupTableProposal(title, description, collectorAuctionLookupRecords) + var collectorAuctionLookupRecords types.CollectorAuctionLookupTable + for i := range assetID { + newSurplusAuction, err := strconv.ParseBool(surplusAuction[i]) + if err != nil { + return txf, nil, err + } + newDebtAuction, err := strconv.ParseBool(debtAuction[i]) + if err != nil { + return txf, nil, err + } + newAssetOutOraclePrice, err := strconv.ParseBool(assetOutOraclePrice[i]) + if err != nil { + return txf, nil, err + } + collectorAuctionLookupRecords.AppId = appID + var AssetIDToAuctionLookup types.AssetIdToAuctionLookupTable + AssetIDToAuctionLookup.AssetId = assetID[i] + AssetIDToAuctionLookup.IsSurplusAuction = newSurplusAuction + AssetIDToAuctionLookup.IsDebtAuction = newDebtAuction + AssetIDToAuctionLookup.AssetOutOraclePrice = newAssetOutOraclePrice + AssetIDToAuctionLookup.AssetOutPrice = assetOutPrice[i] + collectorAuctionLookupRecords.AssetIdToAuctionLookup = append(collectorAuctionLookupRecords.AssetIdToAuctionLookup, AssetIDToAuctionLookup) + } - msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) - if err != nil { - return err - } + from := clientCtx.GetFromAddress() - if err = msg.ValidateBasic(); err != nil { - return err - } + deposit, err := sdk.ParseCoinsNormalized(auctionControlParams.Deposit) + if err != nil { + return txf, nil, err + } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, + content := types.NewAuctionLookupTableProposal(auctionControlParams.Title, auctionControlParams.Description, collectorAuctionLookupRecords) + + msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) + if err != nil { + return txf, nil, err } - cmd.Flags().String(cli.FlagTitle, "", "title of proposal") - cmd.Flags().String(cli.FlagDescription, "", "description of proposal") - cmd.Flags().String(cli.FlagDeposit, "", "deposit of proposal") - _ = cmd.MarkFlagRequired(cli.FlagTitle) - _ = cmd.MarkFlagRequired(cli.FlagDescription) - return cmd + if err = msg.ValidateBasic(); err != nil { + return txf, nil, err + } + return txf, msg, nil }