From a3e3940700d7f1275d8afbe13b1884e9eb4fa97c Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Wed, 8 Mar 2017 11:08:11 -0500 Subject: [PATCH] [FAB-2696] Default chain broken in peer https://jira.hyperledger.org/browse/FAB-2696 According to @aso, the default chain is currently broken because it does not appropriately encode the channel config, and additional config sanity checks are now rejecting the config as invalid. This CR switches the default chain to using the configtxgen supporting structures to generate the genesis block for the default chain, so that all of the config checks will pass. It also causes the configtxgen tool to search a few different paths for relative MSP directories (., PEER_CFG_PATH, ORDERER_CFG_PATH, and finally the GOPATH). Change-Id: Ib6b836212e335b57f0c2b3c23dc4f05e9a47c56e Signed-off-by: Jason Yellick --- .../configtx/tool/provisional/provisional.go | 38 ++++++++++++++- peer/node/start.go | 48 +++++++++---------- 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/common/configtx/tool/provisional/provisional.go b/common/configtx/tool/provisional/provisional.go index 1275a2adae2..3b87224318b 100644 --- a/common/configtx/tool/provisional/provisional.go +++ b/common/configtx/tool/provisional/provisional.go @@ -18,6 +18,8 @@ package provisional import ( "fmt" + "os" + "path/filepath" "github.com/hyperledger/fabric/common/cauthdsl" "github.com/hyperledger/fabric/common/config" @@ -68,6 +70,38 @@ const ( BlockValidationPolicyKey = "BlockValidation" ) +func resolveMSPDir(path string) string { + if path == "" || path[0] == os.PathSeparator { + return path + } + + // Look for MSP dir first in current path, then in ORDERER_CFG_PATH, then PEER_CFG_PATH, and finally in GOPATH + searchPath := []string{ + ".", + os.Getenv("ORDERER_CFG_PATH"), + os.Getenv("PEER_CFG_PATH"), + } + + for _, p := range filepath.SplitList(os.Getenv("GOPATH")) { + searchPath = append(searchPath, filepath.Join(p, "src/github.com/hyperledger/fabric/common/configtx/tool/")) + } + + for _, baseDir := range searchPath { + logger.Infof("Checking for MSPDir at: %s", baseDir) + fqPath := filepath.Join(baseDir, path) + if _, err := os.Stat(fqPath); err != nil { + // The mspdir does not exist + continue + } + return fqPath + } + + logger.Panicf("Unable to resolve a path for MSPDir: %s", path) + + // Unreachable + return "" +} + // DefaultChainCreationPolicyNames is the default value of ChainCreatorsKey. var DefaultChainCreationPolicyNames = []string{AcceptAllPolicyKey} @@ -116,7 +150,7 @@ func New(conf *genesisconfig.Profile) Generator { } for _, org := range conf.Orderer.Organizations { - mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.BCCSP, org.ID) + mspConfig, err := msp.GetVerifyingMspConfig(resolveMSPDir(org.MSPDir), org.BCCSP, org.ID) if err != nil { logger.Panicf("Error loading MSP configuration for org %s: %s", org.Name, err) } @@ -146,7 +180,7 @@ func New(conf *genesisconfig.Profile) Generator { policies.TemplateImplicitMetaMajorityPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.AdminsPolicyKey), } for _, org := range conf.Application.Organizations { - mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.BCCSP, org.ID) + mspConfig, err := msp.GetVerifyingMspConfig(resolveMSPDir(org.MSPDir), org.BCCSP, org.ID) if err != nil { logger.Panicf("Error loading MSP configuration for org %s: %s", org.Name, err) } diff --git a/peer/node/start.go b/peer/node/start.go index ae1c2325dcb..0c61caac6b8 100644 --- a/peer/node/start.go +++ b/peer/node/start.go @@ -28,13 +28,9 @@ import ( "syscall" "time" - "github.com/hyperledger/fabric/common/config" - "github.com/hyperledger/fabric/common/config/msp" - "github.com/hyperledger/fabric/common/configtx" - "github.com/hyperledger/fabric/common/configtx/test" - "github.com/hyperledger/fabric/common/genesis" + genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig" + "github.com/hyperledger/fabric/common/configtx/tool/provisional" "github.com/hyperledger/fabric/common/localmsp" - "github.com/hyperledger/fabric/common/policies" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core" "github.com/hyperledger/fabric/core/chaincode" @@ -48,6 +44,7 @@ import ( "github.com/hyperledger/fabric/msp/mgmt" "github.com/hyperledger/fabric/peer/common" "github.com/hyperledger/fabric/peer/gossip/mcs" + cb "github.com/hyperledger/fabric/protos/common" pb "github.com/hyperledger/fabric/protos/peer" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -59,6 +56,12 @@ var chaincodeDevMode bool var peerDefaultChain bool var orderingEndpoint string +// XXXDefaultChannelMSPID should not be defined in production code +// It should only be referenced in tests. However, it is necessary +// to support the 'default chain' setup so temporarilly adding until +// this concept can be removed to testing scenarios only +const XXXDefaultChannelMSPID = "DEFAULT" + func startCmd() *cobra.Command { // Set the flags on the node start command. flags := nodeStartCmd.Flags() @@ -180,24 +183,21 @@ func serve(args []string) error { chainID := util.GetTestChainID() - // add readers, writers and admin policies for the default chain - policyTemplate := configtx.NewSimpleTemplate( - policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, msp.ReadersPolicyKey), - policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, msp.WritersPolicyKey), - policies.TemplateImplicitMetaMajorityPolicy([]string{config.ApplicationGroupKey}, msp.AdminsPolicyKey), - ) - - // We create a genesis block for the test - // chain with its MSP so that we can transact - block, err := genesis.NewFactoryImpl( - configtx.NewCompositeTemplate( - test.ApplicationOrgTemplate(), - configtx.NewSimpleTemplate(config.TemplateOrdererAddresses([]string{orderingEndpoint})), - policyTemplate)).Block(chainID) - - if nil != err { - logger.Panicf("Unable to create genesis block for [%s] due to [%s]", chainID, err) - } + var block *cb.Block + + func() { + defer func() { + if err := recover(); err != nil { + logger.Fatalf("Peer configured to start with the default test chain, but supporting configuration files did not match. Please ensure that configtx.yaml contains the unmodified SampleSingleMSPSolo profile and that msp/sampleconfig is present.\n%s", err) + } + }() + + genConf := genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile) + genConf.Orderer.Addresses = []string{orderingEndpoint} + genConf.Application.Organizations[0].Name = XXXDefaultChannelMSPID + genConf.Application.Organizations[0].ID = XXXDefaultChannelMSPID + block = provisional.New(genConf).GenesisBlockForChannel(chainID) + }() //this creates testchainid and sets up gossip if err = peer.CreateChainFromBlock(block); err == nil {