Skip to content

Commit

Permalink
[FAB-8615] Remove Channel dependency from ChannelConfig
Browse files Browse the repository at this point in the history
Moved functionality to query the latest config block
from the orderer to the Resource interface.

This is in preparation for the upcoming deprecation
of the Channel interface.

Change-Id: I75eb2b54153128dc8aa64d43baa75333b99ca79b
Signed-off-by: Divyank Katira <Divyank.Katira@securekey.com>
  • Loading branch information
d1vyank committed Mar 1, 2018
1 parent 54c4ba0 commit 713dd0e
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 89 deletions.
21 changes: 0 additions & 21 deletions pkg/client/channel/chclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ import (
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"

"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke"
txnmocks "github.com/hyperledger/fabric-sdk-go/pkg/client/common/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/retry"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/status"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/channel"
fcmocks "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/txn"
Expand Down Expand Up @@ -509,13 +507,10 @@ func TestDiscoveryGreylist(t *testing.T) {

func setupTestChannelService(ctx context.Context, orderers []fab.Orderer) (fab.ChannelService, error) {
const channelName = "testChannel"
testChannel, err := setupChannel(channelName)

chProvider, err := fcmocks.NewMockChannelProvider(ctx)
if err != nil {
return nil, errors.WithMessage(err, "mock channel provider creation failed")
}
chProvider.SetChannel(channelName, testChannel)

chService, err := chProvider.ChannelService(ctx, channelName)
if err != nil {
Expand All @@ -532,22 +527,6 @@ func setupTestChannelService(ctx context.Context, orderers []fab.Orderer) (fab.C
return chService, nil
}

func setupChannel(channelID string) (*channel.Channel, error) {
ctx := setupTestContext()
channel, err := channel.New(ctx, fcmocks.NewMockChannelCfg(channelID))
if err != nil {
return nil, err
}
// Add mock msp to msp manager
msps := make(map[string]msp.MSP)
msps["Org1MSP"] = fcmocks.NewMockMSP(nil)
mspMgr := fcmocks.NewMockMSPManager(msps)

channel.SetMSPManager(mspMgr)

return channel, nil
}

func setupTestContext() context.Context {
user := fcmocks.NewMockUser("test")
ctx := fcmocks.NewMockContext(user)
Expand Down
6 changes: 0 additions & 6 deletions pkg/client/channel/invoke/txnhandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
txnmocks "github.com/hyperledger/fabric-sdk-go/pkg/client/common/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/channel"
fcmocks "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
)

Expand Down Expand Up @@ -217,11 +216,6 @@ func prepareRequestContext(request Request, opts Opts, t *testing.T) *RequestCon
return requestContext
}

func setupTestChannel() (*channel.Channel, error) {
ctx := setupTestContext()
return channel.New(ctx, fcmocks.NewMockChannelCfg("testChannel"))
}

func setupChannelClientContext(discErr error, selectionErr error, peers []fab.Peer, t *testing.T) *ClientContext {
membership := fcmocks.NewMockMembership()

Expand Down
27 changes: 12 additions & 15 deletions pkg/fab/chconfig/chconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/resource"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
msp "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/msp"
Expand All @@ -33,9 +34,9 @@ const (

// Opts contains options for retrieving channel configuration
type Opts struct {
Orderer string // if configured, channel config will be retrieved from this orderer
Targets []fab.Peer // if configured, channel config will be retrieved from peers (targets)
MinResponses int // used with targets option; min number of success responses (from targets/peers)
Orderer fab.Orderer // if configured, channel config will be retrieved from this orderer
Targets []fab.Peer // if configured, channel config will be retrieved from peers (targets)
MinResponses int // used with targets option; min number of success responses (from targets/peers)
}

// Option func for each Opts argument
Expand Down Expand Up @@ -107,7 +108,7 @@ func New(ctx context.Context, channelID string, options ...Option) (*ChannelConf
// Query returns channel configuration
func (c *ChannelConfig) Query() (fab.ChannelCfg, error) {

if c.opts.Orderer != "" {
if c.opts.Orderer != nil {
return c.queryOrderer()
}

Expand All @@ -116,9 +117,9 @@ func (c *ChannelConfig) Query() (fab.ChannelCfg, error) {

func (c *ChannelConfig) queryPeers() (*ChannelCfg, error) {

ch, err := channel.New(c.ctx, &ChannelCfg{name: c.channelID})
l, err := channel.NewLedger(c.ctx, c.channelID)
if err != nil {
return nil, errors.WithMessage(err, "NewChannel failed")
return nil, errors.WithMessage(err, "ledger client creation failed")
}

targets := []fab.ProposalProcessor{}
Expand Down Expand Up @@ -148,7 +149,7 @@ func (c *ChannelConfig) queryPeers() (*ChannelCfg, error) {
minEndorsers = defaultMinResponses
}

configEnvelope, err := ch.QueryConfigBlock(targets, minEndorsers)
configEnvelope, err := l.QueryConfigBlock(targets, minEndorsers)
if err != nil {
return nil, errors.WithMessage(err, "QueryBlockConfig failed")
}
Expand All @@ -158,14 +159,10 @@ func (c *ChannelConfig) queryPeers() (*ChannelCfg, error) {

func (c *ChannelConfig) queryOrderer() (*ChannelCfg, error) {

ch, err := channel.New(c.ctx, &ChannelCfg{name: c.channelID, orderers: []string{c.opts.Orderer}})
r := resource.New(c.ctx)
configEnvelope, err := r.LastConfigFromOrderer(c.channelID, c.opts.Orderer)
if err != nil {
return nil, errors.WithMessage(err, "NewChannel failed")
}

configEnvelope, err := ch.ChannelConfig()
if err != nil {
return nil, errors.WithMessage(err, "ChannelConfig() failed")
return nil, errors.WithMessage(err, "LastConfigFromOrderer failed")
}

return extractConfig(c.channelID, configEnvelope)
Expand All @@ -188,7 +185,7 @@ func WithMinResponses(min int) Option {
}

// WithOrderer encapsulates orderer to Option
func WithOrderer(orderer string) Option {
func WithOrderer(orderer fab.Orderer) Option {
return func(opts *Opts) error {
opts.Orderer = orderer
return nil
Expand Down
13 changes: 5 additions & 8 deletions pkg/fab/chconfig/chconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import (
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/orderer"
"github.com/stretchr/testify/assert"
)

const (
Expand Down Expand Up @@ -58,8 +59,9 @@ func TestChannelConfigWithPeerError(t *testing.T) {
func TestChannelConfigWithOrdererError(t *testing.T) {

ctx := setupTestContext()

channelConfig, err := New(ctx, channelID, WithOrderer("localhost:7054"))
o, err := orderer.New(ctx.Config(), orderer.WithURL("localhost:7054"))
assert.Nil(t, err)
channelConfig, err := New(ctx, channelID, WithOrderer(o))
if err != nil {
t.Fatalf("Failed to create new channel client: %s", err)
}
Expand All @@ -72,11 +74,6 @@ func TestChannelConfigWithOrdererError(t *testing.T) {

}

func setupTestChannel(name string) (*channel.Channel, error) {
ctx := setupTestContext()
return channel.New(ctx, mocks.NewMockChannelCfg(name))
}

func setupTestContext() context.Context {
user := mocks.NewMockUser("test")
ctx := mocks.NewMockContext(user)
Expand Down
5 changes: 5 additions & 0 deletions pkg/fab/mocks/mockresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ func (c *MockResource) GenesisBlockFromOrderer(channelName string, orderer fab.O
return NewSimpleMockBlock(), nil
}

// LastConfigFromOrderer not implemented
func (c *MockResource) LastConfigFromOrderer(channelName string, orderer fab.Orderer) (*common.ConfigEnvelope, error) {
return nil, nil
}

// JoinChannel sends a join channel proposal to the target peer.
func (c *MockResource) JoinChannel(request api.JoinChannelRequest) error {
if c.errorScenario {
Expand Down
1 change: 1 addition & 0 deletions pkg/fab/resource/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Resource interface {
QueryInstalledChaincodes(peer fab.ProposalProcessor) (*pb.ChaincodeQueryResponse, error)
QueryChannels(peer fab.ProposalProcessor) (*pb.ChannelQueryResponse, error)
GenesisBlockFromOrderer(channelName string, orderer fab.Orderer) (*common.Block, error)
LastConfigFromOrderer(channelName string, orderer fab.Orderer) (*common.ConfigEnvelope, error)
JoinChannel(request JoinChannelRequest) error
SignChannelConfig(config []byte, signer context.IdentityContext) (*common.ConfigSignature, error)
}
Expand Down
83 changes: 83 additions & 0 deletions pkg/fab/resource/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

// Package resource provides access to fabric network resource management, typically using system channel queries.
package resource

import (
"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/pkg/context/api/fab"
ccomm "github.com/hyperledger/fabric-sdk-go/pkg/core/config/comm"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/txn"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
"github.com/pkg/errors"
)

// block retrieves the block at the given position
func (r *Resource) block(orderers []fab.Orderer, channel string, pos *ab.SeekPosition) (*common.Block, error) {
th, err := txn.NewHeader(r.clientContext, channel)
if err != nil {
return nil, errors.Wrap(err, "generating TX ID failed")
}

channelHeaderOpts := txn.ChannelHeaderOpts{
TxnHeader: th,
TLSCertHash: ccomm.TLSCertHash(r.clientContext.Config()),
}
seekInfoHeader, err := txn.CreateChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, channelHeaderOpts)
if err != nil {
return nil, errors.Wrap(err, "CreateChannelHeader failed")
}

seekInfoHeaderBytes, err := proto.Marshal(seekInfoHeader)
if err != nil {
return nil, errors.Wrap(err, "marshal seek info failed")
}

signatureHeader, err := txn.CreateSignatureHeader(th)
if err != nil {
return nil, errors.Wrap(err, "CreateSignatureHeader failed")
}

signatureHeaderBytes, err := proto.Marshal(signatureHeader)
if err != nil {
return nil, errors.Wrap(err, "marshal signature header failed")
}

seekHeader := &common.Header{
ChannelHeader: seekInfoHeaderBytes,
SignatureHeader: signatureHeaderBytes,
}

seekInfo := &ab.SeekInfo{
Start: pos,
Stop: pos,
Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
}

seekInfoBytes, err := proto.Marshal(seekInfo)
if err != nil {
return nil, errors.Wrap(err, "marshal seek info failed")
}

payload := common.Payload{
Header: seekHeader,
Data: seekInfoBytes,
}

return txn.SendPayload(r.clientContext, &payload, 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}}}
}
45 changes: 45 additions & 0 deletions pkg/fab/resource/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,48 @@ func ExtractChannelConfig(configEnvelope []byte) ([]byte, error) {

return configUpdateEnvelope.ConfigUpdate, nil
}

func CreateConfigEnvelope(data []byte) (*common.ConfigEnvelope, error) {

envelope := &common.Envelope{}
if err := proto.Unmarshal(data, envelope); err != nil {
return nil, errors.Wrap(err, "unmarshal envelope from config block failed")
}
payload := &common.Payload{}
if err := proto.Unmarshal(envelope.Payload, payload); err != nil {
return nil, errors.Wrap(err, "unmarshal payload from envelope failed")
}
channelHeader := &common.ChannelHeader{}
if err := proto.Unmarshal(payload.Header.ChannelHeader, channelHeader); err != nil {
return nil, errors.Wrap(err, "unmarshal payload from envelope failed")
}
if common.HeaderType(channelHeader.Type) != common.HeaderType_CONFIG {
return nil, errors.New("block must be of type 'CONFIG'")
}
configEnvelope := &common.ConfigEnvelope{}
if err := proto.Unmarshal(payload.Data, configEnvelope); err != nil {
return nil, errors.Wrap(err, "unmarshal config envelope failed")
}

return configEnvelope, 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
}
Loading

0 comments on commit 713dd0e

Please sign in to comment.