Repository navigation
fix(types): do not clamp the delayed public mutable time horizon on a scheduled change to the same value - #25586
Merged
Merged
Conversation
… scheduled change to the same value
iAmMichaelConnor
approved these changes
Oct 4, 2026
Contributor
|
I'll nurse the required ports to the various branches |
iAmMichaelConnor
marked this pull request as ready for review
October 4, 2026 16:16
iAmMichaelConnor
requested review from
IlyasRidhuan,
LeilaWang,
iakovenkos and
ledwards2225
as code owners
October 4, 2026 16:16
iAmMichaelConnor
enabled auto-merge (squash)
October 4, 2026 16:16
1 task done
iAmMichaelConnor
pushed a commit
that referenced
this pull request
Oct 4, 2026
Rolling integration PR for changes labelled `port-to-v6` on `next`. Each merged source PR is cherry-picked onto `cb/port-to-v6` as its own commit, keeping `(#N)` in the title. ## Ported - [x] [#25586](#25586) fix(types): do not clamp the delayed public mutable time horizon on a scheduled change to the same value (clean pick; testnet re-pin pending) - All three files end up identical to `next` at d363a40, as do the `types` and `private-kernel-lib` crates. ## Protocol impact - `ScheduledValueChange::get_time_horizon` no longer clamps the horizon when the scheduled value equals the current one, so a cancelled or idempotent contract update no longer shortens callers' `expiration_timestamp`. A genuine pending change is clamped as before. - This changes the `private_kernel_init` and `private_kernel_inner` circuits (and their batched variants), so the VK tree root that `v6` builds moves. - Labs patch `0001-test-pin-testnet-compatibility-to-the-v6-kernel-VK-t.patch` currently pins `0x05b95d9ef57c61d1c6626545101db55ae2d1f98ecb618d1c220610c049ee522b`, so `testnet_compatibility.test.ts` is expected to fail on this head. - Following the decision recorded on #25549 (a breaking kernel change ported to `v6` re-pins testnet in the same PR), the patch is updated here once CI reports the new root. - Per the source PR, the protocol contracts compile to identical bytecode, so genesis does not move. ## Testing - `./labs-patches/bootstrap.sh check`: the series (0001, 0010) applies cleanly to the labs pin `a0d73c0aed`. - Not built or tested locally (no `nargo` in the port environment); the `types` and kernel unit tests run on this PR's CI. --- *Created by [claudebox](https://claudebox.work/v2/sessions/134efca9a11ee14f/jobs/26) · group: `slackbot` · [Slack thread](https://aztecprotocol.slack.com/archives/C0AGN2WT3CP/p1790609320989739?thread_ts=1790609320.989739&cid=C0AGN2WT3CP)*
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.
Closes AztecProtocol/aztec-claude#2425
Problem
ScheduledValueChange::get_time_horizontreats any pending scheduled change as a bound on how long the value read at the anchor block stays current, clamping the horizon totimestamp_of_change - 1. It does so even when the scheduledpostequalspre, i.e. the change does not move the value. That state is produced by the documented cancellation mechanism (scheduling the current value) and by any idempotent setter such asContractInstanceRegistry::updatere-applying the class a contract already runs.Because the private kernel folds the registry entry's horizon into
expiration_timestampfor every private call to that contract, a cancelled or idempotent update pins every caller's deadline to the phantom instant for a full delay period. As the anchor approaches it, the inclusion window shrinks to zero: atanchor == timestamp_of_change - 1the kernel emitsexpiration_timestamp == anchor_block_timestamp, which the rollup rejects for every later block.Fix
In
get_time_horizon, take the "no change ahead" branch (anchor_block_timestamp + minimum_delay) whenself.pre == self.post. Such a change cannot alter the current value, so the earliest a different value can take effect is bounded byminimum_delay, exactly as when no change is pending. The method gains aT: Eqbound; its callercompute_delayed_public_mutable_time_horizonalready requiresT: Eq.The clamp for a genuine pending change (
pre != post) is unchanged. Which ofpreorposta read returns (get_current_at) is unchanged.Not covered
A contract that has never been updated has the stored class id 0, which the kernel reads as "use the original class". Cancelling that contract's first update needs
update(original class), which stores(0, original, toc). The two values mean the same class but are not equal, so the clamp still applies. This is safe (the horizon is too early, never too late). Covering it needs a kernel-level comparison that maps 0 to the original class id.Scope and cost
private_kernel_init,private_kernel_innerand their batched variants: +5 ACIR opcodes per private call.private_kernel_reset_tailis unchanged.Tests (red → green)
types:test_get_time_horizon_change_to_same_value_in_near_futureasserts the horizon isanchor + minimum_delayand checks the existing horizon invariants. Fails without the fix (returnstimestamp_of_change - 1).private_kernel_lib(private_kernel_init), driven through the real registry hint with a rebuilt public-data tree:expiration_timestamp_not_constrained_by_pending_contract_update_to_same_class: a change to the class the contract already runs atanchor + 1yieldsexpiration_timestamp == anchor + DEFAULT_UPDATE_DELAY - 1. Fails without the fix (emitsanchor).expiration_timestamp_constrained_by_pending_contract_update: control pinning that a genuine pending update atanchor + 1still collapses the deadline toanchor.The patch applies to
next@551aa413aecwith no changes beyond a 3-line hunk offset. Fulltypes/private_kernel_libsuites andnargo fmt --checkpassed on the same change against the private mirror ofnext; CI covers this branch.Labeled
port-to-v6.Created by claudebox · group:
slackbot· requested by Mike (@iAmMichaelConnor) · Slack thread