-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FAB-5649] Invert configtx resource encapsulation
The configtx manager current retains a reference to the channel config, but to support other config types, this actually needs to be inverted so that the channel config retains a reference to the configtx manager. This CR performs this inversion and fixes the embedding packages of the configtx.Manager to instead embed the channelconfig.Resources. [FAB-5650] Move channel creation from configtx One of the last big offenders for putting channel config specific code into the configtx package is the templating code, which provides mechanisms to create new channel configurations. The generic templating is fine to remain there, but the channel specifics must be moved ot the channel config folder. Note: These two sub-tasks were squashed into one because of otherwise difficult to break import cycles. Change-Id: Ib8bf829216e19fbbbd8841c9a3551356ed1676b6 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
- Loading branch information
Jason Yellick
committed
Aug 12, 2017
1 parent
6e6b77d
commit d0c97c0
Showing
33 changed files
with
523 additions
and
450 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package config | ||
|
||
import ( | ||
"fmt" | ||
|
||
configmsp "github.com/hyperledger/fabric/common/config/channel/msp" | ||
"github.com/hyperledger/fabric/common/configtx" | ||
"github.com/hyperledger/fabric/common/policies" | ||
"github.com/hyperledger/fabric/common/util" | ||
"github.com/hyperledger/fabric/msp" | ||
cb "github.com/hyperledger/fabric/protos/common" | ||
"github.com/hyperledger/fabric/protos/utils" | ||
) | ||
|
||
const ( | ||
msgVersion = int32(0) | ||
epoch = 0 | ||
) | ||
|
||
type channelCreationTemplate struct { | ||
consortiumName string | ||
orgs []string | ||
} | ||
|
||
// NewChainCreationTemplate takes a consortium name and a Template to produce a | ||
// Template which outputs an appropriately constructed list of ConfigUpdateEnvelopes. | ||
func NewChainCreationTemplate(consortiumName string, orgs []string) configtx.Template { | ||
return &channelCreationTemplate{ | ||
consortiumName: consortiumName, | ||
orgs: orgs, | ||
} | ||
} | ||
|
||
func (cct *channelCreationTemplate) Envelope(channelID string) (*cb.ConfigUpdateEnvelope, error) { | ||
rSet := TemplateConsortium(cct.consortiumName) | ||
wSet := TemplateConsortium(cct.consortiumName) | ||
|
||
rSet.Groups[ApplicationGroupKey] = cb.NewConfigGroup() | ||
wSet.Groups[ApplicationGroupKey] = cb.NewConfigGroup() | ||
|
||
for _, org := range cct.orgs { | ||
rSet.Groups[ApplicationGroupKey].Groups[org] = cb.NewConfigGroup() | ||
wSet.Groups[ApplicationGroupKey].Groups[org] = cb.NewConfigGroup() | ||
} | ||
|
||
wSet.Groups[ApplicationGroupKey].ModPolicy = configmsp.AdminsPolicyKey | ||
wSet.Groups[ApplicationGroupKey].Policies[configmsp.AdminsPolicyKey] = policies.ImplicitMetaPolicyWithSubPolicy(configmsp.AdminsPolicyKey, cb.ImplicitMetaPolicy_MAJORITY) | ||
wSet.Groups[ApplicationGroupKey].Policies[configmsp.AdminsPolicyKey].ModPolicy = configmsp.AdminsPolicyKey | ||
wSet.Groups[ApplicationGroupKey].Policies[configmsp.WritersPolicyKey] = policies.ImplicitMetaPolicyWithSubPolicy(configmsp.WritersPolicyKey, cb.ImplicitMetaPolicy_ANY) | ||
wSet.Groups[ApplicationGroupKey].Policies[configmsp.WritersPolicyKey].ModPolicy = configmsp.AdminsPolicyKey | ||
wSet.Groups[ApplicationGroupKey].Policies[configmsp.ReadersPolicyKey] = policies.ImplicitMetaPolicyWithSubPolicy(configmsp.ReadersPolicyKey, cb.ImplicitMetaPolicy_ANY) | ||
wSet.Groups[ApplicationGroupKey].Policies[configmsp.ReadersPolicyKey].ModPolicy = configmsp.AdminsPolicyKey | ||
wSet.Groups[ApplicationGroupKey].Version = 1 | ||
|
||
return &cb.ConfigUpdateEnvelope{ | ||
ConfigUpdate: utils.MarshalOrPanic(&cb.ConfigUpdate{ | ||
ChannelId: channelID, | ||
ReadSet: rSet, | ||
WriteSet: wSet, | ||
}), | ||
}, nil | ||
} | ||
|
||
// MakeChainCreationTransaction is a handy utility function for creating new chain transactions using the underlying Template framework | ||
func MakeChainCreationTransaction(channelID string, consortium string, signer msp.SigningIdentity, orgs ...string) (*cb.Envelope, error) { | ||
newChainTemplate := NewChainCreationTemplate(consortium, orgs) | ||
newConfigUpdateEnv, err := newChainTemplate.Envelope(channelID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
payloadSignatureHeader := &cb.SignatureHeader{} | ||
if signer != nil { | ||
sSigner, err := signer.Serialize() | ||
if err != nil { | ||
return nil, fmt.Errorf("Serialization of identity failed, err %s", err) | ||
} | ||
|
||
newConfigUpdateEnv.Signatures = []*cb.ConfigSignature{&cb.ConfigSignature{ | ||
SignatureHeader: utils.MarshalOrPanic(utils.MakeSignatureHeader(sSigner, utils.CreateNonceOrPanic())), | ||
}} | ||
|
||
newConfigUpdateEnv.Signatures[0].Signature, err = signer.Sign(util.ConcatenateBytes(newConfigUpdateEnv.Signatures[0].SignatureHeader, newConfigUpdateEnv.ConfigUpdate)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
payloadSignatureHeader = utils.MakeSignatureHeader(sSigner, utils.CreateNonceOrPanic()) | ||
} | ||
|
||
payloadChannelHeader := utils.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, msgVersion, channelID, epoch) | ||
utils.SetTxID(payloadChannelHeader, payloadSignatureHeader) | ||
payloadHeader := utils.MakePayloadHeader(payloadChannelHeader, payloadSignatureHeader) | ||
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(newConfigUpdateEnv)} | ||
paylBytes := utils.MarshalOrPanic(payload) | ||
|
||
var sig []byte | ||
if signer != nil { | ||
// sign the payload | ||
sig, err = signer.Sign(paylBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return &cb.Envelope{Payload: paylBytes, Signature: sig}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package config | ||
|
||
import ( | ||
"testing" | ||
|
||
configmsp "github.com/hyperledger/fabric/common/config/channel/msp" | ||
"github.com/hyperledger/fabric/common/configtx" | ||
mmsp "github.com/hyperledger/fabric/common/mocks/msp" | ||
cb "github.com/hyperledger/fabric/protos/common" | ||
"github.com/hyperledger/fabric/protos/utils" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestNewChainTemplate(t *testing.T) { | ||
consortiumName := "Test" | ||
orgs := []string{"org1", "org2", "org3"} | ||
nct := NewChainCreationTemplate(consortiumName, orgs) | ||
|
||
newChainID := "foo" | ||
configEnv, err := nct.Envelope(newChainID) | ||
if err != nil { | ||
t.Fatalf("Error creation a chain creation config") | ||
} | ||
|
||
configUpdate, err := configtx.UnmarshalConfigUpdate(configEnv.ConfigUpdate) | ||
if err != nil { | ||
t.Fatalf("Should not have errored: %s", err) | ||
} | ||
|
||
consortiumProto := &cb.Consortium{} | ||
err = proto.Unmarshal(configUpdate.WriteSet.Values[ConsortiumKey].Value, consortiumProto) | ||
assert.NoError(t, err) | ||
assert.Equal(t, consortiumName, consortiumProto.Name, "Should have set correct consortium name") | ||
|
||
assert.Equal(t, configUpdate.WriteSet.Groups[ApplicationGroupKey].Version, uint64(1)) | ||
|
||
assert.Len(t, configUpdate.WriteSet.Groups[ApplicationGroupKey].Groups, len(orgs)) | ||
|
||
for _, org := range orgs { | ||
group, ok := configUpdate.WriteSet.Groups[ApplicationGroupKey].Groups[org] | ||
assert.True(t, ok, "Expected to find %s but did not", org) | ||
for _, policy := range group.Policies { | ||
assert.Equal(t, configmsp.AdminsPolicyKey, policy.ModPolicy) | ||
} | ||
} | ||
} | ||
|
||
func TestMakeChainCreationTransactionWithSigner(t *testing.T) { | ||
channelID := "foo" | ||
|
||
signer, err := mmsp.NewNoopMsp().GetDefaultSigningIdentity() | ||
assert.NoError(t, err, "Creating noop MSP") | ||
|
||
cct, err := MakeChainCreationTransaction(channelID, "test", signer) | ||
assert.NoError(t, err, "Making chain creation tx") | ||
|
||
assert.NotEmpty(t, cct.Signature, "Should have signature") | ||
|
||
payload, err := utils.UnmarshalPayload(cct.Payload) | ||
assert.NoError(t, err, "Unmarshaling payload") | ||
|
||
configUpdateEnv, err := configtx.UnmarshalConfigUpdateEnvelope(payload.Data) | ||
assert.NoError(t, err, "Unmarshaling ConfigUpdateEnvelope") | ||
|
||
assert.NotEmpty(t, configUpdateEnv.Signatures, "Should have config env sigs") | ||
|
||
sigHeader, err := utils.GetSignatureHeader(payload.Header.SignatureHeader) | ||
assert.NoError(t, err, "Unmarshaling SignatureHeader") | ||
assert.NotEmpty(t, sigHeader.Creator, "Creator specified") | ||
} | ||
|
||
func TestMakeChainCreationTransactionNoSigner(t *testing.T) { | ||
channelID := "foo" | ||
cct, err := MakeChainCreationTransaction(channelID, "test", nil) | ||
assert.NoError(t, err, "Making chain creation tx") | ||
|
||
assert.Empty(t, cct.Signature, "Should have empty signature") | ||
|
||
payload, err := utils.UnmarshalPayload(cct.Payload) | ||
assert.NoError(t, err, "Unmarshaling payload") | ||
|
||
configUpdateEnv, err := configtx.UnmarshalConfigUpdateEnvelope(payload.Data) | ||
assert.NoError(t, err, "Unmarshaling ConfigUpdateEnvelope") | ||
|
||
assert.Empty(t, configUpdateEnv.Signatures, "Should have no config env sigs") | ||
|
||
sigHeader, err := utils.GetSignatureHeader(payload.Header.SignatureHeader) | ||
assert.NoError(t, err, "Unmarshaling SignatureHeader") | ||
assert.Empty(t, sigHeader.Creator, "No creator specified") | ||
} |
Oops, something went wrong.