Skip to content

QBFT - Select correct ValidatorProvider when transitioning from validator contract to block header mode #2868

Closed
@siladu

Description

Description

During the transition from contract mode to block header mode, when creating the extra data for a new block, we need to look ahead to the next block's validatorProvider to obtain the nonEmpty voteProvider associated with the BlockValidatorProvider.

Acceptance Criteria

Given we are transitioning from contract to block header mode
When a block’s extra data is created
Then it should select the correct validatorProvider and not error upon selecting the TransactionValidatorProvider with an empty voteProvider.

(The following is a more robust AC which gives better asserts in an automated test than the above AC's "ensure it doesn't error")
Given we are transitioning from contract to block header mode
When a block’s extra data is created
Then it should use the same validators as the previous block (which will be the list of validators currently in the contract)

Steps to Reproduce (Bug)

  1. Start a node using a transition config like below:
"transitions": {
      "qbft": [
        {
          "block": 2,
          "validatorselectionmode": "contract",
          "validatorcontractaddress": "0x0000000000000000000000000000000000008888"
        },
        {
          "block": 4,
          "validatorselectionmode": "blockheader"
        }
      ]
    }
  1. Wait for a block to be mined for the transition back to block header mode
  2. See the block creation fail due to this error:
2021-10-06 21:10:01.007+02:00 | pool-8-thread-1 | ERROR | EventMultiplexer | State machine threw exception while processing event \{BlockTimerExpiry{Round Identifier=ConsensusRoundIdentifier{Sequence=4, Round=0}}\}
java.lang.IllegalStateException: Bft requires a vote provider
	at com.google.common.base.Preconditions.checkState(Preconditions.java:510)
	at org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreatorFactory.createExtraData(BftBlockCreatorFactory.java:108)
	at org.hyperledger.besu.consensus.qbft.blockcreation.QbftBlockCreatorFactory.createExtraData(QbftBlockCreatorFactory.java:93)
	at org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreatorFactory.lambda$create$1(BftBlockCreatorFactory.java:82)
	at org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator.createBlock(AbstractBlockCreator.java:182)
	at org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator.createBlock(AbstractBlockCreator.java:126)
	at org.hyperledger.besu.consensus.qbft.statemachine.QbftRound.createAndSendProposalMessage(QbftRound.java:100)
	at org.hyperledger.besu.consensus.qbft.statemachine.QbftBlockHeightManager.handleBlockTimerExpiry(QbftBlockHeightManager.java:125)
	at org.hyperledger.besu.consensus.common.bft.statemachine.BaseBftController.handleBlockTimerExpiry(BaseBftController.java:140)
	at org.hyperledger.besu.consensus.common.bft.EventMultiplexer.handleBftEvent(EventMultiplexer.java:54)
	at java.base/java.util.Optional.ifPresent(Optional.java:183)
	at org.hyperledger.besu.consensus.common.bft.BftProcessor.run(BftProcessor.java:60)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)

Metadata

Assignees

Labels

TeamGrootGH issues worked on by Groot Team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions