From bf6521b385ef60102f8f820a149b94c134604a6f Mon Sep 17 00:00:00 2001 From: astaphobia Date: Wed, 26 Feb 2020 16:01:35 +0800 Subject: [PATCH 1/7] no need to validate current block height --- common/transaction/sendMoney.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/common/transaction/sendMoney.go b/common/transaction/sendMoney.go index 3c2ca882c..d10ff5a1b 100644 --- a/common/transaction/sendMoney.go +++ b/common/transaction/sendMoney.go @@ -292,7 +292,6 @@ Escrow Part func (tx *SendMoney) EscrowValidate(dbTx bool) error { var ( accountBalance model.AccountBalance - block *model.Block err error row *sql.Row ) @@ -310,14 +309,6 @@ func (tx *SendMoney) EscrowValidate(dbTx bool) error { return blocker.NewBlocker(blocker.ValidationErr, "RecipientAddressRequired") } - block, err = util.GetLastBlock(tx.QueryExecutor, tx.BlockQuery) - if err != nil { - return blocker.NewBlocker(blocker.ValidationErr, err.Error()) - } - if uint64(block.GetHeight()) >= tx.Escrow.GetTimeout() { - return blocker.NewBlocker(blocker.ValidationErr, "TransactionExpired") - } - // todo: this is temporary solution, later we should depend on coinbase, so no genesis transaction exclusion in // validation needed if tx.SenderAddress != constant.MainchainGenesisAccountAddress { From 28e9fe6c052c26f6c5f331d27018ab09b28e9fb0 Mon Sep 17 00:00:00 2001 From: astaphobia Date: Fri, 27 Mar 2020 07:55:01 +0800 Subject: [PATCH 2/7] rename accountDataset to plural name --- common/model/accountDataset.pb.go | 355 +++++++++++++++++++++++++++++ common/model/accountDatasets.pb.go | 168 -------------- 2 files changed, 355 insertions(+), 168 deletions(-) create mode 100644 common/model/accountDataset.pb.go delete mode 100644 common/model/accountDatasets.pb.go diff --git a/common/model/accountDataset.pb.go b/common/model/accountDataset.pb.go new file mode 100644 index 000000000..55634819a --- /dev/null +++ b/common/model/accountDataset.pb.go @@ -0,0 +1,355 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: model/accountDataset.proto + +package model + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// AccountDatasetProperty represent enum values for AccountDataset Property +type AccountDatasetProperty int32 + +const ( + AccountDatasetProperty_AccountDatasetEscrowApproval AccountDatasetProperty = 0 +) + +var AccountDatasetProperty_name = map[int32]string{ + 0: "AccountDatasetEscrowApproval", +} + +var AccountDatasetProperty_value = map[string]int32{ + "AccountDatasetEscrowApproval": 0, +} + +func (x AccountDatasetProperty) String() string { + return proto.EnumName(AccountDatasetProperty_name, int32(x)) +} + +func (AccountDatasetProperty) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8f6e88b2db5bd817, []int{0} +} + +// AccountDataset represent the account dataset structure stored in the database +type AccountDataset struct { + SetterAccountAddress string `protobuf:"bytes,1,opt,name=SetterAccountAddress,proto3" json:"SetterAccountAddress,omitempty"` + RecipientAccountAddress string `protobuf:"bytes,2,opt,name=RecipientAccountAddress,proto3" json:"RecipientAccountAddress,omitempty"` + Property string `protobuf:"bytes,3,opt,name=Property,proto3" json:"Property,omitempty"` + Value string `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"` + TimestampStarts uint64 `protobuf:"varint,5,opt,name=TimestampStarts,proto3" json:"TimestampStarts,omitempty"` + TimestampExpires uint64 `protobuf:"varint,6,opt,name=TimestampExpires,proto3" json:"TimestampExpires,omitempty"` + Height uint32 `protobuf:"varint,7,opt,name=Height,proto3" json:"Height,omitempty"` + Latest bool `protobuf:"varint,8,opt,name=Latest,proto3" json:"Latest,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccountDataset) Reset() { *m = AccountDataset{} } +func (m *AccountDataset) String() string { return proto.CompactTextString(m) } +func (*AccountDataset) ProtoMessage() {} +func (*AccountDataset) Descriptor() ([]byte, []int) { + return fileDescriptor_8f6e88b2db5bd817, []int{0} +} + +func (m *AccountDataset) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AccountDataset.Unmarshal(m, b) +} +func (m *AccountDataset) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AccountDataset.Marshal(b, m, deterministic) +} +func (m *AccountDataset) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccountDataset.Merge(m, src) +} +func (m *AccountDataset) XXX_Size() int { + return xxx_messageInfo_AccountDataset.Size(m) +} +func (m *AccountDataset) XXX_DiscardUnknown() { + xxx_messageInfo_AccountDataset.DiscardUnknown(m) +} + +var xxx_messageInfo_AccountDataset proto.InternalMessageInfo + +func (m *AccountDataset) GetSetterAccountAddress() string { + if m != nil { + return m.SetterAccountAddress + } + return "" +} + +func (m *AccountDataset) GetRecipientAccountAddress() string { + if m != nil { + return m.RecipientAccountAddress + } + return "" +} + +func (m *AccountDataset) GetProperty() string { + if m != nil { + return m.Property + } + return "" +} + +func (m *AccountDataset) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *AccountDataset) GetTimestampStarts() uint64 { + if m != nil { + return m.TimestampStarts + } + return 0 +} + +func (m *AccountDataset) GetTimestampExpires() uint64 { + if m != nil { + return m.TimestampExpires + } + return 0 +} + +func (m *AccountDataset) GetHeight() uint32 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *AccountDataset) GetLatest() bool { + if m != nil { + return m.Latest + } + return false +} + +// GetAccountDatasetsRequest represent request fields to get account dataset +type GetAccountDatasetsRequest struct { + Property string `protobuf:"bytes,1,opt,name=Property,proto3" json:"Property,omitempty"` + Value string `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` + RecipientAccountAddress string `protobuf:"bytes,3,opt,name=RecipientAccountAddress,proto3" json:"RecipientAccountAddress,omitempty"` + SetterAccountAddress string `protobuf:"bytes,4,opt,name=SetterAccountAddress,proto3" json:"SetterAccountAddress,omitempty"` + Height uint32 `protobuf:"varint,5,opt,name=Height,proto3" json:"Height,omitempty"` + Pagination *Pagination `protobuf:"bytes,6,opt,name=Pagination,proto3" json:"Pagination,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetAccountDatasetsRequest) Reset() { *m = GetAccountDatasetsRequest{} } +func (m *GetAccountDatasetsRequest) String() string { return proto.CompactTextString(m) } +func (*GetAccountDatasetsRequest) ProtoMessage() {} +func (*GetAccountDatasetsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8f6e88b2db5bd817, []int{1} +} + +func (m *GetAccountDatasetsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetAccountDatasetsRequest.Unmarshal(m, b) +} +func (m *GetAccountDatasetsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetAccountDatasetsRequest.Marshal(b, m, deterministic) +} +func (m *GetAccountDatasetsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetAccountDatasetsRequest.Merge(m, src) +} +func (m *GetAccountDatasetsRequest) XXX_Size() int { + return xxx_messageInfo_GetAccountDatasetsRequest.Size(m) +} +func (m *GetAccountDatasetsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetAccountDatasetsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetAccountDatasetsRequest proto.InternalMessageInfo + +func (m *GetAccountDatasetsRequest) GetProperty() string { + if m != nil { + return m.Property + } + return "" +} + +func (m *GetAccountDatasetsRequest) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *GetAccountDatasetsRequest) GetRecipientAccountAddress() string { + if m != nil { + return m.RecipientAccountAddress + } + return "" +} + +func (m *GetAccountDatasetsRequest) GetSetterAccountAddress() string { + if m != nil { + return m.SetterAccountAddress + } + return "" +} + +func (m *GetAccountDatasetsRequest) GetHeight() uint32 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *GetAccountDatasetsRequest) GetPagination() *Pagination { + if m != nil { + return m.Pagination + } + return nil +} + +type GetAccountDatasetsResponse struct { + Total uint64 `protobuf:"varint,1,opt,name=Total,proto3" json:"Total,omitempty"` + AccountDatasets []*AccountDataset `protobuf:"bytes,2,rep,name=AccountDatasets,proto3" json:"AccountDatasets,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetAccountDatasetsResponse) Reset() { *m = GetAccountDatasetsResponse{} } +func (m *GetAccountDatasetsResponse) String() string { return proto.CompactTextString(m) } +func (*GetAccountDatasetsResponse) ProtoMessage() {} +func (*GetAccountDatasetsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8f6e88b2db5bd817, []int{2} +} + +func (m *GetAccountDatasetsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetAccountDatasetsResponse.Unmarshal(m, b) +} +func (m *GetAccountDatasetsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetAccountDatasetsResponse.Marshal(b, m, deterministic) +} +func (m *GetAccountDatasetsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetAccountDatasetsResponse.Merge(m, src) +} +func (m *GetAccountDatasetsResponse) XXX_Size() int { + return xxx_messageInfo_GetAccountDatasetsResponse.Size(m) +} +func (m *GetAccountDatasetsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetAccountDatasetsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetAccountDatasetsResponse proto.InternalMessageInfo + +func (m *GetAccountDatasetsResponse) GetTotal() uint64 { + if m != nil { + return m.Total + } + return 0 +} + +func (m *GetAccountDatasetsResponse) GetAccountDatasets() []*AccountDataset { + if m != nil { + return m.AccountDatasets + } + return nil +} + +type GetAccountDatasetRequest struct { + Property string `protobuf:"bytes,1,opt,name=Property,proto3" json:"Property,omitempty"` + RecipientAccountAddress string `protobuf:"bytes,2,opt,name=RecipientAccountAddress,proto3" json:"RecipientAccountAddress,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetAccountDatasetRequest) Reset() { *m = GetAccountDatasetRequest{} } +func (m *GetAccountDatasetRequest) String() string { return proto.CompactTextString(m) } +func (*GetAccountDatasetRequest) ProtoMessage() {} +func (*GetAccountDatasetRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8f6e88b2db5bd817, []int{3} +} + +func (m *GetAccountDatasetRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetAccountDatasetRequest.Unmarshal(m, b) +} +func (m *GetAccountDatasetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetAccountDatasetRequest.Marshal(b, m, deterministic) +} +func (m *GetAccountDatasetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetAccountDatasetRequest.Merge(m, src) +} +func (m *GetAccountDatasetRequest) XXX_Size() int { + return xxx_messageInfo_GetAccountDatasetRequest.Size(m) +} +func (m *GetAccountDatasetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetAccountDatasetRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetAccountDatasetRequest proto.InternalMessageInfo + +func (m *GetAccountDatasetRequest) GetProperty() string { + if m != nil { + return m.Property + } + return "" +} + +func (m *GetAccountDatasetRequest) GetRecipientAccountAddress() string { + if m != nil { + return m.RecipientAccountAddress + } + return "" +} + +func init() { + proto.RegisterEnum("model.AccountDatasetProperty", AccountDatasetProperty_name, AccountDatasetProperty_value) + proto.RegisterType((*AccountDataset)(nil), "model.AccountDataset") + proto.RegisterType((*GetAccountDatasetsRequest)(nil), "model.GetAccountDatasetsRequest") + proto.RegisterType((*GetAccountDatasetsResponse)(nil), "model.GetAccountDatasetsResponse") + proto.RegisterType((*GetAccountDatasetRequest)(nil), "model.GetAccountDatasetRequest") +} + +func init() { proto.RegisterFile("model/accountDataset.proto", fileDescriptor_8f6e88b2db5bd817) } + +var fileDescriptor_8f6e88b2db5bd817 = []byte{ + // 420 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0xc5, 0x4e, 0x1c, 0xc2, 0x54, 0xd0, 0xb2, 0x2a, 0x61, 0x89, 0x38, 0x58, 0x39, 0x59, 0x91, + 0x48, 0x20, 0x5c, 0x10, 0x17, 0x94, 0x8a, 0x0a, 0x0e, 0x1c, 0xaa, 0x6d, 0xc5, 0x81, 0xdb, 0x66, + 0x33, 0x4a, 0x57, 0x8a, 0x3d, 0xcb, 0xee, 0x84, 0x02, 0x1f, 0xc0, 0x27, 0xf1, 0x7d, 0x88, 0x75, + 0x94, 0xd6, 0x69, 0x13, 0x21, 0x2e, 0x96, 0xe6, 0xbd, 0x37, 0x1e, 0xbd, 0x37, 0xb3, 0xd0, 0x2f, + 0x69, 0x8e, 0xcb, 0xb1, 0x36, 0x86, 0x56, 0x15, 0xbf, 0xd7, 0xac, 0x03, 0xf2, 0xc8, 0x79, 0x62, + 0x12, 0x59, 0xe4, 0xfa, 0xbd, 0x5a, 0xe2, 0xf4, 0xc2, 0x56, 0x9a, 0x2d, 0x55, 0x35, 0x3d, 0xf8, + 0x9d, 0xc2, 0xa3, 0x69, 0xa3, 0x4f, 0x4c, 0xe0, 0xf8, 0x1c, 0x99, 0xd1, 0xaf, 0xf1, 0xe9, 0x7c, + 0xee, 0x31, 0x04, 0x99, 0xe4, 0x49, 0xf1, 0x40, 0xdd, 0xc9, 0x89, 0x37, 0xf0, 0x54, 0xa1, 0xb1, + 0xce, 0x62, 0xc5, 0x5b, 0x6d, 0x69, 0x6c, 0xdb, 0x45, 0x8b, 0x3e, 0x74, 0xcf, 0x3c, 0x39, 0xf4, + 0xfc, 0x43, 0xb6, 0xa2, 0x74, 0x53, 0x8b, 0x63, 0xc8, 0x3e, 0xeb, 0xe5, 0x0a, 0x65, 0x3b, 0x12, + 0x75, 0x21, 0x0a, 0x38, 0xbc, 0xb0, 0x25, 0x06, 0xd6, 0xa5, 0x3b, 0x67, 0xed, 0x39, 0xc8, 0x2c, + 0x4f, 0x8a, 0xb6, 0xda, 0x86, 0xc5, 0x10, 0x8e, 0x36, 0xd0, 0xe9, 0x77, 0x67, 0x3d, 0x06, 0xd9, + 0x89, 0xd2, 0x5b, 0xb8, 0xe8, 0x41, 0xe7, 0x23, 0xda, 0xc5, 0x25, 0xcb, 0xfb, 0x79, 0x52, 0x3c, + 0x54, 0xeb, 0xea, 0x2f, 0xfe, 0x49, 0x33, 0x06, 0x96, 0xdd, 0x3c, 0x29, 0xba, 0x6a, 0x5d, 0x0d, + 0x7e, 0xa5, 0xf0, 0xec, 0x03, 0x72, 0x33, 0xbb, 0xa0, 0xf0, 0xeb, 0x0a, 0x03, 0x37, 0x5c, 0x25, + 0xbb, 0x5c, 0xa5, 0x37, 0x5d, 0xed, 0x49, 0xb0, 0xb5, 0x3f, 0xc1, 0x5d, 0xfb, 0x6a, 0xef, 0xd9, + 0xd7, 0xb5, 0xdb, 0xac, 0xe1, 0xf6, 0x15, 0xc0, 0xd9, 0xe6, 0x44, 0x62, 0x56, 0x07, 0x93, 0xc7, + 0xa3, 0x78, 0x3b, 0xa3, 0x6b, 0x42, 0xdd, 0x10, 0x0d, 0xae, 0xa0, 0x7f, 0x57, 0x0e, 0xc1, 0x51, + 0x15, 0x50, 0x48, 0xc8, 0x2e, 0x88, 0xf5, 0x32, 0xa6, 0xd0, 0x3e, 0x49, 0x5f, 0x26, 0xaa, 0x06, + 0xc4, 0x3b, 0x38, 0xdc, 0x6a, 0x92, 0x69, 0xde, 0x2a, 0x0e, 0x26, 0x4f, 0xd6, 0xf3, 0x9a, 0xac, + 0xda, 0x56, 0x0f, 0x1c, 0xc8, 0x5b, 0x83, 0xff, 0x25, 0xff, 0xff, 0xbe, 0xd5, 0xe1, 0x5b, 0xe8, + 0x35, 0xc7, 0x6d, 0xfe, 0x99, 0xc3, 0xf3, 0x26, 0x73, 0x1a, 0x8c, 0xa7, 0xab, 0xa9, 0x73, 0x9e, + 0xbe, 0xe9, 0xe5, 0xd1, 0xbd, 0x93, 0xe1, 0x97, 0x62, 0x61, 0xf9, 0x72, 0x35, 0x1b, 0x19, 0x2a, + 0xc7, 0x3f, 0x89, 0x66, 0xa6, 0xfe, 0xbe, 0x30, 0xe4, 0x71, 0x6c, 0xa8, 0x2c, 0xa9, 0x1a, 0x47, + 0xe7, 0xb3, 0x4e, 0x7c, 0x9b, 0xaf, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x49, 0x66, 0xf8, + 0xd8, 0x03, 0x00, 0x00, +} diff --git a/common/model/accountDatasets.pb.go b/common/model/accountDatasets.pb.go deleted file mode 100644 index ca90a9cd2..000000000 --- a/common/model/accountDatasets.pb.go +++ /dev/null @@ -1,168 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: model/accountDatasets.proto - -package model - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -type AccountDatasetProperty int32 - -const ( - AccountDatasetProperty_AccountDatasetEscrowApproval AccountDatasetProperty = 0 -) - -var AccountDatasetProperty_name = map[int32]string{ - 0: "AccountDatasetEscrowApproval", -} - -var AccountDatasetProperty_value = map[string]int32{ - "AccountDatasetEscrowApproval": 0, -} - -func (x AccountDatasetProperty) String() string { - return proto.EnumName(AccountDatasetProperty_name, int32(x)) -} - -func (AccountDatasetProperty) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_3f0cb489242a465d, []int{0} -} - -// AccountDataset represent the account dataset structure stored in the database -type AccountDataset struct { - SetterAccountAddress string `protobuf:"bytes,1,opt,name=SetterAccountAddress,proto3" json:"SetterAccountAddress,omitempty"` - RecipientAccountAddress string `protobuf:"bytes,2,opt,name=RecipientAccountAddress,proto3" json:"RecipientAccountAddress,omitempty"` - Property string `protobuf:"bytes,3,opt,name=Property,proto3" json:"Property,omitempty"` - Value string `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"` - TimestampStarts uint64 `protobuf:"varint,5,opt,name=TimestampStarts,proto3" json:"TimestampStarts,omitempty"` - TimestampExpires uint64 `protobuf:"varint,6,opt,name=TimestampExpires,proto3" json:"TimestampExpires,omitempty"` - Height uint32 `protobuf:"varint,7,opt,name=Height,proto3" json:"Height,omitempty"` - Latest bool `protobuf:"varint,8,opt,name=Latest,proto3" json:"Latest,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AccountDataset) Reset() { *m = AccountDataset{} } -func (m *AccountDataset) String() string { return proto.CompactTextString(m) } -func (*AccountDataset) ProtoMessage() {} -func (*AccountDataset) Descriptor() ([]byte, []int) { - return fileDescriptor_3f0cb489242a465d, []int{0} -} - -func (m *AccountDataset) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AccountDataset.Unmarshal(m, b) -} -func (m *AccountDataset) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AccountDataset.Marshal(b, m, deterministic) -} -func (m *AccountDataset) XXX_Merge(src proto.Message) { - xxx_messageInfo_AccountDataset.Merge(m, src) -} -func (m *AccountDataset) XXX_Size() int { - return xxx_messageInfo_AccountDataset.Size(m) -} -func (m *AccountDataset) XXX_DiscardUnknown() { - xxx_messageInfo_AccountDataset.DiscardUnknown(m) -} - -var xxx_messageInfo_AccountDataset proto.InternalMessageInfo - -func (m *AccountDataset) GetSetterAccountAddress() string { - if m != nil { - return m.SetterAccountAddress - } - return "" -} - -func (m *AccountDataset) GetRecipientAccountAddress() string { - if m != nil { - return m.RecipientAccountAddress - } - return "" -} - -func (m *AccountDataset) GetProperty() string { - if m != nil { - return m.Property - } - return "" -} - -func (m *AccountDataset) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -func (m *AccountDataset) GetTimestampStarts() uint64 { - if m != nil { - return m.TimestampStarts - } - return 0 -} - -func (m *AccountDataset) GetTimestampExpires() uint64 { - if m != nil { - return m.TimestampExpires - } - return 0 -} - -func (m *AccountDataset) GetHeight() uint32 { - if m != nil { - return m.Height - } - return 0 -} - -func (m *AccountDataset) GetLatest() bool { - if m != nil { - return m.Latest - } - return false -} - -func init() { - proto.RegisterEnum("model.AccountDatasetProperty", AccountDatasetProperty_name, AccountDatasetProperty_value) - proto.RegisterType((*AccountDataset)(nil), "model.AccountDataset") -} - -func init() { proto.RegisterFile("model/accountDatasets.proto", fileDescriptor_3f0cb489242a465d) } - -var fileDescriptor_3f0cb489242a465d = []byte{ - // 286 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0x03, 0x31, - 0x10, 0x86, 0xdd, 0xda, 0xd6, 0x1a, 0x50, 0x4b, 0x28, 0x35, 0xa8, 0x87, 0xc5, 0x53, 0x28, 0xd8, - 0x05, 0xbd, 0x88, 0xb7, 0x8a, 0x05, 0x0f, 0x1e, 0x64, 0x2b, 0x1e, 0xbc, 0xa5, 0xe9, 0xd0, 0x06, - 0x9a, 0x9d, 0x90, 0xcc, 0xfa, 0xf5, 0xc3, 0xfc, 0x7d, 0x62, 0xba, 0x2c, 0x6c, 0xd5, 0x4b, 0xe0, - 0x7d, 0x9e, 0x77, 0x20, 0xcc, 0xb0, 0x53, 0x8b, 0x0b, 0x58, 0x67, 0x4a, 0x6b, 0x2c, 0x0b, 0xba, - 0x53, 0xa4, 0x02, 0x50, 0x18, 0x3b, 0x8f, 0x84, 0xbc, 0x13, 0xe5, 0xf9, 0x57, 0x8b, 0x1d, 0x4e, - 0x1a, 0x05, 0x7e, 0xc9, 0x06, 0x33, 0x20, 0x02, 0x5f, 0xf1, 0xc9, 0x62, 0xe1, 0x21, 0x04, 0x91, - 0xa4, 0x89, 0xdc, 0xcf, 0xff, 0x74, 0xfc, 0x9a, 0x1d, 0xe7, 0xa0, 0x8d, 0x33, 0x50, 0xd0, 0xd6, - 0x58, 0x2b, 0x8e, 0xfd, 0xa7, 0xf9, 0x09, 0xeb, 0x3d, 0x7a, 0x74, 0xe0, 0xe9, 0x43, 0xec, 0xc6, - 0x6a, 0x9d, 0xf9, 0x80, 0x75, 0x9e, 0xd5, 0xba, 0x04, 0xd1, 0x8e, 0x62, 0x13, 0xb8, 0x64, 0x47, - 0x4f, 0xc6, 0x42, 0x20, 0x65, 0xdd, 0x8c, 0x94, 0xa7, 0x20, 0x3a, 0x69, 0x22, 0xdb, 0xf9, 0x36, - 0xe6, 0x23, 0xd6, 0xaf, 0xd1, 0xf4, 0xdd, 0x19, 0x0f, 0x41, 0x74, 0x63, 0xf5, 0x17, 0xe7, 0x43, - 0xd6, 0xbd, 0x07, 0xb3, 0x5c, 0x91, 0xd8, 0x4b, 0x13, 0x79, 0x90, 0x57, 0xe9, 0x87, 0x3f, 0x28, - 0x82, 0x40, 0xa2, 0x97, 0x26, 0xb2, 0x97, 0x57, 0x69, 0x74, 0xc3, 0x86, 0xcd, 0xbd, 0xd5, 0xbf, - 0x4e, 0xd9, 0x59, 0xd3, 0x4c, 0x83, 0xf6, 0xf8, 0x36, 0x71, 0xce, 0xe3, 0xab, 0x5a, 0xf7, 0x77, - 0x6e, 0x47, 0x2f, 0x72, 0x69, 0x68, 0x55, 0xce, 0xc7, 0x1a, 0x6d, 0xf6, 0x89, 0x38, 0xd7, 0x9b, - 0xf7, 0x42, 0xa3, 0x87, 0x4c, 0xa3, 0xb5, 0x58, 0x64, 0xf1, 0x40, 0xf3, 0x6e, 0x3c, 0xd7, 0xd5, - 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x0e, 0x97, 0xee, 0xcd, 0x01, 0x00, 0x00, -} From bcc318c53e4a7ecbd4109231d866cbd69b3f36b5 Mon Sep 17 00:00:00 2001 From: astaphobia Date: Fri, 27 Mar 2020 08:00:31 +0800 Subject: [PATCH 3/7] account dataset grpc service list and single record --- api/api.go | 13 +- api/handler/accountDatasetHandler.go | 28 +++ api/handler/blockHandler.go | 6 +- api/service/accountDatasetService.go | 150 +++++++++++++ api/service/accountDatasetService_test.go | 249 ++++++++++++++++++++++ common/constant/api.go | 2 +- common/query/accountDatasetsQuery.go | 12 +- common/query/accountDatasetsQuery_test.go | 12 +- common/service/accountDataset.pb.go | 151 +++++++++++++ common/service/accountDataset.pb.gw.go | 157 ++++++++++++++ 10 files changed, 762 insertions(+), 18 deletions(-) create mode 100644 api/handler/accountDatasetHandler.go create mode 100644 api/service/accountDatasetService.go create mode 100644 api/service/accountDatasetService_test.go create mode 100644 common/service/accountDataset.pb.go create mode 100644 common/service/accountDataset.pb.gw.go diff --git a/api/api.go b/api/api.go index ee3329399..77c878de4 100644 --- a/api/api.go +++ b/api/api.go @@ -6,7 +6,7 @@ import ( "net" "net/http" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/runtime" log "github.com/sirupsen/logrus" "github.com/zoobc/zoobc-core/api/handler" @@ -56,7 +56,7 @@ func startGrpcServer( } grpcServer := grpc.NewServer( grpc.Creds(creds), - grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( + grpc.UnaryInterceptor(grpcMiddleware.ChainUnaryServer( interceptor.NewServerRateLimiterInterceptor(constant.MaxAPIRequestPerSecond), interceptor.NewServerInterceptor( logger, @@ -167,6 +167,14 @@ func startGrpcServer( )}) // Set GRPC handler for health check rpcService.RegisterHealthCheckServiceServer(grpcServer, &handler.HealthCheckHandler{}) + + // Set GRPC handler for account dataset + rpcService.RegisterAccountDatasetServiceServer(grpcServer, &handler.AccountDatasetHandler{ + Service: service.NewAccountDatasetService( + query.NewAccountDatasetsQuery(), + queryExecutor, + ), + }) // run grpc-gateway handler go func() { if err := grpcServer.Serve(serv); err != nil { @@ -243,5 +251,6 @@ func runProxy(apiPort, rpcPort int) error { _ = rpcService.RegisterEscrowTransactionServiceHandlerFromEndpoint(ctx, mux, fmt.Sprintf("localhost:%d", rpcPort), opts) _ = rpcService.RegisterMultisigServiceHandlerFromEndpoint(ctx, mux, fmt.Sprintf("localhost:%d", rpcPort), opts) _ = rpcService.RegisterHealthCheckServiceHandlerFromEndpoint(ctx, mux, fmt.Sprintf("localhost:%d", rpcPort), opts) + _ = rpcService.RegisterAccountDatasetServiceHandlerFromEndpoint(ctx, mux, fmt.Sprintf("localhost:%d", rpcPort), opts) return http.ListenAndServe(fmt.Sprintf(":%d", apiPort), mux) } diff --git a/api/handler/accountDatasetHandler.go b/api/handler/accountDatasetHandler.go new file mode 100644 index 000000000..e54692425 --- /dev/null +++ b/api/handler/accountDatasetHandler.go @@ -0,0 +1,28 @@ +package handler + +import ( + "context" + + "github.com/zoobc/zoobc-core/api/service" + "github.com/zoobc/zoobc-core/common/model" +) + +type AccountDatasetHandler struct { + Service service.AccountDatasetServiceInterface +} + +func (adh *AccountDatasetHandler) GetAccountDatasets( + _ context.Context, + request *model.GetAccountDatasetsRequest, +) (*model.GetAccountDatasetsResponse, error) { + + return adh.Service.GetAccountDatasets(request) +} + +func (adh *AccountDatasetHandler) GetAccountDataset( + _ context.Context, + request *model.GetAccountDatasetRequest, +) (*model.AccountDataset, error) { + + return adh.Service.GetAccountDataset(request) +} diff --git a/api/handler/blockHandler.go b/api/handler/blockHandler.go index ced11a48a..bd14bc3a1 100644 --- a/api/handler/blockHandler.go +++ b/api/handler/blockHandler.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/zoobc/zoobc-core/api/service" - "github.com/zoobc/zoobc-core/common/constant" "github.com/zoobc/zoobc-core/common/chaintype" + "github.com/zoobc/zoobc-core/common/constant" "github.com/zoobc/zoobc-core/common/model" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -39,8 +39,8 @@ func (bs *BlockHandler) GetBlock(ctx context.Context, req *model.GetBlockRequest // GetBlocks handles request to get data of multiple blocks func (bs *BlockHandler) GetBlocks(ctx context.Context, req *model.GetBlocksRequest) (*model.GetBlocksResponse, error) { - if req.Limit > constant.MaxAPIGetBlocks { - return nil, status.Error(codes.OutOfRange, fmt.Sprintf("limit exceeded, max. %d", constant.MaxAPIGetBlocks)) + if req.Limit > constant.MaxAPILimitPerPage { + return nil, status.Error(codes.OutOfRange, fmt.Sprintf("limit exceeded, max. %d", constant.MaxAPILimitPerPage)) } chainType := chaintype.GetChainType(req.ChainType) diff --git a/api/service/accountDatasetService.go b/api/service/accountDatasetService.go new file mode 100644 index 000000000..1d5cd354d --- /dev/null +++ b/api/service/accountDatasetService.go @@ -0,0 +1,150 @@ +package service + +import ( + "database/sql" + + "github.com/zoobc/zoobc-core/common/constant" + "github.com/zoobc/zoobc-core/common/model" + "github.com/zoobc/zoobc-core/common/query" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type ( + // AccountDatasetServiceInterface a methods collection for AccountDataset + AccountDatasetServiceInterface interface { + GetAccountDatasets(request *model.GetAccountDatasetsRequest) (*model.GetAccountDatasetsResponse, error) + GetAccountDataset(request *model.GetAccountDatasetRequest) (*model.AccountDataset, error) + } + // AccountDatasetService contain fields that needed for AccountDatasetServiceInterface + AccountDatasetService struct { + AccountDatasetQuery *query.AccountDatasetsQuery + QueryExecutor query.ExecutorInterface + } +) + +func NewAccountDatasetService( + accountDatasetQuery *query.AccountDatasetsQuery, + queryExecutor query.ExecutorInterface, +) AccountDatasetServiceInterface { + return &AccountDatasetService{ + AccountDatasetQuery: accountDatasetQuery, + QueryExecutor: queryExecutor, + } +} + +// GetAccountDatasets a method service that use for GetAccountDatasets Handler +func (ads *AccountDatasetService) GetAccountDatasets( + request *model.GetAccountDatasetsRequest, +) (*model.GetAccountDatasetsResponse, error) { + var ( + accDatasets []*model.AccountDataset + rowCount *sql.Row + caseQ = query.NewCaseQuery() + count uint64 + rows *sql.Rows + err error + ) + + caseQ.Select(ads.AccountDatasetQuery.TableName, ads.AccountDatasetQuery.GetFields()...) + if request.GetProperty() != "" { + caseQ.Where(caseQ.Equal("property", request.GetProperty())) + } + if request.GetValue() != "" { + caseQ.Where(caseQ.Equal("value", request.GetValue())) + } + if request.GetRecipientAccountAddress() != "" { + caseQ.Where(caseQ.Equal("recipient_account_address", request.GetRecipientAccountAddress())) + } + if request.GetSetterAccountAddress() != "" { + caseQ.Where(caseQ.Equal("setter_account_address", request.GetSetterAccountAddress())) + } + if request.GetHeight() > 0 { + caseQ.Where(caseQ.Equal("height", request.GetHeight())) + } + caseQ.And(caseQ.Equal("latest", true)) + + countQ, _ := caseQ.Build() + rowCount, _ = ads.QueryExecutor.ExecuteSelectRow(countQ, false) + if err = rowCount.Scan(&count); err != nil { + if err != sql.ErrNoRows { + return nil, status.Error(codes.Internal, "There is something wrong") + } + + return nil, status.Error(codes.NotFound, "Record not found") + } + + pagination := request.GetPagination() + if pagination == nil { + pagination = &model.Pagination{ + OrderField: "height", + OrderBy: model.OrderBy_ASC, + Page: 0, + Limit: constant.MaxAPILimitPerPage, + } + } + if pagination.GetLimit() > constant.MaxAPILimitPerPage { + return nil, status.Errorf(codes.OutOfRange, "Limit exceeded, max. %d", constant.MaxAPILimitPerPage) + } + + if pagination.GetOrderField() != "" { + caseQ.OrderBy(pagination.GetOrderField(), pagination.GetOrderBy()) + } else { + caseQ.OrderBy("height", pagination.GetOrderBy()) + } + caseQ.Paginate(pagination.GetLimit(), pagination.GetPage()) + + selectQ, args := caseQ.Build() + rows, err = ads.QueryExecutor.ExecuteSelect(selectQ, false, args...) + if err != nil { + return nil, status.Error(codes.Internal, "There something wrong") + } + defer rows.Close() + + accDatasets, err = ads.AccountDatasetQuery.BuildModel([]*model.AccountDataset{}, rows) + if err != nil { + return nil, status.Error(codes.Internal, "There something wrong") + } + + return &model.GetAccountDatasetsResponse{ + Total: count, + AccountDatasets: accDatasets, + }, nil +} + +func (ads *AccountDatasetService) GetAccountDataset( + request *model.GetAccountDatasetRequest, +) (*model.AccountDataset, error) { + var ( + err error + accDataset model.AccountDataset + row *sql.Row + caseQ = query.NewCaseQuery() + ) + + if request.GetRecipientAccountAddress() == "" && request.GetProperty() == "" { + return nil, status.Error(codes.InvalidArgument, "Request must have Property or RecipientAccountAddress") + } + + caseQ.Select(ads.AccountDatasetQuery.TableName, ads.AccountDatasetQuery.GetFields()...) + if request.GetProperty() != "" { + caseQ.Where(caseQ.Equal("property", request.GetProperty())) + } + if request.GetRecipientAccountAddress() != "" { + caseQ.Where(caseQ.Equal("recipient_account_address", request.GetRecipientAccountAddress())) + } + caseQ.And(caseQ.Equal("latest", 1)) + + selectQ, args := caseQ.Build() + row, _ = ads.QueryExecutor.ExecuteSelectRow(selectQ, false, args...) + err = ads.AccountDatasetQuery.Scan(&accDataset, row) + if err != nil { + if err != sql.ErrNoRows { + return nil, status.Error(codes.Internal, "There is something wrong") + } + + return nil, status.Error(codes.NotFound, "Record not found") + } + + return &accDataset, nil +} diff --git a/api/service/accountDatasetService_test.go b/api/service/accountDatasetService_test.go new file mode 100644 index 000000000..4082e3656 --- /dev/null +++ b/api/service/accountDatasetService_test.go @@ -0,0 +1,249 @@ +package service + +import ( + "database/sql" + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/zoobc/zoobc-core/common/model" + "github.com/zoobc/zoobc-core/common/query" +) + +type ( + mockGetAccountDatasetsExecutor struct { + query.ExecutorInterface + } +) + +func (*mockGetAccountDatasetsExecutor) ExecuteSelectRow(string, bool, ...interface{}) (*sql.Row, error) { + db, mock, _ := sqlmock.New() + mock.ExpectQuery("").WillReturnRows(sqlmock.NewRows([]string{"total"}).AddRow(1)) + return db.QueryRow(""), nil +} +func (*mockGetAccountDatasetsExecutor) ExecuteSelect(string, bool, ...interface{}) (*sql.Rows, error) { + db, mock, _ := sqlmock.New() + defer db.Close() + + mockRows := mock.NewRows(query.NewAccountDatasetsQuery().GetFields()) + mockRows.AddRow( + "BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgtN", + "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE", + "AccountDatasetEscrowApproval", + 5, + "Message", + 1565942932686, + 1565943056129, + true, + ) + mock.ExpectQuery("").WillReturnRows(mockRows) + + return db.Query("") +} + +func TestAccountDatasetService_GetAccountDatasets(t *testing.T) { + type fields struct { + AccountDatasetQuery *query.AccountDatasetsQuery + QueryExecutor query.ExecutorInterface + } + type args struct { + request *model.GetAccountDatasetsRequest + } + tests := []struct { + name string + fields fields + args args + want *model.GetAccountDatasetsResponse + wantErr bool + }{ + { + name: "wantError:LimitExceeded", + fields: fields{ + AccountDatasetQuery: query.NewAccountDatasetsQuery(), + QueryExecutor: &mockGetAccountDatasetsExecutor{}, + }, + args: args{ + request: &model.GetAccountDatasetsRequest{ + Property: "", + Value: "", + RecipientAccountAddress: "", + SetterAccountAddress: "", + Height: 0, + Pagination: &model.Pagination{ + OrderField: "", + OrderBy: 0, + Page: 0, + Limit: 5001, + }, + }, + }, + wantErr: true, + }, + { + name: "wantSuccess", + fields: fields{ + AccountDatasetQuery: query.NewAccountDatasetsQuery(), + QueryExecutor: &mockGetAccountDatasetsExecutor{}, + }, + args: args{ + request: &model.GetAccountDatasetsRequest{ + Property: "AccountDatasetEscrowApproval", + Value: "Message", + RecipientAccountAddress: "BCZAbcasdljasd_123876123", + SetterAccountAddress: "", + Height: 0, + Pagination: &model.Pagination{ + OrderField: "height", + OrderBy: model.OrderBy_ASC, + Page: 0, + Limit: 500, + }, + }, + }, + want: &model.GetAccountDatasetsResponse{ + Total: 1, + AccountDatasets: []*model.AccountDataset{ + { + SetterAccountAddress: "BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgtN", + RecipientAccountAddress: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE", + Property: "AccountDatasetEscrowApproval", + Value: "Message", + TimestampStarts: 1565942932686, + TimestampExpires: 1565943056129, + Height: 5, + Latest: true, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ads := &AccountDatasetService{ + AccountDatasetQuery: tt.fields.AccountDatasetQuery, + QueryExecutor: tt.fields.QueryExecutor, + } + got, err := ads.GetAccountDatasets(tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("GetAccountDatasets() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAccountDatasets() got = %v, want %v", got, tt.want) + } + }) + } +} + +type ( + mockExecutorGetAccountDataset struct { + query.ExecutorInterface + } + mockExecutorGetAccountDatasetErr struct { + query.ExecutorInterface + } +) + +func (*mockExecutorGetAccountDataset) ExecuteSelectRow(string, bool, ...interface{}) (*sql.Row, error) { + db, mock, _ := sqlmock.New() + defer db.Close() + + mockRow := mock.NewRows(query.NewAccountDatasetsQuery().GetFields()) + mockRow.AddRow( + "BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgtN", + "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE", + "AccountDatasetEscrowApproval", + 5, + "Message", + 1565942932686, + 1565943056129, + true, + ) + mock.ExpectQuery("").WillReturnRows(mockRow) + return db.QueryRow(""), nil +} +func (*mockExecutorGetAccountDatasetErr) ExecuteSelectRow(string, bool, ...interface{}) (*sql.Row, error) { + db, mock, _ := sqlmock.New() + defer db.Close() + + mockRow := mock.NewRows(query.NewAccountDatasetsQuery().GetFields()) + mock.ExpectQuery("").WillReturnRows(mockRow) + return db.QueryRow(""), nil +} + +func TestAccountDatasetService_GetAccountDataset(t *testing.T) { + type fields struct { + AccountDatasetQuery *query.AccountDatasetsQuery + QueryExecutor query.ExecutorInterface + } + type args struct { + request *model.GetAccountDatasetRequest + } + tests := []struct { + name string + fields fields + args args + want *model.AccountDataset + wantErr bool + }{ + { + name: "wantError:InvalidArgs", + fields: fields{ + AccountDatasetQuery: query.NewAccountDatasetsQuery(), + QueryExecutor: &mockExecutorGetAccountDataset{}, + }, + wantErr: true, + }, + { + name: "wantError:NoRows", + fields: fields{ + AccountDatasetQuery: query.NewAccountDatasetsQuery(), + QueryExecutor: &mockExecutorGetAccountDatasetErr{}, + }, + args: args{ + request: &model.GetAccountDatasetRequest{ + Property: "AccountDatasetEscrowApproval", + }, + }, + wantErr: true, + }, + { + name: "wantSuccess", + fields: fields{ + AccountDatasetQuery: query.NewAccountDatasetsQuery(), + QueryExecutor: &mockExecutorGetAccountDataset{}, + }, + args: args{ + request: &model.GetAccountDatasetRequest{ + Property: "AccountDatasetEscrowApproval", + }, + }, + want: &model.AccountDataset{ + SetterAccountAddress: "BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgtN", + RecipientAccountAddress: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE", + Property: "AccountDatasetEscrowApproval", + Value: "Message", + TimestampStarts: 1565942932686, + TimestampExpires: 1565943056129, + Height: 5, + Latest: true, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ads := &AccountDatasetService{ + AccountDatasetQuery: tt.fields.AccountDatasetQuery, + QueryExecutor: tt.fields.QueryExecutor, + } + got, err := ads.GetAccountDataset(tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("GetAccountDataset() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAccountDataset() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/common/constant/api.go b/common/constant/api.go index 8ededaa5a..3525c4b8c 100644 --- a/common/constant/api.go +++ b/common/constant/api.go @@ -2,5 +2,5 @@ package constant var ( MaxAPIRequestPerSecond uint32 = 10 - MaxAPIGetBlocks uint32 = 500 + MaxAPILimitPerPage uint32 = 500 ) diff --git a/common/query/accountDatasetsQuery.go b/common/query/accountDatasetsQuery.go index a1d731291..7ebce86ef 100644 --- a/common/query/accountDatasetsQuery.go +++ b/common/query/accountDatasetsQuery.go @@ -80,16 +80,16 @@ func (adq *AccountDatasetsQuery) AddDataset(dataset *model.AccountDataset) [][]i // Update Dataset will happen when new dataset already exist in highest height updateDataset := fmt.Sprintf(` - UPDATE %s SET (%s) = + UPDATE %s SET (%s) = ( - SELECT '%s', %d, - %d + CASE + SELECT '%s', %d, + %d + CASE WHEN timestamp_expires - %d < 0 THEN 0 - ELSE timestamp_expires - %d END - FROM %s + ELSE timestamp_expires - %d END + FROM %s WHERE %s AND latest = true ORDER BY height DESC LIMIT 1 - ) + ) WHERE %s AND latest = true `, adq.TableName, diff --git a/common/query/accountDatasetsQuery_test.go b/common/query/accountDatasetsQuery_test.go index a66a3b07d..026ae6b6a 100644 --- a/common/query/accountDatasetsQuery_test.go +++ b/common/query/accountDatasetsQuery_test.go @@ -160,16 +160,16 @@ func TestAccountDatasetsQuery_AddDataset(t *testing.T) { dataset: mockDataset, }, want: append(want, append([]interface{}{fmt.Sprintf(` - UPDATE %s SET (%s) = + UPDATE %s SET (%s) = ( - SELECT '%s', %d, - %d + CASE + SELECT '%s', %d, + %d + CASE WHEN timestamp_expires - %d < 0 THEN 0 - ELSE timestamp_expires - %d END - FROM %s + ELSE timestamp_expires - %d END + FROM %s WHERE %s AND latest = true ORDER BY height DESC LIMIT 1 - ) + ) WHERE %s AND latest = true `, mockDatasetQuery.TableName, diff --git a/common/service/accountDataset.pb.go b/common/service/accountDataset.pb.go new file mode 100644 index 000000000..9974c63d3 --- /dev/null +++ b/common/service/accountDataset.pb.go @@ -0,0 +1,151 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: service/accountDataset.proto + +package service + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + model "github.com/zoobc/zoobc-core/common/model" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("service/accountDataset.proto", fileDescriptor_2e05ba97ba46e9e1) } + +var fileDescriptor_2e05ba97ba46e9e1 = []byte{ + // 229 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x29, 0x4e, 0x2d, 0x2a, + 0xcb, 0x4c, 0x4e, 0xd5, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x71, 0x49, 0x2c, 0x49, 0x2c, + 0x4e, 0x2d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0xca, 0x4a, 0x49, 0xe5, 0xe6, + 0xa7, 0xa4, 0xe6, 0x60, 0x55, 0x24, 0x25, 0x93, 0x9e, 0x9f, 0x9f, 0x9e, 0x93, 0xaa, 0x9f, 0x58, + 0x90, 0xa9, 0x9f, 0x98, 0x97, 0x97, 0x5f, 0x92, 0x58, 0x92, 0x99, 0x9f, 0x57, 0x0c, 0x91, 0x35, + 0x9a, 0xcb, 0xc4, 0x25, 0xea, 0x88, 0xa2, 0x2d, 0x18, 0x62, 0xa6, 0x50, 0x07, 0x23, 0x97, 0x90, + 0x7b, 0x6a, 0x09, 0xaa, 0x64, 0xb1, 0x90, 0x82, 0x1e, 0xd8, 0x2e, 0x3d, 0x4c, 0xa9, 0xa0, 0xd4, + 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x29, 0x45, 0x3c, 0x2a, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x95, + 0x74, 0x9b, 0x2e, 0x3f, 0x99, 0xcc, 0xa4, 0x2e, 0xa4, 0xaa, 0x5f, 0x66, 0x88, 0xe6, 0x6a, 0x7d, + 0x2c, 0x76, 0x56, 0x72, 0x09, 0x62, 0x88, 0x0a, 0xc9, 0xe3, 0xb2, 0x06, 0xe6, 0x0e, 0x51, 0xa8, + 0x02, 0x54, 0x59, 0x25, 0x1d, 0xb0, 0xdd, 0x6a, 0x42, 0x2a, 0xc4, 0xd8, 0xed, 0xa4, 0x13, 0xa5, + 0x95, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x5f, 0x95, 0x9f, 0x9f, 0x94, + 0x0c, 0x21, 0x75, 0x93, 0xf3, 0x8b, 0x52, 0xf5, 0x93, 0xf3, 0x73, 0x73, 0xf3, 0xf3, 0xf4, 0xa1, + 0xf1, 0x90, 0xc4, 0x06, 0x0e, 0x54, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x22, 0x08, + 0x37, 0xb7, 0x01, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// AccountDatasetServiceClient is the client API for AccountDatasetService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type AccountDatasetServiceClient interface { + GetAccountDatasets(ctx context.Context, in *model.GetAccountDatasetsRequest, opts ...grpc.CallOption) (*model.GetAccountDatasetsResponse, error) + GetAccountDataset(ctx context.Context, in *model.GetAccountDatasetRequest, opts ...grpc.CallOption) (*model.AccountDataset, error) +} + +type accountDatasetServiceClient struct { + cc *grpc.ClientConn +} + +func NewAccountDatasetServiceClient(cc *grpc.ClientConn) AccountDatasetServiceClient { + return &accountDatasetServiceClient{cc} +} + +func (c *accountDatasetServiceClient) GetAccountDatasets(ctx context.Context, in *model.GetAccountDatasetsRequest, opts ...grpc.CallOption) (*model.GetAccountDatasetsResponse, error) { + out := new(model.GetAccountDatasetsResponse) + err := c.cc.Invoke(ctx, "/service.AccountDatasetService/GetAccountDatasets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accountDatasetServiceClient) GetAccountDataset(ctx context.Context, in *model.GetAccountDatasetRequest, opts ...grpc.CallOption) (*model.AccountDataset, error) { + out := new(model.AccountDataset) + err := c.cc.Invoke(ctx, "/service.AccountDatasetService/GetAccountDataset", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AccountDatasetServiceServer is the server API for AccountDatasetService service. +type AccountDatasetServiceServer interface { + GetAccountDatasets(context.Context, *model.GetAccountDatasetsRequest) (*model.GetAccountDatasetsResponse, error) + GetAccountDataset(context.Context, *model.GetAccountDatasetRequest) (*model.AccountDataset, error) +} + +func RegisterAccountDatasetServiceServer(s *grpc.Server, srv AccountDatasetServiceServer) { + s.RegisterService(&_AccountDatasetService_serviceDesc, srv) +} + +func _AccountDatasetService_GetAccountDatasets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(model.GetAccountDatasetsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccountDatasetServiceServer).GetAccountDatasets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/service.AccountDatasetService/GetAccountDatasets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccountDatasetServiceServer).GetAccountDatasets(ctx, req.(*model.GetAccountDatasetsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccountDatasetService_GetAccountDataset_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(model.GetAccountDatasetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccountDatasetServiceServer).GetAccountDataset(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/service.AccountDatasetService/GetAccountDataset", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccountDatasetServiceServer).GetAccountDataset(ctx, req.(*model.GetAccountDatasetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _AccountDatasetService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "service.AccountDatasetService", + HandlerType: (*AccountDatasetServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAccountDatasets", + Handler: _AccountDatasetService_GetAccountDatasets_Handler, + }, + { + MethodName: "GetAccountDataset", + Handler: _AccountDatasetService_GetAccountDataset_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service/accountDataset.proto", +} diff --git a/common/service/accountDataset.pb.gw.go b/common/service/accountDataset.pb.gw.go new file mode 100644 index 000000000..8501887eb --- /dev/null +++ b/common/service/accountDataset.pb.gw.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: service/accountDataset.proto + +/* +Package service is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package service + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "github.com/zoobc/zoobc-core/common/model" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray + +var ( + filter_AccountDatasetService_GetAccountDatasets_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_AccountDatasetService_GetAccountDatasets_0(ctx context.Context, marshaler runtime.Marshaler, client AccountDatasetServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq model.GetAccountDatasetsRequest + var metadata runtime.ServerMetadata + + if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_AccountDatasetService_GetAccountDatasets_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetAccountDatasets(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +var ( + filter_AccountDatasetService_GetAccountDataset_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_AccountDatasetService_GetAccountDataset_0(ctx context.Context, marshaler runtime.Marshaler, client AccountDatasetServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq model.GetAccountDatasetRequest + var metadata runtime.ServerMetadata + + if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_AccountDatasetService_GetAccountDataset_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetAccountDataset(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +// RegisterAccountDatasetServiceHandlerFromEndpoint is same as RegisterAccountDatasetServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAccountDatasetServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAccountDatasetServiceHandler(ctx, mux, conn) +} + +// RegisterAccountDatasetServiceHandler registers the http handlers for service AccountDatasetService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAccountDatasetServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterAccountDatasetServiceHandlerClient(ctx, mux, NewAccountDatasetServiceClient(conn)) +} + +// RegisterAccountDatasetServiceHandlerClient registers the http handlers for service AccountDatasetService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AccountDatasetServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AccountDatasetServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "AccountDatasetServiceClient" to call the correct interceptors. +func RegisterAccountDatasetServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AccountDatasetServiceClient) error { + + mux.Handle("GET", pattern_AccountDatasetService_GetAccountDatasets_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AccountDatasetService_GetAccountDatasets_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_AccountDatasetService_GetAccountDatasets_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AccountDatasetService_GetAccountDataset_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AccountDatasetService_GetAccountDataset_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_AccountDatasetService_GetAccountDataset_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_AccountDatasetService_GetAccountDatasets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accountDataset", "GetAccountDatasets"}, "")) + + pattern_AccountDatasetService_GetAccountDataset_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accountDataset", "GetAccountDataset"}, "")) +) + +var ( + forward_AccountDatasetService_GetAccountDatasets_0 = runtime.ForwardResponseMessage + + forward_AccountDatasetService_GetAccountDataset_0 = runtime.ForwardResponseMessage +) From 2c5f40445e9344e096ae89a42ec49e3f2462cf8f Mon Sep 17 00:00:00 2001 From: astaphobia Date: Fri, 27 Mar 2020 23:49:39 +0800 Subject: [PATCH 4/7] grpc client example --- api/client/GetAccountDataset/main.go | 38 ++++++++++++++++++++++ api/client/GetAccountDatasets/main.go | 39 +++++++++++++++++++++++ api/service/accountDatasetService.go | 10 +++--- cmd/transaction/cmd.go | 6 ++++ common/transaction/setupAccountDataset.go | 7 ++++ 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 api/client/GetAccountDataset/main.go create mode 100644 api/client/GetAccountDatasets/main.go diff --git a/api/client/GetAccountDataset/main.go b/api/client/GetAccountDataset/main.go new file mode 100644 index 000000000..94ed23db3 --- /dev/null +++ b/api/client/GetAccountDataset/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "context" + "fmt" + "log" + + "github.com/sirupsen/logrus" + "github.com/spf13/viper" + "github.com/zoobc/zoobc-core/common/model" + rpcService "github.com/zoobc/zoobc-core/common/service" + "github.com/zoobc/zoobc-core/common/util" + "google.golang.org/grpc" +) + +func main() { + var apiRPCPort int + if err := util.LoadConfig("../../../resource", "config", "toml"); err != nil { + logrus.Fatal(err) + } else { + apiRPCPort = viper.GetInt("apiRPCPort") + } + + conn, err := grpc.Dial(fmt.Sprintf(":%d", apiRPCPort), grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %s", err) + } + defer conn.Close() + + c := rpcService.NewAccountDatasetServiceClient(conn) + response, err := c.GetAccountDataset(context.Background(), &model.GetAccountDatasetRequest{ + RecipientAccountAddress: "H1ftvv3n6CF5NDzdjmZKLRrBg6yPKHXpmatVUhQ5NWYx", + }) + if err != nil { + log.Fatalf("error calling grpc GetAccountDatasets: %s", err.Error()) + } + log.Printf("response from remote rpc_service.GetTransactions(): %s", response) +} diff --git a/api/client/GetAccountDatasets/main.go b/api/client/GetAccountDatasets/main.go new file mode 100644 index 000000000..59d06f178 --- /dev/null +++ b/api/client/GetAccountDatasets/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "context" + "fmt" + "log" + + "github.com/sirupsen/logrus" + "github.com/spf13/viper" + "github.com/zoobc/zoobc-core/common/model" + rpcService "github.com/zoobc/zoobc-core/common/service" + "github.com/zoobc/zoobc-core/common/util" + "google.golang.org/grpc" +) + +func main() { + var apiRPCPort int + if err := util.LoadConfig("../../../resource", "config", "toml"); err != nil { + logrus.Fatal(err) + } else { + apiRPCPort = viper.GetInt("apiRPCPort") + } + + conn, err := grpc.Dial(fmt.Sprintf(":%d", apiRPCPort), grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %s", err) + } + defer conn.Close() + + c := rpcService.NewAccountDatasetServiceClient(conn) + response, err := c.GetAccountDatasets(context.Background(), &model.GetAccountDatasetsRequest{ + SetterAccountAddress: "HlZLh3VcnNlvByWoAzXOQ2jAlwFOiyO9_njI3oq5Ygha", + RecipientAccountAddress: "H1ftvv3n6CF5NDzdjmZKLRrBg6yPKHXpmatVUhQ5NWYx", + }) + if err != nil { + log.Fatalf("error calling grpc GetAccountDatasets: %s", err.Error()) + } + log.Printf("response from remote rpc_service.GetTransactions(): %s", response) +} diff --git a/api/service/accountDatasetService.go b/api/service/accountDatasetService.go index 1d5cd354d..2de42d852 100644 --- a/api/service/accountDatasetService.go +++ b/api/service/accountDatasetService.go @@ -64,11 +64,11 @@ func (ads *AccountDatasetService) GetAccountDatasets( } caseQ.And(caseQ.Equal("latest", true)) - countQ, _ := caseQ.Build() - rowCount, _ = ads.QueryExecutor.ExecuteSelectRow(countQ, false) + countQ, countArgs := caseQ.Build() + rowCount, _ = ads.QueryExecutor.ExecuteSelectRow(query.GetTotalRecordOfSelect(countQ), false, countArgs...) if err = rowCount.Scan(&count); err != nil { if err != sql.ErrNoRows { - return nil, status.Error(codes.Internal, "There is something wrong") + return nil, status.Error(codes.Internal, "Something wrong happened") } return nil, status.Error(codes.NotFound, "Record not found") @@ -97,13 +97,13 @@ func (ads *AccountDatasetService) GetAccountDatasets( selectQ, args := caseQ.Build() rows, err = ads.QueryExecutor.ExecuteSelect(selectQ, false, args...) if err != nil { - return nil, status.Error(codes.Internal, "There something wrong") + return nil, status.Error(codes.Internal, err.Error()) } defer rows.Close() accDatasets, err = ads.AccountDatasetQuery.BuildModel([]*model.AccountDataset{}, rows) if err != nil { - return nil, status.Error(codes.Internal, "There something wrong") + return nil, status.Error(codes.Internal, "Something wrong happened") } return &model.GetAccountDatasetsResponse{ diff --git a/cmd/transaction/cmd.go b/cmd/transaction/cmd.go index 2de8ce670..4508da367 100644 --- a/cmd/transaction/cmd.go +++ b/cmd/transaction/cmd.go @@ -348,6 +348,12 @@ func (*TXGeneratorCommands) SetupAccountDatasetProcess() RunCommand { recipientAccountAddress, ) + // Recipient required while property set as AccountDatasetEscrowApproval + _, ok := model.AccountDatasetProperty_value[property] + if ok && recipientAccountAddress == "" { + println("--recipient is required while property as AccountDatasetEscrowApproval") + return + } tx = GenerateTxSetupAccountDataset(tx, senderAccountAddress, recipientAccountAddress, property, value, activeTime) if escrow { tx = GenerateEscrowedTransaction(tx) diff --git a/common/transaction/setupAccountDataset.go b/common/transaction/setupAccountDataset.go index 437e1fed8..81f4794ab 100644 --- a/common/transaction/setupAccountDataset.go +++ b/common/transaction/setupAccountDataset.go @@ -146,6 +146,13 @@ func (tx *SetupAccountDataset) Validate(dbTx bool) error { if tx.Body.GetMuchTime() == 0 { return blocker.NewBlocker(blocker.ValidationErr, "SetupAccountDataset, starts time is not allowed same with expiration time") } + + // Recipient required while property set as AccountDatasetEscrowApproval + _, ok := model.AccountDatasetProperty_value[tx.Body.GetProperty()] + if ok && tx.Body.GetRecipientAccountAddress() == "" { + return blocker.NewBlocker(blocker.ValidationErr, "RecipientRequired") + } + // check account balance sender qry, args := tx.AccountBalanceQuery.GetAccountBalanceByAccountAddress(tx.SenderAddress) row, err := tx.QueryExecutor.ExecuteSelectRow(qry, dbTx, args...) From e150817f95417136999fbd6789fdbfff833f4e63 Mon Sep 17 00:00:00 2001 From: astaphobia Date: Mon, 30 Mar 2020 09:00:13 +0800 Subject: [PATCH 5/7] move params checkup to handler package --- api/handler/accountDatasetHandler.go | 20 ++++++++++++++++++++ api/service/accountDatasetService.go | 17 ----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/api/handler/accountDatasetHandler.go b/api/handler/accountDatasetHandler.go index e54692425..040d06750 100644 --- a/api/handler/accountDatasetHandler.go +++ b/api/handler/accountDatasetHandler.go @@ -4,7 +4,10 @@ import ( "context" "github.com/zoobc/zoobc-core/api/service" + "github.com/zoobc/zoobc-core/common/constant" "github.com/zoobc/zoobc-core/common/model" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type AccountDatasetHandler struct { @@ -16,6 +19,19 @@ func (adh *AccountDatasetHandler) GetAccountDatasets( request *model.GetAccountDatasetsRequest, ) (*model.GetAccountDatasetsResponse, error) { + pagination := request.GetPagination() + if pagination == nil { + pagination = &model.Pagination{ + OrderField: "height", + OrderBy: model.OrderBy_ASC, + Page: 0, + Limit: constant.MaxAPILimitPerPage, + } + } + if pagination.GetLimit() > constant.MaxAPILimitPerPage { + return nil, status.Errorf(codes.OutOfRange, "Limit exceeded, max. %d", constant.MaxAPILimitPerPage) + } + return adh.Service.GetAccountDatasets(request) } @@ -24,5 +40,9 @@ func (adh *AccountDatasetHandler) GetAccountDataset( request *model.GetAccountDatasetRequest, ) (*model.AccountDataset, error) { + if request.GetRecipientAccountAddress() == "" && request.GetProperty() == "" { + return nil, status.Error(codes.InvalidArgument, "Request must have Property or RecipientAccountAddress") + } + return adh.Service.GetAccountDataset(request) } diff --git a/api/service/accountDatasetService.go b/api/service/accountDatasetService.go index 2de42d852..9cdd18f9f 100644 --- a/api/service/accountDatasetService.go +++ b/api/service/accountDatasetService.go @@ -3,7 +3,6 @@ package service import ( "database/sql" - "github.com/zoobc/zoobc-core/common/constant" "github.com/zoobc/zoobc-core/common/model" "github.com/zoobc/zoobc-core/common/query" "google.golang.org/grpc/codes" @@ -75,18 +74,6 @@ func (ads *AccountDatasetService) GetAccountDatasets( } pagination := request.GetPagination() - if pagination == nil { - pagination = &model.Pagination{ - OrderField: "height", - OrderBy: model.OrderBy_ASC, - Page: 0, - Limit: constant.MaxAPILimitPerPage, - } - } - if pagination.GetLimit() > constant.MaxAPILimitPerPage { - return nil, status.Errorf(codes.OutOfRange, "Limit exceeded, max. %d", constant.MaxAPILimitPerPage) - } - if pagination.GetOrderField() != "" { caseQ.OrderBy(pagination.GetOrderField(), pagination.GetOrderBy()) } else { @@ -122,10 +109,6 @@ func (ads *AccountDatasetService) GetAccountDataset( caseQ = query.NewCaseQuery() ) - if request.GetRecipientAccountAddress() == "" && request.GetProperty() == "" { - return nil, status.Error(codes.InvalidArgument, "Request must have Property or RecipientAccountAddress") - } - caseQ.Select(ads.AccountDatasetQuery.TableName, ads.AccountDatasetQuery.GetFields()...) if request.GetProperty() != "" { caseQ.Where(caseQ.Equal("property", request.GetProperty())) From a487081a67a6809bbe759c834c32552a0472cbec Mon Sep 17 00:00:00 2001 From: astaphobia Date: Mon, 30 Mar 2020 09:08:31 +0800 Subject: [PATCH 6/7] remove unnecessary test cases --- api/service/accountDatasetService_test.go | 31 ----------------------- 1 file changed, 31 deletions(-) diff --git a/api/service/accountDatasetService_test.go b/api/service/accountDatasetService_test.go index 4082e3656..406d22c0e 100644 --- a/api/service/accountDatasetService_test.go +++ b/api/service/accountDatasetService_test.go @@ -56,29 +56,6 @@ func TestAccountDatasetService_GetAccountDatasets(t *testing.T) { want *model.GetAccountDatasetsResponse wantErr bool }{ - { - name: "wantError:LimitExceeded", - fields: fields{ - AccountDatasetQuery: query.NewAccountDatasetsQuery(), - QueryExecutor: &mockGetAccountDatasetsExecutor{}, - }, - args: args{ - request: &model.GetAccountDatasetsRequest{ - Property: "", - Value: "", - RecipientAccountAddress: "", - SetterAccountAddress: "", - Height: 0, - Pagination: &model.Pagination{ - OrderField: "", - OrderBy: 0, - Page: 0, - Limit: 5001, - }, - }, - }, - wantErr: true, - }, { name: "wantSuccess", fields: fields{ @@ -186,14 +163,6 @@ func TestAccountDatasetService_GetAccountDataset(t *testing.T) { want *model.AccountDataset wantErr bool }{ - { - name: "wantError:InvalidArgs", - fields: fields{ - AccountDatasetQuery: query.NewAccountDatasetsQuery(), - QueryExecutor: &mockExecutorGetAccountDataset{}, - }, - wantErr: true, - }, { name: "wantError:NoRows", fields: fields{ From 2f242a4e868439f078af7be8395ce1e65832ed3c Mon Sep 17 00:00:00 2001 From: astaphobia Date: Mon, 30 Mar 2020 10:04:40 +0800 Subject: [PATCH 7/7] technical error message passed --- api/service/accountDatasetService.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/service/accountDatasetService.go b/api/service/accountDatasetService.go index 9cdd18f9f..e5f0f4e59 100644 --- a/api/service/accountDatasetService.go +++ b/api/service/accountDatasetService.go @@ -67,7 +67,7 @@ func (ads *AccountDatasetService) GetAccountDatasets( rowCount, _ = ads.QueryExecutor.ExecuteSelectRow(query.GetTotalRecordOfSelect(countQ), false, countArgs...) if err = rowCount.Scan(&count); err != nil { if err != sql.ErrNoRows { - return nil, status.Error(codes.Internal, "Something wrong happened") + return nil, status.Error(codes.Internal, err.Error()) } return nil, status.Error(codes.NotFound, "Record not found") @@ -90,7 +90,7 @@ func (ads *AccountDatasetService) GetAccountDatasets( accDatasets, err = ads.AccountDatasetQuery.BuildModel([]*model.AccountDataset{}, rows) if err != nil { - return nil, status.Error(codes.Internal, "Something wrong happened") + return nil, status.Error(codes.Internal, err.Error()) } return &model.GetAccountDatasetsResponse{ @@ -123,7 +123,7 @@ func (ads *AccountDatasetService) GetAccountDataset( err = ads.AccountDatasetQuery.Scan(&accDataset, row) if err != nil { if err != sql.ErrNoRows { - return nil, status.Error(codes.Internal, "There is something wrong") + return nil, status.Error(codes.Internal, err.Error()) } return nil, status.Error(codes.NotFound, "Record not found")