Skip to content

Commit

Permalink
added CLI commands for new messages
Browse files Browse the repository at this point in the history
  • Loading branch information
insumity committed Aug 2, 2024
1 parent 52073e3 commit 1ea02bb
Show file tree
Hide file tree
Showing 4 changed files with 429 additions and 48 deletions.
220 changes: 220 additions & 0 deletions x/ccv/provider/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"strings"
"time"

"cosmossdk.io/math"

Expand Down Expand Up @@ -36,6 +37,10 @@ func GetTxCmd() *cobra.Command {
cmd.AddCommand(NewAssignConsumerKeyCmd())
cmd.AddCommand(NewSubmitConsumerMisbehaviourCmd())
cmd.AddCommand(NewSubmitConsumerDoubleVotingCmd())
cmd.AddCommand(NewRegisterConsumerCmd())
cmd.AddCommand(NewInitializeConsumerCmd())
cmd.AddCommand(NewUpdateConsumerCmd())
cmd.AddCommand(NewRemoveConsumerCmd())
cmd.AddCommand(NewOptInCmd())
cmd.AddCommand(NewOptOutCmd())
cmd.AddCommand(NewSetConsumerCommissionRateCmd())
Expand Down Expand Up @@ -209,6 +214,221 @@ Example:
return cmd
}

func NewRegisterConsumerCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "register-consumer [path/to/registration-record.json]",
Short: "register a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Register a consumer chain to get back the assigned consumer id of this chain.
Note that the one that signs this message is the owner of this consumer chain. The owner can be later
changed by updating the consumer chain.
Example:
%s tx provider register-cosumer [path/to/registration-record.json] --from node0 --home ../node0 --chain-id $CID
`, version.AppName)),
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags())
if err != nil {
return err
}
txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever)

signer := clientCtx.GetFromAddress().String()
registrationRecord := types.ConsumerRegistrationRecord{}
registrationRecordJson, err := os.ReadFile(args[0])
if err != nil {
return err
}
if err := json.Unmarshal(registrationRecordJson, &registrationRecord); err != nil {
return fmt.Errorf("registration record unmarshalling failed: %w", err)
}

msg, err := types.NewMsgRegisterConsumer(signer, registrationRecord)
if err != nil {
return err
}
if err := msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg)
},
}

flags.AddTxFlagsToCmd(cmd)

_ = cmd.MarkFlagRequired(flags.FlagFrom)

return cmd
}

func NewInitializeConsumerCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "initialize-consumer [consumer-id] [path/to/initialization-record.json]",
Short: "initialize a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Initialize a consumer chain to get it ready to launch
Note that only the owner of the chain can initialize it.
Example:
%s tx provider initialize-cosumer [consumer-id] [path/to/initialization-record.json] --from node0 --home ../node0 --chain-id $CID
`, version.AppName)),
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags())
if err != nil {
return err
}
txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever)

signer := clientCtx.GetFromAddress().String()
consumerId := args[0]
initializationRecord := types.ConsumerInitializationRecord{}
initializationRecordJson, err := os.ReadFile(args[1])
if err != nil {
return err
}
if err := json.Unmarshal(initializationRecordJson, &initializationRecord); err != nil {
return fmt.Errorf("initialization record unmarshalling failed: %w", err)
}

msg, err := types.NewMsgInitializeConsumer(signer, consumerId, initializationRecord)
if err != nil {
return err
}
if err := msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg)
},
}

flags.AddTxFlagsToCmd(cmd)

_ = cmd.MarkFlagRequired(flags.FlagFrom)

return cmd
}

func NewUpdateConsumerCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update-consumer [consumer-id] [path/to/update-record.json]",
Short: "update a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Update a consumer chain to change its running parameters (e.g., the allow list).
Note that only the owner of the chain can initialize it.
Example:
%s tx provider update-cosumer [consumer-id] [path/to/update-record.json] --from node0 --home ../node0 --chain-id $CID
`, version.AppName)),
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags())
if err != nil {
return err
}
txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever)

signer := clientCtx.GetFromAddress().String()
consumerId := args[0]
updateRecord := types.ConsumerUpdateRecord{}
updateRecordJson, err := os.ReadFile(args[1])
if err != nil {
return err
}
if err := json.Unmarshal(updateRecordJson, &updateRecord); err != nil {
return fmt.Errorf("update record unmarshalling failed: %w", err)
}

msg, err := types.NewMsgUpdateConsumer(signer, consumerId, updateRecord)
if err != nil {
return err
}
if err := msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg)
},
}

flags.AddTxFlagsToCmd(cmd)

_ = cmd.MarkFlagRequired(flags.FlagFrom)

return cmd
}

func NewRemoveConsumerCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "remove-consumer [consumer-id] [stop-time-layout] [stop-time-value]",
Short: "remove a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Removes (and stops) a consumer chain. Note that only the owner of the chain can remove it.
Stop time is parsed by using the layout and the value (see https://pkg.go.dev/time#Parse).
Example:
%s tx provider remove-cosumer [consumer-id] [stop-time-layout] [stop-time-value] --from node0 --home ../node0 --chain-id $CID
`, version.AppName)),
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags())
if err != nil {
return err
}
txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever)

signer := clientCtx.GetFromAddress().String()
consumerId := args[0]
stopTimeLayout := args[1]
stopTimeValue := args[2]

stopTime, err := time.Parse(stopTimeLayout, stopTimeValue)
if err != nil {
return err
}

msg, err := types.NewMsgRemoveConsumer(signer, consumerId, stopTime)
if err != nil {
return err
}
if err := msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg)
},
}

