mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-06 19:53:56 -05:00
7935: add era1 format to blocks importer (#8352)
* Refactor to use clock to validate expiry Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * 7935: Finish unit testing E2StoreReader Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Build out E2StoreReader and associated files Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Spotless Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Add javadoc to new util module classes Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Implement Era1 block import sub command Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Remove unnecessary e2 and era file stuff Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Rename files to be era1 specific Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Rename e2 package to era1 Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Spotless Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Rename Era1StoreReaderListener to Era1ReaderListener Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Clean up after merge Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Set up Era1BlockImporter to enable FAST sync and variations upon besu running Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Use bouncycastle for little endian to long conversion Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Rename slot related variables to blockIndex Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Spotless Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Fix broken unit test Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Fix AT compilation Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Fix javadoc Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Rework Era1BlockImporter to use appropriate data directory. Add unit test Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Fix javadoc Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * changelog Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Add era1 files to .gitattributes as binary file type Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> * Remove pivot block header file creation from Era1BlockImporter Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> --------- Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net> Signed-off-by: Matilda-Clerke <matilda.clerke@consensys.net>
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -17,4 +17,5 @@
|
||||
*.p12 binary
|
||||
*.db binary
|
||||
*.woff2 binary
|
||||
*.era1 binary
|
||||
goss-linux-amd64 binary
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
- Update `eth_getLogs` to return a `Block not found` error when the requested block is not found. [#8290](https://github.com/hyperledger/besu/pull/8290)
|
||||
- Change `Invalid block, unable to parse RLP` RPC error message to `Invalid block param (block not found)` [#8328](https://github.com/hyperledger/besu/pull/8328)
|
||||
- Support pending transaction score when saving and restoring txpool [#8363](https://github.com/hyperledger/besu/pull/8363)
|
||||
- Add era1 format to blocks import subcommand [#7935](https://github.com/hyperledger/besu/issues/7935)
|
||||
|
||||
### Bug fixes
|
||||
- Add missing RPC method `debug_accountRange` to `RpcMethod.java` so this method can be used with `--rpc-http-api-method-no-auth` [#8153](https://github.com/hyperledger/besu/issues/8153)
|
||||
|
||||
@@ -19,6 +19,7 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;
|
||||
import org.hyperledger.besu.Runner;
|
||||
import org.hyperledger.besu.RunnerBuilder;
|
||||
import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.Era1BlockImporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.BesuCommand;
|
||||
@@ -632,6 +633,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
new BesuCommand(
|
||||
RlpBlockImporter::new,
|
||||
JsonBlockImporter::new,
|
||||
Era1BlockImporter::new,
|
||||
RlpBlockExporter::new,
|
||||
new RunnerBuilder(),
|
||||
new BesuController.Builder(),
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright contributors to Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.chainimport;
|
||||
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.core.BlockImporter;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.BlockImportResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode;
|
||||
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
import org.hyperledger.besu.util.era1.Era1BlockIndex;
|
||||
import org.hyperledger.besu.util.era1.Era1ExecutionBlockBody;
|
||||
import org.hyperledger.besu.util.era1.Era1ExecutionBlockHeader;
|
||||
import org.hyperledger.besu.util.era1.Era1ExecutionBlockReceipts;
|
||||
import org.hyperledger.besu.util.era1.Era1Reader;
|
||||
import org.hyperledger.besu.util.era1.Era1ReaderListener;
|
||||
import org.hyperledger.besu.util.snappy.SnappyFactory;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Tool for importing era1-encoded block data, headers, and transaction receipts from era1 files.
|
||||
*/
|
||||
public class Era1BlockImporter implements Closeable {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Era1BlockImporter.class);
|
||||
|
||||
private static final int ERA1_BLOCK_COUNT_MAX = 8192;
|
||||
private static final int IMPORT_COUNT_FOR_LOG_UPDATE = 1000;
|
||||
|
||||
/** Default Constructor. */
|
||||
public Era1BlockImporter() {}
|
||||
|
||||
/**
|
||||
* Imports the blocks, headers, and transaction receipts from the file found at the supplied path
|
||||
*
|
||||
* @param controller The BesuController
|
||||
* @param path The path
|
||||
* @throws IOException IOException
|
||||
* @throws ExecutionException ExecutionException
|
||||
* @throws InterruptedException InterruptedException
|
||||
* @throws TimeoutException TimeoutException
|
||||
*/
|
||||
public void importBlocks(final BesuController controller, final Path path)
|
||||
throws IOException, ExecutionException, InterruptedException, TimeoutException {
|
||||
final ProtocolSchedule protocolSchedule = controller.getProtocolSchedule();
|
||||
final BlockHeaderFunctions blockHeaderFunctions =
|
||||
ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
|
||||
final ProtocolContext context = controller.getProtocolContext();
|
||||
|
||||
Era1Reader reader = new Era1Reader(new SnappyFactory());
|
||||
|
||||
final List<Future<BlockHeader>> headersFutures = new ArrayList<>(ERA1_BLOCK_COUNT_MAX);
|
||||
final List<Future<BlockBody>> bodiesFutures = new ArrayList<>(ERA1_BLOCK_COUNT_MAX);
|
||||
final List<Future<List<TransactionReceipt>>> receiptsFutures =
|
||||
new ArrayList<>(ERA1_BLOCK_COUNT_MAX);
|
||||
reader.read(
|
||||
new FileInputStream(path.toFile()),
|
||||
new Era1ReaderListener() {
|
||||
|
||||
@Override
|
||||
public void handleExecutionBlockHeader(
|
||||
final Era1ExecutionBlockHeader executionBlockHeader) {
|
||||
headersFutures.add(
|
||||
CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
BlockHeader.readFrom(
|
||||
new BytesValueRLPInput(
|
||||
Bytes.wrap(executionBlockHeader.header()), false),
|
||||
blockHeaderFunctions)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleExecutionBlockBody(final Era1ExecutionBlockBody executionBlockBody) {
|
||||
bodiesFutures.add(
|
||||
CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
BlockBody.readWrappedBodyFrom(
|
||||
new BytesValueRLPInput(Bytes.wrap(executionBlockBody.block()), false),
|
||||
blockHeaderFunctions,
|
||||
true)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleExecutionBlockReceipts(
|
||||
final Era1ExecutionBlockReceipts executionBlockReceipts) {
|
||||
receiptsFutures.add(
|
||||
CompletableFuture.supplyAsync(
|
||||
() -> {
|
||||
RLPInput input =
|
||||
new BytesValueRLPInput(
|
||||
Bytes.wrap(executionBlockReceipts.receipts()), false);
|
||||
final List<TransactionReceipt> receiptsForBlock = new ArrayList<>();
|
||||
input.readList((in) -> receiptsForBlock.add(TransactionReceipt.readFrom(in)));
|
||||
return receiptsForBlock;
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleBlockIndex(final Era1BlockIndex blockIndex) {
|
||||
// not really necessary, do nothing
|
||||
}
|
||||
});
|
||||
|
||||
LOG.info("Read {} blocks, now importing", headersFutures.size());
|
||||
|
||||
Block block = null;
|
||||
for (int i = 0; i < headersFutures.size(); i++) {
|
||||
BlockHeader blockHeader = headersFutures.get(i).get(10, TimeUnit.SECONDS);
|
||||
BlockImporter blockImporter =
|
||||
protocolSchedule.getByBlockHeader(blockHeader).getBlockImporter();
|
||||
block = new Block(blockHeader, bodiesFutures.get(i).get(10, TimeUnit.SECONDS));
|
||||
|
||||
BlockImportResult importResult =
|
||||
blockImporter.importBlockForSyncing(
|
||||
context,
|
||||
block,
|
||||
receiptsFutures.get(i).get(10, TimeUnit.SECONDS),
|
||||
HeaderValidationMode.NONE,
|
||||
HeaderValidationMode.NONE,
|
||||
BodyValidationMode.NONE,
|
||||
false);
|
||||
if (importResult.getStatus() != BlockImportResult.BlockImportStatus.IMPORTED) {
|
||||
LOG.warn(
|
||||
"Failed to import block {} due to {}",
|
||||
blockHeader.getNumber(),
|
||||
importResult.getStatus());
|
||||
} else if (i % IMPORT_COUNT_FOR_LOG_UPDATE == 0) {
|
||||
LOG.info("{}/{} blocks imported", i, headersFutures.size());
|
||||
}
|
||||
}
|
||||
LOG.info("Done importing {} blocks", headersFutures.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.BesuInfo;
|
||||
import org.hyperledger.besu.Runner;
|
||||
import org.hyperledger.besu.RunnerBuilder;
|
||||
import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.Era1BlockImporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
@@ -284,6 +285,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
|
||||
private final Supplier<RlpBlockImporter> rlpBlockImporter;
|
||||
private final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory;
|
||||
private final Supplier<Era1BlockImporter> era1BlockImporter;
|
||||
private final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory;
|
||||
|
||||
// Unstable CLI options
|
||||
@@ -719,6 +721,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
*
|
||||
* @param rlpBlockImporter RlpBlockImporter supplier
|
||||
* @param jsonBlockImporterFactory instance of {@code Function<BesuController, JsonBlockImporter>}
|
||||
* @param era1BlockImporter Era1BlockImporter supplier
|
||||
* @param rlpBlockExporterFactory instance of {@code Function<Blockchain, RlpBlockExporter>}
|
||||
* @param runnerBuilder instance of RunnerBuilder
|
||||
* @param controllerBuilder instance of BesuController.Builder
|
||||
@@ -729,6 +732,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
public BesuCommand(
|
||||
final Supplier<RlpBlockImporter> rlpBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Supplier<Era1BlockImporter> era1BlockImporter,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
final RunnerBuilder runnerBuilder,
|
||||
final BesuController.Builder controllerBuilder,
|
||||
@@ -738,6 +742,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
this(
|
||||
rlpBlockImporter,
|
||||
jsonBlockImporterFactory,
|
||||
era1BlockImporter,
|
||||
rlpBlockExporterFactory,
|
||||
runnerBuilder,
|
||||
controllerBuilder,
|
||||
@@ -760,6 +765,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
*
|
||||
* @param rlpBlockImporter RlpBlockImporter supplier
|
||||
* @param jsonBlockImporterFactory instance of {@code Function<BesuController, JsonBlockImporter>}
|
||||
* @param era1BlockImporter Era1BlockImporter supplier
|
||||
* @param rlpBlockExporterFactory instance of {@code Function<Blockchain, RlpBlockExporter>}
|
||||
* @param runnerBuilder instance of RunnerBuilder
|
||||
* @param controllerBuilder instance of BesuController.Builder
|
||||
@@ -780,6 +786,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
protected BesuCommand(
|
||||
final Supplier<RlpBlockImporter> rlpBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Supplier<Era1BlockImporter> era1BlockImporter,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
final RunnerBuilder runnerBuilder,
|
||||
final BesuController.Builder controllerBuilder,
|
||||
@@ -798,8 +805,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
|
||||
this.logger = commandLogger;
|
||||
this.rlpBlockImporter = rlpBlockImporter;
|
||||
this.rlpBlockExporterFactory = rlpBlockExporterFactory;
|
||||
this.jsonBlockImporterFactory = jsonBlockImporterFactory;
|
||||
this.era1BlockImporter = era1BlockImporter;
|
||||
this.rlpBlockExporterFactory = rlpBlockExporterFactory;
|
||||
this.runnerBuilder = runnerBuilder;
|
||||
this.controllerBuilder = controllerBuilder;
|
||||
this.besuPluginContext = besuPluginContext;
|
||||
@@ -1100,6 +1108,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
new BlocksSubCommand(
|
||||
rlpBlockImporter,
|
||||
jsonBlockImporterFactory,
|
||||
era1BlockImporter,
|
||||
rlpBlockExporterFactory,
|
||||
commandLine.getOut()));
|
||||
commandLine.addSubcommand(
|
||||
|
||||
@@ -19,5 +19,7 @@ public enum BlockImportFormat {
|
||||
/** RLP block import format. */
|
||||
RLP,
|
||||
/** Json block import format. */
|
||||
JSON
|
||||
JSON,
|
||||
/** Era1 block import format. */
|
||||
ERA1,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.hyperledger.besu.cli.subcommands.blocks.BlocksSubCommand.COMMAND_NAME;
|
||||
|
||||
import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.Era1BlockImporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.BesuCommand;
|
||||
@@ -51,6 +52,7 @@ import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -92,6 +94,7 @@ public class BlocksSubCommand implements Runnable {
|
||||
|
||||
private final Supplier<RlpBlockImporter> rlpBlockImporter;
|
||||
private final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory;
|
||||
private final Supplier<Era1BlockImporter> era1BlockImporter;
|
||||
private final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory;
|
||||
|
||||
private final PrintWriter out;
|
||||
@@ -101,17 +104,20 @@ public class BlocksSubCommand implements Runnable {
|
||||
*
|
||||
* @param rlpBlockImporter the RLP block importer
|
||||
* @param jsonBlockImporterFactory the Json block importer factory
|
||||
* @param era1BlockImporter the era1 block importer supplier
|
||||
* @param rlpBlockExporterFactory the RLP block exporter factory
|
||||
* @param out Instance of PrintWriter where command usage will be written.
|
||||
*/
|
||||
public BlocksSubCommand(
|
||||
final Supplier<RlpBlockImporter> rlpBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Supplier<Era1BlockImporter> era1BlockImporter,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
final PrintWriter out) {
|
||||
this.rlpBlockImporter = rlpBlockImporter;
|
||||
this.rlpBlockExporterFactory = rlpBlockExporterFactory;
|
||||
this.jsonBlockImporterFactory = jsonBlockImporterFactory;
|
||||
this.era1BlockImporter = era1BlockImporter;
|
||||
this.rlpBlockExporterFactory = rlpBlockExporterFactory;
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
@@ -198,6 +204,7 @@ public class BlocksSubCommand implements Runnable {
|
||||
checkCommand(parentCommand);
|
||||
checkNotNull(parentCommand.rlpBlockImporter);
|
||||
checkNotNull(parentCommand.jsonBlockImporterFactory);
|
||||
checkNotNull(parentCommand.era1BlockImporter);
|
||||
if (blockImportFiles.isEmpty()) {
|
||||
throw new ParameterException(spec.commandLine(), "No files specified to import.");
|
||||
}
|
||||
@@ -214,12 +221,9 @@ public class BlocksSubCommand implements Runnable {
|
||||
try {
|
||||
LOG.info("Importing from {}", path);
|
||||
switch (format) {
|
||||
case RLP:
|
||||
importRlpBlocks(controller, path);
|
||||
break;
|
||||
case JSON:
|
||||
importJsonBlocks(controller, path);
|
||||
break;
|
||||
case RLP -> importRlpBlocks(controller, path);
|
||||
case JSON -> importJsonBlocks(controller, path);
|
||||
case ERA1 -> importEra1Blocks(controller, path);
|
||||
}
|
||||
} catch (final FileNotFoundException e) {
|
||||
if (blockImportFiles.size() == 1) {
|
||||
@@ -297,6 +301,14 @@ public class BlocksSubCommand implements Runnable {
|
||||
.get()
|
||||
.importBlockchain(path, controller, skipPow, startBlock, endBlock);
|
||||
}
|
||||
|
||||
private void importEra1Blocks(final BesuController controller, final Path path)
|
||||
throws IOException,
|
||||
java.util.concurrent.ExecutionException,
|
||||
InterruptedException,
|
||||
TimeoutException {
|
||||
parentCommand.era1BlockImporter.get().importBlocks(controller, path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.hyperledger.besu.components;
|
||||
import org.hyperledger.besu.Besu;
|
||||
import org.hyperledger.besu.RunnerBuilder;
|
||||
import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.Era1BlockImporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.BesuCommand;
|
||||
@@ -50,6 +51,7 @@ public class BesuCommandModule {
|
||||
new BesuCommand(
|
||||
RlpBlockImporter::new,
|
||||
JsonBlockImporter::new,
|
||||
Era1BlockImporter::new,
|
||||
RlpBlockExporter::new,
|
||||
new RunnerBuilder(),
|
||||
new BesuController.Builder(),
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright contributors to Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.chainimport;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.cli.config.NetworkName;
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
||||
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
|
||||
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
||||
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
|
||||
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
|
||||
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.testutil.BlockTestUtil;
|
||||
import org.hyperledger.besu.testutil.TestClock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
public class Era1BlockImporterTest {
|
||||
@TempDir Path dataDirectory;
|
||||
|
||||
private final Era1BlockImporter era1BlockImporter = new Era1BlockImporter();
|
||||
|
||||
@Test
|
||||
public void testImport()
|
||||
throws IOException,
|
||||
ExecutionException,
|
||||
InterruptedException,
|
||||
TimeoutException,
|
||||
URISyntaxException {
|
||||
final Path source =
|
||||
Path.of(
|
||||
BlockTestUtil.class
|
||||
.getClassLoader()
|
||||
.getResource("mainnet-00000-5ec1ffb8.era1")
|
||||
.toURI());
|
||||
final BesuController targetController =
|
||||
new BesuController.Builder()
|
||||
.fromEthNetworkConfig(
|
||||
EthNetworkConfig.getNetworkConfig(NetworkName.MAINNET), SyncMode.FAST)
|
||||
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
|
||||
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
|
||||
.storageProvider(new InMemoryKeyValueStorageProvider())
|
||||
.networkId(BigInteger.ONE)
|
||||
.miningParameters(MiningConfiguration.newDefault())
|
||||
.nodeKey(NodeKeyUtils.generate())
|
||||
.metricsSystem(new NoOpMetricsSystem())
|
||||
.privacyParameters(PrivacyParameters.DEFAULT)
|
||||
.clock(TestClock.fixed())
|
||||
.transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
|
||||
.evmConfiguration(EvmConfiguration.DEFAULT)
|
||||
.networkConfiguration(NetworkingConfiguration.create())
|
||||
.besuComponent(mock(BesuComponent.class))
|
||||
.apiConfiguration(ImmutableApiConfiguration.builder().build())
|
||||
.dataDirectory(dataDirectory)
|
||||
.build();
|
||||
era1BlockImporter.importBlocks(targetController, source);
|
||||
|
||||
Blockchain blockchain = targetController.getProtocolContext().getBlockchain();
|
||||
BlockHeader chainHeadHeader = blockchain.getChainHeadHeader();
|
||||
Assertions.assertEquals(8191, chainHeadHeader.getNumber());
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
|
||||
import org.hyperledger.besu.Runner;
|
||||
import org.hyperledger.besu.RunnerBuilder;
|
||||
import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.Era1BlockImporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
@@ -216,6 +217,7 @@ public abstract class CommandTestAbstract {
|
||||
@Mock protected RlpBlockExporter rlpBlockExporter;
|
||||
@Mock protected JsonBlockImporter jsonBlockImporter;
|
||||
@Mock protected RlpBlockImporter rlpBlockImporter;
|
||||
@Mock protected Era1BlockImporter era1BlockImporter;
|
||||
@Mock protected StorageServiceImpl storageService;
|
||||
@Mock protected TransactionSelectionServiceImpl txSelectionService;
|
||||
@Mock protected SecurityModuleServiceImpl securityModuleService;
|
||||
@@ -472,6 +474,7 @@ public abstract class CommandTestAbstract {
|
||||
return new TestBesuCommandWithRequiredOption(
|
||||
() -> rlpBlockImporter,
|
||||
this::jsonBlockImporterFactory,
|
||||
() -> era1BlockImporter,
|
||||
(blockchain) -> rlpBlockExporter,
|
||||
mockRunnerBuilder,
|
||||
mockControllerBuilderFactory,
|
||||
@@ -485,6 +488,7 @@ public abstract class CommandTestAbstract {
|
||||
return new TestBesuCommand(
|
||||
() -> rlpBlockImporter,
|
||||
this::jsonBlockImporterFactory,
|
||||
() -> era1BlockImporter,
|
||||
(blockchain) -> rlpBlockExporter,
|
||||
mockRunnerBuilder,
|
||||
mockControllerBuilderFactory,
|
||||
@@ -498,6 +502,7 @@ public abstract class CommandTestAbstract {
|
||||
return new TestBesuCommandWithoutPortCheck(
|
||||
() -> rlpBlockImporter,
|
||||
this::jsonBlockImporterFactory,
|
||||
() -> era1BlockImporter,
|
||||
(blockchain) -> rlpBlockExporter,
|
||||
mockRunnerBuilder,
|
||||
mockControllerBuilderFactory,
|
||||
@@ -538,6 +543,7 @@ public abstract class CommandTestAbstract {
|
||||
TestBesuCommand(
|
||||
final Supplier<RlpBlockImporter> mockBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Supplier<Era1BlockImporter> era1BlockImporter,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
final RunnerBuilder mockRunnerBuilder,
|
||||
final BesuController.Builder controllerBuilderFactory,
|
||||
@@ -550,6 +556,7 @@ public abstract class CommandTestAbstract {
|
||||
super(
|
||||
mockBlockImporter,
|
||||
jsonBlockImporterFactory,
|
||||
era1BlockImporter,
|
||||
rlpBlockExporterFactory,
|
||||
mockRunnerBuilder,
|
||||
controllerBuilderFactory,
|
||||
@@ -635,6 +642,7 @@ public abstract class CommandTestAbstract {
|
||||
TestBesuCommandWithRequiredOption(
|
||||
final Supplier<RlpBlockImporter> mockBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Supplier<Era1BlockImporter> era1BlockImporter,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
final RunnerBuilder mockRunnerBuilder,
|
||||
final BesuController.Builder controllerBuilderFactory,
|
||||
@@ -647,6 +655,7 @@ public abstract class CommandTestAbstract {
|
||||
super(
|
||||
mockBlockImporter,
|
||||
jsonBlockImporterFactory,
|
||||
era1BlockImporter,
|
||||
rlpBlockExporterFactory,
|
||||
mockRunnerBuilder,
|
||||
controllerBuilderFactory,
|
||||
@@ -669,6 +678,7 @@ public abstract class CommandTestAbstract {
|
||||
TestBesuCommandWithoutPortCheck(
|
||||
final Supplier<RlpBlockImporter> mockBlockImporter,
|
||||
final Function<BesuController, JsonBlockImporter> jsonBlockImporterFactory,
|
||||
final Supplier<Era1BlockImporter> era1BlockImporter,
|
||||
final Function<Blockchain, RlpBlockExporter> rlpBlockExporterFactory,
|
||||
final RunnerBuilder mockRunnerBuilder,
|
||||
final BesuController.Builder controllerBuilderFactory,
|
||||
@@ -681,6 +691,7 @@ public abstract class CommandTestAbstract {
|
||||
super(
|
||||
mockBlockImporter,
|
||||
jsonBlockImporterFactory,
|
||||
era1BlockImporter,
|
||||
rlpBlockExporterFactory,
|
||||
mockRunnerBuilder,
|
||||
controllerBuilderFactory,
|
||||
|
||||
@@ -72,7 +72,7 @@ public class BlocksSubCommandTest extends CommandTestAbstract {
|
||||
+ " (exclusive). If not specified all blocks after\n"
|
||||
+ " the start block will be imported.\n"
|
||||
+ " --format=<format> The type of data to be imported, possible values\n"
|
||||
+ " are: RLP, JSON (default: RLP).\n"
|
||||
+ " are: RLP, JSON, ERA1 (default: RLP).\n"
|
||||
+ " --from[=<FILE>...] File containing blocks to import.\n"
|
||||
+ " -h, --help Show this help message and exit.\n"
|
||||
+ " --run Start besu after importing.\n"
|
||||
|
||||
BIN
besu/src/test/resources/mainnet-00000-5ec1ffb8.era1
Executable file
BIN
besu/src/test/resources/mainnet-00000-5ec1ffb8.era1
Executable file
Binary file not shown.
@@ -252,7 +252,10 @@ public class BlockHeader extends SealableBlockHeader
|
||||
public static BlockHeader readFrom(
|
||||
final RLPInput input, final BlockHeaderFunctions blockHeaderFunctions) {
|
||||
final RLPInput headerRlp = input.readAsRlp();
|
||||
headerRlp.enterList();
|
||||
if (headerRlp.enterList() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Hash parentHash = Hash.wrap(headerRlp.readBytes32());
|
||||
final Hash ommersHash = Hash.wrap(headerRlp.readBytes32());
|
||||
final Address coinbase = Address.readFrom(headerRlp);
|
||||
|
||||
Reference in New Issue
Block a user