github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/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  		}
   198  
   199  		bs.consortiumsGroups = append(bs.consortiumsGroups, tcg)
   200  
   201  		for consortiumName, consortium := range conf.Consortiums {
   202  			cg := config.TemplateConsortiumChannelCreationPolicy(consortiumName, policies.ImplicitMetaPolicyWithSubPolicy(
   203  				configvaluesmsp.AdminsPolicyKey,
   204  				cb.ImplicitMetaPolicy_ANY,
   205  			).Policy)
   206  
   207  			cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].ModPolicy = OrdererAdminsPolicy
   208  			cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].Values[config.ChannelCreationPolicyKey].ModPolicy = OrdererAdminsPolicy
   209  			bs.consortiumsGroups = append(bs.consortiumsGroups, cg)
   210  
   211  			for _, org := range consortium.Organizations {
   212  				mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
   213  				if err != nil {
   214  					logger.Panicf("3 - Error loading MSP configuration for org %s: %s", org.Name, err)
   215  				}
   216  				bs.consortiumsGroups = append(bs.consortiumsGroups,
   217  					configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal(
   218  						[]string{config.ConsortiumsGroupKey, consortiumName, org.Name},
   219  						mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   220  					),
   221  				)
   222  			}
   223  		}
   224  	}
   225  
   226  	return bs
   227  }
   228  
   229  // ChannelTemplate TODO
   230  func (bs *bootstrapper) ChannelTemplate() configtx.Template {
   231  	return configtx.NewModPolicySettingTemplate(
   232  		configvaluesmsp.AdminsPolicyKey,
   233  		configtx.NewCompositeTemplate(
   234  			configtx.NewSimpleTemplate(bs.channelGroups...),
   235  			configtx.NewSimpleTemplate(bs.ordererGroups...),
   236  			configtx.NewSimpleTemplate(bs.applicationGroups...),
   237  		),
   238  	)
   239  }
   240  
   241  // GenesisBlock TODO Deprecate and remove
   242  func (bs *bootstrapper) GenesisBlock() *cb.Block {
   243  	block, err := genesis.NewFactoryImpl(
   244  		configtx.NewModPolicySettingTemplate(
   245  			configvaluesmsp.AdminsPolicyKey,
   246  			configtx.NewCompositeTemplate(
   247  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   248  				bs.ChannelTemplate(),
   249  			),
   250  		),
   251  	).Block(TestChainID)
   252  
   253  	if err != nil {
   254  		panic(err)
   255  	}
   256  	return block
   257  }
   258  
   259  // GenesisBlockForChannel TODO
   260  func (bs *bootstrapper) GenesisBlockForChannel(channelID string) *cb.Block {
   261  	block, err := genesis.NewFactoryImpl(
   262  		configtx.NewModPolicySettingTemplate(
   263  			configvaluesmsp.AdminsPolicyKey,
   264  			configtx.NewCompositeTemplate(
   265  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   266  				bs.ChannelTemplate(),
   267  			),
   268  		),
   269  	).Block(channelID)
   270  
   271  	if err != nil {
   272  		panic(err)
   273  	}
   274  	return block
   275  }