PIE-1858: Infrastructure for exposing PoA metrics for plugins. (#37)

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

Signed-off-by: Mark Terry <mark.terry@consensys.net>
pull/66/head
mark-terry 5 years ago committed by GitHub
parent f68a1cdb81
commit e1e720d905
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  2. 4
      besu/src/main/java/org/hyperledger/besu/cli/converter/MetricCategoryConverter.java
  3. 3
      besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
  4. 3
      besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java
  5. 2
      besu/src/main/java/org/hyperledger/besu/controller/IbftLegacyBesuControllerBuilder.java
  6. 6
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueBlockInterface.java
  7. 14
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueContext.java
  8. 4
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueDifficultyCalculatorTest.java
  9. 22
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/NodeCanProduceNextBlockTest.java
  10. 4
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java
  11. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java
  12. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMiningCoordinatorTest.java
  13. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueDifficultyValidationRuleTest.java
  14. 5
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueExtraDataValidationRuleTest.java
  15. 4
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/BlockInterface.java
  16. 19
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/PoAContext.java
  17. 44
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/PoAMetricServiceImpl.java
  18. 4
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java
  19. 5
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftBlockInterface.java
  20. 16
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftContext.java
  21. 6
      consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterface.java
  22. 23
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java
  23. 35
      metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java
  24. 3
      metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java
  25. 2
      plugin-api/build.gradle
  26. 41
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/PoAMetricsService.java

@ -60,6 +60,8 @@ import org.hyperledger.besu.cli.util.CommandLineUtils;
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;
@ -86,6 +88,7 @@ import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider;
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;
@ -99,6 +102,8 @@ import org.hyperledger.besu.plugin.services.PicoCLIOptions;
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;
@ -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;
@ -822,7 +830,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
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);
@ -848,11 +855,17 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
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;
}
@ -894,11 +907,25 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
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) {

@ -39,4 +39,8 @@ public class MetricCategoryConverter implements CommandLine.ITypeConverter<Metri
EnumSet.allOf(categoryEnum)
.forEach(category -> metricCategories.put(category.name(), category));
}
public void addRegistryCategory(final MetricCategory metricCategory) {
metricCategories.put(metricCategory.getName(), metricCategory);
}
}

@ -148,6 +148,7 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder<CliqueCon
epochManager,
blockInterface),
new VoteProposer(),
epochManager);
epochManager,
blockInterface);
}
}

@ -239,6 +239,7 @@ public class IbftBesuControllerBuilder extends BesuControllerBuilder<IbftContext
new VoteTallyUpdater(epochManager, new IbftBlockInterface()),
epochManager,
new IbftBlockInterface()),
new VoteProposer());
new VoteProposer(),
blockInterface);
}
}

@ -88,7 +88,7 @@ public class IbftLegacyBesuControllerBuilder extends BesuControllerBuilder<IbftC
blockInterface);
final VoteProposer voteProposer = new VoteProposer();
return new IbftContext(voteTallyCache, voteProposer);
return new IbftContext(voteTallyCache, voteProposer, blockInterface);
}
@Override

