BlockTestUtil.java
/*
* Copyright ConsenSys AG.
*
* 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.testutil;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.function.Supplier;
import com.google.common.base.Preconditions;
import com.google.common.base.Suppliers;
import com.google.common.io.Resources;
/** The Block test util. */
public final class BlockTestUtil {
private BlockTestUtil() {
throw new RuntimeException("Utility Class");
}
private static final Supplier<ChainResources> testChainSupplier =
Suppliers.memoize(BlockTestUtil::supplyTestChainResources);
private static final Supplier<ChainResources> hiveTestChainSupplier =
Suppliers.memoize(BlockTestUtil::supplyHiveTestChainResources);
private static final Supplier<ChainResources> testChainLondonSupplier =
Suppliers.memoize(BlockTestUtil::supplyTestChainLondonResources);
private static final Supplier<ChainResources> mainnetChainSupplier =
Suppliers.memoize(BlockTestUtil::supplyMainnetChainResources);
private static final Supplier<ChainResources> badPowChainSupplier =
Suppliers.memoize(BlockTestUtil::supplyBadPowChainResources);
private static final Supplier<ChainResources> forkOutdatedSupplier =
Suppliers.memoize(BlockTestUtil::supplyOutdatedForkResources);
private static final Supplier<ChainResources> forkUpgradedSupplier =
Suppliers.memoize(BlockTestUtil::supplyUpgradedForkResources);
private static final Supplier<ChainResources> testRpcCompactChainSupplier =
Suppliers.memoize(BlockTestUtil::supplyTestRpcCompactResources);
/**
* Gets test blockchain url.
*
* @return the test blockchain url
*/
public static URL getTestBlockchainUrl() {
return getTestChainResources().getBlocksURL();
}
/**
* Gets test london blockchain url.
*
* @return the test london blockchain url
*/
public static URL getTestLondonBlockchainUrl() {
return getTestChainLondonResources().getBlocksURL();
}
/**
* Gets test genesis url.
*
* @return the test genesis url
*/
public static URL getTestGenesisUrl() {
return getTestChainResources().getGenesisURL();
}
/**
* Gets test london genesis url.
*
* @return the test london genesis url
*/
public static URL getTestLondonGenesisUrl() {
return getTestChainLondonResources().getGenesisURL();
}
/**
* Gets test chain resources.
*
* @return the test chain resources
*/
public static ChainResources getTestChainResources() {
return testChainSupplier.get();
}
/**
* Gets test chain resources for hive tests.
*
* @return the test chain resources
*/
public static ChainResources getHiveTestChainResources() {
return hiveTestChainSupplier.get();
}
/**
* Gets test chain london resources.
*
* @return the test chain london resources
*/
public static ChainResources getTestChainLondonResources() {
return testChainLondonSupplier.get();
}
/**
* Gets mainnet resources.
*
* @return the mainnet resources
*/
public static ChainResources getMainnetResources() {
return mainnetChainSupplier.get();
}
private static ChainResources getBadPowResources() {
return badPowChainSupplier.get();
}
/**
* Gets outdated fork resources.
*
* @return the outdated fork resources
*/
public static ChainResources getOutdatedForkResources() {
return forkOutdatedSupplier.get();
}
/**
* Gets upgraded fork resources.
*
* @return the upgraded fork resources
*/
public static ChainResources getUpgradedForkResources() {
return forkUpgradedSupplier.get();
}
/**
* Gets Eth Ref Test resources.
*
* @return the Eth Ref Test resources.
*/
public static ChainResources getEthRefTestResources() {
return testRpcCompactChainSupplier.get();
}
private static ChainResources supplyTestChainResources() {
final URL genesisURL =
ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("testGenesis.json"));
final URL blocksURL =
ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("testBlockchain.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyHiveTestChainResources() {
final URL genesisURL =
ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("hive/testGenesis.json"));
final URL blocksURL =
ensureFileUrl(
BlockTestUtil.class.getClassLoader().getResource("hive/testBlockchain.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyTestChainLondonResources() {
final URL genesisURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("fork-london-data/testLondonGenesis.json"));
final URL blocksURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("fork-london-data/testLondonBlockchain.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyMainnetChainResources() {
final URL genesisURL =
ensureFileUrl(
BlockTestUtil.class.getClassLoader().getResource("mainnet-data/mainnet.json"));
final URL blocksURL =
ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("mainnet-data/1000.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyBadPowChainResources() {
final URL genesisURL =
ensureFileUrl(
BlockTestUtil.class.getClassLoader().getResource("mainnet-data/mainnet.json"));
final URL blocksURL =
ensureFileUrl(
BlockTestUtil.class.getClassLoader().getResource("mainnet-data/badpow.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyOutdatedForkResources() {
final URL genesisURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("fork-chain-data/genesis-outdated.json"));
final URL blocksURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("fork-chain-data/fork-outdated.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyUpgradedForkResources() {
final URL genesisURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("fork-chain-data/genesis-upgraded.json"));
final URL blocksURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("fork-chain-data/fork-upgraded.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
private static ChainResources supplyTestRpcCompactResources() {
final URL genesisURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("test-eth-ref-rpc-compact/genesis.json"));
final URL blocksURL =
ensureFileUrl(
BlockTestUtil.class
.getClassLoader()
.getResource("test-eth-ref-rpc-compact/chain.blocks"));
return new ChainResources(genesisURL, blocksURL);
}
/** Take a resource URL and if needed copy it to a temp file and return that URL. */
private static URL ensureFileUrl(final URL resource) {
Preconditions.checkNotNull(resource);
try {
try {
Paths.get(resource.toURI());
} catch (final FileSystemNotFoundException e) {
final Path target = Files.createTempFile("besu", null);
target.toFile().deleteOnExit();
Files.copy(resource.openStream(), target, StandardCopyOption.REPLACE_EXISTING);
return target.toUri().toURL();
}
} catch (final IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
return resource;
}
/**
* Writes the first 1000 blocks of the public chain to the given file.
*
* @param target FIle to write blocks to
*/
public static void write1000Blocks(final Path target) {
try {
Files.write(
target,
Resources.toByteArray(getMainnetResources().getBlocksURL()),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
} catch (final IOException ex) {
throw new IllegalStateException(ex);
}
}
/**
* Writes the first 1000 blocks of the public chain to the given file.
*
* @param target FIle to write blocks to
*/
public static void writeBadPowBlocks(final Path target) {
try {
Files.write(
target,
Resources.toByteArray(getBadPowResources().getBlocksURL()),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
} catch (final IOException ex) {
throw new IllegalStateException(ex);
}
}
/** The Chain resources. */
public static class ChainResources {
private final URL genesisURL;
private final URL blocksURL;
/**
* Instantiates a new Chain resources.
*
* @param genesisURL the genesis url
* @param blocksURL the blocks url
*/
public ChainResources(final URL genesisURL, final URL blocksURL) {
this.genesisURL = genesisURL;
this.blocksURL = blocksURL;
}
/**
* Gets genesis url.
*
* @return the genesis url
*/
public URL getGenesisURL() {
return genesisURL;
}
/**
* Gets blocks url.
*
* @return the blocks url
*/
public URL getBlocksURL() {
return blocksURL;
}
}
}