-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #155 from xpladev/fix/auth
fix: auth query
- Loading branch information
Showing
9 changed files
with
356 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"cosmossdk.io/collections" | ||
errorsmod "cosmossdk.io/errors" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
) | ||
|
||
// HasAccount implements AccountKeeperI. | ||
func (ak AccountKeeper) HasAccount(ctx context.Context, addr sdk.AccAddress) bool { | ||
addr, err := ak.getSliceAddress(ctx, addr) | ||
if err != nil { | ||
return false | ||
} | ||
has, err := ak.Accounts.Has(ctx, addr) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
return has | ||
} | ||
|
||
// GetAccount implements AccountKeeperI. | ||
func (ak AccountKeeper) GetAccount(ctx context.Context, addr sdk.AccAddress) (acc sdk.AccountI) { | ||
addr, err := ak.getSliceAddress(ctx, addr) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return ak.AccountKeeper.GetAccount(ctx, addr) | ||
} | ||
|
||
// GetSequence Returns the Sequence of the account at address | ||
func (ak AccountKeeper) GetSequence(ctx context.Context, addr sdk.AccAddress) (uint64, error) { | ||
acc := ak.GetAccount(ctx, addr) | ||
if acc == nil { | ||
return 0, errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", addr) | ||
} | ||
|
||
return acc.GetSequence(), nil | ||
} | ||
|
||
// SetAccount implements AccountKeeperI. | ||
func (ak AccountKeeper) SetAccount(ctx context.Context, acc sdk.AccountI) { | ||
address := acc.GetAddress() | ||
if len(address) != 20 { | ||
sliceAddress := address[len(address)-20:] | ||
ak.SliceAddresses.Set(ctx, sliceAddress, address) | ||
} | ||
ak.AccountKeeper.SetAccount(ctx, acc) | ||
} | ||
|
||
func (ak AccountKeeper) getSliceAddress(ctx context.Context, addr sdk.AccAddress) (sdk.AccAddress, error) { | ||
originalAddress, err := ak.SliceAddresses.Get(ctx, addr) | ||
if err != nil { | ||
if errors.Is(err, collections.ErrNotFound) { | ||
return addr, nil | ||
} | ||
return nil, err | ||
} | ||
|
||
return originalAddress, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package keeper | ||
|
||
import ( | ||
"testing" | ||
|
||
storetypes "cosmossdk.io/store/types" | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
ctestutil "github.com/cosmos/cosmos-sdk/codec/testutil" | ||
"github.com/cosmos/cosmos-sdk/runtime" | ||
"github.com/cosmos/cosmos-sdk/testutil" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" | ||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGetSliceAddress(t *testing.T) { | ||
|
||
storeKey := storetypes.NewKVStoreKey(authtypes.ModuleName) | ||
tKey := storetypes.NewTransientStoreKey("transient_test") | ||
ctx := testutil.DefaultContext(storeKey, tKey) | ||
|
||
interfaceRegistry := ctestutil.CodecOptions{}.NewInterfaceRegistry() | ||
authtypes.RegisterInterfaces(interfaceRegistry) | ||
cdc := codec.NewProtoCodec(interfaceRegistry) | ||
accountKeeper := NewAccountKeeper( | ||
cdc, | ||
runtime.NewKVStoreService(storeKey), | ||
authtypes.ProtoBaseAccount, | ||
map[string][]string{}, | ||
authcodec.NewBech32Codec(sdk.Bech32MainPrefix), | ||
sdk.Bech32MainPrefix, | ||
authtypes.NewModuleAddress(govtypes.ModuleName).String(), | ||
) | ||
|
||
original := sdk.MustAccAddressFromBech32("cosmos1qg5ega6dykkxc307y25pecuufrjkxkaggkkxh7nad0vhyhtuhw3s6ufdm4") | ||
valid := sdk.MustAccAddressFromBech32("cosmos1rn3ecj89vdd6s3dvd0a8667ewfwhewarkkd5wr") | ||
invalid := sdk.MustAccAddressFromBech32("cosmos1qg5ega6dykkxc307y25pecuufrjkxkags0q9gu") | ||
|
||
accountKeeper.SetAccount(ctx, authtypes.NewBaseAccount(original, nil, 0, 0)) | ||
|
||
assert.True(t, accountKeeper.HasAccount(ctx, original)) | ||
assert.True(t, accountKeeper.HasAccount(ctx, valid)) | ||
assert.False(t, accountKeeper.HasAccount(ctx, invalid)) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
|
||
codectypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" | ||
"github.com/cosmos/cosmos-sdk/x/auth/types" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
) | ||
|
||
var _ types.QueryServer = queryServer{} | ||
|
||
func NewQueryServer(k AccountKeeper) types.QueryServer { | ||
qs := authkeeper.NewQueryServer(k.AccountKeeper) | ||
return queryServer{ | ||
qs, | ||
k, | ||
} | ||
} | ||
|
||
type queryServer struct { | ||
types.QueryServer | ||
|
||
k AccountKeeper | ||
} | ||
|
||
func (s queryServer) AccountAddressByID(ctx context.Context, req *types.QueryAccountAddressByIDRequest) (*types.QueryAccountAddressByIDResponse, error) { | ||
return s.QueryServer.AccountAddressByID(ctx, req) | ||
} | ||
|
||
func (s queryServer) Accounts(ctx context.Context, req *types.QueryAccountsRequest) (*types.QueryAccountsResponse, error) { | ||
return s.QueryServer.Accounts(ctx, req) | ||
} | ||
|
||
// Account returns account details based on address | ||
func (s queryServer) Account(ctx context.Context, req *types.QueryAccountRequest) (*types.QueryAccountResponse, error) { | ||
if req == nil { | ||
return nil, status.Errorf(codes.InvalidArgument, "empty request") | ||
} | ||
|
||
if req.Address == "" { | ||
return nil, status.Error(codes.InvalidArgument, "Address cannot be empty") | ||
} | ||
|
||
addr, err := s.k.addressCodec.StringToBytes(req.Address) | ||
if err != nil { | ||
return nil, err | ||
} | ||
account := s.k.GetAccount(ctx, addr) | ||
if account == nil { | ||
return nil, status.Errorf(codes.NotFound, "account %s not found", req.Address) | ||
} | ||
|
||
any, err := codectypes.NewAnyWithValue(account) | ||
if err != nil { | ||
return nil, status.Errorf(codes.Internal, err.Error()) | ||
} | ||
|
||
return &types.QueryAccountResponse{Account: any}, nil | ||
} | ||
|
||
func (s queryServer) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { | ||
return s.QueryServer.Params(c, req) | ||
} | ||
|
||
func (s queryServer) ModuleAccounts(c context.Context, req *types.QueryModuleAccountsRequest) (*types.QueryModuleAccountsResponse, error) { | ||
return s.QueryServer.ModuleAccounts(c, req) | ||
} | ||
|
||
func (s queryServer) ModuleAccountByName(c context.Context, req *types.QueryModuleAccountByNameRequest) (*types.QueryModuleAccountByNameResponse, error) { | ||
return s.QueryServer.ModuleAccountByName(c, req) | ||
} | ||
|
||
func (s queryServer) Bech32Prefix(ctx context.Context, req *types.Bech32PrefixRequest) (*types.Bech32PrefixResponse, error) { | ||
return s.QueryServer.Bech32Prefix(ctx, req) | ||
} | ||
|
||
func (s queryServer) AddressBytesToString(ctx context.Context, req *types.AddressBytesToStringRequest) (*types.AddressBytesToStringResponse, error) { | ||
return s.QueryServer.AddressBytesToString(ctx, req) | ||
} | ||
|
||
func (s queryServer) AddressStringToBytes(ctx context.Context, req *types.AddressStringToBytesRequest) (*types.AddressStringToBytesResponse, error) { | ||
return s.QueryServer.AddressStringToBytes(ctx, req) | ||
} | ||
|
||
// AccountInfo implements the AccountInfo query. | ||
func (s queryServer) AccountInfo(ctx context.Context, req *types.QueryAccountInfoRequest) (*types.QueryAccountInfoResponse, error) { | ||
if req == nil { | ||
return nil, status.Errorf(codes.InvalidArgument, "empty request") | ||
} | ||
|
||
if req.Address == "" { | ||
return nil, status.Error(codes.InvalidArgument, "address cannot be empty") | ||
} | ||
|
||
addr, err := s.k.addressCodec.StringToBytes(req.Address) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
account := s.k.GetAccount(ctx, addr) | ||
if account == nil { | ||
return nil, status.Errorf(codes.NotFound, "account %s not found", req.Address) | ||
} | ||
|
||
// if there is no public key, avoid serializing the nil value | ||
pubKey := account.GetPubKey() | ||
var pkAny *codectypes.Any | ||
if pubKey != nil { | ||
pkAny, err = codectypes.NewAnyWithValue(account.GetPubKey()) | ||
if err != nil { | ||
return nil, status.Errorf(codes.Internal, err.Error()) | ||
} | ||
} | ||
|
||
return &types.QueryAccountInfoResponse{ | ||
Info: &types.BaseAccount{ | ||
Address: req.Address, | ||
PubKey: pkAny, | ||
AccountNumber: account.GetAccountNumber(), | ||
Sequence: account.GetSequence(), | ||
}, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package keeper | ||
|
||
import ( | ||
"cosmossdk.io/collections" | ||
ccodec "cosmossdk.io/collections/codec" | ||
"cosmossdk.io/core/address" | ||
"cosmossdk.io/core/store" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" | ||
|
||
"github.com/xpladev/xpla/x/auth/types" | ||
) | ||
|
||
type AccountKeeper struct { | ||
authkeeper.AccountKeeper | ||
|
||
addressCodec address.Codec | ||
|
||
cdc codec.BinaryCodec | ||
storeService store.KVStoreService | ||
|
||
// State | ||
SliceAddresses collections.Map[sdk.AccAddress, sdk.AccAddress] | ||
} | ||
|
||
func NewAccountKeeper( | ||
cdc codec.BinaryCodec, storeService store.KVStoreService, proto func() sdk.AccountI, | ||
maccPerms map[string][]string, ac address.Codec, bech32Prefix, authority string, | ||
) AccountKeeper { | ||
|
||
sb := collections.NewSchemaBuilder(storeService) | ||
|
||
ak := AccountKeeper{ | ||
AccountKeeper: authkeeper.NewAccountKeeper(cdc, storeService, proto, maccPerms, ac, bech32Prefix, authority), | ||
addressCodec: ac, | ||
cdc: cdc, | ||
storeService: storeService, | ||
SliceAddresses: collections.NewMap(sb, types.SliceAddressStoreKeyPrefix, "sliceAddresses", sdk.AccAddressKey, ccodec.KeyToValueCodec(sdk.AccAddressKey)), | ||
} | ||
|
||
return ak | ||
} |
Oops, something went wrong.