@ -45,6 +45,12 @@ public class CliqueBlockInterface implements BlockInterface {
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();

@ -14,7 +14,9 @@
*/
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;
@ -22,19 +24,22 @@ 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() {
@ -48,4 +53,9 @@ public class CliqueContext {
public EpochManager getEpochManager() {
return epochManager;
}
@Override
public BlockInterface getBlockInterface() {
return blockInterface;
}
}

@ -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() {
@ -57,7 +58,8 @@ public class CliqueDifficultyCalculatorTest {
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();
}

@ -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;
@ -78,7 +79,8 @@ public class NodeCanProduceNextBlockTest {
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());
@ -103,7 +105,8 @@ public class NodeCanProduceNextBlockTest {
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());
@ -137,7 +140,8 @@ public class NodeCanProduceNextBlockTest {
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);
@ -167,7 +171,8 @@ public class NodeCanProduceNextBlockTest {
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);
@ -212,7 +217,8 @@ public class NodeCanProduceNextBlockTest {
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);
@ -241,7 +247,8 @@ public class NodeCanProduceNextBlockTest {
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);
@ -265,7 +272,8 @@ public class NodeCanProduceNextBlockTest {
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);

@ -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();
@ -87,7 +88,8 @@ public class CliqueBlockCreatorTest {
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();

@ -22,6 +22,7 @@ import static org.mockito.Mockito.when;
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;
@ -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() {
@ -78,7 +80,8 @@ public class CliqueMinerExecutorTest {
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();
}

@ -24,6 +24,7 @@ import static org.mockito.Mockito.times;
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;
@ -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;
@ -82,7 +84,8 @@ public class CliqueMiningCoordinatorTest {
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);

@ -19,6 +19,7 @@ import static org.mockito.ArgumentMatchers.any;
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;
@ -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() {
@ -56,7 +58,8 @@ public class CliqueDifficultyValidationRuleTest {
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();
}

@ -19,6 +19,7 @@ import static org.mockito.ArgumentMatchers.any;
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.CliqueExtraData;
import org.hyperledger.besu.consensus.clique.TestHelpers;
@ -44,6 +45,7 @@ public class CliqueExtraDataValidationRuleTest {
private final KeyPair proposerKeyPair = KeyPair.generate();
private Address localAddr;
private final CliqueBlockInterface blockInterface = new CliqueBlockInterface();
private final List<Address> validatorList = Lists.newArrayList();
private ProtocolContext<CliqueContext> cliqueProtocolContext;
@ -58,7 +60,8 @@ public class CliqueExtraDataValidationRuleTest {
final VoteTallyCache voteTallyCache = mock(VoteTallyCache.class);
when(voteTallyCache.getVoteTallyAfterBlock(any())).thenReturn(new VoteTally(validatorList));
final CliqueContext cliqueContext = new CliqueContext(voteTallyCache, null, null);
final CliqueContext cliqueContext =
new CliqueContext(voteTallyCache, null, null, blockInterface);
cliqueProtocolContext = new ProtocolContext<>(null, null, cliqueContext);
}

@ -22,7 +22,9 @@ import java.util.Optional;
public interface BlockInterface {
Address getProposerOfBlock(final BlockHeader header);
Address getProposerOfBlock(final org.hyperledger.besu.ethereum.core.BlockHeader header);
Address getProposerOfBlock(final org.hyperledger.besu.plugin.data.BlockHeader header);
Optional<ValidatorVote> extractVoteFromHeader(final BlockHeader header);

@ -0,0 +1,19 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.common;
public interface PoAContext {
BlockInterface getBlockInterface();
}

@ -0,0 +1,44 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.common;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.plugin.data.Address;
import org.hyperledger.besu.plugin.data.BlockHeader;
import org.hyperledger.besu.plugin.services.metrics.PoAMetricsService;
import java.util.ArrayList;
import java.util.Collection;
public class PoAMetricServiceImpl implements PoAMetricsService {
private final BlockInterface blockInterface;
private final Blockchain blockchain;
public PoAMetricServiceImpl(final BlockInterface blockInterface, final Blockchain blockchain) {
this.blockInterface = blockInterface;
this.blockchain = blockchain;
}
@Override
public Collection<Address> getValidatorsForLatestBlock() {
return new ArrayList<>(blockInterface.validatorsInBlock(blockchain.getChainHeadHeader()));
}
@Override
public Address getProposerOfBlock(final BlockHeader header) {
return this.blockInterface.getProposerOfBlock(header);
}
}

@ -284,7 +284,9 @@ public class TestContextBuilder {
final ProtocolContext<IbftContext> protocolContext =
new ProtocolContext<>(
blockChain, worldStateArchive, new IbftContext(voteTallyCache, voteProposer));
blockChain,
worldStateArchive,
new IbftContext(voteTallyCache, voteProposer, blockInterface));
final PendingTransactions pendingTransactions =
new PendingTransactions(

@ -33,6 +33,11 @@ public class IbftBlockInterface implements BlockInterface {
return header.getCoinbase();
}
@Override
public Address getProposerOfBlock(final org.hyperledger.besu.plugin.data.BlockHeader header) {
return Address.fromHexString(header.getCoinbase().getHexString());
}
@Override
public Optional<ValidatorVote> extractVoteFromHeader(final BlockHeader header) {
final IbftExtraData ibftExtraData = IbftExtraData.decode(header);

@ -14,18 +14,25 @@
*/
package org.hyperledger.besu.consensus.ibft;
import org.hyperledger.besu.consensus.common.BlockInterface;
import org.hyperledger.besu.consensus.common.PoAContext;
import org.hyperledger.besu.consensus.common.VoteProposer;
import org.hyperledger.besu.consensus.common.VoteTallyCache;
/** Holds the IBFT specific mutable state. */
public class IbftContext {
public class IbftContext implements PoAContext {
private final VoteTallyCache voteTallyCache;
private final VoteProposer voteProposer;
private final BlockInterface blockInterface;
public IbftContext(final VoteTallyCache voteTallyCache, final VoteProposer voteProposer) {
public IbftContext(
final VoteTallyCache voteTallyCache,
final VoteProposer voteProposer,
final BlockInterface blockInterface) {
this.voteTallyCache = voteTallyCache;
this.voteProposer = voteProposer;
this.blockInterface = blockInterface;
}
public VoteTallyCache getVoteTallyCache() {
@ -35,4 +42,9 @@ public class IbftContext {
public VoteProposer getVoteProposer() {
return voteProposer;
}
@Override
public BlockInterface getBlockInterface() {
return blockInterface;
}
}

@ -46,6 +46,12 @@ public class IbftLegacyBlockInterface implements BlockInterface {
return IbftBlockHashing.recoverProposerAddress(header, ibftExtraData);
}
@Override
public Address getProposerOfBlock(final org.hyperledger.besu.plugin.data.BlockHeader header) {
return getProposerOfBlock(
BlockHeader.convertPluginBlockHeader(header, new LegacyIbftBlockHeaderFunctions()));
}
@Override
public Optional<ValidatorVote> extractVoteFromHeader(final BlockHeader header) {
final Address candidate = header.getCoinbase();

@ -210,4 +210,27 @@ public class BlockHeader extends SealableBlockHeader
sb.append("nonce=").append(nonce);
return sb.append("}").toString();
}
public static org.hyperledger.besu.ethereum.core.BlockHeader convertPluginBlockHeader(
final org.hyperledger.besu.plugin.data.BlockHeader pluginBlockHeader,
final BlockHeaderFunctions blockHeaderFunctions) {
return new org.hyperledger.besu.ethereum.core.BlockHeader(
Hash.fromHexString(pluginBlockHeader.getParentHash().getHexString()),
Hash.fromHexString(pluginBlockHeader.getOmmersHash().getHexString()),
org.hyperledger.besu.ethereum.core.Address.fromHexString(
pluginBlockHeader.getCoinbase().getHexString()),
Hash.fromHexString(pluginBlockHeader.getStateRoot().getHexString()),
Hash.fromHexString(pluginBlockHeader.getTransactionsRoot().getHexString()),
Hash.fromHexString(pluginBlockHeader.getReceiptsRoot().getHexString()),
LogsBloomFilter.fromHexString(pluginBlockHeader.getLogsBloom().getHexString()),
UInt256.fromHexString(pluginBlockHeader.getDifficulty().getHexString()),
pluginBlockHeader.getNumber(),
pluginBlockHeader.getGasLimit(),
pluginBlockHeader.getGasUsed(),
pluginBlockHeader.getTimestamp(),
BytesValue.wrap(pluginBlockHeader.getExtraData().getByteArray()),
Hash.fromHexString(pluginBlockHeader.getMixHash().getHexString()),
pluginBlockHeader.getNonce(),
blockHeaderFunctions);
}
}

@ -0,0 +1,35 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.metrics;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
import java.util.ArrayList;
import java.util.List;
public class MetricCategoryRegistryImpl implements MetricCategoryRegistry {
private final List<MetricCategory> metricCategories = new ArrayList<>();
public List<MetricCategory> getMetricCategories() {
return metricCategories;
}
@Override
public void addMetricCategory(final MetricCategory newMetricCategory) {
metricCategories.add(newMetricCategory);
}
}

@ -156,7 +156,8 @@ public class PrometheusMetricsSystem implements ObservableMetricsSystem {
}
private boolean isCategoryEnabled(final MetricCategory category) {
return enabledCategories.contains(category);
return enabledCategories.stream()
.anyMatch(metricCategory -> metricCategory.getName().equals(category.getName()));
}
public void addCollector(final MetricCategory category, final Collector metric) {

@ -56,7 +56,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'azykDVSB2DOA/rgZyedO8Uwe1eGDGRCMUAZN4FMB3R4='
knownHash = 'b8BCiNvy9vSYsTtS1NfszsVT0EMV8tiNc7igzXzTrak='
}
check.dependsOn('checkAPIChanges')

@ -0,0 +1,41 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.plugin.services.metrics;
import org.hyperledger.besu.plugin.data.Address;
import org.hyperledger.besu.plugin.data.BlockHeader;
import java.util.Collection;
/**
* Provides relevant data for producing metrics on the status of a Proof of Authority (PoA) node.
*/
public interface PoAMetricsService {
/**
* Retrieves the validators who have signed the latest block from the canonical chain.
*
* @return Identities of the validators who formed quorum on the latest block.
*/
Collection<Address> getValidatorsForLatestBlock();
/**
* Retrieves the {@link Address} for the proposer of a block on the canonical chain.
*
* @param header The {@link BlockHeader} for which the proposer will be found.
* @return The identity of the proposer for the given block.
*/
Address getProposerOfBlock(final BlockHeader header);
}
Loading…
Cancel
Save