Skip to content

feat: add PermissionedDomains support (XLS-80)#157

Draft
e-desouza wants to merge 9 commits intomainfrom
feat/xls-80-permissioned-domains
Draft

feat: add PermissionedDomains support (XLS-80)#157
e-desouza wants to merge 9 commits intomainfrom
feat/xls-80-permissioned-domains

Conversation

@e-desouza
Copy link
Copy Markdown
Collaborator

@e-desouza e-desouza commented Apr 3, 2026

Summary

Implements XLS-80 (PermissionedDomains) support for xrpl-rust.

New transaction types

  • PermissionedDomainSet — Create or update a permissioned domain with a list of AcceptedCredentials
  • PermissionedDomainDelete — Delete an existing permissioned domain by DomainID

New ledger entry type

  • PermissionedDomain (LedgerEntryType = 0x0082) — On-ledger permissioned domain object with Owner, AcceptedCredentials, Sequence, and audit fields

Shared types

  • Credential — Nested STObject (via serde_with_tag!) with required Issuer and CredentialType fields

Validation

  • Credential.issuer and Credential.credential_type are required (non-optional String fields)
  • PermissionedDomainSet.get_errors() rejects empty issuer or credential_type values

Registration

  • TransactionType::PermissionedDomainSet, TransactionType::PermissionedDomainDelete added to enum
  • LedgerEntryType::PermissionedDomain (0x0082) added to enum
  • Module re-exports and integration tests included

Test plan

  • Serde roundtrip tests for PermissionedDomainSet, PermissionedDomainDelete, PermissionedDomain
  • Builder pattern and new() constructor tests
  • get_transaction_type() variant tests
  • Validation: empty credential fields rejected
  • Multiple credentials in AcceptedCredentials array
  • Integration tests in tests/transactions/
  • cargo fmt, cargo clippy --all-features, cargo test --release all pass
  • All 9 feature-matrix builds compile cleanly

…r XLS-80

Add the Credential serde_with_tag type for wrapping issuer/credential_type
pairs, and add PermissionedDomainSet and PermissionedDomainDelete variants
to the TransactionType enum. Module declarations for the new transaction
types are included.
Implement the PermissionedDomainSet transaction for creating and updating
permissioned domains. Supports optional DomainID for updates, a list of
accepted Credential entries, and the full CommonTransactionBuilder pattern
with builder methods for domain-specific fields.
Implement the PermissionedDomainDelete transaction for removing an
existing permissioned domain from the ledger. Takes a required DomainID
field identifying the domain to delete.
Add the PermissionedDomain ledger object representing a permissioned
domain on the XRP Ledger, with owner, accepted_credentials, sequence,
owner_node, previous_txn_id, and previous_txn_lgr_seq fields. Register
as LedgerEntryType 0x0082 and add the LedgerEntry enum variant.
Add integration test stubs for PermissionedDomainSet and
PermissionedDomainDelete transactions. These tests verify transaction
construction, signing, and submission against a running XRPL node,
accepting temDISABLED when the amendment is not yet enabled.
Copy link
Copy Markdown
Collaborator Author

@e-desouza e-desouza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a read through

Required Credential fields typed as Option without validation — flagged inline.


Review by ReviewBot 🤖

Review by Claude Opus 4.6 · Prompt: V12

The XLS-80 spec requires both `issuer` and `credential_type` on every
Credential entry.  Having them typed as `Option<String>` allowed callers
to construct silently invalid transactions.

- Change `Credential.issuer` and `Credential.credential_type` from
  `Option<String>` to `String`, matching the Signer struct pattern.
- Add `get_errors()` validation in `PermissionedDomainSet` that rejects
  empty issuer or credential_type with `MissingField`.
- Add two tests covering the new validation paths.
- Update all call sites (unit tests, integration test, ledger object
  tests) to use non-optional field construction.
