github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/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/inklabsfoundation/inkchain/common/cauthdsl"
    23  	"github.com/inklabsfoundation/inkchain/common/config"
    24  	configvaluesmsp "github.com/inklabsfoundation/inkchain/common/config/msp"
    25  	"github.com/inklabsfoundation/inkchain/common/configtx"
    26  	genesisconfig "github.com/inklabsfoundation/inkchain/common/configtx/tool/localconfig"
    27  	"github.com/inklabsfoundation/inkchain/common/flogging"
    28  	"github.com/inklabsfoundation/inkchain/common/genesis"
    29  	"github.com/inklabsfoundation/inkchain/common/policies"
    30  	"github.com/inklabsfoundation/inkchain/msp"
    31  	"github.com/inklabsfoundation/inkchain/orderer/common/bootstrap"
    32  	cb "github.com/inklabsfoundation/inkchain/protos/common"
    33  	ab "github.com/inklabsfoundation/inkchain/protos/orderer"
    34  	pb "github.com/inklabsfoundation/inkchain/protos/peer"
    35  	"github.com/inklabsfoundation/inkchain/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  		// Note, AcceptAllPolicy in this context, does not grant any unrestricted
   187  		// access, but allows the /Channel/Admins policy to evaluate to true
   188  		// for the ordering system channel while set to MAJORITY with the addition
   189  		// to the successful evaluation of the /Channel/Orderer/Admins policy (which
   190  		// is not AcceptAll
   191  		tcg.Groups[config.ConsortiumsGroupKey].Policies[configvaluesmsp.AdminsPolicyKey] = &cb.ConfigPolicy{
   192  			Policy: &cb.Policy{
   193  				Type:  int32(cb.Policy_SIGNATURE),
   194  				Value: utils.MarshalOrPanic(cauthdsl.AcceptAllPolicy),
   195  			},
   196  		}
   197  
   198  		bs.consortiumsGroups = append(bs.consortiumsGroups, tcg)
   199  
   200  		for consortiumName, consortium := range conf.Consortiums {
   201  			cg := config.TemplateConsortiumChannelCreationPolicy(consortiumName, policies.ImplicitMetaPolicyWithSubPolicy(
   202  				configvaluesmsp.AdminsPolicyKey,
   203  				cb.ImplicitMetaPolicy_ANY,
   204  			).Policy)
   205  
   206  			cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].ModPolicy = OrdererAdminsPolicy
   207  			cg.Groups[config.ConsortiumsGroupKey].Groups[consortiumName].Values[config.ChannelCreationPolicyKey].ModPolicy = OrdererAdminsPolicy
   208  			bs.consortiumsGroups = append(bs.consortiumsGroups, cg)
   209  
   210  			for _, org := range consortium.Organizations {
   211  				mspConfig, err := msp.GetVerifyingMspConfig(org.MSPDir, org.ID)
   212  				if err != nil {
   213  					logger.Panicf("3 - Error loading MSP configuration for org %s: %s", org.Name, err)
   214  				}
   215  				bs.consortiumsGroups = append(bs.consortiumsGroups,
   216  					configvaluesmsp.TemplateGroupMSPWithAdminRolePrincipal(
   217  						[]string{config.ConsortiumsGroupKey, consortiumName, org.Name},
   218  						mspConfig, org.AdminPrincipal == genesisconfig.AdminRoleAdminPrincipal,
   219  					),
   220  				)
   221  			}
   222  		}
   223  	}
   224  
   225  	return bs
   226  }
   227  
   228  // ChannelTemplate TODO
   229  func (bs *bootstrapper) ChannelTemplate() configtx.Template {
   230  	return configtx.NewModPolicySettingTemplate(
   231  		configvaluesmsp.AdminsPolicyKey,
   232  		configtx.NewCompositeTemplate(
   233  			configtx.NewSimpleTemplate(bs.channelGroups...),
   234  			configtx.NewSimpleTemplate(bs.ordererGroups...),
   235  			configtx.NewSimpleTemplate(bs.applicationGroups...),
   236  		),
   237  	)
   238  }
   239  
   240  // GenesisBlock TODO Deprecate and remove
   241  func (bs *bootstrapper) GenesisBlock() *cb.Block {
   242  	block, err := genesis.NewFactoryImpl(
   243  		configtx.NewModPolicySettingTemplate(
   244  			configvaluesmsp.AdminsPolicyKey,
   245  			configtx.NewCompositeTemplate(
   246  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   247  				bs.ChannelTemplate(),
   248  			),
   249  		),
   250  	).Block(TestChainID)
   251  
   252  	if err != nil {
   253  		panic(err)
   254  	}
   255  	return block
   256  }
   257  
   258  // GenesisBlockForChannel TODO
   259  func (bs *bootstrapper) GenesisBlockForChannel(channelID string) *cb.Block {
   260  	block, err := genesis.NewFactoryImpl(
   261  		configtx.NewModPolicySettingTemplate(
   262  			configvaluesmsp.AdminsPolicyKey,
   263  			configtx.NewCompositeTemplate(
   264  				configtx.NewSimpleTemplate(bs.consortiumsGroups...),
   265  				bs.ChannelTemplate(),
   266  			),
   267  		),
   268  	).Block(channelID)
   269  
   270  	if err != nil {
   271  		panic(err)
   272  	}
   273  	return block
   274  }