Conversation
larskuhtz
force-pushed
the
lars/proposal-creation
branch
from
September 3, 2026 20:45
5c8c39d to
d19b935
Compare
Add the proposal-creation component and wire proposals end-to-end
through the sim:
* proposing.rs: the ProposalPlanner decides when a node seals and
submits its proposals. Deadline-driven (seal at deadline - lead, a
fixed configurable lead for now; the component boundary is the seam
for future payload-economic strategies). The spec's proposing
precondition is enforced as a seal prerequisite -- the chaining gate:
slot r is sealed only once slot r - y is part of the contiguous
finalized prefix (the stand-in for the translated block B_{r-y}),
with y the observation cutoff. The blind window's in-flight-knowledge
requirement is met structurally by the schedule's rotation vacancy.
* da.rs: turn the DAHandle stub into the DataAvailability trait --
consensus-side reads plus the proposer-side submit_proposal -- with
NullDa replacing the old always-absent stub. The sim crate adds
MockDa, an in-memory mock that treats a submission as locally decoded
and disseminates one announcement message per proposal over the
simulated network (same latency model as consensus messages).
* runtime/conductor: surface the facts the planner consumes. The
conductor emits CloseSlots whenever the completion cap advances, and
the runtime forwards OpenSlots/CloseSlots to the (now composable)
FinalizationObserver as handle_slots_opened/handle_chain_advance.
* sim: SimMessage wraps the wire format (consensus + DA announcements);
add_proposer_node wires planner, mock DA, and an extra observer per
node. Entry/FastCommitVote/FastCommitQc become pub so finalization
data is inspectable by consumers.
* tests/proposals.rs: end-to-end runs where the finalized entries carry
the scheduled proposers' payload roots -- K = 1 rotating every slot,
and K = 2 staggered phases with observation cutoff 2 across a window
rollover, exercising genesis exemption, rotation vacancies, and the
chaining gate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The spec (papers/specification/main.tex) defines y as the observation
cutoff (y <= x, the execution delay window): proposals of round r build
against B_{r-y} and state^{r-x}, and a party lacking either does not
propose. The blind window is the sliding window of rounds r-y+1..r whose
proposals may not be known in round r -- not the rotation vacancy, and
not the gate parameter.
Rename PlannerConfig::blind_window to observation_cutoff and rewrite the
module docs in spec terms: the chaining gate is the B_{r-y} prerequisite
(the chained prefix standing in for translation), x/y are protocol
constants enforced as back-pressure, and the in-flight-knowledge half of
the blind window is guaranteed by the schedule's rotation vacancy. No
logic changes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MockDa re-implemented the proposer-index check privately while the proposals test built a second authenticator closure for ChorusContext. Two copies of one policy, free to drift with nothing to catch it. Hand MockDa the HeaderAuth consensus votes with and let it validate announcements through that, so an announcement the mock accepts is by construction one consensus would authenticate. The test builds exactly one, from the schedule, via proposers::header_auth. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
larskuhtz
force-pushed
the
lars/proposal-creation
branch
from
September 14, 2026 21:06
d19b935 to
00a4153
Compare
larskuhtz
removed this pull request from stack #3240
September 14, 2026 21:26
larskuhtz
added this pull request to stack #3258
September 14, 2026 21:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #3225 (
lars/proposer-election). Adds the proposal-creation component and wires proposals end to end through the sim: slots finalize withPositiveentries carrying the scheduled proposers' payload roots, across rotations, vacancies, and a window rollover.Design
Proposal creation is its own component, outside the consensus core. Proposing is driven by the slot deadline, not by eligibility: a proposal only counts if it is disseminated and decoded by a supermajority before the slot deadline
D_s, and a proposer benefits from sealing as late as viable. The planner seals atdeadline − lead, withleada fixed conservative bound for now; the component boundary — facts in, wake and seal commands out — is the seam where adaptive or payload-economic strategies plug in later without touching consensus.Everything else is a constraint from the MCP spec (
main.tex, v1.2.0): a party that does not yet haveB_{r−y}andstate^{r−x}does not propose in roundr, withxthe execution delay andy ≤ xthe observation cutoff.B_{r−y}): slotris sealed only once slotr − yis part of the contiguous finalized prefix reported by the conductor — the stand-in for the translated block until sequencing exists. A lagging chain holds seals back; a seal skipped past its deadline leaves the index empty, a throughput cost and never a consensus hazard.yslots guarantees there are none. The planner sees vacancy simply as "not scheduled".state^{r−x}): not modeled; it slots in beside the chaining gate once execution progress exists as an input.Changes
monad-mcp-chorus/src/proposing.rs:ProposalPlanner— requests a wake atdeadline − leadfor each slot where the schedule assigns this node an index; on wake it seals, or gates on chaining and releases or skips at the next chain advance.monad-mcp-chorus/src/da.rs: the proposer-side seam towards the DA layer —DataAvailability::submit_proposal, by which the planner hands a sealed payload over for dissemination, plusNullDafor proposal-less tests. The consensus-side direction is the existingChorusDAEvent/ChorusDACommandseam.MonadConductoremits the (previously never-emitted)CloseSlotsoutput whenever the completion cap advances; the runtime forwardsOpenSlots/CloseSlotsto the observer ashandle_slots_opened/handle_chain_advance, and observers compose as tuples.Runtimegains the DA-event entry point — an associatedDAEventandhandle_da_event— so a node's DA layer can report availability to the slot instance it drives. Runtimes without a DA layer default it away.monad-mcp-chorus-sim:MockDa, an in-memory DA mock. A submission becomes available locally at once and is announced as one message over the simulated network, under the same latency model as consensus traffic; availability reaches consensus asChorusDAEvents. The mock validates announcements with theHeaderAuthconsensus itself votes with, so the two cannot disagree about who proposes where.SimMessagewraps the wire format, andadd_proposer_nodewires planner, mock DA, and a per-node observer.Entry,FastCommitVoteandFastCommitQcbecomepub, so finalization data is inspectable by consumers — as ledger sequencing eventually will.Testing
MockDaunit tests: submit, announce, availability reporting, idempotent delivery, first root wins, and an announcement for an index its signer does not hold.tests/proposals.rsend to end:K = 1rotating every slot — every entry finalizesPositivewith the scheduled proposer's payload root, on the same finalization schedule as proposal-less runs;K = 2staggered phases withy = 2across a window rollover — genesis exemption, rotation vacancies (Negativeexactly where the schedule says), and the chaining gate under load.