use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionBlockStore method getTwoGenerationBlocksByHashWithInfo.
/**
* Retrieves two generation blocks with unity protocol info.
* <p>
* Always returns a 2-element array. If the blocks cannot be retrieved the array will contain null values.
* Block[0] is the parent block and has the given hash. Block[1] is the grandparent block.
*
* @param hash the hash of the parent block
* @return the retrieved two generation blocks with unity protocol info
*/
public final Block[] getTwoGenerationBlocksByHashWithInfo(byte[] hash) {
Block[] blockFamily = new Block[] { null, null };
if (hash == null) {
return blockFamily;
}
lock.lock();
try {
Block block = getBlockWithInfo(hash);
if (block != null) {
blockFamily[0] = block;
Block parentBlock = getBlockWithInfo(block.getParentHash());
if (parentBlock != null) {
blockFamily[1] = parentBlock;
}
}
return blockFamily;
} finally {
lock.unlock();
}
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionBlockStore method getListHeadersEndWith.
public List<BlockHeader> getListHeadersEndWith(byte[] hash, long qty) {
if (hash == null || qty < 0) {
return null;
}
lock.lock();
try {
List<Block> blocks = getListBlocksEndWith(hash, qty);
List<BlockHeader> headers = new ArrayList<>(blocks.size());
for (Block b : blocks) {
headers.add(b.getHeader());
}
return headers;
} finally {
lock.unlock();
}
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionBlockStore method reBranch.
/**
* @return the common block that was found during the re-branching
*/
public long reBranch(Block forkBlock) {
lock.lock();
try {
Block bestBlock = getBestBlock();
long currentLevel = Math.max(bestBlock.getNumber(), forkBlock.getNumber());
// 1. First ensure that you are one the save level
Block forkLine = forkBlock;
if (forkBlock.getNumber() > bestBlock.getNumber()) {
branchingLevel = currentLevel;
while (currentLevel > bestBlock.getNumber()) {
List<BlockInfo> blocks = getBlockInfoForLevel(currentLevel);
BlockInfo blockInfo = getBlockInfoForHash(blocks, forkLine.getHash());
if (blockInfo != null) {
blockInfo.setMainChain(true);
setBlockInfoForLevel(currentLevel, blocks);
// For collecting branching blocks
branchingBlk.push(this.blocks.get(blockInfo.getHash()));
} else {
LOG.error("Encountered a kernel database corruption: cannot find block with fork line hash {} at the level {} in index data store.", ByteUtil.toHexString(forkLine.getHash()), currentLevel);
LOG.error("Please reboot your node to trigger automatic database recovery by the kernel.");
}
forkLine = this.blocks.get(forkLine.getParentHash());
--currentLevel;
}
}
Block 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);
// For collecting prebranching blocks
preBranchingBlk.push(this.blocks.get(blockInfo.getHash()));
} else {
LOG.error("Encountered a kernel database corruption: cannot find block with best line hash {} at the level {} in index data store.", ByteUtil.toHexString(forkLine.getHash()), currentLevel);
LOG.error("Please reboot your node to trigger automatic database recovery by the kernel.");
}
bestLine = this.blocks.get(bestLine.getParentHash());
--currentLevel;
}
}
// 2. Loop back on each level until common block
long commonBlockNumber = loopBackToCommonBlock(bestLine, forkLine);
logBranchingDetails();
return commonBlockNumber;
} finally {
lock.unlock();
}
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionBlockStore method getBlocksByRange.
/**
* Returns a range of main chain blocks.
*
* @param first the height of the first block in the requested range; this block must exist in
* the blockchain and be above the genesis to return a non-null output
* @param last the height of the last block in the requested range; when requesting blocks in
* ascending order the last element will be substituted with the best block if its height is
* above the best known block
* @return a list containing consecutive main chain blocks with heights ranging according to the
* given parameters; or {@code null} in case of errors or illegal request
* @apiNote The blocks must be added to the list in the order that they are requested. If {@code
* first > last} the blocks are returned in descending order of their height, otherwise when
* {@code first < last} the blocks are returned in ascending order of their height.
*/
public List<Block> getBlocksByRange(long first, long last) {
if (first <= 0L) {
return null;
}
lock.lock();
try {
Block block = getChainBlockByNumber(first);
if (block == null) {
// invalid request
return null;
}
if (first == last) {
return List.of(block);
} else if (first > last) {
// first is highest -> can query directly by parent hash
List<Block> blocks = new ArrayList<>();
blocks.add(block);
for (long i = first - 1; i >= (last > 0 ? last : 1); i--) {
block = getBlockByHashWithInfo(block.getParentHash());
if (block == null) {
// the block should have been stored but null was returned above
LOG.error("Encountered a kernel database corruption: cannot find block at level {} in data store.", i);
LOG.error(" Please shutdown the kernel and rollback the database by executing:\t./aion.sh -n <network> -r {}", i - 1);
// stops at any invalid data
return null;
} else {
blocks.add(block);
}
}
return blocks;
} else {
// last is highest
LinkedList<Block> blocks = new LinkedList<>();
Block lastBlock = getChainBlockByNumber(last);
if (lastBlock == null) {
// assuming height was above best block
// attempt to get best block
lastBlock = getBestBlock();
if (lastBlock == null) {
LOG.error("Encountered a kernel database corruption: cannot find best block in data store.");
LOG.error("Please reboot your node to trigger automatic database recovery by the kernel.");
return null;
} else if (last < lastBlock.getNumber()) {
// the block should have been stored but null was returned above
LOG.error("Encountered a kernel database corruption: cannot find block at level {} in data store.", last);
LOG.error(" Please shutdown the kernel and rollback the database by executing:\t./aion.sh -n <network> -r {}", last - 1);
return null;
}
}
// the block was not null
// or it was higher than the best block and replaced with the best block
// building existing range
blocks.addFirst(lastBlock);
long newLast = lastBlock.getNumber();
for (long i = newLast - 1; i > first; i--) {
lastBlock = getBlockByHashWithInfo(lastBlock.getParentHash());
if (lastBlock == null) {
LOG.error("Encountered a kernel database corruption: cannot find block at level {} in block data store.", i);
LOG.error(" Please shutdown the kernel and rollback the database by executing:\t./aion.sh -n <network> -r {}", i - 1);
return null;
} else {
// always adding at the beginning of the list
// to return the expected order of blocks
blocks.addFirst(lastBlock);
}
}
// adding the initial block
blocks.addFirst(block);
return blocks;
}
} finally {
lock.unlock();
}
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionBlockStore method getAllChainBlockByNumber.
/**
* @implNote method use for the CLI tooling
* @param number block number
* @return list of blocks in the given block level.
*/
List<Block> getAllChainBlockByNumber(long number, Logger log) {
lock.lock();
try {
long size = index.size();
if (number < 0L || number >= size) {
return null;
}
List<BlockInfo> blockInfos = index.get(number);
if (blockInfos == null) {
log.error("Encountered a kernel database corruption: cannot find block at level {} in data store.", number);
log.error(" Please shutdown the kernel and rollback the database by executing:\t./aion.sh -n <network> -r {}", number - 1);
throw new IllegalStateException("Index Database corruption! ");
}
List<Block> blockList = new ArrayList<>();
for (BlockInfo blockInfo : blockInfos) {
Block b = blocks.get(blockInfo.getHash());
if (b == null) {
log.error("Encountered a kernel database corruption: cannot find block with hash {} in data store.", ByteUtil.toHexString(blockInfo.getHash()));
log.error(" Please shutdown the kernel and re import the database by executing:\t./aion.sh -n <network> --redo-import");
throw new IllegalStateException("blocks Database corruption! ");
}
if (blockInfo.isMainChain()) {
b.setMainChain();
}
b.setTotalDifficulty(blockInfo.getTotalDifficulty());
blockList.add(b);
}
return blockList;
} finally {
lock.unlock();
}
}
Aggregations