Log changes in BFT validators (#6437)

* Log changes in BFT validators

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Move the log entry to the block expiry handler, not the round change validator, and only log on round 0

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Remove unused imports

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Javadoc

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Remaining javadoc fix

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Better javadoc fix

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Spotless

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Spotless

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

* Merge fix

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>

---------

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
Signed-off-by: Matt Whitehead <matthew.whitehead@kaleido.io>
pull/6568/head
Matt Whitehead 9 months ago committed by GitHub
parent 9ef48d4399
commit 6b174e84f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 28
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManager.java
  2. 4
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRound.java
  3. 31
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidatorFactory.java
  4. 28
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java
  5. 32
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidatorFactory.java

@ -32,6 +32,7 @@ import org.hyperledger.besu.consensus.ibft.network.IbftMessageTransmitter;
import org.hyperledger.besu.consensus.ibft.payload.MessageFactory;
import org.hyperledger.besu.consensus.ibft.validation.FutureRoundProposalMessageValidator;
import org.hyperledger.besu.consensus.ibft.validation.MessageValidatorFactory;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException;
@ -122,6 +123,9 @@ public class IbftBlockHeightManager implements BaseIbftBlockHeightManager {
@Override
public void handleBlockTimerExpiry(final ConsensusRoundIdentifier roundIdentifier) {
logValidatorChanges(currentRound);
if (roundIdentifier.equals(currentRound.getRoundIdentifier())) {
final long headerTimeStampSeconds = Math.round(clock.millis() / 1000D);
currentRound.createAndSendProposalMessage(headerTimeStampSeconds);
@ -133,6 +137,30 @@ public class IbftBlockHeightManager implements BaseIbftBlockHeightManager {
}
}
/**
* If the list of validators for the next block to be proposed/imported has changed from the
* previous block, log the change. Only log for round 0 (i.e. once per block).
*
* @param ibftRound The current round
*/
private void logValidatorChanges(final IbftRound ibftRound) {
if (ibftRound.getRoundIdentifier().getRoundNumber() == 0) {
final Collection<Address> previousValidators =
MessageValidatorFactory.getValidatorsForBlock(ibftRound.protocolContext, parentHeader);
final Collection<Address> validatorsForHeight =
MessageValidatorFactory.getValidatorsAfterBlock(ibftRound.protocolContext, parentHeader);
if (!(validatorsForHeight.containsAll(previousValidators))
|| !(previousValidators.containsAll(validatorsForHeight))) {
LOG.info(
"Validator list change. Previous chain height {}: {}. Current chain height {}: {}.",
parentHeader.getNumber(),
previousValidators,
parentHeader.getNumber() + 1,
validatorsForHeight);
}
}
}
@Override
public void roundExpired(final RoundExpiry expire) {
if (!expire.getView().equals(currentRound.getRoundIdentifier())) {

@ -57,7 +57,9 @@ public class IbftRound {
private final Subscribers<MinedBlockObserver> observers;
private final RoundState roundState;
private final BlockCreator blockCreator;
private final ProtocolContext protocolContext;
/** The protocol context. */
protected final ProtocolContext protocolContext;
private final ProtocolSchedule protocolSchedule;
private final NodeKey nodeKey;
private final MessageFactory messageFactory; // used only to create stored local msgs

@ -54,18 +54,41 @@ public class MessageValidatorFactory {
this.bftExtraDataCodec = bftExtraDataCodec;
}
private Collection<Address> getValidatorsAfterBlock(final BlockHeader parentHeader) {
/**
* Get the list of validators that are applicable after the given block
*
* @param protocolContext the protocol context
* @param parentHeader the parent header
* @return the list of validators
*/
public static Collection<Address> getValidatorsAfterBlock(
final ProtocolContext protocolContext, final BlockHeader parentHeader) {
return protocolContext
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parentHeader);
}
/**
* Get the list of validators that are applicable for the given block
*
* @param protocolContext the protocol context
* @param parentHeader the parent header
* @return the list of validators
*/
public static Collection<Address> getValidatorsForBlock(
final ProtocolContext protocolContext, final BlockHeader parentHeader) {
return protocolContext
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsForBlock(parentHeader);
}
private SignedDataValidator createSignedDataValidator(
final ConsensusRoundIdentifier roundIdentifier, final BlockHeader parentHeader) {
return new SignedDataValidator(
getValidatorsAfterBlock(parentHeader),
getValidatorsAfterBlock(protocolContext, parentHeader),
proposerSelector.selectProposerForRound(roundIdentifier),
roundIdentifier);
}
@ -79,7 +102,7 @@ public class MessageValidatorFactory {
*/
public MessageValidator createMessageValidator(
final ConsensusRoundIdentifier roundIdentifier, final BlockHeader parentHeader) {
final Collection<Address> validators = getValidatorsAfterBlock(parentHeader);
final Collection<Address> validators = getValidatorsAfterBlock(protocolContext, parentHeader);
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
@ -106,7 +129,7 @@ public class MessageValidatorFactory {
*/
public RoundChangeMessageValidator createRoundChangeMessageValidator(
final long chainHeight, final BlockHeader parentHeader) {
final Collection<Address> validators = getValidatorsAfterBlock(parentHeader);
final Collection<Address> validators = getValidatorsAfterBlock(protocolContext, parentHeader);
final BftBlockInterface bftBlockInterface =
protocolContext.getConsensusContext(BftContext.class).getBlockInterface();

@ -27,6 +27,7 @@ import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter;
import org.hyperledger.besu.consensus.qbft.payload.MessageFactory;
import org.hyperledger.besu.consensus.qbft.validation.FutureRoundProposalMessageValidator;
import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException;
@ -126,6 +127,9 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager {
startNewRound(0);
final QbftRound qbftRound = currentRound.get();
logValidatorChanges(qbftRound);
// mining will be checked against round 0 as the current round is initialised to 0 above
final boolean isProposer =
finalState.isLocalNodeProposerForRound(qbftRound.getRoundIdentifier());
@ -143,6 +147,30 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager {
}
}
/**
* If the list of validators for the next block to be proposed/imported has changed from the
* previous block, log the change. Only log for round 0 (i.e. once per block).
*
* @param qbftRound The current round
*/
private void logValidatorChanges(final QbftRound qbftRound) {
if (qbftRound.getRoundIdentifier().getRoundNumber() == 0) {
final Collection<Address> previousValidators =
MessageValidatorFactory.getValidatorsForBlock(qbftRound.protocolContext, parentHeader);
final Collection<Address> validatorsForHeight =
MessageValidatorFactory.getValidatorsAfterBlock(qbftRound.protocolContext, parentHeader);
if (!(validatorsForHeight.containsAll(previousValidators))
|| !(previousValidators.containsAll(validatorsForHeight))) {
LOG.info(
"Validator list change. Previous chain height {}: {}. Current chain height {}: {}.",
parentHeader.getNumber(),
previousValidators,
parentHeader.getNumber() + 1,
validatorsForHeight);
}
}
}
@Override
public void roundExpired(final RoundExpiry expire) {
if (currentRound.isEmpty()) {

@ -55,13 +55,36 @@ public class MessageValidatorFactory {
this.bftExtraDataCodec = bftExtraDataCodec;
}
private Collection<Address> getValidatorsAfterBlock(final BlockHeader parentHeader) {
/**
* Get the list of validators that are applicable after the given block
*
* @param protocolContext the protocol context
* @param parentHeader the parent header
* @return the list of validators
*/
public static Collection<Address> getValidatorsAfterBlock(
final ProtocolContext protocolContext, final BlockHeader parentHeader) {
return protocolContext
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsAfterBlock(parentHeader);
}
/**
* Get the list of validators that are applicable for the given block
*
* @param protocolContext the protocol context
* @param parentHeader the parent header
* @return the list of validators
*/
public static Collection<Address> getValidatorsForBlock(
final ProtocolContext protocolContext, final BlockHeader parentHeader) {
return protocolContext
.getConsensusContext(BftContext.class)
.getValidatorProvider()
.getValidatorsForBlock(parentHeader);
}
/**
* Create round change message validator.
*
@ -72,7 +95,8 @@ public class MessageValidatorFactory {
public RoundChangeMessageValidator createRoundChangeMessageValidator(
final long chainHeight, final BlockHeader parentHeader) {
final Collection<Address> validatorsForHeight = getValidatorsAfterBlock(parentHeader);
final Collection<Address> validatorsForHeight =
getValidatorsAfterBlock(protocolContext, parentHeader);
final RoundChangePayloadValidator roundChangePayloadValidator =
new RoundChangePayloadValidator(validatorsForHeight, chainHeight);
@ -95,8 +119,8 @@ public class MessageValidatorFactory {
*/
public MessageValidator createMessageValidator(
final ConsensusRoundIdentifier roundIdentifier, final BlockHeader parentHeader) {
final Collection<Address> validatorsForHeight = getValidatorsAfterBlock(parentHeader);
final Collection<Address> validatorsForHeight =
getValidatorsAfterBlock(protocolContext, parentHeader);
final ProposalValidator proposalValidator =
new ProposalValidator(

Loading…
Cancel
Save