diff --git a/tests/e2e/bond/suite.go b/tests/e2e/bond/suite.go index ce355443..67f435d9 100644 --- a/tests/e2e/bond/suite.go +++ b/tests/e2e/bond/suite.go @@ -50,7 +50,7 @@ func (ets *E2ETestSuite) SetupSuite() { //nolint: all } func (ets *E2ETestSuite) TearDownSuite() { - ets.T().Log("tearing down integration test suite") + ets.T().Log("tearing down e2e test suite") ets.network.Cleanup() } diff --git a/tests/e2e/registry/grpc.go b/tests/e2e/registry/grpc.go index bcd19499..c8f05f29 100644 --- a/tests/e2e/registry/grpc.go +++ b/tests/e2e/registry/grpc.go @@ -1,10 +1,9 @@ package registry import ( - "time" + "fmt" "github.com/cosmos/cosmos-sdk/testutil" - sdk "github.com/cosmos/cosmos-sdk/types" registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry" ) @@ -47,11 +46,59 @@ func (ets *E2ETestSuite) TestGRPCQueryParams() { var response registrytypes.QueryParamsResponse err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response) sr.NoError(err) + params := registrytypes.DefaultParams() - params.RecordRent = sdk.NewCoin(ets.cfg.BondDenom, registrytypes.DefaultRecordRent) - params.RecordRentDuration = 10 * time.Second - params.AuthorityGracePeriod = 10 * time.Second - sr.Equal(response.GetParams().String(), params.String()) + ets.updateParams(¶ms) + sr.Equal(params.String(), response.GetParams().String()) + } + }) + } +} + +func (ets *E2ETestSuite) TestGRPCQueryWhoIs() { + val := ets.network.Validators[0] + sr := ets.Require() + reqUrl := val.APIAddress + "/cerc/registry/v1/whois/%s" + authorityName := "QueryWhoIS" + testCases := []struct { + name string + url string + expectErr bool + errorMsg string + preRun func(authorityName string) + }{ + { + "invalid url", + reqUrl + badPath, + true, + "", + func(authorityName string) { + }, + }, + { + "valid request", + reqUrl, + false, + "", + func(authorityName string) { ets.reserveName(authorityName) }, + }, + } + + for _, tc := range testCases { + ets.Run(tc.name, func() { + tc.preRun(authorityName) + tc.url = fmt.Sprintf(tc.url, authorityName) + + resp, err := testutil.GetRequest(tc.url) + ets.NoError(err) + require := ets.Require() + if tc.expectErr { + require.Contains(string(resp), tc.errorMsg) + } else { + var response registrytypes.QueryWhoisResponse + err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response) + sr.NoError(err) + sr.Equal(registrytypes.AuthorityActive, response.GetNameAuthority().Status) } }) } diff --git a/tests/e2e/registry/suite.go b/tests/e2e/registry/suite.go index 1991bb78..a15652ab 100644 --- a/tests/e2e/registry/suite.go +++ b/tests/e2e/registry/suite.go @@ -18,6 +18,7 @@ import ( bondtypes "git.vdb.to/cerc-io/laconic2d/x/bond" bondcli "git.vdb.to/cerc-io/laconic2d/x/bond/client/cli" registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry" + "git.vdb.to/cerc-io/laconic2d/x/registry/client/cli" ) type E2ETestSuite struct { @@ -46,9 +47,8 @@ func (ets *E2ETestSuite) SetupSuite() { var registryGenesis registrytypes.GenesisState ets.Require().NoError(ets.cfg.Codec.UnmarshalJSON(genesisState[registrytypes.ModuleName], ®istryGenesis)) - registryGenesis.Params.RecordRent = sdk.NewCoin(ets.cfg.BondDenom, registrytypes.DefaultRecordRent) - registryGenesis.Params.RecordRentDuration = 10 * time.Second - registryGenesis.Params.AuthorityGracePeriod = 10 * time.Second + ets.updateParams(®istryGenesis.Params) + registryGenesisBz, err := ets.cfg.Codec.MarshalJSON(®istryGenesis) ets.Require().NoError(err) genesisState[registrytypes.ModuleName] = registryGenesisBz @@ -64,7 +64,7 @@ func (ets *E2ETestSuite) SetupSuite() { ets.accountName = "accountName" ets.createAccountWithBalance(ets.accountName, &ets.accountAddress) - // ets.bondId = ets.createBond() + ets.bondId = ets.createBond() } func (ets *E2ETestSuite) TearDownSuite() { @@ -84,7 +84,7 @@ func (ets *E2ETestSuite) createAccountWithBalance(accountName string, accountAdd val.ClientCtx, val.Address, newAddr, - sdk.NewCoins(sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(1000000000000000000))), + sdk.NewCoins(sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(100000000))), addresscodec.NewBech32Codec("laconic"), fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), @@ -100,3 +100,81 @@ func (ets *E2ETestSuite) createAccountWithBalance(accountName string, accountAdd sr.NoError(err) } +func (ets *E2ETestSuite) createBond() string { + val := ets.network.Validators[0] + sr := ets.Require() + createBondCmd := bondcli.NewCreateBondCmd() + args := []string{ + fmt.Sprintf("1000000%s", ets.cfg.BondDenom), + fmt.Sprintf("--%s=%s", flags.FlagFrom, ets.accountName), + fmt.Sprintf("--%s=json", flags.FlagOutput), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", ets.cfg.BondDenom)), + } + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, createBondCmd, args) + sr.NoError(err) + var d sdk.TxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d) + sr.NoError(err) + sr.Zero(d.Code) + + // wait for tx to take effect + err = ets.network.WaitForNextBlock() + sr.NoError(err) + + // getting the bonds list and returning the bond-id + clientCtx := val.ClientCtx + cmd := bondcli.GetQueryBondList() + args = []string{ + fmt.Sprintf("--%s=json", flags.FlagOutput), + } + out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + sr.NoError(err) + var queryResponse bondtypes.QueryGetBondsResponse + err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse) + sr.NoError(err) + + // extract bond id from bonds list + bond := queryResponse.GetBonds()[0] + return bond.GetId() +} + +func (ets *E2ETestSuite) reserveName(authorityName string) { + val := ets.network.Validators[0] + sr := ets.Require() + + clientCtx := val.ClientCtx + cmd := cli.GetCmdReserveName() + args := []string{ + authorityName, + fmt.Sprintf("--owner=%s", ets.accountAddress), + fmt.Sprintf("--%s=%s", flags.FlagFrom, ets.accountName), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=json", flags.FlagOutput), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", ets.cfg.BondDenom)), + } + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + sr.NoError(err) + + var d sdk.TxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d) + sr.NoError(err) + sr.Zero(d.Code) + + err = ets.network.WaitForNextBlock() + sr.NoError(err) +} + +func (ets *E2ETestSuite) updateParams(params *registrytypes.Params) { + params.RecordRent = sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(1000)) + params.RecordRentDuration = 10 * time.Second + + params.AuthorityRent = sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(1000)) + params.AuthorityGracePeriod = 10 * time.Second + + params.AuthorityAuctionCommitFee = sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(100)) + params.AuthorityAuctionRevealFee = sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(100)) + params.AuthorityAuctionMinimumBid = sdk.NewCoin(ets.cfg.BondDenom, math.NewInt(500)) +} diff --git a/x/registry/client/cli/tx.go b/x/registry/client/cli/tx.go index 168aeab7..366e9ad2 100644 --- a/x/registry/client/cli/tx.go +++ b/x/registry/client/cli/tx.go @@ -1,11 +1,15 @@ package cli import ( + "fmt" "os" + "strings" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" "gopkg.in/yaml.v3" "github.com/spf13/cobra" @@ -80,3 +84,48 @@ func GetPayloadFromFile(filePath string) (*registrytypes.ReadablePayload, error) return &payload, nil } + +// GetCmdReserveName is the CLI command for reserving a name. +func GetCmdReserveName() *cobra.Command { + cmd := &cobra.Command{ + Use: "reserve-name [name]", + Short: "Reserve name.", + Long: strings.TrimSpace( + fmt.Sprintf(`Reserver name with owner address . +Example: +$ %s tx %s reserve-name [name] --owner [ownerAddress] +`, + version.AppName, registrytypes.ModuleName, + ), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + owner, err := cmd.Flags().GetString("owner") + if err != nil { + return err + } + ownerAddress, err := sdk.AccAddressFromBech32(owner) + if err != nil { + return err + } + + msg := registrytypes.NewMsgReserveAuthority(args[0], clientCtx.GetFromAddress(), ownerAddress) + err = msg.ValidateBasic() + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + cmd.Flags().String("owner", "", "Owner address, if creating a sub-authority.") + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/registry/msgs.go b/x/registry/msgs.go index 7a68ded3..882078fb 100644 --- a/x/registry/msgs.go +++ b/x/registry/msgs.go @@ -33,3 +33,25 @@ func (msg MsgSetRecord) ValidateBasic() error { return nil } + +// NewMsgReserveAuthority is the constructor function for MsgReserveName. +func NewMsgReserveAuthority(name string, signer sdk.AccAddress, owner sdk.AccAddress) MsgReserveAuthority { + return MsgReserveAuthority{ + Name: name, + Owner: owner.String(), + Signer: signer.String(), + } +} + +// ValidateBasic Implements Msg. +func (msg MsgReserveAuthority) ValidateBasic() error { + if len(msg.Name) == 0 { + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "name is required.") + } + + if len(msg.Signer) == 0 { + return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer") + } + + return nil +}