use of co.rsk.metrics.profilers.Metric in project rskj by rsksmart.
the class BlockChainImpl method isValid.
private boolean isValid(Block block) {
Metric metric = profiler.start(Profiler.PROFILING_TYPE.BLOCK_VALIDATION);
boolean validation = blockValidator.isValid(block);
profiler.stop(metric);
return validation;
}
use of co.rsk.metrics.profilers.Metric in project rskj by rsksmart.
the class BlockChainImpl method internalTryToConnect.
private ImportResult internalTryToConnect(Block block) {
Metric metric = profiler.start(Profiler.PROFILING_TYPE.BEFORE_BLOCK_EXEC);
if (blockStore.getBlockByHash(block.getHash().getBytes()) != null && !BlockDifficulty.ZERO.equals(blockStore.getTotalDifficultyForHash(block.getHash().getBytes()))) {
logger.debug("Block already exist in chain hash: {}, number: {}", block.getPrintableHash(), block.getNumber());
profiler.stop(metric);
return ImportResult.EXIST;
}
Block bestBlock;
BlockDifficulty bestTotalDifficulty;
logger.trace("get current state");
// get current state
synchronized (accessLock) {
bestBlock = status.getBestBlock();
bestTotalDifficulty = status.getTotalDifficulty();
}
Block parent;
BlockDifficulty parentTotalDifficulty;
// Incoming block is child of current best block
if (bestBlock == null || bestBlock.isParentOf(block)) {
parent = bestBlock;
parentTotalDifficulty = bestTotalDifficulty;
} else // else, Get parent AND total difficulty
{
logger.trace("get parent and total difficulty");
parent = blockStore.getBlockByHash(block.getParentHash().getBytes());
if (parent == null) {
profiler.stop(metric);
return ImportResult.NO_PARENT;
}
parentTotalDifficulty = blockStore.getTotalDifficultyForHash(parent.getHash().getBytes());
if (parentTotalDifficulty == null || parentTotalDifficulty.equals(BlockDifficulty.ZERO)) {
profiler.stop(metric);
return ImportResult.NO_PARENT;
}
}
// Validate incoming block before its processing
if (!isValid(block)) {
long blockNumber = block.getNumber();
logger.warn("Invalid block with number: {}", blockNumber);
panicProcessor.panic("invalidblock", String.format("Invalid block %s %s", blockNumber, block.getHash()));
profiler.stop(metric);
return ImportResult.INVALID_BLOCK;
}
profiler.stop(metric);
BlockResult result = null;
if (parent != null) {
long saveTime = System.nanoTime();
logger.trace("execute start");
result = blockExecutor.execute(block, parent.getHeader(), false, noValidation);
logger.trace("execute done");
metric = profiler.start(Profiler.PROFILING_TYPE.AFTER_BLOCK_EXEC);
boolean isValid = noValidation ? true : blockExecutor.validate(block, result);
logger.trace("validate done");
if (!isValid) {
profiler.stop(metric);
return ImportResult.INVALID_BLOCK;
}
// Now that we know it's valid, we can commit the changes made by the block
// to the parent's repository.
long totalTime = System.nanoTime() - saveTime;
String timeInSeconds = FormatUtils.formatNanosecondsToSeconds(totalTime);
if (BlockUtils.tooMuchProcessTime(totalTime)) {
logger.warn("block: num: [{}] hash: [{}], executed after: [{}]seconds", block.getNumber(), block.getPrintableHash(), timeInSeconds);
} else {
logger.trace("block: num: [{}] hash: [{}], executed after: [{}]seconds", block.getNumber(), block.getPrintableHash(), timeInSeconds);
}
// the block is valid at this point
stateRootHandler.register(block.getHeader(), result.getFinalState());
profiler.stop(metric);
}
metric = profiler.start(Profiler.PROFILING_TYPE.AFTER_BLOCK_EXEC);
// the new accumulated difficulty
BlockDifficulty totalDifficulty = parentTotalDifficulty.add(block.getCumulativeDifficulty());
logger.trace("TD: updated to {}", totalDifficulty);
// It is the new best block
if (SelectionRule.shouldWeAddThisBlock(totalDifficulty, status.getTotalDifficulty(), block, bestBlock)) {
if (bestBlock != null && !bestBlock.isParentOf(block)) {
logger.trace("Rebranching: {} ~> {} From block {} ~> {} Difficulty {} Challenger difficulty {}", bestBlock.getPrintableHash(), block.getPrintableHash(), bestBlock.getNumber(), block.getNumber(), status.getTotalDifficulty(), totalDifficulty);
blockStore.reBranch(block);
}
logger.trace("Start switchToBlockChain");
switchToBlockChain(block, totalDifficulty);
logger.trace("Start saveReceipts");
saveReceipts(block, result);
logger.trace("Start processBest");
processBest(block);
logger.trace("Start onBestBlock");
onBestBlock(block, result);
logger.trace("Start onBlock");
onBlock(block, result);
logger.trace("Start flushData");
logger.trace("Better block {} {}", block.getNumber(), block.getPrintableHash());
logger.debug("block added to the blockChain: index: [{}]", block.getNumber());
if (block.getNumber() % 100 == 0) {
logger.info("*** Last block added [ #{} ]", block.getNumber());
}
profiler.stop(metric);
return ImportResult.IMPORTED_BEST;
} else // It is not the new best block
{
if (bestBlock != null && !bestBlock.isParentOf(block)) {
logger.trace("No rebranch: {} ~> {} From block {} ~> {} Difficulty {} Challenger difficulty {}", bestBlock.getPrintableHash(), block.getPrintableHash(), bestBlock.getNumber(), block.getNumber(), status.getTotalDifficulty(), totalDifficulty);
}
logger.trace("Start extendAlternativeBlockChain");
extendAlternativeBlockChain(block, totalDifficulty);
logger.trace("Start saveReceipts");
saveReceipts(block, result);
logger.trace("Start onBlock");
onBlock(block, result);
logger.trace("Start flushData");
if (bestBlock != null && block.getNumber() > bestBlock.getNumber()) {
logger.warn("Strange block number state");
}
logger.trace("Block not imported {} {}", block.getNumber(), block.getPrintableHash());
profiler.stop(metric);
return ImportResult.IMPORTED_NOT_BEST;
}
}
use of co.rsk.metrics.profilers.Metric in project rskj by rsksmart.
the class BlockExecutor method fill.
private void fill(Block block, BlockResult result) {
Metric metric = profiler.start(Profiler.PROFILING_TYPE.FILLING_EXECUTED_BLOCK);
BlockHeader header = block.getHeader();
block.setTransactionsList(result.getExecutedTransactions());
boolean isRskip126Enabled = activationConfig.isActive(RSKIP126, block.getNumber());
header.setTransactionsRoot(BlockHashesHelper.getTxTrieRoot(block.getTransactionsList(), isRskip126Enabled));
header.setReceiptsRoot(BlockHashesHelper.calculateReceiptsTrieRoot(result.getTransactionReceipts(), isRskip126Enabled));
header.setStateRoot(result.getFinalState().getHash().getBytes());
header.setGasUsed(result.getGasUsed());
header.setPaidFees(result.getPaidFees());
header.setLogsBloom(calculateLogsBloom(result.getTransactionReceipts()));
block.flushRLP();
profiler.stop(metric);
}
use of co.rsk.metrics.profilers.Metric in project rskj by rsksmart.
the class BlockExecutor method validate.
/**
* Validate the final state of a block.
*
* @param block A block to validate
* @param result A block result (state root, receipts root, etc...)
* @return true if the block final state is equalBytes to the calculated final state.
*/
public boolean validate(Block block, BlockResult result) {
Metric metric = profiler.start(Profiler.PROFILING_TYPE.BLOCK_FINAL_STATE_VALIDATION);
if (result == BlockResult.INTERRUPTED_EXECUTION_BLOCK_RESULT) {
logger.error("Block {} [{}] execution was interrupted because of an invalid transaction", block.getNumber(), block.getPrintableHash());
profiler.stop(metric);
return false;
}
boolean isValidStateRoot = validateStateRoot(block.getHeader(), result);
if (!isValidStateRoot) {
logger.error("Block {} [{}] given State Root is invalid", block.getNumber(), block.getPrintableHash());
profiler.stop(metric);
return false;
}
boolean isValidReceiptsRoot = validateReceiptsRoot(block.getHeader(), result);
if (!isValidReceiptsRoot) {
logger.error("Block {} [{}] given Receipt Root is invalid", block.getNumber(), block.getPrintableHash());
profiler.stop(metric);
return false;
}
boolean isValidLogsBloom = validateLogsBloom(block.getHeader(), result);
if (!isValidLogsBloom) {
logger.error("Block {} [{}] given Logs Bloom is invalid", block.getNumber(), block.getPrintableHash());
profiler.stop(metric);
return false;
}
if (result.getGasUsed() != block.getGasUsed()) {
logger.error("Block {} [{}] given gasUsed doesn't match: {} != {}", block.getNumber(), block.getPrintableHash(), block.getGasUsed(), result.getGasUsed());
profiler.stop(metric);
return false;
}
Coin paidFees = result.getPaidFees();
Coin feesPaidToMiner = block.getFeesPaidToMiner();
if (!paidFees.equals(feesPaidToMiner)) {
logger.error("Block {} [{}] given paidFees doesn't match: {} != {}", block.getNumber(), block.getPrintableHash(), feesPaidToMiner, paidFees);
profiler.stop(metric);
return false;
}
List<Transaction> executedTransactions = result.getExecutedTransactions();
List<Transaction> transactionsList = block.getTransactionsList();
if (!executedTransactions.equals(transactionsList)) {
logger.error("Block {} [{}] given txs doesn't match: {} != {}", block.getNumber(), block.getPrintableHash(), transactionsList, executedTransactions);
profiler.stop(metric);
return false;
}
profiler.stop(metric);
return true;
}
use of co.rsk.metrics.profilers.Metric in project rskj by rsksmart.
the class BlockChainFlusher method flushAll.
private void flushAll() {
Metric metric = profiler.start(Profiler.PROFILING_TYPE.BLOCKCHAIN_FLUSH);
long saveTime = System.nanoTime();
trieStore.flush();
long totalTime = System.nanoTime() - saveTime;
if (logger.isTraceEnabled()) {
logger.trace("repository flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
}
saveTime = System.nanoTime();
stateRootsStore.flush();
totalTime = System.nanoTime() - saveTime;
if (logger.isTraceEnabled()) {
logger.trace("stateRootsStore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
}
saveTime = System.nanoTime();
receiptStore.flush();
totalTime = System.nanoTime() - saveTime;
if (logger.isTraceEnabled()) {
logger.trace("receiptstore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
}
saveTime = System.nanoTime();
blockStore.flush();
totalTime = System.nanoTime() - saveTime;
if (logger.isTraceEnabled()) {
logger.trace("blockstore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
}
saveTime = System.nanoTime();
blocksBloomStore.flush();
totalTime = System.nanoTime() - saveTime;
if (logger.isTraceEnabled()) {
logger.trace("bloomBlocksStore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
}
profiler.stop(metric);
}
Aggregations