github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/orderer/common/msgprocessor/configupdate/configupdate.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 // Package configupdate is an implementation of the broadcast.Proccessor interface 8 // It facilitates the preprocessing of CONFIG_UPDATE transactions which can 9 // generate either new CONFIG transactions or new channel creation 10 // ORDERER_TRANSACTION messages. 11 package configupdate 12 13 import ( 14 "fmt" 15 16 configtxapi "github.com/hyperledger/fabric/common/configtx/api" 17 "github.com/hyperledger/fabric/common/crypto" 18 cb "github.com/hyperledger/fabric/protos/common" 19 "github.com/hyperledger/fabric/protos/utils" 20 21 "github.com/op/go-logging" 22 ) 23 24 var logger = logging.MustGetLogger("orderer/configupdate") 25 26 const ( 27 // These should eventually be derived from the channel support once enabled 28 msgVersion = int32(0) 29 epoch = 0 30 ) 31 32 // SupportManager provides a way for the Handler to look up the Support for a chain 33 type SupportManager interface { 34 // GetChain gets the chain support for a given ChannelId 35 GetChain(chainID string) (Support, bool) 36 37 // NewChannelConfig returns a bare bones configuration ready for channel 38 // creation request to be applied on top of it 39 NewChannelConfig(envConfigUpdate *cb.Envelope) (configtxapi.Manager, error) 40 } 41 42 // Support enumerates a subset of the full channel support function which is required for this package 43 type Support interface { 44 // ProposeConfigUpdate applies a CONFIG_UPDATE to an existing config to produce a *cb.ConfigEnvelope 45 ProposeConfigUpdate(env *cb.Envelope) (*cb.ConfigEnvelope, error) 46 } 47 48 // Processor implements the broadcast.ConfigProcessor interface. 49 type Processor struct { 50 signer crypto.LocalSigner 51 manager SupportManager 52 systemChannelID string 53 systemChannelSupport Support 54 } 55 56 // New creates a new instance of *Processor. 57 func New(systemChannelID string, supportManager SupportManager, signer crypto.LocalSigner) *Processor { 58 support, ok := supportManager.GetChain(systemChannelID) 59 if !ok { 60 logger.Panicf("Supplied a SupportManager which did not contain a system channel") 61 } 62 63 return &Processor{ 64 systemChannelID: systemChannelID, 65 manager: supportManager, 66 signer: signer, 67 systemChannelSupport: support, 68 } 69 } 70 71 func channelID(env *cb.Envelope) (string, error) { 72 envPayload, err := utils.UnmarshalPayload(env.Payload) 73 if err != nil { 74 return "", fmt.Errorf("Failing to process config update because of payload unmarshaling error: %s", err) 75 } 76 77 if envPayload.Header == nil /* || envPayload.Header.ChannelHeader == nil */ { 78 return "", fmt.Errorf("Failing to process config update because no payload header was set") 79 } 80 81 chdr, err := utils.UnmarshalChannelHeader(envPayload.Header.ChannelHeader) 82 if err != nil { 83 return "", fmt.Errorf("Failing to process config update because of channel header unmarshaling error: %s", err) 84 } 85 86 if chdr.ChannelId == "" { 87 return "", fmt.Errorf("Failing to process config update because no channel ID was set") 88 } 89 90 return chdr.ChannelId, nil 91 } 92 93 // Process takes in an envelope of type CONFIG_UPDATE and proceses it 94 // to transform it either into to a new channel creation request, or 95 // into a channel CONFIG transaction (or errors on failure) 96 func (p *Processor) Process(envConfigUpdate *cb.Envelope) (*cb.Envelope, error) { 97 channelID, err := channelID(envConfigUpdate) 98 if err != nil { 99 return nil, err 100 } 101 102 support, ok := p.manager.GetChain(channelID) 103 if ok { 104 logger.Debugf("Processing channel reconfiguration request for channel %s", channelID) 105 return p.existingChannelConfig(envConfigUpdate, channelID, support) 106 } 107 108 logger.Debugf("Processing channel creation request for channel %s", channelID) 109 return p.newChannelConfig(channelID, envConfigUpdate) 110 } 111 112 func (p *Processor) existingChannelConfig(envConfigUpdate *cb.Envelope, channelID string, support Support) (*cb.Envelope, error) { 113 configEnvelope, err := support.ProposeConfigUpdate(envConfigUpdate) 114 if err != nil { 115 return nil, err 116 } 117 118 return utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID, p.signer, configEnvelope, msgVersion, epoch) 119 } 120 121 func (p *Processor) proposeNewChannelToSystemChannel(newChannelEnvConfig *cb.Envelope) (*cb.Envelope, error) { 122 return utils.CreateSignedEnvelope(cb.HeaderType_ORDERER_TRANSACTION, p.systemChannelID, p.signer, newChannelEnvConfig, msgVersion, epoch) 123 } 124 125 func (p *Processor) newChannelConfig(channelID string, envConfigUpdate *cb.Envelope) (*cb.Envelope, error) { 126 ctxm, err := p.manager.NewChannelConfig(envConfigUpdate) 127 if err != nil { 128 return nil, err 129 } 130 131 newChannelConfigEnv, err := ctxm.ProposeConfigUpdate(envConfigUpdate) 132 if err != nil { 133 return nil, err 134 } 135 136 newChannelEnvConfig, err := utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID, p.signer, newChannelConfigEnv, msgVersion, epoch) 137 if err != nil { 138 return nil, err 139 } 140 141 return p.proposeNewChannelToSystemChannel(newChannelEnvConfig) 142 }