Skip to content

Commit fda7f99

Browse files
author
Jason Yellick
committed
[FAB-1946] Rm ChainHeader from ConfigurationItem
https://jira.hyperledger.org/browse/FAB-1946 The current configuration transaction format expects a header per configuration item. This is more flexible, as it allows multiple parties to each sign subsets of a configuration, then submit it together. However, this additional workflow seems unnecessary, and it multiplies the number of required signatures. It also necessitates the computation of a digest in the channel creation request which is hard on the SDKs. (This digest computation will be removed in a later CR) For now, the ChainHeader is moved to the ConfigurationEnvelope, which means it is not included in the signature, this is insecure, but is the path of least complexity and smallest diff going forward until we reach the ultimate secure solution via FAB-1880. Change-Id: Idaf16c2afe0e2ebdd068d7b312a883a41a4a2017 Signed-off-by: Jason Yellick <[email protected]>
1 parent bdba196 commit fda7f99

14 files changed

+164
-179
lines changed

common/configtx/manager.go

+15-22
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,21 @@ func computeChainIDAndSequence(configtx *cb.ConfigurationEnvelope) (string, uint
9898
return "", 0, errors.New("Empty envelope unsupported")
9999
}
100100

101-
m := uint64(0) //configtx.Items[0].LastModified
102-
var chainID string //:= configtx.Items[0].Header.ChainID
101+
m := uint64(0)
102+
103+
if configtx.Header == nil {
104+
return "", 0, fmt.Errorf("Header not set")
105+
}
106+
107+
if configtx.Header.ChainID == "" {
108+
return "", 0, fmt.Errorf("Header chainID was not set")
109+
}
110+
111+
chainID := configtx.Header.ChainID
112+
113+
if err := validateChainID(chainID); err != nil {
114+
return "", 0, err
115+
}
103116

