Plumb in three more metrics (#344)

* Plumb in three more metrics

* add blockchain_height gauge
* add blockchain_difficulty_total gauge
* add blockchain_announcedBlock_ingest histogram

This involved some deep pluming such that the metrics system needs to be
created in the PantheonCommand, along with trickle down effects into other
consensus engines.  This is likely where it should live anyway.

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Danno Ferrin 6 years ago committed by GitHub
parent 1f3a136b20
commit 6f549c2808
  1. 5
      acceptance-tests/build.gradle
  2. 5
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java
  3. 1
      ethereum/core/build.gradle
  4. 17
      ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/db/DefaultMutableBlockchain.java
  5. 4
      ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/ExecutionContextTestFixture.java
  6. 4
      ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/InMemoryStorageProvider.java
  7. 4
      ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/db/DefaultMutableBlockchainTest.java
  8. 4
      ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/db/GenesisBlockMismatchTest.java
  9. 22
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/BlockPropagationManager.java
  10. 7
      ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/sync/DefaultSynchronizer.java
  11. 9
      ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/BlockPropagationManagerTest.java
  12. 4
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java
  13. 3
      metrics/src/main/java/tech/pegasys/pantheon/metrics/MetricCategory.java
  14. 3
      metrics/src/main/java/tech/pegasys/pantheon/metrics/OperationTimer.java
  15. 2
      metrics/src/main/java/tech/pegasys/pantheon/metrics/noop/NoOpMetricsSystem.java
  16. 8
      pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java
  17. 6
      pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java
  18. 13
      pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java
  19. 9
      pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonController.java
  20. 17
      pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonController.java
  21. 9
      pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java
  22. 9
      pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonController.java
  23. 26
      pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java
  24. 14
      pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java
  25. 1
      pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java
  26. 1
      pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java
  27. 7
      pantheon/src/test/java/tech/pegasys/pantheon/util/BlockImporterTest.java

@ -16,14 +16,15 @@ dependencies {
testRuntime 'org.apache.logging.log4j:log4j-core'
testRuntime 'org.apache.logging.log4j:log4j-slf4j-impl'
testImplementation project(':config')
testImplementation project(':consensus:clique')
testImplementation project(':crypto')
testImplementation project(':ethereum:eth')
testImplementation project(':ethereum:core')
testImplementation project(':ethereum:blockcreation')
testImplementation project(':ethereum:jsonrpc')
testImplementation project(':metrics')
testImplementation project(':pantheon')
testImplementation project(':config')
testImplementation project(':consensus:clique')
testImplementation project(':util')
testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')

@ -21,6 +21,8 @@ import tech.pegasys.pantheon.cli.PantheonControllerBuilder;
import tech.pegasys.pantheon.controller.KeyPairUtil;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import java.io.IOException;
import java.util.Collections;
@ -48,6 +50,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
nodeExecutor = Executors.newCachedThreadPool();
}
final MetricsSystem noOpMetricsSystem = new NoOpMetricsSystem();
final PantheonControllerBuilder builder = new PantheonControllerBuilder();
final EthNetworkConfig ethNetworkConfig =
node.ethNetworkConfig()
@ -63,6 +66,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
.miningParameters(node.getMiningParameters())
.devMode(node.isDevMode())
.nodePrivateKeyFile(KeyPairUtil.getDefaultKeyFile(node.homeDirectory()))
.metricsSystem(noOpMetricsSystem)
.build();
} catch (final IOException e) {
throw new RuntimeException("Error building PantheonController", e);
@ -81,6 +85,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
.webSocketConfiguration(node.webSocketConfiguration())
.dataDir(node.homeDirectory())
.bannedNodeIds(Collections.emptySet())
.metricsSystem(noOpMetricsSystem)
.build();
nodeExecutor.submit(runner::execute);

@ -30,6 +30,7 @@ dependencies {
implementation project(':crypto')
implementation project(':ethereum:rlp')
implementation project(':ethereum:trie')
implementation project(':metrics')
implementation project(':services:kvstore')
implementation 'com.fasterxml.jackson.core:jackson-databind'

@ -29,6 +29,8 @@ import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.core.Transaction;
import tech.pegasys.pantheon.ethereum.core.TransactionReceipt;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException;
import tech.pegasys.pantheon.metrics.MetricCategory;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.uint.UInt256;
@ -51,10 +53,23 @@ public class DefaultMutableBlockchain implements MutableBlockchain {
private final Subscribers<BlockAddedObserver> blockAddedObservers = new Subscribers<>();
public DefaultMutableBlockchain(
final Block genesisBlock, final BlockchainStorage blockchainStorage) {
final Block genesisBlock,
final BlockchainStorage blockchainStorage,
final MetricsSystem metricsSystem) {
checkNotNull(genesisBlock);
this.blockchainStorage = blockchainStorage;
this.setGenesis(genesisBlock);
metricsSystem.createGauge(
MetricCategory.BLOCKCHAIN,
"height",
"Height of the chainhead",
() -> (double) this.getChainHeadBlockNumber());
metricsSystem.createGauge(
MetricCategory.BLOCKCHAIN,
"difficulty_total",
"Total difficulty of the chainhead",
() -> (double) this.getChainHead().getTotalDifficulty().toLong());
}
@Override

@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.ProtocolScheduleBuilder;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStorageWorldStateStorage;
import tech.pegasys.pantheon.ethereum.worldstate.DefaultMutableWorldState;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage;
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage;
@ -50,7 +51,8 @@ public class ExecutionContextTestFixture {
new DefaultMutableBlockchain(
genesis,
new KeyValueStoragePrefixedKeyBlockchainStorage(
keyValueStorage, MainnetBlockHashFunction::createHash));
keyValueStorage, MainnetBlockHashFunction::createHash),
new NoOpMetricsSystem());
this.stateArchive =
new WorldStateArchive(new KeyValueStorageWorldStateStorage(keyValueStorage));
this.protocolSchedule = protocolSchedule;

@ -23,6 +23,7 @@ import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStorageWorldStateStorage;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage;
public class InMemoryStorageProvider implements StorageProvider {
@ -36,7 +37,8 @@ public class InMemoryStorageProvider implements StorageProvider {
final InMemoryKeyValueStorage keyValueStorage = new InMemoryKeyValueStorage();
return new DefaultMutableBlockchain(
genesisBlock,
new KeyValueStoragePrefixedKeyBlockchainStorage(keyValueStorage, blockHashFunction));
new KeyValueStoragePrefixedKeyBlockchainStorage(keyValueStorage, blockHashFunction),
new NoOpMetricsSystem());
}
public static WorldStateArchive createInMemoryWorldStateArchive() {

@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockHashFunction;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator.BlockOptions;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage;
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage;
import tech.pegasys.pantheon.util.uint.UInt256;
@ -713,6 +714,7 @@ public class DefaultMutableBlockchainTest {
return new DefaultMutableBlockchain(
genesisBlock,
new KeyValueStoragePrefixedKeyBlockchainStorage(
kvStore, MainnetBlockHashFunction::createHash));
kvStore, MainnetBlockHashFunction::createHash),
new NoOpMetricsSystem());
}
}

