Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ No logger calls in `setup.py` or handlers — `send_event` + assertions cover ob
### Confidential MPT (XLS-0096)
Five real on-ledger handlers (`transactions/confidential_mpt.py`: MergeInbox, Convert, Send, ConvertBack, Clawback) — true `ConfidentialMPT*` type, real-type `STATE_UPDATERS`, no synthetic-name mapping.

**Packaging.** Models come from xrpl-py's `confidential-mpt` branch (git-pinned, in the core wheel). Proof generation is `xrpl.ext.confidential` — the separate `xrpl-py-confidential` dist, EXCLUDED from the core wheel — so `uv sync` gets models but not proofs. `scripts/setup-confidential-crypto.sh` (in `Dockerfile.workload`) copies `xrpl/ext/confidential` into the venv, fetches `libmpt-crypto.so` from `XRPLF/mpt-crypto`'s public release, and compiles `_mpt_crypto` (fail-loud). Import is guarded: absent add-on → `CRYPTO_AVAILABLE=False`.
**Packaging.** Models come from xrpl-py's `pre-3.3-release-group` branch (git-pinned, in the core wheel; converges the pre-release sponsor + confidential WIP branches). Proof generation is `xrpl.ext.confidential` — the separate `xrpl-py-confidential` dist, EXCLUDED from the core wheel — so `uv sync` gets models but not proofs. `scripts/setup-confidential-crypto.sh` (in `Dockerfile.workload`) copies `xrpl/ext/confidential` into the venv, fetches `libmpt-crypto.so` from `XRPLF/mpt-crypto`'s public release, and compiles `_mpt_crypto` (fail-loud). Import is guarded: absent add-on → `CRYPTO_AVAILABLE=False`.

**Version coherence (not hardcoded).** The script reads the target from the branch's `MPT_CRYPTO_VERSION` and cross-checks it against rippled's `conanfile.py` `mpt-crypto/*` pin (`ARG XRPLD_COMMIT`, default `develop`); divergence fails the build — mismatched proof formats → rippled rejects → `success` starves. Currently `0.4.0-rc2`.

Expand All @@ -103,7 +103,7 @@ Builders (`prepare_confidential_*`) take ElGamal keys explicitly + a **sync** `c

**Faulty fee gotcha:** faulty bases must set `fee=params.confidential_fee()` — autofill's base fee draws `telINSUF_FEE_P` (confidential txns cost 10×), and `tel*` never validates, starving `sometimes(failure)`.

Setup (`_setup_confidential_mpt`, chain step 6c): privacy issuances (`TF_MPT_CAN_CONFIDENTIAL_AMOUNT|CAN_CLAWBACK|CAN_TRANSFER`) on `[7..8]`, holders `[72..76]`; crypto steps gated on `CRYPTO_AVAILABLE`. `MPTokenIssuanceSet(issuer_encryption_key=...)` before Convert. Convert binds account Sequence into the proof, so setup/`_convert_valid` stamp `cc.account_sequence` on submit or `tecBAD_PROOF`.
Setup (`_setup_confidential_mpt`, chain step 6c): privacy issuances (`TF_MPT_CAN_HOLD_CONFIDENTIAL_BALANCE|CAN_CLAWBACK|CAN_TRANSFER`) on `[7..8]`, holders `[72..76]`; crypto steps gated on `CRYPTO_AVAILABLE`. `MPTokenIssuanceSet(issuer_encryption_key=...)` before Convert. Convert binds account Sequence into the proof, so setup/`_convert_valid` stamp `cc.account_sequence` on submit or `tecBAD_PROOF`.

Caveat: `sometimes(success)` + `conf_mpt_version_monotonic` only fire against an XLS-0096 `xrpld` whose mpt-crypto pin matches.

Expand Down
10 changes: 5 additions & 5 deletions workload/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ warn_unused_ignores = true
# complementary flow/annotation checker, so third-party types resolve as Any here.
ignore_missing_imports = true

# Confidential MPT (XLS-0096) models come from xrpl-py's confidential-mpt branch
# (not yet released). Proof generation (xrpl/ext/confidential) is EXCLUDED from the
# core wheel this installs and is built separately in the Antithesis image; see
# scripts/setup-confidential-crypto.sh.
# Confidential MPT (XLS-0096) and sponsor models come from xrpl-py's pre-3.3-release-group
# branch (converges the pre-release WIP branches; not yet released). Proof generation
# (xrpl/ext/confidential) is EXCLUDED from the core wheel this installs and is built
# separately in the Antithesis image; see scripts/setup-confidential-crypto.sh.
[tool.uv.sources]
xrpl-py = { git = "https://github.com/XRPLF/xrpl-py.git", branch = "confidential-mpt" }
xrpl-py = { git = "https://github.com/XRPLF/xrpl-py.git", branch = "pre-3.3-release-group" }
2 changes: 1 addition & 1 deletion workload/src/workload/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ async def _setup_confidential_mpt(

# ── 1. Create privacy-enabled MPT issuances (always) ─────────────
conf_flags = (
MPTokenIssuanceCreateFlag.TF_MPT_CAN_CONFIDENTIAL_AMOUNT
MPTokenIssuanceCreateFlag.TF_MPT_CAN_HOLD_CONFIDENTIAL_BALANCE
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER
)
Expand Down
7 changes: 6 additions & 1 deletion workload/src/workload/transactions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,12 +552,17 @@ def _on_check_create(w: Workload, tx: dict, meta: dict) -> None:
if c.check_id == tx_hash:
c.check_id = check_id
return
# check_cash math (int(send_max)) assumes XRP drops; a fuzz-morphed IOU/MPT SendMax
# is a non-numeric object, so don't track a check we can't cash.
send_max = tx.get("SendMax")
if not isinstance(send_max, str):
return
w.checks.append(
Check(
check_id=check_id,
creator=tx.get("Account", ""),
destination=tx.get("Destination", ""),
send_max=str(tx.get("SendMax", "0")),
send_max=send_max,
)
)

Expand Down