hiero-ledger / hiero-ledger/hiero-consensus-node

Harden CRS update framing and accepted-contributor accounting

Open
#26,568 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
406
Forks
226
Avg merge
3d 4h
Merged PRs (30d)
210

Description

## Summary

Strengthen the execution-layer boundary around CRS contribution validation. Completion of this issue requires **both**:

1. Exact framing validation for CRS updates before crossing the native-library boundary.
2. Explicit, unique, restart-safe accounting of accepted contributors.

Point-level and pairing validation remain the responsibility of the cryptography library; the execution layer should enforce protocol framing and state-transition invariants without parsing curve-point encodings.

## Required work

### 1. Enforce exact CRS update framing

At the execution-layer/native-library boundary:

- Require the submitted `newCrs` length to equal the previous accepted CRS length.
- Require the submitted CRS length to match the ceremony's original expected CRS length.
- Require the contribution proof to have its canonical length (currently 128 bytes).
- Reject malformed framing before copying input into native arrays or invoking JNI where practical.
- When producing a local contribution, require the output of `updateCrs()` to be exactly `previousCrs.length() + proofLength` before splitting it into CRS and proof.
- Do not accept truncated CRS encodings, appended/trailing data, short or extended proofs, or incorrectly framed local update output.

Keep format-specific constants owned by, or exposed through, the cryptography adapter where possible. Do not duplicate Arkworks point parsing in the application.

### 2. Make accepted-contributor accounting explicit

Replace a bare running contribution-weight total with explicit accepted-contributor identity:

- Track the node IDs whose contributions were cryptographically accepted.
- Derive contributed weight from the unique accepted-contributor set and source-roster weights.
- A node must not receive contribution weight more than once, including across ceremony restart/replay paths.
- Adoption of a new candidate CRS and addition of its contributor must occur atomically and only after all framing and cryptographic checks pass.
- An invalid contribution must preserve the previous candidate and accepted-contributor set, receive no weight, and must not prevent the ceremony from progressing to later scheduled contributors.
- Restart/reconstruction from persisted state/publications must produce the same candidate CRS and accepted-contributor set as uninterrupted execution.
- Distinguish an invalid contribution from a local verifier/JNI failure. A local verification failure must be observable and must not allow the ceremony to finalize with ambiguous accounting.

Persist enough information, or retain enough ordered publications, to make reconstruction deterministic across repeated ceremony rounds.

## Acceptance criteria

- [ ] A shorter or longer `newCrs` than the previous accepted CRS is rejected.
- [ ] A CRS with trailing bytes is rejected.
- [ ] A proof whose length is not exactly the canonical proof length is rejected.
- [ ] Malformed local `updateCrs()` output is not submitted.
- [ ] Rejected framing does not invoke the native verifier where the application can determine invalidity itself.
- [ ] Only a cryptographically accepted contribution changes the candidate CRS.
- [ ] Only unique accepted node IDs contribute weight.
- [ ] Repeating a valid contribution from the same node across a restart/replay does not increase contributed weight.
- [ ] An invalid contributor is skipped without poisoning the candidate used by the next honest contributor.
- [ ] Controller reconstruction yields the same candidate, accepted contributors, and contributed weight as uninterrupted execution.
- [ ] Finalization cannot complete after a local verifier failure or with inconsistent contributor accounting.

## Tests

Add execution-layer tests covering at least:

- truncated and extended CRS byte arrays;
- trailing CRS data;
- short and extended proofs;
- incorrectly sized local update output;
- a valid contribution following a rejected contribution;
- duplicate publication by one node across restart/replay;
- reconstruction after accepted and rejected publications; and
- weight threshold calculation from unique accepted contributors.

At least one test should exercise the real cryptography adapter rather than mocking every native-library result, so the node build verifies the expected adapter framing contract.

## Non-goals

- Reimplementing curve-point decoding, identity-point checks, pairing equations, or contribution proofs in Java.
- Adding a mock-signature fallback after real-TSS cutover.

Contributor guide

Open the contributing guide

Research direction

Start at the execution-layer/native-library boundary and trace updateCrs(), JNI verification, candidate adoption, and persisted ceremony reconstruction. Add execution-layer tests for malformed framing, rejected-then-valid contributions, duplicate replay, reconstruction, and unique-weight thresholds; exercise the real cryptography adapter. Done means framing is rejected early, accepted contributors and CRS state reconstruct deterministically, and verifier failures cannot finalize the ceremony.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, cryptography
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.