Skip to content

test: reproduce secp256r1 fee payer is_signer mismatch (swig-ts#107)#139

Open
tracy-codes wants to merge 1 commit intomainfrom
fix/issue-107-secp256r1-fee-payer-signer-mismatch
Open

test: reproduce secp256r1 fee payer is_signer mismatch (swig-ts#107)#139
tracy-codes wants to merge 1 commit intomainfrom
fix/issue-107-secp256r1-fee-payer-signer-mismatch

Conversation

@tracy-codes
Copy link
Contributor

Summary

  • Adds program-level tests that reproduce and verify the bug reported in swig-ts#107
  • Confirms the root cause is an is_signer flag mismatch between client and on-chain message hash computation when the fee payer is also a transfer destination
  • Includes a test that demonstrates the fix (marking fee payer as is_signer=true before hash computation)

Root Cause

When the fee payer appears as a destination in a system_instruction::transfer, the client-side compact_instructions adds it with is_signer=false. However, the Solana runtime always marks the fee payer as is_signer=true on all AccountInfos. The compute_message_hash in secp256r1.rs hashes the AccountsPayload (which includes is_signer), so the hashes diverge, resulting in PermissionDeniedSecp256r1InvalidMessageHash (0xbd2).

Tests Added

Test Purpose
test_secp256r1_multi_transfer_with_fee_payer_destination_v2 Reproduces issue #107 (expects 0xbd2 failure)
test_secp256r1_multi_transfer_to_different_recipients_v2 Control test (passes when destination != payer)
test_secp256r1_multi_transfer_fee_payer_dest_with_signer_fix_v2 Proves the fix works
test_secp256r1_separate_sign_v2_with_fee_payer_destination_v2 Shows same issue with separate SignV2 instructions

Fix Required (in swig-ts)

The TS SDK must ensure that the fee payer is marked as isSigner=true in the accounts list before computing the message hash for secp256r1 (and secp256k1) signing.

…ig-ts#107)

Add tests that reproduce the issue where secp256r1 SignV2 transactions fail
with PermissionDeniedSecp256r1InvalidMessageHash (0xbd2) when a transfer
destination is the fee payer.

Root cause: the Solana runtime marks the fee payer as is_signer=true on all
AccountInfos, but the client SDK computes the message hash with
is_signer=false when the payer appears only as a transfer destination. This
causes the keccak hash to mismatch between client and program.

Tests added:
- test_secp256r1_multi_transfer_with_fee_payer_destination_v2: reproduces #107
- test_secp256r1_multi_transfer_to_different_recipients_v2: control (passes)
- test_secp256r1_multi_transfer_fee_payer_dest_with_signer_fix_v2: confirms fix
- test_secp256r1_separate_sign_v2_with_fee_payer_destination_v2: separate ixs
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