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

     1  /*
     2  Copyright IBM Corp. 2017 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 msp
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"sync"
    23  
    24  	"github.com/hyperledger/fabric/msp"
    25  	mspprotos "github.com/hyperledger/fabric/protos/msp"
    26  )
    27  
    28  type pendingMSPConfig struct {
    29  	mspConfig *mspprotos.MSPConfig
    30  	msp       msp.MSP
    31  }
    32  
    33  type mspConfigStore struct {
    34  	idMap       map[string]*pendingMSPConfig
    35  	proposedMgr msp.MSPManager
    36  }
    37  
    38  // MSPConfigHandler
    39  type MSPConfigHandler struct {
    40  	pendingConfig map[interface{}]*mspConfigStore
    41  	pendingLock   sync.RWMutex
    42  	msp.MSPManager
    43  }
    44  
    45  func NewMSPConfigHandler() *MSPConfigHandler {
    46  	return &MSPConfigHandler{
    47  		pendingConfig: make(map[interface{}]*mspConfigStore),
    48  	}
    49  }
    50  
    51  // BeginConfig called when a config proposal is begun
    52  func (bh *MSPConfigHandler) BeginConfig(tx interface{}) {
    53  	bh.pendingLock.Lock()
    54  	defer bh.pendingLock.Unlock()
    55  	_, ok := bh.pendingConfig[tx]
    56  	if ok {
    57  		panic("Programming error, called BeginConfig multiply for the same tx")
    58  	}
    59  	bh.pendingConfig[tx] = &mspConfigStore{
    60  		idMap: make(map[string]*pendingMSPConfig),
    61  	}
    62  }
    63  
    64  // RollbackProposals called when a config proposal is abandoned
    65  func (bh *MSPConfigHandler) RollbackProposals(tx interface{}) {
    66  	bh.pendingLock.Lock()
    67  	defer bh.pendingLock.Unlock()
    68  	delete(bh.pendingConfig, tx)
    69  }
    70  
    71  // CommitProposals called when a config proposal is committed
    72  func (bh *MSPConfigHandler) CommitProposals(tx interface{}) {
    73  	bh.pendingLock.Lock()
    74  	defer bh.pendingLock.Unlock()
    75  	pendingConfig, ok := bh.pendingConfig[tx]
    76  	if !ok {
    77  		panic("Programming error, called BeginConfig multiply for the same tx")
    78  	}
    79  
    80  	bh.MSPManager = pendingConfig.proposedMgr
    81  	delete(bh.pendingConfig, tx)
    82  }
    83  
    84  // ProposeValue called when config is added to a proposal
    85  func (bh *MSPConfigHandler) ProposeMSP(tx interface{}, mspConfig *mspprotos.MSPConfig) (msp.MSP, error) {
    86  	bh.pendingLock.RLock()
    87  	pendingConfig, ok := bh.pendingConfig[tx]
    88  	bh.pendingLock.RUnlock()
    89  	if !ok {
    90  		panic("Programming error, called BeginConfig multiply for the same tx")
    91  	}
    92  
    93  	// check that the type for that MSP is supported
    94  	if mspConfig.Type != int32(msp.FABRIC) {
    95  		return nil, fmt.Errorf("Setup error: unsupported msp type %d", mspConfig.Type)
    96  	}
    97  
    98  	// create the msp instance
    99  	mspInst, err := msp.NewBccspMsp()
   100  	if err != nil {
   101  		return nil, fmt.Errorf("Creating the MSP manager failed, err %s", err)
   102  	}
   103  
   104  	// set it up
   105  	err = mspInst.Setup(mspConfig)
   106  	if err != nil {
   107  		return nil, fmt.Errorf("Setting up the MSP manager failed, err %s", err)
   108  	}
   109  
   110  	// add the MSP to the map of pending MSPs
   111  	mspID, _ := mspInst.GetIdentifier()
   112  
   113  	existingPendingMSPConfig, ok := pendingConfig.idMap[mspID]
   114  	if ok && !reflect.DeepEqual(existingPendingMSPConfig.mspConfig, mspConfig) {
   115  		return nil, fmt.Errorf("Attempted to define two different versions of MSP: %s", mspID)
   116  	}
   117  
   118  	pendingConfig.idMap[mspID] = &pendingMSPConfig{
   119  		mspConfig: mspConfig,
   120  		msp:       mspInst,
   121  	}
   122  
   123  	return mspInst, nil
   124  }
   125  
   126  // PreCommit instantiates the MSP manager
   127  func (bh *MSPConfigHandler) PreCommit(tx interface{}) error {
   128  	bh.pendingLock.RLock()
   129  	pendingConfig, ok := bh.pendingConfig[tx]
   130  	bh.pendingLock.RUnlock()
   131  	if !ok {
   132  		panic("Programming error, called PreCommit for tx which was not started")
   133  	}
   134  
   135  	if len(pendingConfig.idMap) == 0 {
   136  		// Cannot instantiate an MSP manager with no MSPs
   137  		return nil
   138  	}
   139  
   140  	mspList := make([]msp.MSP, len(pendingConfig.idMap))
   141  	i := 0
   142  	for _, pendingMSP := range pendingConfig.idMap {
   143  		mspList[i] = pendingMSP.msp
   144  		i++
   145  	}
   146  
   147  	pendingConfig.proposedMgr = msp.NewMSPManager()
   148  	err := pendingConfig.proposedMgr.Setup(mspList)
   149  	return err
   150  }