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-core'
testRuntime 'org.apache.logging.log4j:log4j-slf4j-impl' testRuntime 'org.apache.logging.log4j:log4j-slf4j-impl'
testImplementation project(':config')
testImplementation project(':consensus:clique')
testImplementation project(':crypto') testImplementation project(':crypto')
testImplementation project(':ethereum:eth') testImplementation project(':ethereum:eth')
testImplementation project(':ethereum:core') testImplementation project(':ethereum:core')
testImplementation project(':ethereum:blockcreation') testImplementation project(':ethereum:blockcreation')
testImplementation project(':ethereum:jsonrpc') testImplementation project(':ethereum:jsonrpc')
testImplementation project(':metrics')
testImplementation project(':pantheon') testImplementation project(':pantheon')
testImplementation project(':config')
testImplementation project(':consensus:clique')
testImplementation project(':util') testImplementation project(':util')
testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') 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.KeyPairUtil;
import tech.pegasys.pantheon.controller.PantheonController; import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration; 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.io.IOException;
import java.util.Collections; import java.util.Collections;
@ -48,6 +50,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
nodeExecutor = Executors.newCachedThreadPool(); nodeExecutor = Executors.newCachedThreadPool();
} }
final MetricsSystem noOpMetricsSystem = new NoOpMetricsSystem();
final PantheonControllerBuilder builder = new PantheonControllerBuilder(); final PantheonControllerBuilder builder = new PantheonControllerBuilder();
final EthNetworkConfig ethNetworkConfig = final EthNetworkConfig ethNetworkConfig =
node.ethNetworkConfig() node.ethNetworkConfig()
@ -63,6 +66,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
.miningParameters(node.getMiningParameters()) .miningParameters(node.getMiningParameters())
.devMode(node.isDevMode()) .devMode(node.isDevMode())
.nodePrivateKeyFile(KeyPairUtil.getDefaultKeyFile(node.homeDirectory())) .nodePrivateKeyFile(KeyPairUtil.getDefaultKeyFile(node.homeDirectory()))
.metricsSystem(noOpMetricsSystem)
.build(); .build();
} catch (final IOException e) { } catch (final IOException e) {
throw new RuntimeException("Error building PantheonController", e); throw new RuntimeException("Error building PantheonController", e);
@ -81,6 +85,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
.webSocketConfiguration(node.webSocketConfiguration()) .webSocketConfiguration(node.webSocketConfiguration())
.dataDir(node.homeDirectory()) .dataDir(node.homeDirectory())
.bannedNodeIds(Collections.emptySet()) .bannedNodeIds(Collections.emptySet())
.metricsSystem(noOpMetricsSystem)
.build(); .build();
nodeExecutor.submit(runner::execute); nodeExecutor.submit(runner::execute);

@ -30,6 +30,7 @@ dependencies {
implementation project(':crypto') implementation project(':crypto')
implementation project(':ethereum:rlp') implementation project(':ethereum:rlp')
implementation project(':ethereum:trie') implementation project(':ethereum:trie')
implementation project(':metrics')
implementation project(':services:kvstore') implementation project(':services:kvstore')
implementation 'com.fasterxml.jackson.core:jackson-databind' 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.Transaction;
import tech.pegasys.pantheon.ethereum.core.TransactionReceipt; import tech.pegasys.pantheon.ethereum.core.TransactionReceipt;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException; 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.Subscribers;
import tech.pegasys.pantheon.util.uint.UInt256; import tech.pegasys.pantheon.util.uint.UInt256;
@ -51,10 +53,23 @@ public class DefaultMutableBlockchain implements MutableBlockchain {
private final Subscribers<BlockAddedObserver> blockAddedObservers = new Subscribers<>(); private final Subscribers<BlockAddedObserver> blockAddedObservers = new Subscribers<>();
public DefaultMutableBlockchain( public DefaultMutableBlockchain(
final Block genesisBlock, final BlockchainStorage blockchainStorage) { final Block genesisBlock,
final BlockchainStorage blockchainStorage,
final MetricsSystem metricsSystem) {
checkNotNull(genesisBlock); checkNotNull(genesisBlock);
this.blockchainStorage = blockchainStorage; this.blockchainStorage = blockchainStorage;
this.setGenesis(genesisBlock); 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 @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.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStorageWorldStateStorage; import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStorageWorldStateStorage;
import tech.pegasys.pantheon.ethereum.worldstate.DefaultMutableWorldState; 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.InMemoryKeyValueStorage;
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage; import tech.pegasys.pantheon.services.kvstore.KeyValueStorage;
@ -50,7 +51,8 @@ public class ExecutionContextTestFixture {
new DefaultMutableBlockchain( new DefaultMutableBlockchain(
genesis, genesis,
new KeyValueStoragePrefixedKeyBlockchainStorage( new KeyValueStoragePrefixedKeyBlockchainStorage(
keyValueStorage, MainnetBlockHashFunction::createHash)); keyValueStorage, MainnetBlockHashFunction::createHash),
new NoOpMetricsSystem());
this.stateArchive = this.stateArchive =
new WorldStateArchive(new KeyValueStorageWorldStateStorage(keyValueStorage)); new WorldStateArchive(new KeyValueStorageWorldStateStorage(keyValueStorage));
this.protocolSchedule = protocolSchedule; 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.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStorageWorldStateStorage; import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStorageWorldStateStorage;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage; import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage;
public class InMemoryStorageProvider implements StorageProvider { public class InMemoryStorageProvider implements StorageProvider {
@ -36,7 +37,8 @@ public class InMemoryStorageProvider implements StorageProvider {
final InMemoryKeyValueStorage keyValueStorage = new InMemoryKeyValueStorage(); final InMemoryKeyValueStorage keyValueStorage = new InMemoryKeyValueStorage();
return new DefaultMutableBlockchain( return new DefaultMutableBlockchain(
genesisBlock, genesisBlock,
new KeyValueStoragePrefixedKeyBlockchainStorage(keyValueStorage, blockHashFunction)); new KeyValueStoragePrefixedKeyBlockchainStorage(keyValueStorage, blockHashFunction),
new NoOpMetricsSystem());
} }
public static WorldStateArchive createInMemoryWorldStateArchive() { 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.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator; import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator.BlockOptions; 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.InMemoryKeyValueStorage;
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage; import tech.pegasys.pantheon.services.kvstore.KeyValueStorage;
import tech.pegasys.pantheon.util.uint.UInt256; import tech.pegasys.pantheon.util.uint.UInt256;
@ -713,6 +714,7 @@ public class DefaultMutableBlockchainTest {
return new DefaultMutableBlockchain( return new DefaultMutableBlockchain(
genesisBlock, genesisBlock,
new KeyValueStoragePrefixedKeyBlockchainStorage( 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.mainnet.MainnetBlockHashFunction;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage; import tech.pegasys.pantheon.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException; 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.InMemoryKeyValueStorage;
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage; import tech.pegasys.pantheon.services.kvstore.KeyValueStorage;
import tech.pegasys.pantheon.util.bytes.Bytes32; import tech.pegasys.pantheon.util.bytes.Bytes32;
@ -73,7 +74,8 @@ public class GenesisBlockMismatchTest {
new DefaultMutableBlockchain( new DefaultMutableBlockchain(
genesisBlock00, genesisBlock00,
new KeyValueStoragePrefixedKeyBlockchainStorage( new KeyValueStoragePrefixedKeyBlockchainStorage(
kvStore, MainnetBlockHashFunction::createHash)); kvStore, MainnetBlockHashFunction::createHash),
new NoOpMetricsSystem());
final BlockHeader genesisHeader01 = final BlockHeader genesisHeader01 =
BlockHeaderBuilder.create() 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.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason; import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason;
import tech.pegasys.pantheon.ethereum.rlp.RLPException; 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 tech.pegasys.pantheon.util.uint.UInt256;
import java.util.ArrayList; import java.util.ArrayList;
@ -64,6 +67,7 @@ public class BlockPropagationManager<C> {
private final Set<Hash> requestedBlocks = new ConcurrentSet<>(); private final Set<Hash> requestedBlocks = new ConcurrentSet<>();
private final PendingBlocks pendingBlocks; private final PendingBlocks pendingBlocks;
private final OperationTimer announcedBlockIngestTimer;
BlockPropagationManager( BlockPropagationManager(
final SynchronizerConfiguration config, final SynchronizerConfiguration config,
@ -71,7 +75,8 @@ public class BlockPropagationManager<C> {
final ProtocolContext<C> protocolContext, final ProtocolContext<C> protocolContext,
final EthContext ethContext, final EthContext ethContext,
final SyncState syncState, final SyncState syncState,
final PendingBlocks pendingBlocks) { final PendingBlocks pendingBlocks,
final MetricsSystem metricsSystem) {
this.config = config; this.config = config;
this.protocolSchedule = protocolSchedule; this.protocolSchedule = protocolSchedule;
this.protocolContext = protocolContext; this.protocolContext = protocolContext;
@ -79,6 +84,12 @@ public class BlockPropagationManager<C> {
this.syncState = syncState; this.syncState = syncState;
this.pendingBlocks = pendingBlocks; this.pendingBlocks = pendingBlocks;
this.announcedBlockIngestTimer =
metricsSystem.createTimer(
MetricCategory.BLOCKCHAIN,
"pantheon_blockchain_announcedBlock_ingest",
"Time to ingest a single announced block");
} }
public void start() { public void start() {
@ -241,21 +252,24 @@ public class BlockPropagationManager<C> {
final PersistBlockTask<C> importTask = final PersistBlockTask<C> importTask =
PersistBlockTask.create( PersistBlockTask.create(
protocolSchedule, protocolContext, block, HeaderValidationMode.FULL); protocolSchedule, protocolContext, block, HeaderValidationMode.FULL);
final OperationTimer.TimingContext blockTimer = announcedBlockIngestTimer.startTimer();
return ethContext return ethContext
.getScheduler() .getScheduler()
.scheduleWorkerTask(importTask::run) .scheduleWorkerTask(importTask::run)
.whenComplete( .whenComplete(
(r, t) -> { (r, t) -> {
if (t != null) { if (t != null) {
// TODO do we time failures? But we cannot drop a label in at this point.
LOG.warn( LOG.warn(
"Failed to import announced block {} ({}).", "Failed to import announced block {} ({}).",
block.getHeader().getNumber(), block.getHeader().getNumber(),
block.getHash()); block.getHash());
} else { } else {
final double timeInMs = blockTimer.stopTimer() * 1000;
LOG.info( LOG.info(
"Successfully imported announced block {} ({}).", String.format(
block.getHeader().getNumber(), "Successfully imported announced block %d (%s) in %01.3fms.",
block.getHash()); 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.PendingBlocks;
import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState; import tech.pegasys.pantheon.ethereum.eth.sync.state.SyncState;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -40,7 +41,8 @@ public class DefaultSynchronizer<C> implements Synchronizer {
final ProtocolSchedule<C> protocolSchedule, final ProtocolSchedule<C> protocolSchedule,
final ProtocolContext<C> protocolContext, final ProtocolContext<C> protocolContext,
final EthContext ethContext, final EthContext ethContext,
final SyncState syncState) { final SyncState syncState,
final MetricsSystem metricsSystem) {
this.syncState = syncState; this.syncState = syncState;
this.blockPropagationManager = this.blockPropagationManager =
new BlockPropagationManager<>( new BlockPropagationManager<>(
@ -49,7 +51,8 @@ public class DefaultSynchronizer<C> implements Synchronizer {
protocolContext, protocolContext,
ethContext, ethContext,
syncState, syncState,
new PendingBlocks()); new PendingBlocks(),
metricsSystem);
this.downloader = this.downloader =
new Downloader<>(syncConfig, protocolSchedule, protocolContext, ethContext, syncState); 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.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator; import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator;
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator.BlockOptions; 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 tech.pegasys.pantheon.util.uint.UInt256;
import java.util.Collections; import java.util.Collections;
@ -56,6 +58,7 @@ public class BlockPropagationManagerTest {
private SynchronizerConfiguration syncConfig; private SynchronizerConfiguration syncConfig;
private final PendingBlocks pendingBlocks = new PendingBlocks(); private final PendingBlocks pendingBlocks = new PendingBlocks();
private SyncState syncState; private SyncState syncState;
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
@BeforeClass @BeforeClass
public static void setupSuite() { public static void setupSuite() {
@ -87,7 +90,8 @@ public class BlockPropagationManagerTest {
protocolContext, protocolContext,
ethProtocolManager.ethContext(), ethProtocolManager.ethContext(),
syncState, syncState,
pendingBlocks); pendingBlocks,
metricsSystem);
} }
@Test @Test
@ -462,7 +466,8 @@ public class BlockPropagationManagerTest {
protocolContext, protocolContext,
ethProtocolManager.ethContext(), ethProtocolManager.ethContext(),
syncState, syncState,
pendingBlocks); pendingBlocks,
metricsSystem);
final BlockDataGenerator gen = new BlockDataGenerator(); final BlockDataGenerator gen = new BlockDataGenerator();
// Import some blocks // Import some blocks

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

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

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

@ -26,7 +26,7 @@ import java.util.stream.Stream;
public class NoOpMetricsSystem implements MetricsSystem { public class NoOpMetricsSystem implements MetricsSystem {
private static final Counter NO_OP_COUNTER = new NoOpCounter(); 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; private static final OperationTimer NO_OP_TIMER = () -> NO_OP_TIMING_CONTEXT;
@Override @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.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.metrics.MetricsSystem; import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.prometheus.PrometheusMetricsSystem;
import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.nio.file.Path; import java.nio.file.Path;
@ -80,6 +79,7 @@ public class RunnerBuilder {
private WebSocketConfiguration webSocketConfiguration; private WebSocketConfiguration webSocketConfiguration;
private Path dataDir; private Path dataDir;
private Collection<String> bannedNodeIds; private Collection<String> bannedNodeIds;
private MetricsSystem metricsSystem;
private PermissioningConfiguration permissioningConfiguration; private PermissioningConfiguration permissioningConfiguration;
public RunnerBuilder vertx(final Vertx vertx) { public RunnerBuilder vertx(final Vertx vertx) {
@ -143,11 +143,15 @@ public class RunnerBuilder {
return this; return this;
} }
public RunnerBuilder metricsSystem(final MetricsSystem metricsSystem) {
this.metricsSystem = metricsSystem;
return this;
}
public Runner build() { public Runner build() {
Preconditions.checkNotNull(pantheonController); Preconditions.checkNotNull(pantheonController);
final MetricsSystem metricsSystem = PrometheusMetricsSystem.init();
final DiscoveryConfiguration discoveryConfiguration; final DiscoveryConfiguration discoveryConfiguration;
if (discovery) { if (discovery) {
final Collection<?> bootstrap; 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.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException; 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.BlockImporter;
import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.BytesValue;
@ -120,6 +122,8 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
private final Builder synchronizerConfigurationBuilder; private final Builder synchronizerConfigurationBuilder;
private final RunnerBuilder runnerBuilder; private final RunnerBuilder runnerBuilder;
private final MetricsSystem metricsSystem = PrometheusMetricsSystem.init();
// Public IP stored to prevent having to research it each time we need it. // Public IP stored to prevent having to research it each time we need it.
private InetAddress autoDiscoveredDefaultIP = null; private InetAddress autoDiscoveredDefaultIP = null;
@ -446,6 +450,7 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
new MiningParameters(coinbase, minTransactionGasPrice, extraData, isMiningEnabled)) new MiningParameters(coinbase, minTransactionGasPrice, extraData, isMiningEnabled))
.devMode(isDevMode) .devMode(isDevMode)
.nodePrivateKeyFile(getNodePrivateKeyFile()) .nodePrivateKeyFile(getNodePrivateKeyFile())
.metricsSystem(metricsSystem)
.build(); .build();
} catch (final InvalidConfigurationException e) { } catch (final InvalidConfigurationException e) {
throw new ExecutionException(new CommandLine(this), e.getMessage()); throw new ExecutionException(new CommandLine(this), e.getMessage());
@ -520,6 +525,7 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
.webSocketConfiguration(webSocketConfiguration) .webSocketConfiguration(webSocketConfiguration)
.dataDir(dataDir()) .dataDir(dataDir())
.bannedNodeIds(bannedNodeIds) .bannedNodeIds(bannedNodeIds)
.metricsSystem(metricsSystem)
.permissioningConfiguration(permissioningConfiguration) .permissioningConfiguration(permissioningConfiguration)
.build(); .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.eth.sync.SynchronizerConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider; import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -38,6 +39,7 @@ public class PantheonControllerBuilder {
private MiningParameters miningParameters; private MiningParameters miningParameters;
private boolean devMode; private boolean devMode;
private File nodePrivateKeyFile; private File nodePrivateKeyFile;
private MetricsSystem metricsSystem;
public PantheonControllerBuilder synchronizerConfiguration( public PantheonControllerBuilder synchronizerConfiguration(
final SynchronizerConfiguration synchronizerConfiguration) { final SynchronizerConfiguration synchronizerConfiguration) {
@ -75,6 +77,11 @@ public class PantheonControllerBuilder {
return this; return this;
} }
public PantheonControllerBuilder metricsSystem(final MetricsSystem metricsSystem) {
this.metricsSystem = metricsSystem;
return this;
}
public PantheonController<?> build() throws IOException { public PantheonController<?> build() throws IOException {
// instantiate a controller with mainnet config if no genesis file is defined // instantiate a controller with mainnet config if no genesis file is defined
// otherwise use the indicated genesis file // otherwise use the indicated genesis file
@ -90,7 +97,8 @@ public class PantheonControllerBuilder {
DevelopmentProtocolSchedule.create(genesisConfig.getConfigOptions()), DevelopmentProtocolSchedule.create(genesisConfig.getConfigOptions()),
synchronizerConfiguration, synchronizerConfiguration,
miningParameters, miningParameters,
nodeKeys); nodeKeys,
metricsSystem);
} else { } else {
final String genesisConfig = ethNetworkConfig.getGenesisConfig(); final String genesisConfig = ethNetworkConfig.getGenesisConfig();
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisConfig); final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisConfig);
@ -101,7 +109,8 @@ public class PantheonControllerBuilder {
syncWithOttoman, syncWithOttoman,
ethNetworkConfig.getNetworkId(), ethNetworkConfig.getNetworkId(),
miningParameters, 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.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.time.Clock; import java.time.Clock;
@ -104,7 +105,8 @@ public class CliquePantheonController implements PantheonController<CliqueContex
final SynchronizerConfiguration taintedSyncConfig, final SynchronizerConfiguration taintedSyncConfig,
final MiningParameters miningParams, final MiningParameters miningParams,
final int networkId, final int networkId,
final KeyPair nodeKeys) { final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final CliqueConfigOptions cliqueConfig = final CliqueConfigOptions cliqueConfig =
genesisConfig.getConfigOptions().getCliqueConfigOptions(); genesisConfig.getConfigOptions().getCliqueConfigOptions();
final long blocksPerEpoch = cliqueConfig.getEpochLength(); final long blocksPerEpoch = cliqueConfig.getEpochLength();
@ -117,7 +119,7 @@ public class CliquePantheonController implements PantheonController<CliqueContex
final BlockchainStorage blockchainStorage = final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule); storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain = final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage); new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage(); final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage();
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage); final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage);
@ -152,7 +154,8 @@ public class CliquePantheonController implements PantheonController<CliqueContex
protocolSchedule, protocolSchedule,
protocolContext, protocolContext,
ethProtocolManager.ethContext(), ethProtocolManager.ethContext(),
syncState); syncState,
metricsSystem);
final TransactionPool transactionPool = final TransactionPool transactionPool =
TransactionPoolFactory.createTransactionPool( 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.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
@ -72,6 +73,7 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
private final KeyPair keyPair; private final KeyPair keyPair;
private final TransactionPool transactionPool; private final TransactionPool transactionPool;
private final Runnable closer; private final Runnable closer;
private final MetricsSystem metricsStystem;
IbftLegacyPantheonController( IbftLegacyPantheonController(
final GenesisConfigOptions genesisConfig, final GenesisConfigOptions genesisConfig,
@ -82,7 +84,8 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
final Synchronizer synchronizer, final Synchronizer synchronizer,
final KeyPair keyPair, final KeyPair keyPair,
final TransactionPool transactionPool, final TransactionPool transactionPool,
final Runnable closer) { final Runnable closer,
final MetricsSystem metricsSystem) {
this.genesisConfig = genesisConfig; this.genesisConfig = genesisConfig;
this.protocolSchedule = protocolSchedule; this.protocolSchedule = protocolSchedule;
@ -93,6 +96,7 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
this.keyPair = keyPair; this.keyPair = keyPair;
this.transactionPool = transactionPool; this.transactionPool = transactionPool;
this.closer = closer; this.closer = closer;
this.metricsStystem = metricsSystem;
} }
public static PantheonController<IbftContext> init( public static PantheonController<IbftContext> init(
@ -101,14 +105,15 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
final SynchronizerConfiguration taintedSyncConfig, final SynchronizerConfiguration taintedSyncConfig,
final boolean ottomanTestnetOperation, final boolean ottomanTestnetOperation,
final int networkId, final int networkId,
final KeyPair nodeKeys) { final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final ProtocolSchedule<IbftContext> protocolSchedule = final ProtocolSchedule<IbftContext> protocolSchedule =
IbftProtocolSchedule.create(genesisConfig.getConfigOptions()); IbftProtocolSchedule.create(genesisConfig.getConfigOptions());
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final BlockchainStorage blockchainStorage = final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule); storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain = final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage); new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage(); final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage();
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage); final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage);
@ -159,7 +164,8 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
protocolSchedule, protocolSchedule,
protocolContext, protocolContext,
ethProtocolManager.ethContext(), ethProtocolManager.ethContext(),
syncState); syncState,
metricsSystem);
final Runnable closer = final Runnable closer =
() -> { () -> {
@ -183,7 +189,8 @@ public class IbftLegacyPantheonController implements PantheonController<IbftCont
synchronizer, synchronizer,
nodeKeys, nodeKeys,
transactionPool, transactionPool,
closer); closer,
metricsSystem);
} }
@Override @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.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateStorage;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
@ -115,14 +116,15 @@ public class IbftPantheonController implements PantheonController<IbftContext> {
final SynchronizerConfiguration taintedSyncConfig, final SynchronizerConfiguration taintedSyncConfig,
final MiningParameters miningParams, final MiningParameters miningParams,
final int networkId, final int networkId,
final KeyPair nodeKeys) { final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final ProtocolSchedule<IbftContext> protocolSchedule = final ProtocolSchedule<IbftContext> protocolSchedule =
IbftProtocolSchedule.create(genesisConfig.getConfigOptions()); IbftProtocolSchedule.create(genesisConfig.getConfigOptions());
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final BlockchainStorage blockchainStorage = final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule); storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain = final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage); new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage(); final WorldStateStorage worldStateStorage = storageProvider.createWorldStateStorage();
final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage); final WorldStateArchive worldStateArchive = new WorldStateArchive(worldStateStorage);
@ -160,7 +162,8 @@ public class IbftPantheonController implements PantheonController<IbftContext> {
protocolSchedule, protocolSchedule,
protocolContext, protocolContext,
ethProtocolManager.ethContext(), ethProtocolManager.ethContext(),
syncState); syncState,
metricsSystem);
final TransactionPool transactionPool = final TransactionPool transactionPool =
TransactionPoolFactory.createTransactionPool( 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.api.ProtocolManager;
import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration; import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.time.Clock; import java.time.Clock;
@ -90,13 +91,14 @@ public class MainnetPantheonController implements PantheonController<Void> {
final ProtocolSchedule<Void> protocolSchedule, final ProtocolSchedule<Void> protocolSchedule,
final SynchronizerConfiguration taintedSyncConfig, final SynchronizerConfiguration taintedSyncConfig,
final MiningParameters miningParams, final MiningParameters miningParams,
final KeyPair nodeKeys) { final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final BlockchainStorage blockchainStorage = final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule); storageProvider.createBlockchainStorage(protocolSchedule);
final MutableBlockchain blockchain = final MutableBlockchain blockchain =
new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage); new DefaultMutableBlockchain(genesisState.getBlock(), blockchainStorage, metricsSystem);
final WorldStateArchive worldStateArchive = final WorldStateArchive worldStateArchive =
new WorldStateArchive(storageProvider.createWorldStateStorage()); new WorldStateArchive(storageProvider.createWorldStateStorage());
@ -125,7 +127,8 @@ public class MainnetPantheonController implements PantheonController<Void> {
protocolSchedule, protocolSchedule,
protocolContext, protocolContext,
ethProtocolManager.ethContext(), ethProtocolManager.ethContext(),
syncState); syncState,
metricsSystem);
final TransactionPool transactionPool = final TransactionPool transactionPool =
TransactionPoolFactory.createTransactionPool( 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.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration; import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import java.io.Closeable; import java.io.Closeable;
import java.util.Collection; import java.util.Collection;
@ -45,7 +46,8 @@ public interface PantheonController<C> extends Closeable {
final boolean ottomanTestnetOperation, final boolean ottomanTestnetOperation,
final int networkId, final int networkId,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final KeyPair nodeKeys) { final KeyPair nodeKeys,
final MetricsSystem metricsSystem) {
final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions(); final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions();
@ -56,10 +58,17 @@ public interface PantheonController<C> extends Closeable {
MainnetProtocolSchedule.fromConfig(configOptions), MainnetProtocolSchedule.fromConfig(configOptions),
syncConfig, syncConfig,
miningParameters, miningParameters,
nodeKeys); nodeKeys,
metricsSystem);
} else if (configOptions.isRevisedIbft()) { } else if (configOptions.isRevisedIbft()) {
return IbftPantheonController.init( return IbftPantheonController.init(
storageProvider, genesisConfigFile, syncConfig, miningParameters, networkId, nodeKeys); storageProvider,
genesisConfigFile,
syncConfig,
miningParameters,
networkId,
nodeKeys,
metricsSystem);
} else if (configOptions.isIbft()) { } else if (configOptions.isIbft()) {
return IbftLegacyPantheonController.init( return IbftLegacyPantheonController.init(
storageProvider, storageProvider,
@ -67,10 +76,17 @@ public interface PantheonController<C> extends Closeable {
syncConfig, syncConfig,
ottomanTestnetOperation, ottomanTestnetOperation,
networkId, networkId,
nodeKeys); nodeKeys,
metricsSystem);
} else if (configOptions.isClique()) { } else if (configOptions.isClique()) {
return CliquePantheonController.init( return CliquePantheonController.init(
storageProvider, genesisConfigFile, syncConfig, miningParameters, networkId, nodeKeys); storageProvider,
genesisConfigFile,
syncConfig,
miningParameters,
networkId,
nodeKeys,
metricsSystem);
} else { } else {
throw new IllegalArgumentException("Unknown consensus mechanism defined"); 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.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider; 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 tech.pegasys.pantheon.util.uint.UInt256;
import java.io.IOException; import java.io.IOException;
@ -93,6 +95,7 @@ public final class RunnerTest {
// .fastSyncPivotDistance(blockCount / 2).build(); // .fastSyncPivotDistance(blockCount / 2).build();
.fastSyncPivotDistance(0) .fastSyncPivotDistance(0)
.build(); .build();
final MetricsSystem noOpMetricsSystem = new NoOpMetricsSystem();
// Setup state with block data // Setup state with block data
try (final PantheonController<Void> controller = try (final PantheonController<Void> controller =
@ -102,7 +105,8 @@ public final class RunnerTest {
MainnetProtocolSchedule.create(), MainnetProtocolSchedule.create(),
fastSyncConfig, fastSyncConfig,
new MiningParametersTestBuilder().enabled(false).build(), new MiningParametersTestBuilder().enabled(false).build(),
aheadDbNodeKeys)) { aheadDbNodeKeys,
noOpMetricsSystem)) {
setupState(blockCount, controller.getProtocolSchedule(), controller.getProtocolContext()); setupState(blockCount, controller.getProtocolSchedule(), controller.getProtocolContext());
} }
@ -114,7 +118,8 @@ public final class RunnerTest {
MainnetProtocolSchedule.create(), MainnetProtocolSchedule.create(),
fastSyncConfig, fastSyncConfig,
new MiningParametersTestBuilder().enabled(false).build(), new MiningParametersTestBuilder().enabled(false).build(),
aheadDbNodeKeys); aheadDbNodeKeys,
noOpMetricsSystem);
final String listenHost = InetAddress.getLoopbackAddress().getHostAddress(); final String listenHost = InetAddress.getLoopbackAddress().getHostAddress();
final ExecutorService executorService = Executors.newFixedThreadPool(2); final ExecutorService executorService = Executors.newFixedThreadPool(2);
final JsonRpcConfiguration aheadJsonRpcConfiguration = jsonRpcConfiguration(); final JsonRpcConfiguration aheadJsonRpcConfiguration = jsonRpcConfiguration();
@ -127,6 +132,7 @@ public final class RunnerTest {
.discoveryHost(listenHost) .discoveryHost(listenHost)
.discoveryPort(0) .discoveryPort(0)
.maxPeers(3) .maxPeers(3)
.metricsSystem(noOpMetricsSystem)
.bannedNodeIds(Collections.emptySet()); .bannedNodeIds(Collections.emptySet());
final Runner runnerAhead = final Runner runnerAhead =
@ -152,7 +158,8 @@ public final class RunnerTest {
MainnetProtocolSchedule.create(), MainnetProtocolSchedule.create(),
fastSyncConfig, fastSyncConfig,
new MiningParametersTestBuilder().enabled(false).build(), new MiningParametersTestBuilder().enabled(false).build(),
KeyPair.generate()); KeyPair.generate(),
noOpMetricsSystem);
final Runner runnerBehind = final Runner runnerBehind =
runnerBuilder runnerBuilder
.pantheonController(controllerBehind) .pantheonController(controllerBehind)
@ -166,6 +173,7 @@ public final class RunnerTest {
.jsonRpcConfiguration(behindJsonRpcConfiguration) .jsonRpcConfiguration(behindJsonRpcConfiguration)
.webSocketConfiguration(behindWebSocketConfiguration) .webSocketConfiguration(behindWebSocketConfiguration)
.dataDir(temp.newFolder().toPath()) .dataDir(temp.newFolder().toPath())
.metricsSystem(noOpMetricsSystem)
.build(); .build();
executorService.submit(runnerBehind::execute); executorService.submit(runnerBehind::execute);

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

@ -102,6 +102,7 @@ public class PantheonCommandTest extends CommandTestAbstract {
when(mockRunnerBuilder.permissioningConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.permissioningConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.dataDir(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.dataDir(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.bannedNodeIds(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.bannedNodeIds(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.metricsSystem(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.build()).thenReturn(mockRunner); 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.InMemoryStorageProvider;
import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder; import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder;
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration; 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.testutil.BlockTestUtil;
import tech.pegasys.pantheon.util.uint.UInt256; import tech.pegasys.pantheon.util.uint.UInt256;
@ -53,7 +54,8 @@ public final class BlockImporterTest {
false, false,
1, 1,
new MiningParametersTestBuilder().enabled(false).build(), new MiningParametersTestBuilder().enabled(false).build(),
KeyPair.generate()); KeyPair.generate(),
new NoOpMetricsSystem());
final BlockImporter.ImportResult result = final BlockImporter.ImportResult result =
blockImporter.importBlockchain(source, targetController); blockImporter.importBlockchain(source, targetController);
assertThat(result.count).isEqualTo(1000); assertThat(result.count).isEqualTo(1000);
@ -83,7 +85,8 @@ public final class BlockImporterTest {
false, false,
10, 10,
new MiningParametersTestBuilder().enabled(false).build(), new MiningParametersTestBuilder().enabled(false).build(),
KeyPair.generate()); KeyPair.generate(),
new NoOpMetricsSystem());
final BlockImporter.ImportResult result = blockImporter.importBlockchain(source, controller); final BlockImporter.ImportResult result = blockImporter.importBlockchain(source, controller);
assertThat(result.count).isEqualTo(959); assertThat(result.count).isEqualTo(959);

Loading…
Cancel
Save