Skip to content

fix(validate): include withdrawals in conway redeemer pointer check#761

Merged
scarmuega merged 6 commits into
mainfrom
fix/conway-withdrawal-redeemer-pointers
May 8, 2026
Merged

fix(validate): include withdrawals in conway redeemer pointer check#761
scarmuega merged 6 commits into
mainfrom
fix/conway-withdrawal-redeemer-pointers

Conversation

@scarmuega
Copy link
Copy Markdown
Member

@scarmuega scarmuega commented May 8, 2026

Summary

  • Add withdrawals to the Conway phase-1 redeemer pointer check (mk_plutus_script_redeemer_pointers), so script-locked reward accounts produce a RedeemerTag::Reward pointer at the correct sorted index.
  • Sort reward accounts by network, then script-vs-key credential, then hash — matching the ledger's canonical ordering for redeemer indexing.
  • Replace .expect() / unreachable!() panics on reward-account decoding with PostAlonzo(InputDecoding) propagation, so a malformed withdrawal in untrusted block/mempool input becomes a validation error rather than a node-level panic.

Supersedes #708 — same intent, no panics on adversarial input.

Test plan

  • cargo build -p pallas-validate
  • cargo clippy -p pallas-validate --all-targets (clean)
  • cargo test -p pallas-validate (all suites pass: alonzo, babbage, byron, conway, shelley_ma)

Summary by CodeRabbit

  • New Features

    • Enhanced transaction validation with comprehensive support for Conway reward redeemers.
  • Bug Fixes

    • Improved error handling and validation reliability for Plutus redeemer pointer generation. Better handling of withdrawal transactions and reward account processing with enhanced error recovery.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds fallible reward redeemer pointer generation for Conway transactions. The mk_plutus_script_redeemer_pointers function now returns Result, parses withdrawal keys into stake addresses, sorts them deterministically, and generates corresponding Reward redeemer pointers with associated indices. Callers propagate parsing errors via the ? operator.

Changes

Reward Redeemer Pointer Support

Layer / File(s) Summary
Imports and Function Signature
pallas-validate/src/phase1/conway.rs
Expanded imports for stake address types (Address, Network from pallas_addresses) and std::cmp::Ordering. mk_plutus_script_redeemer_pointers signature changes from Vec<RedeemersKey> to Result<Vec<RedeemersKey>, ValidationError>.
Reward Account Sorting
pallas-validate/src/phase1/conway.rs
New sort_reward_accounts comparator orders withdrawal accounts deterministically by network tag, then by stake payload type and hash for consistent redeemer indexing.
Reward Redeemer Generation
pallas-validate/src/phase1/conway.rs
Parses tx_body.withdrawals keys into StakeAddress values, returns PostAlonzo(InputDecoding) error on parse failure, sorts and filters script addresses, then appends RedeemerTag::Reward pointers with sorted indices. Returns Ok(res) on success.
Caller Integration
pallas-validate/src/phase1/conway.rs
Updates check_redeemers to handle the fallible result from mk_plutus_script_redeemer_pointers, propagating ValidationError with the ? operator.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • txpipe/pallas#750: Addresses missing withdrawal/reward redeemer pointers by implementing reward pointer generation from transaction withdrawals with deterministic account sorting to prevent UnneededRedeemer validation errors.

Poem

🐰 A rabbit hops through Conway's gates,
With redeemers sorted—just right, no waits,
Rewards now bubble from withdrawals deep,
Each pointer indexed, no secrets to keep,
Validation flows smooth, a well-ordered leap! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(validate): include withdrawals in conway redeemer pointer check' directly and accurately summarizes the main change: adding withdrawal handling to Conway phase-1 redeemer pointer validation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/conway-withdrawal-redeemer-pointers

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pallas-validate/src/phase1/conway.rs (1)

1154-1246: ⚡ Quick win

Add a regression test for reward-account ordering and decode failures.

This logic is subtle enough that it should be locked down with a Conway test covering: mixed key/script withdrawals across at least two networks, and a malformed withdrawal key that must now surface PostAlonzo(InputDecoding) instead of panicking. That would protect both the new comparator and the new fallible parsing path.

🤖 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 `@pallas-validate/src/phase1/conway.rs` around lines 1154 - 1246, Add a Conway
regression test that covers reward-account ordering and decode failures:
exercise sort_reward_accounts and mk_plutus_script_redeemer_pointers by building
a TransactionBody with withdrawals containing mixed key vs script stake
addresses across at least two networks (Testnet and Mainnet) and assert the
produced RedeemersKey entries for RedeemerTag::Reward are in the expected sorted
order (scripts vs keys and by payload hash/network tag). Also include a
malformed withdrawal key (invalid address bytes) and assert
mk_plutus_script_redeemer_pointers returns Err(PostAlonzo(InputDecoding)) rather
than panicking. Ensure the test imports/uses the same helper functions/types
(sort_reward_accounts, mk_plutus_script_redeemer_pointers, StakeAddress,
Address, RedeemersKey, RedeemerTag) so it will catch regressions in both the
comparator and the fallible parsing path.
🤖 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 `@pallas-validate/src/phase1/conway.rs`:
- Around line 1231-1237: The call to is_phase_2_script is being passed the full
reference_scripts collection which includes native scripts; filter
reference_scripts to only Plutus reference hashes (or otherwise pass the script
kind with each hash) before calling is_phase_2_script so native reference
scripts are excluded from the Plutus redeemer decision. Locate the call to
is_phase_2_script (the invocation that currently passes reference_scripts along
with plutus_v1_scripts, plutus_v2_scripts, plutus_v3_scripts) and replace the
reference_scripts argument with a filtered iterator/collection containing only
Plutus script hashes (e.g., map/filter to select Plutus kinds) or change the API
to accept (hash, kind) pairs and branch on kind so native scripts are not
treated as Phase 2/Plutus scripts.

---

Nitpick comments:
In `@pallas-validate/src/phase1/conway.rs`:
- Around line 1154-1246: Add a Conway regression test that covers reward-account
ordering and decode failures: exercise sort_reward_accounts and
mk_plutus_script_redeemer_pointers by building a TransactionBody with
withdrawals containing mixed key vs script stake addresses across at least two
networks (Testnet and Mainnet) and assert the produced RedeemersKey entries for
RedeemerTag::Reward are in the expected sorted order (scripts vs keys and by
payload hash/network tag). Also include a malformed withdrawal key (invalid
address bytes) and assert mk_plutus_script_redeemer_pointers returns
Err(PostAlonzo(InputDecoding)) rather than panicking. Ensure the test
imports/uses the same helper functions/types (sort_reward_accounts,
mk_plutus_script_redeemer_pointers, StakeAddress, Address, RedeemersKey,
RedeemerTag) so it will catch regressions in both the comparator and the
fallible parsing path.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: c582712e-dfb0-4c4d-b98a-7ed2212c6069

📥 Commits

Reviewing files that changed from the base of the PR and between dd58f79 and 588e559.

📒 Files selected for processing (1)
  • pallas-validate/src/phase1/conway.rs

Comment thread pallas-validate/src/phase1/conway.rs
@scarmuega scarmuega merged commit b221e35 into main May 8, 2026
13 of 15 checks passed
@scarmuega scarmuega deleted the fix/conway-withdrawal-redeemer-pointers branch May 8, 2026 18:55
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.

2 participants