use of io.nuls.consensus.poc.model.Evidence in project nuls by nuls-io.
the class BifurcationUtil method validate.
public ValidateResult validate(BlockHeader header) {
ValidateResult result = ValidateResult.getSuccessResult();
if (NulsContext.MAIN_NET_VERSION <= 1) {
return result;
}
if (ConsensusConfig.getSeedNodeStringList().indexOf(AddressTool.getStringAddressByBytes(header.getPackingAddress())) >= 0) {
return result;
}
if (header.getHeight() == 0L) {
return result;
}
if (header.getHeight() > NulsContext.getInstance().getBestHeight()) {
return result;
}
BlockHeader otherBlockHeader = blockService.getBlockHeader(header.getHeight()).getData();
if (null != otherBlockHeader && !otherBlockHeader.getHash().equals(header.getHash()) && Arrays.equals(otherBlockHeader.getPackingAddress(), header.getPackingAddress())) {
Log.info("-+-+-+-+-+-+-+-+- Received block with the same height and different hashes as the latest local block -+-+-+-+-+-+-+-+- ");
Log.info("-+-+-+-+-+-+-+-+- height:" + header.getHeight() + ", hash of received block:" + header.getHash().getDigestHex() + ", hash of local latest block:" + otherBlockHeader.getHash().getDigestHex());
Log.info("-+-+-+-+-+-+-+-+- Packing address of received block:" + AddressTool.getStringAddressByBytes(header.getPackingAddress()) + ", Packing address of local latest block:" + AddressTool.getStringAddressByBytes(otherBlockHeader.getPackingAddress()));
List<Agent> agentList = PocConsensusContext.getChainManager().getMasterChain().getChain().getAgentList();
Agent agent = null;
for (Agent a : agentList) {
if (a.getDelHeight() > 0) {
continue;
}
if (Arrays.equals(a.getPackingAddress(), header.getPackingAddress())) {
agent = a;
break;
}
}
if (null == agent) {
return result;
}
recordEvidence(agent, header, otherBlockHeader);
if (!isRedPunish(agent)) {
return result;
}
RedPunishTransaction redPunishTransaction = new RedPunishTransaction();
RedPunishData redPunishData = new RedPunishData();
redPunishData.setAddress(agent.getAgentAddress());
long txTime = 0;
try {
// 连续3轮 每一轮两个区块头作为证据 一共 3 * 2 个区块头作为证据
byte[][] headers = new byte[NulsContext.REDPUNISH_BIFURCATION * 2][];
List<Evidence> list = bifurcationEvidenceMap.get(AddressTool.getStringAddressByBytes(agent.getPackingAddress()));
for (int i = 0; i < list.size() && i < NulsContext.REDPUNISH_BIFURCATION; i++) {
Evidence evidence = list.get(i);
int s = i * 2;
headers[s] = evidence.getBlockHeader1().serialize();
headers[++s] = evidence.getBlockHeader2().serialize();
txTime = (evidence.getBlockHeader1().getTime() + evidence.getBlockHeader2().getTime()) / 2;
}
redPunishData.setEvidence(ArraysTool.concatenate(headers));
} catch (Exception e) {
Log.error(e);
return result;
}
redPunishData.setReasonCode(PunishReasonEnum.BIFURCATION.getCode());
redPunishTransaction.setTxData(redPunishData);
redPunishTransaction.setTime(txTime);
CoinData coinData = null;
try {
coinData = ConsensusTool.getStopAgentCoinData(agent, redPunishTransaction.getTime() + PocConsensusConstant.RED_PUNISH_LOCK_TIME);
} catch (IOException e) {
Log.error(e);
return result;
}
redPunishTransaction.setCoinData(coinData);
try {
redPunishTransaction.setHash(NulsDigestData.calcDigestData(redPunishTransaction.serializeForHash()));
} catch (IOException e) {
Log.error(e);
return result;
}
TxMemoryPool.getInstance().add(redPunishTransaction, false);
return result;
}
return result;
}
use of io.nuls.consensus.poc.model.Evidence in project nuls by nuls-io.
the class BifurcationUtil method recordEvidence.
/**
* 统计并验证分叉出块地址的证据,如果是连续的分叉则保存到证据集合中,不是连续的就清空
*
* @param agent 分叉的出块地址所有者节点
* @param header 新收到的区块头
* @param otherBlockHeader 本地当前以保存的最新区块头
*/
private void recordEvidence(Agent agent, BlockHeader header, BlockHeader otherBlockHeader) {
// 验证出块地址PackingAddress,记录分叉的连续次数,如达到连续3轮则红牌惩罚
String packingAddress = AddressTool.getStringAddressByBytes(agent.getPackingAddress());
BlockExtendsData extendsData = new BlockExtendsData(header.getExtend());
Evidence evidence = new Evidence(extendsData.getRoundIndex(), header, otherBlockHeader);
if (!bifurcationEvidenceMap.containsKey(packingAddress)) {
List<Evidence> list = new ArrayList<>();
list.add(evidence);
bifurcationEvidenceMap.put(packingAddress, list);
} else {
List<Evidence> evidenceList = bifurcationEvidenceMap.get(packingAddress);
if (evidenceList.size() >= NulsContext.REDPUNISH_BIFURCATION) {
return;
}
ListIterator<Evidence> iterator = evidenceList.listIterator();
boolean isSerialRoundIndex = false;
while (iterator.hasNext()) {
Evidence e = iterator.next();
// 如果与其中一个记录的轮次是连续的,则加入记录
if (e.getRoundIndex() + 1 == extendsData.getRoundIndex()) {
iterator.add(evidence);
isSerialRoundIndex = true;
}
}
if (!isSerialRoundIndex) {
// 分叉不是连续的轮次,则清空记录(重置).
bifurcationEvidenceMap.remove(packingAddress);
}
}
bifurcationEvidenceStorageService.save(Evidence.bifurcationEvidenceMapToPoMap(bifurcationEvidenceMap));
}
Aggregations