Skip to content

Commit

Permalink
[FAB-8050] Remove internal packages from client
Browse files Browse the repository at this point in the history
This patch removes the internal folders and distributes
the methods to the appropriate packages.

Change-Id: If06861d08b54b8320fc81b167d540c97b775cb6b
Signed-off-by: Troy Ronda <troy@troyronda.com>
  • Loading branch information
troyronda committed Feb 4, 2018
1 parent d4c8e3c commit 42d6b16
Show file tree
Hide file tree
Showing 20 changed files with 349 additions and 329 deletions.
3 changes: 1 addition & 2 deletions api/apifabclient/proposer.go
Expand Up @@ -17,7 +17,7 @@ type ProposalProcessor interface {

// ProposalSender provides the ability for a transaction proposal to be created and sent.
type ProposalSender interface {
SendTransactionProposal(ChaincodeInvokeRequest) ([]*TransactionProposalResponse, TransactionID, error)
SendTransactionProposal(ChaincodeInvokeRequest, []ProposalProcessor) ([]*TransactionProposalResponse, TransactionID, error)
}

// TransactionID contains the ID of a Fabric Transaction Proposal
Expand All @@ -30,7 +30,6 @@ type TransactionID struct {
type ChaincodeInvokeRequest struct {
Targets []ProposalProcessor // TODO: remove
ChaincodeID string
TxnID TransactionID // TODO: remove from external interface
TransientMap map[string][]byte
Fcn string
Args [][]byte
Expand Down
72 changes: 49 additions & 23 deletions pkg/fabric-client/channel/block.go
Expand Up @@ -7,16 +7,13 @@ SPDX-License-Identifier: Apache-2.0
package channel

import (
"time"

"github.com/golang/protobuf/proto"

ab "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/protos/orderer"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
protos_utils "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/utils"

ccomm "github.com/hyperledger/fabric-sdk-go/pkg/config/comm"
fc "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/internal"
"github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/txn"
"github.com/pkg/errors"
)
Expand All @@ -35,10 +32,6 @@ func (c *Channel) GenesisBlock() (*common.Block, error) {
if len(c.Orderers()) == 0 {
return nil, errors.New("GenesisBlock missing orderer assigned to this channel for the GenesisBlock request")
}
creator, err := c.clientContext.Identity()
if err != nil {
return nil, errors.WithMessage(err, "failed to get creator identity")
}

txnID, err := txn.NewID(c.clientContext)
if err != nil {
Expand All @@ -47,28 +40,33 @@ func (c *Channel) GenesisBlock() (*common.Block, error) {

// now build the seek info , will be used once the channel is created
// to get the genesis block back
seekStart := fc.NewSpecificSeekPosition(0)
seekStop := fc.NewSpecificSeekPosition(0)
seekStart := newSpecificSeekPosition(0)
seekStop := newSpecificSeekPosition(0)
seekInfo := &ab.SeekInfo{
Start: seekStart,
Stop: seekStop,
Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
}
protos_utils.MakeChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, 1, c.Name(), 0)

tlsCertHash := ccomm.TLSCertHash(c.clientContext.Config())
seekInfoHeader, err := txn.BuildChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, c.Name(), txnID.ID, 0, "", time.Now(), tlsCertHash)
channelHeaderOpts := txn.ChannelHeaderOpts{
ChannelID: c.Name(),
TxnID: txnID,
TLSCertHash: tlsCertHash,
}
seekInfoHeader, err := txn.CreateChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, channelHeaderOpts)
if err != nil {
return nil, errors.Wrap(err, "BuildChannelHeader failed")
}
seekHeader, err := fc.BuildHeader(creator, seekInfoHeader, txnID.Nonce)
seekHeader, err := txn.CreateHeader(c.clientContext, seekInfoHeader, txnID)
if err != nil {
return nil, errors.Wrap(err, "BuildHeader failed")
}
seekPayload := &common.Payload{
Header: seekHeader,
Data: fc.MarshalOrPanic(seekInfo),
Data: protos_utils.MarshalOrPanic(seekInfo),
}
seekPayloadBytes := fc.MarshalOrPanic(seekPayload)
seekPayloadBytes := protos_utils.MarshalOrPanic(seekPayload)

signedEnvelope, err := txn.SignPayload(c.clientContext, seekPayloadBytes)
if err != nil {
Expand All @@ -82,27 +80,45 @@ func (c *Channel) GenesisBlock() (*common.Block, error) {
return block, nil
}

// createSeekGenesisBlockRequest creates a seek request for block 0 on the specified
// channel. This request is sent to the ordering service to request blocks
func createSeekGenesisBlockRequest(channelName string, creator []byte) []byte {
return protos_utils.MarshalOrPanic(&common.Payload{
Header: &common.Header{
ChannelHeader: protos_utils.MarshalOrPanic(&common.ChannelHeader{
ChannelId: channelName,
}),
SignatureHeader: protos_utils.MarshalOrPanic(&common.SignatureHeader{Creator: creator}),
},
Data: protos_utils.MarshalOrPanic(&ab.SeekInfo{
Start: &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 0}}},
Stop: &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 0}}},
Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
}),
})
}

