Skip to content

Commit a50bd08

Browse files
author
Jason Yellick
committedOct 3, 2017
[FAB-6426] Remove Capability msg 'required' field
The Capability msg currently only has a single field: 'required'. This field doesn't make a ton of sense, because if a capability were not required, then it could simply not be added to the capabilities map. In the interest of not allowing the expression of the same idea two ways (and the complexity which comes with it), this CR removes the 'required' field from the Capability message and instead makes it an empty message which may be extended in the future, should the need ever arise. Change-Id: I4c48d2a3d0c4fedb4bcf86f8476f34470ad494c5 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent 28b0da2 commit a50bd08

File tree

7 files changed

+108
-97
lines changed

7 files changed

+108
-97
lines changed
 

‎common/capabilities/capabilities.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,12 @@ func newRegistry(p provider, capabilities map[string]*cb.Capability) *registry {
4242

4343
// Supported checks that all of the required capabilities are supported by this binary.
4444
func (r *registry) Supported() error {
45-
for capabilityName, capability := range r.capabilities {
45+
for capabilityName := range r.capabilities {
4646
if r.provider.HasCapability(capabilityName) {
4747
continue
4848
}
4949

50-
if capability.Required {
51-
return errors.Errorf("%s capability %s is required but not supported", r.provider.Type(), capabilityName)
52-
}
53-
logger.Debugf("Found unknown %s capability %s but it is not required", r.provider.Type(), capabilityName)
50+
return errors.Errorf("%s capability %s is required but not supported", r.provider.Type(), capabilityName)
5451
}
5552
return nil
5653
}

‎common/capabilities/capabilities_test.go

+9-31
Original file line numberDiff line numberDiff line change
@@ -20,41 +20,19 @@ func init() {
2020
}
2121

2222
func TestSatisfied(t *testing.T) {
23-
t.Run("NilCapabilities", func(t *testing.T) {
24-
var capsMap map[string]*cb.Capability
25-
for _, provider := range []*registry{
26-
NewChannelProvider(capsMap).registry,
27-
NewOrdererProvider(capsMap).registry,
28-
NewApplicationProvider(capsMap).registry,
29-
} {
30-
assert.Nil(t, provider.Supported())
31-
}
32-
})
33-
34-
t.Run("NotRequiredCapabilities", func(t *testing.T) {
35-
capsMap := map[string]*cb.Capability{
36-
"FakeCapability1": &cb.Capability{
37-
Required: false,
38-
},
39-
"FakeCapability2": &cb.Capability{
40-
Required: false,
41-
},
42-
}
43-
for _, provider := range []*registry{
44-
NewChannelProvider(capsMap).registry,
45-
NewOrdererProvider(capsMap).registry,
46-
NewApplicationProvider(capsMap).registry,
47-
} {
48-
assert.Nil(t, provider.Supported())
49-
}
50-
})
23+
var capsMap map[string]*cb.Capability
24+
for _, provider := range []*registry{
25+
NewChannelProvider(capsMap).registry,
26+
NewOrdererProvider(capsMap).registry,
27+
NewApplicationProvider(capsMap).registry,
28+
} {
29+
assert.Nil(t, provider.Supported())
30+
}
5131
}
5232

5333
func TestNotSatisfied(t *testing.T) {
5434
capsMap := map[string]*cb.Capability{
55-
"FakeCapability": &cb.Capability{
56-
Required: true,
57-
},
35+
"FakeCapability": &cb.Capability{},
5836
}
5937
for _, provider := range []*registry{
6038
NewChannelProvider(capsMap).registry,

‎common/channelconfig/channel_util.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ func capabilitiesFromBoolMap(capabilities map[string]bool) *cb.Capabilities {
6868
Capabilities: make(map[string]*cb.Capability),
6969
}
7070
for capability, required := range capabilities {
71-
value.Capabilities[capability] = &cb.Capability{
72-
Required: required,
71+
if !required {
72+
continue
7373
}
74+
value.Capabilities[capability] = &cb.Capability{}
7475
}
7576
return value
7677
}

‎protos/common/configuration.go

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ func (dccv *DynamicChannelConfigValue) VariablyOpaqueFieldProto(name string) (pr
8585
return &OrdererAddresses{}, nil
8686
case "Consortium":
8787
return &Consortium{}, nil
88+
case "Capabilities":
89+
return &Capabilities{}, nil
8890
default:
8991
return nil, fmt.Errorf("unknown Channel ConfigValue name: %s", dccv.name)
9092
}

‎protos/common/configuration.pb.go

+55-43
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎protos/common/configuration.proto

+35-16
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,42 @@ message Consortium {
4848
}
4949

5050

51-
// Capabilities message contains all the capabilities that a channel requires
52-
// participant entities to comply with. The entity should drop off the channel
53-
// if it can't fulfill any of the required capabilities.
54-
// Capabilities is encoded into the configuaration as Values of each type
55-
// Orderer, Channel, or Application.
56-
// The key string should represent the capability name, and it must be unique
57-
// within each type. For readability, it may be advisable to prefix the key with
58-
// its type (eg app-acl)
51+
// Capabilities message defines the capabilities a particular binary must implement
52+
// for that binary to be able to safely participate in the channel. The capabilities
53+
// message is defined at the /Channel level, the /Channel/Application level, and the
54+
// /Channel/Orderer level.
55+
//
56+
// The /Channel level capabilties define capabilities which both the orderer and peer
57+
// binaries must satisfy. These capabilties might be things like a new MSP type,
58+
// or a new policy type.
59+
//
60+
// The /Channel/Orderer level capabilties define capabilities which must be supported
61+
// by the orderer, but which have no bearing on the behavior of the peer. For instance
62+
// if the orderer changes the logic for how it constructs new channels, only all orderers
63+
// must agree on the new logic. The peers do not need to be aware of this change as
64+
// they only interact with the channel after it has been constructed.
65+
//
66+
// Finally, the /Channel/Application level capabilities define capabilities which the peer
67+
// binary must satisfy, but which have no bearing on the orderer. For instance, if the
68+
// peer adds a new UTXO transaction type, or changes the chaincode lifecycle requirements,
69+
// all peers must agree on the new logic. However, orderers never inspect transactions
70+
// this deeply, and therefore have no need to be aware of the change.
71+
//
72+
// The capabilities strings defined in these messages typically correspond to release
73+
// binary versions (e.g. "V1.1"), and are used primarilly as a mechanism for a fully
74+
// upgraded network to switch from one set of logic to a new one.
75+
//
76+
// Although for V1.1, the orderers must be upgraded to V1.1 prior to the rest of the
77+
// network, going forward, because of the split between the /Channel, /Channel/Orderer
78+
// and /Channel/Application capabilities. It should be possible for the orderer and
79+
// application networks to upgrade themselves independently (with the exception of any
80+
// new capabilities defined at the /Channel level).
5981
message Capabilities {
6082
map<string, Capability> capabilities = 1;
6183
}
6284

63-
// Capability holds a set of options. We can add more as needed in the
64-
// future. For now, whether it is required or not. If a configured capability
65-
// is not required, it must be completely compatible with previous releases.
66-
// Compatible features are not required to be encoded as capabilities; they
67-
// only provide flexibility for the admins to control the features.
68-
message Capability {
69-
bool required = 1;
70-
}
85+
// Capability is an empty message for the time being. It is defined as a protobuf
86+
// message rather than a constant, so that we may extend capabilities with other fields
87+
// if the need arises in the future. For the time being, a capability being in the
88+
// capabilities map requires that that capability be supported.
89+
message Capability { }

‎protos/orderer/configuration.go

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ func (docv *DynamicOrdererConfigValue) VariablyOpaqueFieldProto(name string) (pr
109109
return &KafkaBrokers{}, nil
110110
case "ChannelRestrictions":
111111
return &ChannelRestrictions{}, nil
112+
case "Capabilities":
113+
return &common.Capabilities{}, nil
112114
default:
113115
return nil, fmt.Errorf("unknown Orderer ConfigValue name: %s", docv.name)
114116
}

0 commit comments

Comments
 (0)
Please sign in to comment.