feat: Batch (XLS-56) V1_1 signing support#1010
Conversation
WalkthroughUpdates XLS-56 Batch signing to the V1_1 format by expanding the ChangesBatchV1_1 signing payload and signer management
Sequence Diagram(s)sequenceDiagram
participant Client
participant sign_multiaccount_batch
participant encode_for_signing_batch
participant combine_batch_signers
rect rgba(100, 149, 237, 0.5)
note over Client,sign_multiaccount_batch: Per-account signing
Client->>sign_multiaccount_batch: wallet, Batch tx, batch_account, multisign
sign_multiaccount_batch->>sign_multiaccount_batch: resolve sequence (sequence or ticket_sequence)
sign_multiaccount_batch->>sign_multiaccount_batch: validate signing_account in involved_accounts
sign_multiaccount_batch->>encode_for_signing_batch: account, sequence, flags, tx_ids, batch_account, [signer_account]
encode_for_signing_batch-->>sign_multiaccount_batch: V1_1 signing payload bytes
sign_multiaccount_batch-->>Client: Batch with new BatchSigner appended
end
rect rgba(144, 238, 144, 0.5)
note over Client,combine_batch_signers: Combining signer fragments
Client->>combine_batch_signers: [Batch_signed_by_A, Batch_signed_by_B]
combine_batch_signers->>combine_batch_signers: validate equivalence key (account, seq, flags, tx hashes)
combine_batch_signers->>combine_batch_signers: sort + deduplicate BatchSigners by account
combine_batch_signers-->>Client: combined Batch with merged BatchSigners
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…payload Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ar-key Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch_signers Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61ef7d1 to
dbae6c8
Compare
…strict Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/unit/transaction/test_batch_signers.py (1)
27-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider deriving
REGKEY_PUBLIC_KEYinstead of hardcoding.
REGKEY_PUBLIC_KEYduplicatesregkey_wallet.public_key. UsingREGKEY_PUBLIC_KEY = regkey_wallet.public_keyremoves the magic constant and keeps the fixture self-consistent if the seed ever changes; the txn_signature assertions still pin the cryptographic behavior.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/unit/transaction/test_batch_signers.py` around lines 27 - 34, The test fixture currently hardcodes REGKEY_PUBLIC_KEY even though it duplicates regkey_wallet.public_key. Update the setup in test_batch_signers.py so REGKEY_PUBLIC_KEY is derived from regkey_wallet.public_key, keeping the fixture self-consistent and avoiding a magic constant while preserving the existing txn_signature assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/integration_test.yml:
- Line 8: The XRPLD_DOCKER_IMAGE value is using a mutable latest tag, which
makes integration runs non-reproducible. Update the workflow variable in the
integration_test.yml configuration to reference a pinned image digest instead of
:latest, keeping the XRPLD_DOCKER_IMAGE identifier the same but replacing the
tag with an immutable digest so runs always use the same image.
In `@xrpl/transaction/batch_signers.py`:
- Around line 191-198: The deduping logic in the BatchSigners combination path
is too aggressive because it drops later entries with the same
BatchSigner.account even when they contain distinct nested multisigners. Update
the merge logic in the BatchSigner accumulation code to detect duplicate account
entries, then either combine and sort their nested signers by Signer.account
when they are compatible or explicitly reject incompatible direct-vs-multisigned
duplicates. Make the fix in the deduping block that builds deduped_signers so
valid signatures are preserved instead of silently keeping only the first
fragment.
---
Nitpick comments:
In `@tests/unit/transaction/test_batch_signers.py`:
- Around line 27-34: The test fixture currently hardcodes REGKEY_PUBLIC_KEY even
though it duplicates regkey_wallet.public_key. Update the setup in
test_batch_signers.py so REGKEY_PUBLIC_KEY is derived from
regkey_wallet.public_key, keeping the fixture self-consistent and avoiding a
magic constant while preserving the existing txn_signature assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 22f7cf05-e520-456a-9714-f80cf3337af7
📒 Files selected for processing (8)
.ci-config/xrpld.cfg.github/workflows/integration_test.ymlCHANGELOG.mdtests/integration/transactions/test_batch.pytests/unit/core/binarycodec/test_main.pytests/unit/transaction/test_batch_signers.pyxrpl/core/binarycodec/main.pyxrpl/transaction/batch_signers.py
| # Standalone rippled with the XLS-56 BatchV1_1 amendment, built from the amd64 | ||
| # binary artifact of https://github.com/XRPLF/rippled/pull/6446 and pushed to | ||
| # GHCR. Revert to rippleci/xrpld:develop once BatchV1_1 lands in develop. | ||
| XRPLD_DOCKER_IMAGE: ghcr.io/ckeshava/xrpld-batch-v1_1:latest |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Pin the XRPLD image by digest instead of :latest.
Line 8 currently uses a mutable tag, so integration runs are not reproducible and can fail unexpectedly when the tag moves.
Suggested change
- XRPLD_DOCKER_IMAGE: ghcr.io/ckeshava/xrpld-batch-v1_1:latest
+ XRPLD_DOCKER_IMAGE: ghcr.io/ckeshava/xrpld-batch-v1_1@sha256:<pinned_digest>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/integration_test.yml at line 8, The XRPLD_DOCKER_IMAGE
value is using a mutable latest tag, which makes integration runs
non-reproducible. Update the workflow variable in the integration_test.yml
configuration to reference a pinned image digest instead of :latest, keeping the
XRPLD_DOCKER_IMAGE identifier the same but replacing the tag with an immutable
digest so runs always use the same image.
| # BatchSigners must be strictly ascending and unique by account, so | ||
| # de-duplicate when combining fragments that share a signer. | ||
| deduped_signers: List[BatchSigner] = [] | ||
| last_account: Optional[str] = None | ||
| for signer in batch_signers: | ||
| if signer.account != last_account: | ||
| deduped_signers.append(signer) | ||
| last_account = signer.account |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Merge nested multisigners before deduping BatchSigner.account.
Line 196 drops every later BatchSigner with the same account. With the new multisign path, two fragments can validly share BatchSigner.account while carrying different nested Signer.account entries, so the combined transaction loses required signatures. Merge and sort nested signers for equal accounts, or reject incompatible direct-vs-multisigned duplicates instead of silently keeping the first one.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@xrpl/transaction/batch_signers.py` around lines 191 - 198, The deduping logic
in the BatchSigners combination path is too aggressive because it drops later
entries with the same BatchSigner.account even when they contain distinct nested
multisigners. Update the merge logic in the BatchSigner accumulation code to
detect duplicate account entries, then either combine and sort their nested
signers by Signer.account when they are compatible or explicitly reject
incompatible direct-vs-multisigned duplicates. Make the fix in the deduping
block that builds deduped_signers so valid signatures are preserved instead of
silently keeping only the first fragment.
Implements XLS-56 Batch V1_1 signing, matching rippled #6446.
encode_for_signing_batchnow binds the outerAccount,Sequence(orTicketSequence), theBatchSigneraccount, and (for multi-signed signers) the inner signer account into the signed payload, preventing signature replay.sign_multiaccount_batch— builds the V1_1 payload; addsbatch_accountand regular-key / stringmultisignsupport.combine_batch_signers— validates the full payload (account, sequence, flags, tx IDs) and de-duplicates signers.Breaking: batch signatures from older versions are no longer valid; re-sign against a
BatchV1_1network.Depends on rippled#6446 (
BatchV1_1). CI runs the integration suite against a rippled built from that PR;🤖 Generated with Claude Code