Skip to content

Commit

Permalink
[FAB-8660] Operations and PeerSupport interfaces
Browse files Browse the repository at this point in the history
This introduces an interface that represents the currently exported
functions of the peer. An instance of the interface is created during
package initialization which delegates to the existing functions.

- References to the peer functions in endorser.Support are replaced with a
  reference to the peer singleton.
- CreatePeerServer is renamed to the more idiomatic NewPeerServer as it
  is a constructor
- PeerSupportFactory is removed and an instance of PeerSupport is
  provided to endorser.SupportImpl and scc.ProviderFactory

Change-Id: I07ae90092be8349bed60686f7b04a5b9ab02382a
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
  • Loading branch information
sykesm committed Mar 7, 2018
1 parent 35f32a7 commit 580d091
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 108 deletions.
5 changes: 4 additions & 1 deletion core/chaincode/chaincode_support_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/hyperledger/fabric/core/chaincode/accesscontrol"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric/core/common/sysccprovider"
"github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/container"
"github.com/hyperledger/fabric/core/ledger"
Expand Down Expand Up @@ -144,7 +145,9 @@ func initMockPeer(chainIDs ...string) error {
GetApplicationConfigRv: &mc.MockApplication{&mc.MockApplicationCapabilities{}},
GetApplicationConfigBoolRv: true,
}
peer.RegisterSupportFactory(&cmp.MockSupportFactoryImpl{msi})
sysccprovider.RegisterSystemChaincodeProviderFactory(
&scc.ProviderFactory{Peer: peer.Default, PeerSupport: msi},
)

mockAclProvider = &mocks.MockACLProvider{}
mockAclProvider.Reset()
Expand Down
10 changes: 10 additions & 0 deletions core/endorser/endorser.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,3 +538,13 @@ func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedPro

return pResp, nil
}

