Skip to content

Commit e87c815

Browse files
author
Luis Sanchez
committedJul 12, 2017
[FAB-2669] use fs ledger's blockstore iterator
- Updated the orderer's file ledger to use it's underlying blockstore ledger impl's iterator APIs. - Blockstore iterators must be explicitly closed to avoid leaking resources, so now orderer/ledger.Iterator must also be explicitly closed. Added Close() to the orderer/ledger.Iterator interface. Change-Id: Id838a661a11bf5b64a0cbb57d75a27d69d251269 Signed-off-by: Luis Sanchez <sanchezl@us.ibm.com>
1 parent f56a82e commit e87c815

File tree

11 files changed

+210
-123
lines changed

11 files changed

+210
-123
lines changed
 

‎orderer/common/deliver/deliver.go

+111-98
Original file line numberDiff line numberDiff line change
@@ -84,129 +84,142 @@ func (ds *deliverServer) Handle(srv ab.AtomicBroadcast_DeliverServer) error {
8484
return err
8585
}
8686

87-
payload, err := utils.UnmarshalPayload(envelope.Payload)
88-
if err != nil {
89-
logger.Warningf("Received an envelope with no payload: %s", err)
90-
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
91-
}
92-
93-
if payload.Header == nil {
94-
logger.Warningf("Malformed envelope received with bad header")
95-
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
87+
if err := ds.deliverBlocks(srv, envelope); err != nil {
88+
return err
9689
}
9790

98-
chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
99-
if err != nil {
100-
logger.Warningf("Failed to unmarshal channel header: %s", err)
101-
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
102-
}
91+
logger.Debugf("Waiting for new SeekInfo")
92+
}
93+
}
10394

104-
chain, ok := ds.sm.GetChain(chdr.ChannelId)
105-
if !ok {
106-
// Note, we log this at DEBUG because SDKs will poll waiting for channels to be created
107-
// So we would expect our log to be somewhat flooded with these
108-
logger.Debugf("Rejecting deliver because channel %s not found", chdr.ChannelId)
109-
return sendStatusReply(srv, cb.Status_NOT_FOUND)
110-
}
95+
func (ds *deliverServer) deliverBlocks(srv ab.AtomicBroadcast_DeliverServer, envelope *cb.Envelope) error {
11196

112-
erroredChan := chain.Errored()
113-
select {
114-
case <-erroredChan:
115-
logger.Warningf("[channel: %s] Rejecting deliver request because of consenter error", chdr.ChannelId)
116-
return sendStatusReply(srv, cb.Status_SERVICE_UNAVAILABLE)
117-
default:
97+
payload, err := utils.UnmarshalPayload(envelope.Payload)
98+
if err != nil {
99+
logger.Warningf("Received an envelope with no payload: %s", err)
100+
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
101+
}
118102

119-
}
103+
if payload.Header == nil {
104+
logger.Warningf("Malformed envelope received with bad header")
105+
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
106+
}
120107

121-
lastConfigSequence := chain.Sequence()
108+
chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
109+
if err != nil {
110+
logger.Warningf("Failed to unmarshal channel header: %s", err)
111+
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
112+
}
122113

123-
sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager())
124-
result, _ := sf.Apply(envelope)
125-
if result != filter.Forward {
126-
logger.Warningf("[channel: %s] Received unauthorized deliver request", chdr.ChannelId)
127-
return sendStatusReply(srv, cb.Status_FORBIDDEN)
128-
}
114+
chain, ok := ds.sm.GetChain(chdr.ChannelId)
115+
if !ok {
116+
// Note, we log this at DEBUG because SDKs will poll waiting for channels to be created
117+
// So we would expect our log to be somewhat flooded with these
118+
logger.Debugf("Rejecting deliver because channel %s not found", chdr.ChannelId)
119+
return sendStatusReply(srv, cb.Status_NOT_FOUND)
120+
}
129121

