简述
witness 即在tron链中就是产块节点的代名词,一般称为SR
。
一般节点不产块,要配置成witness,需要启动时指定私钥,并使用--witness
或-w
指定成为产块节点。
witness 加载过程
有两种加载方式:
- 参数或配置文件
- 指定
localwitness
启动
参数或配置文件
通过参数指定为witness节点,但是私钥建议写在配置文件中,否则ps
查看一下进程就能看到启动参数,就全暴露了,但是如果有人能上机器,也能查看配置文件。
1
| java -jar FullNode.jar --witness -p xxxxxxxxxxxxxxxxxx
|
输入上面的命令后,节点就会以SR
类型启动,具体是如何加载的,调用栈如下:
1 2 3 4 5 6 7
| FullNode.main() \--Args.setParam(args, Constant.TESTNET_CONF); //381 \--PARAMETER.privateKey //优先加载 参数 \--Constant.LOCAL_WITNESS //或加载 配置文件 \--LocalWitnesses.setPrivateKeys //或从 keystore 中加载 FullNode.startup() \--ConsensusService.start() // 加载localwitness
|
Args.setParam 加载过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| @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) { ... 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); } } localWitnesses.initWitnessAccountAddress(PARAMETER.isECKeyCryptoEngine()); logger.debug("Got privateKey from cmd"); } else if (config.hasPath(Constant.LOCAL_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)) { 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
主要控制共识相关,在启动时。
1 2 3
| ConsensusService.start \--Consensus.start \--DposService.start
|
几个关注的点:
- 设置成
witness
节点
- 加载前面的私钥
- 启动共识
- 更新updateWitness
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public void start() { Param param = Param.getInstance(); 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 = 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