consensus context changes in support of merge context (#2976)

Signed-off-by: garyschulte <garyschulte@gmail.com>
This commit is contained in:
garyschulte
2021-11-04 13:29:58 -07:00
committed by GitHub
parent ec7fc4781a
commit a2f517ce32
50 changed files with 153 additions and 81 deletions

View File

@@ -34,6 +34,7 @@ dependencies {
implementation project(':consensus:common')
implementation project(':consensus:ibft')
implementation project(':consensus:ibftlegacy')
implementation project(':consensus:merge')
implementation project(':consensus:qbft')
implementation project(':crypto')
implementation project(':datatypes')

View File

@@ -20,6 +20,7 @@ import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ConsensusContext;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.methods.JsonRpcMethods;
@@ -86,8 +87,8 @@ public abstract class BesuControllerBuilder {
private static final Logger LOG = LogManager.getLogger();
protected GenesisConfigFile genesisConfig;
private SynchronizerConfiguration syncConfig;
private EthProtocolConfiguration ethereumWireProtocolConfiguration;
protected SynchronizerConfiguration syncConfig;
protected EthProtocolConfiguration ethereumWireProtocolConfiguration;
protected TransactionPoolConfiguration transactionPoolConfiguration;
protected BigInteger networkId;
protected MiningParameters miningParameters;
@@ -100,15 +101,15 @@ public abstract class BesuControllerBuilder {
protected NodeKey nodeKey;
protected boolean isRevertReasonEnabled;
GasLimitCalculator gasLimitCalculator;
private StorageProvider storageProvider;
private boolean isPruningEnabled;
private PrunerConfiguration prunerConfiguration;
Map<String, String> genesisConfigOverrides;
private Map<Long, Hash> requiredBlocks = Collections.emptyMap();
private long reorgLoggingThreshold;
private DataStorageConfiguration dataStorageConfiguration =
protected StorageProvider storageProvider;
protected boolean isPruningEnabled;
protected PrunerConfiguration prunerConfiguration;
protected Map<String, String> genesisConfigOverrides;
protected Map<Long, Hash> requiredBlocks = Collections.emptyMap();
protected long reorgLoggingThreshold;
protected DataStorageConfiguration dataStorageConfiguration =
DataStorageConfiguration.DEFAULT_CONFIG;
private List<NodeMessagePermissioningProvider> messagePermissioningProviders =
protected List<NodeMessagePermissioningProvider> messagePermissioningProviders =
Collections.emptyList();
protected EvmConfiguration evmConfiguration;
@@ -416,7 +417,7 @@ public abstract class BesuControllerBuilder {
protected void validateContext(final ProtocolContext context) {}
protected abstract Object createConsensusContext(
protected abstract ConsensusContext createConsensusContext(
Blockchain blockchain,
WorldStateArchive worldStateArchive,
ProtocolSchedule protocolSchedule);

View File

@@ -86,7 +86,7 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
miningParameters,
new CliqueBlockScheduler(
clock,
protocolContext.getConsensusState(CliqueContext.class).getValidatorProvider(),
protocolContext.getConsensusContext(CliqueContext.class).getValidatorProvider(),
localAddress,
secondsBetweenBlocks),
epochManager);

View File

@@ -141,7 +141,7 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
bftExtraDataCodec().get());
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(BftContext.class).getValidatorProvider();
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider();
final ProposerSelector proposerSelector =
new ProposerSelector(blockchain, bftBlockInterface().get(), true, validatorProvider);
@@ -226,7 +226,7 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(BftContext.class).getValidatorProvider();
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider();
return new IbftQueryPluginServiceFactory(
blockchain, bftBlockInterface().get(), validatorProvider, nodeKey);
}

View File

@@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.controller;
import org.hyperledger.besu.ethereum.ConsensusContext;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.blockcreation.DefaultBlockScheduler;
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
@@ -74,7 +75,7 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
}
@Override
protected Void createConsensusContext(
protected ConsensusContext createConsensusContext(
final Blockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule) {

View File

@@ -181,7 +181,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
qbftForksSchedule);
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(BftContext.class).getValidatorProvider();
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider();
final ProposerSelector proposerSelector =
new ProposerSelector(blockchain, bftBlockInterface().get(), true, validatorProvider);
@@ -268,7 +268,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
protected PluginServiceFactory createAdditionalPluginServices(
final Blockchain blockchain, final ProtocolContext protocolContext) {
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(BftContext.class).getValidatorProvider();
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider();
return new BftQueryPluginServiceFactory(
blockchain, bftExtraDataCodec().get(), validatorProvider, nodeKey, "qbft");
}

View File

@@ -127,22 +127,25 @@ public class BesuControllerBuilderTest {
.thenReturn(mock(WorldStatePreimageStorage.Updater.class));
when(worldStateStorage.updater()).thenReturn(mock(WorldStateStorage.Updater.class));
besuControllerBuilder =
new MainnetBesuControllerBuilder()
.gasLimitCalculator(gasLimitCalculator)
.genesisConfigFile(genesisConfigFile)
.synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration)
.miningParameters(miningParameters)
.metricsSystem(observableMetricsSystem)
.privacyParameters(privacyParameters)
.dataDirectory(tempDirRule.getRoot().toPath())
.clock(clock)
.transactionPoolConfiguration(poolConfiguration)
.nodeKey(nodeKey)
.storageProvider(storageProvider)
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkId(networkId);
besuControllerBuilder = visitWithMockConfigs(new MainnetBesuControllerBuilder());
}
BesuControllerBuilder visitWithMockConfigs(final BesuControllerBuilder builder) {
return builder
.gasLimitCalculator(gasLimitCalculator)
.genesisConfigFile(genesisConfigFile)
.synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration)
.miningParameters(miningParameters)
.metricsSystem(observableMetricsSystem)
.privacyParameters(privacyParameters)
.dataDirectory(tempDirRule.getRoot().toPath())
.clock(clock)
.transactionPoolConfiguration(poolConfiguration)
.nodeKey(nodeKey)
.storageProvider(storageProvider)
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkId(networkId);
}
@Test

View File

@@ -151,7 +151,7 @@ public class QbftBesuControllerBuilderTest {
final ValidatorProvider validatorProvider =
besuController
.getProtocolContext()
.getConsensusState(BftContext.class)
.getConsensusContext(BftContext.class)
.getValidatorProvider();
assertThat(validatorProvider).isInstanceOf(ForkingValidatorProvider.class);
}

View File

@@ -18,6 +18,7 @@ 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.validator.ValidatorProvider;
import org.hyperledger.besu.ethereum.ConsensusContext;
/**
* Holds the data which lives "in parallel" with the importation of blocks etc. when using the
@@ -50,4 +51,9 @@ public class CliqueContext implements PoaContext {
public BlockInterface getBlockInterface() {
return blockInterface;
}
@Override
public <C extends ConsensusContext> C as(final Class<C> klass) {
return klass.cast(this);
}
}

View File

@@ -38,7 +38,7 @@ public class CliqueDifficultyCalculator implements DifficultyCalculator {
final Address nextProposer =
CliqueHelpers.getProposerForBlockAfter(
parent, context.getConsensusState(CliqueContext.class).getValidatorProvider());
parent, context.getConsensusContext(CliqueContext.class).getValidatorProvider());
return nextProposer.equals(localAddress) ? IN_TURN_DIFFICULTY : OUT_OF_TURN_DIFFICULTY;
}
}

View File

@@ -40,7 +40,7 @@ public class CliqueHelpers {
final Address candidate, final ProtocolContext protocolContext, final BlockHeader parent) {
final Collection<Address> validators =
protocolContext
.getConsensusState(CliqueContext.class)
.getConsensusContext(CliqueContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parent);
return validators.contains(candidate);
@@ -49,7 +49,7 @@ public class CliqueHelpers {
public static boolean addressIsAllowedToProduceNextBlock(
final Address candidate, final ProtocolContext protocolContext, final BlockHeader parent) {
final ValidatorProvider validatorProvider =
protocolContext.getConsensusState(CliqueContext.class).getValidatorProvider();
protocolContext.getConsensusContext(CliqueContext.class).getValidatorProvider();
if (!isSigner(candidate, protocolContext, parent)) {
return false;

View File

@@ -31,7 +31,8 @@ public class CliqueMiningTracker {
public boolean isProposerAfter(final BlockHeader header) {
final Address nextProposer =
CliqueHelpers.getProposerForBlockAfter(
header, protocolContext.getConsensusState(CliqueContext.class).getValidatorProvider());
header,
protocolContext.getConsensusContext(CliqueContext.class).getValidatorProvider());
return localAddress.equals(nextProposer);
}

View File

@@ -106,7 +106,7 @@ public class CliqueBlockCreator extends AbstractBlockCreator {
if (epochManager.isEpochBlock(sealableBlockHeader.getNumber())) {
return Optional.empty();
} else {
final CliqueContext cliqueContext = protocolContext.getConsensusState(CliqueContext.class);
final CliqueContext cliqueContext = protocolContext.getConsensusContext(CliqueContext.class);
checkState(
cliqueContext.getValidatorProvider().getVoteProviderAtHead().isPresent(),
"Clique requires a vote provider");

View File

@@ -108,7 +108,7 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor<CliqueBlockMiner>
final Collection<Address> storedValidators =
protocolContext
.getConsensusState(CliqueContext.class)
.getConsensusContext(CliqueContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parentHeader);
validators.addAll(storedValidators);

View File

@@ -57,7 +57,7 @@ public class CliqueExtraDataValidationRule implements AttachedBlockHeaderValidat
try {
final Collection<Address> storedValidators =
protocolContext
.getConsensusState(CliqueContext.class)
.getConsensusContext(CliqueContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parent);

View File

@@ -54,7 +54,7 @@ public class CliqueJsonRpcMethods extends ApiGroupJsonRpcMethods {
final BlockchainQueries blockchainQueries =
new BlockchainQueries(blockchain, worldStateArchive);
final ValidatorProvider validatorProvider =
context.getConsensusState(CliqueContext.class).getValidatorProvider();
context.getConsensusContext(CliqueContext.class).getValidatorProvider();
// Must create our own voteTallyCache as using this would pollute the main voteTallyCache
final ValidatorProvider readOnlyValidatorProvider =
@@ -73,7 +73,7 @@ public class CliqueJsonRpcMethods extends ApiGroupJsonRpcMethods {
private ValidatorProvider createValidatorProvider(
final ProtocolContext context, final MutableBlockchain blockchain) {
final EpochManager epochManager =
context.getConsensusState(CliqueContext.class).getEpochManager();
context.getConsensusContext(CliqueContext.class).getEpochManager();
final CliqueBlockInterface cliqueBlockInterface = new CliqueBlockInterface();
return BlockValidatorProvider.nonForkingValidatorProvider(
blockchain, epochManager, cliqueBlockInterface);

View File

@@ -90,7 +90,7 @@ public class CliqueMiningCoordinatorTest {
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
when(protocolContext.getConsensusState(CliqueContext.class)).thenReturn(cliqueContext);
when(protocolContext.getConsensusContext(CliqueContext.class)).thenReturn(cliqueContext);
when(protocolContext.getBlockchain()).thenReturn(blockChain);
when(minerExecutor.startAsyncMining(any(), any(), any())).thenReturn(Optional.of(blockMiner));
when(syncState.isInSync()).thenReturn(true);

View File

@@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.consensus.common;
public interface PoaContext {
import org.hyperledger.besu.ethereum.ConsensusContext;
public interface PoaContext extends ConsensusContext {
BlockInterface getBlockInterface();
}

View File

@@ -17,6 +17,7 @@ package org.hyperledger.besu.consensus.common.bft;
import org.hyperledger.besu.consensus.common.EpochManager;
import org.hyperledger.besu.consensus.common.PoaContext;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.ethereum.ConsensusContext;
/** Holds the BFT specific mutable state. */
public class BftContext implements PoaContext {
@@ -46,4 +47,9 @@ public class BftContext implements PoaContext {
public BftBlockInterface getBlockInterface() {
return blockInterface;
}
@Override
public <C extends ConsensusContext> C as(final Class<C> klass) {
return klass.cast(this);
}
}

View File

@@ -104,7 +104,7 @@ public class BftBlockCreatorFactory {
}
public Bytes createExtraData(final int round, final BlockHeader parentHeader) {
final BftContext bftContext = protocolContext.getConsensusState(BftContext.class);
final BftContext bftContext = protocolContext.getConsensusContext(BftContext.class);
final ValidatorProvider validatorProvider = bftContext.getValidatorProvider();
Optional<VoteProvider> voteProviderAfterBlock =
validatorProvider.getVoteProviderAfterBlock(parentHeader);

View File

@@ -39,7 +39,7 @@ public class BftCoinbaseValidationRule implements AttachedBlockHeaderValidationR
final Collection<Address> storedValidators =
context
.getConsensusState(BftContext.class)
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parent);
final Address proposer = header.getCoinbase();

View File

@@ -43,7 +43,7 @@ public class BftCommitSealsValidationRule implements AttachedBlockHeaderValidati
@Override
public boolean validate(
final BlockHeader header, final BlockHeader parent, final ProtocolContext protocolContext) {
final BftContext bftContext = protocolContext.getConsensusState(BftContext.class);
final BftContext bftContext = protocolContext.getConsensusContext(BftContext.class);
final Collection<Address> storedValidators =
bftContext.getValidatorProvider().getValidatorsAfterBlock(parent);

View File

@@ -42,7 +42,7 @@ public class BftValidatorsValidationRule implements AttachedBlockHeaderValidatio
public boolean validate(
final BlockHeader header, final BlockHeader parent, final ProtocolContext context) {
try {
final BftContext bftContext = context.getConsensusState(BftContext.class);
final BftContext bftContext = context.getConsensusContext(BftContext.class);
final BftExtraData bftExtraData = bftContext.getBlockInterface().getExtraData(header);
final NavigableSet<Address> sortedReportedValidators =

View File

@@ -31,7 +31,7 @@ public class BftVanityDataValidationRule implements AttachedBlockHeaderValidatio
@Override
public boolean validate(
final BlockHeader header, final BlockHeader parent, final ProtocolContext protocolContext) {
final BftContext bftContext = protocolContext.getConsensusState(BftContext.class);
final BftContext bftContext = protocolContext.getConsensusContext(BftContext.class);
final BftExtraData bftExtraData = bftContext.getBlockInterface().getExtraData(header);
if (bftExtraData.getVanityData().size() != BftExtraDataCodec.EXTRA_VANITY_LENGTH) {

View File

@@ -24,6 +24,8 @@ import org.hyperledger.besu.datatypes.Address;
import java.util.Collection;
import org.mockito.Mockito;
public class BftContextBuilder {
public static BftContext setupContextWithValidators(final Collection<Address> validators) {
@@ -35,6 +37,7 @@ public class BftContextBuilder {
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.getBlockInterface()).thenReturn(mockBftBlockInterface);
when(bftContext.as(Mockito.any())).thenReturn(bftContext);
return bftContext;
}
@@ -56,6 +59,7 @@ public class BftContextBuilder {
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.getBlockInterface()).thenReturn(mockBftBlockInterface);
when(mockBftBlockInterface.getExtraData(any())).thenReturn(bftExtraData);
when(bftContext.as(Mockito.any())).thenReturn(bftContext);
return bftContext;
}
@@ -74,6 +78,7 @@ public class BftContextBuilder {
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.getBlockInterface()).thenReturn(new BftBlockInterface(bftExtraDataCodec));
when(bftContext.as(Mockito.any())).thenReturn(bftContext);
return bftContext;
}

View File

@@ -357,7 +357,7 @@ public class TestContextBuilder {
final BftExecutors bftExecutors = BftExecutors.create(new NoOpMetricsSystem());
final BftFinalState finalState =
new BftFinalState(
protocolContext.getConsensusState(BftContext.class).getValidatorProvider(),
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider(),
nodeKey,
Util.publicKeyToAddress(nodeKey.getPublicKey()),
proposerSelector,

View File

@@ -18,6 +18,7 @@ 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.validator.ValidatorProvider;
import org.hyperledger.besu.ethereum.ConsensusContext;
/** Holds the BFT specific mutable state. */
public class IbftLegacyContext implements PoaContext {
@@ -47,4 +48,9 @@ public class IbftLegacyContext implements PoaContext {
public BlockInterface getBlockInterface() {
return blockInterface;
}
@Override
public <C extends ConsensusContext> C as(final Class<C> klass) {
return klass.cast(this);
}
}

View File

@@ -53,10 +53,10 @@ public class IbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
final MutableBlockchain blockchain = context.getBlockchain();
final BlockchainQueries blockchainQueries =
new BlockchainQueries(blockchain, context.getWorldStateArchive());
final BftContext bftContext = context.getConsensusState(BftContext.class);
final BftContext bftContext = context.getConsensusContext(BftContext.class);
final BlockInterface blockInterface = bftContext.getBlockInterface();
final ValidatorProvider validatorProvider =
context.getConsensusState(BftContext.class).getValidatorProvider();
context.getConsensusContext(BftContext.class).getValidatorProvider();
// Must create our own voteTallyCache as using this would pollute the main voteTallyCache
final ValidatorProvider readOnlyValidatorProvider =
@@ -73,7 +73,7 @@ public class IbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
private ValidatorProvider createValidatorProvider(
final ProtocolContext context, final MutableBlockchain blockchain) {
final BftContext bftContext = context.getConsensusState(BftContext.class);
final BftContext bftContext = context.getConsensusContext(BftContext.class);
final EpochManager epochManager = bftContext.getEpochManager();
final BftBlockInterface bftBlockInterface = bftContext.getBlockInterface();
return BlockValidatorProvider.nonForkingValidatorProvider(

View File

@@ -113,7 +113,7 @@ public class IbftRound {
"Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier());
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
blockToPublish =
bftBlockInterface.replaceRoundInBlock(
bestBlockFromRoundChange.get(),

View File

@@ -72,7 +72,7 @@ public class MessageValidator {
}
final BftBlockInterface blockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return proposalConsistencyValidator.validateProposalMatchesBlock(
msg.getSignedPayload(), msg.getBlock(), blockInterface);
}

View File

@@ -48,7 +48,7 @@ public class MessageValidatorFactory {
private Collection<Address> getValidatorsAfterBlock(final BlockHeader parentHeader) {
return protocolContext
.getConsensusState(BftContext.class)
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parentHeader);
}
@@ -69,7 +69,7 @@ public class MessageValidatorFactory {
final Collection<Address> validators = getValidatorsAfterBlock(parentHeader);
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return new MessageValidator(
createSignedDataValidator(roundIdentifier, parentHeader),
@@ -89,7 +89,7 @@ public class MessageValidatorFactory {
final Collection<Address> validators = getValidatorsAfterBlock(parentHeader);
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return new RoundChangeMessageValidator(
new RoundChangePayloadValidator(
(roundIdentifier) -> createSignedDataValidator(roundIdentifier, parentHeader),

View File

@@ -51,6 +51,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
@@ -89,9 +90,12 @@ public class MessageValidatorTest {
when(proposalBlockConsistencyValidator.validateProposalMatchesBlock(any(), any(), any()))
.thenReturn(true);
BftContext mockBftCtx = mock(BftContext.class);
when(mockBftCtx.as(Mockito.any())).thenReturn(mockBftCtx);
protocolContext =
new ProtocolContext(
mock(MutableBlockchain.class), mock(WorldStateArchive.class), mock(BftContext.class));
mock(MutableBlockchain.class), mock(WorldStateArchive.class), mockBftCtx);
when(blockValidator.validateAndProcessBlock(any(), any(), any(), any()))
.thenReturn(Optional.of(new BlockProcessingOutputs(null, null)));

View File

@@ -57,7 +57,7 @@ public class IbftExtraDataValidationRule implements AttachedBlockHeaderValidatio
try {
final Collection<Address> storedValidators =
context
.getConsensusState(IbftLegacyContext.class)
.getConsensusContext(IbftLegacyContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parent);
final IbftExtraData ibftExtraData = IbftExtraData.decode(header);

View File

@@ -44,6 +44,7 @@ import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Test;
import org.mockito.Mockito;
public class IbftBlockHeaderValidationRulesetFactoryTest {
@@ -55,7 +56,7 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
final ValidatorProvider mockValidatorProvider = mock(ValidatorProvider.class);
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.as(Mockito.any())).thenReturn(bftContext);
return new ProtocolContext(null, null, bftContext);
}

View File

@@ -25,6 +25,8 @@ import org.hyperledger.besu.datatypes.Address;
import java.util.Collection;
import org.mockito.Mockito;
public class IbftLegacyContextBuilder {
public static IbftLegacyContext setupContextWithValidators(final Collection<Address> validators) {
@@ -33,6 +35,7 @@ public class IbftLegacyContextBuilder {
mock(ValidatorProvider.class, withSettings().lenient());
when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider);
when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators);
when(bftContext.as(Mockito.any())).thenReturn(bftContext);
return bftContext;
}
}

View File

@@ -462,7 +462,7 @@ public class TestContextBuilder {
final BftExecutors bftExecutors = BftExecutors.create(new NoOpMetricsSystem());
final BftFinalState finalState =
new BftFinalState(
protocolContext.getConsensusState(BftContext.class).getValidatorProvider(),
protocolContext.getConsensusContext(BftContext.class).getValidatorProvider(),
nodeKey,
Util.publicKeyToAddress(nodeKey.getPublicKey()),
proposerSelector,

View File

@@ -61,7 +61,7 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory {
@Override
public BlockCreator create(final BlockHeader parentHeader, final int round) {
final BlockCreator blockCreator = super.create(parentHeader, round);
final QbftContext qbftContext = protocolContext.getConsensusState(QbftContext.class);
final QbftContext qbftContext = protocolContext.getConsensusContext(QbftContext.class);
if (qbftContext.getPkiBlockCreationConfiguration().isEmpty()) {
return blockCreator;
} else {

View File

@@ -50,7 +50,7 @@ public class QbftValidatorsValidationRule implements AttachedBlockHeaderValidati
// validators and votes must be empty if they are supplied by a contract.
try {
final BftContext bftContext = context.getConsensusState(BftContext.class);
final BftContext bftContext = context.getConsensusContext(BftContext.class);
final BftExtraData bftExtraData = bftContext.getBlockInterface().getExtraData(header);
if (!bftExtraData.getValidators().isEmpty()) {

View File

@@ -51,7 +51,7 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
protected Map<String, JsonRpcMethod> create() {
final BlockchainQueries blockchainQueries =
new BlockchainQueries(context.getBlockchain(), context.getWorldStateArchive());
final BftContext bftContext = context.getConsensusState(BftContext.class);
final BftContext bftContext = context.getConsensusContext(BftContext.class);
final BlockInterface blockInterface = bftContext.getBlockInterface();
final ValidatorProvider validatorProvider = bftContext.getValidatorProvider();

View File

@@ -298,7 +298,7 @@ public class QbftRound {
private Block createCommitBlock(final Block block) {
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return bftBlockInterface.replaceRoundInBlock(
block,
getRoundIdentifier().getRoundNumber(),

View File

@@ -49,7 +49,7 @@ public class MessageValidatorFactory {
private Collection<Address> getValidatorsAfterBlock(final BlockHeader parentHeader) {
return protocolContext
.getConsensusState(BftContext.class)
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parentHeader);
}
@@ -92,7 +92,7 @@ public class MessageValidatorFactory {
bftExtraDataCodec);
final BftBlockInterface blockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return new MessageValidator(
block ->
new SubsequentMessageValidator(

View File

@@ -63,7 +63,7 @@ public class ProposalPayloadValidator {
protocolContext,
bftExtraDataCodec,
protocolContext
.getConsensusState(QbftContext.class)
.getConsensusContext(QbftContext.class)
.getPkiBlockCreationConfiguration()
.map(config -> new CmsValidator(config.getTrustStore())));
}
@@ -111,7 +111,7 @@ public class ProposalPayloadValidator {
if (cmsValidator.isPresent()) {
return validateCms(
block,
protocolContext.getConsensusState(QbftContext.class).getBlockInterface(),
protocolContext.getConsensusContext(QbftContext.class).getBlockInterface(),
cmsValidator.get());
}

View File

@@ -123,7 +123,7 @@ public class ProposalValidator {
// Need to check that if we substitute the LatestPrepareCert round number into the supplied
// block that we get the SAME hash as PreparedCert.
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusState(BftContext.class).getBlockInterface();
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
final Block currentBlockWithOldRound =
bftBlockInterface.replaceRoundInBlock(
proposal.getBlock(),

View File

@@ -33,6 +33,7 @@ configurations {
dependencies {
implementation project(':config')
implementation project(':consensus:merge')
implementation project(':crypto')
implementation project(':datatypes')
implementation project(':enclave')

View File

@@ -0,0 +1,20 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.ethereum;
@FunctionalInterface
public interface ConsensusContext {
<C extends ConsensusContext> C as(final Class<C> klass);
}

View File

@@ -21,7 +21,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
@FunctionalInterface
public interface ConsensusContextFactory {
Object create(
ConsensusContext create(
Blockchain blockchain,
WorldStateArchive worldStateArchive,
ProtocolSchedule protocolSchedule);

View File

@@ -27,15 +27,15 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
public class ProtocolContext {
private final MutableBlockchain blockchain;
private final WorldStateArchive worldStateArchive;
private final Object consensusState;
private final ConsensusContext consensusContext;
public ProtocolContext(
final MutableBlockchain blockchain,
final WorldStateArchive worldStateArchive,
final Object consensusState) {
final ConsensusContext consensusContext) {
this.blockchain = blockchain;
this.worldStateArchive = worldStateArchive;
this.consensusState = consensusState;
this.consensusContext = consensusContext;
}
public static ProtocolContext init(
@@ -62,7 +62,7 @@ public class ProtocolContext {
return worldStateArchive;
}
public <C> C getConsensusState(final Class<C> klass) {
return klass.cast(consensusState);
public <C extends ConsensusContext> C getConsensusContext(final Class<C> klass) {
return consensusContext.as(klass);
}
}

View File

@@ -21,6 +21,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.ethereum.ConsensusContext;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState;
@@ -141,7 +142,15 @@ public class BlockchainSetupUtil {
private static ProtocolContext mainnetProtocolContextProvider(
final MutableBlockchain blockchain, final WorldStateArchive worldStateArchive) {
return new ProtocolContext(blockchain, worldStateArchive, null);
return new ProtocolContext(
blockchain,
worldStateArchive,
new ConsensusContext() {
@Override
public <C extends ConsensusContext> C as(final Class<C> klass) {
return null;
}
});
}
private static BlockchainSetupUtil create(

View File

@@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.eth.sync;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.ethereum.ConsensusContext;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
@@ -46,7 +47,7 @@ public class BonsaiBlockPropagationManagerTest extends AbstractBlockPropagationM
new ProtocolContext(
blockchain,
tempProtocolContext.getWorldStateArchive(),
tempProtocolContext.getConsensusState(Object.class));
tempProtocolContext.getConsensusContext(ConsensusContext.class));
ethProtocolManager =
EthProtocolManagerTestUtil.create(
blockchain,

View File

@@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.eth.sync;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.ethereum.ConsensusContext;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
@@ -46,7 +47,7 @@ public class ForestBlockPropagationManagerTest extends AbstractBlockPropagationM
new ProtocolContext(
blockchain,
tempProtocolContext.getWorldStateArchive(),
tempProtocolContext.getConsensusState(Object.class));
tempProtocolContext.getConsensusContext(ConsensusContext.class));
ethProtocolManager =
EthProtocolManagerTestUtil.create(
blockchain,