Address review: Crosslink Finality terminology, operator definitions, bounded availability semantics, divergences appendix#1
Conversation
Co-authored-by: Daira-Emma Hopwood <daira@jacaranda.org>
Co-authored-by: Daira-Emma Hopwood <daira@jacaranda.org>
Co-authored-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…rmaid-11.12.2 Update to katex 0.16.28 and mermaid 11.12.2
Add a ZIP template.
…tions/checkout-6.0.2 Bump actions/checkout from 5.0.1 to 6.0.2
[ZIP 230] Updating the description for the flagsOrchard field
… in their individual capacities as ecosystem participants.
Electric Coin Company. Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
[ZIP 0] Update to indicate that former ECC ZIP editors are now acting in their individual capacities as ecosystem participants.
[ZIP-234] Update Motivations
[ZIP 226, ZIP 230] Limiting the valueBurn to u63
[ZIP 307] spelling corrections
Replaces the Reserved stub with a comprehensive specification covering message framing, connection handshake, all 19 message types, block and transaction relay, peer discovery, misbehavior scoring, and network upgrade peer management. All constants derived from the zcashd reference implementation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix "order of preference" phrasing for peer discovery mechanisms - Replace "zcashd reference implementation" with "zcashd implementation" throughout and document Zebra's corresponding values - Remove integer type table (belongs in protocol spec) - Add note that CompactSize is not formally defined in protocol spec - Add RFC 4291 reference for IPv4-mapped IPv6 addresses - Spell out "little-endian" instead of abbreviating "LE" - Add Protocol Version Negotiation section to clarify ambiguous "the protocol version" usage - Spell out bit numbering convention for service flags - Add reference to zcashd PR #7039 for alert removal - Note ZIP 155 for addrv2 deployment version assignment status Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace undefined ``bool`` with ``uint8``; 0 for false, 1 for true in the version message relay field - Change "Unix epoch time" / "Unix timestamp" to "Unix-epoch UTC time in seconds" for all timestamp fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Revise DNS seeding to describe both zcashd and Zebra behavior - Remove zcashd-specific SeedSpec6 reference from hardcoded seeds - Clarify command string validation: "ignored" not "rejected"; enumerate all currently used command strings - Use $k$ inline math syntax instead of :math: for service flags - Rewrap pong timeout line with "a corresponding pong" - Fix getblocks/getheaders descriptions: "up to and including hash_stop" and explicit MUST NOT limits - Soften misbehavior penalties from MUST to SHOULD (overspecification) - Note that zcashd does not use headers-first sync (refs zcashd#6292) - Make MSG_TX MUST for v4 transactions (bidirectional requirement) - "To impede" instead of "To prevent" for trickling rationale - "halved rounding down" instead of "halved via integer right-shift" - "its view of the current chain tip" for transaction expiry - Remove orphan expiration check interval (overspecification) - Simplify shielded eligibility to "fully transparent transactions" - Document relay fee complexity with zcashd source reference - Use "zcashd-specific rate-limiting" and "token-bucket algorithm" - Reorder references per ZIP convention (BCP14, RFCs, protocol spec, ZIPs, BIPs, external) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Capitalize "Bloom" filter throughout (named after Burton Howard Bloom) - Capitalize "Testnet" and "Mainnet" in protocol version note - Add version validation disconnect summary to Protocol Version Negotiation section - relay field: no text change needed (informational links noted) - MSG_TX MUST for v4: already addressed in prior commit - MIN_TESTNET_PEER_PROTO_VERSION: confirmed 170040 matches zcashd Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zebra strictly validates that the relay field is 0 or 1; zcashd accepts any non-zero value as true via implicit C++ bool conversion. Use SHOULD to recommend validation without making zcashd non-conformant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ZIP 213: align anchor-depth rationale with ZIP 315 (3 blocks)
Subsumed by ZIP 231; consensus is that a symmetric key stored in memo payload data is a simpler solution to this problem. Closes zcash#633
Remove / unreserve ZIP 318
Status changes from Reserved to Withdrawn. The ZIP was opened as a stub in PR zcash#119 but never developed further. Closes zcash#828. README.rst regenerated by makeindex.sh; the regeneration also removes stale entries for ZIP 318, whose source file was deleted in PR zcash#1282 but whose README entries had not yet been regenerated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zooko
left a comment
There was a problem hiding this comment.
This diff seems to use the term "assured finality". We had previously discussed using that term and had agreed instead to use the term "crosslink finality", as documented here: https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#crosslink-finality
Crosslink Finality
Crosslink provides a kind of finality which we call crosslink finality. Crosslink finality has these properties:
It is [accountable](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) because the chain contains explicit voting records which indicate each participating [finalizer](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME)'s on-chain behavior.
It is [irreversible](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) within the protocol scope. The only way to "undo" a final block is to modify the software to do so, which requires intervention by the user. Note that because a [finality safety violation](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) is always theoretically possible, this implies the only recovery from such a violation is out-of-band to the protocol and requires human intervention.
It is [objectively verifiable](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) because it is possible to determine finality from a local block history without any out-of-band information.
It is [globally consistent](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) meaning that all nodes which have received a sufficient number of valid blocks agree on the finality status, and also can rely on all other nodes in this set arriving at the same conclusion.
It provides [asymmetric cost-of-attack defense](https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) (TODO: Describe this better.)Or maybe this diff doesn't mean "crosslink finality" where it says "assured finality". Maybe it means "irreversible finality" or one of the other properties instead.
ZIP 303: Withdraw (stub never developed beyond PR zcash#119).
|
@copilot, please update the text to use the terminology from this comment. Also, whenever the different sources seem to diverge or disagree, prioritize the https://github.com/ShieldedLabs/zebra-crosslink repo's |
There was a problem hiding this comment.
Pull request overview
This PR adds two new draft ZIP documents describing Shielded Labs Crosslink v1: an informational architecture overview and a consensus ZIP specifying the CCC-SL hybrid consensus construction that cross-links Zcash PoW with a BFT finality protocol.
Changes:
- Added an informational draft ZIP defining Crosslink v1 terminology, motivation, architecture, and component interactions.
- Added a consensus draft ZIP specifying CCC-SL parameters, cross-referencing fields, derived functions, local finalization update rules, stalled-mode policy, and security property sketches.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| zips/draft-shieldedlabs-crosslink-overview.rst | New informational ZIP describing Crosslink v1 goals, terminology, architecture, and component interfaces. |
| zips/draft-shieldedlabs-crosslink-construction.rst | New consensus ZIP specifying the CCC-SL construction (cross-references, local finalization, stalled mode, and security claims). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Category: Informational | ||
| Created: 2026-04-08 | ||
| License: MIT | ||
| Discussions-To: <https://github.com/zcash/zips/issues> |
| * ``CCC-SL`` MUST implement bounded availability: the PoW best-chain MUST NOT | ||
| grow more than ``L`` blocks ahead of the finalized chain during a finality | ||
| stall, where ``L`` is a protocol parameter. |
| Category: Consensus | ||
| Created: 2026-04-08 | ||
| License: MIT | ||
| Discussions-To: <https://github.com/zcash/zips/issues> |
| ``snapshot(B)`` | ||
| For a bft-block or bft-proposal ``B``, the bc-block at the base of the | ||
| bc-chain snapshot committed to by ``B``. Formally: if ``B.headers_bc`` is | ||
| null (genesis), ``snapshot(B) = Origin_bc``; otherwise | ||
| ``snapshot(B) = B.headers_bc[0].truncate_bc(1)``. | ||
|
|
||
| ``LF(H)`` | ||
| For a bc-block ``H``, the last final bft-block in the context of ``H``: | ||
| ``LF(H) = bftLastFinal(H.context_bft)``. | ||
|
|
||
| ``candidate(H)`` | ||
| For a bc-block ``H``, the candidate finalization point: | ||
| ``candidate(H) = lastCommonAncestor(snapshot(LF(H)), H.truncate_bc(σ))``. | ||
|
|
There was a problem hiding this comment.
Added explicit definitions for all three in the Terminology section in commit e93f04c:
≼_bc(bc-prefix relation):A ≼_bc Biff the bc-chain with tipAis a prefix of the bc-chain with tipB.C.truncate_bc(k): the bc-chain with the lastkblocks removed; tip is the block at depthkfromC.lastCommonAncestor(A, B): the deepest bc-block that is an ancestor of bothAandB(tip of the longest common prefix).
| * **Bounded Availability**: The finality gap MUST NOT exceed ``L`` while | ||
| honest bc-block producers follow the protocol. When the gap reaches ``L``, | ||
| bc-block producers MUST enter Stalled Mode. |
| BC contextual validity (finality gap) | ||
| A bc-block ``H`` is contextually valid only if the finality gap constraint | ||
| is satisfied. Let ``fin_height(H)`` be the bc-height of ``candidate(H)`` | ||
| and ``tip_height(H)`` be the bc-height of ``H``. The finality gap is | ||
| ``tip_height(H) - fin_height(H)``. | ||
|
|
||
| If the finality gap at ``H`` exceeds ``L``, then ``H`` MUST be a stalled | ||
| block (i.e., ``isStalledBlock(H)`` MUST return ``true``). | ||
|
|
There was a problem hiding this comment.
The gap > L threshold is correct and intentional (matching the TFL book's finality_depth(H) > L → isStalledBlock(H)). The earlier "reaches L" wording was inconsistent. Fixed in commit e93f04c by:
- Rewriting the Bounded Availability requirement to state the correct invariant: "the finality depth of any non-stalled bc-block MUST NOT exceed
L" (stalled blocks may accumulate beyondL). - Fixing the proof sketch to match:
gap > L→ must be stalled, so all non-stalled blocks havetip_height − fin_height ≤ L.
| the finality gap in the chain accepted by honest full nodes MUST NOT exceed | ||
| ``L``. | ||
|
|
||
| *Proof sketch*: By the BC contextual validity rule, a bc-block with a finality | ||
| gap exceeding ``L`` that is not a stalled block is rejected as bc-invalid. | ||
| Since honest bc-block producers only produce stalled blocks when the gap would | ||
| exceed ``L``, and honest full nodes reject non-stalled blocks with gap ``> L``, | ||
| the finality gap in any honest full node's view of the bc-chain is at most | ||
| ``L``. |
shielded-nate
left a comment
There was a problem hiding this comment.
@copilot, please address the requested change
| Crosslink v1 [#zip-crosslink-overview]_. CCC-SL integrates the Zcash | ||
| Proof-of-Work best-chain protocol with the ``CFP-SL`` BFT finalization | ||
| protocol to provide both the availability properties of the PoW chain and the | ||
| assured finality of a BFT protocol. |
There was a problem hiding this comment.
@copilot I'm quoting this other review and have the same change request:
This diff seems to use the term "assured finality". We had previously discussed using that term and had agreed instead to use the term "crosslink finality", as documented here: https://github.com/ShieldedLabs/zebra-crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#crosslink-finality
Crosslink Finality
Crosslink provides a kind of finality which we call crosslink finality. Crosslink finality has these properties:
- It is [accountable](https://github.com/ShieldedLabs/zebra crosslink/blob/6d02a1b80f896d08f923e39b2505f0565efb5787/book/src/design/terminology.md#FIXME) because the chain contains explicit voting records which indicate each participating finalizer's on-chain behavior.
- It is irreversible within the protocol scope. The only way to "undo" a final block is to modify the software to do so, which requires intervention by the user. Note that because a finality safety violation is always theoretically possible, this implies the only recovery from such a violation is out-of-band to the protocol and requires human intervention.
- It is objectively verifiable because it is possible to determine finality from a local block history without any out-of-band information.
- It is globally consistent meaning that all nodes which have received a sufficient number of valid blocks agree on the finality status, and also can rely on all other nodes in this set arriving at the same conclusion.
- It provides asymmetric cost-of-attack defense (TODO: Describe this better.)
@copilot, please update this PR to rely on this quoted definition of Crosslink Finality rather than "assured finality".
There was a problem hiding this comment.
Done in commit e93f04c. All occurrences of "assured finality" have been replaced with "Crosslink Finality". The full 5-property definition from terminology.md (accountable, irreversible, objectively verifiable, globally consistent, asymmetric cost-of-attack defense) is now included in both ZIPs' Terminology sections, citing the zebra-crosslink terminology.md as the authoritative source.
Done in commit
|
…consensus) Agent-Logs-Url: https://github.com/shielded-nate/zips/sessions/c806cf08-644f-4b31-896b-dd0e7428f728 Co-authored-by: shielded-nate <185561036+shielded-nate@users.noreply.github.com>
…agram, and component definitions Agent-Logs-Url: https://github.com/shielded-nate/zips/sessions/172c763d-e0a3-4ba1-8692-91073ecf28ad Co-authored-by: shielded-nate <185561036+shielded-nate@users.noreply.github.com>
…asing, consistent Π_bft notation Agent-Logs-Url: https://github.com/shielded-nate/zips/sessions/172c763d-e0a3-4ba1-8692-91073ecf28ad Co-authored-by: shielded-nate <185561036+shielded-nate@users.noreply.github.com>
…ns, bounded availability fix, divergences appendix
e93f04c to
00fe13e
Compare
I'm going to merge this into shielded-nate or shieldedlabs repos and do further changes as future PRs.
|
Good enough to merge; more changes in future PRs. |
a8df7f9
into
copilot-crosslink-zip-initial-drafting
mainfromhttps://github.com/zcash/zipsmainnix develop -c make all(blocked:nixis not installed in this environment)