github.com/defanghe/fabric@v2.1.1+incompatible/core/ledger/cceventmgmt/lsccstate_listener.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package cceventmgmt
     8  
     9  import (
    10  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    11  	"github.com/hyperledger/fabric/core/ledger"
    12  )
    13  
    14  // KVLedgerLSCCStateListener listens for state changes for chaincode lifecycle
    15  type KVLedgerLSCCStateListener struct {
    16  	DeployedChaincodeInfoProvider ledger.DeployedChaincodeInfoProvider
    17  }
    18  
    19  func (listener *KVLedgerLSCCStateListener) Initialize(ledgerID string, qe ledger.SimpleQueryExecutor) error {
    20  	// Noop
    21  	return nil
    22  }
    23  
    24  // HandleStateUpdates uses 'DeployedChaincodeInfoProvider' to findout deployment of a chaincode
    25  // and invokes `HandleChaincodeDeploy` function on chaincode event manager (which in turn is responsible for creation of statedb
    26  // artifacts for the chaincode statedata)
    27  func (listener *KVLedgerLSCCStateListener) HandleStateUpdates(trigger *ledger.StateUpdateTrigger) error {
    28  	channelName, kvWrites, postCommitQE, deployCCInfoProvider :=
    29  		trigger.LedgerID, extractPublicUpdates(trigger.StateUpdates), trigger.PostCommitQueryExecutor, listener.DeployedChaincodeInfoProvider
    30  
    31  	logger.Debugf("Channel [%s]: Handling state updates in LSCC namespace - stateUpdates=%#v", channelName, kvWrites)
    32  	updatedChaincodes, err := deployCCInfoProvider.UpdatedChaincodes(kvWrites)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	chaincodeDefs := []*ChaincodeDefinition{}
    37  	for _, updatedChaincode := range updatedChaincodes {
    38  		logger.Infof("Channel [%s]: Handling deploy or update of chaincode [%s]", channelName, updatedChaincode.Name)
    39  		if updatedChaincode.Deleted {
    40  			// TODO handle delete case when delete is implemented in lifecycle
    41  			continue
    42  		}
    43  		deployedCCInfo, err := deployCCInfoProvider.ChaincodeInfo(channelName, updatedChaincode.Name, postCommitQE)
    44  		if err != nil {
    45  			return err
    46  		}
    47  		if !deployedCCInfo.IsLegacy {
    48  			// chaincode defined via new lifecycle, the legacy event mgr should not try to process that
    49  			// event by trying to match this with a legacy package installed. So, ignoring this event
    50  			continue
    51  		}
    52  		chaincodeDefs = append(chaincodeDefs, &ChaincodeDefinition{
    53  			Name:              deployedCCInfo.Name,
    54  			Hash:              deployedCCInfo.Hash,
    55  			Version:           deployedCCInfo.Version,
    56  			CollectionConfigs: deployedCCInfo.ExplicitCollectionConfigPkg,
    57  		})
    58  	}
    59  	return GetMgr().HandleChaincodeDeploy(channelName, chaincodeDefs)
    60  }
    61  
    62  // InterestedInNamespaces implements function from interface `ledger.StateListener`
    63  func (listener *KVLedgerLSCCStateListener) InterestedInNamespaces() []string {
    64  	return listener.DeployedChaincodeInfoProvider.Namespaces()
    65  }
    66  
    67  // StateCommitDone implements function from interface `ledger.StateListener`
    68  func (listener *KVLedgerLSCCStateListener) StateCommitDone(channelName string) {
    69  	GetMgr().ChaincodeDeployDone(channelName)
    70  }
    71  
    72  func extractPublicUpdates(stateUpdates ledger.StateUpdates) map[string][]*kvrwset.KVWrite {
    73  	m := map[string][]*kvrwset.KVWrite{}
    74  	for ns, updates := range stateUpdates {
    75  		m[ns] = updates.PublicUpdates
    76  	}
    77  	return m
    78  }