Skip to content

Commit 75909aa

Browse files
author
Jason Yellick
committed
[FAB-1523] Populate block metadata LastConfig
https://jira.hyperledger.org/browse/FAB-1523 This changeset adds new data types for Metadata and for LastConfiguration which is the second field of the block metadata. The Metadata type is intended to accomodate the other metadata fields as well, but is currently only utilized for the LastConfiguration. This changeset also populates the LastConfiguration field of the block metadata with this new data structure. Change-Id: I36e72f4c27b67dd7455aae2f423b4b14e54f9413 Signed-off-by: Jason Yellick <[email protected]>
1 parent f806802 commit 75909aa

22 files changed

+363
-131
lines changed

common/configtx/filter_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ func (mcm *mockConfigManager) ChainID() string {
4545
panic("Unimplemented")
4646
}
4747

48+
func (mcm *mockConfigManager) Sequence() uint64 {
49+
panic("Unimplemented")
50+
}
51+
4852
func TestForwardNonConfig(t *testing.T) {
4953
cf := NewFilter(&mockConfigManager{})
5054
result, _ := cf.Apply(&cb.Envelope{

common/configtx/manager.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import (
2323
"github.com/hyperledger/fabric/common/policies"
2424
cb "github.com/hyperledger/fabric/protos/common"
2525

26-
"github.com/golang/protobuf/proto"
2726
"errors"
27+
"github.com/golang/protobuf/proto"
2828
)
2929

3030
// Handler provides a hook which allows other pieces of code to participate in config proposals
@@ -52,6 +52,9 @@ type Manager interface {
5252

5353
// ChainID retrieves the chain ID associated with this manager
5454
ChainID() string
55+
56+
// Sequence returns the current sequence number of the configuration
57+
Sequence() uint64
5558
}
5659

5760
// DefaultModificationPolicyID is the ID of the policy used when no other policy can be resolved, for instance when attempting to create a new config item
@@ -295,3 +298,8 @@ func (cm *configurationManager) Apply(configtx *cb.ConfigurationEnvelope) error
295298
func (cm *configurationManager) ChainID() string {
296299
return cm.chainID
297300
}
301+
302+
// Sequence returns the current sequence number of the configuration
303+
func (cm *configurationManager) Sequence() uint64 {
304+
return cm.sequence
305+
}

orderer/common/bootstrap/provisional/provisional.go

+8-11
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,12 @@ func (cbs *commonBootstrapper) makeGenesisBlock(configEnvelope *cb.Configuration
113113
payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(configEnvelope)}
114114
envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil}
115115

116-
blockData := &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}}
117-
118-
return &cb.Block{
119-
Header: &cb.BlockHeader{
120-
Number: 0,
121-
PreviousHash: nil,
122-
DataHash: blockData.Hash(),
123-
},
124-
Data: blockData,
125-
Metadata: nil,
126-
}
116+
block := cb.NewBlock(0, nil)
117+
block.Data = &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}}
118+
block.Header.DataHash = block.Data.Hash()
119+
block.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIGURATION] = utils.MarshalOrPanic(&cb.Metadata{
120+
Value: utils.MarshalOrPanic(&cb.LastConfiguration{Index: 0}),
121+
})
122+
123+
return block
127124
}

orderer/common/bootstrap/provisional/provisional_test.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"testing"
2222

2323
"github.com/hyperledger/fabric/orderer/localconfig"
24+
cb "github.com/hyperledger/fabric/protos/common"
2425
)
2526

2627
var confSolo, confKafka *config.TopLevel
@@ -50,8 +51,12 @@ func TestGenesisBlockHeader(t *testing.T) {
5051
func TestGenesisMetadata(t *testing.T) {
5152
for _, tc := range testCases {
5253
genesisBlock := New(tc).GenesisBlock()
53-
if genesisBlock.Metadata != nil {
54-
t.Fatalf("Expected metadata nil, got %x", genesisBlock.Metadata)
54+
if genesisBlock.Metadata == nil {
55+
t.Fatalf("Expected non-nil metadata")
56+
}
57+
58+
if genesisBlock.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIGURATION] == nil {
59+
t.Fatalf("Should have last config set")
5560
}
5661
}
5762
}

orderer/common/deliver/deliver_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func TestOldestSeek(t *testing.T) {
120120
mm := newMockMultichainManager()
121121
for i := 1; i < ledgerSize; i++ {
122122
ledger := mm.chains[string(systemChainID)].ledger
123-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil))
123+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
124124
}
125125

126126
m := newMockD()
@@ -159,7 +159,7 @@ func TestNewestSeek(t *testing.T) {
159159
mm := newMockMultichainManager()
160160
for i := 1; i < ledgerSize; i++ {
161161
ledger := mm.chains[string(systemChainID)].ledger
162-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil))
162+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
163163
}
164164

165165
m := newMockD()
@@ -191,7 +191,7 @@ func TestSpecificSeek(t *testing.T) {
191191
mm := newMockMultichainManager()
192192
for i := 1; i < ledgerSize; i++ {
193193
ledger := mm.chains[string(systemChainID)].ledger
194-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil))
194+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
195195
}
196196

197197
m := newMockD()
@@ -229,7 +229,7 @@ func TestBadSeek(t *testing.T) {
229229
mm := newMockMultichainManager()
230230
for i := 1; i < ledgerSize; i++ {
231231
ledger := mm.chains[string(systemChainID)].ledger
232-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil))
232+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
233233
}
234234

235235
m := newMockD()
@@ -254,7 +254,7 @@ func TestFailFastSeek(t *testing.T) {
254254
mm := newMockMultichainManager()
255255
for i := 1; i < ledgerSize; i++ {
256256
ledger := mm.chains[string(systemChainID)].ledger
257-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil))
257+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
258258
}
259259

260260
m := newMockD()
@@ -288,7 +288,7 @@ func TestBlockingSeek(t *testing.T) {
288288
mm := newMockMultichainManager()
289289
for i := 1; i < ledgerSize; i++ {
290290
ledger := mm.chains[string(systemChainID)].ledger
291-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil))
291+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
292292
}
293293

294294
m := newMockD()
@@ -315,7 +315,7 @@ func TestBlockingSeek(t *testing.T) {
315315
}
316316

