Skip to content

feat(katana): declare Controller account classes in rollup genesis#584

Merged
kariy merged 6 commits into
mainfrom
feat/rollup-controller-classes
Jun 3, 2026
Merged

feat(katana): declare Controller account classes in rollup genesis#584
kariy merged 6 commits into
mainfrom
feat/rollup-controller-classes

Conversation

@kariy
Copy link
Copy Markdown
Member

@kariy kariy commented Jun 2, 2026

katana init rollup now declares the Cartridge Controller account classes in the rollup genesis by default (so a Controller can be UDC-deployed on the appchain) and seeds 3 dev accounts (the cartridge paymaster sidecar reserves dev accounts 0/1/2 as relayer/gas-tank/estimate).

The classes are declared via a real genesis declare transaction (GenesisTransactionsBuilder::build_preloaded_classes), so the rollup genesis builder is the single source of the genesis state. The declare hash is recomputed from the class artifact, so the classes are usable by their canonical hash even after the genesis.json round-trip — removing the previous runtime re-declare workaround. A rollup's genesis transactions are otherwise unchanged (the core classes dedup to no-ops; the STRK fee token stays pre-allocated).

Originally added as an opt-in --cartridge-controllers flag; the flag was dropped in favour of making rollups Controller-ready by default.

Stacked on #583 (base: feat/rollup-chain-spec).

🤖 Generated with Claude Code

…nnet address

Rollup mode previously deployed a custom STRK ERC20 via UDC at the derived
address 0x2e7…, because UDC-derived addresses can't land at the canonical
Starknet mainnet STRK address (0x0471…). This made it impossible for wallets
and explorers to treat a rollup like Starknet mainnet/sepolia.

The fix mirrors the dev-mode pattern: the STRK fee token is now pre-allocated
into genesis state (class declared, contract deployed, ERC20 storage seeded
with the master account holding initial supply) at DEFAULT_STRK_FEE_TOKEN_ADDRESS,
bypassing UDC entirely. The genesis transactions builder drops the ERC20
declare+deploy txs and points its in-memory fee-token cursor at the canonical
address so the existing transfer_balance invokes keep working.

A small PreloadedStateProvider overlay lets the executor see the pre-allocated
state when processing the genesis block; init_rollup_genesis merges the
pre-allocation into the execution output before commit.

DEFAULT_APPCHAIN_FEE_TOKEN_ADDRESS is removed in favor of the canonical
constant; CLI init and the settlement bootstrap (SNOS / Katana-TEE config
hashes) are updated to bind to it. add_fee_token is extracted into a shared
chain-spec/fee_token module since dev and rollup now both call it.

Out of scope: deployment.rs INITIAL_STATE_ROOT stays at Felt::ZERO. Genesis
state is no longer empty before block 0 executes, so SNOS-proven settlement
will diverge until the settlement bootstrap publishes the real genesis state
root — tracked as a follow-up in the deployment.rs comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

Codec benchmark diff vs main

