Repository navigation
feat(cli): Add support to rollups-node alpha.14 and PRT sentries [Setup + Local runs] - #569
brunomenezes wants to merge 17 commits into
Conversation
Coverage Report
📁 File Coverage (20 files)
|
99e6d83 to
6ce1d09
Compare
🦋 Changeset detectedLatest commit: db40096 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
6ce1d09 to
ddc54c8
Compare
ddc54c8 to
4f3d67a
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
2529ff4 to
a78996a
Compare
|
Hey @endersonmaia could you have a look in the following commits, check if see any problems or improvements in the following commits |
c3a5992 to
2902204
Compare
|
I see you're using new containers for the sentry, but have you tried scaling them instead of new instances? So, instead of creating a new instance Use the On another end, we could leverage This way we wouldn't need to spin up a new container. This would consume less resources BUT may be more complicated since there's already a Service abstraction that controls the containers. The test I did with sentries works, with 2 sentries and sending a couple of inputs and I can see logs and stuff. The suggestions above are just suggestion, nothing blocker. |
|
In see you used a bind mount to expose the secret content, that's what docker compose already does via its Just like we already do with Is there any reason why you didn't use the |
I did not think on using "scaling" for that. However, the sentries aren't identical replicas. Each one has its own signer (a devnet account or a key file), data dir and label, and a later type may run a different binary (ref-node as sentry and Diego's Lua named Crisium) that is why the config is designed with Are you thinking on using replicas when running sentries on your environment? Same signer and configs? On this branch I am separating devnet accounts to avoid the lately wide spread problems with nonces. I also defined a pool of high accounts just for sentries, I reserved accounts from index 20 to 29 (that is more than enough I assume, for testing using devnet)
I think you are spot on in the "more complicated" and not as much of again to be honest. But being a bit more deep on my answer; the |
There is a problem identified by the rollups-node team a couple of weeks/months ago. The compose file
|
813d17d to
5954e82
Compare
5954e82 to
db40096
Compare
|
Closing in favour of #577 that use that one as base branch. |

