diff --git a/Makefile b/Makefile index 7663925..63324cd 100644 --- a/Makefile +++ b/Makefile @@ -32,5 +32,6 @@ unit-tests: @cd blockfetcher && go test -v integration-tests: + @cd tests/chaincode/fabcar/go && GOPROXY="https://goproxy.io" GOSUMDB=off go mod vendor @cd client/ && go test -v @cd ./rest && go test -v \ No newline at end of file diff --git a/client/example/client.go b/client/example/client.go index ebf1346..f041c16 100644 --- a/client/example/client.go +++ b/client/example/client.go @@ -20,7 +20,6 @@ import ( "fmt" fabcli "github.com/hyperledger-labs/fabex/client" "github.com/hyperledger-labs/fabex/helpers" - pb "github.com/hyperledger-labs/fabex/proto" "log" ) @@ -41,10 +40,11 @@ func main() { Use this commented lines for your experiments! */ - //txs, err := client.Explore(1, 15) + //txs, err := client.GetRange(1, 15) //txs, err := client.Get(&pb.Entry{Txid:"3a3e933a3d9953b0b10e6573254b6d3cf2347d72058c0347a55054babdd8e1a1"}) //txs, err := client.Get(&pb.Entry{Payload: "WriteSet"}) - txs, err := client.Get(&pb.Entry{Blocknum: 5}) + //txs, err := client.Get(&pb.Entry{Blocknum: 5}) + txs, err := client.Get(nil) if err != nil { log.Fatal(err) } diff --git a/client/fabex_client.go b/client/fabex_client.go index 0246955..54359f4 100644 --- a/client/fabex_client.go +++ b/client/fabex_client.go @@ -24,6 +24,7 @@ import ( "google.golang.org/grpc" "io" "net" + "reflect" ) type FabexClient struct { @@ -40,9 +41,9 @@ func New(addr, port string) (*FabexClient, error) { return &FabexClient{pb.NewFabexClient(conn)}, nil } -func (fabexCli *FabexClient) Explore(startblock, endblock int) ([]db.Tx, error) { +func (fabexCli *FabexClient) GetRange(startblock, endblock int) ([]db.Tx, error) { - stream, err := fabexCli.Client.Explore(context.Background(), &pb.RequestRange{Startblock: int64(startblock), Endblock: int64(endblock)}) + stream, err := fabexCli.Client.GetRange(context.Background(), &pb.RequestRange{Startblock: int64(startblock), Endblock: int64(endblock)}) if err != nil { return nil, err } @@ -62,7 +63,14 @@ func (fabexCli *FabexClient) Explore(startblock, endblock int) ([]db.Tx, error) } func (fabexCli *FabexClient) Get(filter *pb.Entry) ([]db.Tx, error) { - + checknull := &pb.Entry{} + checknull.Blocknum = 0 + if reflect.DeepEqual(filter, checknull) { + return nil, errors.New("requests for blocks with a number less than 1 are not allowed") + } + if filter == nil { + filter = &pb.Entry{} + } stream, err := fabexCli.Client.Get(context.Background(), filter) if err != nil { return nil, err diff --git a/client/fabex_client_test.go b/client/fabex_client_test.go index b4f90ff..b5f740a 100644 --- a/client/fabex_client_test.go +++ b/client/fabex_client_test.go @@ -111,12 +111,12 @@ func TestNew(t *testing.T) { } } -func TestExplore(t *testing.T) { +func TestGetRange(t *testing.T) { fabcli, err := New("localhost", "6000") if err != nil { t.Errorf(err.Error()) } - txs, err := fabcli.Explore(0, 3) + txs, err := fabcli.GetRange(0, 3) if err != nil { t.Errorf(err.Error()) } @@ -150,4 +150,10 @@ func TestGet(t *testing.T) { } assert.Greater(t, len(txs), 0, "No transactions found") + txs, err = fabcli.Get(nil) + if err != nil { + t.Errorf(err.Error()) + } + assert.Greater(t, len(txs), 0, "No transactions found") + } diff --git a/fabex.go b/fabex.go index 6516725..19cf63a 100644 --- a/fabex.go +++ b/fabex.go @@ -218,18 +218,18 @@ func NewFabexServer(addr string, port string, conf *models.Fabex) *FabexServer { return &FabexServer{addr, port, conf} } -func (s *FabexServer) Explore(req *pb.RequestRange, stream pb.Fabex_ExploreServer) error { +func (s *FabexServer) GetRange(req *pb.RequestRange, stream pb.Fabex_GetRangeServer) error { // set blocks counter to latest saved in db block number value blockCounter := req.Startblock // insert missing blocks/txs into db for blockCounter <= req.Endblock { - customBlock, err := blockfetcher.GetBlock(s.Conf.LedgerClient, uint64(blockCounter)) + QueryResults, err := s.Conf.Db.GetByBlocknum(uint64(blockCounter)) if err != nil { - return errors.Wrap(err, "GetBlock error") + return errors.Wrapf(err, "failed to get txs by block number %d", blockCounter) } - if customBlock != nil { - for _, queryResult := range customBlock.Txs { + if QueryResults != nil { + for _, queryResult := range QueryResults { stream.Send(&pb.Entry{Channelid: queryResult.ChannelId, Txid: queryResult.Txid, Hash: queryResult.Hash, Previoushash: queryResult.PreviousHash, Blocknum: queryResult.Blocknum, Payload: queryResult.Payload, Time: queryResult.Time}) } } @@ -240,6 +240,7 @@ func (s *FabexServer) Explore(req *pb.RequestRange, stream pb.Fabex_ExploreServe } func (s *FabexServer) Get(req *pb.Entry, stream pb.Fabex_GetServer) error { + switch { case req.Txid != "": QueryResults, err := s.Conf.Db.GetByTxId(req.Txid) @@ -268,6 +269,25 @@ func (s *FabexServer) Get(req *pb.Entry, stream pb.Fabex_GetServer) error { for _, queryResult := range QueryResults { stream.Send(&pb.Entry{Channelid: queryResult.ChannelId, Txid: queryResult.Txid, Hash: queryResult.Hash, Previoushash: queryResult.PreviousHash, Blocknum: queryResult.Blocknum, Payload: queryResult.Payload, Time: queryResult.Time}) } + default: + // set blocks counter to latest saved in db block number value + blockCounter := 1 + + // insert missing blocks/txs into db + for { + queryResults, err := s.Conf.Db.GetByBlocknum(uint64(blockCounter)) + if err != nil { + return errors.Wrapf(err, "failed to get txs by block number %d", blockCounter) + } + if queryResults == nil { + break + } + for _, queryResult := range queryResults { + stream.Send(&pb.Entry{Channelid: queryResult.ChannelId, Txid: queryResult.Txid, Hash: queryResult.Hash, Previoushash: queryResult.PreviousHash, Blocknum: queryResult.Blocknum, Payload: queryResult.Payload, Time: queryResult.Time}) + } + + blockCounter++ + } } return nil diff --git a/proto/fabex.pb.go b/proto/fabex.pb.go index 7d5785d..8001a99 100644 --- a/proto/fabex.pb.go +++ b/proto/fabex.pb.go @@ -166,25 +166,25 @@ func init() { func init() { proto.RegisterFile("fabex.proto", fileDescriptor_d7d7206373264ff4) } var fileDescriptor_d7d7206373264ff4 = []byte{ - // 284 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x91, 0xc1, 0x4e, 0xf3, 0x30, - 0x0c, 0xc7, 0xd5, 0x6f, 0xeb, 0xf6, 0xcd, 0xec, 0x64, 0x2e, 0xd1, 0x84, 0xd0, 0x34, 0x0e, 0x8c, - 0x03, 0x2d, 0x82, 0x37, 0x40, 0x1a, 0x48, 0x1c, 0x73, 0x44, 0x5c, 0xd2, 0xd6, 0xb4, 0x15, 0x69, - 0x52, 0xd2, 0x14, 0xb5, 0xcf, 0xc6, 0xcb, 0xa1, 0xba, 0x30, 0x36, 0x4e, 0xf1, 0xff, 0xf7, 0xb7, - 0x13, 0xdb, 0x81, 0x93, 0x57, 0x95, 0x50, 0x17, 0xd5, 0xce, 0x7a, 0x8b, 0x21, 0x8b, 0xcd, 0x13, - 0x2c, 0x25, 0xbd, 0xb7, 0xd4, 0x78, 0xa9, 0x4c, 0x4e, 0x78, 0x0e, 0xd0, 0x78, 0xe5, 0x7c, 0xa2, - 0x6d, 0xfa, 0x26, 0x82, 0x75, 0xb0, 0x9d, 0xc8, 0x03, 0x82, 0x2b, 0xf8, 0x4f, 0x26, 0x1b, 0xdd, - 0x7f, 0xec, 0xee, 0xf5, 0xe6, 0x33, 0x80, 0x70, 0x67, 0xbc, 0xeb, 0xf1, 0x0c, 0x16, 0x69, 0xa1, - 0x8c, 0x21, 0x5d, 0x66, 0x7c, 0xc9, 0x42, 0xfe, 0x02, 0x44, 0x98, 0xfa, 0xae, 0xcc, 0xb8, 0x7e, - 0x21, 0x39, 0x1e, 0x58, 0xa1, 0x9a, 0x42, 0x4c, 0x46, 0x36, 0xc4, 0xb8, 0x81, 0x65, 0xed, 0xe8, - 0xa3, 0xb4, 0x6d, 0xc3, 0xde, 0x94, 0xbd, 0x23, 0x36, 0xf4, 0xc3, 0x8f, 0x9b, 0xb6, 0x12, 0xe1, - 0x3a, 0xd8, 0x4e, 0xe5, 0x5e, 0xa3, 0x80, 0x79, 0xad, 0x7a, 0x6d, 0x55, 0x26, 0x66, 0x5c, 0xfa, - 0x23, 0xb9, 0x83, 0xb2, 0x22, 0x31, 0xe7, 0x09, 0x38, 0xbe, 0x7d, 0x81, 0xf0, 0x61, 0x58, 0x09, - 0x46, 0x30, 0xdf, 0x75, 0xb5, 0xb6, 0x8e, 0xf0, 0x34, 0x1a, 0x57, 0x76, 0xb8, 0xa2, 0xd5, 0xf2, - 0x1b, 0xf2, 0xa8, 0x37, 0x01, 0x5e, 0xc0, 0xe4, 0x91, 0x3c, 0x1e, 0xe1, 0xbf, 0x49, 0xf7, 0x57, - 0xcf, 0x97, 0x79, 0xe9, 0x8b, 0x36, 0x89, 0x52, 0x5b, 0xc5, 0x45, 0x5f, 0x93, 0xd3, 0x94, 0xe5, - 0xe4, 0xae, 0xb5, 0x4a, 0x9a, 0x98, 0x93, 0x63, 0xfe, 0x99, 0x64, 0xc6, 0xc7, 0xdd, 0x57, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x67, 0xd8, 0xef, 0xfe, 0xaf, 0x01, 0x00, 0x00, + // 279 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x51, 0xcd, 0x4e, 0x83, 0x40, + 0x10, 0x0e, 0x02, 0x6d, 0x19, 0x39, 0xad, 0x97, 0x4d, 0x63, 0x4c, 0x83, 0x07, 0xeb, 0x41, 0x30, + 0xfa, 0x06, 0x26, 0xda, 0xc4, 0xe3, 0x1e, 0x4d, 0x3c, 0x2c, 0x30, 0x02, 0x11, 0x76, 0x71, 0x59, + 0x4c, 0x79, 0x36, 0x5f, 0xce, 0x30, 0xd4, 0xda, 0xf6, 0xc4, 0xf7, 0xc3, 0xb7, 0x3b, 0xf3, 0x2d, + 0x9c, 0x7f, 0xc8, 0x14, 0xb7, 0x71, 0x6b, 0xb4, 0xd5, 0xcc, 0x27, 0x12, 0xbd, 0x42, 0x28, 0xf0, + 0xab, 0xc7, 0xce, 0x0a, 0xa9, 0x0a, 0x64, 0x57, 0x00, 0x9d, 0x95, 0xc6, 0xa6, 0xb5, 0xce, 0x3e, + 0xb9, 0xb3, 0x72, 0xd6, 0xae, 0x38, 0x50, 0xd8, 0x12, 0x16, 0xa8, 0xf2, 0xc9, 0x3d, 0x23, 0x77, + 0xcf, 0xa3, 0x1f, 0x07, 0xfc, 0x67, 0x65, 0xcd, 0xc0, 0x2e, 0x21, 0xc8, 0x4a, 0xa9, 0x14, 0xd6, + 0x55, 0x4e, 0x87, 0x04, 0xe2, 0x5f, 0x60, 0x0c, 0x3c, 0xbb, 0xad, 0x72, 0xca, 0x07, 0x82, 0xf0, + 0xa8, 0x95, 0xb2, 0x2b, 0xb9, 0x3b, 0x69, 0x23, 0x66, 0x11, 0x84, 0xad, 0xc1, 0xef, 0x4a, 0xf7, + 0x1d, 0x79, 0x1e, 0x79, 0x47, 0xda, 0x38, 0x0f, 0x5d, 0xae, 0xfa, 0x86, 0xfb, 0x2b, 0x67, 0xed, + 0x89, 0x3d, 0x67, 0x1c, 0xe6, 0xad, 0x1c, 0x6a, 0x2d, 0x73, 0x3e, 0xa3, 0xe8, 0x1f, 0xa5, 0x09, + 0xaa, 0x06, 0xf9, 0x9c, 0x36, 0x20, 0xfc, 0xf0, 0x0e, 0xfe, 0xcb, 0x58, 0x09, 0xbb, 0x06, 0x77, + 0x83, 0x96, 0x85, 0xf1, 0x54, 0x17, 0x6d, 0xb4, 0x3c, 0x62, 0xf7, 0x0e, 0x4b, 0x60, 0xb1, 0xc1, + 0x5d, 0x67, 0x17, 0x3b, 0xef, 0xb0, 0xc8, 0xd3, 0xc0, 0xd3, 0xed, 0xdb, 0x4d, 0x51, 0xd9, 0xb2, + 0x4f, 0xe3, 0x4c, 0x37, 0x49, 0x39, 0xb4, 0x68, 0x6a, 0xcc, 0x0b, 0x34, 0x77, 0xb5, 0x4c, 0xbb, + 0x84, 0x7e, 0x4e, 0xe8, 0x69, 0xd2, 0x19, 0x7d, 0x1e, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x8b, + 0xe9, 0x02, 0x6f, 0xb0, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -199,8 +199,8 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type FabexClient interface { - Explore(ctx context.Context, in *RequestRange, opts ...grpc.CallOption) (Fabex_ExploreClient, error) Get(ctx context.Context, in *Entry, opts ...grpc.CallOption) (Fabex_GetClient, error) + GetRange(ctx context.Context, in *RequestRange, opts ...grpc.CallOption) (Fabex_GetRangeClient, error) } type fabexClient struct { @@ -211,12 +211,12 @@ func NewFabexClient(cc *grpc.ClientConn) FabexClient { return &fabexClient{cc} } -func (c *fabexClient) Explore(ctx context.Context, in *RequestRange, opts ...grpc.CallOption) (Fabex_ExploreClient, error) { - stream, err := c.cc.NewStream(ctx, &_Fabex_serviceDesc.Streams[0], "/fabex.Fabex/Explore", opts...) +func (c *fabexClient) Get(ctx context.Context, in *Entry, opts ...grpc.CallOption) (Fabex_GetClient, error) { + stream, err := c.cc.NewStream(ctx, &_Fabex_serviceDesc.Streams[0], "/fabex.Fabex/Get", opts...) if err != nil { return nil, err } - x := &fabexExploreClient{stream} + x := &fabexGetClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -226,16 +226,16 @@ func (c *fabexClient) Explore(ctx context.Context, in *RequestRange, opts ...grp return x, nil } -type Fabex_ExploreClient interface { +type Fabex_GetClient interface { Recv() (*Entry, error) grpc.ClientStream } -type fabexExploreClient struct { +type fabexGetClient struct { grpc.ClientStream } -func (x *fabexExploreClient) Recv() (*Entry, error) { +func (x *fabexGetClient) Recv() (*Entry, error) { m := new(Entry) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -243,12 +243,12 @@ func (x *fabexExploreClient) Recv() (*Entry, error) { return m, nil } -func (c *fabexClient) Get(ctx context.Context, in *Entry, opts ...grpc.CallOption) (Fabex_GetClient, error) { - stream, err := c.cc.NewStream(ctx, &_Fabex_serviceDesc.Streams[1], "/fabex.Fabex/Get", opts...) +func (c *fabexClient) GetRange(ctx context.Context, in *RequestRange, opts ...grpc.CallOption) (Fabex_GetRangeClient, error) { + stream, err := c.cc.NewStream(ctx, &_Fabex_serviceDesc.Streams[1], "/fabex.Fabex/GetRange", opts...) if err != nil { return nil, err } - x := &fabexGetClient{stream} + x := &fabexGetRangeClient{stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -258,16 +258,16 @@ func (c *fabexClient) Get(ctx context.Context, in *Entry, opts ...grpc.CallOptio return x, nil } -type Fabex_GetClient interface { +type Fabex_GetRangeClient interface { Recv() (*Entry, error) grpc.ClientStream } -type fabexGetClient struct { +type fabexGetRangeClient struct { grpc.ClientStream } -func (x *fabexGetClient) Recv() (*Entry, error) { +func (x *fabexGetRangeClient) Recv() (*Entry, error) { m := new(Entry) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -277,64 +277,64 @@ func (x *fabexGetClient) Recv() (*Entry, error) { // FabexServer is the server API for Fabex service. type FabexServer interface { - Explore(*RequestRange, Fabex_ExploreServer) error Get(*Entry, Fabex_GetServer) error + GetRange(*RequestRange, Fabex_GetRangeServer) error } // UnimplementedFabexServer can be embedded to have forward compatible implementations. type UnimplementedFabexServer struct { } -func (*UnimplementedFabexServer) Explore(req *RequestRange, srv Fabex_ExploreServer) error { - return status.Errorf(codes.Unimplemented, "method Explore not implemented") -} func (*UnimplementedFabexServer) Get(req *Entry, srv Fabex_GetServer) error { return status.Errorf(codes.Unimplemented, "method Get not implemented") } +func (*UnimplementedFabexServer) GetRange(req *RequestRange, srv Fabex_GetRangeServer) error { + return status.Errorf(codes.Unimplemented, "method GetRange not implemented") +} func RegisterFabexServer(s *grpc.Server, srv FabexServer) { s.RegisterService(&_Fabex_serviceDesc, srv) } -func _Fabex_Explore_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(RequestRange) +func _Fabex_Get_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(Entry) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(FabexServer).Explore(m, &fabexExploreServer{stream}) + return srv.(FabexServer).Get(m, &fabexGetServer{stream}) } -type Fabex_ExploreServer interface { +type Fabex_GetServer interface { Send(*Entry) error grpc.ServerStream } -type fabexExploreServer struct { +type fabexGetServer struct { grpc.ServerStream } -func (x *fabexExploreServer) Send(m *Entry) error { +func (x *fabexGetServer) Send(m *Entry) error { return x.ServerStream.SendMsg(m) } -func _Fabex_Get_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(Entry) +func _Fabex_GetRange_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(RequestRange) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(FabexServer).Get(m, &fabexGetServer{stream}) + return srv.(FabexServer).GetRange(m, &fabexGetRangeServer{stream}) } -type Fabex_GetServer interface { +type Fabex_GetRangeServer interface { Send(*Entry) error grpc.ServerStream } -type fabexGetServer struct { +type fabexGetRangeServer struct { grpc.ServerStream } -func (x *fabexGetServer) Send(m *Entry) error { +func (x *fabexGetRangeServer) Send(m *Entry) error { return x.ServerStream.SendMsg(m) } @@ -344,13 +344,13 @@ var _Fabex_serviceDesc = grpc.ServiceDesc{ Methods: []grpc.MethodDesc{}, Streams: []grpc.StreamDesc{ { - StreamName: "Explore", - Handler: _Fabex_Explore_Handler, + StreamName: "Get", + Handler: _Fabex_Get_Handler, ServerStreams: true, }, { - StreamName: "Get", - Handler: _Fabex_Get_Handler, + StreamName: "GetRange", + Handler: _Fabex_GetRange_Handler, ServerStreams: true, }, }, diff --git a/proto/fabex.proto b/proto/fabex.proto index 0e4e3ae..c3435ca 100644 --- a/proto/fabex.proto +++ b/proto/fabex.proto @@ -3,8 +3,8 @@ package fabex; option go_package = "github.com/hyperledger-labs/fabex/proto"; service Fabex { - rpc Explore(RequestRange) returns (stream Entry); rpc Get(Entry) returns (stream Entry); + rpc GetRange(RequestRange) returns (stream Entry); } message RequestRange { diff --git a/tests/chaincode/fabcar/go/go.mod b/tests/chaincode/fabcar/go/go.mod index a06d642..bac87cc 100644 --- a/tests/chaincode/fabcar/go/go.mod +++ b/tests/chaincode/fabcar/go/go.mod @@ -1,6 +1,6 @@ module fabcar -go 1.13 +go 1.14 require ( github.com/fsouza/go-dockerclient v1.6.5 // indirect