Skip to content

Commit

Permalink
[FAB-1946] Rm ChainHeader from ConfigurationItem
Browse files Browse the repository at this point in the history
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 <jyellick@us.ibm.com>
  • Loading branch information
Jason Yellick committed Feb 5, 2017
1 parent bdba196 commit fda7f99
Show file tree
Hide file tree
Showing 14 changed files with 164 additions and 179 deletions.
37 changes: 15 additions & 22 deletions common/configtx/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,21 @@ func computeChainIDAndSequence(configtx *cb.ConfigurationEnvelope) (string, uint
return "", 0, errors.New("Empty envelope unsupported")
}

m := uint64(0) //configtx.Items[0].LastModified
var chainID string //:= configtx.Items[0].Header.ChainID
m := uint64(0)

if configtx.Header == nil {
return "", 0, fmt.Errorf("Header not set")
}

if configtx.Header.ChainID == "" {
return "", 0, fmt.Errorf("Header chainID was not set")
}

chainID := configtx.Header.ChainID

if err := validateChainID(chainID); err != nil {
return "", 0, err
}

for _, signedItem := range configtx.Items {
item := &cb.ConfigurationItem{}
Expand All @@ -110,26 +123,6 @@ func computeChainIDAndSequence(configtx *cb.ConfigurationEnvelope) (string, uint
if item.LastModified > m {
m = item.LastModified
}

if item.Header == nil {
return "", 0, fmt.Errorf("Header not set: %v", item)
}

if item.Header.ChainID == "" {
return "", 0, fmt.Errorf("Header chainID was not set: %v", item)
}

if chainID == "" {
chainID = item.Header.ChainID
} else {
if chainID != item.Header.ChainID {
return "", 0, fmt.Errorf("Mismatched chainIDs in envelope %s != %s", chainID, item.Header.ChainID)
}
}

if err := validateChainID(chainID); err != nil {
return "", 0, err
}
}

return chainID, m, nil
Expand Down
115 changes: 61 additions & 54 deletions common/configtx/manager_test.go

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions common/configtx/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func NewSimpleTemplate(items ...*cb.ConfigurationItem) Template {
func (st *simpleTemplate) Items(chainID string) ([]*cb.SignedConfigurationItem, error) {
signedItems := make([]*cb.SignedConfigurationItem, len(st.items))
for i := range st.items {
st.items[i].Header = &cb.ChainHeader{ChainID: chainID, Type: int32(cb.HeaderType_CONFIGURATION_ITEM)}
mItem, err := proto.Marshal(st.items[i])
if err != nil {
return nil, err
Expand Down Expand Up @@ -113,9 +112,8 @@ func (nct *newChainTemplate) Items(chainID string) ([]*cb.SignedConfigurationIte

creationPolicy := &cb.SignedConfigurationItem{
ConfigurationItem: utils.MarshalOrPanic(&cb.ConfigurationItem{
Header: utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, chainID, epoch),
Type: cb.ConfigurationItem_Orderer,
Key: CreationPolicyKey,
Type: cb.ConfigurationItem_Orderer,
Key: CreationPolicyKey,
Value: utils.MarshalOrPanic(&ab.CreationPolicy{
Policy: nct.creationPolicy,
Digest: HashItems(items, nct.hash),
Expand Down Expand Up @@ -162,7 +160,7 @@ func MakeChainCreationTransaction(creationPolicy string, chainID string, signer
return nil, err
}

manager, err := NewManagerImpl(&cb.ConfigurationEnvelope{Items: items}, NewInitializer(), nil)
manager, err := NewManagerImpl(&cb.ConfigurationEnvelope{Header: &cb.ChainHeader{ChainID: chainID, Type: int32(cb.HeaderType_CONFIGURATION_ITEM)}, Items: items}, NewInitializer(), nil)
if err != nil {
return nil, err
}
Expand All @@ -181,7 +179,10 @@ func MakeChainCreationTransaction(creationPolicy string, chainID string, signer
payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, msgVersion, chainID, epoch)
payloadSignatureHeader := utils.MakeSignatureHeader(sSigner, utils.CreateNonceOrPanic())
payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader)
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(utils.MakeConfigurationEnvelope(signedConfigItems...))}
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{
Items: signedConfigItems,
Header: &cb.ChainHeader{ChainID: chainID, Type: int32(cb.HeaderType_CONFIGURATION_ITEM)},
})}
paylBytes := utils.MarshalOrPanic(payload)

// sign the payload
Expand Down
13 changes: 2 additions & 11 deletions common/configtx/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,15 @@ func verifyItemsResult(t *testing.T, template Template, count int) {

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

func TestSimpleTemplate(t *testing.T) {
hdr := &cb.ChainHeader{
ChainID: "foo",
Type: int32(cb.HeaderType_CONFIGURATION_ITEM),
}
simple := NewSimpleTemplate(
&cb.ConfigurationItem{Value: []byte("0"), Header: hdr},
&cb.ConfigurationItem{Value: []byte("1"), Header: hdr},
&cb.ConfigurationItem{Value: []byte("0")},
&cb.ConfigurationItem{Value: []byte("1")},
)
verifyItemsResult(t, simple, 2)
}
Expand Down Expand Up @@ -94,9 +88,6 @@ func TestNewChainTemplate(t *testing.T) {

for i, signedItem := range items {
item := utils.UnmarshalConfigurationItemOrPanic(signedItem.ConfigurationItem)
if item.Header.ChainID != newChainID {
t.Errorf("Should have appropriately set new chainID")
}
if i == 0 {
if item.Key != CreationPolicyKey {
t.Errorf("First item should have been the creation policy")
Expand Down
Binary file modified common/configtx/test/orderer.template
Binary file not shown.
2 changes: 1 addition & 1 deletion common/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (f *factory) Block(chainID string) (*cb.Block, error) {
payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, msgVersion, chainID, epoch)
payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic())
payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader)
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{Items: items})}
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{Header: &cb.ChainHeader{ChainID: chainID}, Items: items})}
envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil}

block := cb.NewBlock(0, nil)
Expand Down
4 changes: 0 additions & 4 deletions orderer/multichain/systemchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ func TestGoodProposal(t *testing.T) {
mcc.ms.mpm.mp = &mockPolicy{}

chainCreateTx := &cb.ConfigurationItem{
Header: &cb.ChainHeader{
ChainID: newChainID,
Type: int32(cb.HeaderType_CONFIGURATION_ITEM),
},
Key: configtx.CreationPolicyKey,
Type: cb.ConfigurationItem_Orderer,
Value: utils.MarshalOrPanic(&ab.CreationPolicy{
Expand Down
4 changes: 4 additions & 0 deletions orderer/multichain/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ func makeConfigTxWithItems(chainID string, items ...*cb.ConfigurationItem) *cb.E
},
Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{
Items: signedItems,
Header: &cb.ChainHeader{
Type: int32(cb.HeaderType_CONFIGURATION_ITEM),
ChainID: chainID,
},
}),
}
return &cb.Envelope{
Expand Down
83 changes: 42 additions & 41 deletions protos/common/configtx.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions protos/common/configtx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ package common;
// 5. All configuration changes satisfy the corresponding modification policy
message ConfigurationEnvelope {
repeated SignedConfigurationItem Items = 1;

// XXX This needs to be signed over, purely temporary pending completion of https://jira.hyperledger.org/browse/FAB-1880
ChainHeader header = 2;
}

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

message ConfigurationSignature {
Expand Down
Loading

0 comments on commit fda7f99

Please sign in to comment.