@@ -7,20 +7,21 @@ SPDX-License-Identifier: Apache-2.0
7
7
package msgprocessor
8
8
9
9
import (
10
- "fmt"
11
-
12
10
"github.com/hyperledger/fabric/common/channelconfig"
13
- configtxapi "github.com/hyperledger/fabric/common/configtx/api"
14
11
cb "github.com/hyperledger/fabric/protos/common"
15
12
"github.com/hyperledger/fabric/protos/utils"
16
13
17
14
"github.com/golang/protobuf/proto"
15
+ "github.com/pkg/errors"
18
16
)
19
17
20
18
// ChainCreator defines the methods necessary to simulate channel creation.
21
19
type ChainCreator interface {
22
20
// NewChannelConfig returns a template config for a new channel.
23
- NewChannelConfig (envConfigUpdate * cb.Envelope ) (configtxapi.Manager , error )
21
+ NewChannelConfig (envConfigUpdate * cb.Envelope ) (channelconfig.Resources , error )
22
+
23
+ // CreateBundle parses the config into resources
24
+ CreateBundle (channelID string , config * cb.Config ) (channelconfig.Resources , error )
24
25
25
26
// ChannelsCount returns the count of channels which currently exist.
26
27
ChannelsCount () int
@@ -51,16 +52,16 @@ func (scf *SystemChainFilter) Apply(env *cb.Envelope) error {
51
52
52
53
err := proto .Unmarshal (env .Payload , msgData )
53
54
if err != nil {
54
- return fmt .Errorf ("bad payload: %s" , err )
55
+ return errors .Errorf ("bad payload: %s" , err )
55
56
}
56
57
57
58
if msgData .Header == nil {
58
- return fmt .Errorf ("missing payload header" )
59
+ return errors .Errorf ("missing payload header" )
59
60
}
60
61
61
62
chdr , err := utils .UnmarshalChannelHeader (msgData .Header .ChannelHeader )
62
63
if err != nil {
63
- return fmt .Errorf ("bad channel header: %s" , err )
64
+ return errors .Errorf ("bad channel header: %s" , err )
64
65
}
65
66
66
67
if chdr .Type != int32 (cb .HeaderType_ORDERER_TRANSACTION ) {
@@ -76,83 +77,85 @@ func (scf *SystemChainFilter) Apply(env *cb.Envelope) error {
76
77
if maxChannels > 0 {
77
78
// We check for strictly greater than to accommodate the system channel
78
79
if uint64 (scf .cc .ChannelsCount ()) > maxChannels {
79
- return fmt .Errorf ("channel creation would exceed maximimum number of channels: %d" , maxChannels )
80
+ return errors .Errorf ("channel creation would exceed maximimum number of channels: %d" , maxChannels )
80
81
}
81
82
}
82
83
83
84
configTx := & cb.Envelope {}
84
85
err = proto .Unmarshal (msgData .Data , configTx )
85
86
if err != nil {
86
- return fmt .Errorf ("payload data error unmarshaling to envelope: %s" , err )
87
+ return errors .Errorf ("payload data error unmarshaling to envelope: %s" , err )
87
88
}
88
89
89
90
return scf .authorizeAndInspect (configTx )
90
91
}
91
92
92
- func (scf * SystemChainFilter ) authorize (configEnvelope * cb.ConfigEnvelope ) (* cb.ConfigEnvelope , error ) {
93
- if configEnvelope .LastUpdate == nil {
94
- return nil , fmt .Errorf ("updated config does not include a config update" )
95
- }
96
-
97
- configManager , err := scf .cc .NewChannelConfig (configEnvelope .LastUpdate )
98
- if err != nil {
99
- return nil , fmt .Errorf ("error constructing new channel config from update: %s" , err )
100
- }
101
-
102
- newChannelConfigEnv , err := configManager .ProposeConfigUpdate (configEnvelope .LastUpdate )
103
- if err != nil {
104
- return nil , fmt .Errorf ("error proposing channel update to new channel config: %s" , err )
105
- }
106
-
107
- err = configManager .Validate (newChannelConfigEnv )
108
- if err != nil {
109
- return nil , fmt .Errorf ("error applying channel update to new channel config: %s" , err )
110
- }
111
-
112
- return newChannelConfigEnv , nil
113
- }
114
-
115
93
func (scf * SystemChainFilter ) authorizeAndInspect (configTx * cb.Envelope ) error {
116
94
payload := & cb.Payload {}
117
95
err := proto .Unmarshal (configTx .Payload , payload )
118
96
if err != nil {
119
- return fmt .Errorf ("error unmarshaling wrapped configtx envelope payload: %s" , err )
97
+ return errors .Errorf ("error unmarshaling wrapped configtx envelope payload: %s" , err )
120
98
}
121
99
122
100
if payload .Header == nil {
123
- return fmt .Errorf ("wrapped configtx envelope missing header" )
101
+ return errors .Errorf ("wrapped configtx envelope missing header" )
124
102
}
125
103
126
104
chdr , err := utils .UnmarshalChannelHeader (payload .Header .ChannelHeader )
127
105
if err != nil {
128
- return fmt .Errorf ("error unmarshaling wrapped configtx envelope channel header: %s" , err )
106
+ return errors .Errorf ("error unmarshaling wrapped configtx envelope channel header: %s" , err )
129
107
}
130
108
131
109
if chdr .Type != int32 (cb .HeaderType_CONFIG ) {
132
- return fmt .Errorf ("wrapped configtx envelope not a config transaction" )
110
+ return errors .Errorf ("wrapped configtx envelope not a config transaction" )
133
111
}
134
112
135
113
configEnvelope := & cb.ConfigEnvelope {}
136
114
err = proto .Unmarshal (payload .Data , configEnvelope )
137
115
if err != nil {
138
- return fmt .Errorf ("error unmarshalling wrapped configtx config envelope from payload: %s" , err )
116
+ return errors .Errorf ("error unmarshalling wrapped configtx config envelope from payload: %s" , err )
117
+ }
118
+
119
+ if configEnvelope .LastUpdate == nil {
120
+ return errors .Errorf ("updated config does not include a config update" )
121
+ }
122
+
123
+ res , err := scf .cc .NewChannelConfig (configEnvelope .LastUpdate )
124
+ if err != nil {
125
+ return errors .Errorf ("error constructing new channel config from update: %s" , err )
139
126
}
140
127
141
128
// Make sure that the config was signed by the appropriate authorized entities
142
- proposedEnv , err := scf . authorize ( configEnvelope )
129
+ newChannelConfigEnv , err := res . ConfigtxManager (). ProposeConfigUpdate ( configEnvelope . LastUpdate )
143
130
if err != nil {
144
- return err
131
+ return errors . Errorf ( "error proposing channel update to new channel config: %s" , err )
145
132
}
146
133
147
134
// reflect.DeepEqual will not work here, because it considers nil and empty maps as unequal
148
- if ! proto .Equal (proposedEnv . Config , configEnvelope . Config ) {
149
- return fmt .Errorf ("config proposed by the channel creation request did not match the config received with the channel creation request" )
135
+ if ! proto .Equal (newChannelConfigEnv , configEnvelope ) {
136
+ return errors .Errorf ("config proposed by the channel creation request did not match the config received with the channel creation request" )
150
137
}
151
138
152
- // Make sure the config can be parsed into a bundle
153
- _ , err = channelconfig .NewBundle (chdr .ChannelId , configEnvelope .Config )
139
+ bundle , err := scf .cc .CreateBundle (res .ConfigtxManager ().ChainID (), newChannelConfigEnv .Config )
154
140
if err != nil {
155
- return fmt .Errorf ("failed to create config bundle: %s" , err )
141
+ return errors .Wrap (err , "config does not validly parse" )
142
+ }
143
+
144
+ if err = res .ValidateNew (bundle ); err != nil {
145
+ return errors .Wrap (err , "new bundle invalid" )
146
+ }
147
+
148
+ oc , ok := bundle .OrdererConfig ()
149
+ if ! ok {
150
+ return errors .New ("config is missing orderer group" )
151
+ }
152
+
153
+ if err = oc .Capabilities ().Supported (); err != nil {
154
+ return errors .Wrap (err , "config update is not compatible" )
155
+ }
156
+
157
+ if err = bundle .ChannelConfig ().Capabilities ().Supported (); err != nil {
158
+ return errors .Wrap (err , "config update is not compatible" )
156
159
}
157
160
158
161
return nil
0 commit comments