ethereum / ethereum/execution-specs
Feature request: read results of the generated blocks/txs
- Dominant language
- Python
- Stars
- 1.2k
- Forks
- 505
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 116
Description
Sometimes in a test we need to know current values or numbers in order to more accurately write a test. For instance, if we have a complex transaction, interacting with an ERC20 token contract for instance, we'd like to know how much gas a transaction uses which transfers an ERC20 token. It is theoretically possible to calculate this via gas costs, but this is much more complex than specific bytecode contracts which we design (which often are a sequence of the same opcode, which have static gas costs).
In the `uv run fill` situation we use t8n to produce blocks. In particular, in the output of this block we can read the results of the block (for instance the total `gasUsed` of the block) and we can also read the receipts of the transactions (which have the cumulative gas used in them, so we can also use this to calculate how much a transaction has cost).
It would be helpful in tests if we could query such values. For instance:
```python
token_transfer_block = Block(txs=[new_transfer_tx()])
gas_used = token_transfer_block.gas_used # Value read from header after this block has been built
txs_transfer_spam = []
for tx in range(env.gas_limit // gas_used):
txs_transfer_spam.append(new_transfer_tx())
token_spam_block = Block(txs=txs_transfer_spam)
blocks_to_execute = [token_transfer_block, token_spam_block]
# Execute the blockchain_test_here with the blocks_to_execute
```
(This example test would first "test" how much one ERC20 transfer takes takes in gas, and then fills the block we are interesting in (the token_spam_block) with as many ERC20 token transfers transactions as possible)
Possible problems
====
If we use `uv run fill` and thus use t8n setting this up would likely not lead to problems (although this depends a bit on the internal architecture of EEST so cannot really judge here). However, for `uv run execute remote` this is more problematic, since at `uv run execute remote` (or anything not t8n-related but uses RPC to run tests) we cannot enforce (?) that a transaction is included in a block. This is especially a problem if we want a block with multiple transactions. What should we do if we want a block with 2 transactions included (in a certain order) but this is not the case? We can query this via `eth_getBlock` and then inspect the transactions. But if it fails, what should we do? Rollback the chain? Or create new txs on top of the current state (likely: rollback until the client builds the expected block).
This feature is very helpful to write tests, especially ones which use "practical" situations (like replay mainnet txs) and in the test we want to react on the behavior. Also think of variables beyond what we can read from the block header, for instance: the balance of an account or the value of a storage slot after we have executed transactions/blocks.
This should likely be split up in multiple sub-tasks. The thing I would personally find very helpful is if we can inspect the gas used by a certain transaction (like in the example).
Contributor guide
Assessment
This issue has not been assessed yet.