Skip to content

Conversation

@jframe
Copy link
Contributor

@jframe jframe commented Oct 31, 2025

This adds basic validation of qbft messages before they are gossiped. The validation is takes a simple approach and follows what is done in Besu for gossiping messages in QbftController.processMessages which determines whether a qbft message should be gossiped and processed by Qbft.

I also added a new deserialiser for QbftMessage to get only the basic metadata to determine whether message is valid. This avoids needing to potentially decode a lot more data such blocks which can be quite large.

The basic validation rules are:

  • Old messages (sequence < chainHeight): Ignored and not added to the event queue
  • Future messages (sequence > chainHeight): Added to the event queue but not gossiped
  • Current messages (sequence == chainHeight): Validated for author and local validator status and gossiped if valid

Note

Adds lightweight QBFT message decoding and validation for gossiping, and refactors crypto usage to SecpCrypto across the codebase.

  • Consensus:
    • QBFT Gossip Validation: Introduces MinimalQbftMessageDecoder and QbftMessageProcessor to decode minimal metadata (sequence, round, author) and validate messages before queuing/gossiping.
    • Integration: Wires processor into QbftValidatorFactory via p2PNetwork.subscribeToQbftMessages.
    • Seal Verification: SCEP256SealVerifier now uses SecpCrypto.signatureAlgorithm.
    • Tests: Add MinimalQbftMessageDecoderTest and QbftMessageProcessorTest.
  • Crypto:
    • Introduces Crypto interface and SecpCrypto implementation; adds signatureToAddress and privateKeyBytesWithoutPrefix helpers.
    • Enhances PrivateKeyGenerator to expose nodeKey.
  • P2P/App/Test Utils:
    • Replace Crypto usages with SecpCrypto in MaruApp, P2P (ENR, P2PNetworkImpl), tests, and utilities.
  • Build/Deps:
    • consensus adds testFixtures(project(":crypto")).
    • crypto test fixtures add required Besu/Tuweni dependencies.

Written by Cursor Bugbot for commit e43fb11. This will update automatically on new commits. Configure here.

cursor[bot]

This comment was marked as outdated.

@codecov-commenter
Copy link

codecov-commenter commented Oct 31, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@6dce8bb). Learn more about missing BASE report.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #454   +/-   ##
=======================================
  Coverage        ?   83.13%           
  Complexity      ?     1120           
=======================================
  Files           ?      228           
  Lines           ?     8071           
  Branches        ?      629           
=======================================
  Hits            ?     6710           
  Misses          ?     1019           
  Partials        ?      342           
Flag Coverage Δ
kotlin 83.13% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

jonesho
jonesho previously approved these changes Oct 31, 2025
Copy link
Contributor

@jonesho jonesho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just 2 minor comments

import org.junit.jupiter.api.Test

class MinimalQbftMessageDecoderTest {
private val signatureAlgorithm = SignatureAlgorithmFactory.getInstance()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should use Maru's crypto module for that if we're using real signatures

Copy link
Contributor Author

@jframe jframe Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maru's crypto module only provides key generation and hashing. The Signing object only has sign method for ULong. So I can replace key generation and hashing with Maru code, but the message bytes signing I will need to use NodeKey.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a ULongSigner, but you're free to add another one

roundNumber = roundNumber,
author = Address.wrap(Bytes.wrap(author)),
)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: RLP Decoder: Unclosed Lists Corrupt Parsing

The RLP decoder enters an extra list for PROPOSAL and ROUND_CHANGE messages but never exits it. After calling signedDataRlp.leaveList() on line 73, there should be another leaveList() call for these message types to properly exit the outer list wrapper entered on line 62, ensuring the RLP parsing state is correctly maintained.

Fix in Cursor Fix in Web

@jframe jframe merged commit e165017 into Consensys:main Nov 11, 2025
10 checks passed
@jframe jframe deleted the qbft_multivalidator_validation branch November 11, 2025 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants