Commit 89eb2cbe authored by Jonathan Levi (HACERA)'s avatar Jonathan Levi (HACERA) Committed by Gerrit Code Review
Browse files

Merge "Ledger-lscc: Interface for decoupling ledger and lscc"

parents 2035d235 3d3b4a77
......@@ -23,6 +23,21 @@ type TxSimulator struct {
result1 []byte
result2 error
}
GetStateRangeScanIteratorStub func(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error)
getStateRangeScanIteratorMutex sync.RWMutex
getStateRangeScanIteratorArgsForCall []struct {
namespace string
startKey string
endKey string
}
getStateRangeScanIteratorReturns struct {
result1 commonledger.ResultsIterator
result2 error
}
getStateRangeScanIteratorReturnsOnCall map[int]struct {
result1 commonledger.ResultsIterator
result2 error
}
GetStateMetadataStub func(namespace, key string) (map[string][]byte, error)
getStateMetadataMutex sync.RWMutex
getStateMetadataArgsForCall []struct {
......@@ -51,21 +66,6 @@ type TxSimulator struct {
result1 [][]byte
result2 error
}
GetStateRangeScanIteratorStub func(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error)
getStateRangeScanIteratorMutex sync.RWMutex
getStateRangeScanIteratorArgsForCall []struct {
namespace string
startKey string
endKey string
}
getStateRangeScanIteratorReturns struct {
result1 commonledger.ResultsIterator
result2 error
}
getStateRangeScanIteratorReturnsOnCall map[int]struct {
result1 commonledger.ResultsIterator
result2 error
}
ExecuteQueryStub func(namespace, query string) (commonledger.ResultsIterator, error)
executeQueryMutex sync.RWMutex
executeQueryArgsForCall []struct {
......@@ -366,6 +366,59 @@ func (fake *TxSimulator) GetStateReturnsOnCall(i int, result1 []byte, result2 er
}{result1, result2}
}
func (fake *TxSimulator) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error) {
fake.getStateRangeScanIteratorMutex.Lock()
ret, specificReturn := fake.getStateRangeScanIteratorReturnsOnCall[len(fake.getStateRangeScanIteratorArgsForCall)]
fake.getStateRangeScanIteratorArgsForCall = append(fake.getStateRangeScanIteratorArgsForCall, struct {
namespace string
startKey string
endKey string
}{namespace, startKey, endKey})
fake.recordInvocation("GetStateRangeScanIterator", []interface{}{namespace, startKey, endKey})
fake.getStateRangeScanIteratorMutex.Unlock()
if fake.GetStateRangeScanIteratorStub != nil {
return fake.GetStateRangeScanIteratorStub(namespace, startKey, endKey)
}
if specificReturn {
return ret.result1, ret.result2
}
return fake.getStateRangeScanIteratorReturns.result1, fake.getStateRangeScanIteratorReturns.result2
}
func (fake *TxSimulator) GetStateRangeScanIteratorCallCount() int {
fake.getStateRangeScanIteratorMutex.RLock()
defer fake.getStateRangeScanIteratorMutex.RUnlock()
return len(fake.getStateRangeScanIteratorArgsForCall)
}
func (fake *TxSimulator) GetStateRangeScanIteratorArgsForCall(i int) (string, string, string) {
fake.getStateRangeScanIteratorMutex.RLock()
defer fake.getStateRangeScanIteratorMutex.RUnlock()
return fake.getStateRangeScanIteratorArgsForCall[i].namespace, fake.getStateRangeScanIteratorArgsForCall[i].startKey, fake.getStateRangeScanIteratorArgsForCall[i].endKey
}
func (fake *TxSimulator) GetStateRangeScanIteratorReturns(result1 commonledger.ResultsIterator, result2 error) {
fake.GetStateRangeScanIteratorStub = nil
fake.getStateRangeScanIteratorReturns = struct {
result1 commonledger.ResultsIterator
result2 error
}{result1, result2}
}
func (fake *TxSimulator) GetStateRangeScanIteratorReturnsOnCall(i int, result1 commonledger.ResultsIterator, result2 error) {
fake.GetStateRangeScanIteratorStub = nil
if fake.getStateRangeScanIteratorReturnsOnCall == nil {
fake.getStateRangeScanIteratorReturnsOnCall = make(map[int]struct {
result1 commonledger.ResultsIterator
result2 error
})
}
fake.getStateRangeScanIteratorReturnsOnCall[i] = struct {
result1 commonledger.ResultsIterator
result2 error
}{result1, result2}
}
func (fake *TxSimulator) GetStateMetadata(namespace string, key string) (map[string][]byte, error) {
fake.getStateMetadataMutex.Lock()
ret, specificReturn := fake.getStateMetadataReturnsOnCall[len(fake.getStateMetadataArgsForCall)]
......@@ -475,59 +528,6 @@ func (fake *TxSimulator) GetStateMultipleKeysReturnsOnCall(i int, result1 [][]by
}{result1, result2}
}
func (fake *TxSimulator) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error) {
fake.getStateRangeScanIteratorMutex.Lock()
ret, specificReturn := fake.getStateRangeScanIteratorReturnsOnCall[len(fake.getStateRangeScanIteratorArgsForCall)]
fake.getStateRangeScanIteratorArgsForCall = append(fake.getStateRangeScanIteratorArgsForCall, struct {
namespace string
startKey string
endKey string
}{namespace, startKey, endKey})
fake.recordInvocation("GetStateRangeScanIterator", []interface{}{namespace, startKey, endKey})
fake.getStateRangeScanIteratorMutex.Unlock()
if fake.GetStateRangeScanIteratorStub != nil {
return fake.GetStateRangeScanIteratorStub(namespace, startKey, endKey)
}
if specificReturn {
return ret.result1, ret.result2
}
return fake.getStateRangeScanIteratorReturns.result1, fake.getStateRangeScanIteratorReturns.result2
}
func (fake *TxSimulator) GetStateRangeScanIteratorCallCount() int {
fake.getStateRangeScanIteratorMutex.RLock()
defer fake.getStateRangeScanIteratorMutex.RUnlock()
return len(fake.getStateRangeScanIteratorArgsForCall)
}
func (fake *TxSimulator) GetStateRangeScanIteratorArgsForCall(i int) (string, string, string) {
fake.getStateRangeScanIteratorMutex.RLock()
defer fake.getStateRangeScanIteratorMutex.RUnlock()
return fake.getStateRangeScanIteratorArgsForCall[i].namespace, fake.getStateRangeScanIteratorArgsForCall[i].startKey, fake.getStateRangeScanIteratorArgsForCall[i].endKey
}
func (fake *TxSimulator) GetStateRangeScanIteratorReturns(result1 commonledger.ResultsIterator, result2 error) {
fake.GetStateRangeScanIteratorStub = nil
fake.getStateRangeScanIteratorReturns = struct {
result1 commonledger.ResultsIterator
result2 error
}{result1, result2}
}
func (fake *TxSimulator) GetStateRangeScanIteratorReturnsOnCall(i int, result1 commonledger.ResultsIterator, result2 error) {
fake.GetStateRangeScanIteratorStub = nil
if fake.getStateRangeScanIteratorReturnsOnCall == nil {
fake.getStateRangeScanIteratorReturnsOnCall = make(map[int]struct {
result1 commonledger.ResultsIterator
result2 error
})
}
fake.getStateRangeScanIteratorReturnsOnCall[i] = struct {
result1 commonledger.ResultsIterator
result2 error
}{result1, result2}
}
func (fake *TxSimulator) ExecuteQuery(namespace string, query string) (commonledger.ResultsIterator, error) {
fake.executeQueryMutex.Lock()
ret, specificReturn := fake.executeQueryReturnsOnCall[len(fake.executeQueryArgsForCall)]
......@@ -1472,12 +1472,12 @@ func (fake *TxSimulator) Invocations() map[string][][]interface{} {
defer fake.invocationsMutex.RUnlock()
fake.getStateMutex.RLock()
defer fake.getStateMutex.RUnlock()
fake.getStateRangeScanIteratorMutex.RLock()
defer fake.getStateRangeScanIteratorMutex.RUnlock()
fake.getStateMetadataMutex.RLock()
defer fake.getStateMetadataMutex.RUnlock()
fake.getStateMultipleKeysMutex.RLock()
defer fake.getStateMultipleKeysMutex.RUnlock()
fake.getStateRangeScanIteratorMutex.RLock()
defer fake.getStateRangeScanIteratorMutex.RUnlock()
fake.executeQueryMutex.RLock()
defer fake.executeQueryMutex.RUnlock()
fake.getPrivateDataMutex.RLock()
......
......@@ -43,7 +43,7 @@ func (ctp *customTxProcessor) GenerateSimulationResults(txEnvelop *common.Envelo
func TestCustomProcessor(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
provider, _ := NewProvider()
provider := testutilNewProvider(t)
defer provider.Close()
// create a custom tx processor and register it to handle '100 and 101' type of transaction
......
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package kvledger
import (
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/protos/common"
)
type deployedCCInfoRetriever struct {
ledger ledger.PeerLedger
infoProvider ledger.DeployedChaincodeInfoProvider
}
func (r *deployedCCInfoRetriever) ChaincodeInfo(chaincodeName string) (*ledger.DeployedChaincodeInfo, error) {
qe, err := r.ledger.NewQueryExecutor()
if err != nil {
return nil, err
}
defer qe.Done()
return r.infoProvider.ChaincodeInfo(chaincodeName, qe)
}
func (r *deployedCCInfoRetriever) CollectionInfo(chaincodeName, collectionName string) (*common.StaticCollectionConfig, error) {
qe, err := r.ledger.NewQueryExecutor()
if err != nil {
return nil, err
}
defer qe.Done()
return r.infoProvider.CollectionInfo(chaincodeName, collectionName, qe)
}
......@@ -55,7 +55,9 @@ func init() {
// Note, if subledgers are supported in the future,
// the various ledgers could be created/managed at this level
cleanup()
ledgermgmt.Initialize(nil, platforms.NewRegistry(&golang.Platform{}))
ledgermgmt.Initialize(&ledgermgmt.Initializer{
PlatformRegistry: platforms.NewRegistry(&golang.Platform{}),
})
var err error
gb, _ := configtxtest.MakeGenesisBlock(ledgerID)
......
......@@ -50,7 +50,8 @@ func newKVLedger(
historyDB historydb.HistoryDB,
configHistoryMgr confighistory.Mgr,
stateListeners []ledger.StateListener,
bookkeeperProvider bookkeeping.Provider) (*kvLedger, error) {
bookkeeperProvider bookkeeping.Provider,
ccInfoProvider ledger.DeployedChaincodeInfoProvider) (*kvLedger, error) {
logger.Debugf("Creating KVLedger ledgerID=%s: ", ledgerID)
stateListeners = append(stateListeners, configHistoryMgr)
......
......@@ -10,11 +10,10 @@ import (
"bytes"
"fmt"
"github.com/hyperledger/fabric/core/ledger/confighistory"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/core/ledger/confighistory"
"github.com/hyperledger/fabric/core/ledger/kvledger/bookkeeping"
"github.com/hyperledger/fabric/core/ledger/kvledger/history/historydb"
"github.com/hyperledger/fabric/core/ledger/kvledger/history/historydb/historyleveldb"
......@@ -48,39 +47,36 @@ type Provider struct {
configHistoryMgr confighistory.Mgr
stateListeners []ledger.StateListener
bookkeepingProvider bookkeeping.Provider
initializer *ledger.Initializer
}
// NewProvider instantiates a new Provider.
// This is not thread-safe and assumed to be synchronized be the caller
func NewProvider() (ledger.PeerLedgerProvider, error) {
logger.Info("Initializing ledger provider")
// Initialize the ID store (inventory of chainIds/ledgerIds)
idStore := openIDStore(ledgerconfig.GetLedgerProviderPath())
ledgerStoreProvider := ledgerstorage.NewProvider()
// Initialize the versioned database (state database)
vdbProvider, err := privacyenabledstate.NewCommonStorageDBProvider()
if err != nil {
return nil, err
}
// Initialize the history database (index for history of values by key)
historydbProvider := historyleveldb.NewHistoryDBProvider()
bookkeepingProvider := bookkeeping.NewProvider()
// Initialize config history mgr
configHistoryMgr := confighistory.NewMgr()
logger.Info("ledger provider Initialized")
provider := &Provider{idStore, ledgerStoreProvider, vdbProvider, historydbProvider, configHistoryMgr, nil, bookkeepingProvider}
provider.recoverUnderConstructionLedger()
provider := &Provider{idStore, ledgerStoreProvider,
vdbProvider, historydbProvider, nil, nil, bookkeepingProvider, nil}
return provider, nil
}
// Initialize implements the corresponding method from interface ledger.PeerLedgerProvider
func (provider *Provider) Initialize(stateListeners []ledger.StateListener) {
provider.stateListeners = stateListeners
func (provider *Provider) Initialize(initializer *ledger.Initializer) {
provider.initializer = initializer
provider.configHistoryMgr = confighistory.NewMgr()
provider.stateListeners = initializer.StateListeners
provider.recoverUnderConstructionLedger()
}
// Create implements the corresponding method from interface ledger.PeerLedgerProvider
......@@ -155,7 +151,8 @@ func (provider *Provider) openInternal(ledgerID string) (ledger.PeerLedger, erro
// Create a kvLedger for this chain/ledger, which encasulates the underlying data stores
// (id store, blockstore, state database, history database)
l, err := newKVLedger(ledgerID, blockStore, vDB, historyDB, provider.configHistoryMgr, provider.stateListeners, provider.bookkeepingProvider)
l, err := newKVLedger(ledgerID, blockStore, vDB, historyDB, provider.configHistoryMgr,
provider.stateListeners, provider.bookkeepingProvider, provider.initializer.DeployedChaincodeInfoProvider)
if err != nil {
return nil, err
}
......
......@@ -27,8 +27,9 @@ import (
"github.com/hyperledger/fabric/common/ledger/blkstorage/fsblkstorage"
"github.com/hyperledger/fabric/common/ledger/testutil"
"github.com/hyperledger/fabric/common/util"
ledgerproto "github.com/hyperledger/fabric/core/ledger"
lgr "github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
"github.com/hyperledger/fabric/core/ledger/mock"
"github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/ledger/queryresult"
putils "github.com/hyperledger/fabric/protos/utils"
......@@ -39,7 +40,7 @@ func TestLedgerProvider(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
numLedgers := 10
provider, _ := NewProvider()
provider := testutilNewProvider(t)
existingLedgerIDs, err := provider.List()
testutil.AssertNoError(t, err, "")
testutil.AssertEquals(t, len(existingLedgerIDs), 0)
......@@ -55,7 +56,7 @@ func TestLedgerProvider(t *testing.T) {
provider.Close()
provider, _ = NewProvider()
provider = testutilNewProvider(t)
defer provider.Close()
ledgerIds, _ := provider.List()
testutil.AssertEquals(t, len(ledgerIds), numLedgers)
......@@ -97,12 +98,12 @@ func TestLedgerProvider(t *testing.T) {
func TestRecovery(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
provider, _ := NewProvider()
provider := testutilNewProvider(t)
// now create the genesis block
genesisBlock, _ := configtxtest.MakeGenesisBlock(constructTestLedgerID(1))
ledger, err := provider.(*Provider).openInternal(constructTestLedgerID(1))
ledger.CommitWithPvtData(&ledgerproto.BlockAndPvtData{Block: genesisBlock})
ledger.CommitWithPvtData(&lgr.BlockAndPvtData{Block: genesisBlock})
ledger.Close()
// Case 1: assume a crash happens, force underconstruction flag to be set to simulate
......@@ -111,8 +112,7 @@ func TestRecovery(t *testing.T) {
provider.Close()
// construct a new provider to invoke recovery
provider, err = NewProvider()
testutil.AssertNoError(t, err, "Provider failed to recover an underConstructionLedger")
provider = testutilNewProvider(t)
// verify the underecoveryflag and open the ledger
flag, err := provider.(*Provider).idStore.getUnderConstructionFlag()
testutil.AssertNoError(t, err, "Failed to read the underconstruction flag")
......@@ -127,7 +127,7 @@ func TestRecovery(t *testing.T) {
provider.Close()
// construct a new provider to invoke recovery
provider, err = NewProvider()
provider = testutilNewProvider(t)
testutil.AssertNoError(t, err, "Provider failed to recover an underConstructionLedger")
flag, err = provider.(*Provider).idStore.getUnderConstructionFlag()
testutil.AssertNoError(t, err, "Failed to read the underconstruction flag")
......@@ -139,8 +139,8 @@ func TestMultipleLedgerBasicRW(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
numLedgers := 10
provider, _ := NewProvider()
ledgers := make([]ledgerproto.PeerLedger, numLedgers)
provider := testutilNewProvider(t)
ledgers := make([]lgr.PeerLedger, numLedgers)
for i := 0; i < numLedgers; i++ {
bg, gb := testutil.NewBlockGenerator(t, constructTestLedgerID(i), false)
l, err := provider.Create(gb)
......@@ -155,16 +155,16 @@ func TestMultipleLedgerBasicRW(t *testing.T) {
testutil.AssertNoError(t, err, "")
pubSimBytes, _ := res.GetPubSimulationBytes()
b := bg.NextBlock([][]byte{pubSimBytes})
err = l.CommitWithPvtData(&ledgerproto.BlockAndPvtData{Block: b})
err = l.CommitWithPvtData(&lgr.BlockAndPvtData{Block: b})
l.Close()
testutil.AssertNoError(t, err, "")
}
provider.Close()
provider, _ = NewProvider()
provider = testutilNewProvider(t)
defer provider.Close()
ledgers = make([]ledgerproto.PeerLedger, numLedgers)
ledgers = make([]lgr.PeerLedger, numLedgers)
for i := 0; i < numLedgers; i++ {
l, err := provider.Open(constructTestLedgerID(i))
testutil.AssertNoError(t, err, "")
......@@ -189,7 +189,7 @@ func TestLedgerBackup(t *testing.T) {
// create and populate a ledger in the original environment
env := createTestEnv(t, originalPath)
provider, _ := NewProvider()
provider := testutilNewProvider(t)
bg, gb := testutil.NewBlockGenerator(t, ledgerid, false)
gbHash := gb.Header.Hash()
ledger, _ := provider.Create(gb)
......@@ -203,7 +203,7 @@ func TestLedgerBackup(t *testing.T) {
simRes, _ := simulator.GetTxSimulationResults()
pubSimBytes, _ := simRes.GetPubSimulationBytes()
block1 := bg.NextBlock([][]byte{pubSimBytes})
ledger.CommitWithPvtData(&ledgerproto.BlockAndPvtData{Block: block1})
ledger.CommitWithPvtData(&lgr.BlockAndPvtData{Block: block1})
txid = util.GenerateUUID()
simulator, _ = ledger.NewTxSimulator(txid)
......@@ -214,7 +214,7 @@ func TestLedgerBackup(t *testing.T) {
simRes, _ = simulator.GetTxSimulationResults()
pubSimBytes, _ = simRes.GetPubSimulationBytes()
block2 := bg.NextBlock([][]byte{pubSimBytes})
ledger.CommitWithPvtData(&ledgerproto.BlockAndPvtData{Block: block2})
ledger.CommitWithPvtData(&lgr.BlockAndPvtData{Block: block2})
ledger.Close()
provider.Close()
......@@ -231,7 +231,7 @@ func TestLedgerBackup(t *testing.T) {
defer env.cleanup()
// Instantiate the ledger from restore environment and this should behave exactly as it would have in the original environment
provider, _ = NewProvider()
provider = testutilNewProvider(t)
defer provider.Close()
_, err := provider.Create(gb)
......@@ -300,3 +300,12 @@ func TestLedgerBackup(t *testing.T) {
func constructTestLedgerID(i int) string {
return fmt.Sprintf("ledger_%06d", i)
}
func testutilNewProvider(t *testing.T) lgr.PeerLedgerProvider {
provider, err := NewProvider()
testutil.AssertNoError(t, err, "")
provider.Initialize(&lgr.Initializer{
DeployedChaincodeInfoProvider: &mock.DeployedChaincodeInfoProvider{},
})
return provider
}
......@@ -41,7 +41,7 @@ func TestMain(m *testing.M) {
func TestKVLedgerBlockStorage(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
provider, _ := NewProvider()
provider := testutilNewProvider(t)
defer provider.Close()
bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
......@@ -124,7 +124,7 @@ func TestKVLedgerBlockStorageWithPvtdata(t *testing.T) {
t.Skip()
env := newTestEnv(t)
defer env.cleanup()
provider, _ := NewProvider()
provider := testutilNewProvider(t)
defer provider.Close()
bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
......@@ -185,7 +185,7 @@ func TestKVLedgerBlockStorageWithPvtdata(t *testing.T) {
func TestKVLedgerDBRecovery(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
provider, _ := NewProvider()
provider := testutilNewProvider(t)
defer provider.Close()
testLedgerid := "testLedger"
bg, gb := testutil.NewBlockGenerator(t, testLedgerid, false)
......@@ -257,7 +257,7 @@ func TestKVLedgerDBRecovery(t *testing.T) {
// Here the peer comes online and calls NewKVLedger to get a handler for the ledger
// StateDB and HistoryDB should be recovered before returning from NewKVLedger call
provider, _ = NewProvider()
provider = testutilNewProvider(t)
ledger, _ = provider.Open(testLedgerid)
checkBCSummaryForTest(t, ledger,
&bcSummary{
......@@ -305,7 +305,7 @@ func TestKVLedgerDBRecovery(t *testing.T) {
// we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
// history DB should be recovered before returning from NewKVLedger call
provider, _ = NewProvider()
provider = testutilNewProvider(t)
ledger, _ = provider.Open(testLedgerid)
checkBCSummaryForTest(t, ledger,
......@@ -354,7 +354,7 @@ func TestKVLedgerDBRecovery(t *testing.T) {
// we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
// state DB should be recovered before returning from NewKVLedger call
provider, _ = NewProvider()
provider = testutilNewProvider(t)
ledger, _ = provider.Open(testLedgerid)
checkBCSummaryForTest(t, ledger,
&bcSummary{
......@@ -379,7 +379,7 @@ func TestLedgerWithCouchDbEnabledWithBinaryAndJSONData(t *testing.T) {
env := newTestEnv(t)
defer env.cleanup()
provider, _ := NewProvider()
provider := testutilNewProvider(t)
defer provider.Close()
bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
gbHash := gb.Header.Hash()
......
......@@ -18,7 +18,6 @@ package main
import (
"fmt"
"os"
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
......@@ -56,7 +55,9 @@ func init() {
testutil.SetupCoreYAMLConfig()
cleanup()
ledgermgmt.Initialize(nil, platforms.NewRegistry(&golang.Platform{}))
ledgermgmt.Initialize(&ledgermgmt.Initializer{
PlatformRegistry: platforms.NewRegistry(&golang.Platform{}),
})
var err error
gb, _ := configtxtest.MakeGenesisBlock(ledgerID)
peerLedger, err = ledgermgmt.CreateLedger(gb)
......
......@@ -9,10 +9,10 @@ package kvledger
import (
"testing"
"github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset"
"github.com/hyperledger/fabric/common/ledger/testutil"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/core/ledger/mock"
"github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset"
"github.com/stretchr/testify/assert"
)
......@@ -26,7 +26,10 @@ func TestStateListener(t *testing.T) {
channelid := "testLedger"
namespace := "testchaincode"
mockListener := &mockStateListener{namespace: namespace}
provider.Initialize([]ledger.StateListener{mockListener})
provider.Initialize(&ledger.Initializer{
DeployedChaincodeInfoProvider: &mock.DeployedChaincodeInfoProvider{},
StateListeners: []ledger.StateListener{mockListener},
})
bg, gb := testutil.NewBlockGenerator(t, channelid, false)
lgr, err := provider.Create(gb)
......
......@@ -11,12 +11,19 @@ import (
commonledger "github.com/hyperledger/fabric/common/ledger"
"github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/ledger/rwset"
"github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset"
"github.com/hyperledger/fabric/protos/peer"
)
// Initializer encapsulates dependencies for PeerLedgerProvider
type Initializer struct {
StateListeners []StateListener
DeployedChaincodeInfoProvider DeployedChaincodeInfoProvider
}
// PeerLedgerProvider provides handle to ledger instances
type PeerLedgerProvider interface {
Initialize(statelisteners []StateListener)
Initialize(initializer *Initializer)
// Create creates a new ledger with the given genesis block.
// This function guarantees that the creation of ledger and committing the genesis block would an atomic action
// The chain id retrieved from the genesis block is treated as a ledger id
......@@ -373,3 +380,38 @@ type PvtdataHashMismatch struct {
ChaincodeName, CollectionName string
ExpectedHash []byte
}
// DeployedChaincodeInfoProvider is a dependency that is used by ledger to build collection config history
// LSCC module is expected to provide an implementation fo this dependencys
type DeployedChaincodeInfoProvider interface {
Namespaces() []string
UpdatedChaincodes(stateUpdates map[string][]*kvrwset.KVWrite) ([]*ChaincodeLifecycleInfo, error)
ChaincodeInfo(chaincodeName string, qe SimpleQueryExecutor) (*DeployedChaincodeInfo, error)
CollectionInfo(chaincodeName, collectionName string, qe SimpleQueryExecutor) (*common.StaticCollectionConfig, error)
}