波场java-tron3.6 fullnode节点广播交易前的流程分析

本篇文章介绍fullnode节点收到用户发送的过来的交易之后的处理流程,一般用户通过http接口将签名好的交易发送到fullnode节点, fullnode节点会对交易进行相关的检查, 然后执行交易,如果执行的结果没有问题, 就会广播交易。当然其他节点收到这笔广播的交易之后也会做相同的操作。

1 fullnode http 处理函数

  //java-tron/src/main/java/org/tron/core/services/http/BroadcastServlet
  protected void doPost(HttpServletRequest request, HttpServletResponse response) {
   
    try {
   
      String input = request.getReader().lines()
          .collect(Collectors.joining(System.lineSeparator()));
      Util.checkBodySize(input);
      boolean visible = Util.getVisiblePost(input);
      Transaction transaction = Util.packTransaction(input, visible);
      GrpcAPI.Return retur = wallet.broadcastTransaction(transaction);
      response.getWriter().println(JsonFormat.printToString(retur, visible));
    } catch (Exception e) {
   
      logger.debug("Exception: {}", e.getMessage());
      try {
   
        response.getWriter().println(Util.printErrorMsg(e));
      } catch (IOException ioe) {
   
        logger.debug("IOException: {}", ioe.getMessage());
      }
    }
  }
}

用户通过http发送的广播交易的数据包会被传到这里处理,这个函数调用了wallet.broadcastTransaction进行处理。

2 broadcastTransaction 函数

///Users/tron/tron-ws/java-tron/src/main/java/org/tron/core/Wallet.java
 
 //交易广播
  //task1:确认可广播的节点
  //task2:判断本地是否能够接收这笔交易
  //task3:预执行交易,将交易放入pending列表
  //task4:错误处理
  public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) {
   
    GrpcAPI.Return.Builder builder = GrpcAPI.Return.newBuilder();
    //----------------------------------------------------------------------
    //task1:确认可广播的节点
    //----------------------------------------------------------------------
    //将transaction类型转换成TransactionCapsule类型
    TransactionCapsule trx = new TransactionCapsule(signaturedTransaction);
    try {
   
      Message message = new TransactionMessage(signaturedTransaction.toByteArray());
      //如果允许的最小的链接数量不为0
      if (minEffectiveConnection != 0) {
   
        //如果当前活跃节点数为空,返回错误
        if (tronNetDelegate.getActivePeer().isEmpty()) {
   
          logger.warn("Broadcast transaction {} failed, no connection.", trx.getTransactionId());
          return builder.setResult(false).setCode(response_code.NO_CONNECTION)
              .setMessage(ByteString.copyFromUtf8("no connection"))
              .build();
        }

        //找出可广播节点,满足如下条件(1.活跃, 2.不需要互相同步的节点)
        int count = (int) tronNetDelegate.getActivePeer().stream()
            .filter(p -> !p.isNeedSyncFromUs() && !p.isNeedSyncFromPeer())
            .count();

        //如果可广播节点小于允许的最小链接数量,返回错误
        if (count < minEffectiveConnection) {
   
          String info = "effective connection:" + count + " lt minEffectiveConnection:"
              + minEffectiveConnection;
          logger.warn("Broadcast transaction {} failed, {}.", trx.getTransactionId(), info);
          return builder.setResult(false).setCode(response_code.NOT_ENOUGH_EFFECTIVE_CONNECTION)
              .setMessage(ByteString.copyFromUtf8(info))
              .build();
        }
      }
    //----------------------------------------------------------------------
    //task2:判断本地是否能够接收这笔交易
    //----------------------------------------------------------------------
      //等待交易过多,网络阻塞,pendign列表 + repush列表总和 > 2000
      if (dbManager.isTooManyPending()) {
   
        logger.warn("Broadcast transaction {} failed, too many pending.", trx.getTransactionId());
        return builder.setResult(false).setCode(response_code.SERVER_BUSY).build();
      }

      //如果本节点是sr节点, 并且在出块,拒绝交易,返回错误
      if (dbManager.isGeneratingBlock()) {
   
        logger
            .warn("Broadcast transaction {} failed, is generating block.", trx.getTransactionId());
        return builder.setResult(false).setCode(response_code.SERVER_BUSY).build();
      }

      //如果交易已经收到过了,拒绝交易,返回错误
      if (dbManager.getTransactionIdCache().getIfPresent(trx.getTransactionId()) != null) {
   
        logger.warn("Broadcast transaction {} failed, is already exist.", trx.getTransactionId());
        return builder.setResult(false).setCode(response_code.DUP_TRANSACTION_ERROR).build();
      } else {
   //如果没有收到过, 将交易放入idcache
        dbManager.getTransactionIdCache().put(trx.getTransactionId(), true);
      }

      //初始化transaction的result,为执行智能合约做准备
      if (dbManager.getDynamicPropertiesStore().supportVM()) {
   
        trx.resetResult();
      }
    //---------------------------------------------------
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值