@shemnon cheers Danno that’s really helpful
This sounds useful, and I’m wondering if this EIP could come in handy for other mechanisms like ERC-4337 bundlers and the Ultra Tx proposal.
But as the EIP says:
If these rules are not enshrined as block validity conditions then they can be enforced by a smart contract.
Programmatically reverting can still be costly, and there’s no way to ensure that a transaction is top of the block. So for this use case to be practical, you might also need other mechanisms like inclusion lists and revert protection.
You have convinced me ser, system contract makes more sense you are right.
I shared a research post here that applies the TXINDEX precompile to an encrypted mempool design. Hopefully this can clarify why this precompile is useful for encrypted mempools.
I’ve made a couple of changes to this EIP which you can see here.
First I changed back to an opcode (also for EIP-7843 SLOTNUM
). @shemnon suggested to change to a precompile originally, but the feedback I’ve got from client teams is that they would prefer not to add new precompiles. Additionally, I’ve got feedback that it’s not a big problem for L2s to remove opcodes. One other advantage is that there is less gas overhead as an opcode.
The bigger change is going from TXINDEX
to ASSERTTXINDEX
. This is based on feedback from @LukaszRozmej and @wjmelements around parallel block building. This change means that you can statically determine what the expected transaction index is, meaning that you can’t impose complex, dynamic constraints on block building.
Also I will be talking about this EIP and EIP-7843 on PEEPanEIP podcast at 18:30 UTC tomorrow (15th May). If you are interested or have any questions please join!
This EIP proposes to add a new opcode
ASSERTTXINDEX
(0xfb
), that reverts if the index of the current transaction within the block does not match the expected value. This allows for transactions that can only be executed at a certain index within a block.
Why not have a dependsOn
semantics for a new transaction type?
The new opcode aims to improve support for encrypted mempools. Transactions in an encrypted mempool are ordered while the transactions are encrypted, before being decrypted and included onchain at the top of the block. If the builder does not respect the order when including the decrypted transactions then they could frontrun decrypted transactions. The new opcode can be used to make this impossible; if a decrypted transaction is not included at the correct index, it will revert.
So this means that it must be included at the top of the block?
I’m not sure what you mean by dependsOn
semantics, but the latest version of the EIP does have a new transaction type. The old version with ASSERTTXINDEX turned out to be a bit too inflexible.
Yes they must be top of block. The encrypted mempool txs may be split over multiple transactions though, so we could have index 0, 1, 2 for example. The desired index is specified as a field in the transaction type, and it can then be checked onchain with the opcode.
The transaction type spec is better than the opcode spec:
- Index should only be validated once per transaction. Best to validate it immediately and for this requirement to be explicit.
- The
ASSERTINDEX
opcode is useless except for this purpose, and we don’t want to waste the 1-byte opcode space. - Transaction types can be relatively plentiful.
I appreciate the improvement! Each version of this proposal has been better than the last. Here are some ideas I have had since reading the newest spec:
- I wonder how useful this is for indices other than 0. Do you know a use case where another index would be sufficient information for the sender? By index 1, any prior state could have changed.
- The asserted index field could be a nullable (rlp:
0x80
) field in supporting transaction types, and so perhaps a zero assertion should be rlp encoded as0x00
.