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 }