Skip to content

Commit

Permalink
[FAB-6552] Block-to-live policy for pvtdata
Browse files Browse the repository at this point in the history
This CR introduces a BTL policy based on
configuration in the core.yaml file

Change-Id: Icef38b180d8a1f1c3336a59cca2f63dfbdab3964
Signed-off-by: manish <manish.sethi@gmail.com>
  • Loading branch information
manish-sethi committed Apr 30, 2018
1 parent 9015790 commit 3ac6358
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
94 changes: 94 additions & 0 deletions core/ledger/pvtdatapolicy/btlpolicy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package pvtdatapolicy

import (
"math"
"sync"

"github.com/spf13/viper"
)

var defaultBLT uint64 = math.MaxUint64
var btlPolicyMap map[string]BTLPolicy
var lock = &sync.Mutex{}

func init() {
btlPolicyMap = make(map[string]BTLPolicy)
}

// BTLPolicy BlockToLive policy for the pvt data
type BTLPolicy interface {
// init initializes BTLPolicy for the given channelName
init(channelName string) error
// GetBTL returns BlockToLive for a given namespace and collection
GetBTL(ns string, coll string) uint64
// GetExpiringBlock returns the block number by which the pvtdata for given namespace,collection, and committingBlock should expire
GetExpiringBlock(namesapce string, collection string, committingBlock uint64) uint64
}

// GetBTLPolicy constructs (if not already done) and returns the BTLPolicy for the given channel
func GetBTLPolicy(channelName string) (BTLPolicy, error) {
lock.Lock()
defer lock.Unlock()
m := btlPolicyMap[channelName]
if m == nil {
m = &configBasedBTLPolicy{}
m.init(channelName)
btlPolicyMap[channelName] = m
}
return m, nil
}

// configBasedBTLPolicy implements interface BTLPolicy.
// This implementation loads the BTL policy from configuration. This implementation is meant as a stop gap arrangement
// until the config transaction framework is in place. This is becasue, the BTL policy should be consistent across peer
// and should not change across different replays of transactions in the chain and hence it should be set via a config
// transaction only. Later, another implementation should be provided that loads the BTL policy from config transactions
type configBasedBTLPolicy struct {
channelName string
cache map[btlkey]uint64
}

type btlkey struct {
ns string
coll string
}

// Init implements corresponding function in interface `BTLPolicyMgr`
func (m *configBasedBTLPolicy) init(channelName string) error {
m.channelName = channelName
m.cache = make(map[btlkey]uint64)
return nil
}

// GetBTL implements corresponding function in interface `BTLPolicyMgr`
func (m *configBasedBTLPolicy) GetBTL(namesapce string, collection string) uint64 {
var btl uint64
var ok bool
key := btlkey{namesapce, collection}
btl, ok = m.cache[key]
if !ok {
btlConfigured := viper.GetInt("ledger.pvtdata.btlpolicy." + m.channelName + "." + namesapce + "." + collection)
if btlConfigured > 0 {
btl = uint64(btlConfigured)
} else {
btl = defaultBLT
}
m.cache[key] = btl
}
return btl
}

func (m *configBasedBTLPolicy) GetExpiringBlock(namesapce string, collection string, committingBlock uint64) uint64 {
btl := m.GetBTL(namesapce, collection)
expiryBlk := committingBlock + btl + uint64(1)
if expiryBlk <= committingBlock { // committingBlk + btl overflows uint64-max
expiryBlk = math.MaxUint64
}
return expiryBlk
}
34 changes: 34 additions & 0 deletions core/ledger/pvtdatapolicy/btlpolicy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package pvtdatapolicy

import (
"math"
"testing"

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

func TestBTLPolicy(t *testing.T) {
viper.Set("ledger.pvtdata.btlpolicy.ch1.ns1.coll1", 1)
viper.Set("ledger.pvtdata.btlpolicy.ch1.ns2.coll2", 2)
viper.Set("ledger.pvtdata.btlpolicy.ch2.ns2.coll2", 3)
viper.Set("ledger.pvtdata.btlpolicy.ch2.ns3.coll4", 4)

btlCh1, _ := GetBTLPolicy("ch1")
btlCh2, _ := GetBTLPolicy("ch2")

assert.Equal(t, uint64(1), btlCh1.GetBTL("ns1", "coll1"))
assert.Equal(t, uint64(4), btlCh2.GetBTL("ns3", "coll4"))
assert.Equal(t, defaultBLT, btlCh2.GetBTL("ns1", "coll5"))

assert.Equal(t, uint64(5), btlCh1.GetExpiringBlock("ns1", "coll1", 3))
assert.Equal(t, uint64(8), btlCh2.GetExpiringBlock("ns3", "coll4", 3))
assert.Equal(t, uint64(math.MaxUint64), btlCh2.GetExpiringBlock("ns3", "coll4", math.MaxUint64-uint64(2)))
assert.Equal(t, uint64(math.MaxUint64), btlCh2.GetExpiringBlock("ns1", "coll5", math.MaxUint64-uint64(2)))
}

0 comments on commit 3ac6358

Please sign in to comment.