@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.core.LogsBloomFilter;
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockHashFunction;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage;
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage;
import tech.pegasys.pantheon.util.bytes.Bytes32;
@ -73,7 +74,8 @@ public class GenesisBlockMismatchTest {
new DefaultMutableBlockchain(
genesisBlock00,
new KeyValueStoragePrefixedKeyBlockchainStorage(
kvStore, MainnetBlockHashFunction::createHash));
kvStore, MainnetBlockHashFunction::createHash),
new NoOpMetricsSystem());
final BlockHeader genesisHeader01 =
BlockHeaderBuilder.create()

@ -34,6 +34,9 @@ import tech.pegasys.pantheon.ethereum.mainnet.HeaderValidationMode;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason;
import tech.pegasys.pantheon.ethereum.rlp.RLPException;
import tech.pegasys.pantheon.metrics.MetricCategory;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.OperationTimer;
import tech.pegasys.pantheon.util.uint.UInt256;
import java.util.ArrayList;
@ -64,6 +67,7 @@ public class BlockPropagationManager<C> {
private final Set<Hash> requestedBlocks = new ConcurrentSet<>();
private final PendingBlocks pendingBlocks;
private final OperationTimer announcedBlockIngestTimer;
BlockPropagationManager(
final SynchronizerConfiguration config,
@ -71,7 +75,8 @@ public class BlockPropagationManager<C> {
final ProtocolContext<C> protocolContext,
final EthContext ethContext,
final SyncState syncState,
final PendingBlocks pendingBlocks) {
final PendingBlocks pendingBlocks,
final MetricsSystem metricsSystem) {
this.config = config;
this.protocolSchedule = protocolSchedule;
this.protocolContext = protocolContext;
@ -79,6 +84,12 @@ public class BlockPropagationManager<C> {
this.syncState = syncState;
this.pendingBlocks = pendingBlocks;
this.announcedBlockIngestTimer =
metricsSystem.createTimer(
MetricCategory.BLOCKCHAIN,
"pantheon_blockchain_announcedBlock_ingest",
"Time to ingest a single announced block");
}
public void start() {
@ -241,21 +252,24 @@ public class BlockPropagationManager<C> {
final PersistBlockTask<C> importTask =
PersistBlockTask.create(
protocolSchedule, protocolContext, block, HeaderValidationMode.FULL);
final OperationTimer.TimingContext blockTimer = announcedBlockIngestTimer.startTimer();
return ethContext
.getScheduler()
.scheduleWorkerTask(importTask::run)
.whenComplete(
(r, t) -> {
if (t != null) {
// TODO do we time failures? But we cannot drop a label in at this point.
LOG.warn(
"Failed to import announced block {} ({}).",
block.getHeader().getNumber(),
block.getHash());
} else {
final double timeInMs = blockTimer.stopTimer() * 1000;
LOG.info(
"Successfully imported announced block {} ({}).",
block.getHeader().getNumber(),
block.getHash());
String.format(
"Successfully imported announced block %d (%s) in %01.3fms.",
block.getHeader().getNumber(), block.getHash(), timeInMs));
}
});
}

@ -19,6 +19,7 @@ import tech.pegasys.pantheon.ethereum.eth.manager.EthContext;
import tech.pegasys.pantheon.ethereum.eth.sync.state.PendingBlocks;
import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
@ -40,7 +41,8 @@ public class DefaultSynchronizer<C> implements Synchronizer {
final ProtocolSchedule<C> protocolSchedule,
final ProtocolContext<C> protocolContext,
final EthContext ethContext,
final SyncState syncState) {
final SyncState syncState,
final MetricsSystem metricsSystem) {
this.syncState = syncState;
this.blockPropagationManager =
new BlockPropagationManager<>(
@ -49,7 +51,8 @@ public class DefaultSynchronizer<C> implements Synchronizer {
protocolContext,
ethContext,
syncState,
new PendingBlocks());
new PendingBlocks(),
metricsSystem);
this.downloader =
new Downloader<>(syncConfig, protocolSchedule, protocolContext, ethContext, syncState);

@ -35,6 +35,8 @@ import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator.BlockOptions;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.util.uint.UInt256;
import java.util.Collections;
@ -56,6 +58,7 @@ public class BlockPropagationManagerTest {
private SynchronizerConfiguration syncConfig;
private final PendingBlocks pendingBlocks = new PendingBlocks();
private SyncState syncState;
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
@BeforeClass
public static void setupSuite() {
@ -87,7 +90,8 @@ public class BlockPropagationManagerTest {
protocolContext,
ethProtocolManager.ethContext(),
syncState,
pendingBlocks);
pendingBlocks,
metricsSystem);
}
@Test
@ -462,7 +466,8 @@ public class BlockPropagationManagerTest {
protocolContext,
ethProtocolManager.ethContext(),
syncState,
pendingBlocks);
pendingBlocks,
metricsSystem);
final BlockDataGenerator gen = new BlockDataGenerator();
// Import some blocks

@ -295,7 +295,7 @@ public class PeerDiscoveryAgentTest extends AbstractPeerDiscoveryTest {
@Test
public void shouldBeActiveWhenConfigIsTrue() {
final DiscoveryConfiguration config = new DiscoveryConfiguration();
config.setActive(true);
config.setActive(true).setBindPort(0);
final PeerDiscoveryAgent agent = startDiscoveryAgent(config, new PeerBlacklist());
@ -305,7 +305,7 @@ public class PeerDiscoveryAgentTest extends AbstractPeerDiscoveryTest {
@Test
public void shouldNotBeActiveWhenConfigIsFalse() {
final DiscoveryConfiguration config = new DiscoveryConfiguration();
config.setActive(false);
config.setActive(false).setBindPort(0);
final PeerDiscoveryAgent agent = startDiscoveryAgent(config, new PeerBlacklist());

@ -16,7 +16,8 @@ public enum MetricCategory {
PEERS("peers"),
RPC("rpc"),
JVM("jvm", false),
PROCESS("process", false);
PROCESS("process", false),
BLOCKCHAIN("blockchain");
private final String name;
private final boolean pantheonSpecific;

@ -19,7 +19,8 @@ public interface OperationTimer {
TimingContext startTimer();
interface TimingContext extends Closeable {
void stopTimer();
/** @return Elapsed time in seconds. */
double stopTimer();
@Override
default void close() {

@ -26,7 +26,7 @@ import java.util.stream.Stream;
public class NoOpMetricsSystem implements MetricsSystem {
private static final Counter NO_OP_COUNTER = new NoOpCounter();
private static final TimingContext NO_OP_TIMING_CONTEXT = () -> {};
private static final TimingContext NO_OP_TIMING_CONTEXT = () -> 0;
private static final OperationTimer NO_OP_TIMER = () -> NO_OP_TIMING_CONTEXT;
@Override

@ -53,7 +53,6 @@ import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.prometheus.PrometheusMetricsSystem;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.nio.file.Path;
@ -80,6 +79,7 @@ public class RunnerBuilder {
private WebSocketConfiguration webSocketConfiguration;
private Path dataDir;
private Collection<String> bannedNodeIds;
private MetricsSystem metricsSystem;
private PermissioningConfiguration permissioningConfiguration;
public RunnerBuilder vertx(final Vertx vertx) {
@ -143,11 +143,15 @@ public class RunnerBuilder {
return this;
}
public RunnerBuilder metricsSystem(final MetricsSystem metricsSystem) {
this.metricsSystem = metricsSystem;
return this;
}
public Runner build() {
Preconditions.checkNotNull(pantheonController);
final MetricsSystem metricsSystem = PrometheusMetricsSystem.init();
final DiscoveryConfiguration discoveryConfiguration;
if (discovery) {
final Collection<?> bootstrap;

@ -36,6 +36,8 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.prometheus.PrometheusMetricsSystem;
import tech.pegasys.pantheon.util.BlockImporter;
import tech.pegasys.pantheon.util.bytes.BytesValue;
@ -120,6 +122,8 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
private final Builder synchronizerConfigurationBuilder;
private final RunnerBuilder runnerBuilder;
private final MetricsSystem metricsSystem = PrometheusMetricsSystem.init();
// Public IP stored to prevent having to research it each time we need it.
private InetAddress autoDiscoveredDefaultIP = null;
@ -446,6 +450,7 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
new MiningParameters(coinbase, minTransactionGasPrice, extraData, isMiningEnabled))
.devMode(isDevMode)
.nodePrivateKeyFile(getNodePrivateKeyFile())
.metricsSystem(metricsSystem)
.build();
} catch (final InvalidConfigurationException e) {
throw new ExecutionException(new CommandLine(this), e.getMessage());
@ -520,6 +525,7 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
.webSocketConfiguration(webSocketConfiguration)
.dataDir(dataDir())
.bannedNodeIds(bannedNodeIds)
.metricsSystem(metricsSystem)
.permissioningConfiguration(permissioningConfiguration)
.build();

@ -24,6 +24,7 @@ import tech.pegasys.pantheon.ethereum.development.DevelopmentProtocolSchedule;
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.File;
import java.io.IOException;
@ -38,6 +39,7 @@ public class PantheonControllerBuilder {
private MiningParameters miningParameters;
private boolean devMode;
private File nodePrivateKeyFile;
private MetricsSystem metricsSystem;
public PantheonControllerBuilder synchronizerConfiguration(
final SynchronizerConfiguration synchronizerConfiguration) {
@ -75,6 +77,11 @@ public class PantheonControllerBuilder {
return this;
}
public PantheonControllerBuilder metricsSystem(final MetricsSystem metricsSystem) {
this.metricsSystem = metricsSystem;
return this;
}
public PantheonController<?> build() throws IOException {
// instantiate a controller with mainnet config if no genesis file is defined
// otherwise use the indicated genesis file
@ -90,7 +97,8 @@ public class PantheonControllerBuilder {
DevelopmentProtocolSchedule.create(genesisConfig.getConfigOptions()),
synchronizerConfiguration,
miningParameters,
nodeKeys);
nodeKeys,
metricsSystem);
} else {
final String genesisConfig = ethNetworkConfig.getGenesisConfig();
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisConfig);
@ -101,7 +109,8 @@ public class PantheonControllerBuilder {
syncWithOttoman,
ethNetworkConfig.getNetworkId(),
miningParameters,
nodeKeys);
nodeKeys,
metricsSystem);
}
}
}

@ -54,6 +54,7 @@ import tech.pegasys.pantheon.ethereum.p2p.api.ProtocolManager;
import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException;
import java.time.Clock;
@ -104,7 +105,8 @@ public class CliquePantheonController implements PantheonController<CliqueContex
final SynchronizerConfiguration taintedSyncConfig,
final MiningParameters miningParams,
final int networkId,
final KeyPair nodeKeys) {
final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final CliqueConfigOptions cliqueConfig =
genesisConfig.getConfigOptions().getCliqueConfigOptions();
final long blocksPerEpoch = cliqueConfig.getEpochLength();
@ -117,7 +119,7 @@ public class CliquePantheonController implements PantheonController<CliqueContex
final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage);
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage();
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage);
@ -152,7 +154,8 @@ public class CliquePantheonController implements PantheonController<CliqueContex
protocolSchedule,
protocolContext,
ethProtocolManager.ethContext(),
syncState);
syncState,
metricsSystem);
final TransactionPool transactionPool =
TransactionPoolFactory.createTransactionPool(

@ -53,6 +53,7 @@ import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException;
import java.util.Collection;
@ -72,6 +73,7 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
private final KeyPair keyPair;
private final TransactionPool transactionPool;
private final Runnable closer;
private final MetricsSystem metricsStystem;
IbftLegacyPantheonController(
final GenesisConfigOptions genesisConfig,
@ -82,7 +84,8 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
final Synchronizer synchronizer,
final KeyPair keyPair,
final TransactionPool transactionPool,
final Runnable closer) {
final Runnable closer,
final MetricsSystem metricsSystem) {
this.genesisConfig = genesisConfig;
this.protocolSchedule = protocolSchedule;
@ -93,6 +96,7 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
this.keyPair = keyPair;
this.transactionPool = transactionPool;
this.closer = closer;
this.metricsStystem = metricsSystem;
}
public static PantheonController<IbftContext> init(
@ -101,14 +105,15 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
final SynchronizerConfiguration taintedSyncConfig,
final boolean ottomanTestnetOperation,
final int networkId,
final KeyPair nodeKeys) {
final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final ProtocolSchedule<IbftContext> protocolSchedule =
IbftProtocolSchedule.create(genesisConfig.getConfigOptions());
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage);
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage();
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage);
@ -159,7 +164,8 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
protocolSchedule,
protocolContext,
ethProtocolManager.ethContext(),
syncState);
syncState,
metricsSystem);
final Runnable closer =
() -> {
@ -183,7 +189,8 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
synchronizer,
nodeKeys,
transactionPool,
closer);
closer,
metricsSystem);
}
@Override

@ -61,6 +61,7 @@ import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException;
import java.util.Collection;
@ -115,14 +116,15 @@ public class IbftPantheonController implements PantheonController<IbftContext> {
final SynchronizerConfiguration taintedSyncConfig,
final MiningParameters miningParams,
final int networkId,
final KeyPair nodeKeys) {
final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final ProtocolSchedule<IbftContext> protocolSchedule =
IbftProtocolSchedule.create(genesisConfig.getConfigOptions());
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage);
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage();
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage);
@ -160,7 +162,8 @@ public class IbftPantheonController implements PantheonController<IbftContext> {
protocolSchedule,
protocolContext,
ethProtocolManager.ethContext(),
syncState);
syncState,
metricsSystem);
final TransactionPool transactionPool =
TransactionPoolFactory.createTransactionPool(

@ -41,6 +41,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.p2p.api.ProtocolManager;
import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException;
import java.time.Clock;
@ -90,13 +91,14 @@ public class MainnetPantheonController implements PantheonController<Void> {
final ProtocolSchedule<Void> protocolSchedule,
final SynchronizerConfiguration taintedSyncConfig,
final MiningParameters miningParams,
final KeyPair nodeKeys) {
final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage);
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateArchive worldStateArchive =
new WorldStateArchive(storageProvider.createWorldStateStorage());
@ -125,7 +127,8 @@ public class MainnetPantheonController implements PantheonController<Void> {
protocolSchedule,
protocolContext,
ethProtocolManager.ethContext(),
syncState);
syncState,
metricsSystem);
final TransactionPool transactionPool =
TransactionPoolFactory.createTransactionPool(

@ -29,6 +29,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSchedule;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.Closeable;
import java.util.Collection;
@ -45,7 +46,8 @@ public interface PantheonController<C> extends Closeable {
final boolean ottomanTestnetOperation,
final int networkId,
final MiningParameters miningParameters,
final KeyPair nodeKeys) {
final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions();
@ -56,10 +58,17 @@ public interface PantheonController<C> extends Closeable {
MainnetProtocolSchedule.fromConfig(configOptions),
syncConfig,
miningParameters,
nodeKeys);
nodeKeys,
metricsSystem);
} else if (configOptions.isRevisedIbft()) {
return IbftPantheonController.init(
storageProvider, genesisConfigFile, syncConfig, miningParameters, networkId, nodeKeys);
storageProvider,
genesisConfigFile,
syncConfig,
miningParameters,
networkId,
nodeKeys,
metricsSystem);
} else if (configOptions.isIbft()) {
return IbftLegacyPantheonController.init(
storageProvider,
@ -67,10 +76,17 @@ public interface PantheonController<C> extends Closeable {
syncConfig,
ottomanTestnetOperation,
networkId,
nodeKeys);
nodeKeys,
metricsSystem);
} else if (configOptions.isClique()) {
return CliquePantheonController.init(
storageProvider, genesisConfigFile, syncConfig, miningParameters, networkId, nodeKeys);
storageProvider,
genesisConfigFile,
syncConfig,
miningParameters,
networkId,
nodeKeys,
metricsSystem);
} else {
throw new IllegalArgumentException("Unknown consensus mechanism defined");
}

