|
|
@ -6,17 +6,22 @@ import net.consensys.pantheon.consensus.clique.CliqueContext; |
|
|
|
import net.consensys.pantheon.consensus.clique.CliqueVoteTallyUpdater; |
|
|
|
import net.consensys.pantheon.consensus.clique.CliqueVoteTallyUpdater; |
|
|
|
import net.consensys.pantheon.consensus.clique.VoteTallyCache; |
|
|
|
import net.consensys.pantheon.consensus.clique.VoteTallyCache; |
|
|
|
import net.consensys.pantheon.consensus.clique.blockcreation.CliqueBlockMiner; |
|
|
|
import net.consensys.pantheon.consensus.clique.blockcreation.CliqueBlockMiner; |
|
|
|
|
|
|
|
import net.consensys.pantheon.consensus.clique.blockcreation.CliqueBlockScheduler; |
|
|
|
|
|
|
|
import net.consensys.pantheon.consensus.clique.blockcreation.CliqueMinerExecutor; |
|
|
|
|
|
|
|
import net.consensys.pantheon.consensus.clique.blockcreation.CliqueMiningCoordinator; |
|
|
|
import net.consensys.pantheon.consensus.common.EpochManager; |
|
|
|
import net.consensys.pantheon.consensus.common.EpochManager; |
|
|
|
import net.consensys.pantheon.consensus.common.VoteProposer; |
|
|
|
import net.consensys.pantheon.consensus.common.VoteProposer; |
|
|
|
import net.consensys.pantheon.crypto.SECP256K1.KeyPair; |
|
|
|
import net.consensys.pantheon.crypto.SECP256K1.KeyPair; |
|
|
|
import net.consensys.pantheon.ethereum.ProtocolContext; |
|
|
|
import net.consensys.pantheon.ethereum.ProtocolContext; |
|
|
|
import net.consensys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator; |
|
|
|
import net.consensys.pantheon.ethereum.blockcreation.AbstractMiningCoordinator; |
|
|
|
|
|
|
|
import net.consensys.pantheon.ethereum.blockcreation.MiningParameters; |
|
|
|
import net.consensys.pantheon.ethereum.chain.GenesisConfig; |
|
|
|
import net.consensys.pantheon.ethereum.chain.GenesisConfig; |
|
|
|
import net.consensys.pantheon.ethereum.chain.MutableBlockchain; |
|
|
|
import net.consensys.pantheon.ethereum.chain.MutableBlockchain; |
|
|
|
import net.consensys.pantheon.ethereum.core.BlockHashFunction; |
|
|
|
import net.consensys.pantheon.ethereum.core.BlockHashFunction; |
|
|
|
import net.consensys.pantheon.ethereum.core.Hash; |
|
|
|
import net.consensys.pantheon.ethereum.core.Hash; |
|
|
|
import net.consensys.pantheon.ethereum.core.Synchronizer; |
|
|
|
import net.consensys.pantheon.ethereum.core.Synchronizer; |
|
|
|
import net.consensys.pantheon.ethereum.core.TransactionPool; |
|
|
|
import net.consensys.pantheon.ethereum.core.TransactionPool; |
|
|
|
|
|
|
|
import net.consensys.pantheon.ethereum.core.Util; |
|
|
|
import net.consensys.pantheon.ethereum.db.DefaultMutableBlockchain; |
|
|
|
import net.consensys.pantheon.ethereum.db.DefaultMutableBlockchain; |
|
|
|
import net.consensys.pantheon.ethereum.db.WorldStateArchive; |
|
|
|
import net.consensys.pantheon.ethereum.db.WorldStateArchive; |
|
|
|
import net.consensys.pantheon.ethereum.eth.EthProtocol; |
|
|
|
import net.consensys.pantheon.ethereum.eth.EthProtocol; |
|
|
@ -31,11 +36,16 @@ import net.consensys.pantheon.ethereum.p2p.api.ProtocolManager; |
|
|
|
import net.consensys.pantheon.ethereum.p2p.config.SubProtocolConfiguration; |
|
|
|
import net.consensys.pantheon.ethereum.p2p.config.SubProtocolConfiguration; |
|
|
|
import net.consensys.pantheon.ethereum.worldstate.KeyValueStorageWorldStateStorage; |
|
|
|
import net.consensys.pantheon.ethereum.worldstate.KeyValueStorageWorldStateStorage; |
|
|
|
import net.consensys.pantheon.services.kvstore.RocksDbKeyValueStorage; |
|
|
|
import net.consensys.pantheon.services.kvstore.RocksDbKeyValueStorage; |
|
|
|
|
|
|
|
import net.consensys.pantheon.util.time.SystemClock; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.nio.file.Path; |
|
|
|
import java.nio.file.Path; |
|
|
|
|
|
|
|
import java.util.concurrent.ExecutorService; |
|
|
|
|
|
|
|
import java.util.concurrent.Executors; |
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import io.vertx.core.json.JsonObject; |
|
|
|
import org.apache.logging.log4j.Logger; |
|
|
|
import org.apache.logging.log4j.Logger; |
|
|
|
|
|
|
|
|
|
|
|
public class CliquePantheonController |
|
|
|
public class CliquePantheonController |
|
|
@ -50,6 +60,9 @@ public class CliquePantheonController |
|
|
|
private final TransactionPool transactionPool; |
|
|
|
private final TransactionPool transactionPool; |
|
|
|
private final Runnable closer; |
|
|
|
private final Runnable closer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final long EPOCH_LENGTH_DEFAULT = 30_000L; |
|
|
|
|
|
|
|
private static final long SECONDS_BETWEEN_BLOCKS_DEFAULT = 15L; |
|
|
|
|
|
|
|
|
|
|
|
CliquePantheonController( |
|
|
|
CliquePantheonController( |
|
|
|
final GenesisConfig<CliqueContext> genesisConfig, |
|
|
|
final GenesisConfig<CliqueContext> genesisConfig, |
|
|
|
final ProtocolContext<CliqueContext> context, |
|
|
|
final ProtocolContext<CliqueContext> context, |
|
|
@ -72,9 +85,16 @@ public class CliquePantheonController |
|
|
|
final Path home, |
|
|
|
final Path home, |
|
|
|
final GenesisConfig<CliqueContext> genesisConfig, |
|
|
|
final GenesisConfig<CliqueContext> genesisConfig, |
|
|
|
final SynchronizerConfiguration taintedSyncConfig, |
|
|
|
final SynchronizerConfiguration taintedSyncConfig, |
|
|
|
|
|
|
|
final MiningParameters miningParams, |
|
|
|
|
|
|
|
final JsonObject cliqueConfig, |
|
|
|
final int networkId, |
|
|
|
final int networkId, |
|
|
|
final KeyPair nodeKeys) |
|
|
|
final KeyPair nodeKeys) |
|
|
|
throws IOException { |
|
|
|
throws IOException { |
|
|
|
|
|
|
|
final long blocksPerEpoch = cliqueConfig.getLong("epoch", EPOCH_LENGTH_DEFAULT); |
|
|
|
|
|
|
|
final long secondsBetweenBlocks = |
|
|
|
|
|
|
|
cliqueConfig.getLong("period", SECONDS_BETWEEN_BLOCKS_DEFAULT); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final EpochManager epochManger = new EpochManager(blocksPerEpoch); |
|
|
|
final RocksDbKeyValueStorage kv = |
|
|
|
final RocksDbKeyValueStorage kv = |
|
|
|
RocksDbKeyValueStorage.create(Files.createDirectories(home.resolve(DATABASE_PATH))); |
|
|
|
RocksDbKeyValueStorage.create(Files.createDirectories(home.resolve(DATABASE_PATH))); |
|
|
|
final ProtocolSchedule<CliqueContext> protocolSchedule = genesisConfig.getProtocolSchedule(); |
|
|
|
final ProtocolSchedule<CliqueContext> protocolSchedule = genesisConfig.getProtocolSchedule(); |
|
|
@ -87,7 +107,6 @@ public class CliquePantheonController |
|
|
|
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage); |
|
|
|
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage); |
|
|
|
genesisConfig.writeStateTo(worldStateArchive.getMutable(Hash.EMPTY_TRIE_HASH)); |
|
|
|
genesisConfig.writeStateTo(worldStateArchive.getMutable(Hash.EMPTY_TRIE_HASH)); |
|
|
|
|
|
|
|
|
|
|
|
final EpochManager epochManger = new EpochManager(30_000); |
|
|
|
|
|
|
|
final ProtocolContext<CliqueContext> protocolContext = |
|
|
|
final ProtocolContext<CliqueContext> protocolContext = |
|
|
|
new ProtocolContext<>( |
|
|
|
new ProtocolContext<>( |
|
|
|
blockchain, |
|
|
|
blockchain, |
|
|
@ -113,6 +132,28 @@ public class CliquePantheonController |
|
|
|
TransactionPoolFactory.createTransactionPool( |
|
|
|
TransactionPoolFactory.createTransactionPool( |
|
|
|
protocolSchedule, protocolContext, ethProtocolManager.ethContext()); |
|
|
|
protocolSchedule, protocolContext, ethProtocolManager.ethContext()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final ExecutorService minerThreadPool = Executors.newCachedThreadPool(); |
|
|
|
|
|
|
|
CliqueMinerExecutor miningExecutor = |
|
|
|
|
|
|
|
new CliqueMinerExecutor( |
|
|
|
|
|
|
|
protocolContext, |
|
|
|
|
|
|
|
minerThreadPool, |
|
|
|
|
|
|
|
protocolSchedule, |
|
|
|
|
|
|
|
transactionPool.getPendingTransactions(), |
|
|
|
|
|
|
|
nodeKeys, |
|
|
|
|
|
|
|
miningParams, |
|
|
|
|
|
|
|
new CliqueBlockScheduler( |
|
|
|
|
|
|
|
new SystemClock(), |
|
|
|
|
|
|
|
protocolContext.getConsensusState().getVoteTallyCache(), |
|
|
|
|
|
|
|
Util.publicKeyToAddress(nodeKeys.getPublicKey()), |
|
|
|
|
|
|
|
secondsBetweenBlocks), |
|
|
|
|
|
|
|
epochManger); |
|
|
|
|
|
|
|
CliqueMiningCoordinator miningCoordinator = |
|
|
|
|
|
|
|
new CliqueMiningCoordinator(blockchain, miningExecutor); |
|
|
|
|
|
|
|
miningCoordinator.addMinedBlockObserver(ethProtocolManager); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clique mining is implicitly enabled.
|
|
|
|
|
|
|
|
miningCoordinator.enable(); |
|
|
|
|
|
|
|
|
|
|
|
return new CliquePantheonController( |
|
|
|
return new CliquePantheonController( |
|
|
|
genesisConfig, |
|
|
|
genesisConfig, |
|
|
|
protocolContext, |
|
|
|
protocolContext, |
|
|
@ -120,7 +161,16 @@ public class CliquePantheonController |
|
|
|
synchronizer, |
|
|
|
synchronizer, |
|
|
|
nodeKeys, |
|
|
|
nodeKeys, |
|
|
|
transactionPool, |
|
|
|
transactionPool, |
|
|
|
kv::close); |
|
|
|
() -> { |
|
|
|
|
|
|
|
miningCoordinator.disable(); |
|
|
|
|
|
|
|
minerThreadPool.shutdownNow(); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
minerThreadPool.awaitTermination(5, TimeUnit.SECONDS); |
|
|
|
|
|
|
|
} catch (final InterruptedException e) { |
|
|
|
|
|
|
|
LOG.error("Failed to shutdown miner executor"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
kv.close(); |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|