initChain方法在peer.go hyperledger文件中无用吗?

时间:2017-12-22 12:45:46

标签: hyperledger-fabric

当我们调用命令peer node start来启动对等节点时,或者 命令peer join channel -c xxx.block,它将调用peer.go文件中的peer.InitChain(chainID)方法, 但我觉得代码没用。我给它注释,并且对等节点没有任何问题。由于系统代码如lscc,cscc,qscc等已经使用peer.go文件启动,代码如下:

//initialize system chaincodes
    initSysCCs()

所以我认为文件peer.go有无用的方法InitChain(cid string)?

该方法将使用exectransaction.go中的系统链代码和方法

//Execute - execute proposal, return original response of chaincode
func Execute(ctxt context.Context, cccid *ccprovider.CCContext, spec interface{}) (*pb.Response, *pb.ChaincodeEvent, error) {

并最终到达chaincode_support.go,

if notfy, err = chrte.handler.sendExecuteMessage(ctxt, cccid.ChainID, msg, cccid.SignedProposal, cccid.Proposal); err != nil {
    return nil, fmt.Errorf("Error sending %s: %s", msg.Type.String(), err)
}

chainID不会影响要处理的处理程序,并且调用如下:

func (handler *Handler) sendExecuteMessage(ctxt context.Context, chainID string, msg *pb.ChaincodeMessage, signedProp *pb.SignedProposal, prop *pb.Proposal) (chan *pb.ChaincodeMessage, error) {
    txctx, err := handler.createTxContext(ctxt, chainID, msg.Txid, signedProp, prop)
    if err != nil {
        return nil, err
    }
    if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
        chaincodeLogger.Debugf("[%s]Inside sendExecuteMessage. Message %s", shorttxid(msg.Txid), msg.Type.String())
    }

    //if security is disabled the context elements will just be nil
    if err = handler.setChaincodeProposal(signedProp, prop, msg); err != nil {
        return nil, err
    }

    chaincodeLogger.Debugf("[%s]sendExecuteMsg trigger event %s", shorttxid(msg.Txid), msg.Type)
    handler.triggerNextState(msg, true)     //**when triggerNextState, chainId field is useless.** 

    return txctx.responseNotifier, nil
}

1 个答案:

答案 0 :(得分:0)

如果您指的是peer.InitChain(cid string)方法,那么我认为它没用。老实说,我并不完全确定你的解释,因为它有点难以理解,但这个功能在对等初始化时使用。例如。从peer.Initialize(init func(string))方法调用的函数准确here是行:

--save

此方法的作用是调用在start.go中传递的初始值设定项:

        // Skipped rest of the code

        // Create a chain if we get a valid ledger with config block
        if err = createChain(cid, ledger, cb); err != nil {
            peerLogger.Warningf("Failed to load chain %s(%s)", cid, err)
            peerLogger.Debugf("Error reloading chain %s with message %s. We continue to the next chain rather than abort.", cid, err)
            continue
        }

        InitChain(cid)
}

基本上部署系统链代码。请注意,//this brings up all the chains (including testchainid) peer.Initialize(func(cid string) { logger.Debugf("Deploying system CC, for chain <%s>", cid) scc.DeploySysCCs(cid) }) 方法分配chainInializer,通过peer.Initialize调用。

peer.InitChain

所以对你的问题,这不是无用的代码。还要注意区别:

func Initialize(init func(string)) {
    chainInitializer = init

    var cb *common.Block
    var ledger ledger.PeerLedger
    ledgermgmt.Initialize()
    ledgerIds, err := ledgermgmt.GetLedgerIDs()
    if err != nil {
        panic(fmt.Errorf("Error in initializing ledgermgmt: %s", err))
}

实施如下:

//initialize system chaincodes
initSysCCs()

注意事实func initSysCCs() { //deploy system chaincodes scc.DeploySysCCs("") logger.Infof("Deployed system chaincodes") } ,同时遵循以下代码:

chainID==""

部署特定频道ID的链代码,例如//this brings up all the chains (including testchainid) peer.Initialize(func(cid string) { logger.Debugf("Deploying system CC, for chain <%s>", cid) scc.DeploySysCCs(cid) })

沿着路径走,您可以在sysccapi.go找到差异,其中scc.DeploySysCCs(cid)实现为:

deploySysCC

请注意以下内容的代码:

// deploySysCC deploys the given system chaincode on a chain
func deploySysCC(chainID string, syscc *SystemChaincode) error {
    if !syscc.Enabled || !isWhitelisted(syscc) {
        sysccLogger.Info(fmt.Sprintf("system chaincode (%s,%s) disabled", syscc.Name, syscc.Path))
        return nil
    }

    var err error

    ccprov := ccprovider.GetChaincodeProvider()

    txid := util.GenerateUUID()

    ctxt := context.Background()
    if chainID != "" {
        lgr := peer.GetLedger(chainID)
        if lgr == nil {
            panic(fmt.Sprintf("syschain %s start up failure - unexpected nil ledger for channel %s", syscc.Name, chainID))
        }

        //init can do GetState (and other Get's) even if Puts cannot be
        //be handled. Need ledger for this
        ctxt2, txsim, err := ccprov.GetContext(lgr, txid)
        if err != nil {
            return err
        }

        ctxt = ctxt2

        defer txsim.Done()
    }

    chaincodeID := &pb.ChaincodeID{Path: syscc.Path, Name: syscc.Name}
    spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: syscc.InitArgs}}

    // First build and get the deployment spec
    chaincodeDeploymentSpec, err := buildSysCC(ctxt, spec)

    if err != nil {
        sysccLogger.Error(fmt.Sprintf("Error deploying chaincode spec: %v\n\n error: %s", spec, err))
        return err
    }

    version := util.GetSysCCVersion()

    cccid := ccprov.GetCCContext(chainID, chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeId.Name, version, txid, true, nil, nil)

    _, _, err = ccprov.ExecuteWithErrorFilter(ctxt, cccid, chaincodeDeploymentSpec)

    sysccLogger.Infof("system chaincode %s/%s(%s) deployed", syscc.Name, chainID, syscc.Path)

    return err
}