Skip to content

Commit 0ebdc77

Browse files
committed
Introduce LoadConfigBlockMaterial
Signed-off-by: Liran Funaro <liran.funaro@gmail.com>
1 parent 12a17e4 commit 0ebdc77

File tree

6 files changed

+578
-113
lines changed

6 files changed

+578
-113
lines changed

common/channelconfig/load.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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+
"github.com/cockroachdb/errors"
11+
"github.com/hyperledger/fabric-lib-go/bccsp/factory"
12+
"github.com/hyperledger/fabric-protos-go-apiv2/common"
13+
14+
commontypes "github.com/hyperledger/fabric-x-common/api/types"
15+
"github.com/hyperledger/fabric-x-common/common/configtx"
16+
"github.com/hyperledger/fabric-x-common/protoutil"
17+
)
18+
19+
type (
20+
// ConfigBlockMaterial contains the channel-ID, the config block, its bundle, and the organization's material.
21+
ConfigBlockMaterial struct {
22+
ChannelID string
23+
ConfigBlock *common.Block
24+
Bundle *Bundle
25+
OrdererOrganizations []*OrdererOrganizationMaterial
26+
ApplicationOrganizations []*OrganizationMaterial
27+
}
28+
29+
// OrganizationMaterial contains the MspID (Organization ID), and its root CAs in bytes.
30+
OrganizationMaterial struct {
31+
MspID string
32+
CACerts [][]byte
33+
}
34+
35+
// OrdererOrganizationMaterial contains the MspID (Organization ID), orderer endpoints, and their root CAs in bytes.
36+
OrdererOrganizationMaterial struct {
37+
OrganizationMaterial
38+
Endpoints []*commontypes.OrdererEndpoint
39+
}
40+
)
41+
42+
// ErrNotConfigBlock is returned when the block is not a config block.
43+
var ErrNotConfigBlock = errors.New("the block is not a config block")
44+
45+
// LoadConfigBlockMaterialFromFile loads a config block from a file.
46+
// If the block is not a config block, ErrNotConfigBlock will be returned.
47+
func LoadConfigBlockMaterialFromFile(blockPath string) (*ConfigBlockMaterial, error) {
48+
if blockPath == "" {
49+
return nil, errors.New("config block path is empty")
50+
}
51+
configBlock, err := protoutil.ReadBlockFromFile(blockPath)
52+
if err != nil {
53+
return nil, err
54+
}
55+
return LoadConfigBlockMaterial(configBlock)
56+
}
57+
58+
// LoadConfigBlockMaterial attempts to read a config block from the given block.
59+
// If the block is not a config block, ErrNotConfigBlock will be returned.
60+
func LoadConfigBlockMaterial(block *common.Block) (*ConfigBlockMaterial, error) {
61+
// We expect config blocks to have exactly one transaction, with a valid payload.
62+
if block == nil || block.Data == nil || len(block.Data.Data) != 1 {
63+
return nil, ErrNotConfigBlock
64+
}
65+
configTx, err := protoutil.GetEnvelopeFromBlock(block.Data.Data[0])
66+
if err != nil {
67+
return nil, errors.Join(ErrNotConfigBlock, err)
68+
}
69+
70+
payload, err := protoutil.UnmarshalPayload(configTx.Payload)
71+
if err != nil {
72+
return nil, errors.Join(ErrNotConfigBlock, err)
73+
}
74+
if payload.Header == nil {
75+
return nil, ErrNotConfigBlock
76+
}
77+
chHead, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
78+
if err != nil || chHead.Type != int32(common.HeaderType_CONFIG) {
79+
return nil, errors.Join(ErrNotConfigBlock, err)
80+
}
81+
82+
// This is a config block. Let's parse it.
83+
configEnvelope, err := configtx.UnmarshalConfigEnvelope(payload.Data)
84+
if err != nil {
85+
return nil, errors.Wrap(err, "error unmarshalling config envelope from payload data")
86+
}
87+
88+
bundle, err := NewBundle(chHead.ChannelId, configEnvelope.Config, factory.GetDefault())
89+
if err != nil {
90+
return nil, errors.Wrap(err, "error creating channel config bundle")
91+
}
92+
ordererOrgs, err := newOrdererOrganizationsMaterialsFromBundle(bundle)
93+
if err != nil {
94+
return nil, err
95+
}
96+
applicationOrgs, err := newApplicationOrganizationsMaterialsFromBundle(bundle)
97+
if err != nil {
98+
return nil, err
99+
}
100+
return &ConfigBlockMaterial{
101+
ChannelID: chHead.ChannelId,
102+
ConfigBlock: block,
103+
Bundle: bundle,
104+
OrdererOrganizations: ordererOrgs,
105+
ApplicationOrganizations: applicationOrgs,
106+
}, nil
107+
}
108+
109+
// newOrdererOrganizationsMaterialsFromBundle reads the organizations' materials from a config block bundle.
110+
func newOrdererOrganizationsMaterialsFromBundle(bundle *Bundle) ([]*OrdererOrganizationMaterial, error) {
111+
ordererCfg, ok := bundle.OrdererConfig()
112+
if !ok {
113+
return nil, errors.New("could not find orderer config")
114+
}
115+
orgs := ordererCfg.Organizations()
116+
orgsMaterial := newOrganizationsMaterials(orgs)
117+
118+
ordererOrgMaterial := make([]*OrdererOrganizationMaterial, len(orgsMaterial))
119+
for i, org := range orgsMaterial {
120+
var endpoints []*commontypes.OrdererEndpoint
121+
endpointsStr := orgs[org.MspID].Endpoints()
122+
for _, eStr := range endpointsStr {
123+
e, err := commontypes.ParseOrdererEndpoint(eStr)
124+
if err != nil {
125+
return nil, err
126+
}
127+
e.MspID = org.MspID
128+
endpoints = append(endpoints, e)
129+
}
130+
ordererOrgMaterial[i] = &OrdererOrganizationMaterial{
131+
OrganizationMaterial: *org,
132+
Endpoints: endpoints,
133+
}
134+
}
135+
return ordererOrgMaterial, nil
136+
}
137+
138+
// newApplicationOrganizationsMaterialsFromBundle reads the organizations' materials from a config block bundle.
139+
func newApplicationOrganizationsMaterialsFromBundle(bundle *Bundle) ([]*OrganizationMaterial, error) {
140+
applicationCfg, ok := bundle.ApplicationConfig()
141+
if !ok {
142+
return nil, errors.New("could not find application config")
143+
}
144+
return newOrganizationsMaterials(applicationCfg.Organizations()), nil
145+
}
146+
147+
func newOrganizationsMaterials[T Org](orgs map[string]T) []*OrganizationMaterial {
148+
organizationMaterials := make([]*OrganizationMaterial, 0, len(orgs))
149+
for orgID, org := range orgs {
150+
organizationMaterials = append(organizationMaterials, &OrganizationMaterial{
151+
MspID: orgID,
152+
CACerts: org.MSP().GetTLSRootCerts(),
153+
})
154+
}
155+
return organizationMaterials
156+
}

0 commit comments

Comments
 (0)