// block retrieves the block at the given position
func (c *Channel) block(pos *ab.SeekPosition) (*common.Block, error) {
nonce, err := fc.GenerateRandomNonce()
if err != nil {
return nil, errors.Wrap(err, "GenerateRandomNonce failed")
}

creator, err := c.clientContext.Identity()
if err != nil {
return nil, errors.WithMessage(err, "serializing identity failed")
}

txID, err := protos_utils.ComputeProposalTxID(nonce, creator)
txnID, err := txn.NewID(c.clientContext)
if err != nil {
return nil, errors.Wrap(err, "generating TX ID failed")
}

tlsCertHash := ccomm.TLSCertHash(c.clientContext.Config())
seekInfoHeader, err := txn.BuildChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, c.Name(), txID, 0, "", time.Now(), tlsCertHash)
channelHeaderOpts := txn.ChannelHeaderOpts{
ChannelID: c.Name(),
TxnID: txnID,
TLSCertHash: ccomm.TLSCertHash(c.clientContext.Config()),
}
seekInfoHeader, err := txn.CreateChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, channelHeaderOpts)
if err != nil {
return nil, errors.Wrap(err, "BuildChannelHeader failed")
return nil, errors.Wrap(err, "NewChannelHeader failed")
}

seekInfoHeaderBytes, err := proto.Marshal(seekInfoHeader)
Expand All @@ -112,7 +128,7 @@ func (c *Channel) block(pos *ab.SeekPosition) (*common.Block, error) {

signatureHeader := &common.SignatureHeader{
Creator: creator,
Nonce: nonce,
Nonce: txnID.Nonce,
}

signatureHeaderBytes, err := proto.Marshal(signatureHeader)
Expand Down Expand Up @@ -153,3 +169,13 @@ func (c *Channel) block(pos *ab.SeekPosition) (*common.Block, error) {

return txn.SendEnvelope(c.clientContext, signedEnvelope, c.Orderers())
}

// newNewestSeekPosition returns a SeekPosition that requests the newest block
func newNewestSeekPosition() *ab.SeekPosition {
return &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}
}

// newSpecificSeekPosition returns a SeekPosition that requests the block at the given index
func newSpecificSeekPosition(index uint64) *ab.SeekPosition {
return &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: index}}}
}
27 changes: 23 additions & 4 deletions pkg/fabric-client/channel/config.go
Expand Up @@ -14,7 +14,6 @@ import (
mb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/msp"

"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/msp"
fc "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/internal"
"github.com/pkg/errors"
)

