@Test public void roundTripNewBlockMessage() { final UInt256 totalDifficulty = UInt256.of(98765); final BlockDataGenerator blockGenerator = new BlockDataGenerator(); final Block blockForInsertion = blockGenerator.block(); final NewBlockMessage msg = NewBlockMessage.create(blockForInsertion, totalDifficulty); assertThat(msg.getCode()).isEqualTo(EthPV62.NEW_BLOCK); assertThat(msg.totalDifficulty(protocolSchedule)).isEqualTo(totalDifficulty); final Block extractedBlock = msg.block(protocolSchedule); assertThat(extractedBlock).isEqualTo(blockForInsertion); }
@Test public void registerPendingBlock() { final Block block = gen.block(); // Sanity check assertThat(pendingBlocks.contains(block.getHash())).isFalse(); pendingBlocks.registerPendingBlock(block); assertThat(pendingBlocks.contains(block.getHash())).isTrue(); final List<Block> pendingBlocksForParent = pendingBlocks.childrenOf(block.getHeader().getParentHash()); assertThat(pendingBlocksForParent).isEqualTo(Collections.singletonList(block)); }
@Test public void registerSiblingBlocks() { final BlockDataGenerator gen = new BlockDataGenerator(); final Block parentBlock = gen.block(); final Block childBlock = gen.nextBlock(parentBlock); final Block childBlock2 = gen.nextBlock(parentBlock); final List<Block> children = Arrays.asList(childBlock, childBlock2); pendingBlocks.registerPendingBlock(childBlock); pendingBlocks.registerPendingBlock(childBlock2); assertThat(pendingBlocks.contains(childBlock.getHash())).isTrue(); assertThat(pendingBlocks.contains(childBlock2.getHash())).isTrue(); final List<Block> pendingBlocksForParent = pendingBlocks.childrenOf(parentBlock.getHash()); assertThat(pendingBlocksForParent.size()).isEqualTo(2); assertThat(new HashSet<>(pendingBlocksForParent)).isEqualTo(new HashSet<>(children)); }
@Test public void deregisterPendingBlock() { final Block block = gen.block(); pendingBlocks.registerPendingBlock(block); pendingBlocks.deregisterPendingBlock(block); assertThat(pendingBlocks.contains(block.getHash())).isFalse(); final List<Block> pendingBlocksForParent = pendingBlocks.childrenOf(block.getHeader().getParentHash()); assertThat(pendingBlocksForParent).isEqualTo(Collections.emptyList()); }
@Test public void importsInvalidUnorderedBlocks() throws Exception { final BlockDataGenerator gen = new BlockDataGenerator(); blockchainUtil.importFirstBlocks(3); final List<Block> nextBlocks = Arrays.asList(gen.block(), gen.block()); // Sanity check for (final Block nextBlock : nextBlocks) { assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); } // Create task final CompletableFuture<List<Block>> task = PersistBlockTask.forUnorderedBlocks( protocolSchedule, protocolContext, nextBlocks, HeaderValidationMode.FULL, ethTasksTimer) .get(); Awaitility.await().atMost(30, SECONDS).until(task::isDone); assertThat(task.isCompletedExceptionally()).isTrue(); for (final Block nextBlock : nextBlocks) { assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); } }
private void recordNewBlockEvent() { filterManager.recordBlockEvent( BlockAddedEvent.createForHeadAdvancement(new BlockDataGenerator().block()), blockchainQueries.getBlockchain()); }
@Test public void failsToImportInvalidBlockSequenceWhereFirstBlockFails() throws Exception { final BlockDataGenerator gen = new BlockDataGenerator(); blockchainUtil.importFirstBlocks(3); final List<Block> nextBlocks = Arrays.asList(gen.block(), blockchainUtil.getBlock(3)); // Sanity check for (final Block nextBlock : nextBlocks) { assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); } // Create task final CompletableFuture<List<Block>> task = PersistBlockTask.forSequentialBlocks( protocolSchedule, protocolContext, nextBlocks, HeaderValidationMode.FULL, ethTasksTimer) .get(); Awaitility.await().atMost(30, SECONDS).until(task::isDone); assertThat(task.isCompletedExceptionally()).isTrue(); assertThatThrownBy(task::get).hasCauseInstanceOf(InvalidBlockException.class); assertThat(blockchain.contains(nextBlocks.get(0).getHash())).isFalse(); assertThat(blockchain.contains(nextBlocks.get(1).getHash())).isFalse(); }
@Test public void deregisterSubsetOfSiblingBlocks() { final BlockDataGenerator gen = new BlockDataGenerator(); final Block parentBlock = gen.block(); final Block childBlock = gen.nextBlock(parentBlock); final Block childBlock2 = gen.nextBlock(parentBlock); pendingBlocks.registerPendingBlock(childBlock); pendingBlocks.registerPendingBlock(childBlock2); pendingBlocks.deregisterPendingBlock(childBlock); assertThat(pendingBlocks.contains(childBlock.getHash())).isFalse(); assertThat(pendingBlocks.contains(childBlock2.getHash())).isTrue(); final List<Block> pendingBlocksForParent = pendingBlocks.childrenOf(parentBlock.getHash()); assertThat(pendingBlocksForParent).isEqualTo(Collections.singletonList(childBlock2)); }
public static Block createProposalBlock(final List<Address> validators, final int round) { final BytesValue extraData = new IbftExtraData( BytesValue.wrap(new byte[32]), Collections.emptyList(), Optional.empty(), round, validators) .encode(); final BlockOptions blockOptions = BlockOptions.create() .setExtraData(extraData) .setBlockHashFunction(IbftBlockHashing::calculateDataHashForCommittedSeal); return new BlockDataGenerator().block(blockOptions); }
@Test public void getReceiptsStream() throws PeerNotConnected { final ResponseStreamSupplier getStream = (peer) -> peer.getReceipts(asList(gen.hash(), gen.hash())); final MessageData targetMessage = ReceiptsMessage.create(singletonList(gen.receipts(gen.block()))); final MessageData otherMessage = BlockHeadersMessage.create(asList(gen.header(), gen.header())); messageStream(getStream, targetMessage, otherMessage); }
@Test public void importsInvalidUnorderedBlock() throws Exception { final BlockDataGenerator gen = new BlockDataGenerator(); blockchainUtil.importFirstBlocks(3); final Block invalid = gen.block(); final List<Block> nextBlocks = Collections.singletonList(invalid); // Sanity check for (final Block nextBlock : nextBlocks) { assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); } // Create task final CompletableFuture<List<Block>> task = PersistBlockTask.forUnorderedBlocks( protocolSchedule, protocolContext, nextBlocks, HeaderValidationMode.FULL, ethTasksTimer) .get(); Awaitility.await().atMost(30, SECONDS).until(task::isDone); assertThat(task.isCompletedExceptionally()).isTrue(); for (final Block nextBlock : nextBlocks) { assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); } }
@Test public void failsToImportInvalidBlock() { final BlockDataGenerator gen = new BlockDataGenerator(); blockchainUtil.importFirstBlocks(3); final Block nextBlock = gen.block(); // Sanity check assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); // Create task final PersistBlockTask<Void> task = PersistBlockTask.create( protocolSchedule, protocolContext, nextBlock, HeaderValidationMode.FULL, ethTasksTimer); final CompletableFuture<Block> result = task.run(); Awaitility.await().atMost(30, SECONDS).until(result::isDone); assertThat(result.isCompletedExceptionally()).isTrue(); assertThatThrownBy(result::get).hasCauseInstanceOf(InvalidBlockException.class); assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); }
@Test public void rawMessageUpCastsToANewBlockMessage() { final UInt256 totalDifficulty = UInt256.of(12345); final BlockDataGenerator blockGenerator = new BlockDataGenerator(); final Block blockForInsertion = blockGenerator.block(); final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); tmp.startList(); blockForInsertion.writeTo(tmp); tmp.writeUInt256Scalar(totalDifficulty); tmp.endList(); final RawMessage rawMsg = new RawMessage(EthPV62.NEW_BLOCK, tmp.encoded()); final NewBlockMessage newBlockMsg = NewBlockMessage.readFrom(rawMsg); assertThat(newBlockMsg.getCode()).isEqualTo(EthPV62.NEW_BLOCK); assertThat(newBlockMsg.totalDifficulty(protocolSchedule)).isEqualTo(totalDifficulty); final Block extractedBlock = newBlockMsg.block(protocolSchedule); assertThat(extractedBlock).isEqualTo(blockForInsertion); }
@Test public void blockAddedObserver_invokedSingle() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); final AtomicBoolean observerInvoked = new AtomicBoolean(false); blockchain.observeBlockAdded( (block, chain) -> { observerInvoked.set(true); }); blockchain.appendBlock(newBlock, receipts); assertThat(observerInvoked.get()).isTrue(); }
@BeforeClass public static void setupClass() { genesisBlock = blockDataGenerator.genesisBlock(); localBlockchain = createInMemoryBlockchain(genesisBlock); // Setup local chain for (int i = 1; i <= chainHeight; i++) { final BlockDataGenerator.BlockOptions options = new BlockDataGenerator.BlockOptions() .setBlockNumber(i) .setParentHash(localBlockchain.getBlockHashByNumber(i - 1).get()); final Block block = blockDataGenerator.block(options); final List<TransactionReceipt> receipts = blockDataGenerator.receipts(block); localBlockchain.appendBlock(block, receipts); } }
@BeforeClass public static void setupClass() { genesisBlock = blockDataGenerator.genesisBlock(); localBlockchain = createInMemoryBlockchain(genesisBlock); // Setup local chain. for (int i = 1; i <= chainHeight; i++) { final BlockDataGenerator.BlockOptions options = new BlockDataGenerator.BlockOptions() .setBlockNumber(i) .setParentHash(localBlockchain.getBlockHashByNumber(i - 1).get()); final Block block = blockDataGenerator.block(options); final List<TransactionReceipt> receipts = blockDataGenerator.receipts(block); localBlockchain.appendBlock(block, receipts); } }
@Test(expected = IllegalArgumentException.class) public void appendBlockWithMismatchedReceipts() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); receipts.add(gen.receipt()); blockchain.appendBlock(newBlock, receipts); }
@Test(expected = IllegalArgumentException.class) public void appendUnconnectedBlock() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(Hash.ZERO); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); blockchain.appendBlock(newBlock, receipts); }
private Hash appendBlockToBlockchain() { final long blockNumber = currentBlock.getHeader().getNumber() + 1; final Hash parentHash = currentBlock.getHash(); final BlockDataGenerator.BlockOptions options = new BlockDataGenerator.BlockOptions().setBlockNumber(blockNumber).setParentHash(parentHash); currentBlock = blockGenerator.block(options); filterManager.recordBlockEvent( BlockAddedEvent.createForHeadAdvancement(currentBlock), blockchainQueries.getBlockchain()); return currentBlock.getHash(); }
@Test public void appendBlock() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); blockchain.appendBlock(newBlock, receipts); assertBlockIsHead(blockchain, newBlock); assertTotalDifficultiesAreConsistent(blockchain, newBlock); assertThat(blockchain.getForks()).isEmpty(); }