Skip to content

Enforce transaction compilation constraints in compileTransactionMessage#1496

Open
mcintyre94 wants to merge 2 commits intomainfrom
tx-constraints
Open

Enforce transaction compilation constraints in compileTransactionMessage#1496
mcintyre94 wants to merge 2 commits intomainfrom
tx-constraints

Conversation

@mcintyre94
Copy link
Copy Markdown
Member

@mcintyre94 mcintyre94 commented Mar 26, 2026

Summary

  • Adds four compile-time guards to compileTransactionMessage (legacy, v0, and v1) that enforce Solana protocol limits before a transaction reaches the network. Each violation throws a typed SolanaError with structured context (actual count, max allowed, and for per-instruction violations, the instruction index).
  • Adds four new error codes to @solana/errors: SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES (max 64), SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES (max 12), SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS (max 64), and SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION (max 255).
  • Tests cover each constraint at the boundary (N passes, N+1 throws) for all three transaction versions.

These limits are specified in the SIMD-0385 Transaction v1 spec and apply to legacy and v0 transactions as well. They're relevant for all transaction versions, but will be easier to hit without hitting the size limits after we allow 4kb v1 transactions.

A follow-up PR will update the transaction planner to handle these new errors in the same way that it handles transactions that exceed the size limit.

Part of #1223

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 26, 2026

🦋 Changeset detected

Latest commit: aff3413

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 46 packages
Name Type
@solana/errors Minor
@solana/transaction-messages Minor
@solana/accounts Minor
@solana/addresses Minor
@solana/assertions Minor
@solana/codecs-core Minor
@solana/codecs-data-structures Minor
@solana/codecs-numbers Minor
@solana/codecs-strings Minor
@solana/compat Minor
@solana/instruction-plans Minor
@solana/instructions Minor
@solana/keys Minor
@solana/kit Minor
@solana/offchain-messages Minor
@solana/options Minor
@solana/program-client-core Minor
@solana/programs Minor
@solana/react Minor
@solana/rpc-api Minor
@solana/rpc-spec Minor
@solana/rpc-subscriptions-channel-websocket Minor
@solana/rpc-subscriptions-spec Minor
@solana/rpc-subscriptions Minor
@solana/rpc-transformers Minor
@solana/rpc-transport-http Minor
@solana/rpc-types Minor
@solana/rpc Minor
@solana/signers Minor
@solana/subscribable Minor
@solana/sysvars Minor
@solana/transaction-confirmation Minor
@solana/transactions Minor
@solana/wallet-account-signer Minor
@solana/rpc-subscriptions-api Minor
@solana/plugin-interfaces Minor
@solana/rpc-graphql Minor
@solana/rpc-parsed-types Minor
@solana/codecs Minor
@solana/fast-stable-stringify Minor
@solana/functional Minor
@solana/nominal-types Minor
@solana/plugin-core Minor
@solana/promises Minor
@solana/rpc-spec-types Minor
@solana/webcrypto-ed25519-polyfill Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@mcintyre94 mcintyre94 requested a review from lorisleiva March 26, 2026 14:33
@bundlemon
Copy link
Copy Markdown

bundlemon bot commented Mar 26, 2026

BundleMon