flags.AddTxFlagsToCmd(cmd)

_ = cmd.MarkFlagRequired(flags.FlagFrom)

return cmd
}

func NewOptInCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "opt-in [consumer-chain-id] [consumer-pubkey]",
Expand Down
64 changes: 32 additions & 32 deletions x/ccv/provider/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,36 @@ import (

// Provider sentinel errors
var (
ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal")
ErrInvalidConsumerRemovalProp = errorsmod.Register(ModuleName, 2, "invalid consumer removal proposal")
ErrUnknownConsumerId = errorsmod.Register(ModuleName, 3, "no consumer chain with this consumer id")
ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id")
ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key")
ErrInvalidConsumerId = errorsmod.Register(ModuleName, 6, "invalid consumer id")
ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found")
ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address")
ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address")
ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator")
ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment")
ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params")
ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address")
ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom")
ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address")
ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client")
ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists")
ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found")
ErrInvalidConsumerCommissionRate = errorsmod.Register(ModuleName, 19, "consumer commission rate is invalid")
ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain")
ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id")
ErrInvalidConsumerModificationProposal = errorsmod.Register(ModuleName, 22, "invalid consumer modification proposal")
ErrNoUnbondingTime = errorsmod.Register(ModuleName, 23, "provider unbonding time not found")
ErrInvalidAddress = errorsmod.Register(ModuleName, 24, "invalid address")
ErrUnauthorized = errorsmod.Register(ModuleName, 25, "unauthorized")
ErrInvalidPhase = errorsmod.Register(ModuleName, 26, "cannot perform action in the current phase of consumer chain")
ErrNoInitializationRecord = errorsmod.Register(ModuleName, 27, "initialization record is missing")
ErrNoRegistrationRecord = errorsmod.Register(ModuleName, 28, "registration record is missing")
ErrNoChainId = errorsmod.Register(ModuleName, 29, "missing chain id for consumer chain")
ErrNoConsumerGenesis = errorsmod.Register(ModuleName, 30, "missing consumer genesis")
ErrInvalidConsumerGenesis = errorsmod.Register(ModuleName, 31, "invalid consumer genesis")
ErrNoConsumerId = errorsmod.Register(ModuleName, 32, "missing consumer id")
ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal")
ErrInvalidConsumerRemoval = errorsmod.Register(ModuleName, 2, "invalid consumer removal")
ErrUnknownConsumerId = errorsmod.Register(ModuleName, 3, "no consumer chain with this consumer id")
ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id")
ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key")
ErrInvalidConsumerId = errorsmod.Register(ModuleName, 6, "invalid consumer id")
ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found")
ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address")
ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address")
ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator")
ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment")
ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params")
ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address")
ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom")
ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address")
ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client")
ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists")
ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found")
ErrInvalidConsumerCommissionRate = errorsmod.Register(ModuleName, 19, "consumer commission rate is invalid")
ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain")
ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id")
ErrInvalidUpdateRecord = errorsmod.Register(ModuleName, 22, "invalid consumer update record")
ErrNoUnbondingTime = errorsmod.Register(ModuleName, 23, "provider unbonding time not found")
ErrInvalidAddress = errorsmod.Register(ModuleName, 24, "invalid address")
ErrUnauthorized = errorsmod.Register(ModuleName, 25, "unauthorized")
ErrInvalidPhase = errorsmod.Register(ModuleName, 26, "cannot perform action in the current phase of consumer chain")
ErrNoInitializationRecord = errorsmod.Register(ModuleName, 27, "initialization record is missing")
ErrNoRegistrationRecord = errorsmod.Register(ModuleName, 28, "registration record is missing")
ErrNoChainId = errorsmod.Register(ModuleName, 29, "missing chain id for consumer chain")
ErrNoConsumerGenesis = errorsmod.Register(ModuleName, 30, "missing consumer genesis")
ErrInvalidConsumerGenesis = errorsmod.Register(ModuleName, 31, "invalid consumer genesis")
ErrNoConsumerId = errorsmod.Register(ModuleName, 32, "missing consumer id")
)
8 changes: 4 additions & 4 deletions x/ccv/provider/types/legacy_proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ func (sccp *ConsumerRemovalProposal) ValidateBasic() error {
}

if strings.TrimSpace(sccp.ConsumerId) == "" {
return errorsmod.Wrap(ErrInvalidConsumerRemovalProp, "consumer chain id must not be blank")
return errorsmod.Wrap(ErrInvalidConsumerRemoval, "consumer chain id must not be blank")
}

if sccp.StopTime.IsZero() {
return errorsmod.Wrap(ErrInvalidConsumerRemovalProp, "spawn time cannot be zero")
return errorsmod.Wrap(ErrInvalidConsumerRemoval, "spawn time cannot be zero")
}
return nil
}
Expand Down Expand Up @@ -271,12 +271,12 @@ func (cccp *ConsumerModificationProposal) ValidateBasic() error {
}

if strings.TrimSpace(cccp.ConsumerId) == "" {
return errorsmod.Wrap(ErrInvalidConsumerModificationProposal, "consumer chain id must not be blank")
return errorsmod.Wrap(ErrInvalidUpdateRecord, "consumer chain id must not be blank")
}

err := ValidatePSSFeatures(cccp.Top_N, cccp.ValidatorsPowerCap)
if err != nil {
return errorsmod.Wrapf(ErrInvalidConsumerModificationProposal, "invalid PSS features: %s", err.Error())
return errorsmod.Wrapf(ErrInvalidUpdateRecord, "invalid PSS features: %s", err.Error())
}
return nil
}
Expand Down
Loading

0 comments on commit 1ea02bb

Please sign in to comment.