github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/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/config"
    23  	configvaluesmsp "github.com/hyperledger/fabric/common/config/msp"
    24  	"github.com/hyperledger/fabric/common/configtx"
    25  	genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
    26  	"github.com/hyperledger/fabric/common/flogging"
    27  	"github.com/hyperledger/fabric/common/genesis"
    28  	"github.com/hyperledger/fabric/common/policies"
    29  	"github.com/hyperledger/fabric/msp"
    30  	"github.com/hyperledger/fabric/orderer/common/bootstrap"
    31  	cb "github.com/hyperledger/fabric/protos/common"
    32  	ab "github.com/hyperledger/fabric/protos/orderer"
    33  	pb "github.com/hyperledger/fabric/protos/peer"
    34  	logging "github.com/op/go-logging"
    35  )
    36  
    37  const (
    38  	pkgLogID = "common/configtx/tool/provisional"
    39  )
    40  
    41  var (
    42  	logger *logging.Logger
    43  )
    44  
    45  func init() {
    46  	logger = flogging.MustGetLogger(pkgLogID)
    47  	flogging.SetModuleLevel(pkgLogID, "info")
    48  }
    49  
    50  // Generator can either create an orderer genesis block or config template
    51  type Generator interface {
    52  	bootstrap.Helper
    53  
    54  	// ChannelTemplate returns a template which can be used to help initialize a channel
    55  	ChannelTemplate() configtx.Template
    56  
    57  	// GenesisBlockForChannel TODO
    58  	GenesisBlockForChannel(channelID string) *cb.Block
    59  }
    60  
    61  const (
    62  	// ConsensusTypeSolo identifies the solo consensus implementation.
    63  	ConsensusTypeSolo = "solo"
    64  	// ConsensusTypeKafka identifies the Kafka-based consensus implementation.
    65  	ConsensusTypeKafka = "kafka"
    66  	// ConsensusTypeSbft identifies the SBFT consensus implementation.
    67  	ConsensusTypeSbft = "sbft"
    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  
    79  type bootstrapper struct {
    80  	channelGroups     []*cb.ConfigGroup
    81  	ordererGroups     []*cb.ConfigGroup
    82  	applicationGroups []*cb.ConfigGroup
    83  	consortiumsGroups []*cb.ConfigGroup
    84  }
    85  
    86  // New returns a new provisional bootstrap helper.
    87  func New(conf *genesisconfig.Profile) Generator {
    88  	bs := &bootstrapper{
    89  		channelGroups: []*cb.ConfigGroup{
    90  			// Chain Config Types
    91  			config.DefaultHashingAlgorithm(),
    92  			config.DefaultBlockDataHashingStructure(),
    93  			config.TemplateOrdererAddresses(conf.Orderer.Addresses), // TODO, move to conf.Channel when it exists
    94  
    95  			// Default policies
    96  			policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.ReadersPolicyKey),
    97  			policies.TemplateImplicitMetaAnyPolicy([]string{}, configvaluesmsp.WritersPolicyKey),
    98  			policies.TemplateImplicitMetaMajorityPolicy([]string{}, configvaluesmsp.AdminsPolicyKey),
    99  		},
   100  	}
   101  
   102  	if conf.Orderer != nil {
   103  		bs.ordererGroups = []*cb.ConfigGroup{
   104  			// Orderer Config Types
   105  			config.TemplateConsensusType(conf.Orderer.OrdererType),
   106  			config.TemplateBatchSize(&ab.BatchSize{
   107  				MaxMessageCount:   conf.Orderer.BatchSize.MaxMessageCount,
   108  				AbsoluteMaxBytes:  conf.Orderer.BatchSize.AbsoluteMaxBytes,
   109  				PreferredMaxBytes: conf.Orderer.BatchSize.PreferredMaxBytes,
   110  			}),
   111  			config.TemplateBatchTimeout(conf.Orderer.BatchTimeout.String()),
   112  			config.TemplateChannelRestrictions(conf.Orderer.MaxChannels),
   113  
   114  			// Initialize the default Reader/Writer/Admins orderer policies, as well as block validation policy
   115  			policies.TemplateImplicitMetaPolicyWithSubPolicy([]string{config.OrdererGroupKey}, BlockValidationPolicyKey, configvaluesmsp.WritersPolicyKey, cb.ImplicitMetaPolicy_ANY),
   116  			policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.ReadersPolicyKey),
   117  			policies.TemplateImplicitMetaAnyPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.WritersPolicyKey),
   118  			policies.TemplateImplicitMetaMajorityPolicy([]string{config.OrdererGroupKey}, configvaluesmsp.AdminsPolicyKey),
   119  		}
   120  
   121  		for _, org := range conf.Orderer.Organizations {
   122  			mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.BCCSP, org.ID)
   123  			if err != nil {
   124  				logger.Panicf("1 - Error loading MSP configuration for org %s: %s", org.Name, err)
   125  			}
   126  			bs.ordererGroups = append(bs.ordererGroups,
   127  				configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal([]string{config.OrdererGroupKey, org.Name},
   128  					mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   129  				),
   130  			)
   131  		}
   132  
   133  		switch conf.Orderer.OrdererType {
   134  		case ConsensusTypeSolo, ConsensusTypeSbft:
   135  		case ConsensusTypeKafka:
   136  			bs.ordererGroups = append(bs.ordererGroups, config.TemplateKafkaBrokers(conf.Orderer.Kafka.Brokers))
   137  		default:
   138  			panic(fmt.Errorf("Wrong consenter type value given: %s", conf.Orderer.OrdererType))
   139  		}
   140  	}
   141  
   142  	if conf.Application != nil {
   143  
   144  		bs.applicationGroups = []*cb.ConfigGroup{
   145  			// Initialize the default Reader/Writer/Admins application policies
   146  			policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.ReadersPolicyKey),
   147  			policies.TemplateImplicitMetaAnyPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.WritersPolicyKey),
   148  			policies.TemplateImplicitMetaMajorityPolicy([]string{config.ApplicationGroupKey}, configvaluesmsp.AdminsPolicyKey),
   149  		}
   150  		for _, org := range conf.Application.Organizations {
   151  			mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.BCCSP, org.ID)
   152  			if err != nil {
   153  				logger.Panicf("2- Error loading MSP configuration for org %s: %s", org.Name, err)
   154  			}
   155  
   156  			bs.applicationGroups = append(bs.applicationGroups,
   157  				configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal([]string{config.ApplicationGroupKey, org.Name},
   158  					mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   159  				),
   160  			)
   161  			var anchorProtos []*pb.AnchorPeer
   162  			for _, anchorPeer := range org.AnchorPeers {
   163  				anchorProtos = append(anchorProtos, &pb.AnchorPeer{
   164  					Host: anchorPeer.Host,
   165  					Port: int32(anchorPeer.Port),
   166  				})
   167  			}
   168  
   169  			bs.applicationGroups = append(bs.applicationGroups, config.TemplateAnchorPeers(org.Name, anchorProtos))
   170  		}
   171  
   172  	}
   173  
   174  	if conf.Consortiums != nil {
   175  		bs.consortiumsGroups = append(bs.consortiumsGroups, config.TemplateConsortiumsGroup())
   176  		for consortiumName, consortium := range conf.Consortiums {
   177  			bs.consortiumsGroups = append(
   178  				bs.consortiumsGroups,
   179  				config.TemplateConsortiumChannelCreationPolicy(consortiumName, policies.ImplicitMetaPolicyWithSubPolicy(
   180  					configvaluesmsp.AdminsPolicyKey,
   181  					cb.ImplicitMetaPolicy_ANY,
   182  				).Policy),
   183  			)
   184  
   185  			for _, org := range consortium.Organizations {
   186  				mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.BCCSP, org.ID)
   187  				if err != nil {
   188  					logger.Panicf("3 - Error loading MSP configuration for org %s: %s", org.Name, err)
   189  				}
   190  				bs.consortiumsGroups = append(bs.consortiumsGroups,
   191  					configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal(
   192  						[]string{config.ConsortiumsGroupKey, consortiumName, org.Name},
   193  						mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   194  					),
   195  				)
   196  			}
   197  		}
   198  	}
   199  
   200  	return bs
   201  }
   202  
   203  // ChannelTemplate TODO
   204  func (bs *bootstrapper) ChannelTemplate() configtx.Template {
   205  	return configtx.NewModPolicySettingTemplate(
   206  		configvaluesmsp.AdminsPolicyKey,
   207  		configtx.NewCompositeTemplate(
   208  			configtx.NewSimpleTemplate(bs.channelGroups...),
   209  			configtx.NewSimpleTemplate(bs.ordererGroups...),
   210  			configtx.NewSimpleTemplate(bs.applicationGroups...),
   211  		),
   212  	)
   213  }
   214  
   215  // GenesisBlock TODO Deprecate and remove
   216  func (bs *bootstrapper) GenesisBlock() *cb.Block {
   217  	block, err := genesis.NewFactoryImpl(
   218  		configtx.NewModPolicySettingTemplate(
   219  			configvaluesmsp.AdminsPolicyKey,
   220  			configtx.NewCompositeTemplate(
   221  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   222  				bs.ChannelTemplate(),
   223  			),
   224  		),
   225  	).Block(TestChainID)
   226  
   227  	if err != nil {
   228  		panic(err)
   229  	}
   230  	return block
   231  }
   232  
   233  // GenesisBlockForChannel TODO
   234  func (bs *bootstrapper) GenesisBlockForChannel(channelID string) *cb.Block {
   235  	block, err := genesis.NewFactoryImpl(
   236  		configtx.NewModPolicySettingTemplate(
   237  			configvaluesmsp.AdminsPolicyKey,
   238  			configtx.NewCompositeTemplate(
   239  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   240  				bs.ChannelTemplate(),
   241  			),
   242  		),
   243  	).Block(channelID)
   244  
   245  	if err != nil {
   246  		panic(err)
   247  	}
   248  	return block
   249  }