@ -37,6 +37,8 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.util.uint.UInt256;
import java.io.IOException;
@ -93,6 +95,7 @@ public final class RunnerTest {
// .fastSyncPivotDistance(blockCount / 2).build();
.fastSyncPivotDistance(0)
.build();
final MetricsSystem noOpMetricsSystem = new NoOpMetricsSystem();
// Setup state with block data
try (final PantheonController<Void> controller =
@ -102,7 +105,8 @@ public final class RunnerTest {
MainnetProtocolSchedule.create(),
fastSyncConfig,
new MiningParametersTestBuilder().enabled(false).build(),
aheadDbNodeKeys)) {
aheadDbNodeKeys,
noOpMetricsSystem)) {
setupState(blockCount, controller.getProtocolSchedule(), controller.getProtocolContext());
}
@ -114,7 +118,8 @@ public final class RunnerTest {
MainnetProtocolSchedule.create(),
fastSyncConfig,
new MiningParametersTestBuilder().enabled(false).build(),
aheadDbNodeKeys);
aheadDbNodeKeys,
noOpMetricsSystem);
final String listenHost = InetAddress.getLoopbackAddress().getHostAddress();
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final JsonRpcConfiguration aheadJsonRpcConfiguration = jsonRpcConfiguration();
@ -127,6 +132,7 @@ public final class RunnerTest {
.discoveryHost(listenHost)
.discoveryPort(0)
.maxPeers(3)
.metricsSystem(noOpMetricsSystem)
.bannedNodeIds(Collections.emptySet());
final Runner runnerAhead =
@ -152,7 +158,8 @@ public final class RunnerTest {
MainnetProtocolSchedule.create(),
fastSyncConfig,
new MiningParametersTestBuilder().enabled(false).build(),
KeyPair.generate());
KeyPair.generate(),
noOpMetricsSystem);
final Runner runnerBehind =
runnerBuilder
.pantheonController(controllerBehind)
@ -166,6 +173,7 @@ public final class RunnerTest {
.jsonRpcConfiguration(behindJsonRpcConfiguration)
.webSocketConfiguration(behindWebSocketConfiguration)
.dataDir(temp.newFolder().toPath())
.metricsSystem(noOpMetricsSystem)
.build();
executorService.submit(runnerBehind::execute);

@ -85,6 +85,7 @@ public abstract class CommandTestAbstract {
when(mockControllerBuilder.miningParameters(any())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.devMode(anyBoolean())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.nodePrivateKeyFile(any())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.metricsSystem(any())).thenReturn(mockControllerBuilder);
when(mockSyncConfBuilder.build()).thenReturn(mockSyncConf);
}

@ -102,6 +102,7 @@ public class PantheonCommandTest extends CommandTestAbstract {
when(mockRunnerBuilder.permissioningConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.dataDir(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.bannedNodeIds(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.metricsSystem(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.build()).thenReturn(mockRunner);
}

@ -21,6 +21,7 @@ import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.core.InMemoryStorageProvider;
import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder;
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.testutil.BlockTestUtil;
import tech.pegasys.pantheon.util.uint.UInt256;
@ -53,7 +54,8 @@ public final class BlockImporterTest {
false,
1,
new MiningParametersTestBuilder().enabled(false).build(),
KeyPair.generate());
KeyPair.generate(),
new NoOpMetricsSystem());
final BlockImporter.ImportResult result =
blockImporter.importBlockchain(source, targetController);
assertThat(result.count).isEqualTo(1000);
@ -83,7 +85,8 @@ public final class BlockImporterTest {
false,
10,
new MiningParametersTestBuilder().enabled(false).build(),
KeyPair.generate());
KeyPair.generate(),
new NoOpMetricsSystem());
final BlockImporter.ImportResult result = blockImporter.importBlockchain(source, controller);
assertThat(result.count).isEqualTo(959);

Loading…
Cancel
Save