private void assertTotalDifficultiesAreConsistent(final Blockchain blockchain, final Block head) { // Check that total difficulties are summed correctly long num = BlockHeader.GENESIS_BLOCK_NUMBER; UInt256 td = UInt256.of(0); while (num <= head.getHeader().getNumber()) { final Hash curHash = blockchain.getBlockHashByNumber(num).get(); final BlockHeader curHead = blockchain.getBlockHeader(curHash).get(); td = td.plus(curHead.getDifficulty()); assertEquals(td, blockchain.getTotalDifficultyByHash(curHash).get()); num += 1; } // Check reported chainhead td assertEquals(td, blockchain.getChainHead().getTotalDifficulty()); }
@Test public void ignoresFutureNewBlockAnnouncement() { blockchainUtil.importFirstBlocks(2); final Block futureBlock = blockchainUtil.getBlock(11); // Sanity check assertThat(blockchain.contains(futureBlock.getHash())).isFalse(); blockPropagationManager.start(); // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage futureAnnouncement = NewBlockMessage.create( futureBlock, fullBlockchain.getTotalDifficultyByHash(futureBlock.getHash()).get()); // Broadcast EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, futureAnnouncement); final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain); peer.respondWhile(responder, peer::hasOutstandingRequests); assertThat(blockchain.contains(futureBlock.getHash())).isFalse(); }
@Test public void importsAnnouncedNewBlocks_aheadOfChainInOrder() { blockchainUtil.importFirstBlocks(2); final Block nextBlock = blockchainUtil.getBlock(2); final Block nextNextBlock = blockchainUtil.getBlock(3); // Sanity check assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); assertThat(blockchain.contains(nextNextBlock.getHash())).isFalse(); blockPropagationManager.start(); // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage nextAnnouncement = NewBlockMessage.create( nextBlock, fullBlockchain.getTotalDifficultyByHash(nextBlock.getHash()).get()); final NewBlockMessage nextNextAnnouncement = NewBlockMessage.create( nextNextBlock, fullBlockchain.getTotalDifficultyByHash(nextNextBlock.getHash()).get()); final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain); // Broadcast first message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextAnnouncement); peer.respondWhile(responder, peer::hasOutstandingRequests); // Broadcast second message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextNextAnnouncement); peer.respondWhile(responder, peer::hasOutstandingRequests); assertThat(blockchain.contains(nextBlock.getHash())).isTrue(); assertThat(blockchain.contains(nextNextBlock.getHash())).isTrue(); }
@Test public void importsAnnouncedNewBlocks_aheadOfChainOutOfOrder() { blockchainUtil.importFirstBlocks(2); final Block nextBlock = blockchainUtil.getBlock(2); final Block nextNextBlock = blockchainUtil.getBlock(3); // Sanity check assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); assertThat(blockchain.contains(nextNextBlock.getHash())).isFalse(); blockPropagationManager.start(); // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage nextAnnouncement = NewBlockMessage.create( nextBlock, fullBlockchain.getTotalDifficultyByHash(nextBlock.getHash()).get()); final NewBlockMessage nextNextAnnouncement = NewBlockMessage.create( nextNextBlock, fullBlockchain.getTotalDifficultyByHash(nextNextBlock.getHash()).get()); final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain); // Broadcast second message first EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextNextAnnouncement); peer.respondWhile(responder, peer::hasOutstandingRequests); // Broadcast first message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextAnnouncement); peer.respondWhile(responder, peer::hasOutstandingRequests); assertThat(blockchain.contains(nextBlock.getHash())).isTrue(); assertThat(blockchain.contains(nextNextBlock.getHash())).isTrue(); }
@Test public void handlesPendingDuplicateAnnouncements() { blockchainUtil.importFirstBlocks(2); final Block nextBlock = blockchainUtil.getBlock(2); // Sanity check assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); blockPropagationManager.start(); // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockHashesMessage newBlockHash = NewBlockHashesMessage.create( Collections.singletonList( new NewBlockHash(nextBlock.getHash(), nextBlock.getHeader().getNumber()))); final NewBlockMessage newBlock = NewBlockMessage.create( nextBlock, fullBlockchain.getTotalDifficultyByHash(nextBlock.getHash()).get()); // Broadcast messages EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock); EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlockHash); EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock); // Respond final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain); peer.respondWhile(responder, peer::hasOutstandingRequests); assertThat(blockchain.contains(nextBlock.getHash())).isTrue(); verify(blockchain, times(1)).appendBlock(any(), any()); }
@Test public void handlesDuplicateAnnouncements() { blockchainUtil.importFirstBlocks(2); final Block nextBlock = blockchainUtil.getBlock(2); // Sanity check assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); blockPropagationManager.start(); // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockHashesMessage newBlockHash = NewBlockHashesMessage.create( Collections.singletonList( new NewBlockHash(nextBlock.getHash(), nextBlock.getHeader().getNumber()))); final NewBlockMessage newBlock = NewBlockMessage.create( nextBlock, fullBlockchain.getTotalDifficultyByHash(nextBlock.getHash()).get()); final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain); // Broadcast first message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock); peer.respondWhile(responder, peer::hasOutstandingRequests); // Broadcast duplicate EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlockHash); peer.respondWhile(responder, peer::hasOutstandingRequests); // Broadcast duplicate EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock); peer.respondWhile(responder, peer::hasOutstandingRequests); assertThat(blockchain.contains(nextBlock.getHash())).isTrue(); verify(blockchain, times(1)).appendBlock(any(), any()); }
final NewBlockMessage block2Msg = NewBlockMessage.create( block2, fullBlockchain.getTotalDifficultyByHash(block2.getHash()).get()); final NewBlockHashesMessage block3Msg = NewBlockHashesMessage.create( final NewBlockMessage block4Msg = NewBlockMessage.create( block4, fullBlockchain.getTotalDifficultyByHash(block4.getHash()).get()); final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain);
@Test public void updatesChainHeadWhenNewBlockMessageReceived() { blockchainUtil.importFirstBlocks(2); final Block nextBlock = blockchainUtil.getBlock(2); blockPropagationManager.start(); // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final UInt256 totalDifficulty = fullBlockchain.getTotalDifficultyByHash(nextBlock.getHash()).get(); final NewBlockMessage nextAnnouncement = NewBlockMessage.create(nextBlock, totalDifficulty); // Broadcast message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextAnnouncement); final Responder responder = RespondingEthPeer.blockchainResponder(fullBlockchain); peer.respondWhile(responder, peer::hasOutstandingRequests); assertThat(peer.getEthPeer().chainState().getBestBlock().getHash()) .isEqualTo(nextBlock.getHash()); assertThat(peer.getEthPeer().chainState().getEstimatedHeight()) .isEqualTo(nextBlock.getHeader().getNumber()); assertThat(peer.getEthPeer().chainState().getBestBlock().getTotalDifficulty()) .isEqualTo(totalDifficulty); }