Summary
In Conway phase-1 validation, is_phase_2_script (pallas-validate/src/phase1/conway.rs:1256) treats any hash present in reference_scripts as a Plutus script. But get_reference_script_hashes (conway.rs:776) builds that list from all reference scripts — including native scripts — so a native-script credential satisfied via a reference input is wrongly classified as needing a Plutus redeemer.
Effect: mk_plutus_script_redeemer_pointers emits a RedeemerTag::{Spend,Mint,Reward} pointer for the native-script hash, then redeemer_key_coincide fails with RedeemerMissing on a transaction that is actually valid.
Where
get_script_hash_from_reference_input (conway.rs:863) hashes ScriptRef::NativeScript, PlutusV1Script, PlutusV2Script, PlutusV3Script into the same Vec<PolicyId> with no kind tag.
check_redeemers (conway.rs:1107) passes that vec straight into mk_plutus_script_redeemer_pointers (conway.rs:1184).
mk_plutus_script_redeemer_pointers calls is_phase_2_script for the Spend, Mint, and Reward branches (lines 1194, 1210, 1236) — all three inherit the misclassification.
The Reward branch was added in #761, but the bug pre-exists for Spend and Mint on main.
Suggested fix
Filter at the source. Either:
- Change
get_reference_script_hashes to return only Plutus reference-script hashes (skip the ScriptRef::NativeScript arm in get_script_hash_from_reference_input for this consumer), or
- Return
Vec<(PolicyId, ScriptKind)> and have is_phase_2_script branch on kind so native reference scripts are never matched as phase-2.
(1) is the smaller change; (2) is more correct long-term if any other call site needs to know the kind.
Test plan
Reported by CodeRabbit on #761.
Summary
In Conway phase-1 validation,
is_phase_2_script(pallas-validate/src/phase1/conway.rs:1256) treats any hash present inreference_scriptsas a Plutus script. Butget_reference_script_hashes(conway.rs:776) builds that list from all reference scripts — including native scripts — so a native-script credential satisfied via a reference input is wrongly classified as needing a Plutus redeemer.Effect:
mk_plutus_script_redeemer_pointersemits aRedeemerTag::{Spend,Mint,Reward}pointer for the native-script hash, thenredeemer_key_coincidefails withRedeemerMissingon a transaction that is actually valid.Where
get_script_hash_from_reference_input(conway.rs:863) hashesScriptRef::NativeScript,PlutusV1Script,PlutusV2Script,PlutusV3Scriptinto the sameVec<PolicyId>with no kind tag.check_redeemers(conway.rs:1107) passes that vec straight intomk_plutus_script_redeemer_pointers(conway.rs:1184).mk_plutus_script_redeemer_pointerscallsis_phase_2_scriptfor the Spend, Mint, and Reward branches (lines 1194, 1210, 1236) — all three inherit the misclassification.The Reward branch was added in #761, but the bug pre-exists for Spend and Mint on
main.Suggested fix
Filter at the source. Either:
get_reference_script_hashesto return only Plutus reference-script hashes (skip theScriptRef::NativeScriptarm inget_script_hash_from_reference_inputfor this consumer), orVec<(PolicyId, ScriptKind)>and haveis_phase_2_scriptbranch on kind so native reference scripts are never matched as phase-2.(1) is the smaller change; (2) is more correct long-term if any other call site needs to know the kind.
Test plan
RedeemerMissing, fixed behavior validates.Reported by CodeRabbit on #761.