Files updated (10)
Status Path Size Limits
@solana/kit production bundle
kit/dist/index.production.min.js
45.95KB (+272B +0.58%) -
transaction-messages/dist/index.node.mjs
11.32KB (+247B +2.18%) -
transaction-messages/dist/index.browser.mjs
11.32KB (+246B +2.17%) -
transaction-messages/dist/index.native.mjs
11.32KB (+246B +2.17%) -
errors/dist/index.node.mjs
19.34KB (+170B +0.87%) -
errors/dist/index.browser.mjs
19.32KB (+169B +0.86%) -
errors/dist/index.native.mjs
19.32KB (+169B +0.86%) -
wallet-account-signer/dist/index.node.mjs
16.4KB (+145B +0.87%) -
wallet-account-signer/dist/index.browser.mjs
16.37KB (+134B +0.81%) -
wallet-account-signer/dist/index.native.mjs
16.37KB (+133B +0.8%) -
Unchanged files (132)
Status Path Size Limits
rpc-graphql/dist/index.browser.mjs
18.82KB -
rpc-graphql/dist/index.native.mjs
18.81KB -
rpc-graphql/dist/index.node.mjs
18.81KB -
instruction-plans/dist/index.browser.mjs
6.47KB -
instruction-plans/dist/index.native.mjs
6.47KB -
instruction-plans/dist/index.node.mjs
6.46KB -
codecs-data-structures/dist/index.browser.mjs
5.04KB -
codecs-data-structures/dist/index.native.mjs
5.03KB -
codecs-data-structures/dist/index.node.mjs
5.03KB -
offchain-messages/dist/index.browser.mjs
4.89KB -
offchain-messages/dist/index.native.mjs
4.89KB -
offchain-messages/dist/index.node.mjs
4.89KB -
transactions/dist/index.browser.mjs
3.94KB -
transactions/dist/index.native.mjs
3.93KB -
transactions/dist/index.node.mjs
3.93KB -
codecs-core/dist/index.browser.mjs
3.62KB -
codecs-core/dist/index.native.mjs
3.62KB -
codecs-core/dist/index.node.mjs
3.62KB -
webcrypto-ed25519-polyfill/dist/index.node.mj
s
3.61KB -
webcrypto-ed25519-polyfill/dist/index.browser
.mjs
3.59KB -
webcrypto-ed25519-polyfill/dist/index.native.
mjs
3.57KB -
rpc-subscriptions/dist/index.browser.mjs
3.37KB -
rpc-subscriptions/dist/index.node.mjs
3.34KB -
rpc-subscriptions/dist/index.native.mjs
3.31KB -
rpc-transformers/dist/index.browser.mjs
3.16KB -
rpc-transformers/dist/index.native.mjs
3.16KB -
rpc-transformers/dist/index.node.mjs
3.16KB -
signers/dist/index.browser.mjs
3.14KB -
signers/dist/index.native.mjs
3.14KB -
signers/dist/index.node.mjs
3.14KB -
react/dist/index.browser.mjs
3.09KB -
react/dist/index.native.mjs
3.09KB -
react/dist/index.node.mjs
3.09KB -
addresses/dist/index.browser.mjs
2.93KB -
addresses/dist/index.native.mjs
2.92KB -
addresses/dist/index.node.mjs
2.92KB -
kit/dist/index.browser.mjs
2.78KB -
kit/dist/index.native.mjs
2.78KB -
kit/dist/index.node.mjs
2.78KB -
codecs-strings/dist/index.browser.mjs
2.55KB -
codecs-strings/dist/index.node.mjs
2.51KB -
codecs-strings/dist/index.native.mjs
2.47KB -
transaction-confirmation/dist/index.node.mjs
2.41KB -
sysvars/dist/index.browser.mjs
2.37KB -
sysvars/dist/index.native.mjs
2.37KB -
sysvars/dist/index.node.mjs
2.37KB -
transaction-confirmation/dist/index.native.mj
s
2.36KB -
transaction-confirmation/dist/index.browser.m
js
2.35KB -
rpc-subscriptions-spec/dist/index.node.mjs
2.18KB -
rpc-subscriptions-spec/dist/index.native.mjs
2.13KB -
rpc-subscriptions-spec/dist/index.browser.mjs
2.13KB -
keys/dist/index.browser.mjs
2.1KB -
keys/dist/index.native.mjs
2.1KB -
keys/dist/index.node.mjs
2.1KB -
rpc/dist/index.node.mjs
1.95KB -
codecs-numbers/dist/index.browser.mjs
1.95KB -
codecs-numbers/dist/index.native.mjs
1.95KB -
codecs-numbers/dist/index.node.mjs
1.94KB -
rpc-transport-http/dist/index.browser.mjs
1.91KB -
rpc-transport-http/dist/index.native.mjs
1.9KB -
rpc/dist/index.native.mjs
1.81KB -
rpc/dist/index.browser.mjs
1.8KB -
subscribable/dist/index.node.mjs
1.8KB -
subscribable/dist/index.native.mjs
1.75KB -
subscribable/dist/index.browser.mjs
1.74KB -
rpc-transport-http/dist/index.node.mjs
1.72KB -
rpc-types/dist/index.browser.mjs
1.53KB -
rpc-types/dist/index.native.mjs
1.53KB -
rpc-types/dist/index.node.mjs
1.53KB -
rpc-subscriptions-channel-websocket/dist/inde
x.node.mjs
1.33KB -
rpc-subscriptions-channel-websocket/dist/inde
x.native.mjs
1.27KB -
rpc-subscriptions-channel-websocket/dist/inde
x.browser.mjs
1.26KB -
program-client-core/dist/index.browser.mjs
1.21KB -
program-client-core/dist/index.native.mjs
1.21KB -
program-client-core/dist/index.node.mjs
1.21KB -
options/dist/index.browser.mjs
1.18KB -
options/dist/index.native.mjs
1.18KB -
options/dist/index.node.mjs
1.17KB -
accounts/dist/index.browser.mjs
1.17KB -
accounts/dist/index.native.mjs
1.17KB -
accounts/dist/index.node.mjs
1.16KB -
rpc-api/dist/index.browser.mjs
976B -
rpc-api/dist/index.native.mjs
975B -
rpc-api/dist/index.node.mjs
973B -
compat/dist/index.browser.mjs
969B -
compat/dist/index.native.mjs
968B -
compat/dist/index.node.mjs
966B -
rpc-spec-types/dist/index.browser.mjs
962B -
rpc-spec-types/dist/index.native.mjs
961B -
rpc-spec-types/dist/index.node.mjs
959B -
rpc-subscriptions-api/dist/index.native.mjs
870B -
rpc-subscriptions-api/dist/index.node.mjs
869B -
rpc-subscriptions-api/dist/index.browser.mjs
868B -
rpc-spec/dist/index.browser.mjs
852B -
rpc-spec/dist/index.native.mjs
851B -
rpc-spec/dist/index.node.mjs
850B -
promises/dist/index.browser.mjs
799B -
promises/dist/index.native.mjs
798B -
promises/dist/index.node.mjs
797B -
assertions/dist/index.browser.mjs
783B -
instructions/dist/index.browser.mjs
771B -
instructions/dist/index.native.mjs
770B -
instructions/dist/index.node.mjs
768B -
fast-stable-stringify/dist/index.browser.mjs
726B -
fast-stable-stringify/dist/index.native.mjs
725B -
assertions/dist/index.native.mjs
724B -
fast-stable-stringify/dist/index.node.mjs
724B -
assertions/dist/index.node.mjs
723B -
plugin-core/dist/index.browser.mjs
473B -
plugin-core/dist/index.native.mjs
472B -
plugin-core/dist/index.node.mjs
470B -
programs/dist/index.browser.mjs
329B -
programs/dist/index.native.mjs
327B -
programs/dist/index.node.mjs
325B -
event-target-impl/dist/index.node.mjs
230B -
functional/dist/index.browser.mjs
154B -
functional/dist/index.native.mjs
152B -
text-encoding-impl/dist/index.native.mjs
152B -
functional/dist/index.node.mjs
151B -
codecs/dist/index.browser.mjs
137B -
codecs/dist/index.native.mjs
136B -
codecs/dist/index.node.mjs
134B -
event-target-impl/dist/index.browser.mjs
133B -
ws-impl/dist/index.node.mjs
131B -
text-encoding-impl/dist/index.browser.mjs
122B -
text-encoding-impl/dist/index.node.mjs
119B -
ws-impl/dist/index.browser.mjs
113B -
crypto-impl/dist/index.node.mjs
111B -
crypto-impl/dist/index.browser.mjs
109B -
rpc-parsed-types/dist/index.browser.mjs
66B -
rpc-parsed-types/dist/index.native.mjs
65B -
rpc-parsed-types/dist/index.node.mjs
63B -

Total files change +1.89KB +0.39%

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

Documentation Preview: https://kit-docs-rc3eprbbm-anza-tech.vercel.app

Adds validation to \`compileTransactionMessage\` (for all three versions — legacy, v0, v1) that throws a \`SolanaError\` when any of Solana's protocol limits are exceeded: more than 12 unique signer addresses, more than 64 unique account addresses, more than 64 instructions, or more than 255 account references in a single instruction. Four new error codes (\`TOO_MANY_SIGNER_ADDRESSES\`, \`TOO_MANY_ACCOUNT_ADDRESSES\`, \`TOO_MANY_INSTRUCTIONS\`, \`TOO_MANY_ACCOUNTS_IN_INSTRUCTION\`) are added to \`@solana/errors\` with corresponding context types and human-readable messages. Each version's test file is updated with boundary tests covering all four constraints.
Copy link
Copy Markdown
Member Author

mcintyre94 commented Mar 26, 2026

Copy link
Copy Markdown
Member

@lorisleiva lorisleiva left a comment

Choose a reason for hiding this comment

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

Perfect!

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