github.com/ewagmig/fabric@v2.1.1+incompatible/common/channelconfig/util.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package channelconfig 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "math" 13 14 "github.com/golang/protobuf/proto" 15 cb "github.com/hyperledger/fabric-protos-go/common" 16 mspprotos "github.com/hyperledger/fabric-protos-go/msp" 17 ab "github.com/hyperledger/fabric-protos-go/orderer" 18 "github.com/hyperledger/fabric-protos-go/orderer/etcdraft" 19 pb "github.com/hyperledger/fabric-protos-go/peer" 20 "github.com/hyperledger/fabric/bccsp" 21 "github.com/hyperledger/fabric/protoutil" 22 "github.com/pkg/errors" 23 ) 24 25 const ( 26 // ReadersPolicyKey is the key used for the read policy 27 ReadersPolicyKey = "Readers" 28 29 // WritersPolicyKey is the key used for the read policy 30 WritersPolicyKey = "Writers" 31 32 // AdminsPolicyKey is the key used for the read policy 33 AdminsPolicyKey = "Admins" 34 35 defaultHashingAlgorithm = bccsp.SHA256 36 37 defaultBlockDataHashingStructureWidth = math.MaxUint32 38 ) 39 40 // ConfigValue defines a common representation for different *cb.ConfigValue values. 41 type ConfigValue interface { 42 // Key is the key this value should be stored in the *cb.ConfigGroup.Values map. 43 Key() string 44 45 // Value is the message which should be marshaled to opaque bytes for the *cb.ConfigValue.value. 46 Value() proto.Message 47 } 48 49 // StandardConfigValue implements the ConfigValue interface. 50 type StandardConfigValue struct { 51 key string 52 value proto.Message 53 } 54 55 // Key is the key this value should be stored in the *cb.ConfigGroup.Values map. 56 func (scv *StandardConfigValue) Key() string { 57 return scv.key 58 } 59 60 // Value is the message which should be marshaled to opaque bytes for the *cb.ConfigValue.value. 61 func (scv *StandardConfigValue) Value() proto.Message { 62 return scv.value 63 } 64 65 // ConsortiumValue returns the config definition for the consortium name. 66 // It is a value for the channel group. 67 func ConsortiumValue(name string) *StandardConfigValue { 68 return &StandardConfigValue{ 69 key: ConsortiumKey, 70 value: &cb.Consortium{ 71 Name: name, 72 }, 73 } 74 } 75 76 // HashingAlgorithm returns the only currently valid hashing algorithm. 77 // It is a value for the /Channel group. 78 func HashingAlgorithmValue() *StandardConfigValue { 79 return &StandardConfigValue{ 80 key: HashingAlgorithmKey, 81 value: &cb.HashingAlgorithm{ 82 Name: defaultHashingAlgorithm, 83 }, 84 } 85 } 86 87 // BlockDataHashingStructureValue returns the only currently valid block data hashing structure. 88 // It is a value for the /Channel group. 89 func BlockDataHashingStructureValue() *StandardConfigValue { 90 return &StandardConfigValue{ 91 key: BlockDataHashingStructureKey, 92 value: &cb.BlockDataHashingStructure{ 93 Width: defaultBlockDataHashingStructureWidth, 94 }, 95 } 96 } 97 98 // OrdererAddressesValue returns the a config definition for the orderer addresses. 99 // It is a value for the /Channel group. 100 func OrdererAddressesValue(addresses []string) *StandardConfigValue { 101 return &StandardConfigValue{ 102 key: OrdererAddressesKey, 103 value: &cb.OrdererAddresses{ 104 Addresses: addresses, 105 }, 106 } 107 } 108 109 // ConsensusTypeValue returns the config definition for the orderer consensus type. 110 // It is a value for the /Channel/Orderer group. 111 func ConsensusTypeValue(consensusType string, consensusMetadata []byte) *StandardConfigValue { 112 return &StandardConfigValue{ 113 key: ConsensusTypeKey, 114 value: &ab.ConsensusType{ 115 Type: consensusType, 116 Metadata: consensusMetadata, 117 }, 118 } 119 } 120 121 // BatchSizeValue returns the config definition for the orderer batch size. 122 // It is a value for the /Channel/Orderer group. 123 func BatchSizeValue(maxMessages, absoluteMaxBytes, preferredMaxBytes uint32) *StandardConfigValue { 124 return &StandardConfigValue{ 125 key: BatchSizeKey, 126 value: &ab.BatchSize{ 127 MaxMessageCount: maxMessages, 128 AbsoluteMaxBytes: absoluteMaxBytes, 129 PreferredMaxBytes: preferredMaxBytes, 130 }, 131 } 132 } 133 134 // BatchTimeoutValue returns the config definition for the orderer batch timeout. 135 // It is a value for the /Channel/Orderer group. 136 func BatchTimeoutValue(timeout string) *StandardConfigValue { 137 return &StandardConfigValue{ 138 key: BatchTimeoutKey, 139 value: &ab.BatchTimeout{ 140 Timeout: timeout, 141 }, 142 } 143 } 144 145 // ChannelRestrictionsValue returns the config definition for the orderer channel restrictions. 146 // It is a value for the /Channel/Orderer group. 147 func ChannelRestrictionsValue(maxChannelCount uint64) *StandardConfigValue { 148 return &StandardConfigValue{ 149 key: ChannelRestrictionsKey, 150 value: &ab.ChannelRestrictions{ 151 MaxCount: maxChannelCount, 152 }, 153 } 154 } 155 156 // KafkaBrokersValue returns the config definition for the addresses of the ordering service's Kafka brokers. 157 // It is a value for the /Channel/Orderer group. 158 func KafkaBrokersValue(brokers []string) *StandardConfigValue { 159 return &StandardConfigValue{ 160 key: KafkaBrokersKey, 161 value: &ab.KafkaBrokers{ 162 Brokers: brokers, 163 }, 164 } 165 } 166 167 // MSPValue returns the config definition for an MSP. 168 // It is a value for the /Channel/Orderer/*, /Channel/Application/*, and /Channel/Consortiums/*/*/* groups. 169 func MSPValue(mspDef *mspprotos.MSPConfig) *StandardConfigValue { 170 return &StandardConfigValue{ 171 key: MSPKey, 172 value: mspDef, 173 } 174 } 175 176 // CapabilitiesValue returns the config definition for a a set of capabilities. 177 // It is a value for the /Channel/Orderer, Channel/Application/, and /Channel groups. 178 func CapabilitiesValue(capabilities map[string]bool) *StandardConfigValue { 179 c := &cb.Capabilities{ 180 Capabilities: make(map[string]*cb.Capability), 181 } 182 183 for capability, required := range capabilities { 184 if !required { 185 continue 186 } 187 c.Capabilities[capability] = &cb.Capability{} 188 } 189 190 return &StandardConfigValue{ 191 key: CapabilitiesKey, 192 value: c, 193 } 194 } 195 196 // EndpointsValue returns the config definition for the orderer addresses at an org scoped level. 197 // It is a value for the /Channel/Orderer/<OrgName> group. 198 func EndpointsValue(addresses []string) *StandardConfigValue { 199 return &StandardConfigValue{ 200 key: EndpointsKey, 201 value: &cb.OrdererAddresses{ 202 Addresses: addresses, 203 }, 204 } 205 } 206 207 // AnchorPeersValue returns the config definition for an org's anchor peers. 208 // It is a value for the /Channel/Application/*. 209 func AnchorPeersValue(anchorPeers []*pb.AnchorPeer) *StandardConfigValue { 210 return &StandardConfigValue{ 211 key: AnchorPeersKey, 212 value: &pb.AnchorPeers{AnchorPeers: anchorPeers}, 213 } 214 } 215 216 // ChannelCreationPolicyValue returns the config definition for a consortium's channel creation policy 217 // It is a value for the /Channel/Consortiums/*/*. 218 func ChannelCreationPolicyValue(policy *cb.Policy) *StandardConfigValue { 219 return &StandardConfigValue{ 220 key: ChannelCreationPolicyKey, 221 value: policy, 222 } 223 } 224 225 // ACLValues returns the config definition for an applications resources based ACL definitions. 226 // It is a value for the /Channel/Application/. 227 func ACLValues(acls map[string]string) *StandardConfigValue { 228 a := &pb.ACLs{ 229 Acls: make(map[string]*pb.APIResource), 230 } 231 232 for apiResource, policyRef := range acls { 233 a.Acls[apiResource] = &pb.APIResource{PolicyRef: policyRef} 234 } 235 236 return &StandardConfigValue{ 237 key: ACLsKey, 238 value: a, 239 } 240 } 241 242 // ValidateCapabilities validates whether the peer can meet the capabilities requirement in the given config block 243 func ValidateCapabilities(block *cb.Block, bccsp bccsp.BCCSP) error { 244 envelopeConfig, err := protoutil.ExtractEnvelope(block, 0) 245 if err != nil { 246 return errors.Errorf("failed to %s", err) 247 } 248 249 configEnv := &cb.ConfigEnvelope{} 250 _, err = protoutil.UnmarshalEnvelopeOfType(envelopeConfig, cb.HeaderType_CONFIG, configEnv) 251 if err != nil { 252 return errors.Errorf("malformed configuration envelope: %s", err) 253 } 254 255 if configEnv.Config == nil { 256 return errors.New("nil config envelope Config") 257 } 258 259 if configEnv.Config.ChannelGroup == nil { 260 return errors.New("no channel configuration was found in the config block") 261 } 262 263 if configEnv.Config.ChannelGroup.Groups == nil { 264 return errors.New("no channel configuration groups are available") 265 } 266 267 _, exists := configEnv.Config.ChannelGroup.Groups[ApplicationGroupKey] 268 if !exists { 269 return errors.Errorf("invalid configuration block, missing %s "+ 270 "configuration group", ApplicationGroupKey) 271 } 272 273 cc, err := NewChannelConfig(configEnv.Config.ChannelGroup, bccsp) 274 if err != nil { 275 return errors.Errorf("no valid channel configuration found due to %s", err) 276 } 277 278 // Check the channel top-level capabilities 279 if err := cc.Capabilities().Supported(); err != nil { 280 return err 281 } 282 283 // Check the application capabilities 284 if err := cc.ApplicationConfig().Capabilities().Supported(); err != nil { 285 return err 286 } 287 288 return nil 289 } 290 291 // MarshalEtcdRaftMetadata serializes etcd RAFT metadata. 292 func MarshalEtcdRaftMetadata(md *etcdraft.ConfigMetadata) ([]byte, error) { 293 copyMd := proto.Clone(md).(*etcdraft.ConfigMetadata) 294 for _, c := range copyMd.Consenters { 295 // Expect the user to set the config value for client/server certs to the 296 // path where they are persisted locally, then load these files to memory. 297 clientCert, err := ioutil.ReadFile(string(c.GetClientTlsCert())) 298 if err != nil { 299 return nil, fmt.Errorf("cannot load client cert for consenter %s:%d: %s", c.GetHost(), c.GetPort(), err) 300 } 301 c.ClientTlsCert = clientCert 302 303 serverCert, err := ioutil.ReadFile(string(c.GetServerTlsCert())) 304 if err != nil { 305 return nil, fmt.Errorf("cannot load server cert for consenter %s:%d: %s", c.GetHost(), c.GetPort(), err) 306 } 307 c.ServerTlsCert = serverCert 308 } 309 return proto.Marshal(copyMd) 310 }