Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BFT validator RPCs to use validator provider #2592

Merged
merged 16 commits into from
Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ public BesuController build() {
ethProtocolManager);

final PluginServiceFactory additionalPluginServices =
createAdditionalPluginServices(blockchain);
createAdditionalPluginServices(blockchain, protocolContext);

final SubProtocolConfiguration subProtocolConfiguration =
createSubProtocolConfiguration(ethProtocolManager);
Expand Down Expand Up @@ -482,5 +482,5 @@ private List<PeerValidator> createPeerValidators(final ProtocolSchedule protocol
}

protected abstract PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain);
final Blockchain blockchain, final ProtocolContext protocolContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
import org.hyperledger.besu.consensus.common.bft.queries.BftQueryServiceImpl;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.plugin.services.metrics.PoAMetricsService;
Expand All @@ -28,16 +29,19 @@ public class BftQueryPluginServiceFactory implements PluginServiceFactory {

private final Blockchain blockchain;
private final BftExtraDataCodec bftExtraDataCodec;
private final ValidatorProvider validatorProvider;
private final NodeKey nodeKey;
private final String consensusMechanismName;

public BftQueryPluginServiceFactory(
final Blockchain blockchain,
final BftExtraDataCodec bftExtraDataCodec,
final ValidatorProvider validatorProvider,
final NodeKey nodeKey,
final String consensusMechanismName) {
this.blockchain = blockchain;
this.bftExtraDataCodec = bftExtraDataCodec;
this.validatorProvider = validatorProvider;
this.nodeKey = nodeKey;
this.consensusMechanismName = consensusMechanismName;
}
Expand All @@ -47,7 +51,8 @@ public void appendPluginServices(final BesuPluginContextImpl besuContext) {
final BftBlockInterface blockInterface = new BftBlockInterface(bftExtraDataCodec);

final BftQueryServiceImpl service =
new BftQueryServiceImpl(blockInterface, blockchain, nodeKey, consensusMechanismName);
new BftQueryServiceImpl(
blockInterface, blockchain, validatorProvider, nodeKey, consensusMechanismName);
besuContext.addService(BftQueryService.class, service);
besuContext.addService(PoaQueryService.class, service);
besuContext.addService(PoAMetricsService.class, service);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ protected void validateContext(final ProtocolContext context) {
}

@Override
protected PluginServiceFactory createAdditionalPluginServices(final Blockchain blockchain) {
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
return new CliqueQueryPluginServiceFactory(blockchain, nodeKey);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,12 @@ protected MiningCoordinator createMiningCoordinator(
}

@Override
protected PluginServiceFactory createAdditionalPluginServices(final Blockchain blockchain) {
return new IbftQueryPluginServiceFactory(blockchain, bftBlockInterface().get(), nodeKey);
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(BftContext.class).getValidatorProvider();
return new IbftQueryPluginServiceFactory(
blockchain, bftBlockInterface().get(), validatorProvider, nodeKey);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ protected IbftLegacyContext createConsensusContext(
}

@Override
protected PluginServiceFactory createAdditionalPluginServices(final Blockchain blockchain) {
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
return new NoopPluginServiceFactory();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
import org.hyperledger.besu.consensus.common.bft.queries.BftQueryServiceImpl;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.consensus.ibft.queries.IbftQueryServiceImpl;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.ethereum.chain.Blockchain;
Expand All @@ -29,12 +30,17 @@ public class IbftQueryPluginServiceFactory implements PluginServiceFactory {

private final Blockchain blockchain;
private final BftBlockInterface blockInterface;
private final ValidatorProvider validatorProvider;
private final NodeKey nodeKey;

public IbftQueryPluginServiceFactory(
final Blockchain blockchain, final BftBlockInterface blockInterface, final NodeKey nodeKey) {
final Blockchain blockchain,
final BftBlockInterface blockInterface,
final ValidatorProvider validatorProvider,
final NodeKey nodeKey) {
this.blockchain = blockchain;
this.blockInterface = blockInterface;
this.validatorProvider = validatorProvider;
this.nodeKey = nodeKey;
}

Expand All @@ -47,7 +53,7 @@ public void appendPluginServices(final BesuPluginContextImpl besuContext) {
besuContext.addService(PoAMetricsService.class, service);

final BftQueryServiceImpl bftService =
new BftQueryServiceImpl(blockInterface, blockchain, nodeKey, "ibft");
new BftQueryServiceImpl(blockInterface, blockchain, validatorProvider, nodeKey, "ibft");
besuContext.addService(BftQueryService.class, bftService);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ protected Void createConsensusContext(
}

@Override
protected PluginServiceFactory createAdditionalPluginServices(final Blockchain blockchain) {
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
return new NoopPluginServiceFactory();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,12 @@ protected MiningCoordinator createMiningCoordinator(
}

@Override
protected PluginServiceFactory createAdditionalPluginServices(final Blockchain blockchain) {
return new BftQueryPluginServiceFactory(blockchain, bftExtraDataCodec().get(), nodeKey, "qbft");
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(BftContext.class).getValidatorProvider();
return new BftQueryPluginServiceFactory(
blockchain, bftExtraDataCodec().get(), validatorProvider, nodeKey, "qbft");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hyperledger.besu.consensus.common.PoaQueryServiceImpl;
import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
Expand All @@ -31,16 +32,19 @@

public class BftQueryServiceImpl extends PoaQueryServiceImpl implements BftQueryService {

private final ValidatorProvider validatorProvider;
private final String consensusMechanismName;
private final BftBlockInterface bftBlockInterface;

public BftQueryServiceImpl(
final BftBlockInterface blockInterface,
final Blockchain blockchain,
final ValidatorProvider validatorProvider,
final NodeKey nodeKey,
final String consensusMechanismName) {
super(blockInterface, blockchain, nodeKey);
this.bftBlockInterface = blockInterface;
this.validatorProvider = validatorProvider;
this.consensusMechanismName = consensusMechanismName;
}

Expand All @@ -58,6 +62,11 @@ public Collection<Address> getSignersFrom(
return Collections.unmodifiableList(bftBlockInterface.getCommitters(headerFromChain));
}

@Override
public Collection<Address> getValidatorsForLatestBlock() {
return Collections.unmodifiableCollection(validatorProvider.getValidatorsAtHead());
}

@Override
public String getConsensusMechanismName() {
return consensusMechanismName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public interface ValidatorProvider {

Collection<Address> getValidatorsAtHead();

Collection<Address> getValidatorsAfterBlock(final BlockHeader header);
Collection<Address> getValidatorsAfterBlock(BlockHeader header);

Collection<Address> getValidatorsForBlock(BlockHeader header);

Optional<VoteProvider> getVoteProvider();
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class BlockValidatorProvider implements ValidatorProvider {

private final VoteTallyCache voteTallyCache;
private final VoteProvider voteProvider;
private final BlockInterface blockInterface;

public static ValidatorProvider forkingValidatorProvider(
final Blockchain blockchain,
Expand Down Expand Up @@ -65,6 +66,7 @@ private BlockValidatorProvider(
blockInterface,
new BftValidatorOverrides(validatorForkMap));
this.voteProvider = new BlockVoteProvider(voteTallyCache, voteProposer);
this.blockInterface = blockInterface;
}

@Override
Expand All @@ -77,6 +79,11 @@ public Collection<Address> getValidatorsAfterBlock(final BlockHeader header) {
return voteTallyCache.getVoteTallyAfterBlock(header).getValidators();
}

@Override
public Collection<Address> getValidatorsForBlock(final BlockHeader header) {
return blockInterface.validatorsInBlock(header);
}

@Override
public Optional<VoteProvider> getVoteProvider() {
return Optional.of(voteProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.crypto.NodeKeyUtils;
import org.hyperledger.besu.ethereum.chain.Blockchain;
Expand Down Expand Up @@ -56,6 +57,8 @@ public class BftQueryServiceImplTest {

@Mock private BftBlockInterface bftBlockInterface;

@Mock private ValidatorProvider validatorProvider;

private final List<NodeKey> validatorKeys =
Lists.newArrayList(NodeKeyUtils.generate(), NodeKeyUtils.generate());

Expand All @@ -76,7 +79,7 @@ public void setup() {
@Test
public void roundNumberFromBlockIsReturned() {
final BftQueryService service =
new BftQueryServiceImpl(bftBlockInterface, blockchain, null, null);
new BftQueryServiceImpl(bftBlockInterface, blockchain, validatorProvider, null, null);
final int roundNumberInBlock = 5;
final BftExtraData extraData =
new BftExtraData(Bytes.EMPTY, List.of(), Optional.empty(), roundNumberInBlock, List.of());
Expand All @@ -90,15 +93,16 @@ public void getRoundNumberThrowsIfBlockIsNotOnTheChain() {
final NonBesuBlockHeader header = new NonBesuBlockHeader(Hash.EMPTY, Bytes.EMPTY);

final BftQueryService service =
new BftQueryServiceImpl(new BftBlockInterface(bftExtraDataCodec), blockchain, null, null);
new BftQueryServiceImpl(
new BftBlockInterface(bftExtraDataCodec), blockchain, validatorProvider, null, null);
assertThatExceptionOfType(NoSuchElementException.class)
.isThrownBy(() -> service.getRoundNumberFrom(header));
}

@Test
public void getSignersReturnsAddressesOfSignersInBlock() {
final BftQueryService service =
new BftQueryServiceImpl(bftBlockInterface, blockchain, null, null);
new BftQueryServiceImpl(bftBlockInterface, blockchain, validatorProvider, null, null);

final List<Address> signers =
signingKeys.stream()
Expand All @@ -114,7 +118,7 @@ public void getSignersThrowsIfBlockIsNotOnTheChain() {
final NonBesuBlockHeader header = new NonBesuBlockHeader(Hash.EMPTY, Bytes.EMPTY);

final BftQueryService service =
new BftQueryServiceImpl(bftBlockInterface, blockchain, null, null);
new BftQueryServiceImpl(bftBlockInterface, blockchain, validatorProvider, null, null);
assertThatExceptionOfType(NoSuchElementException.class)
.isThrownBy(() -> service.getSignersFrom(header));
}
Expand All @@ -123,7 +127,25 @@ public void getSignersThrowsIfBlockIsNotOnTheChain() {
public void consensusMechanismNameReturnedIsSameAsThatPassedDuringCreation() {
final BftQueryService service =
new BftQueryServiceImpl(
new BftBlockInterface(bftExtraDataCodec), blockchain, null, "consensusMechanism");
new BftBlockInterface(bftExtraDataCodec),
blockchain,
validatorProvider,
null,
"consensusMechanism");
assertThat(service.getConsensusMechanismName()).isEqualTo("consensusMechanism");
}

@Test
public void getValidatorsReturnsAddresses() {
final BftQueryService service =
new BftQueryServiceImpl(bftBlockInterface, blockchain, validatorProvider, null, null);

final List<Address> validators =
signingKeys.stream()
.map(nodeKey -> Util.publicKeyToAddress(nodeKey.getPublicKey()))
.collect(Collectors.toList());
when(validatorProvider.getValidatorsAtHead()).thenReturn(validators);

assertThat(service.getValidatorsForLatestBlock()).containsExactlyElementsOf(validators);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ protected Map<String, JsonRpcMethod> create() {

return mapOf(
new QbftProposeValidatorVote(validatorProvider),
new QbftGetValidatorsByBlockNumber(blockchainQueries, blockInterface),
new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider),
new QbftDiscardValidatorVote(validatorProvider),
new QbftGetValidatorsByBlockHash(context.getBlockchain(), blockInterface),
new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider),
new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries),
new QbftGetPendingVotes(validatorProvider));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
*/
package org.hyperledger.besu.consensus.qbft.jsonrpc.methods;

import org.hyperledger.besu.consensus.common.BlockInterface;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Hash;

Expand All @@ -34,12 +35,12 @@ public class QbftGetValidatorsByBlockHash implements JsonRpcMethod {
private static final Logger LOG = LogManager.getLogger();

private final Blockchain blockchain;
private final BlockInterface blockInterface;
private final ValidatorProvider validatorProvider;

public QbftGetValidatorsByBlockHash(
final Blockchain blockchain, final BlockInterface blockInterface) {
final Blockchain blockchain, final ValidatorProvider validatorProvider) {
this.blockchain = blockchain;
this.blockInterface = blockInterface;
this.validatorProvider = validatorProvider;
}

@Override
Expand All @@ -60,8 +61,8 @@ private Object blockResult(final JsonRpcRequestContext request) {
return blockHeader
.map(
header ->
blockInterface.validatorsInBlock(header).stream()
.map(validator -> validator.toString())
validatorProvider.getValidatorsForBlock(header).stream()
.map(Address::toString)
.collect(Collectors.toList()))
.orElse(null);
}
Expand Down
Loading