Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #75 from s7techlab/rm-hlf
Browse files Browse the repository at this point in the history
refactor peers interface
  • Loading branch information
bogatyr285 authored Oct 26, 2021
2 parents 15167b3 + e3e2fcf commit 53d73b4
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 72 deletions.
127 changes: 56 additions & 71 deletions gateway/service/chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package service

import (
"context"
fmt "fmt"

"github.com/hyperledger/fabric-protos-go/orderer"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/msp"
"github.com/pkg/errors"
)

type ChaincodeService struct {
Expand All @@ -15,47 +15,37 @@ type ChaincodeService struct {

// gateway/chaincode.go needds access to grpc stream
type (
//Chaincode = ChaincodeServer
Chaincode = ChaincodeServer
ChaincodeEventsServer = chaincodeEventsServer
)

type Peer interface {
ChannelChaincode(ctx context.Context, chanName string, ccName string) (Chaincode, error)
Invoke(
ctx context.Context,
chanName string,
ccName string,
args [][]byte,
identity msp.SigningIdentity,
transient map[string][]byte,
txWaiterType string,
) (res *peer.Response, chaincodeTx string, err error)

Query(
ctx context.Context,
chanName string,
ccName string,
args [][]byte,
identity msp.SigningIdentity,
transient map[string][]byte,
) (*peer.ProposalResponse, error)

Events(
ctx context.Context,
channelName string,
ccName string,
identity msp.SigningIdentity,
eventCCSeekOption ...func() (*orderer.SeekPosition, *orderer.SeekPosition),
) (chan *peer.ChaincodeEvent, error)
CurrentIdentity() msp.SigningIdentity
}

type Chaincode interface {
// Invoke returns invoke builder for presented chaincode function
Invoke(fn string) ChaincodeInvokeBuilder
// Query returns query builder for presented function and arguments
Query(fn string, args ...string) ChaincodeQueryBuilder
}

// ChaincodeQueryBuilder describe possibilities how to get query results
type ChaincodeQueryBuilder interface {
// WithIdentity allows to invoke chaincode from custom identity
WithIdentity(identity msp.SigningIdentity) ChaincodeQueryBuilder
// Transient allows to pass arguments to transient map
Transient(args map[string][]byte) ChaincodeQueryBuilder
// AsProposalResponse allows to get raw peer response
AsProposalResponse(ctx context.Context) (*peer.ProposalResponse, error)
}

type ChaincodeInvokeBuilder interface {
// WithIdentity allows to invoke chaincode from custom identity
WithIdentity(identity msp.SigningIdentity) ChaincodeInvokeBuilder
// Transient allows to pass arguments to transient map
Transient(args map[string][]byte) ChaincodeInvokeBuilder
// ArgBytes set slice of bytes as argument
ArgBytes([][]byte) ChaincodeInvokeBuilder
// Do makes invoke with built arguments
Do(ctx context.Context) (res *peer.Response, chaincodeTx string, err error)
}

func New(peerSDK Peer) *ChaincodeService {
Expand All @@ -74,62 +64,57 @@ func (cs *ChaincodeService) Exec(ctx context.Context, in *ChaincodeExec) (*peer.
}

func (cs *ChaincodeService) Invoke(ctx context.Context, in *ChaincodeInput) (*peer.ProposalResponse, error) {
signer, err := SignerFromContext(ctx)
// underlying hlf-sdk(or your implementation must handle it) can handle 'nil' identity cases and set default if call identity wasn't provided
// if smth goes wrong we'll see it on the step below
signer, _ := SignerFromContext(ctx)

response, _, err := cs.peerSDK.Invoke(
ctx,
in.Channel,
in.Chaincode,
in.Args,
signer,
in.Transient,
TxWaiterFromContext(ctx),
)
if err != nil {
return nil, err
return nil, fmt.Errorf("invoke chaincode: %w", err)
}

ccAPI, err := cs.peerSDK.ChannelChaincode(ctx, in.Channel, in.Chaincode)
if err != nil {
return nil, err
}

response, _, err := ccAPI.Invoke(string(in.Args[0])).
WithIdentity(signer).
ArgBytes(in.Args[1:]).
Transient(in.Transient).
Do(ctx)

if err != nil {
return nil, err
}

// todo: add to hlf-peerSDK-go method returning ProposalResponse
// todo: add to hlf-sdk-go method returning ProposalResponse
proposalResponse := &peer.ProposalResponse{
Response: response,
}
return proposalResponse, nil
}

func (cs *ChaincodeService) Query(ctx context.Context, in *ChaincodeInput) (*peer.ProposalResponse, error) {
argSs := make([]string, 0)
for _, arg := range in.Args {
argSs = append(argSs, string(arg))
}

signer, err := SignerFromContext(ctx)
if err != nil {
return nil, err
}

ccAPI, err := cs.peerSDK.ChannelChaincode(ctx, in.Channel, in.Chaincode)
if err != nil {
return nil, err
}

resp, err := ccAPI.Query(argSs[0], argSs[1:]...).
WithIdentity(signer).
Transient(in.Transient).
AsProposalResponse(ctx)
signer, _ := SignerFromContext(ctx)

resp, err := cs.peerSDK.Query(
ctx,
in.Channel,
in.Chaincode,
in.Args,
signer,
in.Transient,
)
if err != nil {
return nil, errors.Wrap(err, `failed to query chaincode`)
return nil, fmt.Errorf("query chaincode: %w", err)
}

return resp, nil
}

func (cs *ChaincodeService) Events(in *ChaincodeLocator, stream Chaincode_EventsServer) error {
events, err := cs.peerSDK.Events(stream.Context(), in.Channel, in.Chaincode)
signer, _ := SignerFromContext(stream.Context())

events, err := cs.peerSDK.Events(
stream.Context(),
in.Channel,
in.Chaincode,
signer,
)
if err != nil {
return err
}
Expand Down
16 changes: 15 additions & 1 deletion gateway/service/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func (c contextKey) String() string {

const (
CtxSignerKey = contextKey(`SigningIdentity`)
CtxDoOptionKey = contextKey(`SdkDoOption`)
CtxTxWaiterKey = contextKey(`TxWaiter`)
)

func ContextWithDefaultSigner(ctx context.Context, defaultSigner msp.SigningIdentity) context.Context {
Expand All @@ -36,3 +36,17 @@ func SignerFromContext(ctx context.Context) (msp.SigningIdentity, error) {
return signer, nil
}
}

func ContextWithTxWaiter(ctx context.Context, txWaiterType string) context.Context {
return context.WithValue(ctx, CtxTxWaiterKey, txWaiterType)
}

// TxWaiterFromContext - fetch 'txWaiterType' param which identify transaction waiting policy
// what params you'll have depends on your implementation
// for example, in hlf-sdk:
// available: 'self'(wait for one peer of endorser org), 'all'(wait for each organizations from endorsement policy)
// default is 'self'(even if you pass empty string)
func TxWaiterFromContext(ctx context.Context) string {
txWaiter, _ := ctx.Value(CtxTxWaiterKey).(string)
return txWaiter
}

0 comments on commit 53d73b4

Please sign in to comment.