前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tron-节点-witness加载过程

tron-节点-witness加载过程

作者头像
潇洒
发布2023-10-23 14:53:34
1690
发布2023-10-23 14:53:34
举报
文章被收录于专栏:石头岛石头岛

简述

witness 即在tron链中就是产块节点的代名词,一般称为SR。 一般节点不产块,要配置成witness,需要启动时指定私钥,并使用--witness-w指定成为产块节点。

witness 加载过程

有两种加载方式:

  1. 参数或配置文件
  2. 指定localwitness启动

参数或配置文件

通过参数指定为witness节点,但是私钥建议写在配置文件中,否则ps查看一下进程就能看到启动参数,就全暴露了,但是如果有人能上机器,也能查看配置文件。

代码语言:javascript
复制
java -jar FullNode.jar --witness -p xxxxxxxxxxxxxxxxxx

输入上面的命令后,节点就会以SR类型启动,具体是如何加载的,调用栈如下:

代码语言:javascript
复制
FullNode.main()
\--Args.setParam(args, Constant.TESTNET_CONF);        //381
   \--PARAMETER.privateKey          //优先加载 参数
   \--Constant.LOCAL_WITNESS        //或加载 配置文件
   \--LocalWitnesses.setPrivateKeys //或从 keystore 中加载
FullNode.startup()
\--ConsensusService.start()   // 加载localwitness

Args.setParam 加载过程

代码语言:javascript
复制
@Slf4j(topic = "app")
@NoArgsConstructor
@Component
public class Args extends CommonParameter {

  @Getter
  @Setter
  private static LocalWitnesses localWitnesses = new LocalWitnesses();


  public static void setParam(final String[] args, final String confFileName) {
    // 省略部分代码
    ...
    // PARAMETER.privateKey 即 -p 或 --private-key 参数
    if (StringUtils.isNoneBlank(PARAMETER.privateKey)) {
      localWitnesses = (new LocalWitnesses(PARAMETER.privateKey));
      if (StringUtils.isNoneBlank(PARAMETER.witnessAddress)) {
        byte[] bytes = Commons.decodeFromBase58Check(PARAMETER.witnessAddress);
        if (bytes != null) {
          localWitnesses.setWitnessAccountAddress(bytes);
          logger.debug("Got localWitnessAccountAddress from cmd");
        } else {
          PARAMETER.witnessAddress = "";
          logger.warn(IGNORE_WRONG_WITNESS_ADDRESS_FORMAT);
        }
      }
      // 初始化 witness
      localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine());
      logger.debug("Got privateKey from cmd");
    } else if (config.hasPath(Constant.LOCAL_WITNESS)) {
      // Constant.LOCAL_WITNESS 即,配置文件中的 localwitness 这个配置项,可以配置多个
      // 作用就是一个 java-tron 服务,配置多个witness产块,这样做的话,要约成本,一台机器就可以配置多个
      localWitnesses = new LocalWitnesses();
      List<String> localwitness = config.getStringList(Constant.LOCAL_WITNESS);
      localWitnesses.setPrivateKeys(localwitness);
      witnessAddressCheck(config);
      localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine());
      logger.debug("Got privateKey from config.conf");
    } else if (config.hasPath(Constant.LOCAL_WITNESS_KEYSTORE)) {
      // 通过 keystore 加载
      localWitnesses = new LocalWitnesses();
      List<String> privateKeys = new ArrayList<String>();
      if (PARAMETER.isWitness()) {
        List<String> localwitness = config.getStringList(Constant.LOCAL_WITNESS_KEYSTORE);
        if (localwitness.size() > 0) {
          String fileName = System.getProperty("user.dir") + "/" + localwitness.get(0);
          String password;
          if (StringUtils.isEmpty(PARAMETER.password)) {
            System.out.println("Please input your password.");
            password = WalletUtils.inputPassword();
          } else {
            password = PARAMETER.password;
            PARAMETER.password = null;
          }

          try {
            Credentials credentials = WalletUtils
                .loadCredentials(password, new File(fileName));
            SignInterface sign = credentials.getSignInterface();
            String prikey = ByteArray.toHexString(sign.getPrivateKey());
            privateKeys.add(prikey);
          } catch (IOException | CipherException e) {
            logger.error(e.getMessage());
            logger.error("Witness node start failed!");
            exit(-1);
          }
        }
      }
      localWitnesses.setPrivateKeys(privateKeys);
      witnessAddressCheck(config);
      localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine());
      logger.debug("Got privateKey from keystore");
    }
    // 省略部分代码
    ...
  }
}

