Search in sources :

Example 11 with ChainContainer

use of io.nuls.consensus.poc.container.ChainContainer in project nuls by nuls-io.

the class ForkChainProcess method monitorOrphanChains.

/**
 * Monitor the orphan chain, if there is a connection with the main chain or the forked chain, the merged chain
 * <p>
 * 监控孤立链,如果有和主链或者分叉链连上的情况,则合并链
 */
private void monitorOrphanChains() {
    List<ChainContainer> orphanChains = chainManager.getOrphanChains();
    Iterator<ChainContainer> iterator = orphanChains.iterator();
    while (iterator.hasNext()) {
        ChainContainer orphanChain = iterator.next();
        if (checkOrphanChainHasConnection(orphanChain)) {
            iterator.remove();
        }
    }
}
Also used : ChainContainer(io.nuls.consensus.poc.container.ChainContainer)

Example 12 with ChainContainer

use of io.nuls.consensus.poc.container.ChainContainer in project nuls by nuls-io.

the class ForkChainProcess method checkOrphanChainHasConnection.

private boolean checkOrphanChainHasConnection(ChainContainer orphanChain) {
    // Determine whether the orphan chain is connected to the main chain
    // 判断该孤立链是否和主链相连
    BlockHeader startBlockHeader = orphanChain.getChain().getStartBlockHeader();
    List<BlockHeader> blockHeaderList = chainManager.getMasterChain().getChain().getAllBlockHeaderList();
    int count = blockHeaderList.size() > PocConsensusConstant.MAX_ISOLATED_BLOCK_COUNT ? PocConsensusConstant.MAX_ISOLATED_BLOCK_COUNT : blockHeaderList.size();
    for (int i = blockHeaderList.size() - 1; i >= blockHeaderList.size() - count; i--) {
        BlockHeader header = blockHeaderList.get(i);
        if (startBlockHeader.getPreHash().equals(header.getHash()) && startBlockHeader.getHeight() == header.getHeight() + 1) {
            // yes connectioned
            orphanChain.getChain().setPreChainId(chainManager.getMasterChain().getChain().getId());
            chainManager.getChains().add(orphanChain);
            ChainLog.debug("discover the OrphanChain {} : start {} - {} , end {} - {} , connection the master chain of {} - {} - {}, move into the fork chians", orphanChain.getChain().getId(), startBlockHeader.getHeight(), startBlockHeader.getHash().getDigestHex(), orphanChain.getChain().getEndBlockHeader().getHeight(), orphanChain.getChain().getEndBlockHeader().getHash(), chainManager.getMasterChain().getChain().getId(), chainManager.getMasterChain().getChain().getBestBlock().getHeader().getHeight(), chainManager.getMasterChain().getChain().getBestBlock().getHeader().getHash());
            return true;
        } else if (startBlockHeader.getHeight() > header.getHeight()) {
            break;
        }
    }
    // 判断该孤链是否和待验证的分叉链相连
    for (ChainContainer forkChain : chainManager.getChains()) {
        Chain chain = forkChain.getChain();
        if (startBlockHeader.getHeight() > chain.getEndBlockHeader().getHeight() + 1 || startBlockHeader.getHeight() <= chain.getStartBlockHeader().getHeight()) {
            continue;
        }
        blockHeaderList = chain.getAllBlockHeaderList();
        for (int i = 0; i < blockHeaderList.size(); i++) {
            BlockHeader header = blockHeaderList.get(i);
            if (startBlockHeader.getPreHash().equals(header.getHash()) && startBlockHeader.getHeight() == header.getHeight() + 1) {
                // yes connectioned
                orphanChain.getChain().setPreChainId(chain.getPreChainId());
                // orphanChain.getChain().initData(chain.getStartBlockHeader(), blockHeaderList.subList(0, i + 1), chain.getAllBlockList().subList(0, i + 1));
                List<Block> blockList = chain.getAllBlockList().subList(0, i + 1);
                for (int m = blockList.size() - 1; m >= 0; m--) {
                    orphanChain.getChain().addPreBlock(blockList.get(m));
                }
                chainManager.getChains().add(orphanChain);
                if (i == blockHeaderList.size() - 1) {
                    chainManager.getChains().remove(forkChain);
                }
                ChainLog.debug("discover the OrphanChain {} : start {} - {} , end {} - {} , connection the fork chain of : start {} - {} , end {} - {}, move into the fork chians", orphanChain.getChain().getId(), startBlockHeader.getHeight(), startBlockHeader.getHash().getDigestHex(), orphanChain.getChain().getEndBlockHeader().getHeight(), orphanChain.getChain().getEndBlockHeader().getHash(), chainManager.getMasterChain().getChain().getId(), chain.getStartBlockHeader().getHeight(), chain.getStartBlockHeader().getHash(), chain.getEndBlockHeader().getHeight(), chain.getEndBlockHeader().getHash());
                return true;
            } else if (startBlockHeader.getHeight() == header.getHeight() + 1) {
                break;
            }
        }
    }
    // 判断孤立链之间是否相连
    for (ChainContainer orphan : chainManager.getOrphanChains()) {
        if (orphan.getChain().getEndBlockHeader().getHash().equals(orphanChain.getChain().getStartBlockHeader().getPreHash()) && orphan.getChain().getEndBlockHeader().getHeight() + 1 == orphanChain.getChain().getStartBlockHeader().getHeight()) {
            // Chain chain = orphan.getChain();
            // chain.initData(orphanChain.getChain().getEndBlockHeader(), orphanChain.getChain().getAllBlockHeaderList(), orphanChain.getChain().getAllBlockList());
            Chain chain = orphan.getChain();
            List<Block> blockList = orphanChain.getChain().getAllBlockList();
            for (Block block : blockList) {
                chain.addBlock(block);
            }
            return true;
        }
    }
    return false;
}
Also used : Chain(io.nuls.consensus.poc.model.Chain) ChainContainer(io.nuls.consensus.poc.container.ChainContainer)

