Search in sources :

Example 21 with BlockDifficulty

use of co.rsk.core.BlockDifficulty in project rskj by rsksmart.

the class DownloadingBackwardsBodiesSyncStateTest method onEnter_connectGenesis_difficultyDoesNotMatch.

/**
 * This situation has no solution except a complete resynchronization.
 * <p>
 * The downloaded state was invalid and does not connect to genesis.
 */
@Test(expected = IllegalStateException.class)
public void onEnter_connectGenesis_difficultyDoesNotMatch() {
    List<BlockHeader> toRequest = new LinkedList<>();
    DownloadingBackwardsBodiesSyncState target = new DownloadingBackwardsBodiesSyncState(syncConfiguration, syncEventsHandler, peersInformation, genesis, blockFactory, blockStore, child, toRequest, peer);
    Keccak256 childHash = new Keccak256(new byte[32]);
    when(child.getHash()).thenReturn(childHash);
    when(child.getNumber()).thenReturn(1L);
    when(genesis.isParentOf(child)).thenReturn(true);
    when(child.getCumulativeDifficulty()).thenReturn(new BlockDifficulty(BigInteger.valueOf(50)));
    when(genesis.getCumulativeDifficulty()).thenReturn(new BlockDifficulty(BigInteger.valueOf(50)));
    when(blockStore.getTotalDifficultyForHash(eq(childHash.getBytes()))).thenReturn(new BlockDifficulty(BigInteger.valueOf(101)));
    target.onEnter();
}
Also used : BlockDifficulty(co.rsk.core.BlockDifficulty) Keccak256(co.rsk.crypto.Keccak256) LinkedList(java.util.LinkedList) Test(org.junit.Test)

Example 22 with BlockDifficulty

use of co.rsk.core.BlockDifficulty in project rskj by rsksmart.

the class DownloadingBackwardsBodiesSyncStateTest method connecting_notGenesis.

@Test
public void connecting_notGenesis() {
    LinkedList<BlockHeader> toRequest = new LinkedList<>();
    LinkedList<BodyResponseMessage> responses = new LinkedList<>();
    LinkedList<Block> expectedBlocks = new LinkedList<>();
    Function<Long, BlockDifficulty> difficultyForBlockNumber = (n) -> new BlockDifficulty(BigInteger.valueOf(n * (n + 1) / 2));
    // their indexes and each one is the children of the previous block.
    for (long i = 2; i <= 10; i++) {
        BlockHeader headerToRequest = mock(BlockHeader.class);
        when(headerToRequest.getNumber()).thenReturn(i);
        Keccak256 headerHash = new Keccak256(ByteUtil.leftPadBytes(ByteUtil.longToBytes(i), 32));
        when(headerToRequest.getHash()).thenReturn(headerHash);
        toRequest.addFirst(headerToRequest);
        when(syncEventsHandler.sendBodyRequest(any(), eq(headerToRequest))).thenReturn(i);
        BodyResponseMessage response = new BodyResponseMessage(i, new LinkedList<>(), new LinkedList<>());
        responses.addFirst(response);
        Block block = mock(Block.class);
        expectedBlocks.addFirst(block);
        when(block.getNumber()).thenReturn(i);
        when(block.getHash()).thenReturn(headerHash);
        when(blockFactory.newBlock(headerToRequest, response.getTransactions(), response.getUncles())).thenReturn(block);
        when(block.isParentOf(any())).thenReturn(true);
        when(blockStore.getTotalDifficultyForHash(headerHash.getBytes())).thenReturn(difficultyForBlockNumber.apply(i));
        when(block.getCumulativeDifficulty()).thenReturn(new BlockDifficulty(BigInteger.valueOf(i)));
    }
    Keccak256 childHash = new Keccak256(ByteUtil.leftPadBytes(ByteUtil.intToBytes(11), 32));
    when(child.getHash()).thenReturn(childHash);
    when(blockStore.getTotalDifficultyForHash(childHash.getBytes())).thenReturn(difficultyForBlockNumber.apply(11L));
    when(child.getCumulativeDifficulty()).thenReturn(new BlockDifficulty(BigInteger.valueOf(11L)));
    when(child.getNumber()).thenReturn(11L);
    DownloadingBackwardsBodiesSyncState target = new DownloadingBackwardsBodiesSyncState(syncConfiguration, syncEventsHandler, peersInformation, genesis, blockFactory, blockStore, child, toRequest, peer);
    while (!responses.isEmpty()) {
        target.onEnter();
        target.newBody(responses.pop(), mock(Peer.class));
        Block block = expectedBlocks.pop();
        BlockDifficulty expectedDifficulty = difficultyForBlockNumber.apply(block.getNumber());
        verify(blockStore).saveBlock(eq(block), eq(expectedDifficulty), eq(true));
    }
}
Also used : BlockDifficulty(co.rsk.core.BlockDifficulty) Peer(co.rsk.net.Peer) Test(org.junit.Test) BlockStore(org.ethereum.db.BlockStore) Keccak256(co.rsk.crypto.Keccak256) Function(java.util.function.Function) Mockito(org.mockito.Mockito) List(java.util.List) ByteUtil(org.ethereum.util.ByteUtil) BigInteger(java.math.BigInteger) LinkedList(java.util.LinkedList) BodyResponseMessage(co.rsk.net.messages.BodyResponseMessage) org.ethereum.core(org.ethereum.core) Before(org.junit.Before) BodyResponseMessage(co.rsk.net.messages.BodyResponseMessage) Peer(co.rsk.net.Peer) Keccak256(co.rsk.crypto.Keccak256) LinkedList(java.util.LinkedList) BlockDifficulty(co.rsk.core.BlockDifficulty) Test(org.junit.Test)

