Summary
On Shellnet 4.0.30 with dexdo v0.0.18 (doctor fully green), note deploy completed both wallet spends and deployed the PrivateNote, then failed on the final step:
Error: deploy PrivateNote from wallet 0:61993c8c…9329:
RootPN.sendEccShellToPrivateNote: block manager rejected message [TVM_ERROR]:
Failed to execute the message. Error occurred during the compute phase.
The resulting note is Active and holds its N10000 nominal, but zero ECC[2] SHELL, so it cannot provision anything. Resuming with --recovery reproduces the identical rejection deterministically (3 attempts): the resume correctly refuses to re-spend and replays the persisted gas-voucher proof, and every replay is rejected the same way. dexdo note recover then refuses to pool the note because the deploy never finalized:
Error: note deploy recovery state is not finalized for pooling
(shell_funded=false, sanity_checked=false); re-run `dexdo note deploy --recovery <this-file> --pool <pool>`
to resume before using `dexdo note recover`.
That is a closed loop: note recover requires a finalized deploy, and the deploy cannot finalize. 100 SHELL + 10,000 NACKL left the funding wallet and are not usable or recoverable through the CLI.
This is the mirror image of #115. There, a stale binary spent before validating; here, a current, doctor-green binary spends before a step that then fails permanently. In both cases note deploy is fail-open on the money path.
Environment
- OS: Linux (Debian, x86_64)
- Network: Shellnet, endpoint
shellnet.ackinacki.org
- dexdo CLI: v0.0.18 (installed via
get.dex.do/install.sh)
- Manifest: official
contracts/deployed.shellnet.json from main, version: 4.0.30
dexdo doctor: PASS — RootPN / RootOracle / PrivateNote pins all "binary pin matches live shellnet"
- Funding wallet: canonical
UpdateCustodianMultisigWallet_v2 (code_hash 09f596d5bb4f63d7…), single custodian
- No seed phrase, note secret, or pool file contents are included in this report
Command
dexdo note deploy \
--multisig-address 0:61993c8c…9329 \
--multisig-seed-file <REDACTED> \
--nominal N10000 \
--token-type nackl \
--endpoint shellnet.ackinacki.org \
--pool pn_pool_v6.json
What happened, in order
- Deposit voucher generated, proven (2080 bytes), wallet spend submitted — NACKL 1,000,000 → 990,000.
note deploy recovery: recorded deployed PrivateNote 0:d6d27c6b6c28e0b1a255dcf461bd3bb741026f8b46a3f210103588ff390474ed
- SHELL gas voucher checkpoint recorded, wallet spend submitted — SHELL 999,967 → 999,867.
- SHELL gas voucher generated and proven (2080 bytes), proof persisted to the recovery file.
RootPN.sendEccShellToPrivateNote rejected by the block manager (TVM compute phase). Exit 1.
Both resume attempts logged:
note deploy recovery: PrivateNote 0:d6d27c6b… is already recorded …; skipping deployPrivateNote spend and resuming later steps.
note deploy recovery: reusing persisted SHELL gas voucher proof …; no wallet spend will be submitted.
Error: … RootPN.sendEccShellToPrivateNote: block manager rejected message [TVM_ERROR] …
Resulting on-chain state
Note 0:d6d27c6b6c28e0b1a255dcf461bd3bb741026f8b46a3f210103588ff390474ed:
status: Active
code_hash: 4712999eb88c096fef770755b21d3b6b3fde724967424a928507a5499767e812 (matches the 4.0.30 PrivateNote pin)
SHELL currency ECC[2] (live spendable balance): 0.000000000 SHELL (raw 0)
VMSHELL native gas: 49.889664000 vmshell
live account ECC balances (authoritative funding): none reported
PrivateNote.getDetails current free token balance: ECC[1]: raw 10000000000000
PrivateNote.getDetails lockedInOrders: none reported
Only pn_pool_v6.json.recovery.json exists; pn_pool_v6.json was never written, so no seller/buyer flow can consume the note.
This is not a depleted-reserve or stale-binary case
RootPN (0:1010…1010, dapp_id 0…04) holds 915,421 SHELL / 4,765,800 NACKL / 1,012.5 USDC — the ECC reserve is not exhausted. Its native balance is only 167.69 vmshell, which may be the real constraint if sendEccShellToPrivateNote needs native gas to execute/forward — worth checking on your side.
doctor is green; the binary is not stale.
- The same script, same wallet, same flags minted two notes successfully ~1 hour earlier the same day (
0:daee689b… and 0:d3a55911…, both funded 100 SHELL + 10,000 NACKL and used for real trading). So the failure appeared mid-session on an unchanged setup.
Expected behaviour
note deploy should fail closed before the second wallet spend if sendEccShellToPrivateNote cannot succeed — the SHELL gas voucher should not be paid for until the delivery path is known-good.
- Failing that,
--recovery must be able to complete a half-finished deploy — either by re-issuing the gas voucher, or by making the replay acceptable to RootPN. Right now the recovery file is a record of a permanent dead end.
- There should be a rescue path for a deployed-but-unfunded note:
withdrawTokens on the stranded nominal, or an explicit "abandon and refund" command. Currently the nominal is visible in getDetails but unreachable.
Impact
Each occurrence permanently costs a full note funding (here 100 SHELL + 10,000 NACKL) with no CLI-side recovery, and gives no warning before the spend. During a points season this is a silent loss of testing budget mid-run.
Questions
- Is the rejection caused by the gas voucher's nullifier being consumed on the first (failed) attempt, so every replay is correctly refused? If so, resume can never work by design and should say so instead of looping.
- Is
RootPN's low native balance (167 vmshell) the trigger for the compute-phase failure?
- Is there any way to recover the nominal from
0:d6d27c6b…, or should it be written off?
Summary
On Shellnet 4.0.30 with dexdo v0.0.18 (
doctorfully green),note deploycompleted both wallet spends and deployed the PrivateNote, then failed on the final step:The resulting note is
Activeand holds its N10000 nominal, but zero ECC[2] SHELL, so it cannot provision anything. Resuming with--recoveryreproduces the identical rejection deterministically (3 attempts): the resume correctly refuses to re-spend and replays the persisted gas-voucher proof, and every replay is rejected the same way.dexdo note recoverthen refuses to pool the note because the deploy never finalized:That is a closed loop:
note recoverrequires a finalized deploy, and the deploy cannot finalize. 100 SHELL + 10,000 NACKL left the funding wallet and are not usable or recoverable through the CLI.This is the mirror image of #115. There, a stale binary spent before validating; here, a current, doctor-green binary spends before a step that then fails permanently. In both cases
note deployis fail-open on the money path.Environment
shellnet.ackinacki.orgget.dex.do/install.sh)contracts/deployed.shellnet.jsonfrommain,version: 4.0.30dexdo doctor: PASS — RootPN / RootOracle / PrivateNote pins all "binary pin matches live shellnet"UpdateCustodianMultisigWallet_v2(code_hash09f596d5bb4f63d7…), single custodianCommand
What happened, in order
note deploy recovery: recorded deployed PrivateNote 0:d6d27c6b6c28e0b1a255dcf461bd3bb741026f8b46a3f210103588ff390474edRootPN.sendEccShellToPrivateNoterejected by the block manager (TVM compute phase). Exit 1.Both resume attempts logged:
Resulting on-chain state
Note
0:d6d27c6b6c28e0b1a255dcf461bd3bb741026f8b46a3f210103588ff390474ed:Only
pn_pool_v6.json.recovery.jsonexists;pn_pool_v6.jsonwas never written, so no seller/buyer flow can consume the note.This is not a depleted-reserve or stale-binary case
RootPN(0:1010…1010, dapp_id0…04) holds 915,421 SHELL / 4,765,800 NACKL / 1,012.5 USDC — the ECC reserve is not exhausted. Its native balance is only 167.69 vmshell, which may be the real constraint ifsendEccShellToPrivateNoteneeds native gas to execute/forward — worth checking on your side.doctoris green; the binary is not stale.0:daee689b…and0:d3a55911…, both funded 100 SHELL + 10,000 NACKL and used for real trading). So the failure appeared mid-session on an unchanged setup.Expected behaviour
note deployshould fail closed before the second wallet spend ifsendEccShellToPrivateNotecannot succeed — the SHELL gas voucher should not be paid for until the delivery path is known-good.--recoverymust be able to complete a half-finished deploy — either by re-issuing the gas voucher, or by making the replay acceptable toRootPN. Right now the recovery file is a record of a permanent dead end.withdrawTokenson the stranded nominal, or an explicit "abandon and refund" command. Currently the nominal is visible ingetDetailsbut unreachable.Impact
Each occurrence permanently costs a full note funding (here 100 SHELL + 10,000 NACKL) with no CLI-side recovery, and gives no warning before the spend. During a points season this is a silent loss of testing budget mid-run.
Questions
RootPN's low native balance (167 vmshell) the trigger for the compute-phase failure?0:d6d27c6b…, or should it be written off?