Search in sources :

Example 1 with Evidence

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;
}
Also used : Agent(io.nuls.consensus.poc.protocol.entity.Agent) RedPunishTransaction(io.nuls.consensus.poc.protocol.tx.RedPunishTransaction) CoinData(io.nuls.kernel.model.CoinData) ValidateResult(io.nuls.kernel.validate.ValidateResult) IOException(java.io.IOException) IOException(java.io.IOException) RedPunishData(io.nuls.consensus.poc.protocol.entity.RedPunishData) Evidence(io.nuls.consensus.poc.model.Evidence) BlockHeader(io.nuls.kernel.model.BlockHeader)

Example 2 with Evidence

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));
}
Also used : BlockExtendsData(io.nuls.consensus.poc.model.BlockExtendsData) Evidence(io.nuls.consensus.poc.model.Evidence)

Aggregations

Evidence (io.nuls.consensus.poc.model.Evidence)2 BlockExtendsData (io.nuls.consensus.poc.model.BlockExtendsData)1 Agent (io.nuls.consensus.poc.protocol.entity.Agent)1 RedPunishData (io.nuls.consensus.poc.protocol.entity.RedPunishData)1 RedPunishTransaction (io.nuls.consensus.poc.protocol.tx.RedPunishTransaction)1 BlockHeader (io.nuls.kernel.model.BlockHeader)1 CoinData (io.nuls.kernel.model.CoinData)1 ValidateResult (io.nuls.kernel.validate.ValidateResult)1 IOException (java.io.IOException)1