Search in sources :

Example 1 with IAionBlock

use of org.aion.zero.types.IAionBlock in project aion by aionnetwork.

the class AionBlockStore method revert.

@Override
public void revert(long previousLevel) {
    IAionBlock bestBlock = getBestBlock();
    long currentLevel = bestBlock.getNumber();
    // ensure that the given level is lower than current
    if (previousLevel >= currentLevel) {
        return;
    }
    // walk back removing blocks greater than the given level value
    IAionBlock bestLine = bestBlock;
    while (currentLevel > previousLevel) {
        // remove all the blocks at that level
        List<BlockInfo> currentLevelBlocks = getBlockInfoForLevel(currentLevel);
        if (currentLevelBlocks == null || currentLevelBlocks.size() == 0) {
            blocks.delete(bestLine.getHash());
            LOG.error("Null block information found at " + currentLevel + " when information should exist.");
        } else {
            for (BlockInfo bk_info : currentLevelBlocks) {
                blocks.delete(bk_info.getHash());
            }
        }
        // remove the level
        index.remove(currentLevel);
        if (bestLine != null) {
            bestLine = getBlockByHash(bestLine.getParentHash());
        } else {
            // attempt to find another block at the parent level
            bestLine = getChainBlockByNumber(currentLevel - 1);
        }
        --currentLevel;
    }
    if (bestLine == null) {
        LOG.error("Block at level #" + previousLevel + " is null. Reverting further back may be required.");
    } else {
        // update the main chain based on difficulty, if needed
        List<BlockInfo> blocks = getBlockInfoForLevel(previousLevel);
        BlockInfo blockInfo = getBlockInfoForHash(blocks, bestLine.getHash());
        // no side chains at this level
        if (blocks.size() == 1 && blockInfo != null) {
            if (!blockInfo.isMainChain()) {
                blockInfo.setMainChain(true);
                setBlockInfoForLevel(previousLevel, blocks);
            }
        } else {
            if (blockInfo == null) {
                LOG.error("Null block information found at " + previousLevel + " when information should exist. " + "Rebuilding information.");
                // recreate missing block info
                blockInfo = new BlockInfo();
                blockInfo.setCummDifficulty(getTotalDifficultyForHash(bestLine.getParentHash()).add(bestLine.getHeader().getDifficultyBI()));
                blockInfo.setHash(bestLine.getHash());
                blocks.add(blockInfo);
            }
            // check for max total difficulty
            BlockInfo maxTDInfo = blockInfo;
            for (BlockInfo info : blocks) {
                if (info.getCummDifficulty().compareTo(maxTDInfo.getCummDifficulty()) > 0) {
                    maxTDInfo = info;
                }
            }
            // 2. Loop back on each level until common block
            IAionBlock forkLine = getBlockByHash(maxTDInfo.getHash());
            loopBackToCommonBlock(bestLine, forkLine);
        }
    }
}
Also used : IAionBlock(org.aion.zero.types.IAionBlock)

Example 2 with IAionBlock

use of org.aion.zero.types.IAionBlock in project aion by aionnetwork.

the class AionBlockStore method reBranch.

@Override
public void reBranch(AionBlock forkBlock) {
    IAionBlock bestBlock = getBestBlock();
    long currentLevel = Math.max(bestBlock.getNumber(), forkBlock.getNumber());
    // 1. First ensure that you are one the save level
    IAionBlock forkLine = forkBlock;
    if (forkBlock.getNumber() > bestBlock.getNumber()) {
        while (currentLevel > bestBlock.getNumber()) {
            List<BlockInfo> blocks = getBlockInfoForLevel(currentLevel);
            BlockInfo blockInfo = getBlockInfoForHash(blocks, forkLine.getHash());
            if (blockInfo != null) {
                blockInfo.setMainChain(true);
                setBlockInfoForLevel(currentLevel, blocks);
            } else {
                LOG.error("Null block information found at " + currentLevel + " when information should exist.");
            }
            forkLine = getBlockByHash(forkLine.getParentHash());
            --currentLevel;
        }
    }
    IAionBlock bestLine = bestBlock;
    if (bestBlock.getNumber() > forkBlock.getNumber()) {
        while (currentLevel > forkBlock.getNumber()) {
            List<BlockInfo> blocks = getBlockInfoForLevel(currentLevel);
            BlockInfo blockInfo = getBlockInfoForHash(blocks, bestLine.getHash());
            if (blockInfo != null) {
                blockInfo.setMainChain(false);
                setBlockInfoForLevel(currentLevel, blocks);
            } else {
                LOG.error("Null block information found at " + currentLevel + " when information should exist.");
            }
            bestLine = getBlockByHash(bestLine.getParentHash());
            --currentLevel;
        }
    }
    // 2. Loop back on each level until common block
    loopBackToCommonBlock(bestLine, forkLine);
}
Also used : IAionBlock(org.aion.zero.types.IAionBlock)

