diff --git a/common/configtx/manager.go b/common/configtx/manager.go index e7ebd42e035..133f4551c7c 100644 --- a/common/configtx/manager.go +++ b/common/configtx/manager.go @@ -1,5 +1,5 @@ /* -Copyright IBM Corp. 2016 All Rights Reserved. +Copyright IBM Corp. 2017 All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import ( "github.com/hyperledger/fabric/common/configtx/api" cb "github.com/hyperledger/fabric/protos/common" + "github.com/hyperledger/fabric/protos/utils" logging "github.com/op/go-logging" ) @@ -99,28 +100,26 @@ func validateChainID(chainID string) error { return nil } -func NewManagerImpl(configEnv *cb.ConfigEnvelope, initializer api.Initializer, callOnUpdate []func(api.Manager)) (api.Manager, error) { - if configEnv == nil { - return nil, fmt.Errorf("Nil config envelope") - } - - if configEnv.Config == nil { - return nil, fmt.Errorf("Nil config envelope Config") +func NewManagerImpl(envConfig *cb.Envelope, initializer api.Initializer, callOnUpdate []func(api.Manager)) (api.Manager, error) { + if envConfig == nil { + return nil, fmt.Errorf("Nil envelope") } - if configEnv.Config.Channel == nil { - return nil, fmt.Errorf("Nil config envelope Config.Channel") + configEnv := &cb.ConfigEnvelope{} + header, err := utils.UnmarshalEnvelopeOfType(envConfig, cb.HeaderType_CONFIG, configEnv) + if err != nil { + return nil, fmt.Errorf("Bad envelope: %s", err) } - if configEnv.Config.Header == nil { - return nil, fmt.Errorf("Nil config envelop Config Header") + if configEnv.Config == nil { + return nil, fmt.Errorf("Nil config envelope Config") } - if err := validateChainID(configEnv.Config.Header.ChannelId); err != nil { + if err := validateChainID(header.ChannelId); err != nil { return nil, fmt.Errorf("Bad channel id: %s", err) } - configMap, err := mapConfig(configEnv.Config.Channel) + configMap, err := mapConfig(configEnv.Config.ChannelGroup) if err != nil { return nil, fmt.Errorf("Error converting config to map: %s", err) } @@ -128,13 +127,13 @@ func NewManagerImpl(configEnv *cb.ConfigEnvelope, initializer api.Initializer, c cm := &configManager{ Resources: initializer, initializer: initializer, - sequence: computeSequence(configEnv.Config.Channel), - chainID: configEnv.Config.Header.ChannelId, + sequence: configEnv.Config.Sequence, + chainID: header.ChannelId, config: configMap, callOnUpdate: callOnUpdate, } - result, err := cm.processConfig(configEnv.Config.Channel) + result, err := cm.processConfig(configEnv.Config.ChannelGroup) if err != nil { return nil, err } @@ -177,10 +176,8 @@ func (cm *configManager) ProposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigE return &cb.ConfigEnvelope{ Config: &cb.Config{ - Header: &cb.ChannelHeader{ - ChannelId: cm.chainID, - }, - Channel: channelGroup, + Sequence: cm.sequence, + ChannelGroup: channelGroup, }, LastUpdate: configtx, }, nil @@ -210,7 +207,7 @@ func (cm *configManager) prepareApply(configEnv *cb.ConfigEnvelope) (map[string] return nil, nil, fmt.Errorf("Config cannot be nil") } - if !reflect.DeepEqual(channelGroup, configEnv.Config.Channel) { + if !reflect.DeepEqual(channelGroup, configEnv.Config.ChannelGroup) { return nil, nil, fmt.Errorf("ConfigEnvelope LastUpdate did not produce the supplied config result") } diff --git a/common/configtx/manager_test.go b/common/configtx/manager_test.go index 6e632a15e97..e54bef97275 100644 --- a/common/configtx/manager_test.go +++ b/common/configtx/manager_test.go @@ -61,19 +61,28 @@ func makeConfigPair(id, modificationPolicy string, lastModified uint64, data []b } } -func makeConfigEnvelope(chainID string, configPairs ...*configPair) *cb.ConfigEnvelope { +func makeEnvelopeConfig(channelID string, configPairs ...*configPair) *cb.Envelope { values := make(map[string]*cb.ConfigValue) for _, pair := range configPairs { values[pair.key] = pair.value } - return &cb.ConfigEnvelope{ - Config: &cb.Config{ - Header: &cb.ChannelHeader{ChannelId: chainID}, - Channel: &cb.ConfigGroup{ - Values: values, + return &cb.Envelope{ + Payload: utils.MarshalOrPanic(&cb.Payload{ + Header: &cb.Header{ + ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{ + Type: int32(cb.HeaderType_CONFIG), + ChannelId: channelID, + }), }, - }, + Data: utils.MarshalOrPanic(&cb.ConfigEnvelope{ + Config: &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Values: values, + }, + }, + }), + }), } } @@ -84,7 +93,7 @@ func makeConfigUpdateEnvelope(chainID string, configPairs ...*configPair) *cb.En } config := &cb.ConfigUpdate{ - Header: &cb.ChannelHeader{ChannelId: chainID}, + ChannelId: chainID, WriteSet: &cb.ConfigGroup{ Values: values, }, @@ -110,7 +119,7 @@ func TestCallback(t *testing.T) { } cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), defaultInitializer(), []func(api.Manager){callback}) if err != nil { @@ -125,7 +134,7 @@ func TestCallback(t *testing.T) { // TestDifferentChainID tests that a config update for a different chain ID fails func TestDifferentChainID(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), defaultInitializer(), nil) if err != nil { @@ -143,7 +152,7 @@ func TestDifferentChainID(t *testing.T) { // TestOldConfigReplay tests that resubmitting a config for a sequence number which is not newer is ignored func TestOldConfigReplay(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), defaultInitializer(), nil) if err != nil { @@ -161,7 +170,7 @@ func TestOldConfigReplay(t *testing.T) { // TestValidConfigChange tests the happy path of updating a config value with no defaultModificationPolicy func TestValidConfigChange(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), defaultInitializer(), nil) if err != nil { @@ -190,7 +199,7 @@ func TestValidConfigChange(t *testing.T) { // config values while advancing another func TestConfigChangeRegressedSequence(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 1, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 1, []byte("foo"))), defaultInitializer(), nil) if err != nil { @@ -213,7 +222,7 @@ func TestConfigChangeRegressedSequence(t *testing.T) { // config values while advancing another func TestConfigChangeOldSequence(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 1, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 1, []byte("foo"))), defaultInitializer(), nil) if err != nil { @@ -236,7 +245,7 @@ func TestConfigChangeOldSequence(t *testing.T) { // by omitting them in the new config func TestConfigImplicitDelete(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope( + makeEnvelopeConfig( defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo")), makeConfigPair("bar", "bar", 0, []byte("bar")), @@ -261,7 +270,7 @@ func TestConfigImplicitDelete(t *testing.T) { // TestEmptyConfigUpdate tests to make sure that an empty config is rejected as an update func TestEmptyConfigUpdate(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), defaultInitializer(), nil) if err != nil { @@ -281,7 +290,7 @@ func TestEmptyConfigUpdate(t *testing.T) { // increasing the config item's LastModified func TestSilentConfigModification(t *testing.T) { cm, err := NewManagerImpl( - makeConfigEnvelope( + makeEnvelopeConfig( defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo")), makeConfigPair("bar", "bar", 0, []byte("bar")), @@ -309,7 +318,7 @@ func TestSilentConfigModification(t *testing.T) { func TestConfigChangeViolatesPolicy(t *testing.T) { initializer := defaultInitializer() cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), initializer, nil) if err != nil { @@ -331,7 +340,7 @@ func TestConfigChangeViolatesPolicy(t *testing.T) { func TestUnchangedConfigViolatesPolicy(t *testing.T) { initializer := defaultInitializer() cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), initializer, nil) if err != nil { @@ -369,7 +378,7 @@ func TestUnchangedConfigViolatesPolicy(t *testing.T) { func TestInvalidProposal(t *testing.T) { initializer := defaultInitializer() cm, err := NewManagerImpl( - makeConfigEnvelope(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig(defaultChain, makeConfigPair("foo", "foo", 0, []byte("foo"))), initializer, nil) if err != nil { @@ -391,7 +400,7 @@ func TestMissingHeader(t *testing.T) { group := cb.NewConfigGroup() group.Values["foo"] = &cb.ConfigValue{} _, err := NewManagerImpl( - &cb.ConfigEnvelope{Config: &cb.Config{Channel: group}}, + &cb.Envelope{Payload: utils.MarshalOrPanic(&cb.Payload{Data: utils.MarshalOrPanic(&cb.ConfigEnvelope{Config: &cb.Config{ChannelGroup: group}})})}, defaultInitializer(), nil) if err == nil { @@ -402,7 +411,7 @@ func TestMissingHeader(t *testing.T) { // TestMissingChainID checks that a config item with a missing chainID causes the config to be rejected func TestMissingChainID(t *testing.T) { _, err := NewManagerImpl( - makeConfigEnvelope("", makeConfigPair("foo", "foo", 0, []byte("foo"))), + makeEnvelopeConfig("", makeConfigPair("foo", "foo", 0, []byte("foo"))), defaultInitializer(), nil) if err == nil { diff --git a/common/configtx/template.go b/common/configtx/template.go index 41099cb369a..90e3147a786 100644 --- a/common/configtx/template.go +++ b/common/configtx/template.go @@ -70,11 +70,8 @@ func NewSimpleTemplate(configGroups ...*cb.ConfigGroup) Template { // Envelope returns a ConfigUpdateEnvelope for the given chainID func (st *simpleTemplate) Envelope(chainID string) (*cb.ConfigUpdateEnvelope, error) { config, err := proto.Marshal(&cb.ConfigUpdate{ - Header: &cb.ChannelHeader{ - ChannelId: chainID, - Type: int32(cb.HeaderType_CONFIG), - }, - WriteSet: st.configGroup, + ChannelId: chainID, + WriteSet: st.configGroup, }) if err != nil { @@ -146,11 +143,8 @@ func (ct *compositeTemplate) Envelope(chainID string) (*cb.ConfigUpdateEnvelope, } marshaledConfig, err := proto.Marshal(&cb.ConfigUpdate{ - Header: &cb.ChannelHeader{ - ChannelId: chainID, - Type: int32(cb.HeaderType_CONFIG), - }, - WriteSet: channel, + ChannelId: chainID, + WriteSet: channel, }) if err != nil { return nil, err diff --git a/common/configtx/update.go b/common/configtx/update.go index 3f1377b3308..29491c049f9 100644 --- a/common/configtx/update.go +++ b/common/configtx/update.go @@ -36,8 +36,8 @@ func (cm *configManager) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelop return nil, err } - if config.Header == nil { - return nil, fmt.Errorf("Must have header set") + if config.ChannelId != cm.chainID { + return nil, fmt.Errorf("Update not for correct channel: %s for %s", config.ChannelId, cm.chainID) } seq := computeSequence(config.WriteSet) @@ -55,11 +55,6 @@ func (cm *configManager) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelop return nil, fmt.Errorf("Config sequence number jumped from %d to %d", cm.sequence, seq) } - // Verify config is intended for this globally unique chain ID - if config.Header.ChannelId != cm.chainID { - return nil, fmt.Errorf("Config is for the wrong chain, expected %s, got %s", cm.chainID, config.Header.ChannelId) - } - configMap, err := mapConfig(config.WriteSet) if err != nil { return nil, err @@ -149,7 +144,7 @@ func envelopeToConfigUpdate(configtx *cb.Envelope) (*cb.ConfigUpdateEnvelope, er return nil, err } - if payload.Header == nil /* || payload.Header.ChannelHeader == nil */ { + if payload.Header == nil { return nil, fmt.Errorf("Envelope must have a Header") } diff --git a/common/configtx/util.go b/common/configtx/util.go index a4c83f40eb9..eca9f4266b9 100644 --- a/common/configtx/util.go +++ b/common/configtx/util.go @@ -17,10 +17,7 @@ limitations under the License. package configtx import ( - "fmt" - cb "github.com/hyperledger/fabric/protos/common" - "github.com/hyperledger/fabric/protos/utils" "github.com/golang/protobuf/proto" ) @@ -100,22 +97,3 @@ func UnmarshalConfigEnvelopeOrPanic(data []byte) *cb.ConfigEnvelope { } return result } - -// ConfigEnvelopeFromBlock extract the config envelope from a config block -func ConfigEnvelopeFromBlock(block *cb.Block) (*cb.ConfigEnvelope, error) { - if block.Data == nil || len(block.Data.Data) != 1 { - return nil, fmt.Errorf("Not a config block, must contain exactly one tx") - } - - envelope, err := utils.UnmarshalEnvelope(block.Data.Data[0]) - if err != nil { - return nil, err - } - - payload, err := utils.UnmarshalPayload(envelope.Payload) - if err != nil { - return nil, err - } - - return UnmarshalConfigEnvelope(payload.Data) -} diff --git a/common/genesis/genesis.go b/common/genesis/genesis.go index 3c4399b6e03..d443b65fad7 100644 --- a/common/genesis/genesis.go +++ b/common/genesis/genesis.go @@ -58,7 +58,7 @@ func (f *factory) Block(chainID string) (*cb.Block, error) { payloadChannelHeader := utils.MakeChannelHeader(cb.HeaderType_CONFIG, msgVersion, chainID, epoch) payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic()) payloadHeader := utils.MakePayloadHeader(payloadChannelHeader, payloadSignatureHeader) - payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigEnvelope{Config: &cb.Config{Header: configUpdate.Header, Channel: configUpdate.WriteSet}})} + payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(&cb.ConfigEnvelope{Config: &cb.Config{ChannelGroup: configUpdate.WriteSet}})} envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil} block := cb.NewBlock(0, nil) diff --git a/core/peer/peer.go b/core/peer/peer.go index 536da17c545..fc683ee32c4 100644 --- a/core/peer/peer.go +++ b/core/peer/peer.go @@ -164,7 +164,7 @@ func getCurrConfigBlockFromLedger(ledger ledger.PeerLedger) (*common.Block, erro // createChain creates a new chain object and insert it into the chains func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error { - configEnvelope, err := configtx.ConfigEnvelopeFromBlock(cb) + envelopeConfig, err := utils.ExtractEnvelope(cb, 0) if err != nil { return err } @@ -181,7 +181,7 @@ func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error { } configtxManager, err := configtx.NewManagerImpl( - configEnvelope, + envelopeConfig, configtxInitializer, []func(cm configtxapi.Manager){gossipCallbackWrapper}, ) diff --git a/orderer/configupdate/configupdate.go b/orderer/configupdate/configupdate.go index 691e0b24d62..bb3e14d4340 100644 --- a/orderer/configupdate/configupdate.go +++ b/orderer/configupdate/configupdate.go @@ -136,8 +136,7 @@ func createInitialConfig(envConfigUpdate *cb.Envelope) (*cb.ConfigEnvelope, erro return &cb.ConfigEnvelope{ Config: &cb.Config{ - Header: configUpdate.Header, - Channel: configUpdate.WriteSet, + ChannelGroup: configUpdate.WriteSet, }, LastUpdate: envConfigUpdate, diff --git a/orderer/configupdate/configupdate_test.go b/orderer/configupdate/configupdate_test.go index d361b86d904..e0112fc1dab 100644 --- a/orderer/configupdate/configupdate_test.go +++ b/orderer/configupdate/configupdate_test.go @@ -111,8 +111,8 @@ func testConfigUpdate() *cb.Envelope { }, Data: utils.MarshalOrPanic(&cb.ConfigUpdateEnvelope{ ConfigUpdate: utils.MarshalOrPanic(&cb.ConfigUpdate{ - Header: ch, - WriteSet: cb.NewConfigGroup(), + ChannelId: ch.ChannelId, + WriteSet: cb.NewConfigGroup(), }), }), }), diff --git a/orderer/multichain/manager.go b/orderer/multichain/manager.go index ef16d870776..b2f7cbd881a 100644 --- a/orderer/multichain/manager.go +++ b/orderer/multichain/manager.go @@ -17,8 +17,6 @@ limitations under the License. package multichain import ( - "fmt" - "github.com/hyperledger/fabric/common/configtx" configtxapi "github.com/hyperledger/fabric/common/configtx/api" configvaluesapi "github.com/hyperledger/fabric/common/configvalues" @@ -27,7 +25,6 @@ import ( "github.com/hyperledger/fabric/protos/utils" "github.com/op/go-logging" - "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/common/crypto" ) @@ -141,38 +138,14 @@ func (ml *multiLedger) GetChain(chainID string) (ChainSupport, bool) { return cs, ok } -func newConfigResources(configEnvelope *cb.ConfigEnvelope) (*configResources, error) { - initializer := configtx.NewInitializer() - configManager, err := configtx.NewManagerImpl(configEnvelope, initializer, nil) - if err != nil { - return nil, fmt.Errorf("Error unpacking config transaction: %s", err) - } - - return &configResources{ - Manager: configManager, - }, nil -} - func (ml *multiLedger) newLedgerResources(configTx *cb.Envelope) *ledgerResources { - payload := &cb.Payload{} - err := proto.Unmarshal(configTx.Payload, payload) - if err != nil { - logger.Fatalf("Error unmarshaling a config transaction payload: %s", err) - } - - configEnvelope := &cb.ConfigEnvelope{} - err = proto.Unmarshal(payload.Data, configEnvelope) - if err != nil { - logger.Fatalf("Error unmarshaling a config transaction to config envelope: %s", err) - } - - configResources, err := newConfigResources(configEnvelope) - + initializer := configtx.NewInitializer() + configManager, err := configtx.NewManagerImpl(configTx, initializer, nil) if err != nil { logger.Fatalf("Error creating configtx manager and handlers: %s", err) } - chainID := configResources.ChainID() + chainID := configManager.ChainID() ledger, err := ml.ledgerFactory.GetOrCreate(chainID) if err != nil { @@ -180,7 +153,7 @@ func (ml *multiLedger) newLedgerResources(configTx *cb.Envelope) *ledgerResource } return &ledgerResources{ - configResources: configResources, + configResources: &configResources{Manager: configManager}, ledger: ledger, } } diff --git a/orderer/multichain/systemchain.go b/orderer/multichain/systemchain.go index c47386a95e4..bbae1c161f4 100644 --- a/orderer/multichain/systemchain.go +++ b/orderer/multichain/systemchain.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/hyperledger/fabric/common/configtx" + configtxapi "github.com/hyperledger/fabric/common/configtx/api" configvaluesapi "github.com/hyperledger/fabric/common/configvalues" configtxorderer "github.com/hyperledger/fabric/common/configvalues/channel/orderer" "github.com/hyperledger/fabric/common/policies" @@ -175,7 +176,7 @@ func (scf *systemChainFilter) authorize(configEnvelope *cb.ConfigEnvelope) error return nil } -func (scf *systemChainFilter) inspect(configResources *configResources) error { +func (scf *systemChainFilter) inspect(configManager configtxapi.Resources) error { // XXX decide what it is that we will require to be the same in the new config, and what will be allowed to be different // Are all keys allowed? etc. @@ -214,11 +215,12 @@ func (scf *systemChainFilter) authorizeAndInspect(configTx *cb.Envelope) error { return err } - configResources, err := newConfigResources(configEnvelope) + initializer := configtx.NewInitializer() + configManager, err := configtx.NewManagerImpl(configTx, initializer, nil) if err != nil { return fmt.Errorf("Failed to create config manager and handlers: %s", err) } // Make sure that the config does not modify any of the orderer - return scf.inspect(configResources) + return scf.inspect(configManager) } diff --git a/orderer/multichain/util_test.go b/orderer/multichain/util_test.go index 6a603fab532..2cd452ca3d0 100644 --- a/orderer/multichain/util_test.go +++ b/orderer/multichain/util_test.go @@ -115,7 +115,7 @@ func makeConfigTxFromConfigUpdateEnvelope(chainID string, configUpdateEnv *cb.Co panic(err) } configTx, err := utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, chainID, mockCrypto(), &cb.ConfigEnvelope{ - Config: &cb.Config{Header: &cb.ChannelHeader{ChannelId: chainID}, Channel: configtx.UnmarshalConfigUpdateOrPanic(configUpdateEnv.ConfigUpdate).WriteSet}, + Config: &cb.Config{ChannelGroup: configtx.UnmarshalConfigUpdateOrPanic(configUpdateEnv.ConfigUpdate).WriteSet}, LastUpdate: configUpdateTx}, msgVersion, epoch) if err != nil { diff --git a/protos/common/configtx.pb.go b/protos/common/configtx.pb.go index 4006009d990..a3858f2fe75 100644 --- a/protos/common/configtx.pb.go +++ b/protos/common/configtx.pb.go @@ -108,8 +108,8 @@ func (*ConfigPolicySchema) Descriptor() ([]byte, []int) { return fileDescriptor1 // Config represents the config for a particular channel type Config struct { - Header *ChannelHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Channel *ConfigGroup `protobuf:"bytes,2,opt,name=channel" json:"channel,omitempty"` + Sequence uint64 `protobuf:"varint,1,opt,name=sequence" json:"sequence,omitempty"` + ChannelGroup *ConfigGroup `protobuf:"bytes,2,opt,name=channel_group,json=channelGroup" json:"channel_group,omitempty"` } func (m *Config) Reset() { *m = Config{} } @@ -117,16 +117,9 @@ func (m *Config) String() string { return proto.CompactTextString(m) func (*Config) ProtoMessage() {} func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } -func (m *Config) GetHeader() *ChannelHeader { +func (m *Config) GetChannelGroup() *ConfigGroup { if m != nil { - return m.Header - } - return nil -} - -func (m *Config) GetChannel() *ConfigGroup { - if m != nil { - return m.Channel + return m.ChannelGroup } return nil } @@ -158,9 +151,9 @@ func (m *ConfigUpdateEnvelope) GetSignatures() []*ConfigSignature { // 4. Each policy is checked against the signatures from the ConfigUpdateEnvelope, any failing to verify are rejected // 5. The write_set is applied to the Config and the ConfigGroupSchema verifies that the updates were legal type ConfigUpdate struct { - Header *ChannelHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - ReadSet *ConfigGroup `protobuf:"bytes,2,opt,name=read_set,json=readSet" json:"read_set,omitempty"` - WriteSet *ConfigGroup `protobuf:"bytes,3,opt,name=write_set,json=writeSet" json:"write_set,omitempty"` + ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId" json:"channel_id,omitempty"` + ReadSet *ConfigGroup `protobuf:"bytes,2,opt,name=read_set,json=readSet" json:"read_set,omitempty"` + WriteSet *ConfigGroup `protobuf:"bytes,3,opt,name=write_set,json=writeSet" json:"write_set,omitempty"` } func (m *ConfigUpdate) Reset() { *m = ConfigUpdate{} } @@ -168,13 +161,6 @@ func (m *ConfigUpdate) String() string { return proto.CompactTextStri func (*ConfigUpdate) ProtoMessage() {} func (*ConfigUpdate) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} } -func (m *ConfigUpdate) GetHeader() *ChannelHeader { - if m != nil { - return m.Header - } - return nil -} - func (m *ConfigUpdate) GetReadSet() *ConfigGroup { if m != nil { return m.ReadSet @@ -281,46 +267,47 @@ func init() { func init() { proto.RegisterFile("common/configtx.proto", fileDescriptor1) } var fileDescriptor1 = []byte{ - // 652 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x6e, 0xda, 0x4c, - 0x10, 0x15, 0x38, 0x71, 0xc2, 0x40, 0x7e, 0xbe, 0x85, 0xe8, 0x73, 0x51, 0xab, 0xa6, 0xae, 0x9a, - 0x26, 0xad, 0x80, 0x34, 0xbd, 0xa0, 0xaa, 0x94, 0x9b, 0x46, 0x51, 0x7b, 0x15, 0xb5, 0xa6, 0x3f, - 0x52, 0x54, 0x09, 0x19, 0x7b, 0x01, 0x2b, 0xc6, 0x6b, 0xad, 0x17, 0x5a, 0x9e, 0xa6, 0x0f, 0xd6, - 0x37, 0xe8, 0x53, 0x54, 0xde, 0x1f, 0x77, 0x0d, 0x06, 0x94, 0x2b, 0xd8, 0x99, 0x73, 0xce, 0xcc, - 0x8e, 0xe7, 0x68, 0xe1, 0xc8, 0x23, 0x93, 0x09, 0x89, 0x3a, 0x1e, 0x89, 0x86, 0xc1, 0x88, 0xfd, - 0x6c, 0xc7, 0x94, 0x30, 0x82, 0x4c, 0x11, 0x6e, 0xd6, 0xb3, 0x74, 0xfa, 0x23, 0x92, 0x4d, 0xc5, - 0x89, 0x49, 0x18, 0x78, 0x01, 0x4e, 0x44, 0xd8, 0xbe, 0x83, 0xfd, 0x2b, 0xae, 0x72, 0x1d, 0xcd, - 0x70, 0x48, 0x62, 0x8c, 0x4e, 0xc0, 0x14, 0xba, 0x56, 0xe9, 0xb8, 0x74, 0x5a, 0xbd, 0xd8, 0x6f, - 0x4b, 0x1d, 0x81, 0x73, 0x64, 0x16, 0xbd, 0x82, 0x6a, 0xe8, 0x26, 0xac, 0x3f, 0x8d, 0x7d, 0x97, - 0x61, 0xab, 0xcc, 0xc1, 0x87, 0x0a, 0xac, 0xe4, 0x1c, 0x48, 0x41, 0x5f, 0x38, 0xc6, 0xfe, 0x6d, - 0xc0, 0x7f, 0x42, 0xe5, 0x3d, 0x25, 0xd3, 0xb8, 0xe7, 0x8d, 0xf1, 0xc4, 0x45, 0x97, 0x60, 0x8e, - 0xd2, 0x63, 0x62, 0x95, 0x8e, 0x8d, 0xd3, 0xea, 0xc5, 0xb3, 0x7c, 0x41, 0x0d, 0xda, 0xe6, 0xff, - 0x93, 0xeb, 0x88, 0xd1, 0xb9, 0x23, 0x49, 0x29, 0x7d, 0xe6, 0x86, 0x53, 0x9c, 0x58, 0xe5, 0x4d, - 0xf4, 0xaf, 0x1c, 0x27, 0xe9, 0x82, 0x84, 0xae, 0x60, 0x57, 0x8d, 0xc4, 0x32, 0xb8, 0xc0, 0xf3, - 0xd5, 0x02, 0x1f, 0x25, 0x52, 0x48, 0x64, 0xc4, 0xe6, 0x67, 0xa8, 0x6a, 0xad, 0xa1, 0x43, 0x30, - 0xee, 0xf0, 0x9c, 0xcf, 0xaf, 0xe2, 0xa4, 0x7f, 0x51, 0x07, 0xb6, 0x79, 0x3d, 0x39, 0xa6, 0x07, - 0x2b, 0x4b, 0x38, 0x02, 0xf7, 0xb6, 0xfc, 0xa6, 0x94, 0xaa, 0x6a, 0x1d, 0xdf, 0x5b, 0x95, 0x73, - 0x97, 0x55, 0xbf, 0xc1, 0x5e, 0xee, 0x1a, 0x05, 0xba, 0xe7, 0x79, 0xdd, 0x66, 0x5e, 0x97, 0xb3, - 0xe7, 0x4b, 0xc2, 0x76, 0x5d, 0x7d, 0x5c, 0xad, 0xb0, 0xdd, 0x00, 0xb4, 0xcc, 0xb2, 0x87, 0x60, - 0x8a, 0x28, 0x6a, 0x81, 0x39, 0xc6, 0xae, 0x8f, 0xa9, 0xdc, 0xb6, 0xa3, 0xac, 0xd6, 0xd8, 0x8d, - 0x22, 0x1c, 0x7e, 0xe0, 0x49, 0x47, 0x82, 0x50, 0x0b, 0x76, 0x3c, 0x91, 0x90, 0xbd, 0xd5, 0x0b, - 0x26, 0xe9, 0x28, 0x8c, 0xcd, 0xa0, 0x21, 0xe2, 0x62, 0x01, 0xb3, 0x1d, 0x7f, 0x0a, 0x7b, 0x62, - 0x8b, 0xd5, 0xf6, 0xa6, 0xc5, 0x6b, 0x4e, 0xcd, 0xd3, 0xc0, 0xa8, 0x0b, 0x90, 0x04, 0xa3, 0xc8, - 0x65, 0x53, 0x9a, 0x2d, 0xd7, 0xff, 0xf9, 0x72, 0x3d, 0x95, 0x77, 0x34, 0xa8, 0xfd, 0xab, 0x04, - 0x35, 0xbd, 0xec, 0x7d, 0x2f, 0xd9, 0x86, 0x5d, 0x8a, 0x5d, 0xbf, 0x9f, 0x60, 0xb6, 0xf6, 0x96, - 0x29, 0xa8, 0x87, 0x19, 0x3a, 0x87, 0xca, 0x0f, 0x1a, 0x30, 0xcc, 0x09, 0xc6, 0x6a, 0xc2, 0x2e, - 0x47, 0xf5, 0x30, 0xb3, 0xff, 0x18, 0x50, 0xd5, 0x32, 0xc8, 0x82, 0x9d, 0x19, 0xa6, 0x49, 0x40, - 0x22, 0xde, 0xe1, 0x96, 0xa3, 0x8e, 0xa8, 0x9b, 0x99, 0x53, 0x0c, 0xe0, 0x71, 0x81, 0x70, 0xa1, - 0x2d, 0xbb, 0x99, 0x2d, 0x8d, 0xd5, 0xc4, 0x22, 0x43, 0x5e, 0x6a, 0x86, 0xdc, 0xe2, 0xd4, 0x27, - 0x45, 0xd4, 0x15, 0x56, 0x44, 0x8f, 0x00, 0x26, 0xc4, 0xef, 0xf3, 0xf3, 0xdc, 0xda, 0xe6, 0x4b, - 0x5d, 0x99, 0x10, 0x5f, 0xec, 0x5f, 0xf3, 0x66, 0x93, 0x53, 0xcf, 0xf2, 0xbb, 0x5f, 0x38, 0x48, - 0xcd, 0x4d, 0x37, 0x9b, 0x3c, 0xba, 0x5e, 0x8f, 0x73, 0x75, 0xbd, 0x4f, 0x9b, 0xdd, 0xf9, 0x22, - 0xaf, 0xd8, 0x28, 0x72, 0xa7, 0xee, 0xcb, 0xef, 0xea, 0x5b, 0xf3, 0x62, 0x6b, 0xbe, 0x75, 0x43, - 0x17, 0xae, 0x49, 0x89, 0x85, 0x81, 0x1a, 0x0b, 0x03, 0xb5, 0x89, 0xda, 0x75, 0x71, 0x5e, 0x23, - 0x7f, 0x02, 0xa6, 0x14, 0x29, 0xe7, 0x1f, 0x16, 0xd9, 0xb2, 0xcc, 0x6e, 0x2a, 0x78, 0x0b, 0x07, - 0x0b, 0xe6, 0x43, 0x67, 0x70, 0x98, 0xd9, 0xaf, 0xaf, 0x39, 0xad, 0xe6, 0x1c, 0x64, 0x71, 0xe1, - 0x31, 0xf4, 0x10, 0x2a, 0x59, 0x48, 0xde, 0xf3, 0x5f, 0xe0, 0x5d, 0xeb, 0xf6, 0xe5, 0x28, 0x60, - 0xe3, 0xe9, 0x20, 0x6d, 0xad, 0x33, 0x9e, 0xc7, 0x98, 0x86, 0xd8, 0x1f, 0x61, 0xda, 0x19, 0xba, - 0x03, 0x1a, 0x78, 0x1d, 0xfe, 0x68, 0x26, 0xf2, 0x65, 0x1d, 0x98, 0xfc, 0xf8, 0xfa, 0x6f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x72, 0x14, 0xff, 0x97, 0x90, 0x07, 0x00, 0x00, + // 663 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x55, 0xdb, 0x6e, 0xd3, 0x40, + 0x10, 0x55, 0xe2, 0xd6, 0x4d, 0x26, 0xe9, 0x85, 0x4d, 0x10, 0xc6, 0x02, 0x51, 0x8c, 0x28, 0x2d, + 0x88, 0xa4, 0x94, 0x87, 0x54, 0x48, 0x7d, 0xa1, 0xaa, 0x80, 0x97, 0x0a, 0x1c, 0x2e, 0x52, 0x85, + 0x88, 0x1c, 0x7b, 0x9b, 0x58, 0x75, 0xbc, 0xc6, 0x5e, 0x07, 0xf2, 0x15, 0x7c, 0x20, 0x7f, 0xc0, + 0x57, 0x20, 0xef, 0xc5, 0xac, 0x13, 0x27, 0x11, 0x4f, 0xc9, 0xcc, 0x9c, 0x73, 0x66, 0x77, 0x76, + 0x8e, 0x0c, 0xb7, 0x5d, 0x32, 0x99, 0x90, 0xb0, 0xeb, 0x92, 0xf0, 0xda, 0x1f, 0xd1, 0x9f, 0x9d, + 0x28, 0x26, 0x94, 0x20, 0x9d, 0xa7, 0xcd, 0x56, 0x5e, 0xce, 0x7e, 0x78, 0xd1, 0x94, 0x9c, 0x88, + 0x04, 0xbe, 0xeb, 0xe3, 0x84, 0xa7, 0xad, 0x1b, 0xd8, 0x39, 0x67, 0x2a, 0x17, 0xe1, 0x14, 0x07, + 0x24, 0xc2, 0xe8, 0x00, 0x74, 0xae, 0x6b, 0x54, 0xf6, 0x2b, 0x87, 0x8d, 0x93, 0x9d, 0x8e, 0xd0, + 0xe1, 0x38, 0x5b, 0x54, 0xd1, 0x0b, 0x68, 0x04, 0x4e, 0x42, 0x07, 0x69, 0xe4, 0x39, 0x14, 0x1b, + 0x55, 0x06, 0xde, 0x93, 0x60, 0x29, 0x67, 0x43, 0x06, 0xfa, 0xc4, 0x30, 0xd6, 0x6f, 0x0d, 0x6e, + 0x71, 0x95, 0x37, 0x31, 0x49, 0xa3, 0xbe, 0x3b, 0xc6, 0x13, 0x07, 0x9d, 0x81, 0x3e, 0xca, 0xc2, + 0xc4, 0xa8, 0xec, 0x6b, 0x87, 0x8d, 0x93, 0xc7, 0xc5, 0x86, 0x0a, 0xb4, 0xc3, 0xfe, 0x27, 0x17, + 0x21, 0x8d, 0x67, 0xb6, 0x20, 0x65, 0xf4, 0xa9, 0x13, 0xa4, 0x38, 0x31, 0xaa, 0xeb, 0xe8, 0x9f, + 0x19, 0x4e, 0xd0, 0x39, 0x09, 0x9d, 0x43, 0x4d, 0x8e, 0xc4, 0xd0, 0x98, 0xc0, 0x93, 0xe5, 0x02, + 0xef, 0x05, 0x92, 0x4b, 0xe4, 0x44, 0xf3, 0x23, 0x34, 0x94, 0xa3, 0xa1, 0x3d, 0xd0, 0x6e, 0xf0, + 0x8c, 0xcd, 0xaf, 0x6e, 0x67, 0x7f, 0x51, 0x17, 0x36, 0x59, 0x3f, 0x31, 0xa6, 0xbb, 0x4b, 0x5b, + 0xd8, 0x1c, 0xf7, 0xaa, 0x7a, 0x5a, 0xc9, 0x54, 0x95, 0x13, 0xff, 0xb7, 0x2a, 0xe3, 0x2e, 0xaa, + 0x7e, 0x81, 0xed, 0xc2, 0x35, 0x4a, 0x74, 0x8f, 0x8b, 0xba, 0x66, 0x51, 0x97, 0xb1, 0x67, 0x0b, + 0xc2, 0x56, 0x4b, 0x3e, 0xae, 0xd2, 0xd8, 0x6a, 0x03, 0x5a, 0x64, 0x59, 0xdf, 0x40, 0xe7, 0x59, + 0x64, 0x42, 0x2d, 0xc1, 0xdf, 0x53, 0x1c, 0xba, 0x98, 0x9d, 0x60, 0xc3, 0xce, 0x63, 0x74, 0x0a, + 0xdb, 0xee, 0xd8, 0x09, 0x43, 0x1c, 0x0c, 0xd8, 0x5b, 0x8b, 0xe3, 0xb4, 0x4a, 0x86, 0x67, 0x37, + 0x05, 0x92, 0x45, 0x16, 0x85, 0x36, 0x2f, 0xf2, 0xc5, 0xcb, 0x77, 0xfb, 0x11, 0x6c, 0xf3, 0xed, + 0x95, 0x5b, 0x9b, 0xb5, 0x6c, 0xda, 0x4d, 0x57, 0x01, 0xa3, 0x1e, 0x40, 0xe2, 0x8f, 0x42, 0x87, + 0xa6, 0x71, 0xbe, 0x54, 0x77, 0x8a, 0x3d, 0xfb, 0xb2, 0x6e, 0x2b, 0x50, 0xeb, 0x57, 0x05, 0x9a, + 0x6a, 0x5b, 0x74, 0x1f, 0x40, 0x5e, 0xc0, 0xf7, 0xc4, 0x80, 0xeb, 0x22, 0xf3, 0xce, 0x43, 0x1d, + 0xa8, 0xc5, 0xd8, 0xf1, 0x06, 0x09, 0xa6, 0xab, 0xae, 0xb6, 0x95, 0x81, 0xfa, 0x98, 0xa2, 0x63, + 0xa8, 0xff, 0x88, 0x7d, 0x8a, 0x19, 0x41, 0x5b, 0x4e, 0xa8, 0x31, 0x54, 0x1f, 0x53, 0xeb, 0x8f, + 0x06, 0x0d, 0xa5, 0x82, 0x0c, 0xd8, 0x9a, 0xe2, 0x38, 0xf1, 0x49, 0x28, 0x86, 0x2d, 0x43, 0xd4, + 0xcb, 0x4d, 0xc8, 0x2f, 0xfc, 0xa0, 0x44, 0xb8, 0xd4, 0x7e, 0xbd, 0xdc, 0x7e, 0xda, 0x72, 0x62, + 0x99, 0xf1, 0xce, 0x14, 0xe3, 0x6d, 0x30, 0xea, 0xc3, 0x32, 0xea, 0x12, 0xcb, 0x65, 0xb3, 0x9d, + 0x10, 0x6f, 0xc0, 0xe2, 0x99, 0xb1, 0xc9, 0x67, 0x3b, 0x21, 0x1e, 0xdf, 0x33, 0xf3, 0x72, 0x9d, + 0x23, 0x8f, 0x8a, 0x3b, 0x5e, 0x3a, 0x48, 0xc5, 0x35, 0x97, 0xeb, 0xbc, 0xb8, 0x5a, 0x8f, 0x71, + 0x55, 0xbd, 0x0f, 0xeb, 0x5d, 0xf8, 0xb4, 0xa8, 0xd8, 0x2e, 0x73, 0xa1, 0xea, 0xbf, 0xaf, 0xf2, + 0xad, 0x59, 0xb3, 0x15, 0x6f, 0xdd, 0x56, 0x85, 0x9b, 0x42, 0x62, 0x6e, 0xa0, 0xda, 0xdc, 0x40, + 0x2d, 0x22, 0x77, 0x9b, 0xc7, 0x2b, 0xe4, 0x0f, 0x40, 0x17, 0x22, 0xd5, 0xe2, 0x07, 0x44, 0x1c, + 0x59, 0x54, 0xd7, 0x35, 0xbc, 0x82, 0xdd, 0x39, 0xb3, 0xa1, 0x23, 0xd8, 0xcb, 0xed, 0x36, 0x18, + 0x63, 0xc7, 0xc3, 0xb1, 0x70, 0xf0, 0x6e, 0x9e, 0x7f, 0xcb, 0xd2, 0xe8, 0x1e, 0xd4, 0xf3, 0x94, + 0xb8, 0xe7, 0xbf, 0xc4, 0xeb, 0xe7, 0x57, 0xcf, 0x46, 0x3e, 0x1d, 0xa7, 0xc3, 0xec, 0x68, 0xdd, + 0xf1, 0x2c, 0xc2, 0x71, 0x80, 0xbd, 0x11, 0x8e, 0xbb, 0xd7, 0xce, 0x30, 0xf6, 0xdd, 0x2e, 0xfb, + 0x38, 0x26, 0xe2, 0x0b, 0x3a, 0xd4, 0x59, 0xf8, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, + 0xff, 0x85, 0xc2, 0x78, 0x07, 0x00, 0x00, } diff --git a/protos/common/configtx.proto b/protos/common/configtx.proto index 2f641a2ce52..7498022ccd0 100644 --- a/protos/common/configtx.proto +++ b/protos/common/configtx.proto @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// XXX This is the older mechanism for specifying channel configuration -// it is intended to be removed once there is no more dependency on it. - syntax = "proto3"; import "common/common.proto"; @@ -65,8 +62,8 @@ message ConfigPolicySchema {} // Config represents the config for a particular channel message Config { - ChannelHeader header = 1; - ConfigGroup channel = 2; + uint64 sequence = 1; + ConfigGroup channel_group = 2; } message ConfigUpdateEnvelope { @@ -84,7 +81,7 @@ message ConfigUpdateEnvelope { // 4. Each policy is checked against the signatures from the ConfigUpdateEnvelope, any failing to verify are rejected // 5. The write_set is applied to the Config and the ConfigGroupSchema verifies that the updates were legal message ConfigUpdate { - ChannelHeader header = 1; // Header scopes the update to a particular Channel + string channel_id = 1; // Which channel this config update is for ConfigGroup read_set = 2; // ReadSet explicitly lists the portion of the config which was read, this should be sparse with only Version set ConfigGroup write_set = 3; // WriteSet lists the portion of the config which was written, this should included updated Versions } diff --git a/protos/utils/commonutils.go b/protos/utils/commonutils.go index 3a54455ba66..0a63dc8de22 100644 --- a/protos/utils/commonutils.go +++ b/protos/utils/commonutils.go @@ -101,6 +101,34 @@ func UnmarshalEnvelope(encoded []byte) (*cb.Envelope, error) { return envelope, err } +// UnmarshalEnvelopeOfType unmarshals an envelope of the specified type, including +// the unmarshaling the payload data +func UnmarshalEnvelopeOfType(envelope *cb.Envelope, headerType cb.HeaderType, message proto.Message) (*cb.ChannelHeader, error) { + payload, err := UnmarshalPayload(envelope.Payload) + if err != nil { + return nil, err + } + + if payload.Header == nil { + return nil, fmt.Errorf("Envelope must have a Header") + } + + chdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader) + if err != nil { + return nil, fmt.Errorf("Invalid ChannelHeader") + } + + if chdr.Type != int32(headerType) { + return nil, fmt.Errorf("Not a tx of type %v", headerType) + } + + if err = proto.Unmarshal(payload.Data, message); err != nil { + return nil, fmt.Errorf("Error unmarshaling message for type %v: %s", headerType, err) + } + + return chdr, nil +} + // ExtractEnvelopeOrPanic retrieves the requested envelope from a given block and unmarshals it -- it panics if either of these operation fail. func ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope { envelope, err := ExtractEnvelope(block, index)