共识阶段加载

ConsensusService 主要控制共识相关,在启动时。

代码语言:javascript
复制
ConsensusService.start
\--Consensus.start
   \--DposService.start // 对共抽的抽象,设计上方便切换共识

几个关注的点:

  1. 设置成witness节点
  2. 加载前面的私钥
  3. 启动共识
  4. 更新updateWitness
代码语言:javascript
复制
public void start() {
  Param param = Param.getInstance();
  // 设置成 witness 节点
  param.setEnable(parameter.isWitness());
  param.setGenesisBlock(parameter.getGenesisBlock());
  param.setMinParticipationRate(parameter.getMinParticipationRate());
  param.setBlockProduceTimeoutPercent(Args.getInstance().getBlockProducedTimeOut());
  param.setNeedSyncCheck(parameter.isNeedSyncCheck());
  param.setAgreeNodeCount(parameter.getAgreeNodeCount());
  List<Miner> miners = new ArrayList<>();
  // 拿到私钥列表
  List<String> privateKeys = Args.getLocalWitnesses().getPrivateKeys();
  if (privateKeys.size() > 1) {
    // 前面说了,可以配置多个 私钥,所以这里遍历
    for (String key : privateKeys) {
      byte[] privateKey = fromHexString(key);
      byte[] privateKeyAddress = SignUtils
          .fromPrivate(privateKey, Args.getInstance().isECKeyCryptoEngine()).getAddress();
      WitnessCapsule witnessCapsule = witnessStore.get(privateKeyAddress);
      if (null == witnessCapsule) {
        logger.warn("Witness {} is not in witnessStore.", Hex.toHexString(privateKeyAddress));
      }
      // 封装到 Miner 中,在产块时私钥相关校验
      Miner miner = param.new Miner(privateKey, ByteString.copyFrom(privateKeyAddress),
          ByteString.copyFrom(privateKeyAddress));
      miners.add(miner);
      logger.info("Add witness: {}, size: {}",
          Hex.toHexString(privateKeyAddress), miners.size());
    }
  } else {
    byte[] privateKey =
        fromHexString(Args.getLocalWitnesses().getPrivateKey());
    byte[] privateKeyAddress = SignUtils.fromPrivate(privateKey,
        Args.getInstance().isECKeyCryptoEngine()).getAddress();
    byte[] witnessAddress = Args.getLocalWitnesses().getWitnessAccountAddress(
        Args.getInstance().isECKeyCryptoEngine());
    WitnessCapsule witnessCapsule = witnessStore.get(witnessAddress);
    if (null == witnessCapsule) {
      logger.warn("Witness {} is not in witnessStore.", Hex.toHexString(witnessAddress));
    }
    Miner miner = param.new Miner(privateKey, ByteString.copyFrom(privateKeyAddress),
        ByteString.copyFrom(witnessAddress));
    miners.add(miner);
  }

  param.setMiners(miners);
  param.setBlockHandle(blockHandle);
  param.setPbftInterface(pbftBaseImpl);
  // 启动共识
  consensus.start(param);
  logger.info("consensus service start success");
}

Dpos 中加载

//TODO

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • witness 加载过程
    • 参数或配置文件
      • Args.setParam 加载过程
      • 共识阶段加载
      • Dpos 中加载
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档