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();
}
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));
}
}
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));
}
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;
}
}
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();
}
Aggregations