Skip to content

feat(CCHAIN-740): Implement validator proof protocol per ADR-006#1450

Merged
ancazamfir merged 30 commits intocirclefin:mainfrom
ancazamfir:validator-proof
Mar 10, 2026
Merged

feat(CCHAIN-740): Implement validator proof protocol per ADR-006#1450
ancazamfir merged 30 commits intocirclefin:mainfrom
ancazamfir:validator-proof

Conversation

@ancazamfir
Copy link
Contributor

@ancazamfir ancazamfir commented Feb 4, 2026

Implementation of #1436

Uses libp2p-stream protocol to satisfy the protocol spec and as proposed by @romac

@ancazamfir ancazamfir marked this pull request as ready for review February 27, 2026 22:44
@ancazamfir ancazamfir requested a review from romac as a code owner February 27, 2026 22:44
@ancazamfir
Copy link
Contributor Author

ancazamfir commented Feb 28, 2026

For testing I used the example/channel app, init and started nodes wiht testnet_manager.bash script.
Current settings in the script:

    export MALACHITE__CONSENSUS__P2P__PROTOCOL__TYPE="gossipsub"
    export MALACHITE__CONSENSUS__P2P__PROTOCOL__ENABLE_PEER_SCORING="false"
    export MALACHITE__VALIDATOR_ROTATION__ENABLED="true"
    export MALACHITE__VALIDATOR_ROTATION__ROTATION_PERIOD="10"
    export MALACHITE__VALIDATOR_ROTATION__SELECTION_SIZE="3"
    export MALACHITE__CONSENSUS__P2P__PROTOCOL__ENABLE_EXPLICIT_PEERING="false"
    export MALACHITE__CONSENSUS__P2P__PROTOCOL__ENABLE_FLOOD_PUBLISH="true"

With these settings the validator set rotates every 10 heights and 3 validators are selected from the validators crates.

Testing uses the metrics to determine node classification, for this PR the validator vs persistent or full-node is of interest. Used check_mesh_vals.py to get and process the metrics.

  • init and start the nodes
./scripts/testnet_manager.bash init --validators 5 --full-nodes 10 --home nodes
./scripts/testnet_manager.bash start --nodes all --home node
  • check the node types, verify that every 10 heights the nodes are properly (re)classified after validator rotation
...
Moniker         Type         Cons  Prop  Live  Expl  Peers  InPeers  OutPeers  Conns  InConns  OutConns
-----------------------------------------------------------------------------------------------------------------------------
app-1           validator    11    11    11    0     11     7        4         15     11       4
app-2           validator    10    8     11    0     11     7        4         15     11       4
app-3           validator    6     11    7     0     11     7        4         15     11       4
-----------------------------------------------------------------------------------------------------------------------------
app-0           persistent   11    11    11    0     11     7        4         15     11       4
app-4           persistent   10    7     8     0     11     7        4         15     11       4
-----------------------------------------------------------------------------------------------------------------------------
app-10          full_node    4     4     4     0     5      0        5         5      0        5
app-11          full_node    4     4     4     0     5      0        5         5      0        5
app-5           full_node    4     4     4     0     5      0        5         5      0        5
app-6           full_node    4     4     4     0     5      0        5         5      0        5
app-7           full_node    4     4     4     0     5      0        5         5      0        5
app-8           full_node    4     4     4     0     5      0        5         5      0        5
app-9           full_node    4     4     4     0     5      0        5         5      0        5

romac and others added 9 commits March 3, 2026 10:40
Wrap the proof read in a 5-second timeout to prevent a malicious or
buggy peer from holding substreams open indefinitely by never sending
data. On timeout, the reader is dropped which closes the substream.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover the critical code paths in the proof-of-validator protocol:
- Behaviour: poll state machine (anti-spam, retry-on-failure), connection
  tracking (first/additional/partial/full close), and send_proof logic
- State: record_verified_proof, reclassify_peers via process_validator_set_update,
  local node reclassification, and persistent peer + proof interaction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@nenadmilosevic95 nenadmilosevic95 left a comment

Choose a reason for hiding this comment

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

Made a full code pass, and the code looks good! Left some comments, most are minor, some we can maybe discuss! Didn't run any tests, plan to do this on Monday!

romac
romac previously approved these changes Mar 9, 2026
Copy link
Contributor

@romac romac left a comment

Choose a reason for hiding this comment

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

Amazing work 🚀

Copy link
Contributor

@nenadmilosevic95 nenadmilosevic95 left a comment

Choose a reason for hiding this comment

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

Awesome work! Left 3 nitpicks, feel free to ignore!

match &event {
// On send failure, allow retry by removing from sent set
Event::ProofSendFailed { peer, .. } => {
self.proofs_sent.remove(peer);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, let's skip it for now

Co-authored-by: nenadmilosevic95 <nenad.milosevic@circle.com>
@ancazamfir ancazamfir added this pull request to the merge queue Mar 10, 2026
Merged via the queue into circlefin:main with commit b6f55de Mar 10, 2026
12 checks passed
@ancazamfir ancazamfir deleted the validator-proof branch March 10, 2026 09:26
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.

4 participants