Benchmark Baseline (ns) Current (ns) Δ
CompiledClass(fixture)/compress 2686623 2398943 -10.71%
CompiledClass(fixture)/decompress 2931175 2698628 -7.93%
ExecutionCheckpoint/compress 35 28 -20.00%
ExecutionCheckpoint/decompress 25 23 -8.00%
PruningCheckpoint/compress 35 29 -17.14%
PruningCheckpoint/decompress 25 23 -8.00%
VersionedHeader/compress 643 652 +1.40%
VersionedHeader/decompress 821 725 -11.69%
StoredBlockBodyIndices/compress 76 71 -6.58%
StoredBlockBodyIndices/decompress 37 36 -2.70%
StorageEntry/compress 146 120 -17.81%
StorageEntry/decompress 141 119 -15.60%
ContractNonceChange/compress 145 118 -18.62%
ContractNonceChange/decompress 234 203 -13.25%
ContractClassChange/compress 217 167 -23.04%
ContractClassChange/decompress 259 219 -15.44%
ContractStorageEntry/compress 160 127 -20.63%
ContractStorageEntry/decompress 309 279 -9.71%
GenericContractInfo/compress 140 122 -12.86%
GenericContractInfo/decompress 102 85 -16.67%
Felt/compress 82 70 -14.63%
Felt/decompress 59 47 -20.34%
BlockHash/compress 82 73 -10.98%
BlockHash/decompress 58 47 -18.97%
TxHash/compress 82 70 -14.63%
TxHash/decompress 59 47 -20.34%
ClassHash/compress 82 70 -14.63%
ClassHash/decompress 59 47 -20.34%
CompiledClassHash/compress 82 70 -14.63%
CompiledClassHash/decompress 59 47 -20.34%
BlockNumber/compress 47 43 -8.51%
BlockNumber/decompress 25 23 -8.00%
TxNumber/compress 47 43 -8.51%
TxNumber/decompress 25 23 -8.00%
FinalityStatus/compress 1 0 -100.00%
FinalityStatus/decompress 12 10 -16.67%
TypedTransactionExecutionInfo/compress 18091 14741 -18.52%
TypedTransactionExecutionInfo/decompress 3635 2531 -30.37%
VersionedContractClass/compress 373 354 -5.09%
VersionedContractClass/decompress 795 647 -18.62%
MigratedCompiledClassHash/compress 146 118 -19.18%
MigratedCompiledClassHash/decompress 138 119 -13.77%
ContractInfoChangeList/compress 1628 1521 -6.57%
ContractInfoChangeList/decompress 2237 2131 -4.74%
BlockChangeList/compress 689 645 -6.39%
BlockChangeList/decompress 903 865 -4.21%
ReceiptEnvelope/compress 30170 25712 -14.78%
ReceiptEnvelope/decompress 6131 5402 -11.89%
TrieDatabaseValue/compress 165 140 -15.15%
TrieDatabaseValue/decompress 219 223 +1.83%
TrieHistoryEntry/compress 289 268 -7.27%
TrieHistoryEntry/decompress 255 197 -22.75%

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

Runner: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz (4 cores) · 15Gi RAM

kariy and others added 3 commits June 2, 2026 15:44
`add_fee_token` is a builder-style genesis helper whose 8 args are each a distinct
token field; allow the lint locally rather than wrapping them in a struct that just
moves the arg list to the callers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`katana init rollup --cartridge-controllers` declares the Cartridge
Controller account classes in the generated genesis, so a Controller can
deploy and sign on the appchain (not just the settlement chain). In that mode
the genesis also seeds 3 dev accounts instead of 1, because the Cartridge
paymaster sidecar reserves accounts 0/1/2 (relayer, gas tank, estimate) and
would otherwise fail to bootstrap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Lockfile catch-up from the `--cartridge-controllers` katana work; regenerated by the build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kariy kariy force-pushed the feat/rollup-controller-classes branch from 3376f8f to 83568bf Compare June 2, 2026 20:49
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 2, 2026

Codecov Report

❌ Patch coverage is 80.59701% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.70%. Comparing base (2bf5976) to head (1a437e4).

Files with missing lines Patch % Lines
crates/chain-spec/src/rollup/utils.rs 87.09% 8 Missing ⚠️
bin/katana/src/cli/init/mod.rs 0.00% 5 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##           feat/rollup-chain-spec     #584      +/-   ##
==========================================================
+ Coverage                   68.68%   68.70%   +0.02%     
==========================================================
  Files                         322      322              
  Lines                       45601    45664      +63     
==========================================================
+ Hits                        31320    31375      +55     
- Misses                      14281    14289       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Classes inserted into `genesis.classes` (e.g. the Cartridge Controller
account classes added by `katana init rollup --cartridge-controllers`)
were never declared on a rollup: the genesis builder only declared the
core classes it deploys, so preloaded classes lived in `genesis.classes`
but had no declare transaction. On a rollup the genesis is built solely
from those transactions, so the classes weren't actually declared, and
the genesis.json round-trip shifted their map key — leaving them
unusable by their canonical hash (worked around with a runtime declare).

