@@ -26,6 +26,7 @@ import (
26
26
"fmt"
27
27
28
28
"github.com/golang/protobuf/proto"
29
+ "github.com/hyperledger/fabric/common/config"
29
30
"github.com/hyperledger/fabric/common/flogging"
30
31
"github.com/hyperledger/fabric/common/policies"
31
32
"github.com/hyperledger/fabric/core/chaincode/shim"
@@ -104,19 +105,33 @@ func (e *PeerConfiger) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
104
105
105
106
switch fname {
106
107
case JoinChain :
108
+ if args [1 ] == nil {
109
+ return shim .Error ("Cannot join the channel <nil> configuration block provided" )
110
+ }
111
+
112
+ block , err := utils .GetBlockFromBlockBytes (args [1 ])
113
+ if err != nil {
114
+ return shim .Error (fmt .Sprintf ("Failed to reconstruct the genesis block, %s" , err ))
115
+ }
116
+
117
+ cid , err := utils .GetChainIDFromBlock (block )
118
+ if err != nil {
119
+ return shim .Error (fmt .Sprintf ("\" JoinChain\" request failed to extract " +
120
+ "channel id from the block due to [%s]" , err ))
121
+ }
122
+
123
+ if err := validateConfigBlock (block ); err != nil {
124
+ return shim .Error (fmt .Sprintf ("\" JoinChain\" for chainID = %s failed because of validation " +
125
+ "of configuration block, because of %s" , cid , err ))
126
+ }
127
+
107
128
// 2. check local MSP Admins policy
108
129
if err = e .policyChecker .CheckPolicyNoChannel (mgmt .Admins , sp ); err != nil {
109
- cid , e := utils .GetChainIDFromBlockBytes (args [1 ])
110
- errorString := fmt .Sprintf ("\" JoinChain\" request failed authorization check " +
111
- "for channel [%s]: [%s]" , cid , err )
112
- if e != nil {
113
- errorString = fmt .Sprintf ("\" JoinChain\" request failed authorization [%s] and unable " +
114
- "to extract channel id from the block due to [%s]" , err , e )
115
- }
116
- return shim .Error (errorString )
130
+ return shim .Error (fmt .Sprintf ("\" JoinChain\" request failed authorization check " +
131
+ "for channel [%s]: [%s]" , cid , err ))
117
132
}
118
133
119
- return joinChain (args [ 1 ] )
134
+ return joinChain (cid , block )
120
135
case GetConfigBlock :
121
136
// 2. check the channel reader policy
122
137
if err = e .policyChecker .CheckPolicy (string (args [1 ]), policies .ChannelApplicationReaders , sp ); err != nil {
@@ -135,44 +150,55 @@ func (e *PeerConfiger) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
135
150
return shim .Error (fmt .Sprintf ("Requested function %s not found." , fname ))
136
151
}
137
152
138
- // joinChain will join the specified chain in the configuration block.
139
- // Since it is the first block, it is the genesis block containing configuration
140
- // for this chain, so we want to update the Chain object with this info
141
- func joinChain (blockBytes []byte ) pb.Response {
142
- block , err := extractBlock (blockBytes )
153
+ // validateConfigBlock validate configuration block to see whenever it's contains valid config transaction
154
+ func validateConfigBlock (block * common.Block ) error {
155
+ envelopeConfig , err := utils .ExtractEnvelope (block , 0 )
143
156
if err != nil {
144
- return shim . Error (fmt .Sprintf ("Failed to reconstruct the genesis block, %s" , err ))
157
+ return errors . New (fmt .Sprintf ("Failed to %s" , err ))
145
158
}
146
159
147
- if err = peer .CreateChainFromBlock (block ); err != nil {
148
- return shim .Error (err .Error ())
160
+ configEnv := & common.ConfigEnvelope {}
161
+ _ , err = utils .UnmarshalEnvelopeOfType (envelopeConfig , common .HeaderType_CONFIG , configEnv )
162
+ if err != nil {
163
+ return errors .New (fmt .Sprintf ("Bad configuration envelope: %s" , err ))
149
164
}
150
165
151
- chainID , err := utils .GetChainIDFromBlock (block )
152
- if err != nil {
153
- return shim .Error (fmt .Sprintf ("Failed to get the chain ID from the configuration block, %s" , err ))
166
+ if configEnv .Config == nil {
167
+ return errors .New ("Nil config envelope Config" )
154
168
}
155
169
156
- peer .InitChain (chainID )
170
+ if configEnv .Config .ChannelGroup == nil {
171
+ return errors .New ("Nil channel group" )
172
+ }
157
173
158
- if err := producer . SendProducerBlockEvent ( block ); err ! = nil {
159
- cnflogger . Errorf ( "Error sending block event %s" , err )
174
+ if configEnv . Config . ChannelGroup . Groups = = nil {
175
+ return errors . New ( "No channel configuration groups are available" )
160
176
}
161
177
162
- return shim .Success (nil )
178
+ _ , exists := configEnv .Config .ChannelGroup .Groups [config .ApplicationGroupKey ]
179
+ if ! exists {
180
+ return errors .New (fmt .Sprintf ("Invalid configuration block, missing %s " +
181
+ "configuration group" , config .ApplicationGroupKey ))
182
+ }
183
+
184
+ return nil
163
185
}
164
186
165
- func extractBlock (bytes []byte ) (* common.Block , error ) {
166
- if bytes == nil {
167
- return nil , errors .New ("Genesis block must not be nil." )
187
+ // joinChain will join the specified chain in the configuration block.
188
+ // Since it is the first block, it is the genesis block containing configuration
189
+ // for this chain, so we want to update the Chain object with this info
190
+ func joinChain (chainID string , block * common.Block ) pb.Response {
191
+ if err := peer .CreateChainFromBlock (block ); err != nil {
192
+ return shim .Error (err .Error ())
168
193
}
169
194
170
- block , err := utils .GetBlockFromBlockBytes (bytes )
171
- if err != nil {
172
- return nil , errors .New (fmt .Sprintf ("Failed to reconstruct the genesis block, %s" , err ))
195
+ peer .InitChain (chainID )
196
+
197
+ if err := producer .SendProducerBlockEvent (block ); err != nil {
198
+ cnflogger .Errorf ("Error sending block event %s" , err )
173
199
}
174
200
175
- return block , nil
201
+ return shim . Success ( nil )
176
202
}
177
203
178
204
// Return the current configuration block for the specified chainID. If the
0 commit comments