186 lines
5.7 KiB
Go
186 lines
5.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
gogotypes "github.com/cosmos/gogoproto/types"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"cosmossdk.io/x/accounts/accountstd"
|
|
basev1 "cosmossdk.io/x/accounts/defaults/base/v1"
|
|
|
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
|
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
)
|
|
|
|
var _ accountstd.Interface = mockRetroCompatAccount{}
|
|
|
|
type mockRetroCompatAccount struct {
|
|
retroCompat *authtypes.QueryLegacyAccountResponse
|
|
address []byte
|
|
}
|
|
|
|
var (
|
|
valid = &mockRetroCompatAccount{
|
|
retroCompat: &authtypes.QueryLegacyAccountResponse{
|
|
Account: &codectypes.Any{},
|
|
Base: &authtypes.BaseAccount{
|
|
Address: "test",
|
|
PubKey: nil,
|
|
AccountNumber: 10,
|
|
Sequence: 20,
|
|
},
|
|
},
|
|
}
|
|
|
|
noInfo = &mockRetroCompatAccount{
|
|
retroCompat: &authtypes.QueryLegacyAccountResponse{
|
|
Account: &codectypes.Any{},
|
|
},
|
|
}
|
|
noImplement = &mockRetroCompatAccount{
|
|
retroCompat: nil,
|
|
}
|
|
)
|
|
|
|
func newMockRetroCompatAccount(name string, acc accountstd.Interface) accountstd.AccountCreatorFunc {
|
|
return func(_ accountstd.Dependencies) (string, accountstd.Interface, error) {
|
|
_, ok := acc.(*mockRetroCompatAccount)
|
|
if !ok {
|
|
return name, nil, errors.New("invalid account type")
|
|
}
|
|
return name, acc, nil
|
|
}
|
|
}
|
|
|
|
func ProvideMockRetroCompatAccountValid() accountstd.DepinjectAccount {
|
|
return accountstd.DepinjectAccount{MakeAccount: newMockRetroCompatAccount("valid", valid)}
|
|
}
|
|
|
|
func ProvideMockRetroCompatAccountNoInfo() accountstd.DepinjectAccount {
|
|
return accountstd.DepinjectAccount{MakeAccount: newMockRetroCompatAccount("no_info", noInfo)}
|
|
}
|
|
|
|
func ProvideMockRetroCompatAccountNoImplement() accountstd.DepinjectAccount {
|
|
return accountstd.DepinjectAccount{MakeAccount: newMockRetroCompatAccount("no_implement", noImplement)}
|
|
}
|
|
|
|
func (m mockRetroCompatAccount) RegisterInitHandler(builder *accountstd.InitBuilder) {
|
|
accountstd.RegisterInitHandler(builder, func(ctx context.Context, req *gogotypes.Empty) (*gogotypes.Empty, error) {
|
|
return &gogotypes.Empty{}, nil
|
|
})
|
|
}
|
|
|
|
func (m mockRetroCompatAccount) RegisterExecuteHandlers(_ *accountstd.ExecuteBuilder) {}
|
|
|
|
func (m mockRetroCompatAccount) RegisterQueryHandlers(builder *accountstd.QueryBuilder) {
|
|
if m.retroCompat == nil {
|
|
return
|
|
}
|
|
accountstd.RegisterQueryHandler(builder, func(ctx context.Context, req *authtypes.QueryLegacyAccount) (*authtypes.QueryLegacyAccountResponse, error) {
|
|
return m.retroCompat, nil
|
|
})
|
|
}
|
|
|
|
func TestAuthToAccountsGRPCCompat(t *testing.T) {
|
|
accs := map[string]accountstd.Interface{
|
|
"valid": valid,
|
|
"no_info": noInfo,
|
|
"no_implement": noImplement,
|
|
}
|
|
|
|
f := createTestSuite(t)
|
|
|
|
// init three accounts
|
|
for n, a := range accs {
|
|
_, addr, err := f.accountsKeeper.Init(f.ctx, n, []byte("me"), &gogotypes.Empty{}, nil, nil)
|
|
require.NoError(t, err)
|
|
a.(*mockRetroCompatAccount).address = addr
|
|
}
|
|
|
|
qs := authkeeper.NewQueryServer(f.authKeeper)
|
|
|
|
t.Run("account supports info and account query", func(t *testing.T) {
|
|
infoResp, err := qs.AccountInfo(f.ctx, &authtypes.QueryAccountInfoRequest{
|
|
Address: f.mustAddr(valid.address),
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, infoResp.Info, valid.retroCompat.Base)
|
|
|
|
accountResp, err := qs.Account(f.ctx, &authtypes.QueryAccountRequest{
|
|
Address: f.mustAddr(noInfo.address),
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, accountResp.Account, valid.retroCompat.Account)
|
|
})
|
|
|
|
t.Run("account only supports account query, not info", func(t *testing.T) {
|
|
_, err := qs.AccountInfo(f.ctx, &authtypes.QueryAccountInfoRequest{
|
|
Address: f.mustAddr(noInfo.address),
|
|
})
|
|
require.Error(t, err)
|
|
require.Equal(t, status.Code(err), codes.NotFound)
|
|
|
|
resp, err := qs.Account(f.ctx, &authtypes.QueryAccountRequest{
|
|
Address: f.mustAddr(noInfo.address),
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, resp.Account, valid.retroCompat.Account)
|
|
})
|
|
|
|
t.Run("account does not support any retro compat", func(t *testing.T) {
|
|
_, err := qs.AccountInfo(f.ctx, &authtypes.QueryAccountInfoRequest{
|
|
Address: f.mustAddr(noImplement.address),
|
|
})
|
|
require.Error(t, err)
|
|
require.Equal(t, status.Code(err), codes.NotFound)
|
|
|
|
_, err = qs.Account(f.ctx, &authtypes.QueryAccountRequest{
|
|
Address: f.mustAddr(noImplement.address),
|
|
})
|
|
|
|
require.Error(t, err)
|
|
require.Equal(t, status.Code(err), codes.NotFound)
|
|
})
|
|
}
|
|
|
|
func TestAccountsBaseAccountRetroCompat(t *testing.T) {
|
|
f := createTestSuite(t)
|
|
// init a base acc
|
|
anyPk, err := codectypes.NewAnyWithValue(secp256k1.GenPrivKey().PubKey())
|
|
require.NoError(t, err)
|
|
|
|
// we init two accounts. Account number should start with 4
|
|
// since the first three accounts are fee_collector, bonded_tokens_pool, not_bonded_tokens_pool
|
|
// generated by init genesis plus one more genesis account, which make the current account number 4.
|
|
_, _, err = f.accountsKeeper.Init(f.ctx, "base", []byte("me"), &basev1.MsgInit{PubKey: anyPk}, nil, nil)
|
|
require.NoError(t, err)
|
|
|
|
_, addr, err := f.accountsKeeper.Init(f.ctx, "base", []byte("me"), &basev1.MsgInit{PubKey: anyPk}, nil, nil)
|
|
require.NoError(t, err)
|
|
|
|
// try to query it via auth
|
|
qs := authkeeper.NewQueryServer(f.authKeeper)
|
|
|
|
r, err := qs.Account(f.ctx, &authtypes.QueryAccountRequest{
|
|
Address: f.mustAddr(addr),
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, r.Account)
|
|
|
|
info, err := qs.AccountInfo(f.ctx, &authtypes.QueryAccountInfoRequest{
|
|
Address: f.mustAddr(addr),
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, info.Info)
|
|
require.Equal(t, info.Info.PubKey, anyPk)
|
|
// Account number should be 5
|
|
require.Equal(t, info.Info.AccountNumber, uint64(5))
|
|
}
|