Skip to content

Commit 1ce056a

Browse files
Luis Sanchezkchristidis
Luis Sanchez
authored andcommitted
[FAB-2204] File LedgerType w/ fsblkstorage
The orderer "file" LedgerType re-introduced with the leveldb based fsblkstorage backing store. * I removed the previously provided OrdererLedger and OrdererLedgerProvider interfaces, instead choosing to implement the ordererledger.Factory interface and its corresponding ledger interfaces. * A Close() method was added to the Factory interface. Change-Id: I43007f3c570633896ef29de32fcd32c3301efcff Signed-off-by: Luis Sanchez <[email protected]>
1 parent 28687ca commit 1ce056a

13 files changed

+524
-262
lines changed

orderer/ledger/blackbox_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func testInitialization(lf ledgerTestFactory, t *testing.T) {
7373
if block == nil {
7474
t.Fatalf("Error retrieving genesis block")
7575
}
76+
7677
}
7778

7879
func TestReinitialization(t *testing.T) {
@@ -84,12 +85,13 @@ func testReinitialization(lf ledgerTestFactory, t *testing.T) {
8485
t.Log("Skipping test as persistence is not available for this ledger type")
8586
return
8687
}
87-
_, oli := lf.New()
88+
olf, oli := lf.New()
8889
aBlock := CreateNextBlock(oli, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})
8990
err := oli.Append(aBlock)
9091
if err != nil {
9192
t.Fatalf("Error appending block: %s", err)
9293
}
94+
olf.Close()
9395

9496
_, li := lf.New()
9597
if li.Height() != 2 {

orderer/ledger/file/factory.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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 fileledger
18+
19+
import (
20+
"sync"
21+
22+
"github.com/hyperledger/fabric/common/ledger/blkstorage"
23+
"github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage"
24+
ordererledger "github.com/hyperledger/fabric/orderer/ledger"
25+
)
26+
27+
type fileLedgerFactory struct {
28+
blkstorageProvider blkstorage.BlockStoreProvider
29+
ledgers map[string]ordererledger.ReadWriter
30+
mutex sync.Mutex
31+
}
32+
33+
// GetOrCreate gets an existing ledger (if it exists) or creates it if it does not
34+
func (lf *fileLedgerFactory) GetOrCreate(chainID string) (ordererledger.ReadWriter, error) {
35+
lf.mutex.Lock()
36+
defer lf.mutex.Unlock()
37+
38+
key := chainID
39+
// check cache
40+
ledger, ok := lf.ledgers[key]
41+
if ok {
42+
return ledger, nil
43+
}
44+
// open fresh
45+
blockStore, err := lf.blkstorageProvider.OpenBlockStore(key)
46+
if err != nil {
47+
return nil, err
48+
}
49+
ledger = &fileLedger{blockStore: blockStore, signal: make(chan struct{})}
50+
lf.ledgers[key] = ledger
51+
return ledger, nil
52+
}
53+
54+
// ChainIDs returns the chain IDs the Factory is aware of
55+
func (lf *fileLedgerFactory) ChainIDs() []string {
56+
chainIDs, err := lf.blkstorageProvider.List()
57+
if err != nil {
58+
panic(err)
59+
}
60+
return chainIDs
61+
}
62+
63+
// Close closes the file ledgers served by this factory
64+
func (lf *fileLedgerFactory) Close() {
65+
lf.blkstorageProvider.Close()
66+
}
67+
68+
// New creates a new ledger factory
69+
func New(directory string) ordererledger.Factory {
70+
return &fileLedgerFactory{
71+
blkstorageProvider: fsblkstorage.NewProvider(
72+
fsblkstorage.NewConf(directory, -1),
73+
&blkstorage.IndexConfig{
74+
AttrsToIndex: []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockNum}},
75+
),
76+
ledgers: make(map[string]ordererledger.ReadWriter),
77+
}
78+
}

orderer/ledger/file/fileledger.go

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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 fileledger
18+
19+
import (
20+
"github.com/hyperledger/fabric/common/ledger/blkstorage"
21+
ordererledger "github.com/hyperledger/fabric/orderer/ledger"
22+
cb "github.com/hyperledger/fabric/protos/common"
23+
ab "github.com/hyperledger/fabric/protos/orderer"
24+
"github.com/op/go-logging"
25+
)
26+
27+
var logger = logging.MustGetLogger("ordererledger/fileledger")
28+
var closedChan chan struct{}
29+
30+
func init() {
31+
closedChan = make(chan struct{})
32+
close(closedChan)
33+
}
34+
35+
type fileLedger struct {
36+
blockStore blkstorage.BlockStore
37+
signal chan struct{}
38+
}
39+
40+
type fileLedgerIterator struct {
41+
ledger *fileLedger
42+
blockNumber uint64
43+
}
44+
45+
// Next blocks until there is a new block available, or returns an error if the
46+
// next block is no longer retrievable
47+
func (i *fileLedgerIterator) Next() (*cb.Block, cb.Status) {
48+
for {
49+
if i.blockNumber < i.ledger.Height() {
50+
block, err := i.ledger.blockStore.RetrieveBlockByNumber(i.blockNumber)
51+
if err != nil {
52+
return nil, cb.Status_SERVICE_UNAVAILABLE
53+
}
54+
i.blockNumber++
55+
return block, cb.Status_SUCCESS
56+
}
57+
<-i.ledger.signal
58+
}
59+
}
60+
61+
// ReadyChan supplies a channel which will block until Next will not block
62+
func (i *fileLedgerIterator) ReadyChan() <-chan struct{} {
63+
signal := i.ledger.signal
64+
if i.blockNumber > i.ledger.Height()-1 {
65+
return signal
66+
}
67+
return closedChan
68+
}
69+
70+
// Iterator returns an Iterator, as specified by a cb.SeekInfo message, and its
71+
// starting block number
72+
func (fl *fileLedger) Iterator(startPosition *ab.SeekPosition) (ordererledger.Iterator, uint64) {
73+
switch start := startPosition.Type.(type) {
74+
case *ab.SeekPosition_Oldest:
75+
return &fileLedgerIterator{ledger: fl, blockNumber: 0}, 0
76+
case *ab.SeekPosition_Newest:
77+
info, err := fl.blockStore.GetBlockchainInfo()
78+
if err != nil {
79+
panic(err)
80+
}
81+
newestBlockNumber := info.Height - 1
82+
return &fileLedgerIterator{ledger: fl, blockNumber: newestBlockNumber}, newestBlockNumber
83+
case *ab.SeekPosition_Specified:
84+
height := fl.Height()
85+
if start.Specified.Number > height {
86+
return &ordererledger.NotFoundErrorIterator{}, 0
87+
}
88+
return &fileLedgerIterator{ledger: fl, blockNumber: start.Specified.Number}, start.Specified.Number
89+
}
90+
// This line should be unreachable, but the compiler requires it
91+
return &ordererledger.NotFoundErrorIterator{}, 0
92+
}
93+
94+
// Height returns the number of blocks on the ledger
95+
func (fl *fileLedger) Height() uint64 {
96+
info, err := fl.blockStore.GetBlockchainInfo()
97+
if err != nil {
98+
panic(err)
99+
}
100+
return info.Height
101+
}
102+
103+
// Append a new block to the ledger
104+
func (fl *fileLedger) Append(block *cb.Block) error {
105+
err := fl.blockStore.AddBlock(block)
106+
if err == nil {
107+
close(fl.signal)
108+
fl.signal = make(chan struct{})
109+
}
110+
return err
111+
}

0 commit comments

Comments
 (0)