feat(x/accounts): wire x/accounts to simapp (#18253)

Co-authored-by: unknown unknown <unknown@unknown>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
testinginprod 2023-11-03 17:36:23 +01:00 committed by GitHub
parent 10ae60ebca
commit f3c55dc90d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 9110 additions and 346 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,8 @@ const _ = grpc.SupportPackageIsVersion7
const (
Query_AccountQuery_FullMethodName = "/cosmos.accounts.v1.Query/AccountQuery"
Query_Schema_FullMethodName = "/cosmos.accounts.v1.Query/Schema"
Query_AccountType_FullMethodName = "/cosmos.accounts.v1.Query/AccountType"
)
// QueryClient is the client API for Query service.
@ -28,6 +30,10 @@ const (
type QueryClient interface {
// AccountQuery runs an account query.
AccountQuery(ctx context.Context, in *AccountQueryRequest, opts ...grpc.CallOption) (*AccountQueryResponse, error)
// Schema returns an x/account schema. Unstable.
Schema(ctx context.Context, in *SchemaRequest, opts ...grpc.CallOption) (*SchemaResponse, error)
// AccountType returns the account type for an address.
AccountType(ctx context.Context, in *AccountTypeRequest, opts ...grpc.CallOption) (*AccountTypeResponse, error)
}
type queryClient struct {
@ -47,12 +53,34 @@ func (c *queryClient) AccountQuery(ctx context.Context, in *AccountQueryRequest,
return out, nil
}
func (c *queryClient) Schema(ctx context.Context, in *SchemaRequest, opts ...grpc.CallOption) (*SchemaResponse, error) {
out := new(SchemaResponse)
err := c.cc.Invoke(ctx, Query_Schema_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) AccountType(ctx context.Context, in *AccountTypeRequest, opts ...grpc.CallOption) (*AccountTypeResponse, error) {
out := new(AccountTypeResponse)
err := c.cc.Invoke(ctx, Query_AccountType_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)
// Schema returns an x/account schema. Unstable.
Schema(context.Context, *SchemaRequest) (*SchemaResponse, error)
// AccountType returns the account type for an address.
AccountType(context.Context, *AccountTypeRequest) (*AccountTypeResponse, error)
mustEmbedUnimplementedQueryServer()
}
@ -63,6 +91,12 @@ type UnimplementedQueryServer struct {
func (UnimplementedQueryServer) AccountQuery(context.Context, *AccountQueryRequest) (*AccountQueryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AccountQuery not implemented")
}
func (UnimplementedQueryServer) Schema(context.Context, *SchemaRequest) (*SchemaResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented")
}
func (UnimplementedQueryServer) AccountType(context.Context, *AccountTypeRequest) (*AccountTypeResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AccountType not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service.
@ -94,6 +128,42 @@ func _Query_AccountQuery_Handler(srv interface{}, ctx context.Context, dec func(
return interceptor(ctx, in, info, handler)
}
func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SchemaRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).Schema(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_Schema_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).Schema(ctx, req.(*SchemaRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_AccountType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AccountTypeRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).AccountType(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_AccountType_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).AccountType(ctx, req.(*AccountTypeRequest))
}
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)
@ -105,6 +175,14 @@ var Query_ServiceDesc = grpc.ServiceDesc{
MethodName: "AccountQuery",
Handler: _Query_AccountQuery_Handler,
},
{
MethodName: "Schema",
Handler: _Query_Schema_Handler,
},
{
MethodName: "AccountType",
Handler: _Query_AccountType_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/accounts/v1/query.proto",

View File

@ -2,6 +2,7 @@
package accountsv1
import (
_ "cosmossdk.io/api/cosmos/msg/v1"
fmt "fmt"
runtime "github.com/cosmos/cosmos-proto/runtime"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@ -2234,49 +2235,53 @@ var file_cosmos_accounts_v1_tx_proto_rawDesc = []byte{
0x0a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x73, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
0x31, 0x22, 0x5e, 0x0a, 0x07, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06,
0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65,
0x6e, 0x64, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x22, 0x56, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a,
0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x0a, 0x0a, 0x4d, 0x73, 0x67,
0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65,
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12,
0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x22, 0x30, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x32, 0xa2, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x48, 0x0a, 0x04, 0x49,
0x6e, 0x69, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63,
0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31,
0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6b, 0x0a, 0x07, 0x4d, 0x73,
0x67, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x21, 0x0a,
0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65,
0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a,
0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x22, 0x56, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x49, 0x6e,
0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x63, 0x0a, 0x0a, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x16, 0x0a,
0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a,
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x65,
0x6e, 0x64, 0x65, 0x72, 0x22, 0x30, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75,
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa9, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x48,
0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x49,
0x6e, 0x69, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74,
0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65,
0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65,
0x1a, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xbb, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d,
0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e,
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x76, 0x31, 0xa2, 0x02,
0x03, 0x43, 0x41, 0x58, 0xaa, 0x02, 0x12, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x43, 0x6f, 0x73, 0x6d,
0x6f, 0x73, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02,
0x1e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
0x02, 0x14, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63,
0x75, 0x74, 0x65, 0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63,
0x75, 0x74, 0x65, 0x1a, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63,
0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0,
0x2a, 0x01, 0x42, 0xbb, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54,
0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x41, 0x58, 0xaa, 0x02,
0x12, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x43, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50,
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x43, 0x6f, 0x73, 0x6d,
0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x3a, 0x3a, 0x56, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -0,0 +1,34 @@
syntax = "proto3";
package cosmos.accounts.testing.counter.v1;
// MsgInit defines a message which initializes the counter with a given amount.
message MsgInit {
// initial_value is the initial amount to set the counter to.
uint64 initial_value = 1;
}
// MsgInitResponse defines the MsgInit response type.
message MsgInitResponse {}
// MsgIncreaseCounter defines a message which increases the counter by a given amount.
message MsgIncreaseCounter {
// amount is the amount to increase the counter by.
uint64 amount = 1;
}
// MsgIncreaseCounterResponse defines the MsgIncreaseCounter response type.
// Returns the new counter value.
message MsgIncreaseCounterResponse {
// new_amount defines the new counter value after the increase.
uint64 new_amount = 1;
}
// QueryCounterRequest is used to query the counter value.
message QueryCounterRequest {}
// QueryCounterResponse returns the counter value.
message QueryCounterResponse {
// value defines the value of the counter.
uint64 value = 1;
}

View File

@ -8,6 +8,10 @@ option go_package = "cosmossdk.io/x/accounts/v1";
service Query {
// AccountQuery runs an account query.
rpc AccountQuery(AccountQueryRequest) returns (AccountQueryResponse) {};
// Schema returns an x/account schema. Unstable.
rpc Schema(SchemaRequest) returns (SchemaResponse) {};
// AccountType returns the account type for an address.
rpc AccountType(AccountTypeRequest) returns (AccountTypeResponse) {};
}
// AccountQueryRequest is the request type for the Query/AccountQuery RPC
@ -23,3 +27,40 @@ message AccountQueryResponse {
// response defines the query response of the account.
bytes response = 1;
}
// SchemaResponse is the response type for the Query/Schema RPC method.
message SchemaRequest {
// account_type defines the account type to query the schema for.
string account_type = 1;
}
// SchemaResponse is the response type for the Query/Schema RPC method.
message SchemaResponse {
// Handler defines a schema descriptor for a handler.
// Where request and response are names that can be used to lookup the
// reflection descriptor.
message Handler {
// request is the request name
string request = 1;
// response is the response name
string response = 2;
}
// init_schema defines the schema descriptor for the Init account method.
Handler init_schema = 1;
// execute_handlers defines the schema descriptor for the Execute account method.
repeated Handler execute_handlers = 2;
// query_handlers defines the schema descriptor for the Query account method.
repeated Handler query_handlers = 3;
}
// AccountTypeRequest is the request type for the Query/AccountType RPC method.
message AccountTypeRequest {
// address defines the address to query the account type for.
string address = 1;
}
// AccountTypeResponse is the response type for the Query/AccountType RPC method.
message AccountTypeResponse {
// account_type defines the account type for the address.
string account_type = 1;
}

View File

@ -4,8 +4,12 @@ package cosmos.accounts.v1;
option go_package = "cosmossdk.io/x/accounts/v1";
import "cosmos/msg/v1/msg.proto";
// Msg defines the Msg service for the x/accounts module.
service Msg {
option (cosmos.msg.v1.service) = true;
// Init creates a new account in the chain.
rpc Init(MsgInit) returns (MsgInitResponse);
@ -15,6 +19,8 @@ service Msg {
// MsgInit defines the Create request type for the Msg/Create RPC method.
message MsgInit {
option (cosmos.msg.v1.signer) = "sender";
// sender is the address of the sender of this message.
string sender = 1;
// account_type is the type of the account to be created.
@ -35,6 +41,7 @@ message MsgInitResponse {
// MsgExecute defines the Execute request type for the Msg/Execute RPC method.
message MsgExecute {
option (cosmos.msg.v1.signer) = "sender";
// sender is the address of the sender of this message.
string sender = 1;
// target is the address of the account to be executed.

View File

@ -20,6 +20,9 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/accounts"
"cosmossdk.io/x/accounts/accountstd"
"cosmossdk.io/x/accounts/testing/counter"
"cosmossdk.io/x/authz"
authzkeeper "cosmossdk.io/x/authz/keeper"
authzmodule "cosmossdk.io/x/authz/module"
@ -98,7 +101,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
consensus "github.com/cosmos/cosmos-sdk/x/consensus"
"github.com/cosmos/cosmos-sdk/x/consensus"
consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
@ -146,7 +149,8 @@ type SimApp struct {
keys map[string]*storetypes.KVStoreKey
// keepers
AccountKeeper authkeeper.AccountKeeper
AccountsKeeper accounts.Keeper
AuthKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.BaseKeeper
StakingKeeper *stakingkeeper.Keeper
SlashingKeeper slashingkeeper.Keeper
@ -256,6 +260,7 @@ func NewSimApp(
govtypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, circuittypes.StoreKey,
authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey, pooltypes.StoreKey,
accounts.StoreKey,
)
// register streaming services
@ -277,12 +282,28 @@ func NewSimApp(
bApp.SetParamStore(app.ConsensusParamsKeeper.ParamsStore)
// add keepers
app.AccountKeeper = authkeeper.NewAccountKeeper(appCodec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, authcodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.AuthKeeper = authkeeper.NewAccountKeeper(appCodec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, authcodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String())
accountsKeeper, err := accounts.NewKeeper(
runtime.NewKVStoreService(keys[accounts.StoreKey]),
runtime.EventService{},
app.AuthKeeper.AddressCodec(),
appCodec.InterfaceRegistry().SigningContext(),
app.MsgServiceRouter(),
app.GRPCQueryRouter(),
accountstd.AddAccount("counter", counter.NewAccount),
)
if err != nil {
panic(err)
}
app.AccountsKeeper = accountsKeeper
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
app.AccountKeeper,
app.AuthKeeper,
BlockedAddresses(),
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
logger,
@ -294,7 +315,7 @@ func NewSimApp(
EnabledSignModes: enabledSignModes,
TextualCoinMetadataQueryFn: txmodule.NewBankKeeperCoinMetadataQueryFn(app.BankKeeper),
}
txConfig, err := authtx.NewTxConfigWithOptions(
txConfig, err = authtx.NewTxConfigWithOptions(
appCodec,
txConfigOpts,
)
@ -304,13 +325,13 @@ func NewSimApp(
app.txConfig = txConfig
app.StakingKeeper = stakingkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr),
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AuthKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr),
)
app.MintKeeper = mintkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.MintKeeper = mintkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AuthKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.PoolKeeper = poolkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[pooltypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.PoolKeeper = poolkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[pooltypes.StoreKey]), app.AuthKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, legacyAmino, runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
@ -318,9 +339,9 @@ func NewSimApp(
invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))
app.CrisisKeeper = crisiskeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[crisistypes.StoreKey]), invCheckPeriod,
app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.AccountKeeper.AddressCodec())
app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.AuthKeeper.AddressCodec())
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[feegrant.StoreKey]), app.AccountKeeper)
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[feegrant.StoreKey]), app.AuthKeeper)
// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
@ -328,17 +349,17 @@ func NewSimApp(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
)
app.CircuitKeeper = circuitkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[circuittypes.StoreKey]), authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.AccountKeeper.AddressCodec())
app.CircuitKeeper = circuitkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[circuittypes.StoreKey]), authtypes.NewModuleAddress(govtypes.ModuleName).String(), app.AuthKeeper.AddressCodec())
app.BaseApp.SetCircuitBreaker(&app.CircuitKeeper)
app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, app.MsgServiceRouter(), app.AccountKeeper)
app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, app.MsgServiceRouter(), app.AuthKeeper)
groupConfig := group.DefaultConfig()
/*
Example of setting group params:
groupConfig.MaxMetadataLen = 1000
*/
app.GroupKeeper = groupkeeper.NewKeeper(keys[group.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper, groupConfig)
app.GroupKeeper = groupkeeper.NewKeeper(keys[group.StoreKey], appCodec, app.MsgServiceRouter(), app.AuthKeeper, groupConfig)
// get skipUpgradeHeights from the app options
skipUpgradeHeights := map[int64]bool{}
@ -360,7 +381,7 @@ func NewSimApp(
govConfig.MaxMetadataLen = 10000
*/
govKeeper := govkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper,
appCodec, runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AuthKeeper, app.BankKeeper,
app.StakingKeeper, app.PoolKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
@ -373,11 +394,11 @@ func NewSimApp(
),
)
app.NFTKeeper = nftkeeper.NewKeeper(runtime.NewKVStoreService(keys[nftkeeper.StoreKey]), appCodec, app.AccountKeeper, app.BankKeeper)
app.NFTKeeper = nftkeeper.NewKeeper(runtime.NewKVStoreService(keys[nftkeeper.StoreKey]), appCodec, app.AuthKeeper, app.BankKeeper)
// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper.AddressCodec(),
appCodec, runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), app.StakingKeeper, app.SlashingKeeper, app.AuthKeeper.AddressCodec(),
)
// If evidence needs to be handled for the app, set routes in router here and seal
app.EvidenceKeeper = *evidenceKeeper
@ -392,27 +413,28 @@ func NewSimApp(
// must be passed by reference here.
app.ModuleManager = module.NewManager(
genutil.NewAppModule(
app.AccountKeeper, app.StakingKeeper, app,
app.AuthKeeper, app.StakingKeeper, app,
txConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
accounts.NewAppModule(app.AccountsKeeper),
auth.NewAppModule(appCodec, app.AuthKeeper, authsims.RandomGenesisAccounts),
vesting.NewAppModule(app.AuthKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AuthKeeper),
crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.PoolKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.interfaceRegistry),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()),
feegrantmodule.NewAppModule(appCodec, app.AuthKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AuthKeeper, app.BankKeeper, app.PoolKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AuthKeeper, nil),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.interfaceRegistry),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AuthKeeper, app.BankKeeper),
upgrade.NewAppModule(app.UpgradeKeeper, app.AuthKeeper.AddressCodec()),
evidence.NewAppModule(app.EvidenceKeeper),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry),
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
circuit.NewAppModule(appCodec, app.CircuitKeeper),
protocolpool.NewAppModule(appCodec, app.PoolKeeper, app.AccountKeeper, app.BankKeeper),
protocolpool.NewAppModule(appCodec, app.PoolKeeper, app.AuthKeeper, app.BankKeeper),
)
// BasicModuleManager defines the module BasicManager is in charge of setting up basic,
@ -460,7 +482,7 @@ func NewSimApp(
// properly initialized with tokens from genesis accounts.
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
genesisModuleOrder := []string{
authtypes.ModuleName, banktypes.ModuleName,
accounts.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
feegrant.ModuleName, nft.ModuleName, group.ModuleName, upgradetypes.ModuleName,
@ -499,7 +521,7 @@ func NewSimApp(
// NOTE: this is not required apps that don't use the simulator for fuzz testing
// transactions
overrideModules := map[string]module.AppModuleSimulation{
authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AuthKeeper, authsims.RandomGenesisAccounts),
}
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)
@ -556,7 +578,7 @@ func (app *SimApp) setAnteHandler(txConfig client.TxConfig) {
anteHandler, err := NewAnteHandler(
HandlerOptions{
ante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
AccountKeeper: app.AuthKeeper,
BankKeeper: app.BankKeeper,
SignModeHandler: txConfig.SignModeHandler(),
FeegrantKeeper: app.FeeGrantKeeper,
@ -609,11 +631,13 @@ func (a *SimApp) Configurator() module.Configurator {
// InitChainer application update at chain initialization
func (app *SimApp) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
var genesisState GenesisState
if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
err := json.Unmarshal(req.AppStateBytes, &genesisState)
if err != nil {
return nil, err
}
if err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()); err != nil {
panic(err)
err = app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
if err != nil {
return nil, err
}
return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
}

View File

@ -16,6 +16,7 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/x/accounts"
authzmodule "cosmossdk.io/x/authz/module"
"cosmossdk.io/x/bank"
banktypes "cosmossdk.io/x/bank/types"
@ -58,7 +59,7 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) {
if modAddr, err := sdk.AccAddressFromBech32(acc); err == nil {
addr = modAddr
} else {
addr = app.AccountKeeper.GetModuleAddress(acc)
addr = app.AuthKeeper.GetModuleAddress(acc)
}
require.True(
@ -196,6 +197,7 @@ func TestRunMigrations(t *testing.T) {
_, err = app.ModuleManager.RunMigrations(
app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()}), configurator,
module.VersionMap{
"accounts": accounts.AppModule{}.ConsensusVersion(),
"bank": 1,
"auth": auth.AppModule{}.ConsensusVersion(),
"authz": authzmodule.AppModule{}.ConsensusVersion(),

View File

@ -66,7 +66,7 @@ type SimApp struct {
interfaceRegistry codectypes.InterfaceRegistry
// keepers
AccountKeeper authkeeper.AccountKeeper
AuthKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
SlashingKeeper slashingkeeper.Keeper
@ -168,7 +168,7 @@ func NewSimApp(
&app.legacyAmino,
&app.txConfig,
&app.interfaceRegistry,
&app.AccountKeeper,
&app.AuthKeeper,
&app.BankKeeper,
&app.StakingKeeper,
&app.SlashingKeeper,
@ -244,7 +244,7 @@ func NewSimApp(
// NOTE: this is not required apps that don't use the simulator for fuzz testing
// transactions
overrideModules := map[string]module.AppModuleSimulation{
authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AuthKeeper, authsims.RandomGenesisAccounts),
}
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)

View File

@ -33,6 +33,8 @@ require (
google.golang.org/protobuf v1.31.0
)
require cosmossdk.io/x/accounts v0.0.0-20231013072015-ec9bcc41ef9c
require (
cosmossdk.io/x/authz v0.0.0-00010101000000-000000000000
cosmossdk.io/x/bank v0.0.0-00010101000000-000000000000
@ -216,6 +218,7 @@ replace (
cosmossdk.io/api => ../api
cosmossdk.io/client/v2 => ../client/v2
cosmossdk.io/tools/confix => ../tools/confix
cosmossdk.io/x/accounts => ../x/accounts
cosmossdk.io/x/authz => ../x/authz
cosmossdk.io/x/bank => ../x/bank
cosmossdk.io/x/circuit => ../x/circuit
@ -226,6 +229,7 @@ replace (
cosmossdk.io/x/group => ../x/group
cosmossdk.io/x/mint => ../x/mint
cosmossdk.io/x/nft => ../x/nft
cosmossdk.io/x/params => ../x/params
cosmossdk.io/x/protocolpool => ../x/protocolpool
cosmossdk.io/x/slashing => ../x/slashing
cosmossdk.io/x/staking => ../x/staking
@ -234,7 +238,6 @@ replace (
// Below are the long-lived replace of the SimApp
replace (
cosmossdk.io/x/params => ../x/params
// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// Simapp always use the latest version of the cosmos-sdk

View File

@ -4,6 +4,7 @@ import (
"context"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/accounts"
protocolpooltypes "cosmossdk.io/x/protocolpool/types"
upgradetypes "cosmossdk.io/x/upgrade/types"
@ -34,6 +35,7 @@ func (app SimApp) RegisterUpgradeHandlers() {
if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := storetypes.StoreUpgrades{
Added: []string{
accounts.ModuleName,
protocolpooltypes.ModuleName,
},
}

View File

@ -53,6 +53,7 @@ require (
cloud.google.com/go/iam v1.1.3 // indirect
cloud.google.com/go/storage v1.33.0 // indirect
cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860 // indirect
cosmossdk.io/x/accounts v0.0.0-20231013072015-ec9bcc41ef9c // indirect
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
@ -213,7 +214,9 @@ require (
// SimApp on main always tests the latest extracted SDK modules importing the sdk
replace (
cosmossdk.io/api => ../api
cosmossdk.io/client/v2 => ../client/v2
cosmossdk.io/x/accounts => ../x/accounts
cosmossdk.io/x/authz => ../x/authz
cosmossdk.io/x/bank => ../x/bank
cosmossdk.io/x/circuit => ../x/circuit

View File

@ -187,8 +187,6 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54 h1:c7kl5S1ME0q2g/7cdxngOAZr6N/5L7vVibmrmQZrQ0U=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54/go.mod h1:7B/5XWh1HYwJk3DzWeNoxOSI+nGx1m5UyYfHLFuKzkw=
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
cosmossdk.io/core v0.12.0 h1:aFuvkG6eDv0IQC+UDjx86wxNWVAxdCFk7OABJ1Vh4RU=

View File

@ -12,8 +12,10 @@ replace (
// SimApp on main always tests the latest extracted SDK modules importing the sdk
replace (
cosmossdk.io/api => ../../../api
cosmossdk.io/client/v2 => ../../../client/v2
cosmossdk.io/simapp => ../../../simapp
cosmossdk.io/x/accounts => ../../../x/accounts
cosmossdk.io/x/authz => ../../../x/authz
cosmossdk.io/x/bank => ../../../x/bank
cosmossdk.io/x/circuit => ../../../x/circuit
@ -55,6 +57,7 @@ require (
cosmossdk.io/depinject v1.0.0-alpha.4 // indirect
cosmossdk.io/errors v1.0.0 // indirect
cosmossdk.io/store v1.0.0 // indirect
cosmossdk.io/x/accounts v0.0.0-20231013072015-ec9bcc41ef9c // indirect
cosmossdk.io/x/authz v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect
cosmossdk.io/x/distribution v0.0.0-20230925135524-a1bc045b3190 // indirect

View File

@ -187,8 +187,6 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54 h1:c7kl5S1ME0q2g/7cdxngOAZr6N/5L7vVibmrmQZrQ0U=
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54/go.mod h1:7B/5XWh1HYwJk3DzWeNoxOSI+nGx1m5UyYfHLFuKzkw=
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
cosmossdk.io/core v0.12.0 h1:aFuvkG6eDv0IQC+UDjx86wxNWVAxdCFk7OABJ1Vh4RU=

View File

@ -10,15 +10,16 @@ import (
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
"cosmossdk.io/collections"
"cosmossdk.io/x/accounts/accountstd"
"cosmossdk.io/x/accounts/internal/implementation"
)
var _ implementation.Account = (*TestAccount)(nil)
func NewTestAccount(sb *collections.SchemaBuilder) *TestAccount {
func NewTestAccount(d accountstd.Dependencies) (*TestAccount, error) {
return &TestAccount{
Counter: collections.NewSequence(sb, collections.NewPrefix(0), "counter"),
}
Counter: collections.NewSequence(d.SchemaBuilder, collections.NewPrefix(0), "counter"),
}, nil
}
type TestAccount struct {

View File

@ -0,0 +1,74 @@
// Package accountstd exports the types and functions that are used by developers to implement smart accounts.
package accountstd
import (
"context"
"cosmossdk.io/x/accounts/internal/implementation"
)
// Interface is the exported interface of an Account.
type Interface = implementation.Account
// ExecuteBuilder is the exported type of ExecuteBuilder.
type ExecuteBuilder = implementation.ExecuteBuilder
// QueryBuilder is the exported type of QueryBuilder.
type QueryBuilder = implementation.QueryBuilder
// InitBuilder is the exported type of InitBuilder.
type InitBuilder = implementation.InitBuilder
// AccountCreatorFunc is the exported type of AccountCreatorFunc.
type AccountCreatorFunc = implementation.AccountCreatorFunc
// Dependencies is the exported type of Dependencies.
type Dependencies = implementation.Dependencies
func RegisterExecuteHandler[
Req any, ProtoReq implementation.ProtoMsg[Req], Resp any, ProtoResp implementation.ProtoMsg[Resp],
](router *ExecuteBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error),
) {
implementation.RegisterExecuteHandler(router, handler)
}
// RegisterQueryHandler registers a query handler for a smart account that uses protobuf.
func RegisterQueryHandler[
Req any, ProtoReq implementation.ProtoMsg[Req], Resp any, ProtoResp implementation.ProtoMsg[Resp],
](router *QueryBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error),
) {
implementation.RegisterQueryHandler(router, handler)
}
// RegisterInitHandler registers an initialisation handler for a smart account that uses protobuf.
func RegisterInitHandler[
Req any, ProtoReq implementation.ProtoMsg[Req], Resp any, ProtoResp implementation.ProtoMsg[Resp],
](router *InitBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error),
) {
implementation.RegisterInitHandler(router, handler)
}
// AddAccount is a helper function to add a smart account to the list of smart accounts.
func AddAccount[A Interface](name string, constructor func(deps Dependencies) (A, error)) AccountCreatorFunc {
return implementation.AddAccount(name, constructor)
}
// Whoami returns the address of the account being invoked.
func Whoami(ctx context.Context) []byte {
return implementation.Whoami(ctx)
}
// Sender returns the sender of the execution request.
func Sender(ctx context.Context) []byte {
return implementation.Sender(ctx)
}
// ExecModule can be used to execute a message towards a module.
func ExecModule[Resp any, RespProto implementation.ProtoMsg[Resp], Req any, ReqProto implementation.ProtoMsg[Req]](ctx context.Context, msg ReqProto) (RespProto, error) {
return implementation.ExecModule[Resp, RespProto, Req, ReqProto](ctx, msg)
}
// QueryModule can be used by an account to execute a module query.
func QueryModule[Resp any, RespProto implementation.ProtoMsg[Resp], Req any, ReqProto implementation.ProtoMsg[Req]](ctx context.Context, req ReqProto) (RespProto, error) {
return implementation.QueryModule[Resp, RespProto, Req, ReqProto](ctx, req)
}

239
x/accounts/cli/cli.go Normal file
View File

@ -0,0 +1,239 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/known/anypb"
v1 "cosmossdk.io/x/accounts/v1"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
)
func TxCmd(name string) *cobra.Command {
cmd := &cobra.Command{
Use: name,
Short: "Transactions command for the " + name + " module",
RunE: client.ValidateCmd,
DisableFlagParsing: true,
}
cmd.AddCommand(GetTxInitCmd(), GetExecuteCmd())
return cmd
}
func QueryCmd(name string) *cobra.Command {
cmd := &cobra.Command{
Use: name,
Short: "Query command for the " + name + " module",
RunE: client.ValidateCmd,
DisableFlagParsing: true,
}
cmd.AddCommand(GetQueryAccountCmd())
return cmd
}
func GetTxInitCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "init [account-type] [json-message]",
Short: "Initialize a new account",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
sender := clientCtx.GetFromAddress()
// we need to convert the message from json to a protobuf message
// to know which message to use, we need to know the account type
// init message schema.
accClient := v1.NewQueryClient(clientCtx)
schema, err := accClient.Schema(cmd.Context(), &v1.SchemaRequest{
AccountType: args[0],
})
if err != nil {
return err
}
msgBytes, err := encodeJSONToProto(schema.InitSchema.Request, args[1])
if err != nil {
return err
}
msg := v1.MsgInit{
Sender: sender.String(),
AccountType: args[0],
Message: msgBytes,
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}
flags.AddTxFlagsToCmd(cmd)
return cmd
}
func GetExecuteCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "execute [account-address] [execute-msg-type-url] [json-message]",
Short: "Execute state transition to account",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
sender := clientCtx.GetFromAddress()
schema, err := getSchemaForAccount(clientCtx, args[0])
if err != nil {
return err
}
msgBytes, err := handlerMsgBytes(schema.ExecuteHandlers, args[1], args[2])
if err != nil {
return err
}
msg := v1.MsgExecute{
Sender: sender.String(),
Target: args[0],
Message: msgBytes,
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}
flags.AddTxFlagsToCmd(cmd)
return cmd
}
func GetQueryAccountCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query [account-address] [query-request-type-url] [json-message]",
Short: "Query account state",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
schema, err := getSchemaForAccount(clientCtx, args[0])
if err != nil {
return err
}
msgBytes, err := handlerMsgBytes(schema.QueryHandlers, args[1], args[2])
if err != nil {
return err
}
queryClient := v1.NewQueryClient(clientCtx)
res, err := queryClient.AccountQuery(cmd.Context(), &v1.AccountQueryRequest{
Target: args[0],
Request: msgBytes,
})
if err != nil {
return err
}
jsonResp, err := handlerResponseJSONBytes(schema.QueryHandlers, args[1], res.Response)
if err != nil {
return err
}
return clientCtx.PrintString(jsonResp)
},
}
flags.AddQueryFlagsToCmd(cmd)
return cmd
}
func getSchemaForAccount(clientCtx client.Context, addr string) (*v1.SchemaResponse, error) {
queryClient := v1.NewQueryClient(clientCtx)
accType, err := queryClient.AccountType(clientCtx.CmdContext, &v1.AccountTypeRequest{
Address: addr,
})
if err != nil {
return nil, err
}
return queryClient.Schema(clientCtx.CmdContext, &v1.SchemaRequest{
AccountType: accType.AccountType,
})
}
func handlerMsgBytes(handlersSchema []*v1.SchemaResponse_Handler, msgTypeURL, msgString string) ([]byte, error) {
var msgSchema *v1.SchemaResponse_Handler
for _, handler := range handlersSchema {
if handler.Request == msgTypeURL {
msgSchema = handler
break
}
}
if msgSchema == nil {
return nil, fmt.Errorf("handler for message type %s not found", msgTypeURL)
}
msgBytes, err := encodeJSONToProto(msgSchema.Request, msgString)
if err != nil {
return nil, err
}
return proto.MarshalOptions{Deterministic: true}.Marshal(&anypb.Any{
TypeUrl: "/" + msgTypeURL,
Value: msgBytes,
})
}
func handlerResponseJSONBytes(handlerSchema []*v1.SchemaResponse_Handler, msgTypeURL string, protoBytes []byte) (string, error) {
var msgSchema *v1.SchemaResponse_Handler
for _, handler := range handlerSchema {
if handler.Request == msgTypeURL {
msgSchema = handler
break
}
}
if msgSchema == nil {
return "", fmt.Errorf("handler for message type %s not found", msgTypeURL)
}
anyMsg := new(anypb.Any)
err := proto.Unmarshal(protoBytes, anyMsg)
if err != nil {
return "", err
}
return decodeProtoToJSON(msgSchema.Response, anyMsg.Value)
}
func encodeJSONToProto(name, jsonMsg string) ([]byte, error) {
jsonBytes := []byte(jsonMsg)
impl, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(name))
if err != nil {
return nil, err
}
msg := impl.New().Interface()
err = protojson.Unmarshal(jsonBytes, msg)
if err != nil {
return nil, err
}
return proto.Marshal(msg)
}
func decodeProtoToJSON(name string, protoBytes []byte) (string, error) {
impl, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(name))
if err != nil {
return "", err
}
msg := impl.New().Interface()
err = proto.UnmarshalOptions{}.Unmarshal(protoBytes, msg)
if err != nil {
return "", fmt.Errorf(
"%w: unable to unmarshal protobytes in message '%s', message name: %s",
err, protoBytes, name)
}
jsonBytes, err := protojson.Marshal(msg)
if err != nil {
return "", err
}
return string(jsonBytes), nil
}

View File

@ -5,25 +5,18 @@ import (
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"cosmossdk.io/collections"
"cosmossdk.io/collections/colltest"
"cosmossdk.io/x/accounts/internal/implementation"
)
func TestGenesis(t *testing.T) {
sb := collections.NewSchemaBuilderFromAccessor(implementation.OpenKVStore)
acc := NewTestAccount(sb)
k, ctx := newKeeper(t, map[string]implementation.Account{
"test": acc,
})
k.queryModuleFunc = func(ctx context.Context, _ proto.Message) (proto.Message, error) {
return &bankv1beta1.QueryBalanceResponse{}, nil
k, ctx := newKeeper(t, implementation.AddAccount("test", NewTestAccount))
k.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error {
return nil
}
// we init two accounts of the same type

View File

@ -3,56 +3,163 @@ module cosmossdk.io/x/accounts
go 1.21
require (
cosmossdk.io/api v0.7.2
cosmossdk.io/api v0.7.3-0.20231029200940-6af7f30bfd54
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.11.0
cosmossdk.io/core v0.12.0
github.com/cosmos/cosmos-sdk v0.0.0-00010101000000-000000000000
github.com/cosmos/gogoproto v1.4.11
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
)
require (
cosmossdk.io/depinject v1.0.0-alpha.4 // indirect
cosmossdk.io/errors v1.0.0 // indirect
cosmossdk.io/log v1.2.1 // indirect
cosmossdk.io/math v1.1.3-rc.1 // indirect
cosmossdk.io/store v1.0.0 // indirect
cosmossdk.io/x/tx v0.12.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/errors v1.11.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20230525220056-bb4fc9527b3b // indirect
github.com/cockroachdb/pebble v0.0.0-20231102162011-844f0582c2eb // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft v0.38.0 // indirect
github.com/cometbft/cometbft-db v0.8.0 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.0 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/getsentry/sentry-go v0.23.0 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v1.0.0 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/emicklei/dot v1.6.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/getsentry/sentry-go v0.25.0 // indirect
github.com/go-kit/kit v0.12.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.1.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/klauspost/compress v1.16.5 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.1 // indirect
github.com/hashicorp/go-plugin v1.5.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/huandu/skiplist v1.2.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/improbable-eng/grpc-web v0.15.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/linxGnu/grocksdb v1.7.16 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/linxGnu/grocksdb v1.8.4 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/rs/cors v1.8.3 // indirect
github.com/rs/zerolog v1.31.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tidwall/btree v1.7.0 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v1.1.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
// REMOVE post v1 release.
replace cosmossdk.io/api => ../../api
replace (
cosmossdk.io/api => ../../api
github.com/cosmos/cosmos-sdk => ../../.
)
replace (
cosmossdk.io/x/bank => ../bank
cosmossdk.io/x/distribution => ../distribution
cosmossdk.io/x/gov => ../gov
cosmossdk.io/x/mint => ../mint
cosmossdk.io/x/slashing => ../slashing
cosmossdk.io/x/staking => ../staking
)

File diff suppressed because it is too large Load Diff

View File

@ -28,11 +28,8 @@ type InitBuilder struct {
// 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)
// schema is the schema of the message that will be passed to the handler function.
schema HandlerSchema
}
// makeHandler returns the handler function that will be called when the smart account is initialized.
@ -47,7 +44,8 @@ func (i *InitBuilder) makeHandler() (func(ctx context.Context, initRequest any)
// NewExecuteBuilder creates a new ExecuteBuilder instance.
func NewExecuteBuilder() *ExecuteBuilder {
return &ExecuteBuilder{
handlers: make(map[string]func(ctx context.Context, executeRequest any) (executeResponse any, err error)),
handlers: make(map[string]func(ctx context.Context, executeRequest any) (executeResponse any, err error)),
handlersSchema: make(map[string]HandlerSchema),
}
}
@ -56,6 +54,11 @@ 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)
// handlersSchema is a map of schemas for the messages that will be passed to the handler functions
// and the messages that will be returned by the handler functions.
handlersSchema map[string]HandlerSchema
// err is the error that occurred before building the handler function.
err error
}

View File

@ -4,9 +4,9 @@ import (
"bytes"
"context"
"errors"
"fmt"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"cosmossdk.io/collections"
"cosmossdk.io/core/store"
@ -18,16 +18,21 @@ var (
AccountStatePrefix = collections.NewPrefix(255)
)
type (
ModuleExecFunc = func(ctx context.Context, msg, msgResp protoiface.MessageV1) error
ModuleQueryFunc = ModuleExecFunc
)
type contextKey struct{}
type contextValue struct {
store store.KVStore // store is the prefixed store for the account.
sender []byte // sender is the address of the entity invoking the account action.
whoami []byte // whoami is the address of the account being invoked.
originalContext context.Context // originalContext that was used to build the account context.
getExpectedSender func(msg proto.Message) ([]byte, error) // getExpectedSender is a function that returns the expected sender for a given message.
moduleExec func(ctx context.Context, msg proto.Message) (proto.Message, error) // moduleExec is a function that executes a module message.
moduleQuery func(ctx context.Context, msg proto.Message) (proto.Message, error) // moduleQuery is a function that queries a module.
store store.KVStore // store is the prefixed store for the account.
sender []byte // sender is the address of the entity invoking the account action.
whoami []byte // whoami is the address of the account being invoked.
originalContext context.Context // originalContext that was used to build the account context.
getExpectedSender func(msg proto.Message) ([]byte, error) // getExpectedSender is a function that returns the expected sender for a given message.
moduleExec ModuleExecFunc // moduleExec is a function that executes a module message.
moduleQuery ModuleQueryFunc // moduleQuery is a function that queries a module.
}
// MakeAccountContext creates a new account execution context given:
@ -43,8 +48,8 @@ func MakeAccountContext(
accountAddr,
sender []byte,
getSenderFunc func(msg proto.Message) ([]byte, error),
moduleExec func(ctx context.Context, msg proto.Message) (proto.Message, error),
moduleQuery func(ctx context.Context, msg proto.Message) (proto.Message, error),
moduleExec ModuleExecFunc,
moduleQuery ModuleQueryFunc,
) context.Context {
return context.WithValue(ctx, contextKey{}, contextValue{
store: prefixstore.New(storeSvc.OpenKVStore(ctx), append(AccountStatePrefix, accountAddr...)),
@ -71,32 +76,26 @@ func ExecModule[Resp any, RespProto ProtoMsg[Resp], Req any, ReqProto ProtoMsg[R
}
// execute module, unwrapping the original context.
resp, err := v.moduleExec(v.originalContext, msg)
resp := RespProto(new(Resp))
err = v.moduleExec(v.originalContext, msg, resp)
if err != nil {
return nil, err
}
concreteResp, ok := resp.(RespProto)
if !ok {
return nil, fmt.Errorf("unexpected response type %T", resp)
}
return concreteResp, nil
return resp, nil
}
// QueryModule can be used by an account to execute a module query.
func QueryModule[Resp any, RespProto ProtoMsg[Resp], Req any, ReqProto ProtoMsg[Req]](ctx context.Context, msg ReqProto) (RespProto, error) {
func QueryModule[Resp any, RespProto ProtoMsg[Resp], Req any, ReqProto ProtoMsg[Req]](ctx context.Context, req ReqProto) (RespProto, error) {
// we do not need to check the sender in a query because it is not a state transition.
// we also unwrap the original context.
v := ctx.Value(contextKey{}).(contextValue)
resp, err := v.moduleQuery(v.originalContext, msg)
resp := RespProto(new(Resp))
err := v.moduleQuery(v.originalContext, req, resp)
if err != nil {
return nil, err
}
concreteResp, ok := resp.(RespProto)
if !ok {
return nil, fmt.Errorf("unexpected response type %T", resp)
}
return concreteResp, nil
return resp, nil
}
// OpenKVStore returns the prefixed store for the account given the context.

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/types/known/wrapperspb"
"cosmossdk.io/collections"
@ -54,10 +55,11 @@ func TestMakeAccountContext(t *testing.T) {
// ensure calling ExecModule works
accountCtx = MakeAccountContext(originalContext, storeService, []byte("legit-exec-module"), []byte("invoker"), func(_ proto.Message) ([]byte, error) {
return []byte("legit-exec-module"), nil
}, func(ctx context.Context, msg proto.Message) (proto.Message, error) {
}, func(ctx context.Context, msg, msgResp protoiface.MessageV1) error {
// ensure we unwrapped the context when invoking a module call
require.Equal(t, originalContext, ctx)
return wrapperspb.String("module exec was called"), nil
proto.Merge(msgResp.(proto.Message), &wrapperspb.StringValue{Value: "module exec was called"})
return nil
}, nil)
resp, err := ExecModule[wrapperspb.StringValue](accountCtx, &wrapperspb.UInt64Value{Value: 1000})
@ -66,9 +68,10 @@ func TestMakeAccountContext(t *testing.T) {
// ensure calling QueryModule works, also by setting everything else communication related to nil
// we can guarantee that exec paths do not impact query paths.
accountCtx = MakeAccountContext(originalContext, storeService, nil, nil, nil, nil, func(ctx context.Context, msg proto.Message) (proto.Message, error) {
accountCtx = MakeAccountContext(originalContext, storeService, nil, nil, nil, nil, func(ctx context.Context, req, resp protoiface.MessageV1) error {
require.Equal(t, originalContext, ctx)
return wrapperspb.String("module query was called"), nil
proto.Merge(resp.(proto.Message), wrapperspb.String("module query was called"))
return nil
})
resp, err = QueryModule[wrapperspb.StringValue](accountCtx, &wrapperspb.UInt64Value{Value: 1000})

View File

@ -1,6 +1,67 @@
package implementation
import "context"
import (
"context"
"fmt"
"cosmossdk.io/collections"
"cosmossdk.io/core/address"
)
// Dependencies are passed to the constructor of a smart account.
type Dependencies struct {
SchemaBuilder *collections.SchemaBuilder
AddressCodec address.Codec
}
// AccountCreatorFunc is a function that creates an account.
type AccountCreatorFunc = func(deps Dependencies) (string, Implementation, error)
// AddAccount is a helper function to add a smart account to the list of smart accounts.
// It returns a function that given an Account implementer, returns the name of the account
// and the Implementation instance.
func AddAccount[A Account](name string, constructor func(deps Dependencies) (A, error)) func(deps Dependencies) (string, Implementation, error) {
return func(deps Dependencies) (string, Implementation, error) {
acc, err := constructor(deps)
if err != nil {
return "", Implementation{}, err
}
impl, err := NewImplementation(acc)
if err != nil {
return "", Implementation{}, err
}
return name, impl, nil
}
}
// MakeAccountsMap creates a map of account names to account implementations
// from a list of account creator functions.
func MakeAccountsMap(addressCodec address.Codec, accounts []AccountCreatorFunc) (map[string]Implementation, error) {
accountsMap := make(map[string]Implementation, len(accounts))
for _, makeAccount := range accounts {
stateSchemaBuilder := collections.NewSchemaBuilderFromAccessor(OpenKVStore)
deps := Dependencies{
SchemaBuilder: stateSchemaBuilder,
AddressCodec: addressCodec,
}
name, impl, err := makeAccount(deps)
if err != nil {
return nil, fmt.Errorf("failed to create account %s: %w", name, err)
}
if _, ok := accountsMap[name]; ok {
return nil, fmt.Errorf("account %s is already registered", name)
}
// build schema
schema, err := stateSchemaBuilder.Build()
if err != nil {
return nil, fmt.Errorf("failed to build schema for account %s: %w", name, err)
}
impl.CollectionsSchema = schema
accountsMap[name] = impl
}
return accountsMap, nil
}
// NewImplementation creates a new Implementation instance given an Account implementer.
func NewImplementation(account Account) (Implementation, error) {
@ -31,8 +92,10 @@ func NewImplementation(account Account) (Implementation, error) {
Init: initHandler,
Execute: executeHandler,
Query: queryHandler,
DecodeInitRequest: ir.decodeRequest,
EncodeInitResponse: ir.encodeResponse,
CollectionsSchema: collections.Schema{},
InitHandlerSchema: ir.schema,
QueryHandlersSchema: qr.er.handlersSchema,
ExecuteHandlersSchema: er.handlersSchema,
DecodeExecuteRequest: er.makeRequestDecoder(),
EncodeExecuteResponse: er.makeResponseEncoder(),
DecodeQueryRequest: qr.er.makeRequestDecoder(),
@ -49,13 +112,16 @@ 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)
// CollectionsSchema represents the state schema.
CollectionsSchema collections.Schema
// InitHandlerSchema represents the init handler schema.
InitHandlerSchema HandlerSchema
// QueryHandlersSchema is the schema of the query handlers.
QueryHandlersSchema map[string]HandlerSchema
// ExecuteHandlersSchema is the schema of the execute handlers.
ExecuteHandlersSchema map[string]HandlerSchema
// 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)
// TODO: remove these fields and use the schemas instead
// DecodeExecuteRequest decodes an execute request coming from the message server.
DecodeExecuteRequest func([]byte) (any, error)
@ -67,3 +133,30 @@ type Implementation struct {
// EncodeQueryResponse encodes a query response to be sent back from the message server.
EncodeQueryResponse func(any) ([]byte, error)
}
// MessageSchema defines the schema of a message.
// A message can also define a state schema.
type MessageSchema struct {
// Name identifies the message name, this must be queriable from some reflection service.
Name string
// TxDecode decodes into the message from transaction bytes.
// CONSENSUS SAFE: can be used in state machine logic.
TxDecode func([]byte) (any, error)
// TxEncode encodes the message into transaction bytes.
// CONSENSUS SAFE: can be used in state machine logic.
TxEncode func(any) ([]byte, error)
// HumanDecode decodes into the message from human-readable bytes.
// CONSENSUS UNSAFE: can be used only from clients, not state machine logic.
HumanDecode func([]byte) (any, error)
// HumanEncode encodes the message into human-readable bytes.
// CONSENSUS UNSAFE: can be used only from clients, not state machine logic.
HumanEncode func(any) ([]byte, error)
}
// HandlerSchema defines the schema of a handler.
type HandlerSchema struct {
// RequestSchema defines the schema of the request.
RequestSchema MessageSchema
// ResponseSchema defines the schema of the response.
ResponseSchema MessageSchema
}

View File

@ -70,10 +70,10 @@ func TestImplementation(t *testing.T) {
// schemas
t.Run("decode init request - ok", func(t *testing.T) {
want := &wrapperspb.StringValue{Value: "test"}
req, err := proto.Marshal(want)
req, err := impl.InitHandlerSchema.ResponseSchema.TxEncode(want)
require.NoError(t, err)
got, err := impl.DecodeInitRequest(req)
got, err := impl.InitHandlerSchema.RequestSchema.TxDecode(req)
require.NoError(t, err)
require.True(t, proto.Equal(want, got.(protoreflect.ProtoMessage)))
})
@ -81,7 +81,7 @@ func TestImplementation(t *testing.T) {
t.Run("encode init response - ok", func(t *testing.T) {
want := &wrapperspb.StringValue{Value: "test"}
gotBytes, err := impl.EncodeInitResponse(want)
gotBytes, err := impl.InitHandlerSchema.ResponseSchema.TxEncode(want)
require.NoError(t, err)
wantBytes, err := proto.Marshal(want)
@ -90,11 +90,6 @@ func TestImplementation(t *testing.T) {
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)

View File

@ -4,14 +4,17 @@ import (
"context"
"fmt"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface"
)
// ProtoMsg is a generic interface for protobuf messages.
type ProtoMsg[T any] interface {
*T
protoreflect.ProtoMessage
protoiface.MessageV1
}
// RegisterInitHandler registers an initialisation handler for a smart account that uses protobuf.
@ -20,7 +23,6 @@ func RegisterInitHandler[
](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)
@ -30,18 +32,9 @@ 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)
router.schema = HandlerSchema{
RequestSchema: *NewProtoMessageSchema[Req, ProtoReq](),
ResponseSchema: *NewProtoMessageSchema[Resp, ProtoResp](),
}
}
@ -64,6 +57,11 @@ func RegisterExecuteHandler[
}
return handler(ctx, concrete)
}
router.handlersSchema[string(reqName)] = HandlerSchema{
RequestSchema: *NewProtoMessageSchema[Req, ProtoReq](),
ResponseSchema: *NewProtoMessageSchema[Resp, ProtoResp](),
}
}
// RegisterQueryHandler registers a query handler for a smart account that uses protobuf.
@ -73,3 +71,45 @@ func RegisterQueryHandler[
) {
RegisterExecuteHandler(router.er, handler)
}
func NewProtoMessageSchema[T any, PT ProtoMsg[T]]() *MessageSchema {
msg := PT(new(T))
marshaler := proto.MarshalOptions{Deterministic: true}
unmarshaler := proto.UnmarshalOptions{DiscardUnknown: true} // TODO: safe to discard unknown? or should reject?
jsonMarshaler := protojson.MarshalOptions{
Multiline: true,
Indent: " ",
UseProtoNames: true,
}
jsonUnmarshaler := protojson.UnmarshalOptions{
DiscardUnknown: true,
}
return &MessageSchema{
Name: string(msg.ProtoReflect().Descriptor().FullName()),
TxDecode: func(bytes []byte) (any, error) {
obj := PT(new(T))
err := unmarshaler.Unmarshal(bytes, obj)
return obj, err
},
TxEncode: func(a any) ([]byte, error) {
concrete, ok := a.(PT)
if !ok {
return nil, fmt.Errorf("%w: wanted %s, got %T", errInvalidMessage, msg.ProtoReflect().Descriptor().FullName(), a)
}
return marshaler.Marshal(concrete)
},
HumanDecode: func(bytes []byte) (any, error) {
obj := PT(new(T))
err := jsonUnmarshaler.Unmarshal(bytes, obj)
return obj, err
},
HumanEncode: func(a any) ([]byte, error) {
concrete, ok := a.(PT)
if !ok {
return nil, fmt.Errorf("%w: wanted %s, got %T", errInvalidMessage, msg.ProtoReflect().Descriptor().FullName(), a)
}
return jsonMarshaler.Marshal(concrete)
},
}
}

View File

@ -8,11 +8,16 @@ import (
"fmt"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"cosmossdk.io/collections"
"cosmossdk.io/core/address"
"cosmossdk.io/core/event"
"cosmossdk.io/core/store"
"cosmossdk.io/x/accounts/accountstd"
"cosmossdk.io/x/accounts/internal/implementation"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
)
var errAccountTypeNotFound = errors.New("account type not found")
@ -24,51 +29,92 @@ var (
AccountNumberKey = collections.NewPrefix(1)
)
// QueryRouter represents a router which can be used to route queries to the correct module.
// It returns the handler given the message name, if multiple handlers are returned, then
// it is up to the caller to choose which one to call.
type QueryRouter interface {
HybridHandlerByRequestName(name string) []func(ctx context.Context, req, resp protoiface.MessageV1) error
}
// MsgRouter represents a router which can be used to route messages to the correct module.
type MsgRouter interface {
HybridHandlerByMsgName(msgName string) func(ctx context.Context, req, resp protoiface.MessageV1) error
}
// SignerProvider defines an interface used to get the expected sender from a message.
type SignerProvider interface {
// GetSigners returns the signers of the message.
GetSigners(msg proto.Message) ([][]byte, error)
}
func NewKeeper(
ss store.KVStoreService,
es event.Service,
addressCodec address.Codec,
getMsgSenderFunc func(msg proto.Message) ([]byte, error),
execModuleFunc func(ctx context.Context, msg proto.Message) (proto.Message, error),
queryModuleFunc func(ctx context.Context, msg proto.Message) (proto.Message, error),
accounts map[string]implementation.Account,
signerProvider SignerProvider,
execRouter MsgRouter,
queryRouter QueryRouter,
accounts ...accountstd.AccountCreatorFunc,
) (Keeper, error) {
sb := collections.NewSchemaBuilder(ss)
keeper := Keeper{
storeService: ss,
addressCodec: addressCodec,
getSenderFunc: getMsgSenderFunc,
execModuleFunc: execModuleFunc,
queryModuleFunc: queryModuleFunc,
accounts: map[string]implementation.Implementation{},
Schema: collections.Schema{},
AccountNumber: collections.NewSequence(sb, AccountNumberKey, "account_number"),
AccountsByType: collections.NewMap(sb, AccountTypeKeyPrefix, "accounts_by_type", collections.BytesKey, collections.StringValue),
AccountsState: collections.NewMap(sb, implementation.AccountStatePrefix, "accounts_state", collections.BytesKey, collections.BytesValue),
storeService: ss,
eventService: es,
addressCodec: addressCodec,
getSenderFunc: func(msg proto.Message) ([]byte, error) {
signers, err := signerProvider.GetSigners(msg)
if err != nil {
return nil, err
}
if len(signers) != 1 {
return nil, fmt.Errorf("expected 1 signer, got %d", len(signers))
}
return signers[0], nil
},
execModuleFunc: func(ctx context.Context, msg, msgResp protoiface.MessageV1) error {
name := getMessageName(msg)
handler := execRouter.HybridHandlerByMsgName(name)
if handler == nil {
return fmt.Errorf("no handler found for message %s", name)
}
return handler(ctx, msg, msgResp)
},
queryModuleFunc: func(ctx context.Context, req, resp protoiface.MessageV1) error {
name := getMessageName(req)
handlers := queryRouter.HybridHandlerByRequestName(name)
if len(handlers) == 0 {
return fmt.Errorf("no handler found for query request %s", name)
}
if len(handlers) > 1 {
return fmt.Errorf("multiple handlers found for query request %s", name)
}
return handlers[0](ctx, req, resp)
},
AccountNumber: collections.NewSequence(sb, AccountNumberKey, "account_number"),
AccountsByType: collections.NewMap(sb, AccountTypeKeyPrefix, "accounts_by_type", collections.BytesKey, collections.StringValue),
AccountsState: collections.NewMap(sb, implementation.AccountStatePrefix, "accounts_state", collections.BytesKey, collections.BytesValue),
}
// make accounts implementation
for typ, acc := range accounts {
impl, err := implementation.NewImplementation(acc)
if err != nil {
return Keeper{}, err
}
keeper.accounts[typ] = impl
}
schema, err := sb.Build()
if err != nil {
return Keeper{}, err
}
keeper.Schema = schema
keeper.accounts, err = implementation.MakeAccountsMap(keeper.addressCodec, accounts)
if err != nil {
return Keeper{}, err
}
return keeper, nil
}
type Keeper struct {
// deps coming from the runtime
storeService store.KVStoreService
eventService event.Service
addressCodec address.Codec
getSenderFunc func(msg proto.Message) ([]byte, error)
execModuleFunc func(ctx context.Context, msg proto.Message) (proto.Message, error)
queryModuleFunc func(ctx context.Context, msg proto.Message) (proto.Message, error)
execModuleFunc implementation.ModuleExecFunc
queryModuleFunc implementation.ModuleQueryFunc
accounts map[string]implementation.Implementation
@ -215,9 +261,13 @@ func (k Keeper) makeAccountContext(ctx context.Context, accountAddr, sender []by
func(_ proto.Message) ([]byte, error) {
return nil, fmt.Errorf("cannot get sender from query")
},
func(ctx context.Context, _ proto.Message) (proto.Message, error) {
return nil, fmt.Errorf("cannot execute module from query")
func(ctx context.Context, msg, msgResp protoiface.MessageV1) error {
return fmt.Errorf("cannot execute module from a query execution context")
},
k.queryModuleFunc,
)
}
func getMessageName(msg protoiface.MessageV1) string {
return codectypes.MsgTypeURL(msg)[1:]
}

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
@ -14,6 +15,8 @@ import (
"cosmossdk.io/collections"
"cosmossdk.io/collections/colltest"
"cosmossdk.io/core/address"
"cosmossdk.io/core/event"
"cosmossdk.io/x/accounts/accountstd"
"cosmossdk.io/x/accounts/internal/implementation"
)
@ -24,22 +27,36 @@ 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) {
type eventService struct{}
func (e eventService) Emit(ctx context.Context, event protoiface.MessageV1) error { return nil }
func (e eventService) EmitKV(ctx context.Context, eventType string, attrs ...event.Attribute) error {
return nil
}
func (e eventService) EmitNonConsensus(ctx context.Context, event protoiface.MessageV1) error {
return nil
}
func (e eventService) EventManager(ctx context.Context) event.Manager { return e }
func newKeeper(t *testing.T, accounts ...implementation.AccountCreatorFunc) (Keeper, context.Context) {
t.Helper()
ss, ctx := colltest.MockStore()
m, err := NewKeeper(ss, addressCodec{}, nil, nil, nil, accounts)
m, err := NewKeeper(ss, eventService{}, addressCodec{}, nil, nil, nil, accounts...)
require.NoError(t, err)
return m, ctx
}
func TestKeeper_Init(t *testing.T) {
m, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
m.queryModuleFunc = func(ctx context.Context, msg proto.Message) (proto.Message, error) {
_, ok := msg.(*bankv1beta1.QueryBalanceRequest)
m, ctx := newKeeper(t, accountstd.AddAccount("test", NewTestAccount))
m.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error {
_, ok := req.(*bankv1beta1.QueryBalanceRequest)
require.True(t, ok)
return &bankv1beta1.QueryBalanceResponse{}, nil
_, ok = resp.(*bankv1beta1.QueryBalanceResponse)
require.True(t, ok)
return nil
}
t.Run("ok", func(t *testing.T) {
@ -68,12 +85,8 @@ func TestKeeper_Init(t *testing.T) {
}
func TestKeeper_Execute(t *testing.T) {
m, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
m.queryModuleFunc = func(_ context.Context, _ proto.Message) (proto.Message, error) {
return &bankv1beta1.QueryBalanceResponse{}, nil
}
m, ctx := newKeeper(t, accountstd.AddAccount("test", NewTestAccount))
m.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error { return nil }
// create account
sender := []byte("sender")
@ -92,11 +105,13 @@ func TestKeeper_Execute(t *testing.T) {
})
t.Run("exec module", func(t *testing.T) {
m.execModuleFunc = func(ctx context.Context, msg proto.Message) (proto.Message, error) {
m.execModuleFunc = func(ctx context.Context, msg, msgResp protoiface.MessageV1) error {
concrete, ok := msg.(*bankv1beta1.MsgSend)
require.True(t, ok)
require.Equal(t, concrete.ToAddress, "recipient")
return &bankv1beta1.MsgSendResponse{}, nil
_, ok = msgResp.(*bankv1beta1.MsgSendResponse)
require.True(t, ok)
return nil
}
m.getSenderFunc = func(msg proto.Message) ([]byte, error) {
@ -111,11 +126,9 @@ func TestKeeper_Execute(t *testing.T) {
}
func TestKeeper_Query(t *testing.T) {
m, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
m.queryModuleFunc = func(_ context.Context, _ proto.Message) (proto.Message, error) {
return &bankv1beta1.QueryBalanceResponse{}, nil
m, ctx := newKeeper(t, accountstd.AddAccount("test", NewTestAccount))
m.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error {
return nil
}
// create account
@ -137,15 +150,17 @@ func TestKeeper_Query(t *testing.T) {
t.Run("query module", func(t *testing.T) {
// we inject the module query function, which accepts only a specific type of message
// we force the response
m.queryModuleFunc = func(ctx context.Context, msg proto.Message) (proto.Message, error) {
concrete, ok := msg.(*bankv1beta1.QueryBalanceRequest)
m.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error {
concrete, ok := req.(*bankv1beta1.QueryBalanceRequest)
require.True(t, ok)
require.Equal(t, string(accAddr), concrete.Address)
require.Equal(t, concrete.Denom, "atom")
return &bankv1beta1.QueryBalanceResponse{Balance: &basev1beta1.Coin{
copyResp := &bankv1beta1.QueryBalanceResponse{Balance: &basev1beta1.Coin{
Denom: "atom",
Amount: "1000",
}}, nil
}}
proto.Merge(resp.(proto.Message), copyResp)
return nil
}
resp, err := m.Query(ctx, accAddr, wrapperspb.String("atom"))

107
x/accounts/module.go Normal file
View File

@ -0,0 +1,107 @@
package accounts
import (
"context"
"encoding/json"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/x/accounts/cli"
v1 "cosmossdk.io/x/accounts/v1"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/types/msgservice"
)
const (
ModuleName = "accounts"
StoreKey = "_" + ModuleName // unfortunately accounts collides with auth store key
)
const (
ConsensusVersion = 1
)
var (
_ appmodule.AppModule = AppModule{}
_ module.HasName = AppModule{}
_ module.HasGenesis = AppModule{}
_ module.HasServices = AppModule{}
_ module.HasConsensusVersion = AppModule{}
)
func NewAppModule(k Keeper) AppModule {
return AppModule{k: k}
}
type AppModule struct {
k Keeper
}
func (m AppModule) IsOnePerModuleType() {}
func (m AppModule) IsAppModule() {}
func (m AppModule) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {}
func (m AppModule) RegisterInterfaces(registry types.InterfaceRegistry) {
msgservice.RegisterMsgServiceDesc(registry, v1.MsgServiceDesc())
}
func (m AppModule) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {}
// App module services
func (m AppModule) RegisterServices(configurator module.Configurator) {
v1.RegisterQueryServer(configurator.QueryServer(), NewQueryServer(m.k))
v1.RegisterMsgServer(configurator.MsgServer(), NewMsgServer(m.k))
}
// App module genesis
func (AppModule) DefaultGenesis(jsonCodec codec.JSONCodec) json.RawMessage {
return jsonCodec.MustMarshalJSON(&v1.GenesisState{})
}
func (AppModule) ValidateGenesis(jsonCodec codec.JSONCodec, config client.TxEncodingConfig, message json.RawMessage) error {
gs := &v1.GenesisState{}
if err := jsonCodec.UnmarshalJSON(message, gs); err != nil {
return err
}
// Add validation logic for gs here
return nil
}
func (m AppModule) InitGenesis(ctx context.Context, jsonCodec codec.JSONCodec, message json.RawMessage) {
gs := &v1.GenesisState{}
jsonCodec.MustUnmarshalJSON(message, gs)
err := m.k.ImportState(ctx, gs)
if err != nil {
panic(err)
}
}
func (m AppModule) ExportGenesis(ctx context.Context, jsonCodec codec.JSONCodec) json.RawMessage {
gs, err := m.k.ExportState(ctx)
if err != nil {
panic(err)
}
return jsonCodec.MustMarshalJSON(gs)
}
func (AppModule) Name() string { return ModuleName }
func (AppModule) GetTxCmd() *cobra.Command {
return cli.TxCmd(ModuleName)
}
func (AppModule) GetQueryCmd() *cobra.Command {
return cli.QueryCmd(ModuleName)
}
func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }

View File

@ -3,6 +3,7 @@ package accounts
import (
"context"
"cosmossdk.io/core/event"
v1 "cosmossdk.io/x/accounts/v1"
)
@ -28,7 +29,7 @@ func (m msgServer) Init(ctx context.Context, request *v1.MsgInit) (*v1.MsgInitRe
}
// decode message bytes into the concrete boxed message type
msg, err := impl.DecodeInitRequest(request.Message)
msg, err := impl.InitHandlerSchema.RequestSchema.TxDecode(request.Message)
if err != nil {
return nil, err
}
@ -40,7 +41,7 @@ func (m msgServer) Init(ctx context.Context, request *v1.MsgInit) (*v1.MsgInitRe
}
// encode the response
respBytes, err := impl.EncodeInitResponse(resp)
respBytes, err := impl.InitHandlerSchema.ResponseSchema.TxEncode(resp)
if err != nil {
return nil, err
}
@ -51,6 +52,18 @@ func (m msgServer) Init(ctx context.Context, request *v1.MsgInit) (*v1.MsgInitRe
return nil, err
}
eventManager := m.k.eventService.EventManager(ctx)
err = eventManager.EmitKV(
ctx,
"account_creation",
event.Attribute{
Key: "address",
Value: accAddrString,
},
)
if err != nil {
return nil, err
}
return &v1.MsgInitResponse{
AccountAddress: accAddrString,
Response: respBytes,

View File

@ -6,23 +6,23 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"cosmossdk.io/x/accounts/internal/implementation"
"cosmossdk.io/x/accounts/accountstd"
v1 "cosmossdk.io/x/accounts/v1"
)
func TestMsgServer(t *testing.T) {
k, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
k.queryModuleFunc = func(ctx context.Context, msg proto.Message) (proto.Message, error) {
_, ok := msg.(*bankv1beta1.QueryBalanceRequest)
k, ctx := newKeeper(t, accountstd.AddAccount("test", NewTestAccount))
k.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error {
_, ok := req.(*bankv1beta1.QueryBalanceRequest)
require.True(t, ok)
return &bankv1beta1.QueryBalanceResponse{}, nil
proto.Merge(resp.(proto.Message), &bankv1beta1.QueryBalanceResponse{})
return nil
}
s := NewMsgServer(k)

View File

@ -2,6 +2,7 @@ package accounts
import (
"context"
"fmt"
v1 "cosmossdk.io/x/accounts/v1"
)
@ -56,3 +57,28 @@ func (q queryServer) AccountQuery(ctx context.Context, request *v1.AccountQueryR
Response: respBytes,
}, nil
}
func (q queryServer) Schema(_ context.Context, request *v1.SchemaRequest) (*v1.SchemaResponse, error) {
// TODO: maybe we should cache this, considering accounts types are not
// added on the fly as the chain is running.
schemas := v1.MakeAccountsSchemas(q.k.accounts)
schema, ok := schemas[request.AccountType]
if !ok {
return nil, fmt.Errorf("%w: %s", errAccountTypeNotFound, request.AccountType)
}
return schema, nil
}
func (q queryServer) AccountType(ctx context.Context, request *v1.AccountTypeRequest) (*v1.AccountTypeResponse, error) {
addr, err := q.k.addressCodec.StringToBytes(request.Address)
if err != nil {
return nil, err
}
accType, err := q.k.AccountsByType.Get(ctx, addr)
if err != nil {
return nil, err
}
return &v1.AccountTypeResponse{
AccountType: accType,
}, nil
}

View File

@ -6,21 +6,19 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"cosmossdk.io/x/accounts/internal/implementation"
"cosmossdk.io/x/accounts/accountstd"
v1 "cosmossdk.io/x/accounts/v1"
)
func TestQueryServer(t *testing.T) {
k, ctx := newKeeper(t, map[string]implementation.Account{
"test": TestAccount{},
})
k.queryModuleFunc = func(ctx context.Context, msg proto.Message) (proto.Message, error) {
return &bankv1beta1.QueryBalanceResponse{}, nil
k, ctx := newKeeper(t, accountstd.AddAccount("test", NewTestAccount))
k.queryModuleFunc = func(ctx context.Context, req, resp protoiface.MessageV1) error {
return nil
}
ms := NewMsgServer(k)

View File

@ -0,0 +1,92 @@
package counter
import (
"bytes"
"context"
"fmt"
counterv1 "cosmossdk.io/api/cosmos/accounts/testing/counter/v1"
"cosmossdk.io/collections"
"cosmossdk.io/x/accounts/accountstd"
)
var (
OwnerPrefix = collections.NewPrefix(0)
CounterPrefix = collections.NewPrefix(1)
)
var _ accountstd.Interface = (*Account)(nil)
// NewAccount creates a new account.
func NewAccount(d accountstd.Dependencies) (Account, error) {
return Account{
Owner: collections.NewItem(d.SchemaBuilder, OwnerPrefix, "owner", collections.BytesValue),
Counter: collections.NewItem(d.SchemaBuilder, CounterPrefix, "counter", collections.Uint64Value),
}, nil
}
// Account implements the Account interface. It is an account
// who can be used to increase a counter.
type Account struct {
// Owner is the address of the account owner.
Owner collections.Item[[]byte]
// Counter is the counter value.
Counter collections.Item[uint64]
}
func (a Account) Init(ctx context.Context, msg *counterv1.MsgInit) (*counterv1.MsgInitResponse, error) {
err := a.Owner.Set(ctx, accountstd.Sender(ctx))
if err != nil {
return nil, err
}
err = a.Counter.Set(ctx, msg.InitialValue)
if err != nil {
return nil, err
}
return &counterv1.MsgInitResponse{}, nil
}
func (a Account) IncreaseCounter(ctx context.Context, msg *counterv1.MsgIncreaseCounter) (*counterv1.MsgIncreaseCounterResponse, error) {
sender := accountstd.Sender(ctx)
owner, err := a.Owner.Get(ctx)
if err != nil {
return nil, err
}
if !bytes.Equal(sender, owner) {
return nil, fmt.Errorf("sender is not the owner of the account")
}
counter, err := a.Counter.Get(ctx)
if err != nil {
return nil, err
}
counter += msg.Amount
err = a.Counter.Set(ctx, counter)
if err != nil {
return nil, err
}
return &counterv1.MsgIncreaseCounterResponse{
NewAmount: counter,
}, nil
}
func (a Account) QueryCounter(ctx context.Context, _ *counterv1.QueryCounterRequest) (*counterv1.QueryCounterResponse, error) {
counter, err := a.Counter.Get(ctx)
if err != nil {
return nil, err
}
return &counterv1.QueryCounterResponse{
Value: counter,
}, nil
}
func (a Account) RegisterInitHandler(builder *accountstd.InitBuilder) {
accountstd.RegisterInitHandler(builder, a.Init)
}
func (a Account) RegisterExecuteHandlers(builder *accountstd.ExecuteBuilder) {
accountstd.RegisterExecuteHandler(builder, a.IncreaseCounter)
}
func (a Account) RegisterQueryHandlers(builder *accountstd.QueryBuilder) {
accountstd.RegisterQueryHandler(builder, a.QueryCounter)
}

File diff suppressed because it is too large Load Diff

47
x/accounts/v1/schema.go Normal file
View File

@ -0,0 +1,47 @@
package v1
import (
"strings"
"golang.org/x/exp/slices"
"google.golang.org/grpc"
"cosmossdk.io/x/accounts/internal/implementation"
)
func MakeAccountsSchemas(impls map[string]implementation.Implementation) map[string]*SchemaResponse {
m := make(map[string]*SchemaResponse, len(impls))
for name, impl := range impls {
m[name] = makeAccountSchema(impl)
}
return m
}
func makeAccountSchema(impl implementation.Implementation) *SchemaResponse {
return &SchemaResponse{
InitSchema: &SchemaResponse_Handler{
Request: impl.InitHandlerSchema.RequestSchema.Name,
Response: impl.InitHandlerSchema.ResponseSchema.Name,
},
ExecuteHandlers: makeHandlersSchema(impl.ExecuteHandlersSchema),
QueryHandlers: makeHandlersSchema(impl.QueryHandlersSchema),
}
}
func makeHandlersSchema(handlers map[string]implementation.HandlerSchema) []*SchemaResponse_Handler {
schemas := make([]*SchemaResponse_Handler, 0, len(handlers))
for name, handler := range handlers {
schemas = append(schemas, &SchemaResponse_Handler{
Request: name,
Response: handler.ResponseSchema.Name,
})
}
slices.SortFunc(schemas, func(a, b *SchemaResponse_Handler) int {
return strings.Compare(a.Request, b.Request)
})
return schemas
}
func MsgServiceDesc() *grpc.ServiceDesc {
return &_Msg_serviceDesc
}

View File

@ -6,6 +6,7 @@ package v1
import (
context "context"
fmt "fmt"
_ "github.com/cosmos/cosmos-sdk/types/msgservice"
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
grpc "google.golang.org/grpc"
@ -268,27 +269,29 @@ func init() {
func init() { proto.RegisterFile("cosmos/accounts/v1/tx.proto", fileDescriptor_29c2b6d8a13d4189) }
var fileDescriptor_29c2b6d8a13d4189 = []byte{
// 319 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xc1, 0x4a, 0xfb, 0x40,
0x10, 0xc6, 0xbb, 0xff, 0xfe, 0x69, 0x75, 0x2c, 0x16, 0xf6, 0x50, 0x42, 0x0a, 0x4b, 0xad, 0xa0,
0x3d, 0x6d, 0xac, 0xfa, 0x02, 0x0a, 0x82, 0x1e, 0x7a, 0x30, 0x48, 0x0f, 0x1e, 0x94, 0x98, 0x0c,
0xa1, 0x48, 0xb3, 0x21, 0xb3, 0x2d, 0xed, 0x5b, 0xf8, 0x0c, 0x3e, 0x8d, 0xc7, 0x1e, 0x3d, 0x4a,
0xf2, 0x22, 0x42, 0xb2, 0x89, 0x15, 0x69, 0x8e, 0xdf, 0x7c, 0x3b, 0xdf, 0xfc, 0x76, 0x18, 0xe8,
0xfb, 0x8a, 0xe6, 0x8a, 0x1c, 0xcf, 0xf7, 0xd5, 0x22, 0xd2, 0xe4, 0x2c, 0xc7, 0x8e, 0x5e, 0xc9,
0x38, 0x51, 0x5a, 0x71, 0x5e, 0x98, 0xb2, 0x34, 0xe5, 0x72, 0x3c, 0x7c, 0x82, 0xf6, 0x84, 0xc2,
0xbb, 0x68, 0xa6, 0x79, 0x0f, 0x5a, 0x84, 0x51, 0x80, 0x89, 0xc5, 0x06, 0x6c, 0xb4, 0xef, 0x1a,
0xc5, 0x8f, 0xa0, 0x63, 0x3a, 0x9e, 0xf5, 0x3a, 0x46, 0xeb, 0x5f, 0xee, 0x1e, 0x98, 0xda, 0xc3,
0x3a, 0x46, 0x6e, 0x41, 0x7b, 0x8e, 0x44, 0x5e, 0x88, 0x56, 0x73, 0xc0, 0x46, 0x1d, 0xb7, 0x94,
0xc3, 0x29, 0x74, 0x4d, 0xbe, 0x8b, 0x14, 0xab, 0x88, 0x90, 0x9f, 0x42, 0xb7, 0xcc, 0xf3, 0x82,
0x20, 0x41, 0x22, 0x33, 0xf0, 0xd0, 0x94, 0xaf, 0x8a, 0x2a, 0xb7, 0x61, 0x2f, 0x31, 0x4d, 0xf9,
0xd0, 0x8e, 0x5b, 0xe9, 0xe1, 0x14, 0x60, 0x42, 0xe1, 0xcd, 0x0a, 0xfd, 0x85, 0xc6, 0x9d, 0xe8,
0x3d, 0x68, 0x69, 0x2f, 0x09, 0x51, 0x1b, 0x68, 0xa3, 0x6a, 0x78, 0xcf, 0x80, 0xff, 0xe4, 0x56,
0xc8, 0xdb, 0x24, 0xec, 0x37, 0xc9, 0xf9, 0x3b, 0x83, 0xe6, 0x84, 0x42, 0x7e, 0x0b, 0xff, 0xf3,
0x35, 0xf6, 0xe5, 0xdf, 0x35, 0x4b, 0xb3, 0x03, 0xfb, 0xb8, 0xc6, 0xac, 0xa6, 0xdd, 0x43, 0xbb,
0xfc, 0x98, 0xd8, 0xf1, 0xde, 0xf8, 0xf6, 0x49, 0xbd, 0x5f, 0x46, 0x5e, 0x5f, 0x7e, 0xa4, 0x82,
0x6d, 0x52, 0xc1, 0xbe, 0x52, 0xc1, 0xde, 0x32, 0xd1, 0xd8, 0x64, 0xa2, 0xf1, 0x99, 0x89, 0xc6,
0xa3, 0x5d, 0x04, 0x50, 0xf0, 0x2a, 0x67, 0xca, 0x59, 0x6d, 0x5f, 0xce, 0x4b, 0x2b, 0xbf, 0x9b,
0x8b, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x58, 0xc2, 0x24, 0xb3, 0x56, 0x02, 0x00, 0x00,
// 349 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xb1, 0x4e, 0x02, 0x41,
0x10, 0x65, 0x45, 0x41, 0x07, 0x22, 0xc9, 0x16, 0x78, 0x39, 0x92, 0x0d, 0x62, 0xa2, 0x84, 0xe2,
0x4e, 0xd4, 0xca, 0x4e, 0x13, 0x13, 0x2d, 0x28, 0xbc, 0x18, 0x0b, 0x1b, 0x73, 0xde, 0x6d, 0x36,
0x84, 0xdc, 0xed, 0xe5, 0x66, 0x21, 0xd0, 0x19, 0xbf, 0xc0, 0xdf, 0xb0, 0xe3, 0x33, 0x2c, 0x29,
0x2d, 0x0d, 0x14, 0xfc, 0x86, 0xf1, 0x6e, 0x0f, 0x31, 0x06, 0x62, 0xf9, 0xe6, 0xcd, 0xbe, 0xf7,
0x66, 0x76, 0xa0, 0xe6, 0x49, 0x0c, 0x24, 0xda, 0xae, 0xe7, 0xc9, 0x7e, 0xa8, 0xd0, 0x1e, 0xb4,
0x6d, 0x35, 0xb4, 0xa2, 0x58, 0x2a, 0x49, 0x69, 0x4a, 0x5a, 0x19, 0x69, 0x0d, 0xda, 0xe6, 0x9e,
0x7e, 0x10, 0xa0, 0xf8, 0xee, 0x0d, 0x50, 0xa4, 0xcd, 0x8d, 0x1e, 0x14, 0x3b, 0x28, 0x6e, 0xc2,
0xae, 0xa2, 0x55, 0x28, 0x20, 0x0f, 0x7d, 0x1e, 0x1b, 0xa4, 0x4e, 0x9a, 0x3b, 0x8e, 0x46, 0x74,
0x1f, 0xca, 0x5a, 0xea, 0x51, 0x8d, 0x22, 0x6e, 0x6c, 0x24, 0x6c, 0x49, 0xd7, 0xee, 0x46, 0x11,
0xa7, 0x06, 0x14, 0x03, 0x8e, 0xe8, 0x0a, 0x6e, 0xe4, 0xeb, 0xa4, 0x59, 0x76, 0x32, 0x78, 0x5e,
0x7a, 0x99, 0x8f, 0x5b, 0x5a, 0xa9, 0x71, 0x0f, 0x15, 0x6d, 0xe6, 0x70, 0x8c, 0x64, 0x88, 0x9c,
0x1e, 0x41, 0x25, 0x13, 0x77, 0x7d, 0x3f, 0xe6, 0x88, 0xda, 0x7d, 0x57, 0x97, 0x2f, 0xd2, 0x2a,
0x35, 0x61, 0x3b, 0xd6, 0x8f, 0x92, 0x04, 0x65, 0x67, 0x81, 0x1b, 0x1e, 0x40, 0x07, 0xc5, 0xd5,
0x90, 0x7b, 0x7d, 0xc5, 0x57, 0xce, 0x51, 0x85, 0x82, 0x72, 0x63, 0xc1, 0x95, 0x9e, 0x40, 0xa3,
0xff, 0x86, 0x3f, 0x06, 0xfa, 0x63, 0xb2, 0xc8, 0xbf, 0x1c, 0x8b, 0xfc, 0x8e, 0x75, 0xf2, 0x46,
0x20, 0xdf, 0x41, 0x41, 0xaf, 0x61, 0x33, 0x59, 0x70, 0xcd, 0xfa, 0xfb, 0x33, 0x96, 0x5e, 0x88,
0x79, 0xb0, 0x86, 0x5c, 0xb8, 0xdd, 0x42, 0x31, 0x9b, 0x92, 0xad, 0xe8, 0xd7, 0xbc, 0x79, 0xb8,
0x9e, 0xcf, 0x24, 0xcd, 0xad, 0xe7, 0xf9, 0xb8, 0x45, 0x2e, 0xcf, 0xde, 0xa7, 0x8c, 0x4c, 0xa6,
0x8c, 0x7c, 0x4e, 0x19, 0x79, 0x9d, 0xb1, 0xdc, 0x64, 0xc6, 0x72, 0x1f, 0x33, 0x96, 0x7b, 0x30,
0x53, 0x1d, 0xf4, 0x7b, 0x56, 0x57, 0xda, 0xc3, 0xe5, 0x9b, 0x7b, 0x2a, 0x24, 0x47, 0x74, 0xfa,
0x15, 0x00, 0x00, 0xff, 0xff, 0xd9, 0x2e, 0x5d, 0x73, 0x90, 0x02, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.