@Override
  public Address selectProposerForRound(final ConsensusRoundIdentifier roundIdentifier) {
    checkArgument(roundIdentifier.getRoundNumber() >= 0);
    checkArgument(roundIdentifier.getSequenceNumber() > 0);

    final long prevBlockNumber = roundIdentifier.getSequenceNumber() - 1;
    final Optional<BlockHeader> maybeParentHeader = blockchain.getBlockHeader(prevBlockNumber);
    if (!maybeParentHeader.isPresent()) {
      LOG.trace("Unable to determine proposer for requested block {}", prevBlockNumber);
      throw new RuntimeException("Unable to determine past proposer");
    }

    final BlockHeader blockHeader = maybeParentHeader.get();
    final Address prevBlockProposer = blockInterface.getProposerOfBlock(blockHeader);
    final Collection<Address> validatorsForRound =
        validatorProvider.getValidatorsAfterBlock(blockHeader);

    return selectProposerForRound(
        roundIdentifier, prevBlockProposer, validatorsForRound, changeEachBlock);
  }
Determines which validator should be acting as the proposer for a given sequence/round.

@param roundIdentifier Identifies the chain height and proposal attempt number.
@return The address of the node which is to propose a block for the provided Round.
consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftProposerSelector.java