Search in sources :

Example 1 with Metric

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;
}
Also used : Metric(co.rsk.metrics.profilers.Metric)

Example 2 with Metric

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;
    }
}
Also used : BlockDifficulty(co.rsk.core.BlockDifficulty) Metric(co.rsk.metrics.profilers.Metric)

Example 3 with Metric

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);
}
Also used : Metric(co.rsk.metrics.profilers.Metric)

Example 4 with 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;
}
Also used : Coin(co.rsk.core.Coin) Metric(co.rsk.metrics.profilers.Metric)

Example 5 with Metric

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);
}
Also used : Metric(co.rsk.metrics.profilers.Metric)

Aggregations

Metric (co.rsk.metrics.profilers.Metric)20 Coin (co.rsk.core.Coin)3 IOException (java.io.IOException)3 RskAddress (co.rsk.core.RskAddress)2 ECKey (org.ethereum.crypto.ECKey)2 ByteArrayWrapper (org.ethereum.db.ByteArrayWrapper)2 VMException (org.ethereum.vm.exception.VMException)2 BlockDifficulty (co.rsk.core.BlockDifficulty)1 Path (java.nio.file.Path)1 SignatureException (java.security.SignatureException)1 Nullable (javax.annotation.Nullable)1 DataWord (org.ethereum.vm.DataWord)1 Program (org.ethereum.vm.program.Program)1 ProgramInvoke (org.ethereum.vm.program.invoke.ProgramInvoke)1