private BlockHeader lookupPreviousHeader( final MutableBlockchain blockchain, final BlockHeader header) { return blockchain .getBlockHeader(header.getParentHash()) .orElseThrow( () -> new IllegalStateException( String.format( "Block %s does not connect to the existing chain. Current chain head %s", header.getNumber(), blockchain.getChainHeadBlockNumber()))); }
@Test public void buildVoteTallyByExtractingValidatorsFromEpochBlock() { when(serialiser.validatorsInBlock(any())).thenReturn(asList(subject, validator1)); final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); final BlockHeader header = headerBuilder.buildHeader(); when(blockchain.getChainHeadBlockNumber()).thenReturn(EPOCH_LENGTH); when(blockchain.getBlockHeader(EPOCH_LENGTH)).thenReturn(Optional.of(header)); final VoteTally voteTally = updater.buildVoteTallyFromBlockchain(blockchain); assertThat(voteTally.getValidators()).containsExactly(subject, validator1); }
@Test public void buildVoteTallyByExtractingValidatorsFromGenesisBlock() { when(serialiser.validatorsInBlock(any())).thenReturn(asList(subject, validator1)); final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); headerBuilder.number(0); final BlockHeader header = headerBuilder.buildHeader(); when(blockchain.getChainHeadBlockNumber()).thenReturn(EPOCH_LENGTH); when(blockchain.getBlockHeader(EPOCH_LENGTH)).thenReturn(Optional.of(header)); final VoteTally voteTally = updater.buildVoteTallyFromBlockchain(blockchain); assertThat(voteTally.getValidators()).containsExactly(subject, validator1); }
@Test public void addVotesFromBlocksAfterMostRecentEpoch() { when(serialiser.validatorsInBlock(any())).thenReturn(asList(validator1)); when(serialiser.extractVoteFromHeader(any())) .thenReturn(Optional.of(new ValidatorVote(ADD, proposerAddress, subject))); final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); headerBuilder.number(EPOCH_LENGTH); final BlockHeader epochHeader = headerBuilder.buildHeader(); headerBuilder.number(EPOCH_LENGTH + 1); final BlockHeader voteBlockHeader = headerBuilder.buildHeader(); when(blockchain.getChainHeadBlockNumber()).thenReturn(EPOCH_LENGTH + 1); when(blockchain.getBlockHeader(EPOCH_LENGTH)).thenReturn(Optional.of(epochHeader)); when(blockchain.getBlockHeader(EPOCH_LENGTH + 1)).thenReturn(Optional.of(voteBlockHeader)); final VoteTally voteTally = updater.buildVoteTallyFromBlockchain(blockchain); assertThat(voteTally.getValidators()).containsExactly(subject, validator1); } }
@Test public void getOmmerCountForInvalidNumber() { final BlockchainWithData data = setupBlockchain(3); final BlockchainQueries queries = data.blockchainQueries; final long invalidNumber = data.blockchain.getChainHeadBlockNumber() + 10; final Optional<Integer> result = queries.getOmmerCount(invalidNumber); assertFalse(result.isPresent()); }
@Test public void syncsToBetterChain_singleSegment() { otherBlockchainSetup.importFirstBlocks(5); final long targetBlock = otherBlockchain.getChainHeadBlockNumber(); // Sanity check assertThat(targetBlock).isGreaterThan(localBlockchain.getChainHeadBlockNumber()); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, otherBlockchain); final Responder responder = RespondingEthPeer.blockchainResponder(otherBlockchain); final SynchronizerConfiguration syncConfig = SynchronizerConfiguration.builder() .downloaderChainSegmentSize(10) .build() .validated(localBlockchain); final FullSyncDownloader<?> downloader = downloader(syncConfig); downloader.start(); while (!syncState.syncTarget().isPresent()) { peer.respond(responder); } assertThat(syncState.syncTarget()).isPresent(); assertThat(syncState.syncTarget().get().peer()).isEqualTo(peer.getEthPeer()); while (localBlockchain.getChainHeadBlockNumber() < targetBlock) { peer.respond(responder); } assertThat(localBlockchain.getChainHeadBlockNumber()).isEqualTo(targetBlock); }
@Test public void syncsToBetterChain_singleSegmentOnBoundary() { otherBlockchainSetup.importFirstBlocks(5); final long targetBlock = otherBlockchain.getChainHeadBlockNumber(); // Sanity check assertThat(targetBlock).isGreaterThan(localBlockchain.getChainHeadBlockNumber()); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, otherBlockchain); final Responder responder = RespondingEthPeer.blockchainResponder(otherBlockchain); final SynchronizerConfiguration syncConfig = SynchronizerConfiguration.builder() .downloaderChainSegmentSize(4) .build() .validated(localBlockchain); final FullSyncDownloader<?> downloader = downloader(syncConfig); downloader.start(); while (!syncState.syncTarget().isPresent()) { peer.respond(responder); } assertThat(syncState.syncTarget()).isPresent(); assertThat(syncState.syncTarget().get().peer()).isEqualTo(peer.getEthPeer()); while (localBlockchain.getChainHeadBlockNumber() < targetBlock) { peer.respond(responder); } assertThat(localBlockchain.getChainHeadBlockNumber()).isEqualTo(targetBlock); }
@Test public void syncsToBetterChain_multipleSegments() { otherBlockchainSetup.importFirstBlocks(15); final long targetBlock = otherBlockchain.getChainHeadBlockNumber(); // Sanity check assertThat(targetBlock).isGreaterThan(localBlockchain.getChainHeadBlockNumber()); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, otherBlockchain); final Responder responder = RespondingEthPeer.blockchainResponder(otherBlockchain); final SynchronizerConfiguration syncConfig = SynchronizerConfiguration.builder() .downloaderChainSegmentSize(10) .build() .validated(localBlockchain); final FullSyncDownloader<?> downloader = downloader(syncConfig); downloader.start(); while (!syncState.syncTarget().isPresent()) { peer.respond(responder); } assertThat(syncState.syncTarget()).isPresent(); assertThat(syncState.syncTarget().get().peer()).isEqualTo(peer.getEthPeer()); while (localBlockchain.getChainHeadBlockNumber() < targetBlock) { peer.respond(responder); } assertThat(localBlockchain.getChainHeadBlockNumber()).isEqualTo(targetBlock); }
@Test public void shouldRequestHeaderChainHeadWhenNewPeerConnects() { final Responder responder = RespondingEthPeer.blockchainResponder( blockchainSetupUtil.getBlockchain(), blockchainSetupUtil.getWorldArchive()); chainHeadTracker.onPeerConnected(respondingPeer.getEthPeer()); assertThat(chainHeadState().getEstimatedHeight()).isZero(); respondingPeer.respond(responder); assertThat(chainHeadState().getEstimatedHeight()) .isEqualTo(blockchain.getChainHeadBlockNumber()); }
@Test public void shouldCheckTrialingPeerLimits() { final Responder responder = RespondingEthPeer.blockchainResponder( blockchainSetupUtil.getBlockchain(), blockchainSetupUtil.getWorldArchive()); chainHeadTracker.onPeerConnected(respondingPeer.getEthPeer()); assertThat(chainHeadState().getEstimatedHeight()).isZero(); respondingPeer.respond(responder); assertThat(chainHeadState().getEstimatedHeight()) .isEqualTo(blockchain.getChainHeadBlockNumber()); }
@Test public void doesNotSyncToWorseChain() { localBlockchainSetup.importFirstBlocks(15); // Sanity check assertThat(localBlockchain.getChainHeadBlockNumber()) .isGreaterThan(BlockHeader.GENESIS_BLOCK_NUMBER); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, otherBlockchain); final Responder responder = RespondingEthPeer.blockchainResponder(otherBlockchain); final FullSyncDownloader<?> downloader = downloader(); downloader.start(); peer.respond(responder); assertThat(syncState.syncTarget()).isNotPresent(); while (peer.hasOutstandingRequests()) { peer.respond(responder); } assertThat(syncState.syncTarget()).isNotPresent(); verify(localBlockchain, times(0)).appendBlock(any(), any()); }
assertThat(targetBlock).isGreaterThan(localBlockchain.getChainHeadBlockNumber()); assertThat(otherBlockchain.contains(localBlockchain.getChainHead().getHash())).isFalse(); downloader.start(); while (localBlockchain.getChainHeadBlockNumber() < targetBlock) { peer.respond(responder); assertThat(localBlockchain.getChainHeadBlockNumber()).isEqualTo(targetBlock);
private void importBlocks(final List<Block> blocks) { for (final Block block : blocks) { if (block.getHeader().getNumber() == BlockHeader.GENESIS_BLOCK_NUMBER) { continue; } final ProtocolSpec<C> protocolSpec = protocolSchedule.getByBlockNumber(block.getHeader().getNumber()); final BlockImporter<C> blockImporter = protocolSpec.getBlockImporter(); final boolean result = blockImporter.importBlock(protocolContext, block, HeaderValidationMode.FULL); if (!result) { throw new IllegalStateException("Unable to import block " + block.getHeader().getNumber()); } } this.maxBlockNumber = blockchain.getChainHeadBlockNumber(); } }
final long targetBlock = otherBlockchain.getChainHeadBlockNumber(); assertThat(targetBlock).isGreaterThan(localBlockchain.getChainHeadBlockNumber()); assertThat(syncState.syncTarget().get().peer()).isEqualTo(bestPeer.getEthPeer()); while (localBlockchain.getChainHeadBlockNumber() < bestPeerChainHead) {
gen.block(BlockOptions.create().setBlockNumber(blockchain.getChainHeadBlockNumber())); blockchainUtil.importBlockAtIndex((int) blockchain.getChainHeadBlockNumber() + 1); blockchainUtil.importBlockAtIndex((int) blockchain.getChainHeadBlockNumber() + 1); assertThat(blockchain.contains(blockToPurge.getHash())).isFalse(); assertThat(pendingBlocks.contains(blockToPurge.getHash())).isFalse();
@Test public void recoversFromSyncTargetDisconnect() { localBlockchainSetup.importFirstBlocks(2); final long localChainHeadAtStart = localBlockchain.getChainHeadBlockNumber(); otherBlockchainSetup.importAllBlocks(); final long targetBlock = otherBlockchain.getChainHeadBlockNumber(); assertThat(targetBlock).isGreaterThan(localBlockchain.getChainHeadBlockNumber()); secondBestPeer.respond(secondBestResponder); assertThat(localBlockchain.getChainHeadBlockNumber()) .isNotEqualTo(localChainHeadAtStart); }); () -> { secondBestPeer.respond(secondBestResponder); assertThat(localBlockchain.getChainHeadBlockNumber()) .isEqualTo(secondBestPeerChainHead); });
for (long i = 0L; i <= remoteBlockchain.getChainHeadBlockNumber(); i++) { headers.add(remoteBlockchain.getBlockHeader(i).get());