当我们调用命令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
}
答案 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
}