Skip to content

Commit

Permalink
PIE-1858: Infrastructure for exposing PoA metrics for plugins. (hyper…
Browse files Browse the repository at this point in the history
…ledger#37)

[PIE-1858] Added functionality to register custom metrics categories and exposed some PoA data for metrics.

Signed-off-by: Mark Terry <[email protected]>
Signed-off-by: edwardmack <[email protected]>
  • Loading branch information
mark-terry authored and edwardmack committed Nov 4, 2019
1 parent 74e0008 commit 615e966
Show file tree
Hide file tree
Showing 26 changed files with 289 additions and 26 deletions.
31 changes: 29 additions & 2 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
import org.hyperledger.besu.cli.util.ConfigOptionSearchAndRunHandler;
import org.hyperledger.besu.cli.util.VersionProvider;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.consensus.common.PoAContext;
import org.hyperledger.besu.consensus.common.PoAMetricServiceImpl;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.controller.BesuControllerBuilder;
import org.hyperledger.besu.controller.KeyPairUtil;
Expand All @@ -86,6 +88,7 @@
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder;
import org.hyperledger.besu.ethereum.worldstate.PruningConfiguration;
import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.metrics.StandardMetricCategory;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
Expand All @@ -99,6 +102,8 @@
import org.hyperledger.besu.plugin.services.StorageService;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
import org.hyperledger.besu.plugin.services.metrics.PoAMetricsService;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBPlugin;
import org.hyperledger.besu.services.BesuConfigurationImpl;
import org.hyperledger.besu.services.BesuEventsImpl;
Expand Down Expand Up @@ -185,6 +190,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private final BesuPluginContextImpl besuPluginContext;
private final StorageServiceImpl storageService;
private final Map<String, String> environment;
private final MetricCategoryRegistryImpl metricCategoryRegistry =
new MetricCategoryRegistryImpl();
private final MetricCategoryConverter metricCategoryConverter = new MetricCategoryConverter();

protected KeyLoader getKeyLoader() {
return KeyPairUtil::loadKeyPair;
Expand Down Expand Up @@ -822,7 +830,6 @@ private BesuCommand registerConverters() {
commandLine.registerConverter(Wei.class, (arg) -> Wei.of(Long.parseUnsignedLong(arg)));
commandLine.registerConverter(PositiveNumber.class, PositiveNumber::fromString);

final MetricCategoryConverter metricCategoryConverter = new MetricCategoryConverter();
metricCategoryConverter.addCategories(BesuMetricCategory.class);
metricCategoryConverter.addCategories(StandardMetricCategory.class);
commandLine.registerConverter(MetricCategory.class, metricCategoryConverter);
Expand All @@ -848,11 +855,17 @@ private BesuCommand handleUnstableOptions() {
private BesuCommand preparePlugins() {
besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
besuPluginContext.addService(StorageService.class, storageService);
besuPluginContext.addService(MetricCategoryRegistry.class, metricCategoryRegistry);

// register built-in plugins
new RocksDBPlugin().register(besuPluginContext);

besuPluginContext.registerPlugins(pluginsDir());

metricCategoryRegistry
.getMetricCategories()
.forEach(metricCategoryConverter::addRegistryCategory);

return this;
}

Expand Down Expand Up @@ -894,11 +907,25 @@ private BesuCommand startPlugins() {
besuController.getProtocolManager().getBlockBroadcaster(),
besuController.getTransactionPool(),
besuController.getSyncState()));
besuPluginContext.addService(MetricsSystem.class, getMetricsSystem());
addPluginMetrics(besuController);
besuPluginContext.startPlugins();
return this;
}

private void addPluginMetrics(final BesuController<?> besuController) {
besuPluginContext.addService(MetricsSystem.class, getMetricsSystem());

final Object consensusState = besuController.getProtocolContext().getConsensusState();

if (consensusState != null && PoAContext.class.isAssignableFrom(consensusState.getClass())) {
final PoAMetricServiceImpl service =
new PoAMetricServiceImpl(
((PoAContext) consensusState).getBlockInterface(),
besuController.getProtocolContext().getBlockchain());
besuPluginContext.addService(PoAMetricsService.class, service);
}
}

private void prepareLogging() {
// set log level per CLI flags
if (logLevel != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ public <T extends Enum<T> & MetricCategory> void addCategories(final Class<T> ca
EnumSet.allOf(categoryEnum)
.forEach(category -> metricCategories.put(category.name(), category));
}

public void addRegistryCategory(final MetricCategory metricCategory) {
metricCategories.put(metricCategory.getName(), metricCategory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ protected CliqueContext createConsensusContext(
epochManager,
blockInterface),
new VoteProposer(),
epochManager);
epochManager,
blockInterface);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ protected IbftContext createConsensusContext(
new VoteTallyUpdater(epochManager, new IbftBlockInterface()),
epochManager,
new IbftBlockInterface()),
new VoteProposer());
new VoteProposer(),
blockInterface);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ protected IbftContext createConsensusContext(
blockInterface);

final VoteProposer voteProposer = new VoteProposer();
return new IbftContext(voteTallyCache, voteProposer);
return new IbftContext(voteTallyCache, voteProposer, blockInterface);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ public Address getProposerOfBlock(final BlockHeader header) {
return CliqueHelpers.getProposerOfBlock(header);
}

@Override
public Address getProposerOfBlock(final org.hyperledger.besu.plugin.data.BlockHeader header) {
return getProposerOfBlock(
BlockHeader.convertPluginBlockHeader(header, new CliqueBlockHeaderFunctions()));
}

@Override
public Optional<ValidatorVote> extractVoteFromHeader(final BlockHeader header) {
final Address candidate = header.getCoinbase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,32 @@
*/
package org.hyperledger.besu.consensus.clique;

import org.hyperledger.besu.consensus.common.BlockInterface;
import org.hyperledger.besu.consensus.common.EpochManager;
import org.hyperledger.besu.consensus.common.PoAContext;
import org.hyperledger.besu.consensus.common.VoteProposer;
import org.hyperledger.besu.consensus.common.VoteTallyCache;

/**
* Holds the data which lives "in parallel" with the importation of blocks etc. when using the
* Clique consensus mechanism.
*/
public class CliqueContext {
public class CliqueContext implements PoAContext {

private final VoteTallyCache voteTallyCache;
private final VoteProposer voteProposer;
private final EpochManager epochManager;
private final BlockInterface blockInterface;

public CliqueContext(
final VoteTallyCache voteTallyCache,
final VoteProposer voteProposer,
final EpochManager epochManager) {
final EpochManager epochManager,
final BlockInterface blockInterface) {
this.voteTallyCache = voteTallyCache;
this.voteProposer = voteProposer;
this.epochManager = epochManager;
this.blockInterface = blockInterface;
}

public VoteTallyCache getVoteTallyCache() {
Expand All @@ -48,4 +53,9 @@ public VoteProposer getVoteProposer() {
public EpochManager getEpochManager() {
return epochManager;
}

@Override
public BlockInterface getBlockInterface() {
return blockInterface;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class CliqueDifficultyCalculatorTest {
private final List<Address> validatorList = Lists.newArrayList();
private ProtocolContext<CliqueContext> cliqueProtocolContext;
private BlockHeaderTestFixture blockHeaderBuilder;
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();

@Before
public void setup() {
Expand All @@ -57,7 +58,8 @@ public void setup() {
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();

final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(null, null, cliqueContext);
blockHeaderBuilder = new BlockHeaderTestFixture();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class NodeCanProduceNextBlockTest {
private final List<Address> validatorList = Lists.newArrayList();
private final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture();
private ProtocolContext<CliqueContext> cliqueProtocolContext;
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();

MutableBlockchain blockChain;
private Block genesisBlock;
Expand Down Expand Up @@ -78,7 +79,8 @@ public void networkWithOneValidatorIsAllowedToCreateConsecutiveBlocks() {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.number(1).parentHash(genesisBlock.getHash());
Expand All @@ -103,7 +105,8 @@ public void networkWithTwoValidatorsIsAllowedToProduceBlockIfNotPreviousBlockPro
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.number(1).parentHash(genesisBlock.getHash());
Expand Down Expand Up @@ -137,7 +140,8 @@ public void networkWithTwoValidatorsIsNotAllowedToProduceBlockIfIsPreviousBlockP
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.parentHash(genesisBlock.getHash()).number(1);
Expand Down Expand Up @@ -167,7 +171,8 @@ public void withThreeValidatorsMustHaveOneBlockBetweenSignings() {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.parentHash(genesisBlock.getHash()).number(1);
Expand Down Expand Up @@ -212,7 +217,8 @@ public void signerIsValidIfInsufficientBlocksExistInHistory() {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.parentHash(genesisBlock.getHash()).number(1);
Expand Down Expand Up @@ -241,7 +247,8 @@ public void exceptionIsThrownIfOnAnOrphanedChain() {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.parentHash(Hash.ZERO).number(3);
Expand All @@ -265,7 +272,8 @@ public void nonValidatorIsNotAllowedToCreateABlock() {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(blockChain, null, cliqueContext);

headerBuilder.parentHash(Hash.ZERO).number(3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public class CliqueBlockCreatorTest {
private final KeyPair otherKeyPair = KeyPair.generate();
private final List<Address> validatorList = Lists.newArrayList();
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();

private ProtocolSchedule<CliqueContext> protocolSchedule;
private final WorldStateArchive stateArchive = createInMemoryWorldStateArchive();
Expand All @@ -87,7 +88,8 @@ public void setup() {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
voteProposer = new VoteProposer();
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);

final Block genesis =
GenesisState.fromConfig(GenesisConfigFile.mainnet(), protocolSchedule).getBlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions;
import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.clique.CliqueExtraData;
import org.hyperledger.besu.consensus.clique.CliqueProtocolSchedule;
Expand Down Expand Up @@ -65,6 +66,7 @@ public class CliqueMinerExecutorTest {
private ProtocolContext<CliqueContext> cliqueProtocolContext;
private BlockHeaderTestFixture blockHeaderBuilder;
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();

@Before
public void setup() {
Expand All @@ -78,7 +80,8 @@ public void setup() {
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();

final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(null, null, cliqueContext);
blockHeaderBuilder = new BlockHeaderTestFixture();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.clique.CliqueMiningTracker;
import org.hyperledger.besu.consensus.clique.TestHelpers;
Expand Down Expand Up @@ -64,6 +65,7 @@ public class CliqueMiningCoordinatorTest {
private final BlockHeaderTestFixture headerTestFixture = new BlockHeaderTestFixture();

private CliqueMiningTracker miningTracker;
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();

@Mock private MutableBlockchain blockChain;
@Mock private ProtocolContext<CliqueContext> protocolContext;
Expand All @@ -82,7 +84,8 @@ public void setup() {
final VoteTally voteTally = mock(VoteTally.class);
when(voteTally.getValidators()).thenReturn(validators);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(voteTally);
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, null, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, null, null, blockInterface);

when(protocolContext.getConsensusState()).thenReturn(cliqueContext);
when(protocolContext.getBlockchain()).thenReturn(blockChain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.clique.TestHelpers;
import org.hyperledger.besu.consensus.common.VoteProposer;
Expand All @@ -45,6 +46,7 @@ public class CliqueDifficultyValidationRuleTest {
private final List<Address> validatorList = Lists.newArrayList();
private ProtocolContext<CliqueContext> cliqueProtocolContext;
private BlockHeaderTestFixture blockHeaderBuilder;
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();

@Before
public void setup() {
Expand All @@ -56,7 +58,8 @@ public void setup() {
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final VoteProposer voteProposer = new VoteProposer();

final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, voteProposer, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, voteProposer, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(null, null, cliqueContext);
blockHeaderBuilder = new BlockHeaderTestFixture();
}
Expand Down
Loading

0 comments on commit 615e966

Please sign in to comment.