Skip to content

Commit 02322a1

Browse files
author
Jason Yellick
committed
[FAB-2213] Embed CONFIG_UPDATE tx in CONFIG
https://jira.hyperledger.org/browse/FAB-2213 In order to support auditability on who submitted a config update transaction, the full submitted envelope needs to be embedded into the configuration, not just the config envelope. This CR modifies the configtx proto to accommodate this. Change-Id: Id75b4206c3dff11ef71d9826e7e8e7b50dcb3700 Signed-off-by: Jason Yellick <[email protected]>
1 parent 6b78395 commit 02322a1

File tree

14 files changed

+170
-83
lines changed

14 files changed

+170
-83
lines changed

common/configtx/api/api.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ type Manager interface {
8484
Resources
8585

8686
// Apply attempts to apply a configtx to become the new config
87-
Apply(configtx *cb.ConfigUpdateEnvelope) error
87+
Apply(configtx *cb.Envelope) error
8888

8989
// Validate attempts to validate a new configtx against the current config state
90-
Validate(configtx *cb.ConfigUpdateEnvelope) error
90+
Validate(configtx *cb.Envelope) error
9191

9292
// ConfigEnvelope returns the *cb.ConfigEnvelope from the last successful Apply
9393
ConfigEnvelope() *cb.ConfigEnvelope

common/configtx/manager.go

+34-4
Original file line numberDiff line numberDiff line change
@@ -310,16 +310,46 @@ func (cm *configManager) processConfig(configtx *cb.ConfigUpdateEnvelope) (map[s
310310
return computedResult, nil
311311
}
312312

313+
func envelopeToConfigUpdate(configtx *cb.Envelope) (*cb.ConfigUpdateEnvelope, error) {
314+
payload, err := utils.UnmarshalPayload(configtx.Payload)
315+
if err != nil {
316+
return nil, err
317+
}
318+
319+
if payload.Header == nil || payload.Header.ChannelHeader == nil {
320+
return nil, fmt.Errorf("Envelope must have ChannelHeader")
321+
}
322+
323+
if payload.Header == nil || payload.Header.ChannelHeader.Type != int32(cb.HeaderType_CONFIG_UPDATE) {
324+
return nil, fmt.Errorf("Not a tx of type CONFIG_UPDATE")
325+
}
326+
327+
configUpdateEnv, err := UnmarshalConfigUpdateEnvelope(payload.Data)
328+
if err != nil {
329+
return nil, fmt.Errorf("Error unmarshaling ConfigUpdateEnvelope: %s", err)
330+
}
331+
332+
return configUpdateEnv, nil
333+
}
334+
313335
// Validate attempts to validate a new configtx against the current config state
314-
func (cm *configManager) Validate(configtx *cb.ConfigUpdateEnvelope) error {
315-
_, err := cm.processConfig(configtx)
336+
func (cm *configManager) Validate(configtx *cb.Envelope) error {
337+
configUpdateEnv, err := envelopeToConfigUpdate(configtx)
338+
if err != nil {
339+
return err
340+
}
341+
_, err = cm.processConfig(configUpdateEnv)
316342
cm.rollbackHandlers()
317343
return err
318344
}
319345

320346
// Apply attempts to apply a configtx to become the new config
321-
func (cm *configManager) Apply(configtx *cb.ConfigUpdateEnvelope) error {
322-
configMap, err := cm.processConfig(configtx)
347+
func (cm *configManager) Apply(configtx *cb.Envelope) error {
348+
configUpdateEnv, err := envelopeToConfigUpdate(configtx)
349+
if err != nil {
350+
return err
351+
}
352+
configMap, err := cm.processConfig(configUpdateEnv)
323353
if err != nil {
324354
cm.rollbackHandlers()
325355
return err

common/configtx/manager_test.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func makeConfigEnvelope(chainID string, configPairs ...*configPair) *cb.ConfigEn
7272
}
7373
}
7474

75-
func makeConfigUpdateEnvelope(chainID string, configPairs ...*configPair) *cb.ConfigUpdateEnvelope {
75+
func makeConfigUpdateEnvelope(chainID string, configPairs ...*configPair) *cb.Envelope {
7676
values := make(map[string]*cb.ConfigValue)
7777
for _, pair := range configPairs {
7878
values[pair.key] = pair.value
@@ -84,8 +84,17 @@ func makeConfigUpdateEnvelope(chainID string, configPairs ...*configPair) *cb.Co
8484
Values: values,
8585
},
8686
}
87-
return &cb.ConfigUpdateEnvelope{
88-
ConfigUpdate: utils.MarshalOrPanic(config),
87+
return &cb.Envelope{
88+
Payload: utils.MarshalOrPanic(&cb.Payload{
89+
Header: &cb.Header{
90+
ChannelHeader: &cb.ChannelHeader{
91+
Type: int32(cb.HeaderType_CONFIG_UPDATE),
92+
},
93+
},
94+
Data: utils.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
95+
ConfigUpdate: utils.MarshalOrPanic(config),
96+
}),
97+
}),
8998
}
9099
}
91100

@@ -274,7 +283,7 @@ func TestEmptyConfigUpdate(t *testing.T) {
274283
t.Fatalf("Error constructing config manager: %s", err)
275284
}
276285

277-
newConfig := &cb.ConfigUpdateEnvelope{}
286+
newConfig := &cb.Envelope{}
278287

279288
err = cm.Validate(newConfig)
280289
if err == nil {

common/configtx/template.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,17 @@ func MakeChainCreationTransaction(creationPolicy string, chainID string, signer
199199
Header: configUpdate.Header,
200200
Channel: configUpdate.WriteSet,
201201
},
202-
LastUpdate: newConfigUpdateEnv,
202+
LastUpdate: &cb.Envelope{
203+
Payload: utils.MarshalOrPanic(&cb.Payload{
204+
Header: &cb.Header{
205+
ChannelHeader: &cb.ChannelHeader{
206+
ChannelId: chainID,
207+
Type: int32(cb.HeaderType_CONFIG_UPDATE),
208+
},
209+
},
210+
Data: utils.MarshalOrPanic(newConfigUpdateEnv),
211+
}),
212+
},
203213
}
204214

205215
payloadChannelHeader := utils.MakeChannelHeader(cb.HeaderType_CONFIG, msgVersion, chainID, epoch)

common/configtx/util.go

+10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ func UnmarshalConfigUpdate(data []byte) (*cb.ConfigUpdate, error) {
4545
return configUpdate, nil
4646
}
4747

48+
// UnmarshalConfigUpdateEnvelope attempts to unmarshal bytes to a *cb.ConfigUpdate
49+
func UnmarshalConfigUpdateEnvelope(data []byte) (*cb.ConfigUpdateEnvelope, error) {
50+
configUpdateEnvelope := &cb.ConfigUpdateEnvelope{}
51+
err := proto.Unmarshal(data, configUpdateEnvelope)
52+
if err != nil {
53+
return nil, err
54+
}
55+
return configUpdateEnvelope, nil
56+
}
57+
4858
// UnmarshalConfigEnvelope attempts to unmarshal bytes to a *cb.ConfigEnvelope
4959
func UnmarshalConfigEnvelope(data []byte) (*cb.ConfigEnvelope, error) {
5060
configEnv := &cb.ConfigEnvelope{}

common/mocks/configtx/configtx.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ type Manager struct {
120120
ApplyVal error
121121

122122
// AppliedConfigUpdateEnvelope is set by Apply
123-
AppliedConfigUpdateEnvelope *cb.ConfigUpdateEnvelope
123+
AppliedConfigUpdateEnvelope *cb.Envelope
124124

125125
// ValidateVal is returned by Validate
126126
ValidateVal error
@@ -142,12 +142,12 @@ func (cm *Manager) Sequence() uint64 {
142142
}
143143

144144
// Apply returns ApplyVal
145-
func (cm *Manager) Apply(configtx *cb.ConfigUpdateEnvelope) error {
145+
func (cm *Manager) Apply(configtx *cb.Envelope) error {
146146
cm.AppliedConfigUpdateEnvelope = configtx
147147
return cm.ApplyVal
148148
}
149149

150150
// Validate returns ValidateVal
151-
func (cm *Manager) Validate(configtx *cb.ConfigUpdateEnvelope) error {
151+
func (cm *Manager) Validate(configtx *cb.Envelope) error {
152152
return cm.ValidateVal
153153
}

core/committer/txvalidator/validator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type Support interface {
4343
MSPManager() msp.MSPManager
4444

4545
// Apply attempts to apply a configtx to become the new config
46-
Apply(configtx *common.ConfigUpdateEnvelope) error
46+
Apply(configtx *common.Envelope) error
4747
}
4848

4949
//Validator interface which defines API to validate block transactions

core/mocks/txvalidator/support.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ func (ms *Support) MSPManager() msp.MSPManager {
3939
}
4040

4141
// Apply returns ApplyVal
42-
func (ms *Support) Apply(configtx *common.ConfigUpdateEnvelope) error {
42+
func (ms *Support) Apply(configtx *common.Envelope) error {
4343
return ms.ApplyVal
4444
}

orderer/common/configtxfilter/filter.go

+7-10
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ package configtxfilter
1919
import (
2020
"fmt"
2121

22+
"github.com/hyperledger/fabric/common/configtx"
2223
"github.com/hyperledger/fabric/common/configtx/api"
2324
"github.com/hyperledger/fabric/orderer/common/filter"
2425
cb "github.com/hyperledger/fabric/protos/common"
25-
26-
"github.com/golang/protobuf/proto"
26+
"github.com/hyperledger/fabric/protos/utils"
2727
)
2828

2929
type configFilter struct {
@@ -39,7 +39,7 @@ func NewFilter(manager api.Manager) filter.Rule {
3939

4040
type configCommitter struct {
4141
manager api.Manager
42-
configEnvelope *cb.ConfigUpdateEnvelope
42+
configEnvelope *cb.Envelope
4343
}
4444

4545
func (cc *configCommitter) Commit() {
@@ -55,9 +55,7 @@ func (cc *configCommitter) Isolated() bool {
5555

5656
// Apply applies the rule to the given Envelope, replying with the Action to take for the message
5757
func (cf *configFilter) Apply(message *cb.Envelope) (filter.Action, filter.Committer) {
58-
msgData := &cb.Payload{}
59-
60-
err := proto.Unmarshal(message.Payload, msgData)
58+
msgData, err := utils.UnmarshalPayload(message.Payload)
6159
if err != nil {
6260
return filter.Forward, nil
6361
}
@@ -66,19 +64,18 @@ func (cf *configFilter) Apply(message *cb.Envelope) (filter.Action, filter.Commi
6664
return filter.Forward, nil
6765
}
6866

69-
config := &cb.ConfigEnvelope{}
70-
err = proto.Unmarshal(msgData.Data, config)
67+
configEnvelope, err := configtx.UnmarshalConfigEnvelope(msgData.Data)
7168
if err != nil {
7269
return filter.Reject, nil
7370
}
7471

75-
err = cf.configManager.Validate(config.LastUpdate)
72+
err = cf.configManager.Validate(configEnvelope.LastUpdate)
7673
if err != nil {
7774
return filter.Reject, nil
7875
}
7976

8077
return filter.Accept, &configCommitter{
8178
manager: cf.configManager,
82-
configEnvelope: config.LastUpdate,
79+
configEnvelope: configEnvelope.LastUpdate,
8380
}
8481
}

orderer/common/configtxfilter/filter_test.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,19 @@ func TestAcceptGoodConfig(t *testing.T) {
4747
configUpdateEnv := &cb.ConfigUpdateEnvelope{
4848
ConfigUpdate: utils.MarshalOrPanic(configGroup),
4949
}
50-
configEnvBytes := utils.MarshalOrPanic(&cb.ConfigEnvelope{
51-
LastUpdate: configUpdateEnv,
52-
})
50+
configEnv := &cb.ConfigEnvelope{
51+
LastUpdate: &cb.Envelope{
52+
Payload: utils.MarshalOrPanic(&cb.Payload{
53+
Header: &cb.Header{
54+
ChannelHeader: &cb.ChannelHeader{
55+
Type: int32(cb.HeaderType_CONFIG_UPDATE),
56+
},
57+
},
58+
Data: utils.MarshalOrPanic(configUpdateEnv),
59+
}),
60+
},
61+
}
62+
configEnvBytes := utils.MarshalOrPanic(configEnv)
5363
configBytes := utils.MarshalOrPanic(&cb.Payload{Header: &cb.Header{ChannelHeader: &cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG)}}, Data: configEnvBytes})
5464
configEnvelope := &cb.Envelope{
5565
Payload: configBytes,
@@ -63,12 +73,10 @@ func TestAcceptGoodConfig(t *testing.T) {
6373
t.Fatal("Config transactions should be isolated to their own block")
6474
}
6575

66-
t.Logf("%+v", committer.(*configCommitter).configEnvelope)
67-
6876
committer.Commit()
6977

70-
if !reflect.DeepEqual(mcm.AppliedConfigUpdateEnvelope, configUpdateEnv) {
71-
t.Fatalf("Should have applied new config on commit got %+v and %+v", mcm.AppliedConfigUpdateEnvelope, configUpdateEnv)
78+
if !reflect.DeepEqual(mcm.AppliedConfigUpdateEnvelope, configEnv.LastUpdate) {
79+
t.Fatalf("Should have applied new config on commit got %+v and %+v", mcm.AppliedConfigUpdateEnvelope, configEnv.LastUpdate)
7280
}
7381
}
7482

orderer/multichain/systemchain.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/hyperledger/fabric/orderer/common/filter"
2525
cb "github.com/hyperledger/fabric/protos/common"
2626
ab "github.com/hyperledger/fabric/protos/orderer"
27+
"github.com/hyperledger/fabric/protos/utils"
2728

2829
"github.com/golang/protobuf/proto"
2930
)
@@ -155,8 +156,19 @@ func (sc *systemChain) authorize(configEnvelope *cb.ConfigEnvelope) cb.Status {
155156
return cb.Status_BAD_REQUEST
156157
}
157158

158-
configNext := &cb.ConfigUpdate{}
159-
err := proto.Unmarshal(configEnvelope.LastUpdate.ConfigUpdate, configNext)
159+
configEnvEnvPayload, err := utils.UnmarshalPayload(configEnvelope.LastUpdate.Payload)
160+
if err != nil {
161+
logger.Debugf("Failing to validate chain creation because of payload unmarshaling error: %s", err)
162+
return cb.Status_BAD_REQUEST
163+
}
164+
165+
configUpdateEnv, err := configtx.UnmarshalConfigUpdateEnvelope(configEnvEnvPayload.Data)
166+
if err != nil {
167+
logger.Debugf("Failing to validate chain creation because of config update envelope unmarshaling error: %s", err)
168+
return cb.Status_BAD_REQUEST
169+
}
170+
171+
configNext, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
160172
if err != nil {
161173
logger.Debugf("Failing to validate chain creation because of unmarshaling error: %s", err)
162174
return cb.Status_BAD_REQUEST
@@ -200,7 +212,7 @@ func (sc *systemChain) authorize(configEnvelope *cb.ConfigEnvelope) cb.Status {
200212
return cb.Status_INTERNAL_SERVER_ERROR
201213
}
202214

203-
signedData, err := configEnvelope.LastUpdate.AsSignedData()
215+
signedData, err := configUpdateEnv.AsSignedData()
204216
if err != nil {
205217
logger.Debugf("Failed to validate chain creation because config envelope could not be converted to signed data: %s", err)
206218
return cb.Status_BAD_REQUEST

orderer/multichain/util_test.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,17 @@ func makeConfigTxFromConfigUpdateEnvelope(chainID string, configUpdateEnv *cb.Co
114114
Header: configUpdate.Header,
115115
Channel: configUpdate.WriteSet,
116116
},
117-
LastUpdate: configUpdateEnv,
117+
LastUpdate: &cb.Envelope{
118+
Payload: utils.MarshalOrPanic(&cb.Payload{
119+
Header: &cb.Header{
120+
ChannelHeader: &cb.ChannelHeader{
121+
Type: int32(cb.HeaderType_CONFIG_UPDATE),
122+
ChannelId: chainID,
123+
},
124+
},
125+
Data: utils.MarshalOrPanic(configUpdateEnv),
126+
}),
127+
},
118128
}),
119129
}
120130
return &cb.Envelope{

0 commit comments

Comments
 (0)