diff --git a/orderer/ledger/blackbox_test.go b/orderer/ledger/blackbox_test.go index bc5446e21d6..6f7cae6cf7c 100644 --- a/orderer/ledger/blackbox_test.go +++ b/orderer/ledger/blackbox_test.go @@ -73,6 +73,7 @@ func testInitialization(lf ledgerTestFactory, t *testing.T) { if block == nil { t.Fatalf("Error retrieving genesis block") } + } func TestReinitialization(t *testing.T) { @@ -84,12 +85,13 @@ func testReinitialization(lf ledgerTestFactory, t *testing.T) { t.Log("Skipping test as persistence is not available for this ledger type") return } - _, oli := lf.New() + olf, oli := lf.New() aBlock := CreateNextBlock(oli, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}) err := oli.Append(aBlock) if err != nil { t.Fatalf("Error appending block: %s", err) } + olf.Close() _, li := lf.New() if li.Height() != 2 { diff --git a/orderer/ledger/file/factory.go b/orderer/ledger/file/factory.go new file mode 100644 index 00000000000..ce60ded6bf7 --- /dev/null +++ b/orderer/ledger/file/factory.go @@ -0,0 +1,78 @@ +/* +Copyright IBM Corp. 2017 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fileledger + +import ( + "sync" + + "github.com/hyperledger/fabric/common/ledger/blkstorage" + "github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage" + ordererledger "github.com/hyperledger/fabric/orderer/ledger" +) + +type fileLedgerFactory struct { + blkstorageProvider blkstorage.BlockStoreProvider + ledgers map[string]ordererledger.ReadWriter + mutex sync.Mutex +} + +// GetOrCreate gets an existing ledger (if it exists) or creates it if it does not +func (lf *fileLedgerFactory) GetOrCreate(chainID string) (ordererledger.ReadWriter, error) { + lf.mutex.Lock() + defer lf.mutex.Unlock() + + key := chainID + // check cache + ledger, ok := lf.ledgers[key] + if ok { + return ledger, nil + } + // open fresh + blockStore, err := lf.blkstorageProvider.OpenBlockStore(key) + if err != nil { + return nil, err + } + ledger = &fileLedger{blockStore: blockStore, signal: make(chan struct{})} + lf.ledgers[key] = ledger + return ledger, nil +} + +// ChainIDs returns the chain IDs the Factory is aware of +func (lf *fileLedgerFactory) ChainIDs() []string { + chainIDs, err := lf.blkstorageProvider.List() + if err != nil { + panic(err) + } + return chainIDs +} + +// Close closes the file ledgers served by this factory +func (lf *fileLedgerFactory) Close() { + lf.blkstorageProvider.Close() +} + +// New creates a new ledger factory +func New(directory string) ordererledger.Factory { + return &fileLedgerFactory{ + blkstorageProvider: fsblkstorage.NewProvider( + fsblkstorage.NewConf(directory, -1), + &blkstorage.IndexConfig{ + AttrsToIndex: []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockNum}}, + ), + ledgers: make(map[string]ordererledger.ReadWriter), + } +} diff --git a/orderer/ledger/file/fileledger.go b/orderer/ledger/file/fileledger.go new file mode 100644 index 00000000000..7a38952f6e3 --- /dev/null +++ b/orderer/ledger/file/fileledger.go @@ -0,0 +1,111 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fileledger + +import ( + "github.com/hyperledger/fabric/common/ledger/blkstorage" + ordererledger "github.com/hyperledger/fabric/orderer/ledger" + cb "github.com/hyperledger/fabric/protos/common" + ab "github.com/hyperledger/fabric/protos/orderer" + "github.com/op/go-logging" +) + +var logger = logging.MustGetLogger("ordererledger/fileledger") +var closedChan chan struct{} + +func init() { + closedChan = make(chan struct{}) + close(closedChan) +} + +type fileLedger struct { + blockStore blkstorage.BlockStore + signal chan struct{} +} + +type fileLedgerIterator struct { + ledger *fileLedger + blockNumber uint64 +} + +// Next blocks until there is a new block available, or returns an error if the +// next block is no longer retrievable +func (i *fileLedgerIterator) Next() (*cb.Block, cb.Status) { + for { + if i.blockNumber < i.ledger.Height() { + block, err := i.ledger.blockStore.RetrieveBlockByNumber(i.blockNumber) + if err != nil { + return nil, cb.Status_SERVICE_UNAVAILABLE + } + i.blockNumber++ + return block, cb.Status_SUCCESS + } + <-i.ledger.signal + } +} + +// ReadyChan supplies a channel which will block until Next will not block +func (i *fileLedgerIterator) ReadyChan() <-chan struct{} { + signal := i.ledger.signal + if i.blockNumber > i.ledger.Height()-1 { + return signal + } + return closedChan +} + +// Iterator returns an Iterator, as specified by a cb.SeekInfo message, and its +// starting block number +func (fl *fileLedger) Iterator(startPosition *ab.SeekPosition) (ordererledger.Iterator, uint64) { + switch start := startPosition.Type.(type) { + case *ab.SeekPosition_Oldest: + return &fileLedgerIterator{ledger: fl, blockNumber: 0}, 0 + case *ab.SeekPosition_Newest: + info, err := fl.blockStore.GetBlockchainInfo() + if err != nil { + panic(err) + } + newestBlockNumber := info.Height - 1 + return &fileLedgerIterator{ledger: fl, blockNumber: newestBlockNumber}, newestBlockNumber + case *ab.SeekPosition_Specified: + height := fl.Height() + if start.Specified.Number > height { + return &ordererledger.NotFoundErrorIterator{}, 0 + } + return &fileLedgerIterator{ledger: fl, blockNumber: start.Specified.Number}, start.Specified.Number + } + // This line should be unreachable, but the compiler requires it + return &ordererledger.NotFoundErrorIterator{}, 0 +} + +// Height returns the number of blocks on the ledger +func (fl *fileLedger) Height() uint64 { + info, err := fl.blockStore.GetBlockchainInfo() + if err != nil { + panic(err) + } + return info.Height +} + +// Append a new block to the ledger +func (fl *fileLedger) Append(block *cb.Block) error { + err := fl.blockStore.AddBlock(block) + if err == nil { + close(fl.signal) + fl.signal = make(chan struct{}) + } + return err +} diff --git a/orderer/ledger/file/fileledger_test.go b/orderer/ledger/file/fileledger_test.go new file mode 100644 index 00000000000..e10739249bf --- /dev/null +++ b/orderer/ledger/file/fileledger_test.go @@ -0,0 +1,237 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fileledger + +import ( + "bytes" + "io/ioutil" + "os" + "testing" + + "github.com/hyperledger/fabric/common/configtx/tool/provisional" + ordererledger "github.com/hyperledger/fabric/orderer/ledger" + cb "github.com/hyperledger/fabric/protos/common" + ab "github.com/hyperledger/fabric/protos/orderer" + + logging "github.com/op/go-logging" +) + +var genesisBlock = cb.NewBlock(0, nil) + +func init() { + logging.SetLevel(logging.DEBUG, "") +} + +type testEnv struct { + t *testing.T + location string + flf ordererledger.Factory +} + +func initialize(t *testing.T) (*testEnv, *fileLedger) { + name, err := ioutil.TempDir("", "hyperledger_fabric") + if err != nil { + t.Fatalf("Error creating temp dir: %s", err) + } + flf := New(name).(*fileLedgerFactory) + fl, err := flf.GetOrCreate(provisional.TestChainID) + if err != nil { + panic(err) + } + fl.Append(genesisBlock) + return &testEnv{location: name, t: t, flf: flf}, fl.(*fileLedger) +} + +func (tev *testEnv) tearDown() { + tev.shutDown() + err := os.RemoveAll(tev.location) + if err != nil { + tev.t.Fatalf("Error tearing down env: %s", err) + } +} + +func (tev *testEnv) shutDown() { + tev.flf.Close() +} + +func TestInitialization(t *testing.T) { + tev, fl := initialize(t) + defer tev.tearDown() + + if fl.Height() != 1 { + t.Fatalf("Block height should be 1") + } + block := ordererledger.GetBlock(fl, 0) + if block == nil { + t.Fatalf("Error retrieving genesis block") + } + if !bytes.Equal(block.Header.Hash(), genesisBlock.Header.Hash()) { + t.Fatalf("Block hashes did no match") + } +} + +func TestReinitialization(t *testing.T) { + // initialize ledger provider and a ledger for the test chain + tev, leger1 := initialize(t) + + // make sure we cleanup at the end (delete all traces of ledgers) + defer tev.tearDown() + + // create a block to add to the ledger + b1 := ordererledger.CreateNextBlock(leger1, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}) + + // add the block to the ledger + leger1.Append(b1) + + // shutdown the ledger + leger1.blockStore.Shutdown() + + // shut down the ledger provider + tev.shutDown() + + // re-initialize the ledger provider (not the test ledger itself!) + provider2 := New(tev.location) + + // assert expected ledgers exist + chains := provider2.ChainIDs() + if len(chains) != 1 { + t.Fatalf("Should have recovered the chain") + } + + // get the existing test chain ledger + ledger2, err := provider2.GetOrCreate(chains[0]) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + + fl := ledger2.(*fileLedger) + if fl.Height() != 2 { + t.Fatalf("Block height should be 2. Got %v", fl.Height()) + } + block := ordererledger.GetBlock(fl, 1) + if block == nil { + t.Fatalf("Error retrieving block 1") + } + if !bytes.Equal(block.Header.Hash(), b1.Header.Hash()) { + t.Fatalf("Block hashes did no match") + } +} + +func TestMultiReinitialization(t *testing.T) { + tev, _ := initialize(t) + defer tev.tearDown() + tev.shutDown() + flf := New(tev.location) + + _, err := flf.GetOrCreate("foo") + if err != nil { + t.Fatalf("Error creating chain") + } + + _, err = flf.GetOrCreate("bar") + if err != nil { + t.Fatalf("Error creating chain") + } + flf.Close() + flf = New(tev.location) + chains := flf.ChainIDs() + if len(chains) != 3 { + t.Fatalf("Should have recovered the chains") + } +} + +func TestAddition(t *testing.T) { + tev, fl := initialize(t) + defer tev.tearDown() + info, _ := fl.blockStore.GetBlockchainInfo() + prevHash := info.CurrentBlockHash + fl.Append(ordererledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + if fl.Height() != 2 { + t.Fatalf("Block height should be 2") + } + block := ordererledger.GetBlock(fl, 1) + if block == nil { + t.Fatalf("Error retrieving genesis block") + } + if !bytes.Equal(block.Header.PreviousHash, prevHash) { + t.Fatalf("Block hashes did no match") + } +} + +func TestRetrieval(t *testing.T) { + tev, fl := initialize(t) + defer tev.tearDown() + fl.Append(ordererledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}}) + if num != 0 { + t.Fatalf("Expected genesis block iterator, but got %d", num) + } + signal := it.ReadyChan() + select { + case <-signal: + default: + t.Fatalf("Should be ready for block read") + } + block, status := it.Next() + if status != cb.Status_SUCCESS { + t.Fatalf("Expected to successfully read the genesis block") + } + if block.Header.Number != 0 { + t.Fatalf("Expected to successfully retrieve the genesis block") + } + signal = it.ReadyChan() + select { + case <-signal: + default: + t.Fatalf("Should still be ready for block read") + } + block, status = it.Next() + if status != cb.Status_SUCCESS { + t.Fatalf("Expected to successfully read the second block") + } + if block.Header.Number != 1 { + t.Fatalf("Expected to successfully retrieve the second block but got block number %d", block.Header.Number) + } +} + +func TestBlockedRetrieval(t *testing.T) { + tev, fl := initialize(t) + defer tev.tearDown() + it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}}) + if num != 1 { + t.Fatalf("Expected block iterator at 1, but got %d", num) + } + signal := it.ReadyChan() + select { + case <-signal: + t.Fatalf("Should not be ready for block read") + default: + } + fl.Append(ordererledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + select { + case <-signal: + default: + t.Fatalf("Should now be ready for block read") + } + block, status := it.Next() + if status != cb.Status_SUCCESS { + t.Fatalf("Expected to successfully read the second block") + } + if block.Header.Number != 1 { + t.Fatalf("Expected to successfully retrieve the second block") + } +} diff --git a/orderer/ledger/fileledger_test.go b/orderer/ledger/fileledger_test.go new file mode 100644 index 00000000000..19efbf8fcb2 --- /dev/null +++ b/orderer/ledger/fileledger_test.go @@ -0,0 +1,77 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ordererledger_test + +import ( + "io/ioutil" + "os" + + "github.com/hyperledger/fabric/common/configtx/tool/provisional" + . "github.com/hyperledger/fabric/orderer/ledger" + fileledger "github.com/hyperledger/fabric/orderer/ledger/file" +) + +func init() { + testables = append(testables, &fileLedgerTestEnv{}) +} + +type fileLedgerTestFactory struct { + location string +} + +type fileLedgerTestEnv struct { +} + +func (env *fileLedgerTestEnv) Initialize() (ledgerTestFactory, error) { + var err error + location, err := ioutil.TempDir("", "hyperledger") + if err != nil { + return nil, err + } + return &fileLedgerTestFactory{location: location}, nil +} + +func (env *fileLedgerTestEnv) Name() string { + return "fileledger" +} + +func (env *fileLedgerTestEnv) Close(lf Factory) { + lf.Close() +} + +func (env *fileLedgerTestFactory) Destroy() error { + err := os.RemoveAll(env.location) + return err +} + +func (env *fileLedgerTestFactory) Persistent() bool { + return true +} + +func (env *fileLedgerTestFactory) New() (Factory, ReadWriter) { + flf := fileledger.New(env.location) + fl, err := flf.GetOrCreate(provisional.TestChainID) + if err != nil { + panic(err) + } + if fl.Height() == 0 { + if err = fl.Append(genesisBlock); err != nil { + panic(err) + } + } + return flf, fl +} diff --git a/orderer/ledger/fsledger/fsledger.go b/orderer/ledger/fsledger/fsledger.go deleted file mode 100644 index f97a611d214..00000000000 --- a/orderer/ledger/fsledger/fsledger.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fsledger - -import ( - "errors" - - "github.com/hyperledger/fabric/common/ledger" - "github.com/hyperledger/fabric/common/ledger/blkstorage" - - "github.com/hyperledger/fabric/protos/common" -) - -const ( - fileSegmentSize = 64 * 1024 * 1024 -) - -// fsLedger - an orderer ledger implementation that persists blocks on filesystem based store -type fsLedger struct { - blockStore blkstorage.BlockStore -} - -// GetBlockchainInfo returns basic info about blockchain -func (l *fsLedger) GetBlockchainInfo() (*common.BlockchainInfo, error) { - return l.blockStore.GetBlockchainInfo() -} - -// GetBlockByNumber returns block at a given height -func (l *fsLedger) GetBlockByNumber(blockNumber uint64) (*common.Block, error) { - return l.blockStore.RetrieveBlockByNumber(blockNumber) -} - -// GetBlocksIterator returns an iterator that starts from `startBlockNumber`(inclusive). -// The iterator is a blocking iterator i.e., it blocks till the next block gets available in the ledger -// ResultsIterator contains type BlockHolder -func (l *fsLedger) GetBlocksIterator(startBlockNumber uint64) (ledger.ResultsIterator, error) { - return l.blockStore.RetrieveBlocks(startBlockNumber) -} - -//Prune prunes the blocks/transactions that satisfy the given policy -func (l *fsLedger) Prune(policy ledger.PrunePolicy) error { - return errors.New("Not yet implemented") -} - -// Close closes the ledger -func (l *fsLedger) Close() { - l.blockStore.Shutdown() -} - -// Commit adds a new block -func (l *fsLedger) Commit(block *common.Block) error { - return l.blockStore.AddBlock(block) -} diff --git a/orderer/ledger/fsledger/fsledger_provider.go b/orderer/ledger/fsledger/fsledger_provider.go deleted file mode 100644 index a8224b8b48b..00000000000 --- a/orderer/ledger/fsledger/fsledger_provider.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fsledger - -import ( - "github.com/hyperledger/fabric/common/ledger/blkstorage" - "github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage" -) - -// Provider impements interface OrdererLedgerProvider -type Provider struct { - blkStoreProvider blkstorage.BlockStoreProvider -} - -// NewProvider construct a new filesystem based orderer ledger provider. Only one instance should be created -func NewProvider(conf *fsblkstorage.Conf) *Provider { - attrsToIndex := []blkstorage.IndexableAttr{ - blkstorage.IndexableAttrBlockNum, - } - indexConfig := &blkstorage.IndexConfig{AttrsToIndex: attrsToIndex} - fsBlkStoreProvider := fsblkstorage.NewProvider(conf, indexConfig) - return &Provider{fsBlkStoreProvider} -} - -// Create implements corresponding method in the interface ledger.OrdererLedgerProvider -func (p *Provider) Create(ledgerID string) (OrdererLedger, error) { - blkStore, err := p.blkStoreProvider.CreateBlockStore(ledgerID) - if err != nil { - return nil, err - } - return &fsLedger{blkStore}, nil -} - -// Open implements corresponding method in the interface ledger.OrdererLedgerProvider -func (p *Provider) Open(ledgerID string) (OrdererLedger, error) { - blkStore, err := p.blkStoreProvider.OpenBlockStore(ledgerID) - if err != nil { - return nil, err - } - return &fsLedger{blkStore}, nil -} - -// Exists implements corresponding method in the interface ledger.OrdererLedgerProvider -func (p *Provider) Exists(ledgerID string) (bool, error) { - return p.blkStoreProvider.Exists(ledgerID) -} - -// List implements corresponding method in the interface ledger.OrdererLedgerProvider -func (p *Provider) List() ([]string, error) { - return p.blkStoreProvider.List() -} - -// Close implements corresponding method in the interface ledger.OrdererLedgerProvider -func (p *Provider) Close() { - p.blkStoreProvider.Close() -} diff --git a/orderer/ledger/fsledger/fsledger_test.go b/orderer/ledger/fsledger/fsledger_test.go deleted file mode 100644 index eb7e3475cb3..00000000000 --- a/orderer/ledger/fsledger/fsledger_test.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fsledger - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/hyperledger/fabric/common/ledger" - "github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage" - "github.com/hyperledger/fabric/common/ledger/testutil" -) - -var testFolder string - -func init() { - var err error - testFolder, err = ioutil.TempDir("", "fsledger") - if err != nil { - panic(err) - } -} - -func TestOrdererLedger(t *testing.T) { - conf := fsblkstorage.NewConf(testFolder, 0) - cleanup(t) - defer cleanup(t) - - ordererLedgerProvider := NewProvider(conf) - defer ordererLedgerProvider.Close() - - ordererLedger, _ := ordererLedgerProvider.Create("testLedger") - defer ordererLedger.Close() - - // Construct test blocks and add to orderer ledger - blocks := testutil.ConstructTestBlocks(t, 10) - for _, block := range blocks { - ordererLedger.Commit(block) - } - - // test GetBlockchainInfo() - bcInfo, err := ordererLedger.GetBlockchainInfo() - testutil.AssertNoError(t, err, "Error in getting BlockchainInfo") - testutil.AssertEquals(t, bcInfo.Height, uint64(10)) - - // test GetBlockByNumber() - block, err := ordererLedger.GetBlockByNumber(1) - testutil.AssertNoError(t, err, "Error in getting block by number") - testutil.AssertEquals(t, block, blocks[1]) - - // get blocks iterator for block number starting from 2 - itr, err := ordererLedger.GetBlocksIterator(2) - testutil.AssertNoError(t, err, "Error in getting iterator") - blockHolder, err := itr.Next() - testutil.AssertNoError(t, err, "") - testutil.AssertEquals(t, blockHolder.(ledger.BlockHolder).GetBlock(), blocks[2]) - // get next block from iterator. The block should be 4th block - blockHolder, err = itr.Next() - testutil.AssertNoError(t, err, "") - testutil.AssertEquals(t, blockHolder.(ledger.BlockHolder).GetBlock(), blocks[3]) -} - -func cleanup(t *testing.T) { - err := os.RemoveAll(testFolder) - if err != nil { - t.Fatalf("Error in cleanup:%s", err) - } -} diff --git a/orderer/ledger/fsledger/ledger_interface.go b/orderer/ledger/fsledger/ledger_interface.go deleted file mode 100644 index 23ae3404b7b..00000000000 --- a/orderer/ledger/fsledger/ledger_interface.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fsledger - -import ( - commonledger "github.com/hyperledger/fabric/common/ledger" -) - -// OrdererLedger implements methods required by 'orderer ledger' -type OrdererLedger interface { - commonledger.Ledger -} - -// OrdererLedgerProvider provides handle to raw ledger instances -type OrdererLedgerProvider interface { - // Create creates a new ledger with a given unique id - Create(ledgerID string) (OrdererLedger, error) - // Open opens an already created ledger - Open(ledgerID string) (OrdererLedger, error) - // Exists tells whether the ledger with given id exits - Exists(ledgerID string) (bool, error) - // List lists the ids of the existing ledgers - List() ([]string, error) - // Close closes the ValidatedLedgerProvider - Close() -} diff --git a/orderer/ledger/json/jsonledger.go b/orderer/ledger/json/jsonledger.go index b69d88cdfd2..255b416e624 100644 --- a/orderer/ledger/json/jsonledger.go +++ b/orderer/ledger/json/jsonledger.go @@ -140,6 +140,11 @@ func (jlf *jsonLedgerFactory) GetOrCreate(chainID string) (ordererledger.ReadWri return ch, nil } +// Close does nothing for json ledger +func (jlf *jsonLedgerFactory) Close() { + return // nothing to do +} + // newChain creates a new chain backed by a json ledger func newChain(directory string) ordererledger.ReadWriter { jl := &jsonLedger{ diff --git a/orderer/ledger/jsonledger_test.go b/orderer/ledger/jsonledger_test.go index fbe7823ae11..a2b593f1dc2 100644 --- a/orderer/ledger/jsonledger_test.go +++ b/orderer/ledger/jsonledger_test.go @@ -67,6 +67,10 @@ func (env *jsonLedgerTestFactory) New() (Factory, ReadWriter) { if err != nil { panic(err) } - fl.Append(genesisBlock) + if fl.Height() == 0 { + if err = fl.Append(genesisBlock); err != nil { + panic(err) + } + } return flf, fl } diff --git a/orderer/ledger/ordererledger.go b/orderer/ledger/ordererledger.go index c2bf9d43498..19ab80396f6 100644 --- a/orderer/ledger/ordererledger.go +++ b/orderer/ledger/ordererledger.go @@ -30,6 +30,9 @@ type Factory interface { // ChainIDs returns the chain IDs the Factory is aware of ChainIDs() []string + + // Close releases all resources acquired by the factory + Close() } // Iterator is useful for a chain Reader to stream blocks as they are created diff --git a/orderer/ledger/ram/ramledger.go b/orderer/ledger/ram/ramledger.go index 50db31f40c1..4a9af830084 100644 --- a/orderer/ledger/ram/ramledger.go +++ b/orderer/ledger/ram/ramledger.go @@ -93,6 +93,11 @@ func (rlf *ramLedgerFactory) ChainIDs() []string { return ids } +// Close does nothing for ram ledger +func (rlf *ramLedgerFactory) Close() { + return // nothing to do +} + // newChain creates a new instance of the ram ledger for a chain func newChain(maxSize int) ordererledger.ReadWriter { preGenesis := &cb.Block{