Repository navigation
v3.0.0-alpha.6
Pre-release
Pre-release
A new deployment generation (#287). Nodes from earlier releases
cannot read these contracts, this node cannot start against earlier ones, and
every address moves. Nothing is deployed on mainnet yet, so no migration is
needed.
Contracts
- Clock refill: a winner returning from a child tournament is refilled by up
toT + 2G(commitment budget plus two inclusions), within the sealed
pair's envelopemax(r1, r2), so repeated Sybil delegations cannot drain a
correct commitment's clock. A leaf proof or a timeout win earns one
inclusionG. The root allowance isC + 2G + (L - 1)(T + 2G). - In-flight reserve: the root allowance holds one more inclusion, because a
response is accepted only while its latency fits the balance and the root
join's lateness is deducted with no discount; at one levelC + Glost
the correct commitment at zero censorship (F-01,
docs/reviews/2026-10-13-prt-cyber-verification). The canonical mainnet
allowance is one week plus 140 minutes.ClockBudgetschanges, so the
provider's initcode and every address built from it move. - Refunds count the leaf proof's bytes at 16 units per byte. Only the proof
is metered: the state transition fixes its length, and it now rejects input
bytes at a position with no input (InputBytesWithoutInput). Every
allocation was recalibrated;WIN_LEAF_MATCHis 5,536,000. - Interface changes:
TournamentArguments(the clone arguments) and
TournamentParametersgaincommitmentBudget, sotournamentParameters()
returns six fields;CanonicalTournamentParametersProvider's constructor
takes(blockMilliseconds, censorshipSeconds, inclusionSeconds), derives
the budgets (ClockBudgets) and can revert withBlockTimeCannotBeZero;
CartesiStateTransitiongains one error and the
UARCH_PRISTINE_STATE_HASH()getter. Tournament's function ABI is
unchanged; its events change as below. - Tournament and factory events gain fields, so every changed event has a
new topic0.MatchCreatedandMatchAdvancedadd the responder's
deadline, andMatchAdvancedthe pair and the post-advance height;
LeafMatchSealedadds the pair, the sealed divergence and both deadlines;
NewInnerTournamentadds the pair, the contested final states, and the
child's descriptor and bond;TournamentCreatedadds the descriptor and
bond. The newStandingChangedfollows every join and match deletion
with the live match count, the dangling commitment and, once no match is
live, the finish instant and an inner winner's parent commitment and
expiry. IMultiLevelTournamentFactory.instantiateInneralso returns the child's
descriptor, which the parent publishes; existing selectors and ERC-165
ids are unchanged. The rollups contracts import these interfaces, so their
bytecode metadata changes too, and every CREATE2 address built from these
sources moves:CartesiStateTransition,Tournament, the factory,
DaveAppFactory, and the applications and consensuses it creates.- The canonical table is two levels:
log2step = [38, 0],
height = [54, 38], with a 120-minute commitment budget. Existing
applications keep the table of the factory that deployed them:
DaveConsensusbinds its tournament factory immutably. Off-chain
claimers now build the root commitment at one leaf per 2^38 meta-cycles
(an emulator mcycle computation-hash period of 2^18, 2^30 leaves per
input window, root height 54), so a claimer pinned to the three-level
root (2^44, height 48) cannot join applications from the new factory. - An epoch now settles no sooner than about one week and 140 minutes after it
seals on mainnet (one week and 60 minutes before), and about 10 hours 20
minutes on testnets, plus the claim staging period unless every sentry
agrees. - Join bonds at the 50 gwei work-price cap, canonical table: root (height
54) 0.36115 ETH, leaf (38) 0.51265 ETH. CartesiStateTransitionqualifies Cartesi Machine v0.22 through
solidity-step v0.16:CM_MARCHID()is 22, now imported from step instead
of a local literal, and every uarch reset restores v0.22's pristine uarch
hash. Every machine state hash moves, so templates must be rebuilt with the
v0.22 tools.
Chains
- Supported: Ethereum mainnet and Sepolia, in the
deployment-addresses
asset. - Experimental, in the
deployment-addresses-experimentalasset:- OP Mainnet, Base and their Sepolia testnets: the node runs there but is
not validated, and refunds leave out the L1 data fee. - Arbitrum One and Arbitrum Sepolia, registered at the parent chain's
12 s block time (their addresses equal Ethereum's and Sepolia's). The
node does not support them and stops at startup: contracts there measure
clocks in the parent chain's block numbers, while logs use Arbitrum's.
- OP Mainnet, Base and their Sepolia testnets: the node runs there but is
Addresses
The CREATE2 addresses the deploy scripts produce, as in the
deployment-addresses asset. These moved:
| Contract | Ethereum mainnet | Sepolia |
|---|---|---|
CanonicalTournamentParametersProvider |
0xF536648a9cc6c20c4824dDf653C03145A2A31DD9 |
0x008C22Ba3Fb5CBAb17A78188EC3251e31Df5e719 |
MultiLevelTournamentFactory |
0xeF9028820bA365Cd0368ACe2681BfdD78815C000 |
0x66f3d801Aa9b047113fc9Ca09Fe9Efd9A338F397 |
DaveAppFactory |
0x37238515E8161486C53741abe615EF1452309128 |
0xBD2a661328595113669a6b4c235126eec8c06A15 |
CartesiStateTransition |
0x81d9bD8A7EdAC76B7A5b6635076944924883383a |
same |
Tournament |
0x070d2c95Da45F665D383C3757476A76a5b0Be237 |
same |
The rollups contracts (cartesi-rollups-contracts 3.0.0-alpha.10) keep their
v3.0.0-alpha.5 addresses on both chains, InputBox at
0xEbE9f4Dfc04ae10bBeE663859c3dc5A23f94eA3C among them.
Node
- Links Cartesi Machine v0.22, which refuses machines stored by v0.21: a
node built against v0.21 cannot start against these contracts, and v0.21
templates and data directories do not load. - Start from a fresh data directory: the schema changed (tournament events are
no longer stored; the chain id is pinned), and the directory holds a
node.lockthat refuses a second process. The store carries a format stamp,
so a directory an earlier release built exits 40. A stopped directory may
now be moved or copied: snapshot paths derive from their state hashes. A
fresh directory seeded from the template replays every input since the
application's deployment; one seeded from the state the current sealed epoch
starts from executes from that epoch on and never touches an earlier one, so
bonds its signer holds there are the operator's to recover. See the README's
operator notes for both and for a side-by-side upgrade. - Changing the signer no longer needs a fresh directory: the node recovers
its current signer's bonds, and a previous signer's stay recoverable by
anyone throughtryRecoveringBond, which pays the recorded claimer. The
node does not revisit a completed epoch for them. - A first start checks the seed image (the template, or the last settled
state at the finalized head) against the chain, and every start checks the
directory's pins and each endpoint's chain id, before writing anything; an
endpoint on another chain exits 30, and one that does not answer, the
submit endpoint included, exits 1. A seeded directory never reads
--template-pathagain. - A first start also refuses a seed image whose files the node maps for
writing lack the owner write bit (exit 30): it would seed and then fail
every batch. Make such an image writable (chmod -R u+w). - Startup warns when no separate submit endpoint is set off anvil, and a send
the submit endpoint does not answer is a WARN that pages after 5 minutes,
not an ERROR on every send. The README lists what a submit relay must do,
answeringeth_chainIdincluded, and docs/runbooks/submit-relay.md
qualifies one; none has passed yet. - The exit status says why the node stopped: 0 a requested stop, 1 any other
error, 2 a usage error, 30 terminal (an operator must act), 40 a data
directory to rebuild, 101 a panic. Under systemd, set
RestartPreventExitStatus=2 30 40. See the README's operator notes. - One paging rule: a failure that would cost a dispute logs WARN while it
lasts and ERROR once it has lasted 5 minutes, the response window, so an
ERROR asks an operator to act. - An obligation the local commitment already missed (joins closed before it
joined, its clock expired, its match or its match's child is eliminable)
logs an ERROR every tick, and a loss names its case: elimination, another
class's child win, or another commitment's root win, whose ERROR says
whether its final state is this node's. Once a state this node did not
compute settles, the node stops with exit 30 at the next epoch. - A sentry also claims its own computed state after another commitment wins
the root, as the dissent a guardian reads; staging and acceptance still
follow only its own win. - The runner refuses a batch or an epoch roll with less than 1 GiB free on
the data directory's filesystem, where a full disk would kill it mid-batch
with nothing logged. - Every AWS KMS call is bounded like an RPC attempt (20 s), so a KMS endpoint
that never answers fails the tick instead of parking it. - Once caught up, the node logs an ERROR when the read endpoint's latest
block is 5 minutes old or more: such a provider answers consistently with
an old head while dispute clocks run. - The first log line names the release tag the binary was built from (or
says it is an unreleased build), the linked Cartesi Machine and its
MARCHID, and startup logs whether the signer is a sentry of the
consensus. The configuration it runs with is now one log line, not a
record split over several. - Startup also requires the deployed state transition's
UARCH_PRISTINE_STATE_HASH(), the linked emulator's pristine uarch hash and
the template's uarch state hash to be equal, beside theCM_MARCHIDcheck,
and names the pair that disagrees. - Ingestion starts at the application's (or its consensus's) deployment,
checks the chain's input and sealed-epoch totals at the finalized head, and
refuses an incomplete response there before committing (catch-up chunks are
checked for contiguity only; see the README's operator notes). --long-block-range-error-codesis removed: any failedeth_getLogsover
more than one block is split, and a failure at one block fails the tick.
Passing the flag is now a startup error; its environment variable is
ignored.--auth-private-keyis removed: any local user can read a process's
arguments. Thepksigner takes its key from
CARTESI_SLING_AUTH_PRIVATE_KEYor--auth-private-key-file, and
passing the old flag is a usage error. See the README's Run section.--blockchain-http-endpointand--blockchain-idare required; they
defaulted to anvil'shttp://127.0.0.1:8545and 31337.aws-kmsno longer defaults--aws-regiontous-east-1or builds
https://kms.<region>.amazonaws.com: the AWS SDK resolves the region and
endpoint (profile, instance metadata, FIPS, other partitions), and the
two flags only override it. They no longer readAWS_REGIONand
AWS_ENDPOINT_URLthemselves; the SDK still does. A start where no region
resolves fails, naming--aws-region.- Bond recovery keeps its dispute tree across ticks instead of re-walking it,
so its scan no longer grows with the dispute's age. - Gas limits come from estimates (half again, at least 150,000, clamped at the
EIP-7825 cap); a call that already reverts is not sent; an underpriced
replacement is retried once. The node logs an error when the batch needs
more than the signer holds; see the README's funding floor. - A terminal application's epoch is defended and then held, never staged,
instead of crashing every node. - SIGTERM stops the node like Ctrl-C; a second signal exits at once.
- SQLite commits sync fully, and release builds keep overflow checks.
- Logged RPC errors no longer quote the endpoint URL, which often carries an
API key. - The RPC client keeps reqwest's defaults apart from a 20 s timeout, HTTP/2
keep-alive PINGs and a 60 s idle timeout. A rate-limited request is resent
at most twice, never waiting over 5 s, and never for Infura's result-count
rejection, which the log fetch splits instead.
For developers
- Renamed or removed recipes:
measure-constantsis
measure-level-constants;prt-contracts::measure-gasand
rollups-contracts::measure-prt-leaf-gasarejust measure-prt-gas; the
clean-*recipes areprograms::clean PROGRAM, onecleanper contracts
project and the rootclean; the e2e entry points arejust e2e,
just e2e-smokeandjust e2e-logs. - Also removed: the Docker dev environment and its recipes (
setup-docker,
prepare-docker-context,run-dockered,exec-dockered),
update-submodules,check-rust-workspace,test-prt-timeout-boundaries,
the per-scenariotest-rollups-*recipes (usejust e2e) and the
per-moduledoctorrecipes (usejust doctor). - The honeypot image is an opt-in build from a pinned ref:
programs::build-honeypot-snapshotisprograms::build-honeypot. Docker is
needed only forjust test-kmsand the honeypot image. - Each worktree's devnet needs one rebuild:
just rollups-contracts::build-devnet. build-devnetnow deploys a three-level test table through a test-only
provider (TableTournamentParametersProvider), the one CI and local tests
run;DEVNET_GEOMETRY=canonicaldeploys the production contracts and
geometry, as the release's-anvil-asset does. That asset's clocks assume
12 s blocks and no censorship slack: an epoch settles no sooner than 700
blocks (140 minutes) after it seals, and a leaf join gets 600 blocks to
build its commitment. A dense two-level leaf takes tens of minutes to
build, so on a devnet that mines faster an honest node can run out of
clock.- The measurement tool is the node crate's example,
cargo run --example measure, which thejust measure*recipes run; release builds no longer
compile it. just test-node-harnessruns the anvil harness and the other anvil tests
in parallel.just test-lua-clientalso checks the Lua client's event layouts against
the compiledITournamentABI, so it now needsforge,jqand the PRT
contract dependencies (just prt-contracts::install-deps).
What's Changed
- PRT clock refill and calldata refunds, and a hardened, two-level-ready validator node by @GCdePaula in #287
- Rename cartesi-rollups-pr-node to cartesi-sling-node by @endersonmaia in #293
- Refactor/consistent env and parameters naming by @endersonmaia in #294
- Sling rename follow-ups: hide env values in --help, name the node, fuller startup config by @GCdePaula in #295
- Two-level tournaments: [38, 0] / [54, 38] at T = 120 by @GCdePaula in #296
- Tournament events: match schedules and tournament standing by @GCdePaula in #297
- PRT cyber verification: in-flight reserve fix, record and suites by @GCdePaula in #298
- Sling node hardening for the v0.22 generation by @GCdePaula in #299
- Release v3.0.0-alpha.6: piped-key fix and changelog cut by @GCdePaula in #300
Full Changelog: v3.0.0-alpha.5...v3.0.0-alpha.6