Example 23 with BlockDifficulty

use of co.rsk.core.BlockDifficulty in project rskj by rsksmart.

the class BlockUnclesValidationRuleTest method rejectBlockWithSiblingUncle.

@Test
public void rejectBlockWithSiblingUncle() {
    BlockGenerator blockGenerator = new BlockGenerator();
    Block genesis = blockGenerator.getGenesisBlock();
    Block block1 = blockGenerator.createChildBlock(genesis);
    Block uncle = blockGenerator.createChildBlock(block1);
    List<BlockHeader> uncles = new ArrayList<>();
    uncles.add(uncle.getHeader());
    Block block = blockGenerator.createChildBlock(block1, null, uncles, 1, null);
    BlockStore blockStore = new IndexedBlockStore(null, new HashMapDB(), new HashMapBlocksIndex());
    blockStore.saveBlock(genesis, new BlockDifficulty(BigInteger.valueOf(1)), true);
    blockStore.saveBlock(block1, new BlockDifficulty(BigInteger.valueOf(2)), true);
    BlockUnclesValidationRule rule = new BlockUnclesValidationRule(blockStore, 10, 10, new BlockHeaderCompositeRule(), new BlockHeaderParentCompositeRule());
    Assert.assertFalse(rule.isValid(block));
}
Also used : IndexedBlockStore(org.ethereum.db.IndexedBlockStore) BlockStore(org.ethereum.db.BlockStore) IndexedBlockStore(org.ethereum.db.IndexedBlockStore) ArrayList(java.util.ArrayList) HashMapDB(org.ethereum.datasource.HashMapDB) BlockGenerator(co.rsk.blockchain.utils.BlockGenerator) BlockDifficulty(co.rsk.core.BlockDifficulty) Block(org.ethereum.core.Block) HashMapBlocksIndex(co.rsk.db.HashMapBlocksIndex) BlockHeader(org.ethereum.core.BlockHeader) Test(org.junit.Test)

Example 24 with BlockDifficulty

use of co.rsk.core.BlockDifficulty 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 25 with BlockDifficulty

use of co.rsk.core.BlockDifficulty in project rskj by rsksmart.

the class MainNetMinerTest method setup.

@Before
public void setup() {
    config = spy(new TestSystemProperties());
    when(config.getNetworkConstants()).thenReturn(Constants.mainnet());
    when(config.getActivationConfig()).thenReturn(ActivationConfigsForTest.all());
    RskTestFactory factory = new RskTestFactory(config) {

        @Override
        public GenesisLoader buildGenesisLoader() {
            return new TestGenesisLoader(getTrieStore(), "rsk-unittests.json", BigInteger.ZERO, true, true, true) {

                @Override
                public Genesis load() {
                    Genesis genesis = super.load();
                    genesis.getHeader().setDifficulty(new BlockDifficulty(BigInteger.valueOf(300000)));
                    return genesis;
                }
            };
        }
    };
    mainchainView = factory.getMiningMainchainView();
    transactionPool = factory.getTransactionPool();
    blockStore = factory.getBlockStore();
    blockProcessor = factory.getNodeBlockProcessor();
    repositoryLocator = factory.getRepositoryLocator();
    blockFactory = factory.getBlockFactory();
    blockExecutor = factory.getBlockExecutor();
}
Also used : BlockDifficulty(co.rsk.core.BlockDifficulty) Genesis(org.ethereum.core.Genesis) RskTestFactory(org.ethereum.util.RskTestFactory) TestGenesisLoader(co.rsk.core.genesis.TestGenesisLoader) TestSystemProperties(co.rsk.config.TestSystemProperties) Before(org.junit.Before)

Aggregations

BlockDifficulty (co.rsk.core.BlockDifficulty)60 Test (org.junit.Test)32 Block (org.ethereum.core.Block)23 BigInteger (java.math.BigInteger)14 HashMapDB (org.ethereum.datasource.HashMapDB)11 Keccak256 (co.rsk.crypto.Keccak256)9 Ignore (org.junit.Ignore)9 BlockGenerator (co.rsk.blockchain.utils.BlockGenerator)8 BlockHeader (org.ethereum.core.BlockHeader)7 ActivationConfigsForTest (org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest)6 KeyValueDataSource (org.ethereum.datasource.KeyValueDataSource)6 Coin (co.rsk.core.Coin)5 MapDBBlocksIndex (co.rsk.db.MapDBBlocksIndex)5 LevelDbDataSource (org.ethereum.datasource.LevelDbDataSource)5 BlockStore (org.ethereum.db.BlockStore)5 DifficultyCalculator (co.rsk.core.DifficultyCalculator)4 BlockChainImpl (co.rsk.core.bc.BlockChainImpl)4 HashMapBlocksIndex (co.rsk.db.HashMapBlocksIndex)4 BlockChainBuilder (co.rsk.test.builders.BlockChainBuilder)4 ArrayList (java.util.ArrayList)4