The CredentialType field is a Blob type in the XRPL binary codec
definitions, which requires hex-encoded input. The test was passing
the raw ASCII string "KYC" instead of its hex representation "4B5943",
causing a TryFromStrError during binary serialization.
The rippleci/rippled:develop image updated after 2026-04-01 and broke
integration tests across all PRs (container exits before becoming healthy,
causing Connection refused on localhost:5005).

Pin to the last known-good digest and replace the simple until loop with
a bounded retry that checks container liveness, prints status per attempt,
and dumps container logs on failure.
- Enforce XLS-80 AcceptedCredentials bounds (1..=10) in
  PermissionedDomainSet::get_errors.
- Add validate_credential helper that rejects CredentialType values
  that are not valid hex Blob: non-empty, even length, ASCII hex only,
  and at most 64 hex chars (rippled MaxCredentialTypeLength = 32 bytes).
- Validate DomainID in PermissionedDomainDelete as exactly 64 hex chars.
- Tighten integration-test engine_result assertions to a strict
  allowlist rather than substring matches that could swallow unrelated
  tec codes.
- Extend PermissionedDomain ledger-object serialize test to assert
  PascalCase JSON keys so silent field-name drift is caught.
- Update all affected unit tests to use valid hex CredentialType and
  64-char DomainID values.

Deferred: optional Credential field rework (required-field degrades
deserialization) is lower priority and risks breaking callers.
pdp2121 pushed a commit that referenced this pull request Apr 21, 2026
… #3270) (#291)

## Summary

The `rippled` binary was renamed to `xrpld` upstream, and the
`rippleci/rippled` image stopped receiving updates. Our integration
tests across every open PR started failing because the published
`develop` image exited before becoming healthy (`Connection refused` on
`localhost:5005`, **0 passed / 41 failed**).

This PR mirrors the upstream fix in xrpl.js:
[XRPLF/xrpl.js#3270](XRPLF/xrpl.js#3270).
Switching to `rippleci/xrpld:develop` is the **actual root-cause fix**
rather than pinning an old digest of the deprecated image.

## Changes

`.github/workflows/integration_test.yml`:
- `RIPPLED_DOCKER_IMAGE` -> `XRPLD_DOCKER_IMAGE:
rippleci/xrpld:develop`.
- `docker run` simplified to `${IMAGE} --standalone` (the `xrpld` image
handles `mkdir` + launch internally; no more `bash -c "mkdir -p
/var/lib/rippled/db/ && rippled -a"` wrapper).
- Volume mount changed from `/etc/opt/ripple/` to `/etc/opt/xrpld/`.
- Container name: `rippled-service` -> `xrpld-service`.
- Removed the docker `--health-cmd` (which shelled out to the renamed
`rippled` CLI and always failed) in favour of a direct JSON-RPC poll
against `http://localhost:5005/`.
- Always dump container logs on the stop step for post-mortem
visibility.

`.ci-config/rippled.cfg` -> `.ci-config/xrpld.cfg`:
- `path=/var/lib/rippled/db/nudb` -> `path=/var/lib/xrpld/db/nudb`.
- `[database_path] /var/lib/rippled/db` -> `/var/lib/xrpld/db`.
- `[debug_logfile] /var/log/rippled/debug.log` ->
`/var/log/xrpld/debug.log`.

## Verification

Validated on throwaway PR #292 (now closed): **Integration Test green in
2m53s** on this exact workflow. Unit tests, Build & Lint, Quality Check
also pass.

## Related follow-up

The 7 in-flight PRs (#130, #131, #151, #153, #156, #157, #158) currently
carry a stopgap commit pinning `rippleci/rippled:develop` to a specific
digest. After this PR merges to `main`, those branches should:
1. Rebase on `main` to pick up the xrpld switch, or
2. Cherry-pick this commit and drop the stopgap digest pin.

## Test plan

- [x] Validated end-to-end on PR #292
- [x] Build & Lint, Unit Test, Integration Test, Quality Check all pass
- [ ] Merge and confirm subsequent PRs inherit the fix without manual
cherry-pick

## Credit

Approach lifted from @ckeshava's
[xrpl.js#3270](XRPLF/xrpl.js#3270).
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