Skip to content

Commit

Permalink
[FAB-2591] Introduce file-ledger option
Browse files Browse the repository at this point in the history
https://jira.hyperledger.org/browse/FAB-2591

This changeset allows the user to choose the file ledger, introduced in
a previous changeset.

Change-Id: Id518961af10fddb4954291592cf53b12f1e3d1fa
Signed-off-by: Kostas Christidis <kostas@christidis.io>
  • Loading branch information
kchristidis committed Mar 6, 2017
1 parent 3000b25 commit f803a9f
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 47 deletions.
47 changes: 1 addition & 46 deletions orderer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package main

import (
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
Expand All @@ -31,15 +30,9 @@ import (
"github.com/hyperledger/fabric/core/comm"
"github.com/hyperledger/fabric/orderer/common/bootstrap/file"
"github.com/hyperledger/fabric/orderer/kafka"
"github.com/hyperledger/fabric/orderer/ledger"
jsonledger "github.com/hyperledger/fabric/orderer/ledger/json"
ramledger "github.com/hyperledger/fabric/orderer/ledger/ram"
"github.com/hyperledger/fabric/orderer/localconfig"
"github.com/hyperledger/fabric/orderer/multichain"
"github.com/hyperledger/fabric/orderer/sbft"
"github.com/hyperledger/fabric/orderer/sbft/backend"
sbftcrypto "github.com/hyperledger/fabric/orderer/sbft/crypto"
"github.com/hyperledger/fabric/orderer/sbft/simplebft"
"github.com/hyperledger/fabric/orderer/solo"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"
Expand Down Expand Up @@ -93,26 +86,7 @@ func main() {
logger.Panic("Failed to initialize local MSP:", err)
}

var lf ledger.Factory
switch conf.General.LedgerType {
case "file":
// just use the json ledger type for now
fallthrough
case "json":
location := conf.FileLedger.Location
if location == "" {
var err error
location, err = ioutil.TempDir("", conf.FileLedger.Prefix)
if err != nil {
logger.Panic("Error creating temp dir:", err)
}
}
lf = jsonledger.New(location)
case "ram":
fallthrough
default:
lf = ramledger.New(int(conf.RAMLedger.HistorySize))
}
lf, _ := createLedgerFactory(conf)

// Are we bootstrapping?
if len(lf.ChainIDs()) == 0 {
Expand Down Expand Up @@ -166,22 +140,3 @@ func main() {
logger.Info("Beginning to serve requests")
grpcServer.Start()
}

func makeSbftConsensusConfig(conf *config.TopLevel) *sbft.ConsensusConfig {
cfg := simplebft.Config{N: conf.Genesis.SbftShared.N, F: conf.Genesis.SbftShared.F,
BatchDurationNsec: uint64(conf.Genesis.DeprecatedBatchTimeout),
BatchSizeBytes: uint64(conf.Genesis.DeprecatedBatchSize),
RequestTimeoutNsec: conf.Genesis.SbftShared.RequestTimeoutNsec}
peers := make(map[string][]byte)
for addr, cert := range conf.Genesis.SbftShared.Peers {
peers[addr], _ = sbftcrypto.ParseCertPEM(cert)
}
return &sbft.ConsensusConfig{Consensus: &cfg, Peers: peers}
}

func makeSbftStackConfig(conf *config.TopLevel) *backend.StackConfig {
return &backend.StackConfig{ListenAddr: conf.SbftLocal.PeerCommAddr,
CertFile: conf.SbftLocal.CertFile,
KeyFile: conf.SbftLocal.KeyFile,
DataDir: conf.SbftLocal.DataDir}
}
2 changes: 1 addition & 1 deletion orderer/orderer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ General:

# Log Level: The level at which to log. This accepts logging specifications
# per: fabric/docs/Setup/logging-control.md
LogLevel: debug
LogLevel: info

# Genesis method: The method by which to retrieve/generate the genesis
# block. Available values are "provisional", "file". Provisional utilizes
Expand Down
110 changes: 110 additions & 0 deletions orderer/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
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 main

import (
"io/ioutil"
"os"
"path/filepath"

"github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage"
"github.com/hyperledger/fabric/orderer/ledger"
fileledger "github.com/hyperledger/fabric/orderer/ledger/file"
jsonledger "github.com/hyperledger/fabric/orderer/ledger/json"
ramledger "github.com/hyperledger/fabric/orderer/ledger/ram"
config "github.com/hyperledger/fabric/orderer/localconfig"
"github.com/hyperledger/fabric/orderer/sbft"
"github.com/hyperledger/fabric/orderer/sbft/backend"
sbftcrypto "github.com/hyperledger/fabric/orderer/sbft/crypto"
"github.com/hyperledger/fabric/orderer/sbft/simplebft"
)

func createLedgerFactory(conf *config.TopLevel) (ledger.Factory, string) {
var lf ledger.Factory
var ld string
switch conf.General.LedgerType {
case "file":
ld = conf.FileLedger.Location
if ld == "" {
ld = createTempDir(conf.FileLedger.Prefix)
}
logger.Debug("Ledger dir:", ld)
lf = fileledger.New(ld)
// The file-based ledger stores the blocks for each channel
// in a fsblkstorage.ChainsDir sub-directory that we have
// to create separately. Otherwise the call to the ledger
// Factory's ChainIDs below will fail (dir won't exist).
createSubDir(ld, fsblkstorage.ChainsDir)
case "json":
ld = conf.FileLedger.Location
if ld == "" {
ld = createTempDir(conf.FileLedger.Prefix)
}
logger.Debug("Ledger dir:", ld)
lf = jsonledger.New(ld)
case "ram":
fallthrough
default:
lf = ramledger.New(int(conf.RAMLedger.HistorySize))
}
return lf, ld
}

func createTempDir(dirPrefix string) string {
dirPath, err := ioutil.TempDir("", dirPrefix)
if err != nil {
logger.Panic("Error creating temp dir:", err)
}
return dirPath
}

func createSubDir(parentDirPath string, subDir string) (string, bool) {
var created bool
subDirPath := filepath.Join(parentDirPath, subDir)
if _, err := os.Stat(subDirPath); err != nil {
if os.IsNotExist(err) {
if err = os.Mkdir(subDirPath, 0755); err != nil {
logger.Panic("Error creating sub dir:", err)
}
created = true
} else {
logger.Debugf("Found %s sub-dir and using it", fsblkstorage.ChainsDir)
}
}
return subDirPath, created
}

// XXX The functions below need to be moved to the SBFT package ASAP

func makeSbftConsensusConfig(conf *config.TopLevel) *sbft.ConsensusConfig {
cfg := simplebft.Config{N: conf.Genesis.SbftShared.N, F: conf.Genesis.SbftShared.F,
BatchDurationNsec: uint64(conf.Genesis.DeprecatedBatchTimeout),
BatchSizeBytes: uint64(conf.Genesis.DeprecatedBatchSize),
RequestTimeoutNsec: conf.Genesis.SbftShared.RequestTimeoutNsec}
peers := make(map[string][]byte)
for addr, cert := range conf.Genesis.SbftShared.Peers {
peers[addr], _ = sbftcrypto.ParseCertPEM(cert)
}
return &sbft.ConsensusConfig{Consensus: &cfg, Peers: peers}
}

func makeSbftStackConfig(conf *config.TopLevel) *backend.StackConfig {
return &backend.StackConfig{ListenAddr: conf.SbftLocal.PeerCommAddr,
CertFile: conf.SbftLocal.CertFile,
KeyFile: conf.SbftLocal.KeyFile,
DataDir: conf.SbftLocal.DataDir}
}
106 changes: 106 additions & 0 deletions orderer/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
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 main

import (
"os"
"testing"

config "github.com/hyperledger/fabric/orderer/localconfig"
)

func TestCreateLedgerFactory(t *testing.T) {
testCases := []struct {
name string
ledgerType string
ledgerDir string
ledgerDirPrefix string
expectPanic bool
}{
{"RAM", "ram", "", "", false},
{"JSONwithPathSet", "json", "test-dir", "", false},
{"JSONwithPathUnset", "json", "", "test-prefix", false},
{"FilewithPathSet", "file", "test-dir", "", false},
{"FilewithPathUnset", "file", "", "test-prefix", false},
}

conf := config.Load()

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer func() {
r := recover()
if tc.expectPanic && r == nil {
t.Fatal("Should have panicked")
}
if !tc.expectPanic && r != nil {
t.Fatal("Should not have panicked")
}
}()

conf.General.LedgerType = tc.ledgerType
conf.FileLedger.Location = tc.ledgerDir
conf.FileLedger.Prefix = tc.ledgerDirPrefix
lf, ld := createLedgerFactory(conf)

defer func() {
if ld != "" {
os.RemoveAll(ld)
t.Log("Removed temp dir:", ld)
}
}()
lf.ChainIDs()
})
}
}

func TestCreateSubDir(t *testing.T) {
testCases := []struct {
name string
count int
expectCreated bool
expectPanic bool
}{
{"CleanDir", 1, true, false},
{"HasSubDir", 2, false, false},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer func() {
r := recover()
if tc.expectPanic && r == nil {
t.Fatal("Should have panicked")
}
if !tc.expectPanic && r != nil {
t.Fatal("Should not have panicked")
}
}()

parentDirPath := createTempDir("test-dir")

var created bool
for i := 0; i < tc.count; i++ {
_, created = createSubDir(parentDirPath, "test-sub-dir")
}

if created != tc.expectCreated {
t.Fatalf("Sub dir created = %v, but expectation was = %v", created, tc.expectCreated)
}
})
}
}

0 comments on commit f803a9f

Please sign in to comment.