From 26e127e9df88d266d7ca4472823c56dccf948d4e Mon Sep 17 00:00:00 2001 From: Jim Zhang Date: Fri, 10 Jun 2022 10:58:52 -0400 Subject: [PATCH 1/2] Support isInit in the gateway client Signed-off-by: Jim Zhang --- go.mod | 2 ++ go.sum | 4 ++-- internal/fabric/client/client_gateway_clientside.go | 9 +++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 01e11e5..338b47d 100644 --- a/go.mod +++ b/go.mod @@ -51,3 +51,5 @@ require ( ) replace google.golang.org/grpc => google.golang.org/grpc v1.29.0 + +replace github.com/hyperledger/fabric-sdk-go => github.com/kaleido-io/fabric-sdk-go v1.0.1-0.20220610141558-4cdb9535ce4b diff --git a/go.sum b/go.sum index 8068cea..d36a164 100644 --- a/go.sum +++ b/go.sum @@ -386,8 +386,6 @@ github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDW github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20211118165945-23d738fc3553 h1:E9f0v1q4EDfrE+0LdkxVtdYKAZ7PGCaj1bBx45R9yEQ= github.com/hyperledger/fabric-protos-go v0.0.0-20211118165945-23d738fc3553/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220510182741-7a94fbc3efed h1:qV/VjdWRENbrUyxQPl19sCMz3PywjxnUWymq+lcqZwI= -github.com/hyperledger/fabric-sdk-go v1.0.1-0.20220510182741-7a94fbc3efed/go.mod h1:JRplpKBeAvXjsBhOCCM/KvMRUbdDyhsAh80qbXzKc10= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -431,6 +429,8 @@ github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSg github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kaleido-io/fabric-sdk-go v1.0.1-0.20220610141558-4cdb9535ce4b h1:PUn8zRTSokSIVOJaB7MaaylcetcvE+o4ms3AFFtc7gc= +github.com/kaleido-io/fabric-sdk-go v1.0.1-0.20220610141558-4cdb9535ce4b/go.mod h1:JRplpKBeAvXjsBhOCCM/KvMRUbdDyhsAh80qbXzKc10= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= diff --git a/internal/fabric/client/client_gateway_clientside.go b/internal/fabric/client/client_gateway_clientside.go index 4f728be..76b980c 100644 --- a/internal/fabric/client/client_gateway_clientside.go +++ b/internal/fabric/client/client_gateway_clientside.go @@ -73,7 +73,7 @@ func newRPCClientWithClientSideGateway(configProvider core.ConfigProvider, txTim func (w *gwRPCWrapper) Invoke(channelId, signer, chaincodeName, method string, args []string, isInit bool) (*TxReceipt, error) { log.Tracef("RPC [%s:%s:%s:isInit=%t] --> %+v", channelId, chaincodeName, method, isInit, args) - result, txStatus, err := w.sendTransaction(channelId, signer, chaincodeName, method, args, false) + result, txStatus, err := w.sendTransaction(channelId, signer, chaincodeName, method, args, isInit) if err != nil { log.Errorf("Failed to send transaction [%s:%s:%s:isInit=%t]. %s", channelId, chaincodeName, method, isInit, err) return nil, err @@ -158,7 +158,12 @@ func (w *gwRPCWrapper) sendTransaction(signer, channelId, chaincodeName, method return nil, nil, err } notifier := tx.RegisterCommitEvent() - result, err := tx.Submit(args...) + var result []byte + if isInit { + result, err = tx.SubmitInit(args...) + } else { + result, err = tx.Submit(args...) + } if err != nil { return nil, nil, err } From a6e7c9a54a8a62067a23f3ffe8df27a9c1332529 Mon Sep 17 00:00:00 2001 From: Jim Zhang Date: Fri, 10 Jun 2022 15:52:31 -0400 Subject: [PATCH 2/2] Add unit tests Signed-off-by: Jim Zhang --- .../client/client_gateway_clientside.go | 46 +++++++++--- internal/fabric/client/rpc_test.go | 70 +++++++++++++++++++ 2 files changed, 105 insertions(+), 11 deletions(-) diff --git a/internal/fabric/client/client_gateway_clientside.go b/internal/fabric/client/client_gateway_clientside.go index 76b980c..aee33d0 100644 --- a/internal/fabric/client/client_gateway_clientside.go +++ b/internal/fabric/client/client_gateway_clientside.go @@ -34,11 +34,16 @@ import ( // defined to allow mocking in tests type gatewayCreator func(core.ConfigProvider, string, int) (*gateway.Gateway, error) type networkCreator func(*gateway.Gateway, string) (*gateway.Network, error) +type txPreparer func(*gwRPCWrapper, string, string, string, string) (*gateway.Transaction, <-chan *fab.TxStatusEvent, error) +type txSubmitter func(*gateway.Transaction, ...string) ([]byte, error) type gwRPCWrapper struct { *commonRPCWrapper - gatewayCreator gatewayCreator - networkCreator networkCreator + gatewayCreator gatewayCreator + networkCreator networkCreator + txPreparer txPreparer + txSubmitter txSubmitter + txInitSubmitter txSubmitter // networkCreator networkC // one gateway client per signer gwClients map[string]*gateway.Gateway @@ -61,6 +66,9 @@ func newRPCClientWithClientSideGateway(configProvider core.ConfigProvider, txTim }, gatewayCreator: createGateway, networkCreator: getNetwork, + txPreparer: prepareTx, + txSubmitter: submitTx, + txInitSubmitter: submitInitTx, gwClients: make(map[string]*gateway.Gateway), gwGatewayClients: make(map[string]map[string]*gateway.Network), gwChannelClients: make(map[string]map[string]*channel.Client), @@ -148,21 +156,15 @@ func (w *gwRPCWrapper) Close() error { } func (w *gwRPCWrapper) sendTransaction(signer, channelId, chaincodeName, method string, args []string, isInit bool) ([]byte, *fab.TxStatusEvent, error) { - channelClient, err := w.getGatewayClient(signer, channelId) - if err != nil { - return nil, nil, err - } - contractClient := channelClient.GetContract(chaincodeName) - tx, err := contractClient.CreateTransaction(method) + tx, notifier, err := w.txPreparer(w, signer, channelId, chaincodeName, method) if err != nil { return nil, nil, err } - notifier := tx.RegisterCommitEvent() var result []byte if isInit { - result, err = tx.SubmitInit(args...) + result, err = w.txInitSubmitter(tx, args...) } else { - result, err = tx.Submit(args...) + result, err = w.txSubmitter(tx, args...) } if err != nil { return nil, nil, err @@ -246,3 +248,25 @@ func createGateway(configProvider core.ConfigProvider, signer string, txTimeout func getNetwork(gateway *gateway.Gateway, channelId string) (*gateway.Network, error) { return gateway.GetNetwork(channelId) } + +func prepareTx(w *gwRPCWrapper, signer, channelId, chaincodeName, method string) (*gateway.Transaction, <-chan *fab.TxStatusEvent, error) { + channelClient, err := w.getGatewayClient(signer, channelId) + if err != nil { + return nil, nil, err + } + contractClient := channelClient.GetContract(chaincodeName) + tx, err := contractClient.CreateTransaction(method) + if err != nil { + return nil, nil, err + } + notifier := tx.RegisterCommitEvent() + return tx, notifier, nil +} + +func submitTx(tx *gateway.Transaction, args ...string) ([]byte, error) { + return tx.Submit(args...) +} + +func submitInitTx(tx *gateway.Transaction, args ...string) ([]byte, error) { + return tx.SubmitInit(args...) +} diff --git a/internal/fabric/client/rpc_test.go b/internal/fabric/client/rpc_test.go index 84784e8..d9036be 100644 --- a/internal/fabric/client/rpc_test.go +++ b/internal/fabric/client/rpc_test.go @@ -32,6 +32,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/client/ledger" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/gateway" mspApi "github.com/hyperledger/fabric-sdk-go/pkg/msp/api" "github.com/hyperledger/firefly-fabconnect/internal/conf" @@ -134,6 +135,7 @@ func createMockChannelClient(channelProvider context.ChannelProvider) (*channel. } func createMockGateway(configProvider core.ConfigProvider, signer string, txTimeout int) (*gateway.Gateway, error) { + return &gateway.Gateway{}, nil } @@ -215,6 +217,74 @@ func TestGatewayClientInstantiation(t *testing.T) { assert.Empty(wrapper.gwGatewayClients["user1"]) } +func TestGatewayClientSendTx(t *testing.T) { + assert := assert.New(t) + + config := conf.RPCConf{ + UseGatewayClient: true, + ConfigPath: tmpShortCCPFile, + } + rpc, idclient, err := RPCConnect(config, 5) + assert.NoError(err) + assert.NotNil(rpc) + assert.NotNil(idclient) + + wrapper, ok := rpc.(*gwRPCWrapper) + assert.True(ok) + wrapper.gatewayCreator = createMockGateway + wrapper.networkCreator = createMockNetwork + + mockPrepareTx := func(w *gwRPCWrapper, signer, channelId, chaincodeName, method string) (*gateway.Transaction, <-chan *fab.TxStatusEvent, error) { + notifier := make(chan *fab.TxStatusEvent) + go func() { + notifier <- &fab.TxStatusEvent{} + }() + return nil, notifier, nil + } + mockSubmitTx := func(tx *gateway.Transaction, args ...string) ([]byte, error) { + return []byte(""), nil + } + wrapper.txPreparer = mockPrepareTx + wrapper.txSubmitter = mockSubmitTx + + _, _, err = wrapper.sendTransaction("signer1", "channel-1", "chaincode-1", "method-1", []string{"args-1"}, false) + assert.NoError(err) +} + +func TestGatewayClientSendInitTx(t *testing.T) { + assert := assert.New(t) + + config := conf.RPCConf{ + UseGatewayClient: true, + ConfigPath: tmpShortCCPFile, + } + rpc, idclient, err := RPCConnect(config, 5) + assert.NoError(err) + assert.NotNil(rpc) + assert.NotNil(idclient) + + wrapper, ok := rpc.(*gwRPCWrapper) + assert.True(ok) + wrapper.gatewayCreator = createMockGateway + wrapper.networkCreator = createMockNetwork + + mockPrepareTx := func(w *gwRPCWrapper, signer, channelId, chaincodeName, method string) (*gateway.Transaction, <-chan *fab.TxStatusEvent, error) { + notifier := make(chan *fab.TxStatusEvent) + go func() { + notifier <- &fab.TxStatusEvent{} + }() + return nil, notifier, nil + } + mockSubmitInitTx := func(tx *gateway.Transaction, args ...string) ([]byte, error) { + return []byte(""), nil + } + wrapper.txPreparer = mockPrepareTx + wrapper.txInitSubmitter = mockSubmitInitTx + + _, _, err = wrapper.sendTransaction("signer1", "channel-1", "chaincode-1", "method-1", []string{"args-1"}, true) + assert.NoError(err) +} + func TestChannelClientInstantiation(t *testing.T) { assert := assert.New(t)