130-
seekInfo := &ab.SeekInfo{}
131-
if err = proto.Unmarshal(payload.Data, seekInfo); err != nil {
132-
logger.Warningf("[channel: %s] Received a signed deliver request with malformed seekInfo payload: %s", chdr.ChannelId, err)
133-
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
134-
}
122+
erroredChan := chain.Errored()
123+
select {
124+
case <-erroredChan:
125+
logger.Warningf("[channel: %s] Rejecting deliver request because of consenter error", chdr.ChannelId)
126+
return sendStatusReply(srv, cb.Status_SERVICE_UNAVAILABLE)
127+
default:
135128

136-
if seekInfo.Start == nil || seekInfo.Stop == nil {
137-
logger.Warningf("[channel: %s] Received seekInfo message with missing start or stop %v, %v", chdr.ChannelId, seekInfo.Start, seekInfo.Stop)
138-
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
139-
}
129+
}
140130

141-
logger.Debugf("[channel: %s] Received seekInfo (%p) %v", chdr.ChannelId, seekInfo, seekInfo)
142-
143-
cursor, number := chain.Reader().Iterator(seekInfo.Start)
144-
var stopNum uint64
145-
switch stop := seekInfo.Stop.Type.(type) {
146-
case *ab.SeekPosition_Oldest:
147-
stopNum = number
148-
case *ab.SeekPosition_Newest:
149-
stopNum = chain.Reader().Height() - 1
150-
case *ab.SeekPosition_Specified:
151-
stopNum = stop.Specified.Number
152-
if stopNum < number {
153-
logger.Warningf("[channel: %s] Received invalid seekInfo message: start number %d greater than stop number %d", chdr.ChannelId, number, stopNum)
154-
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
155-
}
156-
}
131+
lastConfigSequence := chain.Sequence()
157132

158-
for {
159-
if seekInfo.Behavior == ab.SeekInfo_BLOCK_UNTIL_READY {
160-
select {
161-
case <-erroredChan:
162-
logger.Warningf("[channel: %s] Aborting deliver request because of consenter error", chdr.ChannelId)
163-
return sendStatusReply(srv, cb.Status_SERVICE_UNAVAILABLE)
164-
case <-cursor.ReadyChan():
165-
}
166-
} else {
167-
select {
168-
case <-cursor.ReadyChan():
169-
default:
170-
return sendStatusReply(srv, cb.Status_NOT_FOUND)
171-
}
172-
}
133+
sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager())
134+
result, _ := sf.Apply(envelope)
135+
if result != filter.Forward {
136+
logger.Warningf("[channel: %s] Received unauthorized deliver request", chdr.ChannelId)
137+
return sendStatusReply(srv, cb.Status_FORBIDDEN)
138+
}
173139

174-
currentConfigSequence := chain.Sequence()
175-
if currentConfigSequence > lastConfigSequence {
176-
lastConfigSequence = currentConfigSequence
177-
sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager())
178-
result, _ := sf.Apply(envelope)
179-
if result != filter.Forward {
180-
logger.Warningf("[channel: %s] Client authorization revoked for deliver request", chdr.ChannelId)
181-
return sendStatusReply(srv, cb.Status_FORBIDDEN)
182-
}
183-
}
140+
seekInfo := &ab.SeekInfo{}
141+
if err = proto.Unmarshal(payload.Data, seekInfo); err != nil {
142+
logger.Warningf("[channel: %s] Received a signed deliver request with malformed seekInfo payload: %s", chdr.ChannelId, err)
143+
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
144+
}
184145

185-
block, status := cursor.Next()
186-
if status != cb.Status_SUCCESS {
187-
logger.Errorf("[channel: %s] Error reading from channel, cause was: %v", chdr.ChannelId, status)
188-
return sendStatusReply(srv, status)
189-
}
146+
if seekInfo.Start == nil || seekInfo.Stop == nil {
147+
logger.Warningf("[channel: %s] Received seekInfo message with missing start or stop %v, %v", chdr.ChannelId, seekInfo.Start, seekInfo.Stop)
148+
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
149+
}
190150

