Skip to content

Commit a5e4044

Browse files
fixup! refactor(fabric): remove import of common/channelconfig
Signed-off-by: Marcus Brandenburger <bur@zurich.ibm.com>
1 parent 2224538 commit a5e4044

File tree

10 files changed

+376
-4
lines changed

10 files changed

+376
-4
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
Copyright State Street Corp. 2018 All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package channelconfig
8+
9+
import (
10+
pb "github.com/hyperledger/fabric-protos-go-apiv2/peer"
11+
)
12+
13+
// aclsProvider provides mappings for resource to policy names
14+
type aclsProvider struct {
15+
aclPolicyRefs map[string]string
16+
}
17+
18+
func (ag *aclsProvider) PolicyRefForAPI(aclName string) string {
19+
return ag.aclPolicyRefs[aclName]
20+
}
21+
22+
// this translates policies to absolute paths if needed
23+
func newAPIsProvider(acls map[string]*pb.APIResource) *aclsProvider {
24+
aclPolicyRefs := make(map[string]string)
25+
26+
for key, acl := range acls {
27+
if len(acl.PolicyRef) == 0 {
28+
continue
29+
}
30+
// If the policy is fully qualified, ie to /Channel/Application/Readers leave it alone
31+
// otherwise, make it fully qualified referring to /Channel/Application/policyName
32+
if acl.PolicyRef[0] != '/' {
33+
aclPolicyRefs[key] = "/" + ChannelGroupKey + "/" + ApplicationGroupKey + "/" + acl.PolicyRef
34+
} else {
35+
aclPolicyRefs[key] = acl.PolicyRef
36+
}
37+
}
38+
39+
return &aclsProvider{
40+
aclPolicyRefs: aclPolicyRefs,
41+
}
42+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
Copyright State Street Corp. 2018 All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package channelconfig
8+
9+
import (
10+
"testing"
11+
12+
pb "github.com/hyperledger/fabric-protos-go-apiv2/peer"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
const (
17+
sampleAPI1Name = "Foo"
18+
sampleAPI1PolicyRef = "foo"
19+
20+
sampleAPI2Name = "Bar"
21+
sampleAPI2PolicyRef = "/Channel/foo"
22+
)
23+
24+
var sampleAPIsProvider = map[string]*pb.APIResource{
25+
sampleAPI1Name: {PolicyRef: sampleAPI1PolicyRef},
26+
sampleAPI2Name: {PolicyRef: sampleAPI2PolicyRef},
27+
}
28+
29+
func TestGreenAPIsPath(t *testing.T) {
30+
ag := newAPIsProvider(sampleAPIsProvider)
31+
require.NotNil(t, ag)
32+
33+
t.Run("PresentAPIs", func(t *testing.T) {
34+
require.Equal(t, "/Channel/Application/"+sampleAPI1PolicyRef, ag.PolicyRefForAPI(sampleAPI1Name))
35+
require.Equal(t, sampleAPI2PolicyRef, ag.PolicyRefForAPI(sampleAPI2Name))
36+
})
37+
38+
t.Run("MissingAPIs", func(t *testing.T) {
39+
require.Empty(t, ag.PolicyRefForAPI("missing"))
40+
})
41+
}
42+
43+
func TestNilACLs(t *testing.T) {
44+
ccg := newAPIsProvider(nil)
45+
46+
require.NotNil(t, ccg)
47+
require.NotNil(t, ccg.aclPolicyRefs)
48+
require.Empty(t, ccg.aclPolicyRefs)
49+
}
50+
51+
func TestEmptyACLs(t *testing.T) {
52+
ccg := newAPIsProvider(map[string]*pb.APIResource{})
53+
54+
require.NotNil(t, ccg)
55+
require.NotNil(t, ccg.aclPolicyRefs)
56+
require.Empty(t, ccg.aclPolicyRefs)
57+
}
58+
59+
func TestEmptyPolicyRef(t *testing.T) {
60+
ars := map[string]*pb.APIResource{
61+
"unsetAPI": {PolicyRef: ""},
62+
}
63+
64+
ccg := newAPIsProvider(ars)
65+
66+
require.NotNil(t, ccg)
67+
require.NotNil(t, ccg.aclPolicyRefs)
68+
require.Empty(t, ccg.aclPolicyRefs)
69+
70+
ars = map[string]*pb.APIResource{
71+
"unsetAPI": {PolicyRef: ""},
72+
"setAPI": {PolicyRef: sampleAPI2PolicyRef},
73+
}
74+
75+
ccg = newAPIsProvider(ars)
76+
77+
require.NotNil(t, ccg)
78+
require.NotNil(t, ccg.aclPolicyRefs)
79+
require.NotEmpty(t, ccg.aclPolicyRefs)
80+
require.NotContains(t, ccg.aclPolicyRefs, sampleAPI1Name)
81+
}

platform/fabric/core/generic/membership/channelconfig/application.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package channelconfig
88

99
import (
1010
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
11+
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/membership/channelconfig/capabilities"
1112
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
1213
pb "github.com/hyperledger/fabric-protos-go-apiv2/peer"
1314
)
@@ -58,3 +59,15 @@ func NewApplicationConfig(appGroup *cb.ConfigGroup, mspConfig *MSPConfigHandler)
5859
func (ac *ApplicationConfig) Organizations() map[string]ApplicationOrg {
5960
return ac.applicationOrgs
6061
}
62+
63+
// Capabilities returns a map of capability name to Capability
64+
func (ac *ApplicationConfig) Capabilities() ApplicationCapabilities {
65+
return capabilities.NewApplicationProvider(ac.protos.Capabilities.Capabilities)
66+
}
67+
68+
// APIPolicyMapper returns a PolicyMapper that maps API names to policies
69+
func (ac *ApplicationConfig) APIPolicyMapper() PolicyMapper {
70+
pm := newAPIsProvider(ac.protos.ACLs.Acls)
71+
72+
return pm
73+
}

platform/fabric/core/generic/membership/channelconfig/channel.go

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/membership/channelconfig/capabilities"
1515
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/msp"
1616
"github.com/hyperledger/fabric-lib-go/bccsp"
17+
"github.com/hyperledger/fabric-lib-go/bccsp/factory"
1718
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
1819
)
1920

@@ -43,6 +44,10 @@ const (
4344

4445
// ChannelValues gives read only access to the channel configuration
4546
type ChannelValues interface {
47+
// HashingAlgorithm returns the default algorithm to be used when hashing
48+
// such as computing block hashes, and CreationPolicy digests
49+
HashingAlgorithm() func(input []byte) []byte
50+
4651
// BlockDataHashingStructureWidth returns the width to use when constructing the
4752
// Merkle tree to compute the BlockData hash
4853
BlockDataHashingStructureWidth() uint32
@@ -54,6 +59,7 @@ type ChannelValues interface {
5459

5560
// ChannelProtos is where the proposed configuration is unmarshaled into
5661
type ChannelProtos struct {
62+
HashingAlgorithm *cb.HashingAlgorithm
5763
BlockDataHashingStructure *cb.BlockDataHashingStructure
5864
OrdererAddresses *cb.OrdererAddresses
5965
Orderers *cb.Orderers
@@ -65,10 +71,13 @@ type ChannelProtos struct {
6571
type ChannelConfig struct {
6672
protos *ChannelProtos
6773

74+
hashingAlgorithm func(input []byte) []byte
75+
6876
mspManager msp.MSPManager
6977

70-
appConfig *ApplicationConfig
71-
ordererConfig *OrdererConfig
78+
appConfig *ApplicationConfig
79+
ordererConfig *OrdererConfig
80+
consortiumsConfig *ConsortiumsConfig
7281
}
7382

7483
// NewChannelConfig creates a new ChannelConfig
@@ -96,8 +105,8 @@ func NewChannelConfig(channelGroup *cb.ConfigGroup, bccsp bccsp.BCCSP) (*Channel
96105
cc.appConfig, err = NewApplicationConfig(group, mspConfigHandler)
97106
case OrdererGroupKey:
98107
cc.ordererConfig, err = NewOrdererConfig(group, mspConfigHandler, channelCapabilities)
99-
case "Consortium":
100-
// ignore
108+
case ConsortiumsGroupKey:
109+
cc.consortiumsConfig, err = NewConsortiumsConfig(group, mspConfigHandler)
101110
default:
102111
return nil, fmt.Errorf("disallowed channel group: %s", group)
103112
}
@@ -128,6 +137,16 @@ func (cc *ChannelConfig) ApplicationConfig() *ApplicationConfig {
128137
return cc.appConfig
129138
}
130139

140+
// ConsortiumsConfig returns the consortium config associated with this channel if it exists
141+
func (cc *ChannelConfig) ConsortiumsConfig() *ConsortiumsConfig {
142+
return cc.consortiumsConfig
143+
}
144+
145+
// HashingAlgorithm returns a function pointer to the chain hashing algorithm
146+
func (cc *ChannelConfig) HashingAlgorithm() func(input []byte) []byte {
147+
return cc.hashingAlgorithm
148+
}
149+
131150
// BlockDataHashingStructureWidth returns the width to use when forming the block data hashing structure
132151
func (cc *ChannelConfig) BlockDataHashingStructureWidth() uint32 {
133152
return cc.protos.BlockDataHashingStructure.Width
@@ -154,6 +173,7 @@ func (cc *ChannelConfig) Capabilities() ChannelCapabilities {
154173
// Validate inspects the generated configuration protos and ensures that the values are correct
155174
func (cc *ChannelConfig) Validate(channelCapabilities ChannelCapabilities) error {
156175
for _, validator := range []func() error{
176+
cc.validateHashingAlgorithm,
157177
cc.validateBlockDataHashingStructure,
158178
} {
159179
if err := validator(); err != nil {
@@ -176,6 +196,35 @@ func (cc *ChannelConfig) Validate(channelCapabilities ChannelCapabilities) error
176196
return nil
177197
}
178198

199+
func (cc *ChannelConfig) validateHashingAlgorithm() error {
200+
computeSHA256 := func(data []byte) (hash []byte) {
201+
hash, err := factory.GetDefault().Hash(data, &bccsp.SHA256Opts{})
202+
if err != nil {
203+
panic(errors.Errorf("failed computing SHA3_256 on [% x]", data))
204+
}
205+
return
206+
}
207+
208+
computeSHA3256 := func(data []byte) (hash []byte) {
209+
hash, err := factory.GetDefault().Hash(data, &bccsp.SHA3_256Opts{})
210+
if err != nil {
211+
panic(errors.Errorf("Failed computing SHA3_256 on [% x]", data))
212+
}
213+
return
214+
}
215+
216+
switch cc.protos.HashingAlgorithm.Name {
217+
case bccsp.SHA256:
218+
cc.hashingAlgorithm = computeSHA256
219+
case bccsp.SHA3_256:
220+
cc.hashingAlgorithm = computeSHA3256
221+
default:
222+
return errors.Errorf("unknown hashing algorithm type: %s", cc.protos.HashingAlgorithm.Name)
223+
}
224+
225+
return nil
226+
}
227+
179228
func (cc *ChannelConfig) validateBlockDataHashingStructure() error {
180229
if cc.protos.BlockDataHashingStructure.Width != math.MaxUint32 {
181230
return fmt.Errorf("BlockDataHashStructure width only supported at MaxUint32 in this version")
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
11+
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
12+
)
13+
14+
const (
15+
// ChannelCreationPolicyKey is the key used in the consortium config to denote the policy
16+
// to be used in evaluating whether a channel creation request is authorized
17+
ChannelCreationPolicyKey = "ChannelCreationPolicy"
18+
)
19+
20+
// ConsortiumProtos holds the config protos for the consortium config
21+
type ConsortiumProtos struct {
22+
ChannelCreationPolicy *cb.Policy
23+
}
24+
25+
// ConsortiumConfig holds the consortium's configuration information
26+
type ConsortiumConfig struct {
27+
protos *ConsortiumProtos
28+
orgs map[string]Org
29+
}
30+
31+
// NewConsortiumConfig creates a new instance of the consortium's config
32+
func NewConsortiumConfig(consortiumGroup *cb.ConfigGroup, mspConfig *MSPConfigHandler) (*ConsortiumConfig, error) {
33+
cc := &ConsortiumConfig{
34+
protos: &ConsortiumProtos{},
35+
orgs: make(map[string]Org),
36+
}
37+
38+
if err := DeserializeProtoValuesFromGroup(consortiumGroup, cc.protos); err != nil {
39+
return nil, errors.Wrap(err, "failed to deserialize values")
40+
}
41+
42+
for orgName, orgGroup := range consortiumGroup.Groups {
43+
var err error
44+
if cc.orgs[orgName], err = NewOrganizationConfig(orgName, orgGroup, mspConfig); err != nil {
45+
return nil, err
46+
}
47+
}
48+
49+
return cc, nil
50+
}
51+
52+
// Organizations returns the set of organizations in the consortium
53+
func (cc *ConsortiumConfig) Organizations() map[string]Org {
54+
return cc.orgs
55+
}
56+
57+
// ChannelCreationPolicy returns the policy structure used to validate
58+
// the channel creation
59+
func (cc *ConsortiumConfig) ChannelCreationPolicy() *cb.Policy {
60+
return cc.protos.ChannelCreationPolicy
61+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package channelconfig
7+
8+
import (
9+
"testing"
10+
11+
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/msp"
12+
"github.com/hyperledger/fabric-lib-go/bccsp/sw"
13+
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
func TestConsortiumConfig(t *testing.T) {
18+
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
19+
require.NoError(t, err)
20+
cc, err := NewConsortiumConfig(&cb.ConfigGroup{}, NewMSPConfigHandler(msp.MSPv1_0, cryptoProvider))
21+
require.NoError(t, err)
22+
orgs := cc.Organizations()
23+
require.Equal(t, 0, len(orgs))
24+
25+
policy := cc.ChannelCreationPolicy()
26+
require.EqualValues(t, cb.Policy_UNKNOWN, policy.Type, "Expected policy type to be UNKNOWN")
27+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
11+
)
12+
13+
const (
14+
// ConsortiumsGroupKey is the group name for the consortiums config
15+
ConsortiumsGroupKey = "Consortiums"
16+
)
17+
18+
// ConsortiumsConfig holds the consoritums configuration information
19+
type ConsortiumsConfig struct {
20+
consortiums map[string]Consortium
21+
}
22+
23+
// NewConsortiumsConfig creates a new instance of the consoritums config
24+
func NewConsortiumsConfig(consortiumsGroup *cb.ConfigGroup, mspConfig *MSPConfigHandler) (*ConsortiumsConfig, error) {
25+
cc := &ConsortiumsConfig{
26+
consortiums: make(map[string]Consortium),
27+
}
28+
29+
for consortiumName, consortiumGroup := range consortiumsGroup.Groups {
30+
var err error
31+
if cc.consortiums[consortiumName], err = NewConsortiumConfig(consortiumGroup, mspConfig); err != nil {
32+
return nil, err
33+
}
34+
}
35+
return cc, nil
36+
}
37+
38+
// Consortiums returns a map of the current consortiums
39+
func (cc *ConsortiumsConfig) Consortiums() map[string]Consortium {
40+
return cc.consortiums
41+
}

0 commit comments

Comments
 (0)