-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SIMD-0082: Relax Transaction Constraints #82
SIMD-0082: Relax Transaction Constraints #82
Conversation
820aecc
to
819d63a
Compare
3. Have program accounts that: | ||
1. exist | ||
2. are executable | ||
4. Have writable accounts that are: | ||
1. not executable, unless owned by | ||
`BPFLoaderUpgradeab1e11111111111111111111111` | ||
2. if owned by `BPFLoaderUpgradeab1e11111111111111111111111`, | ||
then `BPFLoaderUpgradeab1e11111111111111111111111` must be included | ||
3. if owned by `Stake11111111111111111111111111111111111111`, then the | ||
current slot must not be within the epoch stakes reward distribution period | ||
5. Have executable `BPFLoaderUpgradeab1e11111111111111111111111` owned accounts | ||
with `UpgradeableLoaderState::Program` state, and derived program data account | ||
that exist | ||
6. Have a call chain depth of 5 or less | ||
7. Have no builtin loader ownership chains | ||
(pending `4UDcAfQ6EcA6bdcadkeHpkarkhZGJ7Bpq7wTAiRMjkoi`) | ||
8. Have total loaded data size which does not exceed | ||
requested_loaded_accounts_data_size_limit | ||
(pending `DdLwVYuvDz26JohmgSbA7mjpJFgX5zP2dkp8qsF2C33V`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried to be as specific as possible in the document itself, but these constraints (3-8) can be summarized as "transaction must be executable"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have done a first pass but will need to go more in depth later.
Specifically, this proposal relaxes constraints that a transaction included in | ||
a block must: | ||
|
||
1. Have a fee-payer with enough funds to pay fees |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list seems to denote the current status of constraints on transactions. This is useful background, but we need to precisely specify the new constraints on transactions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... in a separate list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit confused on what you're suggesting would make the document more clear here; this proposal does not add any new constraints.
The list here is an incomplete list of the constraints on transactions, it is only the constraints that are being removed/relaxed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list describes what the constraints are now, but does not explicitly list what the relaxed constraints are. Consider that I or another FD dev needs to stare at this and implement the exact rules for what defines a valid transaction.
|
||
## Detailed Design | ||
|
||
Specifically, this proposal relaxes constraints that a transaction included in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list seems to mix "constraints on transactions which invalidate entries and blocks" and "constraints on transaction execution which invalidate the transaction". The list should be split up or the ones of the latter type should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a very fair comment, as that is something is changing with this proposal. Currently, the list of constraints that invalidate the block is a superset of those which invalidate execution. That will no longer be the case, and I should make that more clear.
7. Have no builtin loader ownership chains | ||
(pending `4UDcAfQ6EcA6bdcadkeHpkarkhZGJ7Bpq7wTAiRMjkoi`) | ||
8. Have total loaded data size which does not exceed | ||
requested_loaded_accounts_data_size_limit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add links to the feature documents.
block-limits would require the validator to check whether or not a transaction | ||
is executable, which negates the benefits of this proposal. | ||
|
||
Additionally, f these transactions did not count towards block-limits, a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, f these transactions did not count towards block-limits, a | |
Additionally, if these transactions did not count towards block-limits, a |
|
||
### Block-Limits | ||
|
||
Pending the activation of `2ry7ygxiYURULZCrypHhveanvP5tzZ4toRwVp89oCNSj`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SIMD should stand for itself and should not have any links, as far as i know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It at least needs to describe the feature.
validators must validate a block is within block-limits. | ||
With this proposal, some transactions may not be executable, but will still | ||
count towards block-limits. | ||
If these transactions did not count towards block-limits, the validation of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do they specifically contribute to block limits.
effect on state. | ||
In case 2, the fee-paying account should be drained of all funds, but have no | ||
other effect on state. | ||
In case 3, the fee-paying account should be drained of all funds, with fees |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems a bit harsh, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially this is too harsh. Alternatively we could just drain them to the rent-exempt level.
Not sure which seems fairer. If submitting a transaction that cannot pay fees, they should be punished imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imho, since the commission is paid, the transaction should be executed. Deleting the account is a different event.
### Fee-Paying | ||
|
||
Currently, iff a transaction's fee-payer does not have enough funds to pay the | ||
fee, the transaction cannot be included in a block. With this proposal, it is | ||
possible for such a transaction to be included in the block, and there are | ||
three different edge-cases to consider: | ||
|
||
1. The fee-payer account does not exist (0 lamports) | ||
2. The fee-payer account does not have enough funds for the entire fee | ||
3. The fee-payer account has enough funds for the fee, but would no longer be | ||
rent-exempt | ||
|
||
In case 1, the transaction should simply be ignored for execution, and have no | ||
effect on state. | ||
In case 2, the fee-paying account should be drained of all funds, but have no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably a good exercise to also enumerate the normal case
In case 2, the fee-paying account should be drained of all funds, but have no | ||
other effect on state. | ||
In case 3, the fee-paying account should be drained of all funds, with fees | ||
being paid to the block-producer, and the remainder of lamports being dropped. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dropped
=> burnt
?
are broken, the entire block is marked invalid; with this proposal, the | ||
block is not marked invalid, but the transaction will not be executed. | ||
These constraints must still be satisfied in order for the transaction to be | ||
executed, and have an effect on state. However, there are some new considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe better off being explicit about side-effects on some on-chain states for these constraints-violating transactions. namely, the status cache to avoid repeated inclusion of same transactions.
- Removing fee-paying requirement could allow validator clients to produce | ||
blocks that do not pay fees. If not checked by block-producer, this could | ||
allow malicious users to abuse such producers/leaders. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, malicious leaders could create full of garbage blocks, which only contains bad transactions at no cost, burdening all the validations onto other validators, esp, heavy account state lookup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed with @ryoqun, this attack vector is the main thing that needs to be solved. Maybe this specific problem can be discussed in a separate SIMD since relaxing other transaction constraints is more straightforward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made a comment in this chain: #82 (comment)
I don't think there's a DOS that's creating more work than would be possible within current protocol.
I can currently create a block thats full of valid heavy transactions, and then tag in some invalidating transaction at the last tick. All the validators wasted their time executing all those txs, and there's no reward for them since the block is thrown out entirely.
This would change the vector, since they could have all txs that do not pay fees. But, that only makes the execution less intense, since they still have a cost that counts towards block limits.
relaxed as well. | ||
|
||
The relaxation of these constraints is only relaxed for transactions being | ||
included in a block. During block validation, if any of these constraints |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this affect transaction simulation? Currently, we get an error when we simulate transactions where the payer does not have enough balance. This will make these kinds of errors indetectable during transaction simulation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean. Transaction simulation is unrelated to block invalidation, and doesn't change with this proposal.
You'd still get the same transaction error which indicates it cannot pay for fees.
3. The fee-payer account has enough funds for the fee, but would no longer be | ||
rent-exempt | ||
|
||
In case 1, the transaction should simply be ignored for execution, and have no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also consider that base fee will eventually change and could be much greater than now.
- Any dynamic fees based on block utilization cannot/should not reward the | ||
block-producer directly. Otherwise, this incentivizes block-producers to fill | ||
blocks with non-fee paying transactions in order to raise fees. | ||
- Non-fee paying transactions included in a block will be recorded in long-term |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a way to attack the cluster and use more space. A malicious leader could create 48M CU / (CU required to load payer account which currently stands at 0) number of transactions. This could be a massive number of transactions, depending on CUs charge that we decide to load the payer account. If each transaction was given the maximum size of 1280 bytes or eventually more if we include ZK transactions, then I can possibly create a huge block burdening the whole cluster's network resources because of the turbine.
I feel like the leader should be somehow punished/slashed for adding transactions where the payer does not have enough balance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently transactions do have a minimum cost of 1070 CUs = 720 SigVerify + 300 WriteLock.
This corresponds to a maximum of 44776 txs per slot, assuming 48M CU limit.
Additionally, cost has 1 CU per 4 bytes of instruction data. So large ix data txs would cost more than this bare minimum of 1070 CUs as well.
It's still a large number of transactions of 34532 txs per slot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's worth noting that currently, all direct rewards are going to the block-producer anyway.
If that large number of transactions were valid fee-paying transactions, it would only be more work for other validators than if they could not pay fees. Either way, other nodes are not directly rewarded for the validation/execution.
There is still some discussion to be had around indirect rewards via the burning of SOL in those fees. I think that's potentially a valid reason we may want to force the block-producer into paying fees. Hoping to discuss this more
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree, block producers should pay a fee as they are using network resources, storage space to transfer invalid transactions. Malicious node can just start creating blocks with invalid transactions of 1280 bytes using 44.20096 MBs/ block in network and storage.
- Transactions that would previously be dropped with an error, can now be | ||
included, and even charged fees. | ||
- Users must be more careful when constructing transactions to ensure they | ||
are executable if they don't want to waste fees |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there additional tools (or simulator enhancement) needed for transaction submitters ensure their transactions against those relaxed constraints?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simulation doesn't change. It currently would tell you that your transaction had an error. That error doesn't change, it only changes what will happen to a block it may be included in.
For example, if a transaction had an invalid program account, simulation will still return ProgramAccountNotFound
error.
If the user simulates, and then still submits that transaction, then they probably deserve to be charged, imo.
updates. This is because the only account-state required for transaction | ||
validation is the ALT resolution, which is resolved at the beginning of a slot. | ||
- Block-production could be done asynchronously | ||
- Block-validation could be done without execution, but still relies on the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be done without execution
Can use some explanations/examples here.
- Block-validation could be done without execution, but still relies on the | ||
execution of previous blocks. | ||
|
||
## Security Considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could any other relaxed constraints, in addition to relaxing "fee-payer requirement", lead to similar dos vector, if block producer build with bad transactions?
Is it necessary to charge transactions failed due to those relaxed constraints by its transaction base fee?
|
||
- Any dynamic fees based on block utilization cannot/should not reward the | ||
block-producer directly. Otherwise, this incentivizes block-producers to fill | ||
blocks with non-fee paying transactions in order to raise fees. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo, it is necessary to have someone to pay for ledger space occupied by those failed transactions (that do not update global state machine). There are several ideas, including have Producer pay. Should the discussion of how to do that be part of this SIMD?
## Drawbacks | ||
|
||
- Any dynamic fees based on block utilization cannot/should not reward the | ||
block-producer directly. Otherwise, this incentivizes block-producers to fill |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any dynamic fees based on block utilization cannot/should not reward the block-producer directly
Humbly not like the sound of a future proposal (eg Dynamic base fee) is already constrained by current design.
But if bock producer cannot include no-paying transactions for free, say producers are liable for adding those bad transactions to block and have to pay for those, then we wouldn't have to worry about this drawback?
In case 1, the transaction should simply be ignored for execution, and have no | ||
effect on state. | ||
In case 2, the fee-paying account should be drained of all funds, but have no | ||
other effect on state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this, Case 2
would never exists, would bad actors fall back to case 1
to quickly build tx with random payer account for DoS attack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this,
Might have missed a comment this is attached to. With what?
Case 2 would probably not occur if it was a malicious actor, but could happen if some non-strict block-producer made and assumption a fee-payer was good and was not.
account state necessarily requires synchronous execution within the protocol. | ||
This proposal on its' own, will not enable asynchronous execution, but it will | ||
remove one of the barriers to asynchronous execution. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit confused by "aim" in Summary section and Motivations here. As "aim" seems to yield benefit to block producer ("...transaction can be included..."), which is not part of protocol; while Motivation talks about modifying protocol.
Is it correct yo say this proposal has two parts:
- remove listed constraints/requirement of transaction for block producer to include them into block; this part solely in Producer implementation, does not modify protocol;
- instead of invalidate entire block at earlist failure of transaction due to named constraints, validator only not execute bad transactions but will continue validate the block. (bad transactions included in ledger). This part of protocol altering.
or maybe I am thinking on wrong track?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think only your 2nd point is included in the proposal. Block-production changse are enabled by the changes in the proposal, but not required beyond potential changes to the fee-colection.
instead of invalidate entire block at earlist failure of transaction due to named constraints, validator only not execute bad transactions but will continue validate the block. (bad transactions included in ledger).
yes. Those bad transactions may end up having limited effect if we are still able to collect fees, or if we decide to make the block-producer cover those fees. They will not be executed though.
Proposal does not suggest or require the block-producer to make any changes, but allows for changes. For several of the constraints, the producer is still incentivized to perform the checks (fee-payer, nonce) because otherwise they will not receive rewards for those transactions. There's freedom in how that is done, and the block-producer could potentially do this in a non-strict fashion.
I'll cover this in the updated prop, but essentially block-validation and consensus really consists of 2 primary questions:
- is this block valid?
- what is the result of the block?
The changes here are intending to make answering this first question, "is this block valid?", a simpler process that does not require executing the block. This proposal separates these questions logically, but w/ current voting we still require the 2nd question, "what is the result of the block?", be answered synchronously.
|
||
## Summary | ||
|
||
This proposal aims to relax some of the constraints on which individual |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to relax some of the constraints
to clarify, "relax" means "removal"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The constraints still exist in the sense we need to check "can this transaction be executed". They do not exist for the validity of the block.
Right now, those 2 different types of constraints are overlapping. I need to re-write this proposal with @lheeger-jump's suggestion on making it very explicit that these 2 things are different.
count towards block-limits. | ||
If these transactions did not count towards block-limits, the validation of | ||
block-limits would require the validator to check whether or not a transaction | ||
is executable, which negates the benefits of this proposal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the case here is "producer builds a block of 48M cu, but validator only spent less than 48M to execute all transactions (as some of TXs are failed and not executed)", and this should be OK (except the DoS vector - that entire block is unexecutable txs, which can be addressed by making producer pay for these unexecutable txs)
- Transactions that would previously be dropped with an error, can now be | ||
included, and even charged fees. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Transactions that would previously be dropped with an error, can now be | |
included, and even charged fees. | |
- Transactions that would previously be dropped with an error without paying fees, can now be | |
included and will be charged fees. |
I think "and even charged fees" doesn't sound declarative enough. My understanding is that the crux of this SIMD is that before we dropped txs for a variety of reasons and didn't charge fees and after we will allow invalid txs to be in a block and will charge fees for them.
2. Relax all but fee-paying constraint | ||
- This was actually the initial proposal, but it was decided that it would | ||
be better to relax as many constraints as possible, rather than just some. | ||
Any reliance on account state, means the protocol requires synchronous | ||
execution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, "it would be better to relax as many constraints as possible" just means that the fee-paying constraint is also removed right? I think you could say that directly here.
- This was considered, since it is a transaction-level constraint that is | ||
depdendent on account-state. However, due to entry-level and block-level | ||
constraints that rely on the address lookup table resolution, this | ||
constraint cannot easily be relaxed without also relaxing those | ||
constraints. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand why there is still a constraint for address lookup tables. If the lookup table is invalid for some reason can't validators just charge the fee payer some fees?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ALT resolution contributes to constraints at higher levels i.e. entry and block.
Entries need to have non-conflicting transactions (without adoption of #83).
Blocks are required to not exceed account write limits (currently 12M CUs).
In both these situations, if we allow ALTs to not resolve I think the behavior becomes very unclear. Do we only consider the static accounts? all resolvable accounts? no accounts?
Not clear to me any of those options is ideal or makes sense. I think we'd like to remove this constraint eventually, but I think it probably makes more sense to do after these complicating entry and block constraints are also removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks for explaining what the entry and block constraints are, I hadn't considered those. FWIW ALTs were designed to be apend only and the warmup time (currently one slot) is configurable by the runtime and can be increased in the future if it helps bankless leaders manage a cache of ALTs. So I think we could try to move forward with removing this constraint.
a block must: | ||
|
||
1. Have a fee-payer with enough funds to pay fees | ||
2. Have a valid nonce account, if specified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider that both normal transactions and durable nonce transactions can only be processed once to be valid? Validators and bankless leaders can use the status cache to avoid including normal transactions more than once, but they need to check that the nonce is valid or not to avoid including durable nonce transactions more than once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considered, but I need to rewrite sections of the proposal to be very explicit.
Status cache should still be used to avoid including transactions multiple times. Duplicate inclusion of transactions is still a violation of constraints and leads to the entire block being marked as invalid. This does not depend on account state, which is why I think this should be left in.
With respect to nonces, we want to avoid depdendence on account state, so cannot check the validity of the nonce account for the question of block validity. However, the nonce acount state must still be checked before execution. If the nonce account does not exist or is otherwise invalid, the transaction is not executed and fees are not charged to the fee-payer.
I view this as a similar situation to the fee-payer check; The block-producer is incentivized to check these states. They are free to do that in some non-strict method, but if done incorrectly, they lose out on rewards and the transaction has no/limited on state and have effectively burned their CUs.
There's an ongoing discussion of if fees should be paid by the block-producer should a transaction be unable to pay. So whether or not the producer gets charged fees in these cases is still an open question.
Pushed some clarifications. As mentioned, I need to re-write a few sections wrt being explicit on separation of "includability" and "executability" constraints. I think the main open question is how to treat non fee-paying transactions. In my opinion, this should be answered and included as part of this SIMD.
I'm not that oppposed to 2, although it might be more complicated. It opens some new questions around what to do if the producer also cannot pay for the fees. |
I think it's hard to imagine a fee-maximizing validator not maintaining a status cache, durable nonce cache, ALT cache, etc (are there more?). I lean towards enforcing all validators to maintain those caches in order to produce valid blocks. Is that also an option? (EDIT: If we continue forward assuming that validators are incentivized to avoid non-fee paying transactions, can we explain how they could reasonably implement that? I think block space could be DOS'd otherwise) |
Are these the only cases in which transactions don't pay fees?
Can you document them in the SIMD and explain why they can't be avoided and need to be addressed? |
I'll document it, but to be clear. Normal transactions can still not be replayed. This SIMD does not propose changes to the status cache. If a block contains an already executed normal transaction, then the entire block will be invalid. With nonced transactions, correct. They could be included multiple times, would not pay fees or be executed after the first one.
Just to re-iterate, the SIMD doesn't propose changes to status-cache.
Sure, rejecting wholely or part of the SIMD would leave those constraints in the protocol.
There's no reason a validator could not continue to do strict fee-paying checks, as they do today, for block-production.
Yeah, so this part of prevention is behind a currently inactive feature: solana-labs/solana#29595 That feature will cause transactions to count towards block-limits with the requested CUs (+builtin costs), not actually executed. |
Couldn't some malicious actor send a bunch of non-fee paying transactions then to saturate block-limits and prevent fee-paying users from using the chain? I think this should be explicitly prevented by the design of this SIMD if possible. |
A malicious user could send those transactions, but any reasonable producer will have some logic, albeit not necessarily strict, for filtering out transactions that cannot pay fees. Since if they pack those transactions they either get no rewards, or have to pay the fees themselves (hoping to discuss this tomorrow at community call). I will explicitly mention this potential case in the SIMD. |
Converting to a draft as I rework the proposal to fit the feedback received during the core community call. |
@lheeger-jump made the lists much more clear, tried to enumerate all relevant checks that affect whether or not a transaction can be accepted in a block. Because many of the other changes are less controversial, I've opted to remove the fee-payer relaxation out of this SIMD and would do that as a follow-up proposal. |
@apfitzge @jstarry this math works out Allow invalid txs and skip over them
Subtract the number of invalid txs at the end of the epoch from the leaders reward points (1 vote 1 point, so each invalid tx is 1 missed point)
5800 sol is the min to be scheduled once per each for a 4 slot period. max number of invalid txs in that period is 100k. * 5800 * 0.05 reward apy ~= 2 sol per epoch in rewards if the validator didn't vote at all, they lost out on 2sol worth of network rewards. If they voted, they lose out on at least 1/4th of the rewards, which is > 0.5 sol. |
TVC eliminates the 1:1 vote-to-credit relationship, so those number would need to be tuned. Even without the complicating factors of relaxing fee-payer or signature constraints, which are contentious changes, this proposal seems to be idling waiting for reviews. Maybe I'm off - @jstarry lmk if I should add these back into this proposal. |
How can proposer exceed the shred limits @apfitzge? I don't think they can exceed 100k txs in 4 slots, but they can submit super large txs and reduce the penalty. But the penalty can just be tuned to be 10 points per invalid tx, or X points per tx byte. Either way. TVC changes don't really impact this since the best case is about the same. |
- be executable | ||
- the owner account be owned by the native loader: `NativeLoader1111111111111111111111111111111` | ||
- the owner account must be executable | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a complete test suite that tests every single one of these constraints (via txn execution) so that we can also test the behavior when the feature flag is flipped to make sure we relax all the correct constraints
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, any client should be testing against the protocol, and those tests much change if the protocol changes.
There should already (big should in our codebase...) be tests for all these cases, as they are currently protocol violations, that we must check for.
Tests can be modified to use feature-flag which would change the result of processing pipeline from rejected -> not executed.
because that's not the shred limits, afaik shred limits would be 131072 txs per slot. |
3. Transaction signatures must be valid and in the same order as the static | ||
account keys in the `VersionedMessage`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From conversation in #159 we should only be requiring the fee payer signature to be valid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but that was a separate change not part of this SIMD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok maybe rather than having a single all encompassing SIMD for transaction constraints, we limit this one to account loading related constraints?
7. Transactions that use address lookup tables must be resolvable: | ||
- The address lookup table account must exist. | ||
- The address lookup table account must be owned by the address lookup | ||
table program: `AddressLookupTab1e1111111111111111111111111` | ||
- The address lookup table account data must be deserializable into | ||
`AddressLookupTable` as defined in `solana-sdk`. | ||
- All account table indices specified in the transaction must be less than | ||
the number of active addresses in the address lookup table. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved to the runtime error section. It's pretty straightforward to handle transactions with invalid address lookup tables in replay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plan was for this to be in a separate follow-up SIMD since the choice here is very much not obvious imo.
How do we apply CUs to account-level cost if we cannot resolve ALTs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with it being covered in a separate SIMD
- OR the transaction must be a nonced transaction, and the nonce | ||
account must exist and be valid for the given `recent_blockhash`. | ||
12. The transaction must not have already been processed. | ||
13. The transaction fee-payer account must: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need a section talking about durable nonce transactions. They must:
- use a recent blockhash value different from the durable nonce for the current bank
- have at least one transaction instruction, the first of which is designated the nonce advance instruction which must:
- invoke the system program
11111111111111111111111111111111
- have instruction data that deserializes to the
SystemInstruction::AdvanceNonceAccount
variant - have at least one account input, the first of which is designated the nonce address/account which must:
- be loaded with a write-lock
- be owned by the system program:
11111111111111111111111111111111
- be deserializable to non-legacy initialized nonce state
- have a durable nonce hash equal to the transaction's recent blockhash field
- invoke the system program
- be signed by the nonce authority deserialized from the nonce account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this SIMD can be trimmed down a lot and just focus on what I consider to be "transaction loading" constraints. We don't need to enumerate all of the protocol constraints in this document, so I think we should get rid of the "Current Protocol-Violation Errors" and the "Proposed Protocol-Violation Errors" sections which just leaves the "Proposed New Runtime Errors" section which is the only thing anyone will want to know when reading this document.
I know this SIMD started off as a general relax all the tx constraints proposal, but now that it's been scoped down, I think it should be renamed and focused to only relaxing account loading related transaction accounts. Which, in my opinion, includes all of the new runtime constraints you've listed with the exception of the precompile verification constrain which is already covered in #159
Last review from Jump's side explicitly asked me to add in these which is why I did. |
This SIMD has been split into a few smaller SIMDs (biggest one being #191). Closing this issue since I will not be pushing for this to be merged. Discussions are not deleted and this PR is linked to from the split SIMD(s) |
The first in a series of SIMDs aimed at the relaxation of constraints blocking us from (potentially) having asynchronous execution.
This proposal does not lock Solana into moving towards asynchronous execution.
This proposal stands on its own to simplify the protocol and give more flexibility in implementation of both block-production and block-validation.