Summary
Adapts the CLI to rollups-node 2.0.0-alpha.14 (cartesi/rollups-node#809 → cartesi/rollups-node#815) and Dave 3.0.0-alpha.6, fixes
cartesi runbugs found on the way, and letscartesi run --prtappoint and run PRT sentries fromcartesi.toml.The branch is based on
prerelease/v2-alphawith the alpha.14 node released: SDK 0.12.0-alpha.45 (#562) carries it, and the last two commits make it the CLI's default SDK and bump the explorer to 2.0.0-alpha.6, which supports the alpha.14 node.Sentry configuration Design (why)
Tip
✅ Confirmed by Guilherme from the Dave team: the paragraph below is his description of how sentries take part in claim acceptance.
How sentries fit in the stack: under PRT, each epoch is decided by a tournament. Once it has a winner, the result is staged on the application's DaveConsensus and can be accepted only after the claim staging period, which gives the guardian time to foreclose if the result is wrong. Sentries are addresses set at deployment on the DaveConsensus (the sentry manager can rotate them). Each one runs the application's machine over the same inputs and submits the post-epoch state hash it computed. If every sentry submitted the staged hash, the result can be accepted without waiting out the staging period. If any sentry is missing or disagrees, or there are no sentries, the full period applies. Sentries cannot change which result is staged or block it. But when they all agree, the guardian's window is skipped, so the fast path is only as trustworthy as the sentries are independent of whoever won the tournament.
The list comes from the contract, not the CLI.
deploy application --prttakes--sentries a,b,c, and the DaveConsensus keeps a set of sentries. A claim is accepted before the staging period ends only when all of them agree.[[prt.sentries]]is that list incartesi.toml. The minimal config is one entry with onlytype = "sling".Locally, two
slingsentries on the same snapshot replay the same deterministic machine and compute the same claim. A second one adds no extra evidence that the claim is right. More than one is still useful:addressis appointed but run by someone else, as in a rehearsal of a real topology on a fork.docker compose -p <project> stop sentry-2) makes acceptance fall back to the staging period. Adding an address-only entry that nobody runs has the same effect, which is the case of another operator being slow or offline.[[prt.sentries]]keystype"sling"exists today: acartesi-sling-nodecontainer. Withouttypethe sentry is only appointed, and someone else runs it.addresstype.private_key_fileaddressthe address comes from the key. Reaches the container as an init-service copy.typeand can't be empty. Format, and the match withaddress, are checked before any container starts.labelsentry-<label>, as shown in the run output andcartesi logs.-and_. Unique. Default: the 1-based position, which is also the sentry's ID on the consensus.Each sentry's address comes from the first of these that is set:
address.private_key_file.cartesi runfunds. For example, threetype = "sling"entries with nothing else set get accounts 20, 21 and 22.Sentries are appointed in the order of the entries, so the first one is sentry 1.
[prt]also takes an optionalsentry_manager, the address allowed to replace the sentries later. Without--prt,cartesi runignores the whole[prt]section.Environment of a sling sentry container
CARTESI_SLING_APP_ADDRESSCARTESI_SLING_BLOCKCHAIN_HTTP_ENDPOINThttp://anvil:8545CARTESI_SLING_BLOCKCHAIN_ID31337anvil.id, also right in fork mode (anvil runs with--chain-id 31337)CARTESI_SLING_DATA_DIR/var/lib/cartesi-rollups-node/snapshotsCARTESI_SLING_POLLING_INTERVALcartesi run --block-timeCARTESI_SLING_TEMPLATE_PATH/var/lib/cartesi-rollups-node/template/image./.cartesimounted read-only, the machine the node deployedCARTESI_SLING_AUTH_PRIVATE_KEY_FILE/run/secrets/sentry-<label>private_key_file: the init service's copyCARTESI_SLING_AUTH_PRIVATE_KEYChanges
Node alpha.14
app removerefuses without--allow-abandonment, so every shell rebuild failed at undeploy. The CLI now passes the flag.--default-block pending. The CLI drops the choice.@cartesi/wagmi-plugin1.0.0-alpha.9.cartesi runfixesCARTESI_CONTRACTS_APPLICATION_FACTORY_ADDRESS: variable not defined, since the node was never given the ApplicationFactory.$namein forwardedCARTESI_*values and in--fork-urlas variables, so a password or API key in a URL arrived changed.CARTESI_*_FILEkey files were forwarded as paths only, so the node couldn't open them. They now reach the container as copies owned by the node's user, installed by a root init service, which also works on native Linux where a bind mount keeps the host owner.CARTESI_BLOCKCHAIN_HTTP_ENDPOINTfailed only once the node container started, with the value hidden. It is now rejected before anything starts, with the same rules as the node and without echoing the value.--prt, the shell's redeploy no longer passes the previous application's consensus. The node ignored it, since a PRT deploy always creates its own DaveConsensus for the new machine, but the command read as if the consensus were reused.Signer separation
cartesi sendandcartesi depositdefaulted to devnet account 0, the account the node signs its claims with, so user inputs shared the claimer's nonces. They now default to account 8, and--fromstill picks another.PRT sentries
deploy application --prthas taken--sentriesand--sentry-managersince alpha.13, but the CLI couldn't set them, and nothing ran a sentry.[prt]section incartesi.tomlnames an optionalsentry_managerand[[prt.sentries]]entries, appointed on the DaveConsensus in that order.type = "sling"is run by the CLI as acartesi-sling-nodecontainer,sentry-<label>, on the same machine snapshot the application was deployed with.private_key_file(your key, you fund it) or, with neitheraddressnor key file, from the CLI's sentry pool, devnet accounts 20 to 29, funded with 10,000 ETH bycartesi run.addressis appointed and run elsewhere.--claim-staging-period.--prtthe section is ignored.cartesi logs, and the shell's View logs, show the sentries next to the node, andcartesi logs sentry-greenshows one.Order under
--prt: parse[prt]and resolve each sentry → start the environment → fund the pool sentries → deploy with--sentries/--sentry-manager→ startsentry-<label>containers → on a shell rebuild, stop the sentries → undeploy (--allow-abandonment) → redeploy on a new DaveConsensus → start the sentries again.PRT sentries config example
Checks before anything starts
private_key_filemust hold a hex private key on its first line, matchaddresswhen both are given, and not be a devnet account's key./run/secrets, never as an environment variable.Detailed changes
commands/run.ts:--allow-abandonmenton undeploy, andpendingremoved from--default-block.[prt]resolution, sentry funding before the deploy, and sentry containers after it and across rebuilds. Once the sentries run, it prints the manager and each sentry with its account and origin, aligned with the deploy's check marks.compose/node.ts:CARTESI_CONTRACTS_APPLICATION_FACTORY_ADDRESSin the node's defaults (a host value still overrides it).$escaped in forwarded values. Anode-secret-initservice and anode_secretsvolume when aCARTESI_*_FILEvariable is set, with the env pointing at/run/secrets/<name>.compose/secrets.ts(new):fileSecretandsecretInitService, the root init service that installscartesi:cartesi 0400copies. Shared by the node and the sentries.compose/sentry.ts(new): thesentry-<label>service oncartesi/rollups-runtime, runningcartesi-sling-node pkagainst the project's anvil and polling every block. The key comes through env for devnet accounts, or as a secret copy for key files.commands/logs.ts:cartesi logs [service...]overdocker compose logs. It shows the node and every sentry by default, or the services named, with a prefix per service when more than one is shown.compose/anvil.ts,compose/common.ts:escapeComposeValue, applied to--fork-url.validations.ts:assertBlockchainEndpoint(mirrors Go'surl.Parseplus the node's http(s)-with-host rule, checked against the alpha.14 binary) andassertSecretFiles.config/toml/prt.ts(new),config/types.ts,config/errors.ts,config/defaults.ts,config.ts: the[prt]table (sentry_manager,[[prt.sentries]]withaddress,type,label,private_key_file), unknown keys rejected like the other tables.sentries.ts(new): the sentry pool,resolveSentries(addresses, key files, reserved accounts, duplicates, warnings),checkSentries(funding and balances),describeSentry.exec/rollups.ts:--sentriesand--sentry-manageron deploy,getDaveConsensus(contract consensus --json),composeEnvironmentfactored out ofstartEnvironment, andstartSentries/stopSentries.wallet.ts:getDefaultSender(account 8) andgetDevnetAccount(address and key of mnemonic accounts 0–29).commands/send.ts,commands/deposit*.ts: default sender throughgetDefaultSender, and the--fromhelp names devnet account 8.exec/cartesi-machine.ts: require cartesi-machine 0.22.package.json:@cartesi/wagmi-plugin1.0.0-alpha.9 (Dave alpha.6 PRT contracts).config/constants.ts:DEFAULT_SDK_VERSION0.12.0-alpha.45.exec/rollups.ts: the explorer image 2.0.0-alpha.6.undeploy.test.ts(undeploy and redeploy),run.test.ts(dry runs: default block,$, key files, endpoint,[prt]errors),send.test.ts(default sender),prt.test.ts(sentries appointed, sling nodes running on funded accounts, a claim accepted far inside a 1,000,000-block staging period, a claim that waits while one sentry is stopped and is accepted once it is back,cartesi logsshowing them), a key-file case innode-startup.test.ts(the node reads0600key files, their copies arecartesi:cartesi 0400, the host files are untouched), and the two previously skipped withdrawal cases.cartesi logsand the default SDK. Patch for the redeploy fix,--default-block,$escaping, key files, the contracts bump and the explorer bump.