use of org.hyperledger.besu.ethereum.util.RawBlockIterator in project besu by hyperledger.
the class RlpBlockExporterTest method exportBlocks_withRangeBeyondChainHead.
@Test
public void exportBlocks_withRangeBeyondChainHead() throws IOException {
final File outputPath = folder.newFile();
final RlpBlockExporter exporter = new RlpBlockExporter(blockchain);
final long lowerBound = chainHead - 10;
final long upperBound = chainHead + 10;
exporter.exportBlocks(outputPath, Optional.of(lowerBound), Optional.of(upperBound));
// Iterate over blocks and check that they match expectations
final RawBlockIterator blockIterator = getBlockIterator(outputPath.toPath());
long currentBlockNumber = lowerBound;
while (blockIterator.hasNext()) {
final Block actual = blockIterator.next();
final Block expected = getBlock(blockchain, currentBlockNumber);
assertThat(actual).isEqualTo(expected);
currentBlockNumber++;
}
// Check that we iterated to the end of the chain
assertThat(currentBlockNumber).isEqualTo(chainHead + 1L);
}
use of org.hyperledger.besu.ethereum.util.RawBlockIterator in project besu by hyperledger.
the class RlpBlockExporterTest method exportBlocks_withLowerBound.
@Test
public void exportBlocks_withLowerBound() throws IOException {
final File outputPath = folder.newFile();
final RlpBlockExporter exporter = new RlpBlockExporter(blockchain);
final long lowerBound = 990;
exporter.exportBlocks(outputPath, Optional.of(lowerBound), Optional.empty());
// Iterate over blocks and check that they match expectations
final RawBlockIterator blockIterator = getBlockIterator(outputPath.toPath());
long currentBlockNumber = lowerBound;
while (blockIterator.hasNext()) {
final Block actual = blockIterator.next();
final Block expected = getBlock(blockchain, currentBlockNumber);
assertThat(actual).isEqualTo(expected);
currentBlockNumber++;
}
// Check that we iterated to the end of the chain
assertThat(currentBlockNumber).isEqualTo(chainHead + 1L);
}
use of org.hyperledger.besu.ethereum.util.RawBlockIterator in project besu by hyperledger.
the class RlpBlockExporterTest method exportBlocks_withUpperAndLowerBounds.
@Test
public void exportBlocks_withUpperAndLowerBounds() throws IOException {
final File outputPath = folder.newFile();
final RlpBlockExporter exporter = new RlpBlockExporter(blockchain);
final long lowerBound = 5;
final long upperBound = 10;
exporter.exportBlocks(outputPath, Optional.of(lowerBound), Optional.of(upperBound));
// Iterate over blocks and check that they match expectations
final RawBlockIterator blockIterator = getBlockIterator(outputPath.toPath());
long currentBlockNumber = lowerBound;
while (blockIterator.hasNext()) {
final Block actual = blockIterator.next();
final Block expected = getBlock(blockchain, currentBlockNumber);
assertThat(actual).isEqualTo(expected);
currentBlockNumber++;
}
// Check that we iterated to the end of the chain
assertThat(currentBlockNumber).isEqualTo(upperBound);
}
use of org.hyperledger.besu.ethereum.util.RawBlockIterator in project besu by hyperledger.
the class BlockchainSetupUtil method create.
private static BlockchainSetupUtil create(final ChainResources chainResources, final DataStorageFormat storageFormat, final ProtocolScheduleProvider protocolScheduleProvider, final ProtocolContextProvider protocolContextProvider, final EthScheduler scheduler) {
final TemporaryFolder temp = new TemporaryFolder();
try {
temp.create();
final String genesisJson = Resources.toString(chainResources.getGenesisURL(), Charsets.UTF_8);
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisJson);
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile);
final GenesisState genesisState = GenesisState.fromJson(genesisJson, protocolSchedule);
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
final WorldStateArchive worldArchive = storageFormat == DataStorageFormat.BONSAI ? createBonsaiInMemoryWorldStateArchive(blockchain) : createInMemoryWorldStateArchive();
final TransactionPool transactionPool = mock(TransactionPool.class);
genesisState.writeStateTo(worldArchive.getMutable());
final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive);
final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI());
final List<Block> blocks = new ArrayList<>();
final BlockHeaderFunctions blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
try (final RawBlockIterator iterator = new RawBlockIterator(blocksPath, rlp -> BlockHeader.readFrom(rlp, blockHeaderFunctions))) {
while (iterator.hasNext()) {
blocks.add(iterator.next());
}
}
return new BlockchainSetupUtil(genesisState, blockchain, protocolContext, protocolSchedule, worldArchive, transactionPool, blocks, scheduler);
} catch (final IOException | URISyntaxException ex) {
throw new IllegalStateException(ex);
} finally {
temp.delete();
}
}
use of org.hyperledger.besu.ethereum.util.RawBlockIterator in project besu by hyperledger.
the class RlpBlockImporter method importBlockchain.
public RlpBlockImporter.ImportResult importBlockchain(final Path blocks, final BesuController besuController, final boolean skipPowValidation, final long startBlock, final long endBlock) throws IOException {
final ProtocolSchedule protocolSchedule = besuController.getProtocolSchedule();
final ProtocolContext context = besuController.getProtocolContext();
final MutableBlockchain blockchain = context.getBlockchain();
int count = 0;
try (final RawBlockIterator iterator = new RawBlockIterator(blocks, rlp -> BlockHeader.readFrom(rlp, ScheduleBasedBlockHeaderFunctions.create(protocolSchedule)))) {
BlockHeader previousHeader = null;
CompletableFuture<Void> previousBlockFuture = null;
final AtomicReference<Throwable> threadedException = new AtomicReference<>();
while (iterator.hasNext()) {
final Block block = iterator.next();
final BlockHeader header = block.getHeader();
final long blockNumber = header.getNumber();
if (blockNumber == BlockHeader.GENESIS_BLOCK_NUMBER || blockNumber < startBlock || blockNumber >= endBlock) {
continue;
}
if (blockchain.contains(header.getHash())) {
continue;
}
if (previousHeader == null) {
previousHeader = lookupPreviousHeader(blockchain, header);
}
final ProtocolSpec protocolSpec = protocolSchedule.getByBlockNumber(blockNumber);
final BlockHeader lastHeader = previousHeader;
final CompletableFuture<Void> validationFuture = CompletableFuture.runAsync(() -> validateBlock(protocolSpec, context, lastHeader, header, skipPowValidation), validationExecutor);
final CompletableFuture<Void> extractingFuture = CompletableFuture.runAsync(() -> extractSignatures(block));
final CompletableFuture<Void> calculationFutures;
if (previousBlockFuture == null) {
calculationFutures = extractingFuture;
} else {
calculationFutures = CompletableFuture.allOf(extractingFuture, previousBlockFuture);
}
try {
do {
final Throwable t = (Exception) threadedException.get();
if (t != null) {
throw new RuntimeException("Error importing block " + header.getNumber(), t);
}
} while (!blockBacklog.tryAcquire(1, SECONDS));
} catch (final InterruptedException e) {
LOG.error("Interrupted adding to backlog.", e);
break;
}
previousBlockFuture = validationFuture.runAfterBothAsync(calculationFutures, () -> evaluateBlock(context, block, header, protocolSpec, skipPowValidation), importExecutor);
previousBlockFuture.exceptionally(exception -> {
threadedException.set(exception);
return null;
});
++count;
previousHeader = header;
}
if (previousBlockFuture != null) {
previousBlockFuture.join();
}
logProgress(blockchain.getChainHeadBlockNumber());
return new RlpBlockImporter.ImportResult(blockchain.getChainHead().getTotalDifficulty(), count);
}
}
Aggregations