Example 3 with IAionBlock

use of org.aion.zero.types.IAionBlock in project aion by aionnetwork.

the class AionBlockStore method getListHeadersEndWith.

@Override
public List<A0BlockHeader> getListHeadersEndWith(byte[] hash, long qty) {
    List<AionBlock> blocks = getListBlocksEndWith(hash, qty);
    List<A0BlockHeader> headers = new ArrayList<>(blocks.size());
    for (IAionBlock b : blocks) {
        headers.add(b.getHeader());
    }
    return headers;
}
Also used : A0BlockHeader(org.aion.zero.types.A0BlockHeader) IAionBlock(org.aion.zero.types.IAionBlock) ArrayList(java.util.ArrayList) AionBlock(org.aion.zero.impl.types.AionBlock) IAionBlock(org.aion.zero.types.IAionBlock)

Example 4 with IAionBlock

use of org.aion.zero.types.IAionBlock in project aion by aionnetwork.

the class AionBlockStore method getTotalDifficultyForHash.

@Override
public BigInteger getTotalDifficultyForHash(byte[] hash) {
    IAionBlock block = this.getBlockByHash(hash);
    if (block == null) {
        return ZERO;
    }
    Long level = block.getNumber();
    List<BlockInfo> blockInfos = index.get(level.intValue());
    for (BlockInfo blockInfo : blockInfos) {
        if (Arrays.equals(blockInfo.getHash(), hash)) {
            return blockInfo.cummDifficulty;
        }
    }
    return ZERO;
}
Also used : IAionBlock(org.aion.zero.types.IAionBlock)

Example 5 with IAionBlock

use of org.aion.zero.types.IAionBlock in project aion by aionnetwork.

the class AionBlockStore method pruneAndCorrect.

@Override
public void pruneAndCorrect() {
    IAionBlock block = getBestBlock();
    long initialLevel = block.getNumber();
    long level = initialLevel;
    // top down pruning of nodes on side chains
    while (level > 0) {
        pruneSideChains(block);
        block = getBlockByHash(block.getParentHash());
        if (block == null) {
            LOG.error("Block #" + (level - 1) + " missing from the database. " + "Cannot proceed with block pruning and total difficulty updates.");
            return;
        }
        level = block.getNumber();
    }
    // prune genesis
    pruneSideChains(block);
    // bottom up repair of information
    BigInteger parentTotalDifficulty = block.getCumulativeDifficulty();
    level = 1;
    while (level <= initialLevel) {
        parentTotalDifficulty = correctTotalDifficulty(level, parentTotalDifficulty);
        LOG.info("Updated total difficulty on level " + level + " to " + parentTotalDifficulty + ".");
        level++;
    }
}
Also used : IAionBlock(org.aion.zero.types.IAionBlock) BigInteger(java.math.BigInteger)

Aggregations

IAionBlock (org.aion.zero.types.IAionBlock)8 ArrayList (java.util.ArrayList)2 AionBlock (org.aion.zero.impl.types.AionBlock)2 BigInteger (java.math.BigInteger)1 IEvent (org.aion.evtmgr.IEvent)1 EventConsensus (org.aion.evtmgr.impl.evt.EventConsensus)1 Bloom (org.aion.mcf.vm.types.Bloom)1 Log (org.aion.mcf.vm.types.Log)1 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)1 A0BlockHeader (org.aion.zero.types.A0BlockHeader)1 AionTxReceipt (org.aion.zero.types.AionTxReceipt)1