Skip to content

fix(persistent-tee): emit v1 report_data in mock-prove journal#74

Merged
kariy merged 2 commits into
mainfrom
fix/mock-prove-v1-report-data
May 4, 2026
Merged

fix(persistent-tee): emit v1 report_data in mock-prove journal#74
kariy merged 2 commits into
mainfrom
fix/mock-prove-v1-report-data

Conversation

@kariy
Copy link
Copy Markdown
Member

@kariy kariy commented May 4, 2026

Summary

saya-tee --mock-prove is broken against the current piltover feat/tee-persistent branch: every settlement attempt reverts at fee estimation with tee: config hash half mismatch, so saya never submits an update_state tx. This PR rebuilds the mock-prove journal under the v1 report_data schema piltover#16 introduced, restoring end-to-end
settlement.

Why

After piltover#16 (tee-config-hash-v1, merged into the feat/tee-persistent branch), validate_input for TeeInput checks two halves of the 64-byte report_data:

  • first 32 bytes must equal the v1 commitment Poseidon(['KatanaTeeReport1', 'KatanaTeeAppchain', prev_state_root, state_root, prev_block_hash, block_hash, prev_block_number, block_number, messages_commitment, katana_tee_config_hash])10 fields, including the version + mode tags and the config hash. - second 32 bytes must equal tee_input.katana_tee_config_hash.

mock_proof.rs was still emitting the legacy 7-field Poseidon and a zero second half (the old assert!(report_data.limb2 == 0 && report_data.limb3 == 0) shape), so:

  • Check feat: completely rewrite project #2 fails: piltover sees 0 in the second half but compares against the (non-zero) tee_input.katana_tee_config_hash — revert with TEE_CONFIG_HASH_HALF_MISMATCH.
  • Check dependency update #1 would also fail (legacy hash ≠ v1 hash) but never gets reached.

The fee-estimation revert is silent in saya logs beyond a single Failed estimation line, which is why the symptom presented as "saya never sends a tx."

The piltover `feat/tee-persistent` branch landed the v1 report_data schema
(piltover#16, "tee-config-hash-v1"): `validate_input` for `TeeInput` now
recomputes a 10-field Poseidon over [version, mode, transition fields,
katana_tee_config_hash] for the first 32 bytes of `report_data`, and
decodes the second 32 bytes as `katana_tee_config_hash`. The mock-prove
journal builder was still writing the legacy 7-field commitment with a
zeroed second half, so every settlement attempt reverted at fee
estimation with `tee: config hash half mismatch` and saya never
submitted an `update_state` tx.

- compute_appchain_commitment: hash the v1 10-field array (adds
  KATANA_TEE_REPORT_VERSION, KATANA_TEE_APPCHAIN_MODE, and
  katana_tee_config_hash).
- build_raw_report: take config_hash and pack it into bytes [32..64]
  alongside the commitment in [0..32].
- prover.rs: thread `attestation.katana_tee_config_hash` into both
  helpers in the mock_prove branch.
- Tests: replace the limb2/limb3-zero assertion with a both-halves
  round-trip; pin the inlined version-tag felt values to their ASCII
  source strings.

Verified end-to-end against a live L2/L3 setup: saya-tee --mock-prove
batched and settled blocks 2..=11 in a single update_state, advancing
piltover's block_number to 0xb with execution_status SUCCEEDED.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kariy kariy changed the title fix(persistent-tee): emit v1 report_data in mock-prove journal fix(persistent-tee): emit v1 report_data in mock-prove journal May 4, 2026
…nt helper

`compute_appchain_commitment` now takes 8 fields (was 7), tripping clippy's
default threshold. Bundling into a struct would obscure the parity check
against the on-chain Cairo call shape (`piltover` `validate_input` lines
198-207). Apply a localized `#[allow]` instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kariy kariy merged commit 17c0ee0 into main May 4, 2026
5 of 7 checks passed
kariy added a commit to dojoengine/katana that referenced this pull request May 4, 2026
`dojoengine/saya#74` updated `saya-tee --mock-prove` to emit the v1
report_data layout this PR enforces. Without that bump the e2e job
reverts at fee estimation with `tee: config hash half mismatch`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
kariy added a commit to dojoengine/katana that referenced this pull request May 4, 2026
…#556)

`tee_generateQuote` responses now carry a `katana_tee_config_hash` —
Pedersen-array hash of [`KatanaTeeConfig1`, chain_id, fee_token] —
bound into both halves of the SEV-SNP `report_data`:

  report_data[0..32]  = Poseidon([REPORT_VERSION, MODE,
                                  ...transition fields...,
                                  katana_tee_config_hash])
  report_data[32..64] = katana_tee_config_hash (raw felt252)

The hash is precomputed at `TeeApi::new` from the chain spec, with no
caller input. The on-chain Piltover verifier recomputes it from its
own config and rejects attestations from any other appchain
configuration at verify time, instead of letting the misconfiguration
surface later as a state-transition mismatch.

The hash function mirrors the existing `compute_starknet_os_config_hash`
(same Pedersen-array shape, same chain_id and STRK fee_token sources).

Wire-format breaks (v1-only — legacy zero-config reports are dropped):
- `tee_generateQuote(prev, block, Option<Felt>)` → `tee_generateQuote(prev, block)`
- `--katana-tee-config-hash` removed from `katana rpc tee generate-quote`
- Legacy 7-field appchain / 8-field sharding Poseidon shapes deleted

Downstream coordination:
- `dojoengine/saya#74` updates `saya-tee --mock-prove` to emit the
  matching v1 layout. Without it, every `update_state` reverts with
  `tee: config hash half mismatch`.
- Piltover's matching v1 verification is in `cartridge-gg/piltover`
  on `feat/tee-persistent` (merged as `tee-config-hash-v1`).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant