Skip to content

KIP-21: Partitioned sequencing commitment with O(activity) proving#36

Open
michaelsutton wants to merge 5 commits intokaspanet:masterfrom
michaelsutton:kip21
Open

KIP-21: Partitioned sequencing commitment with O(activity) proving#36
michaelsutton wants to merge 5 commits intokaspanet:masterfrom
michaelsutton:kip21

Conversation

@michaelsutton
Copy link
Copy Markdown
Contributor

@michaelsutton michaelsutton commented Feb 24, 2026

Summary

This PR adds KIP-21 as a draft consensus spec for replacing the current linear per-block seqcommit recurrence with a partitioned, lane-based commitment scheme.

The design keeps a single header commitment (accepted_id_merkle_root) while enabling lane-local proving that scales with lane activity (O(activity)), via two global anchors plus lane-local witnesses/diff.

Scheme illustration:

Global chain:  S0 -> S1 -> S2 -> ... -> Sn
                 |    |              |
                 v    v              v
               A0    A1             An      (A = ActiveLanesRoot)

Lane L proof:
  inclusion(L, A0) ---- lane-local compressed transition ---- inclusion(L, An)

This PR includes

  • Defines lane extraction and lane-tip state transition rules.
  • Defines ActiveLanesRoot as an SMT over active lane tips.
  • Defines SeqStateRoot and selected-parent recurrence for SeqCommit(B).
  • Preserves the ability to reconstruct global sequencing order from committed lane activity using merge_idx plus lane witnesses/SMT-diff proofs under SeqCommit anchors.
  • Commits accepting-block context (timestamp, daa_score, blue_score).
  • Commits mergeset miner payloads (including non-accepted mergeset coinbase payloads) with block hash + blue work binding.
  • Defines purge rules and oldest-first purge index behavior.
  • Defines reorg-safe incremental maintenance via reversible diffs.
  • Adds proving guidance:
    • global order reconstruction notes,
    • two-anchor lane proof model,
    • reactivated-lane non-inclusion pattern,
    • optional persistent witness store.

For prior research context, see "Subnets sequencing commitments": https://research.kas.pa/t/subnets-sequencing-commitments/274

Comment thread kip-0021.md

This KIP replaces the current per-chain-block linear sequencing commitment recurrence with a partitioned sequencing commitment scheme.

Instead of committing to all accepted transactions in every chain block as one global append-only stream, consensus maintains a commitment over the tips of active application lanes. Each active lane has its own recursive tip hash and last-touch blue score. Global order remains reconstructible via `merge_idx` (Section 10.1), but is no longer directly committed as one monolithic per-block list. The block header continues to expose a single `accepted_id_merkle_root` value (consumed by `OpChainblockSeqCommit`), but post-activation it commits to (i) the active-lanes sparse Merkle tree (SMT) root and (ii) per-block context and mergeset miner payloads, chained through selected-parent recursion.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You mention the term "lane" a lot. I think you should write "(as defined below)" or something similar after the first usage.

Comment thread kip-0021.md
This document mixes consensus rules and proving/operations guidance. Use this reading path:

* Consensus implementers: read *Terminology* through *Script Semantics*, then *Reorg-Safe Incremental Maintenance* and *Purge Index*, then *Relationship to Covenants++ Workstream* and *Backward Compatibility*.
* Proving/witness implementers: read *Per-Lane Block Activity Digest (§4.2)*, *Update or Initialize Lane Tips (§5.2)*, and *Commitment Structure (§6)* (especially §6.3-§6.7), then *Complexity (§10)* and *Optional Persistent Witness Store (§11)*.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider using links every time you use a section number

Comment thread kip-0021.md Outdated

### 1. Terminology

* Lane (`lane`): the logical application lane tracked by this commitment scheme. (In this KIP, lanes are extracted from `tx.subnetwork_id`; future KIPs may define finer-grained lane extraction such as account-level lanes.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe add something like "a lane is some ordered subset of mergeset's accepted transactions" or "a lane defines a predicate to filter mergeset transactions"

Comment thread kip-0021.md
Rationale for keying:

* The committed SMT key is `lane_key(lane) = H_lane_key(lane_id_bytes(lane))` (Section 6.1).
* Because key width is normalized by `H_lane_key`, zero-padding lane IDs is unnecessary.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This paragraph is not very clear. Do you mean that zero-padding might be needed to accommodate for SMT leaf requirements? I think the standard is that leaves are always hashed items, so there's no need to mention it (I mean, padding would violate the standard and would require justification)

Comment thread kip-0021.md

Rationale for keying:

* The committed SMT key is `lane_key(lane) = H_lane_key(lane_id_bytes(lane))` (Section 6.1).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is lane here? Is it just an abstract concept? I think it's clearer to write lane_key(lane_id) = ...

I think the whole document will be easier to reason about if you'll replace lane with lane_id in many places (mainly in code snippets).

Comment thread kip-0021.md

```
TipUpdateHash(parent_ref, lane_id_bytes(lane), activity_digest, MergesetContextHash(B)) =
H_lane_tip(parent_ref || lane_id_bytes(lane) || activity_digest || MergesetContextHash(B))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just a thought: maybe add here SeqCommit(parent(B)) and replace parent_ref with ZERO_HASH when inactive? This way the structure will be more "deterministic"

Comment thread kip-0021.md

Current encoding (subnetwork lanes):

* Let `subnetwork_id` be the canonical 20-byte `tx.subnetwork_id`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So users are now allowed to use freely any non-reserve subnetwork ID? I think it's worth writing it explicitly - it's another consensus change triggered by this KIP

Comment thread kip-0021.md
Consensus sets:

```
B.header.accepted_id_merkle_root = SeqCommit(B)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems unrelated - the previous sentence doesn't mention SeqCommit(B). Maybe it shoule be part of "6.6 Sequencing State Root (Normative)"?

Comment thread kip-0021.md
H_mergeset_context(
le_u64(B.header.timestamp)
|| le_u64(B.header.daa_score)
|| le_u64(B.header.blue_score)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe it's a little far-fetched, but utxo_commitment might also be relevant for an L2 application that needs to get the full L1 UTXO set.

Comment thread kip-0021.md
Comment on lines +532 to +533
1. `peek_oldest_score()`
2. `pop_oldest_while(score <= purge_cutoff)`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe change score -> blue_score? (Also below)

Comment thread kip-0021.md

Rationale for keying:

* The committed SMT key is `lane_key(lane) = H_lane_key(lane_id_bytes(lane))` (Section 6.1).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do we really need hashing here? Cant we reuse lane_id_bytes and add 20 zeroes as padding?

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.

3 participants