Skip to content

Commit 50120eb

Browse files
author
Jason Yellick
committed
Re-enable configtx handling
Before the orderer and peer components standardized on a proto message format for shared communication, some proto messages were being unmarshaled as the wrong type, resulting in messages which looked like configuration transactions, but were not. All these transactions were then rejected because they did not apply correctly as configuration. The fabric has since standardized on a shared set of protos, so it should be safe to re-enable configuration transaction filtering. This changeset re-enables the configuration filters. Additionally, this changeset hooks the configuration transaction execution (application) into the multichain manager writerinterceptor path and adds tests for this path. Change-Id: I5ba75861812d54e19fa6eeac98174215761f9ad2 Signed-off-by: Jason Yellick <[email protected]>
1 parent ae9f2f2 commit 50120eb

File tree

3 files changed

+115
-5
lines changed

3 files changed

+115
-5
lines changed

orderer/multichain/chainsupport.go

+35-5
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ import (
2020
"github.com/hyperledger/fabric/orderer/common/blockcutter"
2121
"github.com/hyperledger/fabric/orderer/common/broadcast"
2222
"github.com/hyperledger/fabric/orderer/common/broadcastfilter"
23+
"github.com/hyperledger/fabric/orderer/common/broadcastfilter/configfilter"
2324
"github.com/hyperledger/fabric/orderer/common/configtx"
2425
"github.com/hyperledger/fabric/orderer/common/deliver"
2526
"github.com/hyperledger/fabric/orderer/common/policies"
2627
"github.com/hyperledger/fabric/orderer/common/sharedconfig"
2728
"github.com/hyperledger/fabric/orderer/rawledger"
2829
cb "github.com/hyperledger/fabric/protos/common"
30+
31+
"github.com/golang/protobuf/proto"
2932
)
3033

3134
// Consenter defines the backing ordering mechanism
@@ -112,7 +115,7 @@ func newChainSupport(configManager configtx.Manager, policyManager policies.Mana
112115
func createBroadcastRuleset(configManager configtx.Manager) *broadcastfilter.RuleSet {
113116
return broadcastfilter.NewRuleSet([]broadcastfilter.Rule{
114117
broadcastfilter.EmptyRejectRule,
115-
// configfilter.New(configManager),
118+
configfilter.New(configManager),
116119
broadcastfilter.AcceptRule,
117120
})
118121
}
@@ -153,17 +156,44 @@ func (cs *chainSupport) Enqueue(env *cb.Envelope) bool {
153156
return cs.chain.Enqueue(env)
154157
}
155158

159+
// writeInterceptor performs 'execution/processing' of blockContents before committing them to the normal passive ledger
160+
// This is intended to support reconfiguration transactions, and ultimately chain creation
156161
type writeInterceptor struct {
157-
backing rawledger.Writer
162+
configtxManager configtx.Manager
163+
backing rawledger.Writer
158164
}
159165

160-
// TODO ultimately set write interception policy by config
161-
func newWriteInterceptor(configManager configtx.Manager, backing rawledger.Writer) *writeInterceptor {
166+
func newWriteInterceptor(configtxManager configtx.Manager, backing rawledger.Writer) *writeInterceptor {
162167
return &writeInterceptor{
163-
backing: backing,
168+
backing: backing,
169+
configtxManager: configtxManager,
164170
}
165171
}
166172

167173
func (wi *writeInterceptor) Append(blockContents []*cb.Envelope, metadata [][]byte) *cb.Block {
174+
// Note that in general any errors encountered in this path are fatal.
175+
// The previous layers (broadcastfilters, blockcutter) should have scrubbed any invalid
176+
// 'executable' transactions like config before committing via Append
177+
178+
if len(blockContents) == 1 {
179+
payload := &cb.Payload{}
180+
err := proto.Unmarshal(blockContents[0].Payload, payload)
181+
if err != nil {
182+
logger.Fatalf("Asked to write a malformed envelope to the chain: %s", err)
183+
}
184+
185+
if payload.Header.ChainHeader.Type == int32(cb.HeaderType_CONFIGURATION_TRANSACTION) {
186+
configEnvelope := &cb.ConfigurationEnvelope{}
187+
err = proto.Unmarshal(payload.Data, configEnvelope)
188+
if err != nil {
189+
logger.Fatalf("Configuration envelope was malformed: %s", err)
190+
}
191+
192+
err = wi.configtxManager.Apply(configEnvelope)
193+
if err != nil {
194+
logger.Fatalf("Error applying configuration transaction which was already validated: %s", err)
195+
}
196+
}
197+
}
168198
return wi.backing.Append(blockContents, metadata)
169199
}

orderer/multichain/chainsupport_mock_test.go

+25
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,28 @@ func (mch *mockChain) Start() {
6262
func (mch *mockChain) Halt() {
6363
close(mch.queue)
6464
}
65+
66+
type mockConfigtxManager struct {
67+
config *cb.ConfigurationEnvelope
68+
}
69+
70+
func (mcm *mockConfigtxManager) Apply(configtx *cb.ConfigurationEnvelope) error {
71+
mcm.config = configtx
72+
return nil
73+
}
74+
75+
func (mcm *mockConfigtxManager) Validate(configtx *cb.ConfigurationEnvelope) error {
76+
panic("Unimplemented")
77+
}
78+
79+
func (mcm *mockConfigtxManager) ChainID() string {
80+
panic("Unimplemented")
81+
}
82+
83+
type mockLedgerWriter struct {
84+
}
85+
86+
func (mlw *mockLedgerWriter) Append(blockContents []*cb.Envelope, metadata [][]byte) *cb.Block {
87+
logger.Debugf("Committed block")
88+
return nil
89+
}
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package multichain
18+
19+
import (
20+
"testing"
21+
22+
cb "github.com/hyperledger/fabric/protos/common"
23+
)
24+
25+
func TestCommitConfig(t *testing.T) {
26+
mcm := &mockConfigtxManager{}
27+
ctx1 := makeConfigTx("foo", 0)
28+
wi := newWriteInterceptor(mcm, &mockLedgerWriter{})
29+
wi.Append([]*cb.Envelope{ctx1}, nil)
30+
if mcm.config == nil {
31+
t.Fatalf("Should have applied configuration")
32+
}
33+
}
34+
35+
func TestIgnoreMultiConfig(t *testing.T) {
36+
mcm := &mockConfigtxManager{}
37+
ctx1 := makeConfigTx("foo", 0)
38+
ctx2 := makeConfigTx("foo", 1)
39+
wi := newWriteInterceptor(mcm, &mockLedgerWriter{})
40+
wi.Append([]*cb.Envelope{ctx1, ctx2}, nil)
41+
if mcm.config != nil {
42+
t.Fatalf("Should not have applied configuration, we should only check batches with a single tx")
43+
}
44+
}
45+
46+
func TestIgnoreSingleNonConfig(t *testing.T) {
47+
mcm := &mockConfigtxManager{}
48+
ctx1 := makeNormalTx("foo", 0)
49+
wi := newWriteInterceptor(mcm, &mockLedgerWriter{})
50+
wi.Append([]*cb.Envelope{ctx1}, nil)
51+
if mcm.config != nil {
52+
t.Fatalf("Should not have applied configuration, it was a normal transaction")
53+
}
54+
55+
}

0 commit comments

Comments
 (0)