Example 13 with ChainContainer

use of io.nuls.consensus.poc.container.ChainContainer in project nuls by nuls-io.

the class ForkChainProcess method changeChain.

private boolean changeChain(ChainContainer newMasterChain, ChainContainer originalForkChain, List<Object[]> verifyResultList) throws NulsException, IOException {
    if (newMasterChain == null || originalForkChain == null || verifyResultList == null) {
        return false;
    }
    // Now the master chain, the forked chain after the switch, needs to be put into the list of chains to be verified.
    // 现在的主链,在切换之后的分叉链,需要放入待验证链列表里面
    ChainContainer oldChain = chainManager.getMasterChain().getAfterTheForkChain(originalForkChain);
    // rollbackTransaction
    List<Block> rollbackBlockList = oldChain.getChain().getAllBlockList();
    ChainLog.debug("rollbackTransaction the master chain , need rollbackTransaction block count is {}, master chain is {} : {} - {} , service best block : {} - {}", rollbackBlockList.size(), chainManager.getMasterChain().getChain().getId(), chainManager.getBestBlock().getHeader().getHeight(), chainManager.getBestBlock().getHeader().getHash(), blockService.getBestBlock().getData().getHeader().getHeight(), blockService.getBestBlock().getData().getHeader().getHash());
    // Need descending order
    // 需要降序排列
    Collections.reverse(rollbackBlockList);
    if (rollbackBlockList != null && rollbackBlockList.size() > 0 && rollbackBlockList.get(0).getHeader().getHeight() != chainManager.getMasterChain().getBestBlock().getHeader().getHeight()) {
        Log.error("------------------------回滚的起始高度不是主链最新高度");
        Log.error("----------------------- masterChain:" + chainManager.getMasterChain().getBestBlock().getHeader().getHeight() + ",hash:" + chainManager.getMasterChain().getBestBlock().getHeader().getHash().getDigestHex());
        Log.error("----------------------- rollbackBlockList:" + rollbackBlockList.get(0).getHeader().getHeight() + ",hash:" + rollbackBlockList.get(0).getHeader().getHash().getDigestHex());
    }
    boolean rollbackResult = rollbackBlocks(rollbackBlockList);
    if (!rollbackResult) {
        return false;
    }
    boolean changeSuccess = true;
    List<Block> successList = new ArrayList<>();
    try {
        changeSuccess = doChange(successList, originalForkChain, verifyResultList);
    } catch (Exception e) {
        Log.error(e);
        changeSuccess = false;
    }
    ChainLog.debug("add new blocks complete, result {}, success count is {} , now service best block : {} - {}", changeSuccess, successList.size(), blockService.getBestBlock().getData().getHeader().getHeight(), blockService.getBestBlock().getData().getHeader().getHash());
    if (changeSuccess) {
        chainManager.setMasterChain(newMasterChain);
        newMasterChain.initRound();
        NulsContext.getInstance().setBestBlock(newMasterChain.getBestBlock());
        if (oldChain.getChain().getAllBlockList().size() > 0) {
            Collections.reverse(rollbackBlockList);
            chainManager.getChains().add(oldChain);
        }
    } else {
        // Fallback status
        // 回退状态
        Collections.reverse(successList);
        for (Block rollBlock : successList) {
            Result rs = blockService.rollbackBlock(rollBlock);
            if (rs.isSuccess()) {
                // 回滚版本更新统计数据
                nulsProtocolProcess.processProtocolRollback(rollBlock.getHeader());
                randomSeedService.rollbackBlock(rollBlock.getHeader());
            }
            RewardStatisticsProcess.rollbackBlock(rollBlock);
        }
        Collections.reverse(rollbackBlockList);
        for (Block addBlock : rollbackBlockList) {
            nulsProtocolProcess.processProtocolUpGrade(addBlock.getHeader());
            Result rs = blockService.saveBlock(addBlock);
            if (!rs.isSuccess()) {
                nulsProtocolProcess.processProtocolRollback(addBlock.getHeader());
            }
            RewardStatisticsProcess.addBlock(addBlock);
        }
    }
    return changeSuccess;
}
Also used : ChainContainer(io.nuls.consensus.poc.container.ChainContainer) IOException(java.io.IOException) NulsException(io.nuls.kernel.exception.NulsException) ContractResult(io.nuls.contract.dto.ContractResult) ValidateResult(io.nuls.kernel.validate.ValidateResult)

