Relax Fee-Payer Constraint
- Idea
- Draft
- Review
- Accept
- Implement
- Active
Decision brief
Why this proposal matters
This proposal aims to relax the handling of invalid fee-payers for blockhash transactions in Solana. Currently, if a transaction with an invalid fee-payer is included in a block, the entire block is rejected. This proposal suggests that instead of rejecting the entire block, the blockhash transaction with the invalid fee-payer should simply skip execution.
Proposal at a glance
What changes
- The fee-payer account is a System Fee-Payer or a Nonce Fee-Payer.
- If it is a System Fee-Payer, it has exactly fee lamports, or has at least fee + rent_exempt_reserve lamports.
- If it is a Nonce Fee-Payer, it has at least fee + rent_exempt_reserve lamports.
Stakeholder map
Who is affected
Builders & client teams Impact unknown
No proposal-specific evidence was found for this group.
Action requirement unknownValidators & operators Medium impact
Blocks produced after the change may be rejected by previous versions of the validator client(s).
Action requirement unknownUsers & stakers Medium impact
Transactions that are unable to pay fees may be included in blocks.
Action requirement unknownGovernance & ecosystem Medium impact
This proposal aims to relax the handling of invalid fee-payers for blockhash transactions in Solana. Currently, if a transaction with an invalid fee-payer is included in a block, the entire block is rejected. This proposal suggests that instead of rejecting the entire block, the blockhash transaction with the invalid fee-payer should simply skip execution.
Action may be requiredExact source revision
Full proposal document
0616093b2952Summary
This proposal aims to relax the handling of invalid fee-payers for blockhash transactions in Solana. Currently, if a transaction with an invalid fee-payer is included in a block, the entire block is rejected. This proposal suggests that instead of rejecting the entire block, the blockhash transaction with the invalid fee-payer should simply skip execution.
Motivation
The current constraint forces block-validation to be synchronous since in order to determine if a block is valid or not, some subset of transactions must be executed in order to determine if the fee-payer has sufficient funds to pay the transaction fees. By relaxing this constraint, we move one step closer towards asynchronous validation/execution.
New Terminology
A Blockhash Transaction is defined as a transaction that uses a real blockhash, as opposed to a durable nonce, for its recent blockhash / lifetime specifier.
A System Fee-Payer is defined as an account owned by the System Program with data length 0.
A Nonce Fee-Payer is defined as an account owned by the System Program with data
length 80 and the first eight bytes being 01 00 00 00 01 00 00 00 (a Current
Initialized nonce) or 00 00 00 00 01 00 00 00 (a Legacy Initialized nonce).
The remaining 72 bytes are arbitrary.
A Nonce Fee-Payer is unrelated to the concept of a nonce transaction: a transaction that uses a Nonce Fee-Payer and uses a real blockhash is a Blockhash Transaction.
Detailed Design
Any transaction has a statically determined fee fee lamports.
A transaction can successfully pay fees if:
- The fee-payer account is a System Fee-Payer or a Nonce Fee-Payer.
- If it is a System Fee-Payer, it has exactly
feelamports, or has at leastfee+rent_exempt_reservelamports. - If it is a Nonce Fee-Payer, it has at least
fee+rent_exempt_reservelamports.
If the fee-payer account does not meet these conditions, the transaction may be included in a block, but it must not be executed. The transaction will have no effect on account state.
Invalid fee-payer transactions will count their requested, or default, cost units towards block limits. This is intended to make it strictly cheaper to process invalid fee-payer transactions compared to valid fee-payer transactions of the same construction.
This SIMD only applies to blockhash transactions. Handling any failure of nonce transactions is more involved, and nonce transaction fee-payer failure will be deferred to SIMD-0297, which also relaxes the nonce account validity constraint.
Alternatives Considered
- Requiring some sort of fee-payer lock up/bonding mechanism to ensure that fee-
payers have sufficient funds to pay for the transaction fees.
- This is more complex compared to this proposal.
Impact
Transactions that are unable to pay fees may be included in blocks.
Security Considerations
- Possible attack vector where a malicious leader can spam transactions with invalid fee-payers. Mitigation for this is charging full cost units for these.
Drawbacks
- If there is no interest in simplifying block-validation to allow for asynchronous, this proposal is not necesary.
- Concern about data propagation for without paying fees to the network (burn):
- This concern has been raised in the past when this has been discussed.
- However, the concern is largely invalid since even without this proposal, a malicious leader could still propagate data through the network for free by simply using an invalid fee-payer.
Backwards Compatibility
- All previously valid transactions and blocks are still valid.
- Blocks produced after the change may be rejected by previous versions of the validator client(s).
Evidence graph
Related proposals and rollout
One or more sources are unavailable.
Upstream review record
Upstream discussion & review
GitHub review is editorial context, not evidence of on-chain support, voting, or outcome.
PR #290 · merged SIMD-0290: Relax Fee Payer Constraint 11 comments and reviews · Jan 12, 2026Using assumption that checking fee payer is a constant cost regardless of whether it can pay fees or not (not really true, but for the cost-model it is what we assume). Then we 3 paths, and the things we do: 1. Account exists and has enough funds: - check if fee payer account exists - check fee payer account balance - execution 3. Account exists and doesn't have enough funds: - check if fee payer account exists - check fee payer account balance - (stop early) 5. Account does not exist: - check if fee payer account exists - (stop early) ^ we do less work, i.e. don't need to do any execution checks if the fee payer cannot pay.
GitHub ↗Since these transactions are still stored in the block, even if they aren't executed, I could embed arbitrary data into the instruction buffers and use the chain as a rent-free storage or broadcast layer. Anyone could then retrieve that data later over RPC, effectively turning Solana into a no-cost messaging layer. You can send them sure, but why would a (non-malicious) leader include them if they do not provide income? They wouldn't. In fact, any transactions that cannot pay fees is a sign of a bad leader not doing what they should. The proposal is 100% not suggesting these transactions should be included. Just that they can, because we need to eliminate the dependence on state for validity
GitHub ↗You can send them sure, but why would a (non-malicious) leader include them if they do not provide income? They wouldn't. In fact, any transactions that cannot pay fees is a sign of a bad leader not doing what they should. Have we considered how a leader would know this, without knowing anything about the account's state?
GitHub ↗Have we considered how a leader would know this, without knowing anything about the account's state? Nothing states the leader doesn't know the account state - the leader can have scheduling of only what it knows the state of (or at least a minimum bound on balance). Again the purpose of this is not to allow the leader to pack transactions without knowing if they can pay fees...they should know or be pretty sure it has enough to pay the transaction otherwise they lose out on income. This also isn't the same as being fully synced up on execution. Let's consider 2 scenarios: 1. A fee paying account signing many transactions often, strictly used as fee-payer. 2. A fee paying account signing inf
GitHub ↗I'm leader at slot N+4. Without executing Tx3 I don't know the exact balance since X may have been sent additional lamports, but I don't care, since I know the balance must be = 40000. So when I'm leader in slot N+4, if I see a Tx4 w/ fee payer X that pays 30000 I'm 100% sure that I can safely include the tx. And I didn't need to execute any of the transactions. But doesn't this imply that you're keeping track of at least the state transition function for the lamports field? So are all nodes supposed to just do some high-level speculative accounting for the fee payer to keep a cache of every possible fee payer and their best guess as to a range in which their balance could conceivably be by
GitHub ↗Yes, if leaders do not want to waste their blockspace (they don't) AND want to be able to fall behind in execution they will have some way to estimate fee payer balance - in many cases this will not require full execution and can be done much much faster than execution. How they do this is an implementation detail so doesn't belong in a SIMD. It does not have to be what I described above, leaders could include only fee-payers with state they are fully synced up on. Leaders are highly incentivized to be as close to the tip as possible since that is how they will have the best fee-payer balance estimates, and thus likely leads to more fees collected.
GitHub ↗@apfitzge okay thanks for the discussion! The leader incentive-based approach to avoiding chain spam makes sense to me. If you have a crappy "fee payer funded probability graph", you aren't making money! How they do this is an implementation detail so doesn't belong in a SIMD. Fair, but it doesn't hurt to be forward-thinking about protocol features that can make this easier to estimate, if need be.
GitHub ↗@Benhawkins18 think this is ready to merge.
GitHub ↗Provenance
Evidence & technical details
Rollout or chain data, source revisions, freshness and integrity. 1
Provenance
Evidence & technical details
Rollout or chain data, source revisions, freshness and integrity.SIMD
Deployment Status
FEEXbxUuKobtrt1qNK5pjtzbPQhsppBTrNNG74xu4maiExact source revision
Sources & integrity
- Proposal document pinned_commit_blob
0616093b2952ed6de52c4a27d66aadd11d48d4f9 - simd-document document · current · Sep 11, 2026
0616093b2952ed6de52c4a27d66aadd11d48d4f9
One or more sources are unavailable.
simd.watch community discussion · SIMD-0290
Powered by Giscus · Sign in with GitHub to comment
Community comments load when this section approaches the viewport.