github.com/yimialmonte/fabric@v2.1.1+incompatible/core/ledger/ledger_interface.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package ledger
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/hyperledger/fabric-lib-go/healthz"
    14  	"github.com/hyperledger/fabric-protos-go/common"
    15  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    16  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    17  	"github.com/hyperledger/fabric-protos-go/peer"
    18  	"github.com/hyperledger/fabric/bccsp"
    19  	commonledger "github.com/hyperledger/fabric/common/ledger"
    20  	"github.com/hyperledger/fabric/common/metrics"
    21  	"github.com/hyperledger/fabric/core/ledger/util/couchdb"
    22  )
    23  
    24  // Initializer encapsulates dependencies for PeerLedgerProvider
    25  type Initializer struct {
    26  	StateListeners                  []StateListener
    27  	DeployedChaincodeInfoProvider   DeployedChaincodeInfoProvider
    28  	MembershipInfoProvider          MembershipInfoProvider
    29  	ChaincodeLifecycleEventProvider ChaincodeLifecycleEventProvider
    30  	MetricsProvider                 metrics.Provider
    31  	HealthCheckRegistry             HealthCheckRegistry
    32  	Config                          *Config
    33  	CustomTxProcessors              map[common.HeaderType]CustomTxProcessor
    34  	Hasher                          Hasher
    35  }
    36  
    37  // Config is a structure used to configure a ledger provider.
    38  type Config struct {
    39  	// RootFSPath is the top-level directory where ledger files are stored.
    40  	RootFSPath string
    41  	// StateDBConfig holds the configuration parameters for the state database.
    42  	StateDBConfig *StateDBConfig
    43  	// PrivateDataConfig holds the configuration parameters for the private data store.
    44  	PrivateDataConfig *PrivateDataConfig
    45  	// HistoryDBConfig holds the configuration parameters for the transaction history database.
    46  	HistoryDBConfig *HistoryDBConfig
    47  }
    48  
    49  // StateDBConfig is a structure used to configure the state parameters for the ledger.
    50  type StateDBConfig struct {
    51  	// StateDatabase is the database to use for storing last known state.  The
    52  	// two supported options are "goleveldb" and "CouchDB".
    53  	StateDatabase string
    54  	// CouchDB is the configuration for CouchDB.  It is used when StateDatabase
    55  	// is set to "CouchDB".
    56  	CouchDB *couchdb.Config
    57  }
    58  
    59  // PrivateDataConfig is a structure used to configure a private data storage provider.
    60  type PrivateDataConfig struct {
    61  	// BatchesInterval is the minimum duration (milliseconds) between batches
    62  	// for converting ineligible missing data entries into eligible entries.
    63  	BatchesInterval int
    64  	// MatchBatchSize is the maximum size of batches when converting ineligible
    65  	// missing data entries into eligible entries.
    66  	MaxBatchSize int
    67  	// PurgeInterval is the number of blocks to wait until purging expired
    68  	// private data entries.
    69  	PurgeInterval int
    70  }
    71  
    72  // HistoryDBConfig is a structure used to configure the transaction history database.
    73  type HistoryDBConfig struct {
    74  	Enabled bool
    75  }
    76  
    77  // PeerLedgerProvider provides handle to ledger instances
    78  type PeerLedgerProvider interface {
    79  	// Create creates a new ledger with the given genesis block.
    80  	// This function guarantees that the creation of ledger and committing the genesis block would an atomic action
    81  	// The chain id retrieved from the genesis block is treated as a ledger id
    82  	Create(genesisBlock *common.Block) (PeerLedger, error)
    83  	// Open opens an already created ledger
    84  	Open(ledgerID string) (PeerLedger, error)
    85  	// Exists tells whether the ledger with given id exists
    86  	Exists(ledgerID string) (bool, error)
    87  	// List lists the ids of the existing ledgers
    88  	List() ([]string, error)
    89  	// Close closes the PeerLedgerProvider
    90  	Close()
    91  }
    92  
    93  // PeerLedger differs from the OrdererLedger in that PeerLedger locally maintain a bitmask
    94  // that tells apart valid transactions from invalid ones
    95  type PeerLedger interface {
    96  	commonledger.Ledger
    97  	// GetTransactionByID retrieves a transaction by id
    98  	GetTransactionByID(txID string) (*peer.ProcessedTransaction, error)
    99  	// GetBlockByHash returns a block given it's hash
   100  	GetBlockByHash(blockHash []byte) (*common.Block, error)
   101  	// GetBlockByTxID returns a block which contains a transaction
   102  	GetBlockByTxID(txID string) (*common.Block, error)
   103  	// GetTxValidationCodeByTxID returns reason code of transaction validation
   104  	GetTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error)
   105  	// NewTxSimulator gives handle to a transaction simulator.
   106  	// A client can obtain more than one 'TxSimulator's for parallel execution.
   107  	// Any snapshoting/synchronization should be performed at the implementation level if required
   108  	NewTxSimulator(txid string) (TxSimulator, error)
   109  	// NewQueryExecutor gives handle to a query executor.
   110  	// A client can obtain more than one 'QueryExecutor's for parallel execution.
   111  	// Any synchronization should be performed at the implementation level if required
   112  	NewQueryExecutor() (QueryExecutor, error)
   113  	// NewHistoryQueryExecutor gives handle to a history query executor.
   114  	// A client can obtain more than one 'HistoryQueryExecutor's for parallel execution.
   115  	// Any synchronization should be performed at the implementation level if required
   116  	NewHistoryQueryExecutor() (HistoryQueryExecutor, error)
   117  	// GetPvtDataAndBlockByNum returns the block and the corresponding pvt data.
   118  	// The pvt data is filtered by the list of 'ns/collections' supplied
   119  	// A nil filter does not filter any results and causes retrieving all the pvt data for the given blockNum
   120  	GetPvtDataAndBlockByNum(blockNum uint64, filter PvtNsCollFilter) (*BlockAndPvtData, error)
   121  	// GetPvtDataByNum returns only the pvt data  corresponding to the given block number
   122  	// The pvt data is filtered by the list of 'ns/collections' supplied in the filter
   123  	// A nil filter does not filter any results and causes retrieving all the pvt data for the given blockNum
   124  	GetPvtDataByNum(blockNum uint64, filter PvtNsCollFilter) ([]*TxPvtData, error)
   125  	// CommitLegacy commits the block and the corresponding pvt data in an atomic operation following the v14 validation/commit path
   126  	// TODO: add a new Commit() path that replaces CommitLegacy() for the validation refactor described in FAB-12221
   127  	CommitLegacy(blockAndPvtdata *BlockAndPvtData, commitOpts *CommitOptions) error
   128  	// GetConfigHistoryRetriever returns the ConfigHistoryRetriever
   129  	GetConfigHistoryRetriever() (ConfigHistoryRetriever, error)
   130  	// CommitPvtDataOfOldBlocks commits the private data corresponding to already committed block
   131  	// If hashes for some of the private data supplied in this function does not match
   132  	// the corresponding hash present in the block, the unmatched private data is not
   133  	// committed and instead the mismatch inforation is returned back
   134  	CommitPvtDataOfOldBlocks(reconciledPvtdata []*ReconciledPvtdata) ([]*PvtdataHashMismatch, error)
   135  	// GetMissingPvtDataTracker return the MissingPvtDataTracker
   136  	GetMissingPvtDataTracker() (MissingPvtDataTracker, error)
   137  	// DoesPvtDataInfoExist returns true when
   138  	// (1) the ledger has pvtdata associated with the given block number (or)
   139  	// (2) a few or all pvtdata associated with the given block number is missing but the
   140  	//     missing info is recorded in the ledger (or)
   141  	// (3) the block is committed and does not contain any pvtData.
   142  	DoesPvtDataInfoExist(blockNum uint64) (bool, error)
   143  }
   144  
   145  // SimpleQueryExecutor encapsulates basic functions
   146  type SimpleQueryExecutor interface {
   147  	// GetState gets the value for given namespace and key. For a chaincode, the namespace corresponds to the chaincodeId
   148  	GetState(namespace string, key string) ([]byte, error)
   149  	// GetStateRangeScanIterator returns an iterator that contains all the key-values between given key ranges.
   150  	// startKey is included in the results and endKey is excluded. An empty startKey refers to the first available key
   151  	// and an empty endKey refers to the last available key. For scanning all the keys, both the startKey and the endKey
   152  	// can be supplied as empty strings. However, a full scan should be used judiciously for performance reasons.
   153  	// The returned ResultsIterator contains results of type *KV which is defined in fabric-protos/ledger/queryresult.
   154  	GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error)
   155  	// GetPrivateDataHash gets the hash of the value of a private data item identified by a tuple <namespace, collection, key>
   156  	// Function `GetPrivateData` is only meaningful when it is invoked on a peer that is authorized to have the private data
   157  	// for the collection <namespace, collection>. However, the function `GetPrivateDataHash` can be invoked on any peer
   158  	// to get the hash of the current value
   159  	GetPrivateDataHash(namespace, collection, key string) ([]byte, error)
   160  }
   161  
   162  // QueryExecutor executes the queries
   163  // Get* methods are for supporting KV-based data model. ExecuteQuery method is for supporting a rich datamodel and query support
   164  //
   165  // ExecuteQuery method in the case of a rich data model is expected to support queries on
   166  // latest state, historical state and on the intersection of state and transactions
   167  type QueryExecutor interface {
   168  	SimpleQueryExecutor
   169  	// GetStateMetadata returns the metadata for given namespace and key
   170  	GetStateMetadata(namespace, key string) (map[string][]byte, error)
   171  	// GetStateMultipleKeys gets the values for multiple keys in a single call
   172  	GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error)
   173  	// GetStateRangeScanIteratorWithMetadata returns an iterator that contains all the key-values between given key ranges.
   174  	// startKey is included in the results and endKey is excluded. An empty startKey refers to the first available key
   175  	// and an empty endKey refers to the last available key. For scanning all the keys, both the startKey and the endKey
   176  	// can be supplied as empty strings. However, a full scan should be used judiciously for performance reasons.
   177  	// metadata is a map of additional query parameters
   178  	// The returned ResultsIterator contains results of type *KV which is defined in fabric-protos/ledger/queryresult.
   179  	GetStateRangeScanIteratorWithMetadata(namespace string, startKey, endKey string, metadata map[string]interface{}) (QueryResultsIterator, error)
   180  	// ExecuteQuery executes the given query and returns an iterator that contains results of type specific to the underlying data store.
   181  	// Only used for state databases that support query
   182  	// For a chaincode, the namespace corresponds to the chaincodeId
   183  	// The returned ResultsIterator contains results of type *KV which is defined in fabric-protos/ledger/queryresult.
   184  	ExecuteQuery(namespace, query string) (commonledger.ResultsIterator, error)
   185  	// ExecuteQueryWithMetadata executes the given query and returns an iterator that contains results of type specific to the underlying data store.
   186  	// metadata is a map of additional query parameters
   187  	// Only used for state databases that support query
   188  	// For a chaincode, the namespace corresponds to the chaincodeId
   189  	// The returned ResultsIterator contains results of type *KV which is defined in fabric-protos/ledger/queryresult.
   190  	ExecuteQueryWithMetadata(namespace, query string, metadata map[string]interface{}) (QueryResultsIterator, error)
   191  	// GetPrivateData gets the value of a private data item identified by a tuple <namespace, collection, key>
   192  	GetPrivateData(namespace, collection, key string) ([]byte, error)
   193  	// GetPrivateDataMetadata gets the metadata of a private data item identified by a tuple <namespace, collection, key>
   194  	GetPrivateDataMetadata(namespace, collection, key string) (map[string][]byte, error)
   195  	// GetPrivateDataMetadataByHash gets the metadata of a private data item identified by a tuple <namespace, collection, keyhash>
   196  	GetPrivateDataMetadataByHash(namespace, collection string, keyhash []byte) (map[string][]byte, error)
   197  	// GetPrivateDataMultipleKeys gets the values for the multiple private data items in a single call
   198  	GetPrivateDataMultipleKeys(namespace, collection string, keys []string) ([][]byte, error)
   199  	// GetPrivateDataRangeScanIterator returns an iterator that contains all the key-values between given key ranges.
   200  	// startKey is included in the results and endKey is excluded. An empty startKey refers to the first available key
   201  	// and an empty endKey refers to the last available key. For scanning all the keys, both the startKey and the endKey
   202  	// can be supplied as empty strings. However, a full scan shuold be used judiciously for performance reasons.
   203  	// The returned ResultsIterator contains results of type *KV which is defined in fabric-protos/ledger/queryresult.
   204  	GetPrivateDataRangeScanIterator(namespace, collection, startKey, endKey string) (commonledger.ResultsIterator, error)
   205  	// ExecuteQuery executes the given query and returns an iterator that contains results of type specific to the underlying data store.
   206  	// Only used for state databases that support query
   207  	// For a chaincode, the namespace corresponds to the chaincodeId
   208  	// The returned ResultsIterator contains results of type *KV which is defined in fabric-protos/ledger/queryresult.
   209  	ExecuteQueryOnPrivateData(namespace, collection, query string) (commonledger.ResultsIterator, error)
   210  	// Done releases resources occupied by the QueryExecutor
   211  	Done()
   212  }
   213  
   214  // HistoryQueryExecutor executes the history queries
   215  type HistoryQueryExecutor interface {
   216  	// GetHistoryForKey retrieves the history of values for a key.
   217  	// The returned ResultsIterator contains results of type *KeyModification which is defined in fabric-protos/ledger/queryresult.
   218  	GetHistoryForKey(namespace string, key string) (commonledger.ResultsIterator, error)
   219  }
   220  
   221  // TxSimulator simulates a transaction on a consistent snapshot of the 'as recent state as possible'
   222  // Set* methods are for supporting KV-based data model. ExecuteUpdate method is for supporting a rich datamodel and query support
   223  type TxSimulator interface {
   224  	QueryExecutor
   225  	// SetState sets the given value for the given namespace and key. For a chaincode, the namespace corresponds to the chaincodeId
   226  	SetState(namespace string, key string, value []byte) error
   227  	// DeleteState deletes the given namespace and key
   228  	DeleteState(namespace string, key string) error
   229  	// SetMultipleKeys sets the values for multiple keys in a single call
   230  	SetStateMultipleKeys(namespace string, kvs map[string][]byte) error
   231  	// SetStateMetadata sets the metadata associated with an existing key-tuple <namespace, key>
   232  	SetStateMetadata(namespace, key string, metadata map[string][]byte) error
   233  	// DeleteStateMetadata deletes the metadata (if any) associated with an existing key-tuple <namespace, key>
   234  	DeleteStateMetadata(namespace, key string) error
   235  	// ExecuteUpdate for supporting rich data model (see comments on QueryExecutor above)
   236  	ExecuteUpdate(query string) error
   237  	// SetPrivateData sets the given value to a key in the private data state represented by the tuple <namespace, collection, key>
   238  	SetPrivateData(namespace, collection, key string, value []byte) error
   239  	// SetPrivateDataMultipleKeys sets the values for multiple keys in the private data space in a single call
   240  	SetPrivateDataMultipleKeys(namespace, collection string, kvs map[string][]byte) error
   241  	// DeletePrivateData deletes the given tuple <namespace, collection, key> from private data
   242  	DeletePrivateData(namespace, collection, key string) error
   243  	// SetPrivateDataMetadata sets the metadata associated with an existing key-tuple <namespace, collection, key>
   244  	SetPrivateDataMetadata(namespace, collection, key string, metadata map[string][]byte) error
   245  	// DeletePrivateDataMetadata deletes the metadata associated with an existing key-tuple <namespace, collection, key>
   246  	DeletePrivateDataMetadata(namespace, collection, key string) error
   247  	// GetTxSimulationResults encapsulates the results of the transaction simulation.
   248  	// This should contain enough detail for
   249  	// - The update in the state that would be caused if the transaction is to be committed
   250  	// - The environment in which the transaction is executed so as to be able to decide the validity of the environment
   251  	//   (at a later time on a different peer) during committing the transactions
   252  	// Different ledger implementation (or configurations of a single implementation) may want to represent the above two pieces
   253  	// of information in different way in order to support different data-models or optimize the information representations.
   254  	// Returned type 'TxSimulationResults' contains the simulation results for both the public data and the private data.
   255  	// The public data simulation results are expected to be used as in V1 while the private data simulation results are expected
   256  	// to be used by the gossip to disseminate this to the other endorsers (in phase-2 of sidedb)
   257  	GetTxSimulationResults() (*TxSimulationResults, error)
   258  }
   259  
   260  // QueryResultsIterator - an iterator for query result set
   261  type QueryResultsIterator interface {
   262  	commonledger.ResultsIterator
   263  	// GetBookmarkAndClose returns a paging bookmark and releases resources occupied by the iterator
   264  	GetBookmarkAndClose() string
   265  }
   266  
   267  // TxPvtData encapsulates the transaction number and pvt write-set for a transaction
   268  type TxPvtData struct {
   269  	SeqInBlock uint64
   270  	WriteSet   *rwset.TxPvtReadWriteSet
   271  }
   272  
   273  // TxPvtDataMap is a map from txNum to the pvtData
   274  type TxPvtDataMap map[uint64]*TxPvtData
   275  
   276  // MissingPvtData contains a namespace and collection for
   277  // which the pvtData is not present. It also denotes
   278  // whether the missing pvtData is eligible (i.e., whether
   279  // the peer is member of the [namespace, collection]
   280  type MissingPvtData struct {
   281  	Namespace  string
   282  	Collection string
   283  	IsEligible bool
   284  }
   285  
   286  // TxMissingPvtDataMap is a map from txNum to the list of
   287  // missing pvtData
   288  type TxMissingPvtDataMap map[uint64][]*MissingPvtData
   289  
   290  // BlockAndPvtData encapsulates the block and a map that contains the tuples <seqInBlock, *TxPvtData>
   291  // The map is expected to contain the entries only for the transactions that has associated pvt data
   292  type BlockAndPvtData struct {
   293  	Block          *common.Block
   294  	PvtData        TxPvtDataMap
   295  	MissingPvtData TxMissingPvtDataMap
   296  }
   297  
   298  // ReconciledPvtdata contains the private data for a block for reconciliation
   299  type ReconciledPvtdata struct {
   300  	BlockNum  uint64
   301  	WriteSets TxPvtDataMap
   302  }
   303  
   304  // Add adds a given missing private data in the MissingPrivateDataList
   305  func (txMissingPvtData TxMissingPvtDataMap) Add(txNum uint64, ns, coll string, isEligible bool) {
   306  	txMissingPvtData[txNum] = append(txMissingPvtData[txNum], &MissingPvtData{ns, coll, isEligible})
   307  }
   308  
   309  // RetrievedPvtdata is a dependency that is implemented by coordinator/gossip for ledger
   310  // to be able to purge the transactions from the block after retrieving private data
   311  type RetrievedPvtdata interface {
   312  	GetBlockPvtdata() *BlockPvtdata
   313  	Purge()
   314  }
   315  
   316  // TxPvtdataInfo captures information about the requested private data to be retrieved
   317  type TxPvtdataInfo struct {
   318  	TxID                  string
   319  	Invalid               bool
   320  	SeqInBlock            uint64
   321  	CollectionPvtdataInfo []*CollectionPvtdataInfo
   322  }
   323  
   324  // CollectionPvtdataInfo contains information about the private data for a given collection
   325  type CollectionPvtdataInfo struct {
   326  	Namespace, Collection string
   327  	ExpectedHash          []byte
   328  	CollectionConfig      *peer.StaticCollectionConfig
   329  	Endorsers             []*peer.Endorsement
   330  }
   331  
   332  // BlockPvtdata contains the retrieved private data as well as missing and ineligible
   333  // private data for use at commit time
   334  type BlockPvtdata struct {
   335  	PvtData        TxPvtDataMap
   336  	MissingPvtData TxMissingPvtDataMap
   337  }
   338  
   339  // CommitOptions encapsulates options associated with a block commit.
   340  type CommitOptions struct {
   341  	FetchPvtDataFromLedger bool
   342  }
   343  
   344  // PvtCollFilter represents the set of the collection names (as keys of the map with value 'true')
   345  type PvtCollFilter map[string]bool
   346  
   347  // PvtNsCollFilter specifies the tuple <namespace, PvtCollFilter>
   348  type PvtNsCollFilter map[string]PvtCollFilter
   349  
   350  // NewPvtNsCollFilter constructs an empty PvtNsCollFilter
   351  func NewPvtNsCollFilter() PvtNsCollFilter {
   352  	return make(map[string]PvtCollFilter)
   353  }
   354  
   355  // Has returns true if the pvtdata includes the data for collection <ns,coll>
   356  func (pvtdata *TxPvtData) Has(ns string, coll string) bool {
   357  	if pvtdata.WriteSet == nil {
   358  		return false
   359  	}
   360  	for _, nsdata := range pvtdata.WriteSet.NsPvtRwset {
   361  		if nsdata.Namespace == ns {
   362  			for _, colldata := range nsdata.CollectionPvtRwset {
   363  				if colldata.CollectionName == coll {
   364  					return true
   365  				}
   366  			}
   367  		}
   368  	}
   369  	return false
   370  }
   371  
   372  // Add adds a namespace-collection tuple to the filter
   373  func (filter PvtNsCollFilter) Add(ns string, coll string) {
   374  	collFilter, ok := filter[ns]
   375  	if !ok {
   376  		collFilter = make(map[string]bool)
   377  		filter[ns] = collFilter
   378  	}
   379  	collFilter[coll] = true
   380  }
   381  
   382  // Has returns true if the filter has the entry for tuple namespace-collection
   383  func (filter PvtNsCollFilter) Has(ns string, coll string) bool {
   384  	collFilter, ok := filter[ns]
   385  	if !ok {
   386  		return false
   387  	}
   388  	return collFilter[coll]
   389  }
   390  
   391  // TxSimulationResults captures the details of the simulation results
   392  type TxSimulationResults struct {
   393  	PubSimulationResults *rwset.TxReadWriteSet
   394  	PvtSimulationResults *rwset.TxPvtReadWriteSet
   395  }
   396  
   397  // GetPubSimulationBytes returns the serialized bytes of public readwrite set
   398  func (txSim *TxSimulationResults) GetPubSimulationBytes() ([]byte, error) {
   399  	return proto.Marshal(txSim.PubSimulationResults)
   400  }
   401  
   402  // GetPvtSimulationBytes returns the serialized bytes of private readwrite set
   403  func (txSim *TxSimulationResults) GetPvtSimulationBytes() ([]byte, error) {
   404  	if !txSim.ContainsPvtWrites() {
   405  		return nil, nil
   406  	}
   407  	return proto.Marshal(txSim.PvtSimulationResults)
   408  }
   409  
   410  // ContainsPvtWrites returns true if the simulation results include the private writes
   411  func (txSim *TxSimulationResults) ContainsPvtWrites() bool {
   412  	return txSim.PvtSimulationResults != nil
   413  }
   414  
   415  // StateListener allows a custom code for performing additional stuff upon state change
   416  // for a particular namespace against which the listener is registered.
   417  // This helps to perform custom tasks other than the state updates.
   418  // A ledger implementation is expected to invoke Function `HandleStateUpdates` once per block and
   419  // the `stateUpdates` parameter passed to the function captures the state changes caused by the block
   420  // for the namespace. The actual data type of stateUpdates depends on the data model enabled.
   421  // For instance, for KV data model, the actual type would be proto message
   422  // `github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset.KVWrite`
   423  // Function `HandleStateUpdates` is expected to be invoked before block is committed and if this
   424  // function returns an error, the ledger implementation is expected to halt block commit operation
   425  // and result in a panic.
   426  // The function Initialize is invoked only once at the time of opening the ledger.
   427  type StateListener interface {
   428  	Initialize(ledgerID string, qe SimpleQueryExecutor) error
   429  	InterestedInNamespaces() []string
   430  	HandleStateUpdates(trigger *StateUpdateTrigger) error
   431  	StateCommitDone(channelID string)
   432  }
   433  
   434  // StateUpdateTrigger encapsulates the information and helper tools that may be used by a StateListener
   435  type StateUpdateTrigger struct {
   436  	LedgerID                    string
   437  	StateUpdates                StateUpdates
   438  	CommittingBlockNum          uint64
   439  	CommittedStateQueryExecutor SimpleQueryExecutor
   440  	PostCommitQueryExecutor     SimpleQueryExecutor
   441  }
   442  
   443  // StateUpdates encapsulates the state updates
   444  type StateUpdates map[string]*KVStateUpdates
   445  
   446  // KVStateUpdates captures the state updates for a namespace for KV datamodel
   447  type KVStateUpdates struct {
   448  	PublicUpdates   []*kvrwset.KVWrite
   449  	CollHashUpdates map[string][]*kvrwset.KVWriteHash
   450  }
   451  
   452  // ConfigHistoryRetriever allow retrieving history of collection configs
   453  type ConfigHistoryRetriever interface {
   454  	CollectionConfigAt(blockNum uint64, chaincodeName string) (*CollectionConfigInfo, error)
   455  	MostRecentCollectionConfigBelow(blockNum uint64, chaincodeName string) (*CollectionConfigInfo, error)
   456  }
   457  
   458  // MissingPvtDataTracker allows getting information about the private data that is not missing on the peer
   459  type MissingPvtDataTracker interface {
   460  	GetMissingPvtDataInfoForMostRecentBlocks(maxBlocks int) (MissingPvtDataInfo, error)
   461  }
   462  
   463  // MissingPvtDataInfo is a map of block number to MissingBlockPvtdataInfo
   464  type MissingPvtDataInfo map[uint64]MissingBlockPvtdataInfo
   465  
   466  // MissingBlockPvtdataInfo is a map of transaction number (within the block) to MissingCollectionPvtDataInfo
   467  type MissingBlockPvtdataInfo map[uint64][]*MissingCollectionPvtDataInfo
   468  
   469  // MissingCollectionPvtDataInfo includes the name of the chaincode and collection for which private data is missing
   470  type MissingCollectionPvtDataInfo struct {
   471  	Namespace, Collection string
   472  }
   473  
   474  // CollectionConfigInfo encapsulates a collection config for a chaincode and its committing block number
   475  type CollectionConfigInfo struct {
   476  	CollectionConfig   *peer.CollectionConfigPackage
   477  	CommittingBlockNum uint64
   478  }
   479  
   480  // Add adds a missing data entry to the MissingPvtDataInfo Map
   481  func (missingPvtDataInfo MissingPvtDataInfo) Add(blkNum, txNum uint64, ns, coll string) {
   482  	missingBlockPvtDataInfo, ok := missingPvtDataInfo[blkNum]
   483  	if !ok {
   484  		missingBlockPvtDataInfo = make(MissingBlockPvtdataInfo)
   485  		missingPvtDataInfo[blkNum] = missingBlockPvtDataInfo
   486  	}
   487  
   488  	if _, ok := missingBlockPvtDataInfo[txNum]; !ok {
   489  		missingBlockPvtDataInfo[txNum] = []*MissingCollectionPvtDataInfo{}
   490  	}
   491  
   492  	missingBlockPvtDataInfo[txNum] = append(missingBlockPvtDataInfo[txNum],
   493  		&MissingCollectionPvtDataInfo{
   494  			Namespace:  ns,
   495  			Collection: coll})
   496  }
   497  
   498  // ErrCollectionConfigNotYetAvailable is an error which is returned from the function
   499  // ConfigHistoryRetriever.CollectionConfigAt() if the latest block number committed
   500  // is lower than the block number specified in the request.
   501  type ErrCollectionConfigNotYetAvailable struct {
   502  	MaxBlockNumCommitted uint64
   503  	Msg                  string
   504  }
   505  
   506  func (e *ErrCollectionConfigNotYetAvailable) Error() string {
   507  	return e.Msg
   508  }
   509  
   510  // NotFoundInIndexErr is used to indicate missing entry in the index
   511  type NotFoundInIndexErr string
   512  
   513  func (NotFoundInIndexErr) Error() string {
   514  	return "Entry not found in index"
   515  }
   516  
   517  // CollConfigNotDefinedError is returned whenever an operation
   518  // is requested on a collection whose config has not been defined
   519  type CollConfigNotDefinedError struct {
   520  	Ns string
   521  }
   522  
   523  func (e *CollConfigNotDefinedError) Error() string {
   524  	return fmt.Sprintf("collection config not defined for chaincode [%s], pass the collection configuration upon chaincode definition/instantiation", e.Ns)
   525  }
   526  
   527  // InvalidCollNameError is returned whenever an operation
   528  // is requested on a collection whose name is invalid
   529  type InvalidCollNameError struct {
   530  	Ns, Coll string
   531  }
   532  
   533  func (e *InvalidCollNameError) Error() string {
   534  	return fmt.Sprintf("collection [%s] not defined in the collection config for chaincode [%s]", e.Coll, e.Ns)
   535  }
   536  
   537  // PvtdataHashMismatch is used when the hash of private write-set
   538  // does not match the corresponding hash present in the block
   539  // See function `PeerLedger.CommitPvtData` for the usages
   540  type PvtdataHashMismatch struct {
   541  	BlockNum, TxNum       uint64
   542  	Namespace, Collection string
   543  	ExpectedHash          []byte
   544  }
   545  
   546  // DeployedChaincodeInfoProvider is a dependency that is used by ledger to build collection config history
   547  // LSCC module is expected to provide an implementation for this dependencies
   548  type DeployedChaincodeInfoProvider interface {
   549  	// Namespaces returns the slice of the namespaces that are used for maintaining chaincode lifecycle data
   550  	Namespaces() []string
   551  	// UpdatedChaincodes returns the chaincodes that are getting updated by the supplied 'stateUpdates'
   552  	UpdatedChaincodes(stateUpdates map[string][]*kvrwset.KVWrite) ([]*ChaincodeLifecycleInfo, error)
   553  	// ChaincodeInfo returns the info about a deployed chaincode
   554  	ChaincodeInfo(channelName, chaincodeName string, qe SimpleQueryExecutor) (*DeployedChaincodeInfo, error)
   555  	// CollectionInfo returns the proto msg that defines the named collection. This function can be called for both explicit and implicit collections
   556  	CollectionInfo(channelName, chaincodeName, collectionName string, qe SimpleQueryExecutor) (*peer.StaticCollectionConfig, error)
   557  	// ImplicitCollections returns a slice that contains one proto msg for each of the implicit collections
   558  	ImplicitCollections(channelName, chaincodeName string, qe SimpleQueryExecutor) ([]*peer.StaticCollectionConfig, error)
   559  	// AllCollectionsConfigPkg returns a combined collection config pkg that contains both explicit and implicit collections
   560  	AllCollectionsConfigPkg(channelName, chaincodeName string, qe SimpleQueryExecutor) (*peer.CollectionConfigPackage, error)
   561  }
   562  
   563  // DeployedChaincodeInfo encapsulates chaincode information from the deployed chaincodes
   564  type DeployedChaincodeInfo struct {
   565  	Name                        string
   566  	Hash                        []byte
   567  	Version                     string
   568  	ExplicitCollectionConfigPkg *peer.CollectionConfigPackage
   569  	IsLegacy                    bool
   570  }
   571  
   572  // ChaincodeLifecycleInfo captures the update info of a chaincode
   573  type ChaincodeLifecycleInfo struct {
   574  	Name    string
   575  	Deleted bool
   576  	Details *ChaincodeLifecycleDetails // Can contain finer details about lifecycle event that can be used for certain optimization
   577  }
   578  
   579  // ChaincodeLifecycleDetails captures the finer details of chaincode lifecycle event
   580  type ChaincodeLifecycleDetails struct {
   581  	Updated bool // true, if an existing chaincode is updated (false for newly deployed chaincodes).
   582  	// Following attributes are meaningful only if 'Updated' is true
   583  	HashChanged        bool     // true, if the chaincode code package is changed
   584  	CollectionsUpdated []string // names of the explicit collections that are either added or updated
   585  	CollectionsRemoved []string // names of the explicit collections that are removed
   586  }
   587  
   588  // MembershipInfoProvider is a dependency that is used by ledger to determine whether the current peer is
   589  // a member of a collection. Gossip module is expected to provide the dependency to ledger
   590  type MembershipInfoProvider interface {
   591  	// AmMemberOf checks whether the current peer is a member of the given collection
   592  	AmMemberOf(channelName string, collectionPolicyConfig *peer.CollectionPolicyConfig) (bool, error)
   593  }
   594  
   595  type HealthCheckRegistry interface {
   596  	RegisterChecker(string, healthz.HealthChecker) error
   597  }
   598  
   599  // ChaincodeLifecycleEventListener interface enables ledger components (mainly, intended for statedb)
   600  // to be able to listen to chaincode lifecycle events. 'dbArtifactsTar' represents db specific artifacts
   601  // (such as index specs) packaged in a tar. Note that this interface is redefined here (in addition to
   602  // the one defined in ledger/cceventmgmt package). Using the same interface for the new lifecycle path causes
   603  // a cyclic import dependency. Moreover, eventually the whole package ledger/cceventmgmt is intented to
   604  // be removed when migration to new lifecycle is mandated.
   605  type ChaincodeLifecycleEventListener interface {
   606  	// HandleChaincodeDeploy is invoked when chaincode installed + defined becomes true.
   607  	// The expected usage are to creates all the necessary statedb structures (such as indexes) and update
   608  	// service discovery info. This function is invoked immediately before the committing the state changes
   609  	// that contain chaincode definition or when a chaincode install happens
   610  	HandleChaincodeDeploy(chaincodeDefinition *ChaincodeDefinition, dbArtifactsTar []byte) error
   611  	// ChaincodeDeployDone is invoked after the chaincode deployment is finished - `succeeded` indicates
   612  	// whether the deploy finished successfully
   613  	ChaincodeDeployDone(succeeded bool)
   614  }
   615  
   616  // ChaincodeDefinition captures the info about chaincode
   617  type ChaincodeDefinition struct {
   618  	Name              string
   619  	Hash              []byte
   620  	Version           string
   621  	CollectionConfigs *peer.CollectionConfigPackage
   622  }
   623  
   624  func (cdef *ChaincodeDefinition) String() string {
   625  	return fmt.Sprintf("Name=%s, Version=%s, Hash=%#v", cdef.Name, cdef.Version, cdef.Hash)
   626  }
   627  
   628  type ChaincodeLifecycleEventProvider interface {
   629  	RegisterListener(channelID string, listener ChaincodeLifecycleEventListener)
   630  }
   631  
   632  // CustomTxProcessor allows to generate simulation results during commit time for custom transactions.
   633  // A custom processor may represent the information in a propriety fashion and can use this process to translate
   634  // the information into the form of `TxSimulationResults`. Because, the original information is signed in a
   635  // custom representation, an implementation of a `Processor` should be cautious that the custom representation
   636  // is used for simulation in an deterministic fashion and should take care of compatibility cross fabric versions.
   637  // 'initializingLedger' true indicates that either the transaction being processed is from the genesis block or the ledger is
   638  // synching the state (which could happen during peer startup if the statedb is found to be lagging behind the blockchain).
   639  // In the former case, the transactions processed are expected to be valid and in the latter case, only valid transactions
   640  // are reprocessed and hence any validation can be skipped.
   641  type CustomTxProcessor interface {
   642  	GenerateSimulationResults(txEnvelop *common.Envelope, simulator TxSimulator, initializingLedger bool) error
   643  }
   644  
   645  // InvalidTxError is expected to be thrown by a custom transaction processor
   646  // if it wants the ledger to record a particular transaction as invalid
   647  type InvalidTxError struct {
   648  	Msg string
   649  }
   650  
   651  func (e *InvalidTxError) Error() string {
   652  	return e.Msg
   653  }
   654  
   655  // Hasher implements the hash function that should be used for all ledger components.
   656  // Currently works at a stepping stone to decrease surface area of bccsp
   657  type Hasher interface {
   658  	Hash(msg []byte, opts bccsp.HashOpts) (hash []byte, err error)
   659  }
   660  
   661  //go:generate counterfeiter -o mock/state_listener.go -fake-name StateListener . StateListener
   662  //go:generate counterfeiter -o mock/query_executor.go -fake-name QueryExecutor . QueryExecutor
   663  //go:generate counterfeiter -o mock/tx_simulator.go -fake-name TxSimulator . TxSimulator
   664  //go:generate counterfeiter -o mock/deployed_ccinfo_provider.go -fake-name DeployedChaincodeInfoProvider . DeployedChaincodeInfoProvider
   665  //go:generate counterfeiter -o mock/membership_info_provider.go -fake-name MembershipInfoProvider . MembershipInfoProvider
   666  //go:generate counterfeiter -o mock/health_check_registry.go -fake-name HealthCheckRegistry . HealthCheckRegistry
   667  //go:generate counterfeiter -o mock/cc_event_listener.go -fake-name ChaincodeLifecycleEventListener . ChaincodeLifecycleEventListener
   668  //go:generate counterfeiter -o mock/custom_tx_processor.go -fake-name CustomTxProcessor . CustomTxProcessor
   669  //go:generate counterfeiter -o mock/cc_event_provider.go -fake-name ChaincodeLifecycleEventProvider . ChaincodeLifecycleEventProvider