Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Compute-unit consumption

Every SithBit instruction costs compute units (CU) when it executes on-chain. The table below records what each user-facing flow consumed when it was last measured, and the ceiling the integration suite fences it under — a tripwire that catches a program change silently making an instruction materially more expensive.

Values are per transaction as the CLI builds it, so bundled instructions ride along: mail send carries a ComputeBudget limit instruction, and mailbox create bundles the wallet’s self-CreateAlias.

Instruction / flowCLI commandMeasured CUFenced ceiling
SendMail (plain wallet-to-wallet) mail send23,61847,000
SendMail (relay from-address)mail send -f29,87653,000
SendMail (with bounty)mail send --bounty23,59247,000
SendMail (reply linkage)mail send --reply-to25,07548,000
ClaimBounty (domained operator-share path)mail claim-bounty24,84748,000
RefundBounty (expiry-gated sender reclaim)mail refund-bounty7,57931,000
DeleteMailmail delete15,11138,000
RefundMailmail refund16,21139,000
CreateMailbox (+ bundled CreateAlias) mailbox create32,08555,000
SetEncryptionKeymailbox key set10,81134,000
RequestCloseMailbox (opens the close timelock)mailbox close13,33436,000
CancelCloseMailbox (request aborted)mailbox close --cancel12,15635,000
FinalizeCloseMailbox (past the timelock; both rents refunded)mailbox close --finalize12,85836,000
CreateFrombox (third-party first purchase, default 9-account reputation tail — reputation-scaled pricing plus the lazy first-use mint of the payer’s sender-reputation PDA) frombox stamp / frombox update (create-if-absent)35,25658,000
CreateAlias alias create14,88838,000
OfferTransferAliasalias transfer init18,89442,000
AcceptTransferAlias (zero-fee, flat fee paid)alias transfer accept13,83837,000
CancelTransferAlias (offer retracted past binding window)alias transfer cancel24,82848,000
ListAliasForSalealias sell20,30843,000
BuyAliasalias buy20,74744,000
CancelAliasListing (listing withdrawn past binding window)alias sell --cancel19,18342,000
SellAlias (open auction)alias sell --auction26,79850,000
BidAliasalias bid19,71543,000
SettleAuctionalias settle-auction26,67450,000
AuthorizeDomain domain create15,24238,000
ListDomainForSaledomain sell32,55356,000
BuyDomaindomain buy19,80743,000
CancelDomainListing (listing withdrawn past binding window)domain sell --cancel16,00139,000
AttestSender (staged DNSSEC-proof verified sender)domain attest-sender322,474345,000
RevokeSenderAttestation (holder-signed close)domain revoke-attestation11,22434,000
SetSenderAttestationFeepostmaster fee attestation6,54630,000
SetReputationFloorpostmaster fee reputation-floor6,75630,000
CreatePinLease (per-CID storage deposit)mail lease create34,22157,000
ClosePinLease (holder-signed drain)mail lease close7,31630,000
SetPinLeaseFeepostmaster fee pin-lease6,96230,000

For scale: Solana’s default per-instruction budget is 200,000 CU and the per-transaction maximum is 1,400,000 CU — every SithBit flow fits comfortably inside the default budget except the DNSSEC-proof-verified ones (domain attest-sender above, and the untabled domain authorize / domain reclaim it mirrors), whose on-chain RSA chain walk is why the CLI prepends an explicit ComputeBudget limit sized to the proof’s zone depth — still well under the transaction maximum.

Methodology

The measurements come from the CLI integration suite (mail_client/tests/api/cu.rs), which runs against a local surfpool validator with the exact program binaries from target/deploy/:

  1. Each flow is driven end-to-end through the compiled sithbit CLI; the transaction signature is captured from the explorer URL the CLI prints.
  2. The landed transaction is fetched with getTransaction and the consumption read from meta.computeUnitsConsumed.
  3. The recorded ceiling is the max measured value plus a 22,500-CU bump-grind allowance, rounded up to the next 1,000 CU. The test asserts every future run stays at or under the ceiling.

The “measured” column is the highest of several samples, and the allowance exists because consumption is not a constant: it swings in exact multiples of ~1,500 CU between runs of the same command, because PDA bump-seed grinding (finding the off-curve address for each fresh alias, message, or listing) costs one syscall per failed candidate and the number of candidates depends on the seeds involved. The same domain sell flow was observed at both 14,553 and 32,553 CU across runs, and alias transfer cancel swung from 9,816 to 24,828 CU — the widest spread recorded. The allowance covers a 15-iteration unlucky grind streak, which keeps the fence effectively flake-free while still tripping on any program change that adds real work.

To re-measure — after a program change trips a fence, or to refresh the table — build the programs and run the suite with output visible:

cargo build-sbf --manifest-path mail_program/Cargo.toml
cargo build-sbf --manifest-path alias_program/Cargo.toml
cargo build-sbf --manifest-path domain_program/Cargo.toml
cargo test -p mail-client --features postmaster cu -- --nocapture

Each measurement prints as CU measured | <flow> | <units>. Update the constants in cu.rs and this table together, deliberately — the fence exists so cost regressions are a recorded decision, never an accident. The docs gate enforces the pairing: mail_docs/check_cu_rows.py diffs this table’s measured and ceiling values against the suite’s constants, both ways, so a re-measured constant cannot leave a stale row behind.

Caveat: all numbers were measured on the current program build in this repository. Different program versions (or a cluster running a different feature set) will consume different amounts; treat the table as a snapshot fenced by the tests, not a protocol constant.