github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/common/configtx/tool/provisional/provisional.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package provisional
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/hyperledger/fabric/common/cauthdsl"
    23  	"github.com/hyperledger/fabric/common/config"
    24  	configvaluesmsp "github.com/hyperledger/fabric/common/config/msp"
    25  	"github.com/hyperledger/fabric/common/configtx"
    26  	genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
    27  	"github.com/hyperledger/fabric/common/flogging"
    28  	"github.com/hyperledger/fabric/common/genesis"
    29  	"github.com/hyperledger/fabric/common/policies"
    30  	"github.com/hyperledger/fabric/msp"
    31  	"github.com/hyperledger/fabric/orderer/common/bootstrap"
    32  	cb "github.com/hyperledger/fabric/protos/common"
    33  	ab "github.com/hyperledger/fabric/protos/orderer"
    34  	pb "github.com/hyperledger/fabric/protos/peer"
    35  	"github.com/hyperledger/fabric/protos/utils"
    36  	logging "github.com/op/go-logging"
    37  )
    38  
    39  const (
    40  	pkgLogID = "common/configtx/tool/provisional"
    41  )
    42  
    43  var (
    44  	logger *logging.Logger
    45  )
    46  
    47  func init() {
    48  	logger = flogging.MustGetLogger(pkgLogID)
    49  	flogging.SetModuleLevel(pkgLogID, "info")
    50  }
    51  
    52  // Generator can either create an orderer genesis block or config template
    53  type Generator interface {
    54  	bootstrap.Helper
    55  
    56  	// ChannelTemplate returns a template which can be used to help initialize a channel
    57  	ChannelTemplate() configtx.Template
    58  
    59  	// GenesisBlockForChannel TODO
    60  	GenesisBlockForChannel(channelID string) *cb.Block
    61  }
    62  
    63  const (
    64  	// ConsensusTypeSolo identifies the solo consensus implementation.
    65  	ConsensusTypeSolo = "solo"
    66  	// ConsensusTypeKafka identifies the Kafka-based consensus implementation.
    67  	ConsensusTypeKafka = "kafka"
    68  
    69  	// TestChainID is the default value of ChainID. It is used by all testing
    70  	// networks. It it necessary to set and export this variable so that test
    71  	// clients can connect without being rejected for targeting a chain which
    72  	// does not exist.
    73  	TestChainID = "testchainid"
    74  
    75  	// BlockValidationPolicyKey TODO
    76  	BlockValidationPolicyKey = "BlockValidation"
    77  
    78  	// OrdererAdminsPolicy is the absolute path to the orderer admins policy
    79  	OrdererAdminsPolicy = "/Channel/Orderer/Admins"
    80  )
    81  
    82  type bootstrapper struct {
    83  	channelGroups     []*cb.ConfigGroup
    84  	ordererGroups     []*cb.ConfigGroup
    85  	applicationGroups []*cb.ConfigGroup
    86  	consortiumsGroups []*cb.ConfigGroup
    87  }
    88  
    89  // New returns a new provisional bootstrap helper.
    90  func New(conf *genesisconfig.Profile) Generator {
    91  	bs := &bootstrapper{
    92  		channelGroups: []*cb.ConfigGroup{
    93  			// Chain Config Types
    94  			config.DefaultHashingAlgorithm(),
    95  			config.DefaultBlockDataHashingStructure(),
    96  
    97  			// Default policies
    98  			policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.ReadersPolicyKey),
    99  			policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.WritersPolicyKey),
   100  			policies.TemplateImplicitMetaMajorityPolicy([]string{}, configvaluesmsp.AdminsPolicyKey),
   101  		},
   102  	}
   103  
   104  	if conf.Orderer != nil {
   105  		// Orderer addresses
   106  		oa := config.TemplateOrdererAddresses(conf.Orderer.Addresses)
   107  		oa.Values[config.OrdererAddressesKey].ModPolicy = OrdererAdminsPolicy
   108  
   109  		bs.ordererGroups = []*cb.ConfigGroup{
   110  			oa,
   111  
   112  			// Orderer Config Types
   113  			config.TemplateConsensusType(conf.Orderer.OrdererType),
   114  			config.TemplateBatchSize(&ab.BatchSize{
   115  				MaxMessageCount:   conf.Orderer.BatchSize.MaxMessageCount,
   116  				AbsoluteMaxBytes:  conf.Orderer.BatchSize.AbsoluteMaxBytes,
   117  				PreferredMaxBytes: conf.Orderer.BatchSize.PreferredMaxBytes,
   118  			}),
   119  			config.TemplateBatchTimeout(conf.Orderer.BatchTimeout.String()),
   120  			config.TemplateChannelRestrictions(conf.Orderer.MaxChannels),
   121  
   122  			// Initialize the default Reader/Writer/Admins orderer policies, as well as block validation policy
   123  			policies.TemplateImplicitMetaPolicyWithSubPolicy([]string{config.OrdererGroupKey}, BlockValidationPolicyKey, configvaluesmsp.WritersPolicyKey, cb.ImplicitMetaPolicy_ANY),
   124  			policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.ReadersPolicyKey),
   125  			policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.WritersPolicyKey),
   126  			policies.TemplateImplicitMetaMajorityPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.AdminsPolicyKey),
   127  		}
   128  
   129  		for _, org := range conf.Orderer.Organizations {
   130  			mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
   131  			if err != nil {
   132  				logger.Panicf("1 - Error loading MSP configuration for org %s: %s", org.Name, err)
   133  			}
   134  			bs.ordererGroups = append(bs.ordererGroups,
   135  				configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal([]string{config.OrdererGroupKey, org.Name},
   136  					mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   137  				),
   138  			)
   139  		}
   140  
   141  		switch conf.Orderer.OrdererType {
   142  		case ConsensusTypeSolo:
   143  		case ConsensusTypeKafka:
   144  			bs.ordererGroups = append(bs.ordererGroups, config.TemplateKafkaBrokers(conf.Orderer.Kafka.Brokers))
   145  		default:
   146  			panic(fmt.Errorf("Wrong consenter type value given: %s", conf.Orderer.OrdererType))
   147  		}
   148  	}
   149  
   150  	if conf.Application != nil {
   151  
   152  		bs.applicationGroups = []*cb.ConfigGroup{
   153  			// Initialize the default Reader/Writer/Admins application policies
   154  			policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.ReadersPolicyKey),
   155  			policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.WritersPolicyKey),
   156  			policies.TemplateImplicitMetaMajorityPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.AdminsPolicyKey),
   157  		}
   158  		for _, org := range conf.Application.Organizations {
   159  			mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
   160  			if err != nil {
   161  				logger.Panicf("2- Error loading MSP configuration for org %s: %s", org.Name, err)
   162  			}
   163  
   164  			bs.applicationGroups = append(bs.applicationGroups,
   165  				configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal([]string{config.ApplicationGroupKey, org.Name},
   166  					mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   167  				),
   168  			)
   169  			var anchorProtos []*pb.AnchorPeer
   170  			for _, anchorPeer := range org.AnchorPeers {
   171  				anchorProtos = append(anchorProtos, &pb.AnchorPeer{
   172  					Host: anchorPeer.Host,
   173  					Port: int32(anchorPeer.Port),
   174  				})
   175  			}
   176  
   177  			bs.applicationGroups = append(bs.applicationGroups, config.TemplateAnchorPeers(org.Name, anchorProtos))
   178  		}
   179  
   180  	}
   181  
   182  	if conf.Consortiums != nil {
   183  		tcg := config.TemplateConsortiumsGroup()
   184  		tcg.Groups[config.ConsortiumsGroupKey].ModPolicy = OrdererAdminsPolicy
   185  
   186  		// Fix for https://jira.hyperledger.org/browse/FAB-4373
   187  		// Note, AcceptAllPolicy in this context, does not grant any unrestricted
   188  		// access, but allows the /Channel/Admins policy to evaluate to true
   189  		// for the ordering system channel while set to MAJORITY with the addition
   190  		// to the successful evaluation of the /Channel/Orderer/Admins policy (which
   191  		// is not AcceptAll
   192  		tcg.Groups[config.ConsortiumsGroupKey].Policies[configvaluesmsp.AdminsPolicyKey] = &cb.ConfigPolicy{
   193  			Policy: &cb.Policy{
   194  				Type:  int32(cb.Policy_SIGNATURE),
   195  				Value: utils.MarshalOrPanic(cauthdsl.AcceptAllPolicy),
   196  			},
   197  			ModPolicy: OrdererAdminsPolicy,
   198  		}
   199  
   200  		bs.consortiumsGroups = append(bs.consortiumsGroups, tcg)
   201  
   202  		for consortiumName, consortium := range conf.Consortiums {
   203  			cg := config.TemplateConsortiumChannelCreationPolicy(consortiumName, policies.ImplicitMetaPolicyWithSubPolicy(
   204  				configvaluesmsp.AdminsPolicyKey,
   205  				cb.ImplicitMetaPolicy_ANY,
   206  			).Policy)
   207  
   208  			cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].ModPolicy = OrdererAdminsPolicy
   209  			cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].Values[config.ChannelCreationPolicyKey].ModPolicy = OrdererAdminsPolicy
   210  			bs.consortiumsGroups = append(bs.consortiumsGroups, cg)
   211  
   212  			for _, org := range consortium.Organizations {
   213  				mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
   214  				if err != nil {
   215  					logger.Panicf("3 - Error loading MSP configuration for org %s: %s", org.Name, err)
   216  				}
   217  				bs.consortiumsGroups = append(bs.consortiumsGroups,
   218  					configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal(
   219  						[]string{config.ConsortiumsGroupKey, consortiumName, org.Name},
   220  						mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   221  					),
   222  				)
   223  			}
   224  		}
   225  	}
   226  
   227  	return bs
   228  }
   229  
   230  // ChannelTemplate TODO
   231  func (bs *bootstrapper) ChannelTemplate() configtx.Template {
   232  	return configtx.NewModPolicySettingTemplate(
   233  		configvaluesmsp.AdminsPolicyKey,
   234  		configtx.NewCompositeTemplate(
   235  			configtx.NewSimpleTemplate(bs.channelGroups...),
   236  			configtx.NewSimpleTemplate(bs.ordererGroups...),
   237  			configtx.NewSimpleTemplate(bs.applicationGroups...),
   238  		),
   239  	)
   240  }
   241  
   242  // GenesisBlock TODO Deprecate and remove
   243  func (bs *bootstrapper) GenesisBlock() *cb.Block {
   244  	block, err := genesis.NewFactoryImpl(
   245  		configtx.NewModPolicySettingTemplate(
   246  			configvaluesmsp.AdminsPolicyKey,
   247  			configtx.NewCompositeTemplate(
   248  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   249  				bs.ChannelTemplate(),
   250  			),
   251  		),
   252  	).Block(TestChainID)
   253  
   254  	if err != nil {
   255  		panic(err)
   256  	}
   257  	return block
   258  }
   259  
   260  // GenesisBlockForChannel TODO
   261  func (bs *bootstrapper) GenesisBlockForChannel(channelID string) *cb.Block {
   262  	block, err := genesis.NewFactoryImpl(
   263  		configtx.NewModPolicySettingTemplate(
   264  			configvaluesmsp.AdminsPolicyKey,
   265  			configtx.NewCompositeTemplate(
   266  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   267  				bs.ChannelTemplate(),
   268  			),
   269  		),
   270  	).Block(channelID)
   271  
   272  	if err != nil {
   273  		panic(err)
   274  	}
   275  	return block
   276  }