长安链源码分析之交易过程分析(2)
 作者:李
- 2022-10-25  湖南
- 本文字数:2186 字 - 阅读完需:约 7 分钟 
本文已参与「开源摘星计划」,欢迎正在阅读的你加入。活动链接:https://github.com/weopenprojects/WeOpen-Star
处理合约查询请求,整个逻辑非常清晰
这里面有些细节,比如合约虚拟机到底怎么执行的,有待研究
//处理查询合约func (s *ApiService) dealQuery(tx *commonPb.Transaction, source protocol.TxSource) *commonPb.TxResponse {	var (		err     error		errMsg  string		errCode commonErr.ErrCode		store   protocol.BlockchainStore		vmMgr   protocol.VmManager		resp    = &commonPb.TxResponse{TxId: tx.Payload.TxId}	)	//获取链id	chainId := tx.Payload.ChainId
	//获取存储模块	if store, err = s.chainMakerServer.GetStore(chainId); err != nil {		errCode = commonErr.ERR_CODE_GET_STORE		errMsg = s.getErrMsg(errCode, err)		s.log.Error(errMsg)		resp.Code = commonPb.TxStatusCode_INTERNAL_ERROR		resp.Message = errMsg		resp.TxId = tx.Payload.TxId		return resp	}
	//获取虚拟机管理模块	if vmMgr, err = s.chainMakerServer.GetVmManager(chainId); err != nil {		errCode = commonErr.ERR_CODE_GET_VM_MGR		errMsg = s.getErrMsg(errCode, err)		s.log.Error(errMsg)		resp.Code = commonPb.TxStatusCode_INTERNAL_ERROR		resp.Message = errMsg		resp.TxId = tx.Payload.TxId		return resp	}
	//如果是系统内部链,调用系统链查询	if chainId == SYSTEM_CHAIN {		return s.dealSystemChainQuery(tx, vmMgr)	}
	//获取快照日志模块	var log = logger.GetLoggerByChain(logger.MODULE_SNAPSHOT, chainId)
	//基于存储模块和日志模块创建一个快照模块	var snap protocol.Snapshot	snap, err = snapshot.NewQuerySnapshot(store, log)	if err != nil {		s.log.Error(err)		resp.Code = commonPb.TxStatusCode_INTERNAL_ERROR		resp.Message = err.Error()		resp.TxId = tx.Payload.TxId		return resp	}
	//创建一个交易上下文	ctx := vm.NewTxSimContext(vmMgr, snap, tx, protocol.DefaultBlockVersion, log)
	//根据合约名称获取合约	contract, err := store.GetContractByName(tx.Payload.ContractName)	if err != nil {		s.log.Error(err)		resp.Code = commonPb.TxStatusCode_INTERNAL_ERROR		resp.Message = err.Error()		resp.TxId = tx.Payload.TxId		return resp	}
	//判断合约类型,如果合约运行时不是本地运行时	var bytecode []byte	if contract.RuntimeType != commonPb.RuntimeType_NATIVE {		//获取合约的字节信息		bytecode, err = store.GetContractBytecode(contract.Name)		if err != nil {			s.log.Error(err)			resp.Code = commonPb.TxStatusCode_INTERNAL_ERROR			resp.Message = err.Error()			resp.TxId = tx.Payload.TxId			return resp		}	}	//虚拟机管理器运行合约	txResult, _, txStatusCode := vmMgr.RunContract(contract, tx.Payload.Method,		bytecode, s.kvPair2Map(tx.Payload.Parameters), ctx, 0, tx.Payload.TxType)	s.log.DebugDynamic(func() string {		contractJson, _ := json.Marshal(contract)		return fmt.Sprintf("vmMgr.RunContract: txStatusCode:%d, resultCode:%d, contractName[%s](%s), "+			"method[%s], txType[%s], message[%s],result len: %d",			txStatusCode, txResult.Code, tx.Payload.ContractName, string(contractJson), tx.Payload.Method,			tx.Payload.TxType, txResult.Message, len(txResult.Result))	})	//如果监控已经打开,发送监控信息	if localconf.ChainMakerConfig.MonitorConfig.Enabled {		if txStatusCode == commonPb.TxStatusCode_SUCCESS && txResult.Code != 1 {			s.metricQueryCounter.WithLabelValues(chainId, "true").Inc()		} else {			s.metricQueryCounter.WithLabelValues(chainId, "false").Inc()		}	}	//执行合约失败	if txStatusCode != commonPb.TxStatusCode_SUCCESS {		errMsg = fmt.Sprintf("txStatusCode:%d, resultCode:%d, contractName[%s] method[%s] txType[%s], %s",			txStatusCode, txResult.Code, tx.Payload.ContractName, tx.Payload.Method, tx.Payload.TxType, txResult.Message)		s.log.Warn(errMsg)
		resp.Code = txStatusCode		if txResult.Message == archive.ErrArchivedBlock.Error() {			resp.Code = commonPb.TxStatusCode_ARCHIVED_BLOCK		} else if txResult.Message == archive.ErrArchivedTx.Error() {			resp.Code = commonPb.TxStatusCode_ARCHIVED_TX		}
		resp.Message = errMsg		resp.ContractResult = txResult		resp.TxId = tx.Payload.TxId		return resp	}
	//执行合约超时	if txResult.Code == 1 {		resp.Code = commonPb.TxStatusCode_CONTRACT_FAIL		resp.Message = commonPb.TxStatusCode_CONTRACT_FAIL.String()		resp.ContractResult = txResult		resp.TxId = tx.Payload.TxId		return resp	}	//执行合约成功	resp.Code = commonPb.TxStatusCode_SUCCESS	resp.Message = commonPb.TxStatusCode_SUCCESS.String()	resp.ContractResult = txResult	resp.TxId = tx.Payload.TxId	return resp}复制代码
 划线
评论
复制
发布于: 刚刚阅读数: 4

李
关注
还未添加个人签名 2018-05-04 加入
还未添加个人简介









 
    
评论