Skip to content

Mode B — Stateless Atomic Attestation

Mode B attests and executes in one transaction. Instruction 0 is Teton. Instruction 1 is the consumer. The pair succeeds or fails together.

Use Mode B for discrete actions: NAV marks, liquidations, hourly rebalances.

The canonical instruction is verify_atomic_with_nonce. verify_atomic returns VerifierError::NonceRequired and writes no state (@spec TETON-SEC-005).

  1. The enclave binds REPORT_DATA[32..64] = SHA-256(slot_hash ‖ action_hash ‖ consumer_program_id).
  2. The client packs Teton at index 0 and the consumer at index 1.
  3. The verifier loads slot_hash from SlotHashes at nonce_slot (age ≤ 150).
  4. The verifier checks VCEK / Nitro signature, measurement, TCB, and the action commitment (@spec TETON-VERIFY-012).
  5. The verifier allocates a 17-byte UsedNonceAccount PDA seeded [b"nonce", signer_pubkey, commitment].
  6. The consumer calls assert_atomic_attestation and reads the preceding Teton instruction through sysvar::instructions.

Stage 2 stays under 550,000 CUs (@spec TETON-PERF-002). Mock-crypto SBF harness: verify_atomic_with_nonce ≈ 59,638 CUs. The consumer introspection check is bounded at 2,500 CUs (@spec TETON-CONSUMER-002).

On the wire, Mode B SNP data is:

discriminator (8) ‖ VerifyAtomicHeader (72) ‖ SNP report (1,184) = 1,264 bytes.

The 80-byte prefix at 0x00..0x50 is the discriminator plus header:

Offset Size Field
0 8 VERIFY_ATOMIC_WITH_NONCE_DISCRIMINATOR [209, 4, 10, 239, 3, 142, 223, 250]
8 8 nonce_slot (u64 LE)
16 32 action_hash
48 32 consumer_program_id
80 1184 SNP report (zero-copy, @spec TETON-ARCH-002)

teton_core::VerifyAtomicHeader is the 72-byte body after the discriminator (nonce_slot, action_hash, consumer_program_id).

The verifier pins slot_hashes_account.key == sysvar::slot_hashes::ID and loads the 32-byte hash at nonce_slot. Age above 150 slots is VerifierError::StaleNonce.

The commitment is native hashv:

expected = SHA-256(slot_hash ‖ header.action_hash ‖ header.consumer_program_id)
REPORT_DATA[32..64] == expected

A mismatch is VerifierError::ActionHashMismatch.

Item Value
Size 17 bytes (disc 8 + slot 8 + bump 1)
Discriminator [157, 75, 223, 206, 73, 132, 216, 154]
Seeds [b"nonce", signer_pubkey, commitment]
Allocate System Program create_account, funded by payer (@spec TETON-ARCH-001)
Replay VerifierError::NonceAlreadyUsed

teton_cpi::assert_atomic_attestation rejects require_nonce == false and rejects the verify_atomic discriminator (@spec TETON-VERIFY-013).

payer, policy_registry, vcek, used_nonce, SlotHashes, Clock, system_program.

Nitro Mode B uses verify_nitro_attestation with mode = 1 and appends the Instructions sysvar. The consumer program id is the next instruction’s program id.

A 1,264-byte SNP payload exceeds the 1,232-byte legacy UDP MTU. Use Solana v1 transactions (4,096-byte MTU, SIMD-0296). The TypeScript SDK throws PacketTooLargeError on the legacy path. See the TypeScript SDK.