191-
logger.Debugf("[channel: %s] Delivering block for (%p)", chdr.ChannelId, seekInfo)
151+
logger.Debugf("[channel: %s] Received seekInfo (%p) %v", chdr.ChannelId, seekInfo, seekInfo)
152+
153+
cursor, number := chain.Reader().Iterator(seekInfo.Start)
154+
defer cursor.Close()
155+
var stopNum uint64
156+
switch stop := seekInfo.Stop.Type.(type) {
157+
case *ab.SeekPosition_Oldest:
158+
stopNum = number
159+
case *ab.SeekPosition_Newest:
160+
stopNum = chain.Reader().Height() - 1
161+
case *ab.SeekPosition_Specified:
162+
stopNum = stop.Specified.Number
163+
if stopNum < number {
164+
logger.Warningf("[channel: %s] Received invalid seekInfo message: start number %d greater than stop number %d", chdr.ChannelId, number, stopNum)
165+
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
166+
}
167+
}
192168

193-
if err := sendBlockReply(srv, block); err != nil {
194-
logger.Warningf("[channel: %s] Error sending to stream: %s", chdr.ChannelId, err)
195-
return err
169+
for {
170+
if seekInfo.Behavior == ab.SeekInfo_BLOCK_UNTIL_READY {
171+
select {
172+
case <-erroredChan:
173+
logger.Warningf("[channel: %s] Aborting deliver request because of consenter error", chdr.ChannelId)
174+
return sendStatusReply(srv, cb.Status_SERVICE_UNAVAILABLE)
175+
case <-cursor.ReadyChan():
196176
}
177+
} else {
178+
select {
179+
case <-cursor.ReadyChan():
180+
default:
181+
return sendStatusReply(srv, cb.Status_NOT_FOUND)
182+
}
183+
}
197184

198-
if stopNum == block.Header.Number {
199-
break
185+
currentConfigSequence := chain.Sequence()
186+
if currentConfigSequence > lastConfigSequence {
187+
lastConfigSequence = currentConfigSequence
188+
sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager())
189+
result, _ := sf.Apply(envelope)
190+
if result != filter.Forward {
191+
logger.Warningf("[channel: %s] Client authorization revoked for deliver request", chdr.ChannelId)
192+
return sendStatusReply(srv, cb.Status_FORBIDDEN)
200193
}
201194
}
202195

203-
if err := sendStatusReply(srv, cb.Status_SUCCESS); err != nil {
196+
block, status := cursor.Next()
197+
if status != cb.Status_SUCCESS {
198+
logger.Errorf("[channel: %s] Error reading from channel, cause was: %v", chdr.ChannelId, status)
199+
return sendStatusReply(srv, status)
200+
}
201+
202+
logger.Debugf("[channel: %s] Delivering block for (%p)", chdr.ChannelId, seekInfo)
203+
204+
if err := sendBlockReply(srv, block); err != nil {
204205
logger.Warningf("[channel: %s] Error sending to stream: %s", chdr.ChannelId, err)
205206
return err
206207
}
207208

208-
logger.Debugf("[channel: %s] Done delivering for (%p), waiting for new SeekInfo", chdr.ChannelId, seekInfo)
209+
if stopNum == block.Header.Number {
210+
break
211+
}
209212
}
213+
214+
if err := sendStatusReply(srv, cb.Status_SUCCESS); err != nil {
215+
logger.Warningf("[channel: %s] Error sending to stream: %s", chdr.ChannelId, err)
216+
return err
217+
}
218+
219+
logger.Debugf("[channel: %s] Done delivering for (%p)", chdr.ChannelId, seekInfo)
220+
221+
return nil
222+
210223
}
211224

212225
func sendStatusReply(srv ab.AtomicBroadcast_DeliverServer, status cb.Status) error {

‎orderer/ledger/blackbox_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ func testRetrieval(lf ledgerTestFactory, t *testing.T) {
139139
_, li := lf.New()
140140
li.Append(CreateNextBlock(li, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
141141
it, num := li.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}})
142+
defer it.Close()
142143
if num != 0 {
143144
t.Fatalf("Expected genesis block iterator, but got %d", num)
144145
}
@@ -177,6 +178,7 @@ func TestBlockedRetrieval(t *testing.T) {
177178
func testBlockedRetrieval(lf ledgerTestFactory, t *testing.T) {
178179
_, li := lf.New()
179180
it, num := li.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}})
181+
defer it.Close()
180182
if num != 1 {
181183
t.Fatalf("Expected block iterator at 1, but got %d", num)
182184
}

‎orderer/ledger/file/impl.go

+23-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package fileledger
1818

1919
import (
20+
cl "github.com/hyperledger/fabric/common/ledger"
2021
"github.com/hyperledger/fabric/common/ledger/blkstorage"
2122
ledger "github.com/hyperledger/fabric/orderer/ledger"
2223
cb "github.com/hyperledger/fabric/protos/common"
@@ -38,21 +39,22 @@ type fileLedger struct {
3839
}
3940

4041
type fileLedgerIterator struct {
41-
ledger *fileLedger
42-
blockNumber uint64
42+
ledger *fileLedger
43+
blockNumber uint64
44+
commonIterator cl.ResultsIterator
4345
}
4446

4547
// Next blocks until there is a new block available, or returns an error if the
4648
// next block is no longer retrievable
4749
func (i *fileLedgerIterator) Next() (*cb.Block, cb.Status) {
4850
for {
4951
if i.blockNumber < i.ledger.Height() {
50-
block, err := i.ledger.blockStore.RetrieveBlockByNumber(i.blockNumber)
52+
result, err := i.commonIterator.Next()
5153
if err != nil {
5254
return nil, cb.Status_SERVICE_UNAVAILABLE
5355
}
5456
i.blockNumber++
55-
return block, cb.Status_SUCCESS
57+
return result.(*cb.Block), cb.Status_SUCCESS
5658
}
5759
<-i.ledger.signal
5860
}
@@ -67,28 +69,41 @@ func (i *fileLedgerIterator) ReadyChan() <-chan struct{} {
6769
return closedChan
6870
}
6971

72+
// Close releases resources acquired by the Iterator
73+
func (i *fileLedgerIterator) Close() {
74+
i.commonIterator.Close()
75+
}
76+
7077
// Iterator returns an Iterator, as specified by a cb.SeekInfo message, and its
7178
// starting block number
7279
func (fl *fileLedger) Iterator(startPosition *ab.SeekPosition) (ledger.Iterator, uint64) {
80+
var startingBlockNumber uint64
7381
switch start := startPosition.Type.(type) {
7482
case *ab.SeekPosition_Oldest:
75-
return &fileLedgerIterator{ledger: fl, blockNumber: 0}, 0
83+
startingBlockNumber = 0
7684
case *ab.SeekPosition_Newest:
7785
info, err := fl.blockStore.GetBlockchainInfo()
7886
if err != nil {
7987
logger.Panic(err)
8088
}
8189
newestBlockNumber := info.Height - 1
82-
return &fileLedgerIterator{ledger: fl, blockNumber: newestBlockNumber}, newestBlockNumber
90+
startingBlockNumber = newestBlockNumber
8391
case *ab.SeekPosition_Specified:
92+
startingBlockNumber = start.Specified.Number
8493
height := fl.Height()
85-
if start.Specified.Number > height {
94+
if startingBlockNumber > height {
8695
return &ledger.NotFoundErrorIterator{}, 0
8796
}
88-
return &fileLedgerIterator{ledger: fl, blockNumber: start.Specified.Number}, start.Specified.Number
8997
default:
9098
return &ledger.NotFoundErrorIterator{}, 0
9199
}
100+
101+
iterator, err := fl.blockStore.RetrieveBlocks(startingBlockNumber)
102+
if err != nil {
103+
return &ledger.NotFoundErrorIterator{}, 0
104+
}
105+
106+
return &fileLedgerIterator{ledger: fl, blockNumber: startingBlockNumber, commonIterator: iterator}, startingBlockNumber
92107
}
93108

94109
// Height returns the number of blocks on the ledger

0 commit comments

Comments
 (0)