317317
ledger := mm.chains[string(systemChainID)].ledger
318-
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", ledgerSize+1))}}, nil))
318+
ledger.Append(rawledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", ledgerSize+1))}}))
319319

320320
select {
321321
case deliverReply := <-m.sendChan:

orderer/kafka/main.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ func (ch *chainImpl) loop() {
234234
}
235235
// If !ok, batches == nil, so this will be skipped
236236
for i, batch := range batches {
237-
ch.support.WriteBlock(batch, nil, committers[i])
237+
block := ch.support.CreateNextBlock(batch)
238+
ch.support.WriteBlock(block, committers[i])
238239
}
239240
}
240241
case <-ch.exitChan: // when Halt() is called

orderer/mocks/configtx/configtx.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright IBM Corp. 2017 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 configtx
18+
19+
import cb "github.com/hyperledger/fabric/protos/common"
20+
21+
// Manager is a mock implementation of configtx.Manager
22+
type Manager struct {
23+
// ChainIDVal is returned as the result of ChainID()
24+
ChainIDVal string
25+
26+
// SequenceVal is returned as the result of Sequence()
27+
SequenceVal uint64
28+
}
29+
30+
// ConsensusType returns the ConsensusTypeVal
31+
func (cm *Manager) ChainID() string {
32+
return cm.ChainIDVal
33+
}
34+
35+
// BatchSize returns the BatchSizeVal
36+
func (cm *Manager) Sequence() uint64 {
37+
return cm.SequenceVal
38+
}
39+
40+
// Apply panics
41+
func (cm *Manager) Apply(configtx *cb.ConfigurationEnvelope) error {
42+
panic("Unimplemented")
43+
}
44+
45+
// Validate panics
46+
func (cm *Manager) Validate(configtx *cb.ConfigurationEnvelope) error {
47+
panic("Unimplemented")
48+
49+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Copyright IBM Corp. 2017 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 configtx
18+
19+
import (
20+
"testing"
21+
22+
"github.com/hyperledger/fabric/common/configtx"
23+
)
24+
25+
func TestConfigtxManagerInterface(t *testing.T) {
26+
_ = configtx.Manager(&Manager{})
27+
}

orderer/mocks/multichain/multichain.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
mockblockcutter "github.com/hyperledger/fabric/orderer/mocks/blockcutter"
2424
mocksharedconfig "github.com/hyperledger/fabric/orderer/mocks/sharedconfig"
2525
cb "github.com/hyperledger/fabric/protos/common"
26+
"github.com/hyperledger/fabric/protos/utils"
2627

2728
"github.com/op/go-logging"
2829
)
@@ -55,10 +56,27 @@ func (mcs *ConsenterSupport) SharedConfig() sharedconfig.Manager {
5556
return mcs.SharedConfigVal
5657
}
5758

59+
// CreateNextBlock creates a simple block structure with the given data
60+
func (mcs *ConsenterSupport) CreateNextBlock(data []*cb.Envelope) *cb.Block {
61+
block := cb.NewBlock(0, nil)
62+
mtxs := make([][]byte, len(data))
63+
for i := range data {
64+
mtxs[i] = utils.MarshalOrPanic(data[i])
65+
}
66+
block.Data = &cb.BlockData{Data: mtxs}
67+
return block
68+
}
69+
5870
// WriteBlock writes data to the Batches channel
59-
func (mcs *ConsenterSupport) WriteBlock(data []*cb.Envelope, metadata [][]byte, committers []filter.Committer) {
71+
// Note that _committers is ignored by this mock implementation
72+
func (mcs *ConsenterSupport) WriteBlock(block *cb.Block, _committers []filter.Committer) *cb.Block {
6073
logger.Debugf("mockWriter: attempting to write batch")
61-
mcs.Batches <- data
74+
umtxs := make([]*cb.Envelope, len(block.Data.Data))
75+
for i := range block.Data.Data {
76+
umtxs[i] = utils.UnmarshalEnvelopeOrPanic(block.Data.Data[i])
77+
}
78+
mcs.Batches <- umtxs
79+
return block
6280
}
6381

6482
// ChainID returns the chain ID this specific consenter instance is associated with

orderer/multichain/chainsupport.go

+26-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/hyperledger/fabric/orderer/common/sharedconfig"
2727
"github.com/hyperledger/fabric/orderer/rawledger"
2828
cb "github.com/hyperledger/fabric/protos/common"
29+
"github.com/hyperledger/fabric/protos/utils"
2930
)
3031

3132
// Consenter defines the backing ordering mechanism
@@ -59,7 +60,8 @@ type Chain interface {
5960
type ConsenterSupport interface {
6061
BlockCutter() blockcutter.Receiver
6162
SharedConfig() sharedconfig.Manager
62-
WriteBlock(data []*cb.Envelope, metadata [][]byte, committers []filter.Committer)
63+
CreateNextBlock(messages []*cb.Envelope) *cb.Block
64+
WriteBlock(block *cb.Block, committers []filter.Committer) *cb.Block
6365
ChainID() string // ChainID returns the chain ID this specific consenter instance is associated with
6466
}
6567

@@ -81,6 +83,8 @@ type chainSupport struct {
8183
sharedConfigManager sharedconfig.Manager
8284
ledger rawledger.ReadWriter
8385
filters *filter.RuleSet
86+
lastConfiguration uint64
87+
lastConfigSeq uint64
8488
}
8589

8690
func newChainSupport(
@@ -173,10 +177,29 @@ func (cs *chainSupport) Enqueue(env *cb.Envelope) bool {
173177
return cs.chain.Enqueue(env)
174178
}
175179

176-
func (cs *chainSupport) WriteBlock(data []*cb.Envelope, metadata [][]byte, committers []filter.Committer) {
180+
func (cs *chainSupport) CreateNextBlock(messages []*cb.Envelope) *cb.Block {
181+
return rawledger.CreateNextBlock(cs.ledger, messages)
182+
}
183+
184+
func (cs *chainSupport) WriteBlock(block *cb.Block, committers []filter.Committer) *cb.Block {
177185
for _, committer := range committers {
178186
committer.Commit()
179187
}
180188

181-
cs.ledger.Append(rawledger.CreateNextBlock(cs.ledger, data, metadata))
189+
configSeq := cs.configManager.Sequence()
190+
if configSeq > cs.lastConfigSeq {
191+
cs.lastConfiguration = block.Header.Number
192+
cs.lastConfigSeq = configSeq
193+
}
194+
195+
block.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIGURATION] = utils.MarshalOrPanic(&cb.Metadata{
196+
Value: utils.MarshalOrPanic(&cb.LastConfiguration{Index: cs.lastConfiguration}),
197+
// XXX Add signature once signing is available
198+
})
199+
200+
err := cs.ledger.Append(block)
201+
if err != nil {
202+
logger.Panicf("Could not append block: %s", err)
203+
}
204+
return block
182205
}

0 commit comments

Comments
 (0)