Example 14 with ChainContainer

use of io.nuls.consensus.poc.container.ChainContainer in project nuls by nuls-io.

the class ChainManagerTest method testCheckIsBeforeOrphanChainAndAdd.

@Test
public void testCheckIsBeforeOrphanChainAndAdd() {
    testGetBestBlockHeight();
    Block block = createBlock();
    Block block1 = createBlock();
    block1.getHeader().setHeight(1L);
    block1.getHeader().setPreHash(block.getHeader().getHash());
    ChainContainer orphanChain = new ChainContainer(new Chain());
    orphanChain.getChain().addBlock(block1);
    chainManager.getOrphanChains().add(orphanChain);
    assertEquals(1, chainManager.getOrphanChains().size());
    boolean success = chainManager.checkIsBeforeOrphanChainAndAdd(block);
    assertTrue(success);
}
Also used : Chain(io.nuls.consensus.poc.model.Chain) ChainContainer(io.nuls.consensus.poc.container.ChainContainer) Block(io.nuls.kernel.model.Block) Test(org.junit.Test) BaseTest(io.nuls.consensus.poc.BaseTest)

Example 15 with ChainContainer

use of io.nuls.consensus.poc.container.ChainContainer in project nuls by nuls-io.

the class ChainManager method newOrphanChain.

public void newOrphanChain(Block block) {
    Chain orphanChain = new Chain();
    orphanChain.initData(block);
    ChainContainer orphanChainContainer = new ChainContainer(orphanChain);
    orphanChains.add(orphanChainContainer);
}
Also used : Chain(io.nuls.consensus.poc.model.Chain) ChainContainer(io.nuls.consensus.poc.container.ChainContainer)

Aggregations

ChainContainer (io.nuls.consensus.poc.container.ChainContainer)17 Chain (io.nuls.consensus.poc.model.Chain)9 Block (io.nuls.kernel.model.Block)4 IOException (java.io.IOException)4 BaseTest (io.nuls.consensus.poc.BaseTest)3 NulsException (io.nuls.kernel.exception.NulsException)3 BlockHeader (io.nuls.kernel.model.BlockHeader)3 Test (org.junit.Test)3 Agent (io.nuls.consensus.poc.protocol.entity.Agent)2 Deposit (io.nuls.consensus.poc.protocol.entity.Deposit)2 ContractResult (io.nuls.contract.dto.ContractResult)2 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)2 ValidateResult (io.nuls.kernel.validate.ValidateResult)2 CreateAgentTransaction (io.nuls.consensus.poc.protocol.tx.CreateAgentTransaction)1 DepositTransaction (io.nuls.consensus.poc.protocol.tx.DepositTransaction)1 PunishLogPo (io.nuls.consensus.poc.storage.po.PunishLogPo)1 PunishLogStorageService (io.nuls.consensus.poc.storage.service.PunishLogStorageService)1 ECKey (io.nuls.core.tools.crypto.ECKey)1 ArrayList (java.util.ArrayList)1