Expand All @@ -27,21 +26,21 @@ func (c *Channel) ChannelConfig() (*common.ConfigEnvelope, error) {
logger.Debugf("channelConfig - start for channel %s", c.name)

// Get the newest block
block, err := c.block(fc.NewNewestSeekPosition())
block, err := c.block(newNewestSeekPosition())
if err != nil {
return nil, err
}
logger.Debugf("channelConfig - Retrieved newest block number: %d\n", block.Header.Number)

// Get the index of the last config block
lastConfig, err := fc.GetLastConfigFromBlock(block)
lastConfig, err := getLastConfigFromBlock(block)
if err != nil {
return nil, errors.Wrap(err, "GetLastConfigFromBlock failed")
}
logger.Debugf("channelConfig - Last config index: %d\n", lastConfig.Index)

// Get the last config block
block, err = c.block(fc.NewSpecificSeekPosition(lastConfig.Index))
block, err = c.block(newSpecificSeekPosition(lastConfig.Index))

if err != nil {
return nil, errors.WithMessage(err, "retrieve block failed")
Expand Down Expand Up @@ -139,3 +138,23 @@ func loadMSPs(mspConfigs []*mb.MSPConfig, cs apicryptosuite.CryptoSuite) ([]msp.
logger.Debugf("loadMSPs - loaded %d MSPs", len(msps))
return msps, nil
}

// getLastConfigFromBlock returns the LastConfig data from the given block
func getLastConfigFromBlock(block *common.Block) (*common.LastConfig, error) {
if block.Metadata == nil {
return nil, errors.New("block metadata is nil")
}
metadata := &common.Metadata{}
err := proto.Unmarshal(block.Metadata.Metadata[common.BlockMetadataIndex_LAST_CONFIG], metadata)
if err != nil {
return nil, errors.Wrap(err, "unmarshal block metadata failed")
}

lastConfig := &common.LastConfig{}
err = proto.Unmarshal(metadata.Value, lastConfig)
if err != nil {
return nil, errors.Wrap(err, "unmarshal last config from metadata failed")
}

return lastConfig, err
}
17 changes: 8 additions & 9 deletions pkg/fabric-client/channel/query.go
Expand Up @@ -135,12 +135,11 @@ func (c *Channel) QueryInstantiatedChaincodes() (*pb.ChaincodeQueryResponse, err

targets := []fab.ProposalProcessor{c.PrimaryPeer()}
request := fab.ChaincodeInvokeRequest{
Targets: targets,
ChaincodeID: "lscc",
Fcn: "getchaincodes",
}

payload, err := c.QueryByChaincode(request)
payload, err := queryByChaincode(c.clientContext, c.name, request, targets)
if err != nil {
return nil, errors.WithMessage(err, "lscc.getchaincodes failed")
}
Expand All @@ -160,11 +159,11 @@ func (c *Channel) QueryInstantiatedChaincodes() (*pb.ChaincodeQueryResponse, err
// results in the byte array format and the caller will have to be able to decode.
// these results.
func (c *Channel) QueryByChaincode(request fab.ChaincodeInvokeRequest) ([][]byte, error) {
request, err := c.chaincodeInvokeRequestAddDefaultPeers(request)
targets, err := c.chaincodeInvokeRequestAddDefaultPeers(request.Targets)
if err != nil {
return nil, err
}
return queryByChaincode(c.name, request, c.clientContext)
return queryByChaincode(c.clientContext, c.name, request, targets)
}

func filterProposalResponses(tpr []*fab.TransactionProposalResponse) ([][]byte, error) {
Expand All @@ -184,7 +183,7 @@ func filterProposalResponses(tpr []*fab.TransactionProposalResponse) ([][]byte,
return responses, nil
}

func queryByChaincode(channelID string, request fab.ChaincodeInvokeRequest, clientContext fab.Context) ([][]byte, error) {
func queryByChaincode(clientContext fab.Context, channelID string, request fab.ChaincodeInvokeRequest, targets []fab.ProposalProcessor) ([][]byte, error) {
if err := validateChaincodeInvokeRequest(request); err != nil {
return nil, err
}
Expand All @@ -194,7 +193,7 @@ func queryByChaincode(channelID string, request fab.ChaincodeInvokeRequest, clie
return nil, errors.WithMessage(err, "NewProposal failed")
}

tpr, err := txn.SendProposal(tp, request.Targets)
tpr, err := txn.SendProposal(tp, targets)
if err != nil {
return nil, errors.WithMessage(err, "SendProposal failed")
}
Expand Down Expand Up @@ -227,17 +226,17 @@ func (c *Channel) queryBySystemChaincodeByTarget(chaincodeID string, fcn string,
//
// TODO: This function's name is confusing - call the normal QueryByChaincode for system chaincode on a channel.
func (c *Channel) QueryBySystemChaincode(request fab.ChaincodeInvokeRequest) ([][]byte, error) {
request, err := c.chaincodeInvokeRequestAddDefaultPeers(request)
targets, err := c.chaincodeInvokeRequestAddDefaultPeers(request.Targets)
if err != nil {
return nil, err
}
return queryByChaincode(systemChannel, request, c.clientContext)
return queryByChaincode(c.clientContext, systemChannel, request, targets)
}

// QueryBySystemChaincode invokes a system chaincode
// TODO - should be moved.
func QueryBySystemChaincode(request fab.ChaincodeInvokeRequest, clientContext fab.Context) ([][]byte, error) {
return queryByChaincode(systemChannel, request, clientContext)
return queryByChaincode(clientContext, systemChannel, request, request.Targets)
}

// QueryConfigBlock returns the current configuration block for the specified channel. If the
Expand Down
2 changes: 1 addition & 1 deletion pkg/fabric-client/channel/query_test.go
Expand Up @@ -146,7 +146,7 @@ func TestQueryMissingParams(t *testing.T) {
if err == nil {
t.Fatalf("Expected error")
}
_, err = queryByChaincode("", request, channel.clientContext)
_, err = queryByChaincode(channel.clientContext, "", request, request.Targets)
if err == nil {
t.Fatalf("Expected error")
}
Expand Down
20 changes: 8 additions & 12 deletions pkg/fabric-client/channel/txn.go
Expand Up @@ -42,18 +42,18 @@ func (c *Channel) SendTransaction(tx *fab.Transaction) (*fab.TransactionResponse

// SendTransactionProposal sends the created proposal to peer for endorsement.
// TODO: return the entire request or just the txn ID?
func (c *Channel) SendTransactionProposal(request fab.ChaincodeInvokeRequest) ([]*fab.TransactionProposalResponse, fab.TransactionID, error) {
func (c *Channel) SendTransactionProposal(request fab.ChaincodeInvokeRequest, targets []fab.ProposalProcessor) ([]*fab.TransactionProposalResponse, fab.TransactionID, error) {
tp, err := txn.NewProposal(c.clientContext, c.name, request)
if err != nil {
return nil, fab.TransactionID{}, errors.WithMessage(err, "new transaction proposal failed")
}

request, err = c.chaincodeInvokeRequestAddDefaultPeers(request)
targets, err = c.chaincodeInvokeRequestAddDefaultPeers(targets)
if err != nil {
return nil, fab.TransactionID{}, err
}

tpr, err := txn.SendProposal(tp, request.Targets)
tpr, err := txn.SendProposal(tp, targets)
if err != nil {
return nil, fab.TransactionID{}, errors.WithMessage(err, "send transaction proposal failed")
}
Expand Down Expand Up @@ -195,23 +195,19 @@ func validateChaincodeInvokeRequest(request fab.ChaincodeInvokeRequest) error {
if request.Fcn == "" {
return errors.New("Fcn is required")
}

if request.Targets == nil || len(request.Targets) < 1 {
return errors.New("Targets is required")
}
return nil
}

func (c *Channel) chaincodeInvokeRequestAddDefaultPeers(request fab.ChaincodeInvokeRequest) (fab.ChaincodeInvokeRequest, error) {
func (c *Channel) chaincodeInvokeRequestAddDefaultPeers(targets []fab.ProposalProcessor) ([]fab.ProposalProcessor, error) {
// Use default peers if targets are not specified.
if request.Targets == nil || len(request.Targets) == 0 {
if targets == nil || len(targets) == 0 {
if c.peers == nil || len(c.peers) == 0 {
return request, errors.New("targets were not specified and no peers have been configured")
return nil, errors.New("targets were not specified and no peers have been configured")
}

request.Targets = c.txnProcessors()
return c.txnProcessors(), nil
}
return request, nil
return targets, nil
}

// helper function that sends an instantiate or upgrade chaincode proposal to one or more endorsing peers
Expand Down

0 comments on commit 42d6b16

Please sign in to comment.