feat(accounts): Add message server and query server logic. (#17614)

Co-authored-by: unknown unknown <unknown@unknown>
Co-authored-by: samricotta <37125168+samricotta@users.noreply.github.com>
This commit is contained in:
testinginprod 2023-09-07 09:42:23 +02:00 committed by GitHub
parent 943f2860a1
commit c60283b91a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 5780 additions and 72 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,10 @@
package accountsv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
@ -15,12 +18,16 @@ import (
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const ()
const (
Query_AccountQuery_FullMethodName = "/cosmos.accounts.v1.Query/AccountQuery"
)
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type QueryClient interface {
// AccountQuery runs an account query.
AccountQuery(ctx context.Context, in *AccountQueryRequest, opts ...grpc.CallOption) (*AccountQueryResponse, error)
}
type queryClient struct {
@ -31,10 +38,21 @@ func NewQueryClient(cc grpc.ClientConnInterface) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) AccountQuery(ctx context.Context, in *AccountQueryRequest, opts ...grpc.CallOption) (*AccountQueryResponse, error) {
out := new(AccountQueryResponse)
err := c.cc.Invoke(ctx, Query_AccountQuery_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
// All implementations must embed UnimplementedQueryServer
// for forward compatibility
type QueryServer interface {
// AccountQuery runs an account query.
AccountQuery(context.Context, *AccountQueryRequest) (*AccountQueryResponse, error)
mustEmbedUnimplementedQueryServer()
}
@ -42,6 +60,9 @@ type QueryServer interface {
type UnimplementedQueryServer struct {
}
func (UnimplementedQueryServer) AccountQuery(context.Context, *AccountQueryRequest) (*AccountQueryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AccountQuery not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service.
@ -55,13 +76,36 @@ func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) {
s.RegisterService(&Query_ServiceDesc, srv)
}
func _Query_AccountQuery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AccountQueryRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).AccountQuery(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_AccountQuery_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).AccountQuery(ctx, req.(*AccountQueryRequest))
}
return interceptor(ctx, in, info, handler)
}
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Query_ServiceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.accounts.v1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/query.proto",
Methods: []grpc.MethodDesc{
{
MethodName: "AccountQuery",
Handler: _Query_AccountQuery_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/query.proto",
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,10 @@
package accountsv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
@ -15,12 +18,19 @@ import (
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const ()
const (
Msg_Init_FullMethodName = "/cosmos.accounts.v1.Msg/Init"
Msg_Execute_FullMethodName = "/cosmos.accounts.v1.Msg/Execute"
)
// MsgClient is the client API for Msg service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type MsgClient interface {
// Init creates a new account in the chain.
Init(ctx context.Context, in *MsgInit, opts ...grpc.CallOption) (*MsgInitResponse, error)
// Execute executes a message to the target account.
Execute(ctx context.Context, in *MsgExecute, opts ...grpc.CallOption) (*MsgExecuteResponse, error)
}
type msgClient struct {
@ -31,10 +41,32 @@ func NewMsgClient(cc grpc.ClientConnInterface) MsgClient {
return &msgClient{cc}
}
func (c *msgClient) Init(ctx context.Context, in *MsgInit, opts ...grpc.CallOption) (*MsgInitResponse, error) {
out := new(MsgInitResponse)
err := c.cc.Invoke(ctx, Msg_Init_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *msgClient) Execute(ctx context.Context, in *MsgExecute, opts ...grpc.CallOption) (*MsgExecuteResponse, error) {
out := new(MsgExecuteResponse)
err := c.cc.Invoke(ctx, Msg_Execute_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// MsgServer is the server API for Msg service.
// All implementations must embed UnimplementedMsgServer
// for forward compatibility
type MsgServer interface {
// Init creates a new account in the chain.
Init(context.Context, *MsgInit) (*MsgInitResponse, error)
// Execute executes a message to the target account.
Execute(context.Context, *MsgExecute) (*MsgExecuteResponse, error)
mustEmbedUnimplementedMsgServer()
}
@ -42,6 +74,12 @@ type MsgServer interface {
type UnimplementedMsgServer struct {
}
func (UnimplementedMsgServer) Init(context.Context, *MsgInit) (*MsgInitResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Init not implemented")
}
func (UnimplementedMsgServer) Execute(context.Context, *MsgExecute) (*MsgExecuteResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented")
}
func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {}
// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service.
@ -55,13 +93,58 @@ func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) {
s.RegisterService(&Msg_ServiceDesc, srv)
}
func _Msg_Init_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgInit)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).Init(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_Init_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).Init(ctx, req.(*MsgInit))
}
return interceptor(ctx, in, info, handler)
}
func _Msg_Execute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgExecute)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).Execute(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_Execute_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).Execute(ctx, req.(*MsgExecute))
}
return interceptor(ctx, in, info, handler)
}
// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Msg_ServiceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.accounts.v1.Msg",
HandlerType: (*MsgServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/tx.proto",
Methods: []grpc.MethodDesc{
{
MethodName: "Init",
Handler: _Msg_Init_Handler,
},
{
MethodName: "Execute",
Handler: _Msg_Execute_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/tx.proto",
}

View File

@ -1,4 +1,5 @@
syntax = "proto3";
package cosmos.accounts.v1;
option go_package = "cosmossdk.io/x/accounts/v1";
option go_package = "cosmossdk.io/x/accounts/v1";

View File

@ -1,7 +1,25 @@
syntax = "proto3";
package cosmos.accounts.v1;
option go_package = "cosmossdk.io/x/accounts/v1";
option go_package = "cosmossdk.io/x/accounts/v1";
// Query defines the Query service for the x/accounts module.
service Query {}
service Query {
// AccountQuery runs an account query.
rpc AccountQuery(AccountQueryRequest) returns (AccountQueryResponse) {};
}
// AccountQueryRequest is the request type for the Query/AccountQuery RPC
message AccountQueryRequest {
// target defines the account to be queried.
string target = 1;
// request defines the query message being sent to the account.
bytes request = 2;
}
// AccountQueryResponse is the response type for the Query/AccountQuery RPC method.
message AccountQueryResponse {
// response defines the query response of the account.
bytes response = 1;
}

View File

@ -1,7 +1,50 @@
syntax = "proto3";
package cosmos.accounts.v1;
option go_package = "cosmossdk.io/x/accounts/v1";
option go_package = "cosmossdk.io/x/accounts/v1";
// Msg defines the Msg service for the x/accounts module.
service Msg {}
service Msg {
// Init creates a new account in the chain.
rpc Init(MsgInit) returns (MsgInitResponse);
// Execute executes a message to the target account.
rpc Execute(MsgExecute) returns (MsgExecuteResponse);
}
// MsgInit defines the Create request type for the Msg/Create RPC method.
message MsgInit {
// sender is the address of the sender of this message.
string sender = 1;
// account_type is the type of the account to be created.
string account_type = 2;
// message is the message to be sent to the account, it's up to the account
// implementation to decide what encoding format should be used to interpret
// this message.
bytes message = 3;
}
// MsgInitResponse defines the Create response type for the Msg/Create RPC method.
message MsgInitResponse {
// account_address is the address of the newly created account.
string account_address = 1;
// response is the response returned by the account implementation.
bytes response = 2;
}
// MsgExecute defines the Execute request type for the Msg/Execute RPC method.
message MsgExecute {
// sender is the address of the sender of this message.
string sender = 1;
// target is the address of the account to be executed.
string target = 2;
// message is the message to be sent to the account, it's up to the account
bytes message = 3;
}
// MsgExecuteResponse defines the Execute response type for the Msg/Execute RPC method.
message MsgExecuteResponse {
// response is the response returned by the account implementation.
bytes response = 1;
}

View File

@ -4,6 +4,9 @@
# docker build --pull --rm -f "contrib/devtools/Dockerfile" -t cosmossdk-proto:latest "contrib/devtools"
# docker run --rm -v $(pwd):/workspace --workdir /workspace cosmossdk-proto sh ./scripts/protocgen.sh
echo "Formatting protobuf files"
find ./ -name "*.proto" -exec clang-format -i {} \;
set -e
echo "Generating gogo proto code"
@ -36,5 +39,3 @@ go mod tidy
./scripts/protocgen-pulsar.sh
echo "Formatting protobuf files"
find ./ -name "*.proto" -exec clang-format -i {} \;

View File

@ -2,8 +2,10 @@ package accounts
import (
"context"
"strconv"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
"cosmossdk.io/x/accounts/internal/implementation"
)
@ -22,10 +24,23 @@ func (t TestAccount) RegisterExecuteHandlers(builder *implementation.ExecuteBuil
implementation.RegisterExecuteHandler(builder, func(_ context.Context, _ *emptypb.Empty) (*emptypb.Empty, error) {
return &emptypb.Empty{}, nil
})
implementation.RegisterExecuteHandler(builder, func(_ context.Context, req *wrapperspb.StringValue) (*wrapperspb.UInt64Value, error) {
value, err := strconv.ParseUint(req.Value, 10, 64)
if err != nil {
return nil, err
}
return wrapperspb.UInt64(value), nil
})
}
func (t TestAccount) RegisterQueryHandlers(builder *implementation.QueryBuilder) {
implementation.RegisterQueryHandler(builder, func(_ context.Context, _ *emptypb.Empty) (*emptypb.Empty, error) {
return &emptypb.Empty{}, nil
})
implementation.RegisterQueryHandler(builder, func(_ context.Context, req *wrapperspb.UInt64Value) (*wrapperspb.StringValue, error) {
return wrapperspb.String(strconv.FormatUint(req.Value, 10)), nil
})
}

View File

@ -5,7 +5,9 @@ import (
"errors"
"fmt"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/known/anypb"
)
var (
@ -25,6 +27,12 @@ type InitBuilder struct {
// Although the function here is defined to take an any, the smart account will work
// with a typed version of it.
handler func(ctx context.Context, initRequest any) (initResponse any, err error)
// decodeRequest is the function that will be used to decode the init request from bytes.
decodeRequest func([]byte) (any, error)
// encodeResponse is the function that will be used to encode the init response to bytes.
encodeResponse func(any) ([]byte, error)
}
// makeHandler returns the handler function that will be called when the smart account is initialized.
@ -48,7 +56,6 @@ func NewExecuteBuilder() *ExecuteBuilder {
type ExecuteBuilder struct {
// handlers is a map of handler functions that will be called when the smart account is executed.
handlers map[string]func(ctx context.Context, executeRequest any) (executeResponse any, err error)
// err is the error that occurred before building the handler function.
err error
}
@ -87,6 +94,42 @@ func (r *ExecuteBuilder) makeHandler() (func(ctx context.Context, executeRequest
}, nil
}
func (r *ExecuteBuilder) makeRequestDecoder() func(requestBytes []byte) (any, error) {
return func(requestBytes []byte) (any, error) {
anyPB := new(anypb.Any)
err := proto.Unmarshal(requestBytes, anyPB)
if err != nil {
return nil, err
}
msg, err := anyPB.UnmarshalNew()
if err != nil {
return nil, err
}
// we do not check if it is part of a valid message set as an account can handle
// and the handler will do so.
return msg, nil
}
}
func (r *ExecuteBuilder) makeResponseEncoder() func(executeResponse any) ([]byte, error) {
return func(executeResponse any) ([]byte, error) {
executeResponsePB, ok := executeResponse.(protoreflect.ProtoMessage)
if !ok {
return nil, fmt.Errorf("%w: expected protoreflect.Message, got %T", errInvalidMessage, executeResponse)
}
anyPB, err := anypb.New(executeResponsePB)
if err != nil {
return nil, err
}
// we do not check if it is part of an account's valid response message set
// as make handler will never allow for an invalid response to be returned.
return proto.Marshal(anyPB)
}
}
// NewQueryBuilder creates a new QueryBuilder instance.
func NewQueryBuilder() *QueryBuilder {
return &QueryBuilder{

View File

@ -28,9 +28,15 @@ func NewImplementation(account Account) (Implementation, error) {
return Implementation{}, err
}
return Implementation{
Init: initHandler,
Execute: executeHandler,
Query: queryHandler,
Init: initHandler,
Execute: executeHandler,
Query: queryHandler,
DecodeInitRequest: ir.decodeRequest,
EncodeInitResponse: ir.encodeResponse,
DecodeExecuteRequest: er.makeRequestDecoder(),
EncodeExecuteResponse: er.makeResponseEncoder(),
DecodeQueryRequest: qr.er.makeRequestDecoder(),
EncodeQueryResponse: qr.er.makeResponseEncoder(),
}, nil
}
@ -43,4 +49,21 @@ type Implementation struct {
Execute func(ctx context.Context, msg any) (resp any, err error)
// Query defines the query handler for the smart account.
Query func(ctx context.Context, msg any) (resp any, err error)
// Schema
// DecodeInitRequest decodes an init request coming from the message server.
DecodeInitRequest func([]byte) (any, error)
// EncodeInitResponse encodes an init response to be sent back from the message server.
EncodeInitResponse func(any) ([]byte, error)
// DecodeExecuteRequest decodes an execute request coming from the message server.
DecodeExecuteRequest func([]byte) (any, error)
// EncodeExecuteResponse encodes an execute response to be sent back from the message server.
EncodeExecuteResponse func(any) ([]byte, error)
// DecodeQueryRequest decodes a query request coming from the message server.
DecodeQueryRequest func([]byte) (any, error)
// EncodeQueryResponse encodes a query response to be sent back from the message server.
EncodeQueryResponse func(any) ([]byte, error)
}

View File

@ -5,6 +5,9 @@ import (
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
@ -63,4 +66,60 @@ func TestImplementation(t *testing.T) {
_, err = impl.Init(ctx, "test")
require.ErrorIs(t, err, errInvalidMessage)
})
// schemas
t.Run("decode init request - ok", func(t *testing.T) {
want := &wrapperspb.StringValue{Value: "test"}
req, err := proto.Marshal(want)
require.NoError(t, err)
got, err := impl.DecodeInitRequest(req)
require.NoError(t, err)
require.True(t, proto.Equal(want, got.(protoreflect.ProtoMessage)))
})
t.Run("encode init response - ok", func(t *testing.T) {
want := &wrapperspb.StringValue{Value: "test"}
gotBytes, err := impl.EncodeInitResponse(want)
require.NoError(t, err)
wantBytes, err := proto.Marshal(want)
require.NoError(t, err)
require.Equal(t, wantBytes, gotBytes)
})
t.Run("encode init response - invalid message", func(t *testing.T) {
_, err := impl.EncodeInitResponse([]byte("invalid"))
require.ErrorIs(t, err, errInvalidMessage)
})
t.Run("decode execute request - ok", func(t *testing.T) {
wantReq := &wrapperspb.StringValue{Value: "test"}
anyBPReq, err := anypb.New(wantReq)
require.NoError(t, err)
reqBytes, err := proto.Marshal(anyBPReq)
require.NoError(t, err)
gotReq, err := impl.DecodeExecuteRequest(reqBytes)
require.NoError(t, err)
require.True(t, proto.Equal(wantReq, gotReq.(protoreflect.ProtoMessage)))
})
t.Run("encode execute response - ok", func(t *testing.T) {
resp := &wrapperspb.StringValue{Value: "test"}
gotRespBytes, err := impl.EncodeExecuteResponse(resp)
require.NoError(t, err)
anyPBResp, err := anypb.New(resp)
require.NoError(t, err)
wantRespBytes, err := proto.Marshal(anyPBResp)
require.NoError(t, err)
require.Equal(t, wantRespBytes, gotRespBytes)
})
t.Run("encode execute response - not a protobuf message", func(t *testing.T) {
_, err := impl.EncodeExecuteResponse("test")
require.ErrorIs(t, err, errInvalidMessage)
require.ErrorContains(t, err, "expected protoreflect.Message")
})
}

View File

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
)
@ -18,6 +19,8 @@ func RegisterInitHandler[
Req any, ProtoReq ProtoMsg[Req], Resp any, ProtoResp ProtoMsg[Resp],
](router *InitBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error)) {
reqName := ProtoReq(new(Req)).ProtoReflect().Descriptor().FullName()
respName := ProtoResp(new(Resp)).ProtoReflect().Descriptor().FullName()
router.handler = func(ctx context.Context, initRequest any) (initResponse any, err error) {
concrete, ok := initRequest.(ProtoReq)
if !ok {
@ -25,6 +28,20 @@ func RegisterInitHandler[
}
return handler(ctx, concrete)
}
router.decodeRequest = func(b []byte) (any, error) {
req := new(Req)
err := proto.Unmarshal(b, ProtoReq(req))
return req, err
}
router.encodeResponse = func(resp any) ([]byte, error) {
protoResp, ok := resp.(ProtoResp)
if !ok {
return nil, fmt.Errorf("%w: wanted %s, got %T", errInvalidMessage, respName, resp)
}
return proto.Marshal(protoResp)
}
}
// RegisterExecuteHandler registers an execution handler for a smart account that uses protobuf.

View File

@ -8,6 +8,7 @@ import (
"fmt"
"cosmossdk.io/collections"
"cosmossdk.io/core/address"
"cosmossdk.io/core/store"
"cosmossdk.io/x/accounts/internal/implementation"
)
@ -21,10 +22,11 @@ var (
AccountNumberKey = collections.NewPrefix(1)
)
func NewKeeper(ss store.KVStoreService, accounts map[string]implementation.Account) (Keeper, error) {
func NewKeeper(ss store.KVStoreService, addressCodec address.Codec, accounts map[string]implementation.Account) (Keeper, error) {
sb := collections.NewSchemaBuilder(ss)
keeper := Keeper{
storeService: ss,
addressCodec: addressCodec,
accounts: map[string]implementation.Implementation{},
AccountNumber: collections.NewSequence(sb, AccountNumberKey, "account_number"),
AccountsByType: collections.NewMap(sb, AccountTypeKeyPrefix, "accounts_by_type", collections.BytesKey, collections.StringValue),
@ -51,17 +53,18 @@ type Keeper struct {
accounts map[string]implementation.Implementation
addressCodec address.Codec
// Schema is the schema for the module.
Schema collections.Schema
// AccountNumber is the last global account number.
AccountNumber collections.Sequence
// AccountsByType maps account address to their implementation.
AccountsByType collections.Map[[]byte, string]
}
// Create creates a new account of the given type.
func (k Keeper) Create(
// Init creates a new account of the given type.
func (k Keeper) Init(
ctx context.Context,
accountType string,
creator []byte,

View File

@ -9,13 +9,21 @@ import (
"cosmossdk.io/collections"
"cosmossdk.io/collections/colltest"
"cosmossdk.io/core/address"
"cosmossdk.io/x/accounts/internal/implementation"
)
var _ address.Codec = (*addressCodec)(nil)
type addressCodec struct{}
func (a addressCodec) StringToBytes(text string) ([]byte, error) { return []byte(text), nil }
func (a addressCodec) BytesToString(bz []byte) (string, error) { return string(bz), nil }
func newKeeper(t *testing.T, accounts map[string]implementation.Account) (Keeper, context.Context) {
t.Helper()
ss, ctx := colltest.MockStore()
m, err := NewKeeper(ss, accounts)
m, err := NewKeeper(ss, addressCodec{}, accounts)
require.NoError(t, err)
return m, ctx
}
@ -28,7 +36,7 @@ func TestKeeper_Create(t *testing.T) {
t.Run("ok", func(t *testing.T) {
sender := []byte("sender")
resp, addr, err := m.Create(ctx, "test", sender, &emptypb.Empty{})
resp, addr, err := m.Init(ctx, "test", sender, &emptypb.Empty{})
require.NoError(t, err)
require.Equal(t, &emptypb.Empty{}, resp)
require.NotNil(t, addr)
@ -45,7 +53,7 @@ func TestKeeper_Create(t *testing.T) {
})
t.Run("unknown account type", func(t *testing.T) {
_, _, err := m.Create(ctx, "unknown", []byte("sender"), &emptypb.Empty{})
_, _, err := m.Init(ctx, "unknown", []byte("sender"), &emptypb.Empty{})
require.ErrorIs(t, err, errAccountTypeNotFound)
})
}
@ -57,7 +65,7 @@ func TestKeeper_Execute(t *testing.T) {
// create account
sender := []byte("sender")
_, accAddr, err := m.Create(ctx, "test", sender, &emptypb.Empty{})
_, accAddr, err := m.Init(ctx, "test", sender, &emptypb.Empty{})
require.NoError(t, err)
t.Run("ok", func(t *testing.T) {
@ -79,7 +87,7 @@ func TestKeeper_Query(t *testing.T) {
// create account
sender := []byte("sender")
_, accAddr, err := m.Create(ctx, "test", sender, &emptypb.Empty{})
_, accAddr, err := m.Init(ctx, "test", sender, &emptypb.Empty{})
require.NoError(t, err)
t.Run("ok", func(t *testing.T) {

105
x/accounts/msg_server.go Normal file
View File

@ -0,0 +1,105 @@
package accounts
import (
"context"
v1 "cosmossdk.io/x/accounts/v1"
)
var _ v1.MsgServer = msgServer{}
func NewMsgServer(k Keeper) v1.MsgServer {
return &msgServer{k}
}
type msgServer struct {
k Keeper
}
func (m msgServer) Init(ctx context.Context, request *v1.MsgInit) (*v1.MsgInitResponse, error) {
creator, err := m.k.addressCodec.StringToBytes(request.Sender)
if err != nil {
return nil, err
}
impl, err := m.k.getImplementation(request.AccountType)
if err != nil {
return nil, err
}
// decode message bytes into the concrete boxed message type
msg, err := impl.DecodeInitRequest(request.Message)
if err != nil {
return nil, err
}
// run account creation logic
resp, accAddr, err := m.k.Init(ctx, request.AccountType, creator, msg)
if err != nil {
return nil, err
}
// encode the response
respBytes, err := impl.EncodeInitResponse(resp)
if err != nil {
return nil, err
}
// encode the address
accAddrString, err := m.k.addressCodec.BytesToString(accAddr)
if err != nil {
return nil, err
}
return &v1.MsgInitResponse{
AccountAddress: accAddrString,
Response: respBytes,
}, nil
}
func (m msgServer) Execute(ctx context.Context, execute *v1.MsgExecute) (*v1.MsgExecuteResponse, error) {
// decode sender address
senderAddr, err := m.k.addressCodec.StringToBytes(execute.Sender)
if err != nil {
return nil, err
}
// decode the target address
targetAddr, err := m.k.addressCodec.StringToBytes(execute.Target)
if err != nil {
return nil, err
}
// get account type
accType, err := m.k.AccountsByType.Get(ctx, targetAddr)
if err != nil {
return nil, err
}
// get the implementation
impl, err := m.k.getImplementation(accType)
if err != nil {
return nil, err
}
// decode message bytes into the concrete boxed message type
req, err := impl.DecodeExecuteRequest(execute.Message)
if err != nil {
return nil, err
}
// run account execution logic
resp, err := m.k.Execute(ctx, targetAddr, senderAddr, req)
if err != nil {
return nil, err
}
// encode the response
respBytes, err := impl.EncodeExecuteResponse(resp)
if err != nil {
return nil, err
}
return &v1.MsgExecuteResponse{
Response: respBytes,
}, nil
}

View File

@ -0,0 +1,52 @@
package accounts
import (
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
"cosmossdk.io/x/accounts/internal/implementation"
v1 "cosmossdk.io/x/accounts/v1"
)
func TestMsgServer(t *testing.T) {
k, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
s := NewMsgServer(k)
// create
initMsg, err := proto.Marshal(&emptypb.Empty{})
require.NoError(t, err)
initResp, err := s.Init(ctx, &v1.MsgInit{
Sender: "sender",
AccountType: "test",
Message: initMsg,
})
require.NoError(t, err)
require.NotNil(t, initResp)
// execute
executeMsg := &wrapperspb.StringValue{
Value: "10",
}
executeMsgAny, err := anypb.New(executeMsg)
require.NoError(t, err)
executeMsgBytes, err := proto.Marshal(executeMsgAny)
require.NoError(t, err)
execResp, err := s.Execute(ctx, &v1.MsgExecute{
Sender: "sender",
Target: initResp.AccountAddress,
Message: executeMsgBytes,
})
require.NoError(t, err)
require.NotNil(t, execResp)
}

View File

@ -0,0 +1,58 @@
package accounts
import (
"context"
v1 "cosmossdk.io/x/accounts/v1"
)
var _ v1.QueryServer = queryServer{}
func NewQueryServer(k Keeper) v1.QueryServer {
return &queryServer{k}
}
type queryServer struct {
k Keeper
}
func (q queryServer) AccountQuery(ctx context.Context, request *v1.AccountQueryRequest) (*v1.AccountQueryResponse, error) {
// get target addr
targetAddr, err := q.k.addressCodec.StringToBytes(request.Target)
if err != nil {
return nil, err
}
// get acc type
accType, err := q.k.AccountsByType.Get(ctx, targetAddr)
if err != nil {
return nil, err
}
// get impl
impl, err := q.k.getImplementation(accType)
if err != nil {
return nil, err
}
// decode req into boxed concrete type
queryReq, err := impl.DecodeQueryRequest(request.Request)
if err != nil {
return nil, err
}
// run query
resp, err := q.k.Query(ctx, targetAddr, queryReq)
if err != nil {
return nil, err
}
// encode response
respBytes, err := impl.EncodeQueryResponse(resp)
if err != nil {
return nil, err
}
return &v1.AccountQueryResponse{
Response: respBytes,
}, nil
}

View File

@ -0,0 +1,57 @@
package accounts
import (
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
"cosmossdk.io/x/accounts/internal/implementation"
v1 "cosmossdk.io/x/accounts/v1"
)
func TestQueryServer(t *testing.T) {
k, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
ms := NewMsgServer(k)
qs := NewQueryServer(k)
// create
initMsg, err := proto.Marshal(&emptypb.Empty{})
require.NoError(t, err)
initResp, err := ms.Init(ctx, &v1.MsgInit{
Sender: "sender",
AccountType: "test",
Message: initMsg,
})
require.NoError(t, err)
// query
req := &wrapperspb.UInt64Value{Value: 10}
anypbReq, err := anypb.New(req)
require.NoError(t, err)
anypbReqBytes, err := proto.Marshal(anypbReq)
require.NoError(t, err)
queryResp, err := qs.AccountQuery(ctx, &v1.AccountQueryRequest{
Target: initResp.AccountAddress,
Request: anypbReqBytes,
})
require.NoError(t, err)
respAnyPB := &anypb.Any{}
err = proto.Unmarshal(queryResp.Response, respAnyPB)
require.NoError(t, err)
resp, err := respAnyPB.UnmarshalNew()
require.NoError(t, err)
require.Equal(t, "10", resp.(*wrapperspb.StringValue).Value)
}

View File

@ -9,7 +9,11 @@ import (
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
@ -23,18 +27,130 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// AccountQueryRequest is the request type for the Query/AccountQuery RPC
type AccountQueryRequest struct {
// target defines the account to be queried.
Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"`
// request defines the query message being sent to the account.
Request []byte `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"`
}
func (m *AccountQueryRequest) Reset() { *m = AccountQueryRequest{} }
func (m *AccountQueryRequest) String() string { return proto.CompactTextString(m) }
func (*AccountQueryRequest) ProtoMessage() {}
func (*AccountQueryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_16ad14c22e3080d2, []int{0}
}
func (m *AccountQueryRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *AccountQueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_AccountQueryRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *AccountQueryRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_AccountQueryRequest.Merge(m, src)
}
func (m *AccountQueryRequest) XXX_Size() int {
return m.Size()
}
func (m *AccountQueryRequest) XXX_DiscardUnknown() {
xxx_messageInfo_AccountQueryRequest.DiscardUnknown(m)
}
var xxx_messageInfo_AccountQueryRequest proto.InternalMessageInfo
func (m *AccountQueryRequest) GetTarget() string {
if m != nil {
return m.Target
}
return ""
}
func (m *AccountQueryRequest) GetRequest() []byte {
if m != nil {
return m.Request
}
return nil
}
// AccountQueryResponse is the response type for the Query/AccountQuery RPC method.
type AccountQueryResponse struct {
// response defines the query response of the account.
Response []byte `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"`
}
func (m *AccountQueryResponse) Reset() { *m = AccountQueryResponse{} }
func (m *AccountQueryResponse) String() string { return proto.CompactTextString(m) }
func (*AccountQueryResponse) ProtoMessage() {}
func (*AccountQueryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_16ad14c22e3080d2, []int{1}
}
func (m *AccountQueryResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *AccountQueryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_AccountQueryResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *AccountQueryResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_AccountQueryResponse.Merge(m, src)
}
func (m *AccountQueryResponse) XXX_Size() int {
return m.Size()
}
func (m *AccountQueryResponse) XXX_DiscardUnknown() {
xxx_messageInfo_AccountQueryResponse.DiscardUnknown(m)
}
var xxx_messageInfo_AccountQueryResponse proto.InternalMessageInfo
func (m *AccountQueryResponse) GetResponse() []byte {
if m != nil {
return m.Response
}
return nil
}
func init() {
proto.RegisterType((*AccountQueryRequest)(nil), "cosmos.accounts.v1.AccountQueryRequest")
proto.RegisterType((*AccountQueryResponse)(nil), "cosmos.accounts.v1.AccountQueryResponse")
}
func init() { proto.RegisterFile("cosmos/accounts/v1/query.proto", fileDescriptor_16ad14c22e3080d2) }
var fileDescriptor_16ad14c22e3080d2 = []byte{
// 120 bytes of a gzipped FileDescriptorProto
// 219 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x29, 0xd6, 0x2f, 0x33, 0xd4, 0x2f,
0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x82, 0xc8, 0xeb, 0xc1,
0xe4, 0xf5, 0xca, 0x0c, 0x8d, 0xd8, 0xb9, 0x58, 0x03, 0x41, 0x4a, 0x9c, 0x4c, 0x4e, 0x3c, 0x92,
0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c,
0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x0a, 0xa2, 0xad, 0x38, 0x25, 0x5b, 0x2f, 0x33,
0x5f, 0xbf, 0x02, 0xd9, 0xf8, 0x24, 0x36, 0xb0, 0xc9, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff,
0x25, 0xf2, 0xcc, 0xc1, 0x7b, 0x00, 0x00, 0x00,
0xe4, 0xf5, 0xca, 0x0c, 0x95, 0xdc, 0xb9, 0x84, 0x1d, 0x21, 0xdc, 0x40, 0x90, 0xca, 0xa0, 0xd4,
0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x21, 0x31, 0x2e, 0xb6, 0x92, 0xc4, 0xa2, 0xf4, 0xd4, 0x12, 0x09,
0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x28, 0x4f, 0x48, 0x82, 0x8b, 0xbd, 0x08, 0xa2, 0x44, 0x82,
0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc6, 0x55, 0x32, 0xe2, 0x12, 0x41, 0x35, 0xa8, 0xb8, 0x20,
0x3f, 0xaf, 0x38, 0x55, 0x48, 0x8a, 0x8b, 0xa3, 0x08, 0xca, 0x06, 0x9b, 0xc5, 0x13, 0x04, 0xe7,
0x1b, 0xe5, 0x70, 0xb1, 0x82, 0x15, 0x0b, 0x25, 0x73, 0xf1, 0x20, 0x6b, 0x16, 0x52, 0xd7, 0xc3,
0x74, 0xaa, 0x1e, 0x16, 0x77, 0x4a, 0x69, 0x10, 0x56, 0x08, 0xb1, 0x4b, 0x89, 0xc1, 0xc9, 0xe4,
0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e,
0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xa4, 0x20, 0x86, 0x14, 0xa7, 0x64,
0xeb, 0x65, 0xe6, 0xeb, 0x57, 0x20, 0x07, 0x60, 0x12, 0x1b, 0x38, 0xec, 0x8c, 0x01, 0x01, 0x00,
0x00, 0xff, 0xff, 0xdf, 0xce, 0x73, 0x6a, 0x5d, 0x01, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -49,6 +165,8 @@ const _ = grpc.SupportPackageIsVersion4
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
// AccountQuery runs an account query.
AccountQuery(ctx context.Context, in *AccountQueryRequest, opts ...grpc.CallOption) (*AccountQueryResponse, error)
}
type queryClient struct {
@ -59,22 +177,459 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) AccountQuery(ctx context.Context, in *AccountQueryRequest, opts ...grpc.CallOption) (*AccountQueryResponse, error) {
out := new(AccountQueryResponse)
err := c.cc.Invoke(ctx, "/cosmos.accounts.v1.Query/AccountQuery", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// AccountQuery runs an account query.
AccountQuery(context.Context, *AccountQueryRequest) (*AccountQueryResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (*UnimplementedQueryServer) AccountQuery(ctx context.Context, req *AccountQueryRequest) (*AccountQueryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AccountQuery not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
}
func _Query_AccountQuery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AccountQueryRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).AccountQuery(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.accounts.v1.Query/AccountQuery",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).AccountQuery(ctx, req.(*AccountQueryRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.accounts.v1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/query.proto",
Methods: []grpc.MethodDesc{
{
MethodName: "AccountQuery",
Handler: _Query_AccountQuery_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/query.proto",
}
func (m *AccountQueryRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AccountQueryRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *AccountQueryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Request) > 0 {
i -= len(m.Request)
copy(dAtA[i:], m.Request)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Request)))
i--
dAtA[i] = 0x12
}
if len(m.Target) > 0 {
i -= len(m.Target)
copy(dAtA[i:], m.Target)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Target)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *AccountQueryResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AccountQueryResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *AccountQueryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Response) > 0 {
i -= len(m.Response)
copy(dAtA[i:], m.Response)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Response)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *AccountQueryRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Target)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
l = len(m.Request)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func (m *AccountQueryResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Response)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozQuery(x uint64) (n int) {
return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *AccountQueryRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AccountQueryRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AccountQueryRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Target = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Request = append(m.Request[:0], dAtA[iNdEx:postIndex]...)
if m.Request == nil {
m.Request = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *AccountQueryResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AccountQueryResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AccountQueryResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Response", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Response = append(m.Response[:0], dAtA[iNdEx:postIndex]...)
if m.Response == nil {
m.Response = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthQuery
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupQuery
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthQuery
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
)

File diff suppressed because it is too large Load Diff