// shorttxid replicates the chaincode package function to shorten txids.
// ~~TODO utilize a common shorttxid utility across packages.~~
// TODO use a formal type for transaction ID and make it a stringer
func shorttxid(txid string) string {
if len(txid) < 8 {
return txid
}
return txid[0:8]
}
32 changes: 13 additions & 19 deletions core/endorser/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import (

// SupportImpl provides an implementation of the endorser.Support interface
// issuing calls to various static methods of the peer
type SupportImpl struct{}
type SupportImpl struct {
Peer peer.Operations
PeerSupport peer.Support
}

// IsSysCCAndNotInvokableExternal returns true if the supplied chaincode is
// ia system chaincode and it NOT invokable
Expand All @@ -38,7 +41,7 @@ func (s *SupportImpl) IsSysCCAndNotInvokableExternal(name string) bool {
// a client may obtain more than one such simulator; they are made unique
// by way of the supplied txid
func (s *SupportImpl) GetTxSimulator(ledgername string, txid string) (ledger.TxSimulator, error) {
lgr := peer.GetLedger(ledgername)
lgr := s.Peer.GetLedger(ledgername)
if lgr == nil {
return nil, errors.Errorf("channel does not exist: %s", ledgername)
}
Expand All @@ -48,7 +51,7 @@ func (s *SupportImpl) GetTxSimulator(ledgername string, txid string) (ledger.TxS
// GetHistoryQueryExecutor gives handle to a history query executor for the
// specified ledger
func (s *SupportImpl) GetHistoryQueryExecutor(ledgername string) (ledger.HistoryQueryExecutor, error) {
lgr := peer.GetLedger(ledgername)
lgr := s.Peer.GetLedger(ledgername)
if lgr == nil {
return nil, errors.Errorf("channel does not exist: %s", ledgername)
}
Expand All @@ -57,7 +60,7 @@ func (s *SupportImpl) GetHistoryQueryExecutor(ledgername string) (ledger.History

// GetTransactionByID retrieves a transaction by id
func (s *SupportImpl) GetTransactionByID(chid, txID string) (*pb.ProcessedTransaction, error) {
lgr := peer.GetLedger(chid)
lgr := s.Peer.GetLedger(chid)
if lgr == nil {
return nil, errors.Errorf("failed to look up the ledger for channel %s", chid)
}
Expand All @@ -68,13 +71,13 @@ func (s *SupportImpl) GetTransactionByID(chid, txID string) (*pb.ProcessedTransa
return tx, nil
}

//IsSysCC returns true if the name matches a system chaincode's
//system chaincode names are system, chain wide
// IsSysCC returns true if the name matches a system chaincode's
// system chaincode names are system, chain wide
func (s *SupportImpl) IsSysCC(name string) bool {
return scc.IsSysCC(name)
}

//Execute - execute proposal, return original response of chaincode
// Execute a proposal and return the chaincode response
func (s *SupportImpl) Execute(ctxt context.Context, cid, name, version, txid string, syscc bool, signedProp *pb.SignedProposal, prop *pb.Proposal, spec interface{}) (*pb.Response, *pb.ChaincodeEvent, error) {
cccid := ccprovider.NewCCContext(cid, name, version, txid, syscc, signedProp, prop)

Expand Down Expand Up @@ -105,8 +108,8 @@ func (s *SupportImpl) GetChaincodeDefinition(ctx context.Context, chainID string
return chaincode.GetChaincodeDefinition(ctxt, txid, signedProp, prop, chainID, chaincodeID)
}

//CheckACL checks the ACL for the resource for the channel using the
//SignedProposal from which an id can be extracted for testing against a policy
// CheckACL checks the ACL for the resource for the channel using the
// SignedProposal from which an id can be extracted for testing against a policy
func (s *SupportImpl) CheckACL(signedProp *pb.SignedProposal, chdr *common.ChannelHeader, shdr *common.SignatureHeader, hdrext *pb.ChaincodeHeaderExtension) error {
return aclmgmt.GetACLProvider().CheckACL(resources.PROPOSE, chdr.ChannelId, signedProp)
}
Expand All @@ -132,14 +135,5 @@ func (s *SupportImpl) CheckInstantiationPolicy(name, version string, cd resource
// GetApplicationConfig returns the configtxapplication.SharedConfig for the channel
// and whether the Application config exists
func (s *SupportImpl) GetApplicationConfig(cid string) (channelconfig.Application, bool) {
return peer.GetSupport().GetApplicationConfig(cid)
}

// shorttxid replicates the chaincode package function to shorten txids.
// TODO utilize a common shorttxid utility across packages.
func shorttxid(txid string) string {
if len(txid) < 8 {
return txid
}
return txid[0:8]
return s.PeerSupport.GetApplicationConfig(cid)
}
13 changes: 3 additions & 10 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ func updateTrustedRoots(cm channelconfig.Resources) {
trustedRoots = append(trustedRoots, serverConfig.SecOpts.ServerRootCAs...)
}

server := GetPeerServer()
server := peerServer
// now update the client roots for the peerServer
if server != nil {
err := server.SetClientRootCAs(trustedRoots)
Expand Down Expand Up @@ -675,11 +675,9 @@ func (c *channelPolicyManagerGetter) Manager(channelID string) (policies.Manager
return policyManager, policyManager != nil
}

// CreatePeerServer creates an instance of comm.GRPCServer
// NewPeerServer creates an instance of comm.GRPCServer
// This server is used for peer communications
func CreatePeerServer(listenAddress string,
serverConfig comm.ServerConfig) (comm.GRPCServer, error) {

func NewPeerServer(listenAddress string, serverConfig comm.ServerConfig) (comm.GRPCServer, error) {
var err error
peerServer, err = comm.NewGRPCServer(listenAddress, serverConfig)
if err != nil {
Expand All @@ -689,11 +687,6 @@ func CreatePeerServer(listenAddress string,
return peerServer, nil
}

// GetPeerServer returns the peer server instance
func GetPeerServer() comm.GRPCServer {
return peerServer
}

type collectionSupport struct {
ledger.PeerLedger
}
Expand Down
77 changes: 77 additions & 0 deletions core/peer/peer_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// Copyright IBM Corp. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

package peer

import (
"github.com/hyperledger/fabric/common/channelconfig"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/resourcesconfig"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/protos/common"
pb "github.com/hyperledger/fabric/protos/peer"
)

// Operations exposes an interface to the package level functions that operated
// on singletons in the package. This is a step towards moving from package
// level data for the peer to instance level data.
type Operations interface {
CreateChainFromBlock(cb *common.Block) error
GetChannelConfig(cid string) channelconfig.Resources
GetChannelsInfo() []*pb.ChannelInfo
GetCurrConfigBlock(cid string) *common.Block
GetLedger(cid string) ledger.PeerLedger
GetMSPIDs(cid string) []string
GetPolicyManager(cid string) policies.Manager
GetResourcesConfig(cid string) resourcesconfig.Resources
InitChain(cid string)
Initialize(init func(string))
}

type peerImpl struct {
createChainFromBlock func(cb *common.Block) error
getChannelConfig func(cid string) channelconfig.Resources
getChannelsInfo func() []*pb.ChannelInfo
getCurrConfigBlock func(cid string) *common.Block
getLedger func(cid string) ledger.PeerLedger
getMSPIDs func(cid string) []string
getPolicyManager func(cid string) policies.Manager
getResourcesConfig func(cid string) resourcesconfig.Resources
initChain func(cid string)
initialize func(init func(string))
}

// Default provides in implementation of the Peer interface that provides
// access to the package level state.
var Default Operations = &peerImpl{
createChainFromBlock: CreateChainFromBlock,
getChannelConfig: GetChannelConfig,
getChannelsInfo: GetChannelsInfo,
getCurrConfigBlock: GetCurrConfigBlock,
getLedger: GetLedger,
getMSPIDs: GetMSPIDs,
getPolicyManager: GetPolicyManager,
getResourcesConfig: GetResourcesConfig,
initChain: InitChain,
initialize: Initialize,
}

var DefaultSupport Support = &supportImpl{operations: Default}

func (p *peerImpl) CreateChainFromBlock(cb *common.Block) error { return p.createChainFromBlock(cb) }
func (p *peerImpl) GetChannelConfig(cid string) channelconfig.Resources {
return p.getChannelConfig(cid)
}
func (p *peerImpl) GetChannelsInfo() []*pb.ChannelInfo { return p.getChannelsInfo() }
func (p *peerImpl) GetCurrConfigBlock(cid string) *common.Block { return p.getCurrConfigBlock(cid) }
func (p *peerImpl) GetLedger(cid string) ledger.PeerLedger { return p.getLedger(cid) }
func (p *peerImpl) GetMSPIDs(cid string) []string { return p.getMSPIDs(cid) }
func (p *peerImpl) GetPolicyManager(cid string) policies.Manager { return p.getPolicyManager(cid) }
func (p *peerImpl) GetResourcesConfig(cid string) resourcesconfig.Resources {
return p.getResourcesConfig(cid)
}
func (p *peerImpl) InitChain(cid string) { p.initChain(cid) }
func (p *peerImpl) Initialize(init func(string)) { p.initialize(init) }
20 changes: 8 additions & 12 deletions core/peer/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/hyperledger/fabric/peer/gossip/mocks"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)

Expand All @@ -53,7 +54,6 @@ func (ds *mockDeliveryClient) StopDeliverForChannel(chainID string) error {

// Stop terminates delivery service and closes the connection
func (*mockDeliveryClient) Stop() {

}

type mockDeliveryClientFactory struct {
Expand All @@ -63,21 +63,17 @@ func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []s
return &mockDeliveryClient{}, nil
}

func TestCreatePeerServer(t *testing.T) {

server, err := CreatePeerServer(":4050", comm.ServerConfig{})
assert.NoError(t, err, "CreatePeerServer returned unexpected error")
assert.Equal(t, "[::]:4050", server.Address(),
"CreatePeerServer returned the wrong address")
func TestNewPeerServer(t *testing.T) {
server, err := NewPeerServer(":4050", comm.ServerConfig{})
assert.NoError(t, err, "NewPeerServer returned unexpected error")
assert.Equal(t, "[::]:4050", server.Address(), "NewPeerServer returned the wrong address")
server.Stop()

_, err = CreatePeerServer("", comm.ServerConfig{})
assert.Error(t, err, "expected CreatePeerServer to return error with missing address")

_, err = NewPeerServer("", comm.ServerConfig{})
assert.Error(t, err, "expected NewPeerServer to return error with missing address")
}

func TestInitChain(t *testing.T) {

chainId := "testChain"
chainInitializer = func(cid string) {
assert.Equal(t, chainId, cid, "chainInitializer received unexpected cid")
Expand Down Expand Up @@ -108,7 +104,7 @@ func TestCreateChainFromBlock(t *testing.T) {
// Initialize gossip service
grpcServer := grpc.NewServer()
socket, err := net.Listen("tcp", fmt.Sprintf("%s:%d", "", 13611))
assert.NoError(t, err)
require.NoError(t, err)

msptesttools.LoadMSPSetupForTesting()

Expand Down
14 changes: 6 additions & 8 deletions core/peer/pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ func TestUpdateRootsFromConfigBlock(t *testing.T) {
"Org1-cert.pem"))
viper.Set("peer.fileSystemPath", "/var/hyperledger/test/")
defer os.RemoveAll("/var/hyperledger/test/")
err := peer.CreateChainFromBlock(block)
err := peer.Default.CreateChainFromBlock(block)
if err != nil {
t.Fatalf("Failed to create config block (%s)", err)
}
t.Logf("Channel %s MSPIDs: (%s)", cid, peer.GetMSPIDs(cid))
t.Logf("Channel %s MSPIDs: (%s)", cid, peer.Default.GetMSPIDs(cid))
}

org1CertPool, err := createCertPool([][]byte{org1CA})
Expand Down Expand Up @@ -292,14 +292,12 @@ func TestUpdateRootsFromConfigBlock(t *testing.T) {
test := test
t.Run(test.name, func(t *testing.T) {
t.Logf("Running test %s ...", test.name)
_, err := peer.CreatePeerServer(test.listenAddress, test.serverConfig)
server, err := peer.NewPeerServer(test.listenAddress, test.serverConfig)
if err != nil {
t.Fatalf("CreatePeerServer failed with error [%s]", err)
t.Fatalf("NewPeerServer failed with error [%s]", err)
} else {
assert.NoError(t, err, "CreatePeerServer should not have returned an error")
// get the server from peer
server := peer.GetPeerServer()
assert.NotNil(t, server, "GetPeerServer should not return a nil value")
assert.NoError(t, err, "NewPeerServer should not have returned an error")
assert.NotNil(t, server, "NewPeerServer should have created a server")
// register a GRPC test service
testpb.RegisterTestServiceServer(server.Server(), &testServiceServer{})
go server.Start()
Expand Down
33 changes: 3 additions & 30 deletions core/peer/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ type Support interface {
}

type supportImpl struct {
operations Operations
}

func (s *supportImpl) GetApplicationConfig(cid string) (channelconfig.Application, bool) {
cc := GetChannelConfig(cid)
cc := s.operations.GetChannelConfig(cid)
if cc == nil {
return nil, false
}
Expand All @@ -43,38 +44,10 @@ func (s *supportImpl) GetApplicationConfig(cid string) (channelconfig.Applicatio
}

func (s *supportImpl) ChaincodeByName(chainname, ccname string) (resourcesconfig.ChaincodeDefinition, bool) {
rc := GetResourcesConfig(chainname)
rc := s.operations.GetResourcesConfig(chainname)
if rc == nil {
return nil, false
}

return rc.ChaincodeRegistry().ChaincodeByName(ccname)
}

type SupportFactoryImpl struct {
}

func (c *SupportFactoryImpl) NewSupport() Support {
return &supportImpl{}
}

// RegisterSupportFactory should be called to specify
// which factory should be used to serve GetSupport calls
func RegisterSupportFactory(ccfact SupportFactory) {
supportFactory = ccfact
}

// GetSupport returns a new Support instance by calling the factory
func GetSupport() Support {
if supportFactory == nil {
panic("The factory must be set first via RegisterSupportFactory")
}
return supportFactory.NewSupport()
}

// init is called when this package is loaded; this way by default,
// all calls to GetSupport will be satisfied by SupportFactoryImpl,
// unless RegisterSupportFactory is called again
func init() {
RegisterSupportFactory(&SupportFactoryImpl{})
}
Loading

0 comments on commit 580d091

Please sign in to comment.