Skip to content

Commit

Permalink
[FAB-6553] Ledger bookkeeping provider
Browse files Browse the repository at this point in the history
This CR introduces a bookkeeping provider.
This is intented to be used in maintaining different
aspects of ledger data management.

The initial use would be to maintain the expiry schedule
of pvt data items in the pvt statedb

Change-Id: I21f5eef5034cc413c39fdf4bee798fefafbcdf27
Signed-off-by: manish <manish.sethi@gmail.com>
  • Loading branch information
manish-sethi committed Apr 30, 2018
1 parent 3ac6358 commit b966981
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 5 deletions.
54 changes: 54 additions & 0 deletions core/ledger/kvledger/bookkeeping/provider.go
@@ -0,0 +1,54 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bookkeeping

import (
"fmt"

"github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
)

// Category is an enum type for representing the bookkeeping of different type
type Category int

const (
// PvtdataExpiry repersents the bookkeeping related to expiry of pvtdata because of BTL policy
PvtdataExpiry Category = iota
)

// Provider provides handle to different bookkeepers for the given ledger
type Provider interface {
// GetDBHandle returns a db handle that can be used for maintaining the bookkeeping of a given category
GetDBHandle(ledgerID string, cat Category) *leveldbhelper.DBHandle
// Close closes the BookkeeperProvider
Close()
}

type provider struct {
dbProvider *leveldbhelper.Provider
}

// NewProvider instantiates a new provider
func NewProvider() Provider {
dbProvider := leveldbhelper.NewProvider(&leveldbhelper.Conf{DBPath: getInternalBookkeeperPath()})
return &provider{dbProvider: dbProvider}
}

// GetDBHandle implements the function in the interface 'BookkeeperProvider'
func (provider *provider) GetDBHandle(ledgerID string, cat Category) *leveldbhelper.DBHandle {
return provider.dbProvider.GetDBHandle(fmt.Sprintf(ledgerID+"/%d", cat))
}

// Close implements the function in the interface 'BookKeeperProvider'
func (provider *provider) Close() {
provider.dbProvider.Close()
}

func getInternalBookkeeperPath() string {
return ledgerconfig.GetInternalBookkeeperPath()
}
31 changes: 31 additions & 0 deletions core/ledger/kvledger/bookkeeping/provider_test.go
@@ -0,0 +1,31 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bookkeeping

import (
"os"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)

func TestMain(m *testing.M) {
viper.Set("peer.fileSystemPath", "/tmp/fabric/ledgertests/kvledger/bookkeeping")
os.Exit(m.Run())
}

func TestProvider(t *testing.T) {
testEnv := NewTestEnv(t)
defer testEnv.Cleanup()
p := testEnv.TestProvider
db := p.GetDBHandle("TestLedger", PvtdataExpiry)
assert.NoError(t, db.Put([]byte("key"), []byte("value"), true))
val, err := db.Get([]byte("key"))
assert.NoError(t, err)
assert.Equal(t, []byte("value"), val)
}
49 changes: 49 additions & 0 deletions core/ledger/kvledger/bookkeeping/test_exports.go
@@ -0,0 +1,49 @@
/*
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 bookkeeping

import (
"os"
"testing"
)

// TestEnv provides the bookkeeper provider env for testing
type TestEnv struct {
t testing.TB
TestProvider Provider
}

// NewTestEnv construct a TestEnv for testing
func NewTestEnv(t *testing.T) *TestEnv {
removePath(t)
provider := NewProvider()
return &TestEnv{t, provider}
}

// Cleanup cleansup the store env after testing
func (env *TestEnv) Cleanup() {
env.TestProvider.Close()
removePath(env.t)
}

func removePath(t testing.TB) {
dbPath := getInternalBookkeeperPath()
if err := os.RemoveAll(dbPath); err != nil {
t.Fatalf("Err: %s", err)
t.FailNow()
}
}
10 changes: 5 additions & 5 deletions core/ledger/ledgerconfig/ledger_config.go
Expand Up @@ -68,11 +68,6 @@ func GetHistoryLevelDBPath() string {
return filepath.Join(GetRootPath(), confHistoryLeveldb)
}

// GetPvtWritesetStorePath returns the filesystem path that is used for permanent storage of privare write-sets
func GetPvtWritesetStorePath() string {
return filepath.Join(GetRootPath(), confPvtWritesetStore)
}

// GetBlockStorePath returns the filesystem path that is used for the chain block stores
func GetBlockStorePath() string {
return filepath.Join(GetRootPath(), confChains)
Expand All @@ -83,6 +78,11 @@ func GetPvtdataStorePath() string {
return filepath.Join(GetRootPath(), confPvtdataStore)
}

// GetInternalBookkeeperPath returns the filesystem path that is used for bookkeeping the internal stuff by by KVledger (such as expiration time for pvt)
func GetInternalBookkeeperPath() string {
return filepath.Join(GetRootPath(), "bookkeeper")
}

// GetMaxBlockfileSize returns maximum size of the block file
func GetMaxBlockfileSize() int {
return 64 * 1024 * 1024
Expand Down

0 comments on commit b966981

Please sign in to comment.