104117
for _, signedItem := range configtx.Items {
105118
item := &cb.ConfigurationItem{}
@@ -110,26 +123,6 @@ func computeChainIDAndSequence(configtx *cb.ConfigurationEnvelope) (string, uint
110123
if item.LastModified > m {
111124
m = item.LastModified
112125
}
113-
114-
if item.Header == nil {
115-
return "", 0, fmt.Errorf("Header not set: %v", item)
116-
}
117-
118-
if item.Header.ChainID == "" {
119-
return "", 0, fmt.Errorf("Header chainID was not set: %v", item)
120-
}
121-
122-
if chainID == "" {
123-
chainID = item.Header.ChainID
124-
} else {
125-
if chainID != item.Header.ChainID {
126-
return "", 0, fmt.Errorf("Mismatched chainIDs in envelope %s != %s", chainID, item.Header.ChainID)
127-
}
128-
}
129-
130-
if err := validateChainID(chainID); err != nil {
131-
return "", 0, err
132-
}
133126
}
134127

135128
return chainID, m, nil

common/configtx/manager_test.go

+61-54
Large diffs are not rendered by default.

common/configtx/template.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ func NewSimpleTemplate(items ...*cb.ConfigurationItem) Template {
5353
func (st *simpleTemplate) Items(chainID string) ([]*cb.SignedConfigurationItem, error) {
5454
signedItems := make([]*cb.SignedConfigurationItem, len(st.items))
5555
for i := range st.items {
56-
st.items[i].Header = &cb.ChainHeader{ChainID: chainID, Type: int32(cb.HeaderType_CONFIGURATION_ITEM)}
5756
mItem, err := proto.Marshal(st.items[i])
5857
if err != nil {
5958
return nil, err
@@ -113,9 +112,8 @@ func (nct *newChainTemplate) Items(chainID string) ([]*cb.SignedConfigurationIte
113112

114113
creationPolicy := &cb.SignedConfigurationItem{
115114
ConfigurationItem: utils.MarshalOrPanic(&cb.ConfigurationItem{
116-
Header: utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, chainID, epoch),
117-
Type: cb.ConfigurationItem_Orderer,
118-
Key: CreationPolicyKey,
115+
Type: cb.ConfigurationItem_Orderer,
116+
Key: CreationPolicyKey,
119117
Value: utils.MarshalOrPanic(&ab.CreationPolicy{
120118
Policy: nct.creationPolicy,
121119
Digest: HashItems(items, nct.hash),
@@ -162,7 +160,7 @@ func MakeChainCreationTransaction(creationPolicy string, chainID string, signer
162160
return nil, err
163161
}
164162

165-
manager, err := NewManagerImpl(&cb.ConfigurationEnvelope{Items: items}, NewInitializer(), nil)
163+
manager, err := NewManagerImpl(&cb.ConfigurationEnvelope{Header: &cb.ChainHeader{ChainID: chainID, Type: int32(cb.HeaderType_CONFIGURATION_ITEM)}, Items: items}, NewInitializer(), nil)
166164
if err != nil {
167165
return nil, err
168166
}
@@ -181,7 +179,10 @@ func MakeChainCreationTransaction(creationPolicy string, chainID string, signer
181179
payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, msgVersion, chainID, epoch)
182180
payloadSignatureHeader := utils.MakeSignatureHeader(sSigner, utils.CreateNonceOrPanic())
183181
payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader)
184-
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(utils.MakeConfigurationEnvelope(signedConfigItems...))}
182+
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{
183+
Items: signedConfigItems,
184+
Header: &cb.ChainHeader{ChainID: chainID, Type: int32(cb.HeaderType_CONFIGURATION_ITEM)},
185+
})}
185186
paylBytes := utils.MarshalOrPanic(payload)
186187

187188
// sign the payload

common/configtx/template_test.go

+2-11
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,15 @@ func verifyItemsResult(t *testing.T, template Template, count int) {
4040

4141
for i, signedItem := range result {
4242
item := utils.UnmarshalConfigurationItemOrPanic(signedItem.ConfigurationItem)
43-
assert.Equal(t, newChainID, item.Header.ChainID, "Should have appropriately set new chainID")
4443
expected := fmt.Sprintf("%d", i)
4544
assert.Equal(t, expected, string(item.Value), "Expected %s but got %s", expected, item.Value)
46-
assert.Equal(t, int32(cb.HeaderType_CONFIGURATION_ITEM), item.Header.Type)
4745
}
4846
}
4947

5048
func TestSimpleTemplate(t *testing.T) {
51-
hdr := &cb.ChainHeader{
52-
ChainID: "foo",
53-
Type: int32(cb.HeaderType_CONFIGURATION_ITEM),
54-
}
5549
simple := NewSimpleTemplate(
56-
&cb.ConfigurationItem{Value: []byte("0"), Header: hdr},
57-
&cb.ConfigurationItem{Value: []byte("1"), Header: hdr},
50+
&cb.ConfigurationItem{Value: []byte("0")},
51+
&cb.ConfigurationItem{Value: []byte("1")},
5852
)
5953
verifyItemsResult(t, simple, 2)
6054
}
@@ -94,9 +88,6 @@ func TestNewChainTemplate(t *testing.T) {
9488

9589
for i, signedItem := range items {
9690
item := utils.UnmarshalConfigurationItemOrPanic(signedItem.ConfigurationItem)
97-
if item.Header.ChainID != newChainID {
98-
t.Errorf("Should have appropriately set new chainID")
99-
}
10091
if i == 0 {
10192
if item.Key != CreationPolicyKey {
10293
t.Errorf("First item should have been the creation policy")

common/configtx/test/orderer.template

0 Bytes
Binary file not shown.

common/genesis/genesis.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func (f *factory) Block(chainID string) (*cb.Block, error) {
5151
payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, msgVersion, chainID, epoch)
5252
payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic())
5353
payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader)
54-
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{Items: items})}
54+
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{Header: &cb.ChainHeader{ChainID: chainID}, Items: items})}
5555
envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil}
5656

5757
block := cb.NewBlock(0, nil)

orderer/multichain/systemchain_test.go

-4
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,6 @@ func TestGoodProposal(t *testing.T) {
118118
mcc.ms.mpm.mp = &mockPolicy{}
119119

120120
chainCreateTx := &cb.ConfigurationItem{
121-
Header: &cb.ChainHeader{
122-
ChainID: newChainID,
123-
Type: int32(cb.HeaderType_CONFIGURATION_ITEM),
124-
},
125121
Key: configtx.CreationPolicyKey,
126122
Type: cb.ConfigurationItem_Orderer,
127123
Value: utils.MarshalOrPanic(&ab.CreationPolicy{

orderer/multichain/util_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ func makeConfigTxWithItems(chainID string, items ...*cb.ConfigurationItem) *cb.E
103103
},
104104
Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{
105105
Items: signedItems,
106+
Header: &cb.ChainHeader{
107+
Type: int32(cb.HeaderType_CONFIGURATION_ITEM),
108+
ChainID: chainID,
109+
},
106110
}),
107111
}
108112
return &cb.Envelope{

protos/common/configtx.pb.go

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

protos/common/configtx.proto

+8-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ package common;
4848
// 5. All configuration changes satisfy the corresponding modification policy
4949
message ConfigurationEnvelope {
5050
repeated SignedConfigurationItem Items = 1;
51+
52+
// XXX This needs to be signed over, purely temporary pending completion of https://jira.hyperledger.org/browse/FAB-1880
53+
ChainHeader header = 2;
5154
}
5255

5356
// ConfigurationTemplate is used as a serialization format to share configuration templates
@@ -71,12 +74,11 @@ message ConfigurationItem {
7174
Peer = 3; // Marshaled format for this type is yet to be determined
7275
MSP = 4; // Marshaled MSPConfig proto
7376
}
74-
ChainHeader Header = 1; // The header which ties this configuration to a particular chain
75-
ConfigurationType Type = 2; // The type of configuration this is.
76-
uint64 LastModified = 3; // The Sequence number in the ConfigurationEnvelope this item was last modified
77-
string ModificationPolicy = 4; // What policy to check before allowing modification
78-
string Key = 5; // A unique ID, unique scoped by Type, to reference the value by
79-
bytes Value = 6; // The byte representation of this configuration, usually a marshaled message
77+
ConfigurationType Type = 1; // The type of configuration this is.
78+
uint64 LastModified = 2; // The Sequence number in the ConfigurationEnvelope this item was last modified
79+
string ModificationPolicy = 3; // What policy to check before allowing modification
80+
string Key = 4; // A unique ID, unique scoped by Type, to reference the value by
81+
bytes Value = 5; // The byte representation of this configuration, usually a marshaled message
8082
}
8183

8284
message ConfigurationSignature {

0 commit comments

Comments
 (0)