Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PIE-1810] Add read-only blockchain factory method #1845

Merged
merged 3 commits into from
Aug 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import tech.pegasys.pantheon.ethereum.chain.Blockchain;
import tech.pegasys.pantheon.ethereum.chain.BlockchainStorage;
import tech.pegasys.pantheon.ethereum.chain.DefaultMutableBlockchain;
import tech.pegasys.pantheon.ethereum.chain.DefaultBlockchain;
import tech.pegasys.pantheon.ethereum.chain.GenesisState;
import tech.pegasys.pantheon.ethereum.chain.MutableBlockchain;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down Expand Up @@ -60,7 +60,7 @@ public static <T> ProtocolContext<T> init(
storageProvider.createWorldStatePreimageStorage();

final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
DefaultBlockchain.createMutable(genesisState.getBlock(), blockchainStorage, metricsSystem);

final WorldStateArchive worldStateArchive =
new WorldStateArchive(worldStateStorage, preimageStorage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

import com.google.common.annotations.VisibleForTesting;

public class DefaultMutableBlockchain implements MutableBlockchain {
public class DefaultBlockchain implements MutableBlockchain {

protected final BlockchainStorage blockchainStorage;

Expand All @@ -53,13 +53,16 @@ public class DefaultMutableBlockchain implements MutableBlockchain {
private volatile int chainHeadTransactionCount;
private volatile int chainHeadOmmerCount;

public DefaultMutableBlockchain(
final Block genesisBlock,
private DefaultBlockchain(
final Optional<Block> genesisBlock,
final BlockchainStorage blockchainStorage,
final MetricsSystem metricsSystem) {
checkNotNull(genesisBlock);
checkNotNull(blockchainStorage);
checkNotNull(metricsSystem);

this.blockchainStorage = blockchainStorage;
this.setGenesis(genesisBlock);
genesisBlock.ifPresent(this::setGenesis);

final Hash chainHead = blockchainStorage.getChainHead().get();
chainHeader = blockchainStorage.getBlockHeader(chainHead).get();
Expand Down Expand Up @@ -112,6 +115,40 @@ public DefaultMutableBlockchain(
() -> chainHeadOmmerCount);
}

public static MutableBlockchain createMutable(
final Block genesisBlock,
final BlockchainStorage blockchainStorage,
final MetricsSystem metricsSystem) {
checkNotNull(genesisBlock);
return new DefaultBlockchain(Optional.of(genesisBlock), blockchainStorage, metricsSystem);
}

public static Blockchain create(
final BlockchainStorage blockchainStorage, final MetricsSystem metricsSystem) {
checkArgument(
validateStorageNonEmpty(blockchainStorage), "Cannot create Blockchain from empty storage");
return new DefaultBlockchain(Optional.empty(), blockchainStorage, metricsSystem);
}

private static boolean validateStorageNonEmpty(final BlockchainStorage blockchainStorage) {
// Run a few basic checks to make sure data looks available and consistent
final Optional<Hash> maybeHead = blockchainStorage.getChainHead();
if (maybeHead.isEmpty()) {
return false;
}
final Optional<Hash> genesisHash =
blockchainStorage.getBlockHash(BlockHeader.GENESIS_BLOCK_NUMBER);
if (genesisHash.isEmpty()) {
return false;
}
final Optional<UInt256> td = blockchainStorage.getTotalDifficulty(maybeHead.get());
if (td.isEmpty()) {
return false;
}

return true;
}

@Override
public ChainHead getChainHead() {
return new ChainHead(chainHeader.getHash(), totalDifficulty, chainHeader.getNumber());
Expand Down Expand Up @@ -359,6 +396,7 @@ private BlockAddedEvent handleChainReorg(
removedTransactions);
}

@Override
public boolean rewindToBlock(final long blockNumber) {
final Optional<Hash> blockHash = blockchainStorage.getBlockHash(blockNumber);
if (blockHash.isEmpty()) {
Expand Down Expand Up @@ -413,7 +451,7 @@ Set<Hash> getForks() {
return new HashSet<>(blockchainStorage.getForkHeads());
}

protected void setGenesis(final Block genesisBlock) {
private void setGenesis(final Block genesisBlock) {
checkArgument(
genesisBlock.getHeader().getNumber() == BlockHeader.GENESIS_BLOCK_NUMBER,
"Invalid genesis block.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,13 @@ public interface MutableBlockchain extends Blockchain {
* @param receipts The list of receipts associated with this block's transactions.
*/
void appendBlock(Block block, List<TransactionReceipt> receipts);

/**
* Rolls back the canonical chainhead to the specified block number.
*
* @param blockNumber The block number to roll back to.
* @return {@code true} on success, {@code false} if the canonical chain height is less than
* {@code blockNumber}
*/
boolean rewindToBlock(final long blockNumber);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import tech.pegasys.pantheon.config.GenesisConfigFile;
import tech.pegasys.pantheon.config.StubGenesisConfigOptions;
import tech.pegasys.pantheon.ethereum.ProtocolContext;
import tech.pegasys.pantheon.ethereum.chain.DefaultMutableBlockchain;
import tech.pegasys.pantheon.ethereum.chain.DefaultBlockchain;
import tech.pegasys.pantheon.ethereum.chain.GenesisState;
import tech.pegasys.pantheon.ethereum.chain.MutableBlockchain;
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockHeaderFunctions;
Expand Down Expand Up @@ -49,7 +49,7 @@ private ExecutionContextTestFixture(
this.genesis = genesisState.getBlock();
this.keyValueStorage = keyValueStorage;
this.blockchain =
new DefaultMutableBlockchain(
DefaultBlockchain.createMutable(
genesis,
new KeyValueStoragePrefixedKeyBlockchainStorage(
keyValueStorage, new MainnetBlockHeaderFunctions()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
package tech.pegasys.pantheon.ethereum.core;

import tech.pegasys.pantheon.ethereum.chain.BlockchainStorage;
import tech.pegasys.pantheon.ethereum.chain.DefaultMutableBlockchain;
import tech.pegasys.pantheon.ethereum.chain.DefaultBlockchain;
import tech.pegasys.pantheon.ethereum.chain.MutableBlockchain;
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockHeaderFunctions;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
Expand Down Expand Up @@ -43,7 +43,7 @@ public static MutableBlockchain createInMemoryBlockchain(final Block genesisBloc
public static MutableBlockchain createInMemoryBlockchain(
final Block genesisBlock, final BlockHeaderFunctions blockHeaderFunctions) {
final InMemoryKeyValueStorage keyValueStorage = new InMemoryKeyValueStorage();
return new DefaultMutableBlockchain(
return DefaultBlockchain.createMutable(
genesisBlock,
new KeyValueStoragePrefixedKeyBlockchainStorage(keyValueStorage, blockHeaderFunctions),
new NoOpMetricsSystem());
Expand Down
Loading