Declare any preloaded class through a real genesis declare tx, the same
way the core classes are declared. `declare` recomputes the class hash
from the artifact (not the map key), so the class lands at its canonical
hash even after a genesis.json round-trip. The STRK fee token class is
skipped — it's pre-allocated into state at the canonical mainnet address,
not declared (enforced by `strk_pre_allocated_at_canonical_address`); the
UDC/account classes are already declared, so dedup makes them no-ops and
a controllerless rollup's genesis transactions are byte-identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kariy kariy force-pushed the feat/rollup-controller-classes branch from 4271395 to 95d8e2c Compare June 3, 2026 16:22
Drop the opt-in `--cartridge-controllers` flag on `katana init rollup`
and make rollups Cartridge Controller–ready by default: the Controller
account classes are always declared in the genesis, and 3 dev accounts
are always seeded (the Cartridge paymaster sidecar reserves accounts
0/1/2, so fewer aborts its bootstrap). The classes are declared via a
real genesis declare tx, so they're usable by their canonical hash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kariy kariy changed the title feat(katana): opt-in Controller account classes in rollup genesis feat(katana): declare Controller account classes in rollup genesis Jun 3, 2026
Base automatically changed from feat/rollup-chain-spec to main June 3, 2026 17:41
@kariy kariy merged commit d82d222 into main Jun 3, 2026
20 of 21 checks passed
@kariy kariy deleted the feat/rollup-controller-classes branch June 3, 2026 17:41
kariy added a commit that referenced this pull request Jun 3, 2026
Most blockers are resolved now: the fee-token mismatch (canonical STRK pre-allocated
in the rollup genesis) and the stale-fee / false "Simulation Error" review-screen
bugs (merged upstream in cartridge-gg/controller#2609). Rework the section into
"Resolved" vs "Still open" — the latter being the self-hosted keychain (switch
re-point not yet in the deployed x.cartridge.gg, CORS proxy) and the runtime
controller-class declare. Note the #584 gap: it declares the round-tripped genesis
artifact at a shifted hash, not the canonical 0x743c8 the keychain deploys, so the
runtime declare is still required.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kariy added a commit that referenced this pull request Jun 3, 2026
Expand keychain-fork/README into a working setup: clone controller at the #2609
merge + apply the local patch, generate trusted mkcert certs, install/build-deps/run
the keychain on :3010 (with health-check curls), point the demo at it, declare the
controller class (the #584 runtime step), and connect. Adds a Gotchas section
(trusted cert mandatory, keychain must be up first, Chrome PNA flag, ports, re-declare
each ./up.sh).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kariy added a commit that referenced this pull request Jun 3, 2026
…ler class

The production keychain at x.cartridge.gg redeployed from main right after #2609
(confirmed: the deployed bundle carries the use-simulate fix), so it now has both the
behavioral fixes and the switchChain rebuild. That lets the demo drive the appchain
Controller with the *hosted* keychain directly — no self-hosted keychain, no CORS
proxy. The default path needs no app/.env.local.

The one remaining gap was the controller class hash: katana #584 declares the
round-tripped genesis artifact at a shifted hash, not the canonical 0x743c8 the
keychain deploys, so the Controller couldn't auto-deploy on the appchain after boot.
Fold a boot-time declare into up.sh (CONTROLLER mode) via a new
scripts/declare-controller-class.ts, so `CONTROLLER=1 ./up.sh` is now sufficient.

Docs: rewrite client.md "known blockers" (most resolved; the #584 declare is now
handled by up.sh), make the README "Using Controller" accurate, and demote the
keychain-fork to a documented fallback for unreleased keychain changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant