refactor(nft): remove global bech32 (#15654)

This commit is contained in:
Marko 2023-04-03 12:28:17 +02:00 committed by GitHub
parent bd8b01cd12
commit b4d1109efc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 83 additions and 36 deletions

View File

@ -5,6 +5,7 @@ import (
"cosmossdk.io/x/nft/client/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
@ -40,7 +41,7 @@ func ExecQueryNFT(val *network.Validator, classID, nftID string) (testutil.Buffe
}
func ExecQueryNFTs(val *network.Validator, classID, owner string) (testutil.BufferWriter, error) {
cmd := cli.GetCmdQueryNFTs()
cmd := cli.GetCmdQueryNFTs(address.NewBech32Codec("cosmos"))
var args []string
args = append(args, fmt.Sprintf("--%s=%s", cli.FlagClassID, classID))
args = append(args, fmt.Sprintf("--%s=%s", cli.FlagOwner, owner))

View File

@ -3,22 +3,20 @@ package feegrant
import (
context "context"
"cosmossdk.io/core/address"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// AccountKeeper defines the expected auth Account Keeper (noalias)
type AccountKeeper interface {
address.Codec
GetModuleAddress(moduleName string) sdk.AccAddress
GetModuleAccount(ctx context.Context, moduleName string) sdk.ModuleAccountI
NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
SetAccount(ctx context.Context, acc sdk.AccountI)
// StringToBytes decodes text to bytes
StringToBytes(text string) ([]byte, error)
// BytesToString encodes bytes to text
BytesToString(bz []byte) (string, error)
}
// BankKeeper defines the expected supply Keeper (noalias)

View File

@ -6,10 +6,10 @@ import (
"github.com/spf13/cobra"
"cosmossdk.io/core/address"
"cosmossdk.io/x/nft"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/version"
)
@ -21,7 +21,7 @@ const (
)
// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd() *cobra.Command {
func GetQueryCmd(ac address.Codec) *cobra.Command {
nftQueryCmd := &cobra.Command{
Use: nft.ModuleName,
Short: "Querying commands for the nft module",
@ -35,7 +35,7 @@ func GetQueryCmd() *cobra.Command {
GetCmdQueryClass(),
GetCmdQueryClasses(),
GetCmdQueryNFT(),
GetCmdQueryNFTs(),
GetCmdQueryNFTs(ac),
GetCmdQueryOwner(),
GetCmdQueryBalance(),
GetCmdQuerySupply(),
@ -127,7 +127,7 @@ func GetCmdQueryNFT() *cobra.Command {
}
// GetCmdQueryNFTs implements the query nft command.
func GetCmdQueryNFTs() *cobra.Command {
func GetCmdQueryNFTs(ac address.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "nfts",
Short: "query all NFTs of a given class or owner address.",
@ -156,7 +156,7 @@ $ %s query %s nfts <class-id> --owner=<owner>
}
if len(owner) > 0 {
if _, err := sdk.AccAddressFromBech32(owner); err != nil {
if _, err := ac.StringToBytes(owner); err != nil {
return err
}
}

View File

@ -9,6 +9,7 @@ import (
"cosmossdk.io/x/nft/client/cli"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec/address"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
@ -169,7 +170,7 @@ func (s *CLITestSuite) TestQueryNFTs() {
for _, tc := range testCases {
s.Run(tc.name, func() {
cmd := cli.GetCmdQueryNFTs()
cmd := cli.GetCmdQueryNFTs(address.NewBech32Codec("cosmos"))
var args []string
args = append(args, fmt.Sprintf("--%s=%s", cli.FlagClassID, tc.args.ClassID))
args = append(args, fmt.Sprintf("--%s=%s", cli.FlagOwner, tc.args.Owner))

View File

@ -3,6 +3,7 @@ package nft
import (
context "context"
"cosmossdk.io/core/address"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -16,4 +17,6 @@ type BankKeeper interface {
type AccountKeeper interface {
GetModuleAddress(name string) sdk.AccAddress
GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
address.Codec
}

View File

@ -1,11 +1,11 @@
package nft
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"cosmossdk.io/core/address"
)
// ValidateGenesis checks that the given genesis state has no integrity issues
func ValidateGenesis(data GenesisState) error {
func ValidateGenesis(data GenesisState, ac address.Codec) error {
for _, class := range data.Classes {
if len(class.Id) == 0 {
return ErrEmptyClassID
@ -16,7 +16,7 @@ func ValidateGenesis(data GenesisState) error {
if len(nft.Id) == 0 {
return ErrEmptyNFTID
}
if _, err := sdk.AccAddressFromBech32(entry.Owner); err != nil {
if _, err := ac.StringToBytes(entry.Owner); err != nil {
return err
}
}

View File

@ -17,7 +17,10 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *nft.GenesisState) {
}
for _, entry := range data.Entries {
for _, nft := range entry.Nfts {
owner := sdk.MustAccAddressFromBech32(entry.Owner)
owner, err := k.ac.StringToBytes(entry.Owner)
if err != nil {
panic(err)
}
if err := k.Mint(ctx, *nft, owner); err != nil {
panic(err)

View File

@ -24,7 +24,7 @@ func (k Keeper) Balance(goCtx context.Context, r *nft.QueryBalanceRequest) (*nft
return nil, nft.ErrEmptyClassID
}
owner, err := sdk.AccAddressFromBech32(r.Owner)
owner, err := k.ac.StringToBytes(r.Owner)
if err != nil {
return nil, err
}
@ -77,7 +77,7 @@ func (k Keeper) NFTs(goCtx context.Context, r *nft.QueryNFTsRequest) (*nft.Query
var owner sdk.AccAddress
if len(r.Owner) > 0 {
owner, err = sdk.AccAddressFromBech32(r.Owner)
owner, err = k.ac.StringToBytes(r.Owner)
if err != nil {
return nil, err
}

View File

@ -16,6 +16,7 @@ func TestGRPCQuery(t *testing.T) {
}
func (s *TestSuite) TestBalance() {
s.accountKeeper.EXPECT().StringToBytes("owner").Return(nil, fmt.Errorf("decoding bech32 failed")).AnyTimes()
var req *nft.QueryBalanceRequest
testCases := []struct {
msg string

View File

@ -1,6 +1,7 @@
package keeper
import (
"cosmossdk.io/core/address"
store "cosmossdk.io/core/store"
"cosmossdk.io/x/nft"
@ -12,6 +13,7 @@ type Keeper struct {
cdc codec.BinaryCodec
storeService store.KVStoreService
bk nft.BankKeeper
ac address.Codec
}
// NewKeeper creates a new nft Keeper instance
@ -27,5 +29,6 @@ func NewKeeper(storeService store.KVStoreService,
cdc: cdc,
storeService: storeService,
bk: bk,
ac: ak,
}
}

View File

@ -37,10 +37,11 @@ const (
type TestSuite struct {
suite.Suite
ctx sdk.Context
addrs []sdk.AccAddress
queryClient nft.QueryClient
nftKeeper keeper.Keeper
ctx sdk.Context
addrs []sdk.AccAddress
queryClient nft.QueryClient
nftKeeper keeper.Keeper
accountKeeper *nfttestutil.MockAccountKeeper
encCfg moduletestutil.TestEncodingConfig
}
@ -60,6 +61,11 @@ func (s *TestSuite) SetupTest() {
accountKeeper := nfttestutil.NewMockAccountKeeper(ctrl)
bankKeeper := nfttestutil.NewMockBankKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress("nft").Return(s.addrs[0]).AnyTimes()
for _, addr := range s.addrs {
accountKeeper.EXPECT().StringToBytes(addr.String()).Return(addr, nil).AnyTimes()
}
s.accountKeeper = accountKeeper
nftKeeper := keeper.NewKeeper(storeService, s.encCfg.Codec, accountKeeper, bankKeeper)
queryHelper := baseapp.NewQueryServerTestHelper(ctx, s.encCfg.InterfaceRegistry)

View File

@ -1,6 +1,7 @@
package keeper
import (
"bytes"
"context"
errorsmod "cosmossdk.io/errors"
@ -15,17 +16,17 @@ var _ nft.MsgServer = Keeper{}
// Send implements Send method of the types.MsgServer.
func (k Keeper) Send(goCtx context.Context, msg *nft.MsgSend) (*nft.MsgSendResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
sender, err := sdk.AccAddressFromBech32(msg.Sender)
sender, err := k.ac.StringToBytes(msg.Sender)
if err != nil {
return nil, err
}
owner := k.GetOwner(ctx, msg.ClassId, msg.Id)
if !owner.Equals(sender) {
return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not the owner of nft %s", sender, msg.Id)
if !bytes.Equal(owner, sender) {
return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not the owner of nft %s", msg.Sender, msg.Id)
}
receiver, err := sdk.AccAddressFromBech32(msg.Receiver)
receiver, err := k.ac.StringToBytes(msg.Receiver)
if err != nil {
return nil, err
}

View File

@ -9,6 +9,7 @@ import (
"github.com/spf13/cobra"
"google.golang.org/grpc"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/store"
"cosmossdk.io/depinject"
@ -38,6 +39,7 @@ var (
// AppModuleBasic defines the basic application module used by the nft module.
type AppModuleBasic struct {
cdc codec.Codec
ac address.Codec
}
// Name returns the nft module's name.
@ -68,13 +70,13 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the nft module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEncodingConfig, bz json.RawMessage) error {
func (ab AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEncodingConfig, bz json.RawMessage) error {
var data nft.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return errors.Wrapf(err, "failed to unmarshal %s genesis state", nft.ModuleName)
}
return nft.ValidateGenesis(data)
return nft.ValidateGenesis(data, ab.ac)
}
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the nft module.
@ -85,8 +87,8 @@ func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, m
}
// GetQueryCmd returns the cli query commands for the nft module
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
return cli.GetQueryCmd()
func (ab AppModuleBasic) GetQueryCmd() *cobra.Command {
return cli.GetQueryCmd(ab.ac)
}
// GetTxCmd returns the transaction commands for the nft module
@ -107,7 +109,7 @@ type AppModule struct {
// NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak nft.AccountKeeper, bk nft.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc},
AppModuleBasic: AppModuleBasic{cdc: cdc, ac: ak},
keeper: keeper,
accountKeeper: ak,
bankKeeper: bk,

View File

@ -72,6 +72,21 @@ func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder {
return m.recorder
}
// BytesToString mocks base method.
func (m *MockAccountKeeper) BytesToString(bz []byte) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BytesToString", bz)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BytesToString indicates an expected call of BytesToString.
func (mr *MockAccountKeeperMockRecorder) BytesToString(bz interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BytesToString", reflect.TypeOf((*MockAccountKeeper)(nil).BytesToString), bz)
}
// GetAccount mocks base method.
func (m *MockAccountKeeper) GetAccount(ctx context.Context, addr types.AccAddress) types.AccountI {
m.ctrl.T.Helper()
@ -99,3 +114,18 @@ func (mr *MockAccountKeeperMockRecorder) GetModuleAddress(name interface{}) *gom
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetModuleAddress", reflect.TypeOf((*MockAccountKeeper)(nil).GetModuleAddress), name)
}
// StringToBytes mocks base method.
func (m *MockAccountKeeper) StringToBytes(text string) ([]byte, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StringToBytes", text)
ret0, _ := ret[0].([]byte)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// StringToBytes indicates an expected call of StringToBytes.
func (mr *MockAccountKeeperMockRecorder) StringToBytes(text interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StringToBytes", reflect.TypeOf((*MockAccountKeeper)(nil).StringToBytes), text)
}

View File

@ -3,6 +3,7 @@ package types
import (
context "context"
"cosmossdk.io/core/address"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -16,6 +17,8 @@ type DistributionKeeper interface {
// AccountKeeper defines the expected account keeper (noalias)
type AccountKeeper interface {
address.Codec
IterateAccounts(ctx context.Context, process func(sdk.AccountI) (stop bool))
GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI // only used for simulation
@ -24,11 +27,6 @@ type AccountKeeper interface {
// TODO remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862
SetModuleAccount(context.Context, sdk.ModuleAccountI)
// StringToBytes decodes address strings to bytes
StringToBytes(text string) ([]byte, error)
// BytesToString encodes address bytes to text
BytesToString(bz []byte) (string, error)
}
// BankKeeper defines the expected interface needed to retrieve account balances.