-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Update EIP-7907: Reduce code limit, increase cost per word, fix EXTCODESIZE
issue
#9910
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
base: master
Are you sure you want to change the base?
Conversation
File
|
EXTCODESIZE
issueEXTCODESIZE
issue
The commit d082da4 (as a parent of b037684) contains errors. |
|
||
## Rationale | ||
|
||
The gas cost of 2 per word was chosen in-line with [EIP-3860](./eip-3860.md). This accounts for: | ||
The gas cost of 4 per word was chosen in-line with the per word code defined by [EIP-2929](./eip-2929.md)'s `COLD_ACCOUNT_ACCESS_COST. The value is derived from the current gas per word code of `ceil(2600 / (24676//32)) = 4` where `2600` is the current cold account load cost and `24676` is the maximum allow code size at that price. In general, this accounts for: |
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 agree that we should reuse 2600
in the excess gas calculation. One thought is whether the excess gas should include the cost of reading account from MPT.
The original 2600 gas accounts for:
- cost for reading the account from MPT
- cost for reading the code via codehash (from
account
) - jump analysis, memory, etc
When reading a large contract, since the first 2600 already covers the cost of reading the account, should the excess gas include the cost of reading the account or not? It is not, the 2600
per extra 24KB (or 3072
of 24KB using 4 gas per word) may be too conservative? (But I am fine if such a conservative design is intended.)
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 it is hard to say conclusively. This I err on the side of caution until we have empirical data to guide us. At a 3072
per additional 24KB, it should be pretty close to parity when you consider the overhead of preparing calls to other contracts in something like diamond standard.
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 marginal per-word cost of loading data should be lower than the initial 2600 gas per 24kb (which works out to about 3.38 gas per word). i am under the impression that a more comprehensive gas tuning across all opcodes is being prepared. but it still feels weird to price the marginal cost per word over the cost per-word of the initial 24kb, since it's a sequential load and no additional db access needs to be done. if 2 gas per word is considered too cheap, maybe 3 gas per word is better?
2. Change the gas schedule for opcodes which load code. Specifically, the opcodes `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE` and `EXTCODECOPY` are modified so that `largeContractCost = ceil32(excess_contract_size) * GAS_INIT_CODE_WORD_COST // 32` gas is added to the access cost if the code is cold, where `excess_contract_size = max(0, contract_size - 0x6000)`, and `GAS_INIT_CODE_WORD_COST = 2`. (Cf. initcode metering: [EELS](https://github.com/ethereum/execution-specs/blob/1a587803e3e698407d204888b02342393f8b4fe5/src/ethereum/cancun/vm/gas.py#L269)). This introduces a new warm state for contract code - warm if the code has been loaded, cold if not. | ||
1. Update the [EIP-170](./eip-170.md) contract code size limit of 24KB (`0x6000` bytes) to 48KB (`0xc000` bytes). | ||
2. Change the gas schedule for opcodes which load code. Specifically, the opcodes `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE` and `EXTCODECOPY` are modified so that `largeContractCost = ceil32(excess_contract_size) * GAS_CODE_LOAD_WORD_COST // 32` gas is added to the access cost if the code is cold, where `excess_contract_size = max(0, contract_size - 0x6000)`, and `GAS_CODE_LOAD_WORD_COST = 4`. (Cf. initcode metering: [EELS](https://github.com/ethereum/execution-specs/blob/1a587803e3e698407d204888b02342393f8b4fe5/src/ethereum/cancun/vm/gas.py#L269)). This introduces a new warm state for contract code - warm if the code has been loaded, cold if not. | ||
3. The cost for `EXTCODESIZE` is updated to acknowlege the potential for two database reads: once for the code hash and once for the code size associated with the code hash. |
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 would EXTCODESIZE
charge exactly? I may miss the info somewhere.
Hey there, I'm Derek from Offchain Labs. Speaking on behalf of Arbitrum teams and developers, we'd very much like to see the original 256 KiB max contract size code rather than the proposed reduction to 48 KiB here in this PR. Devnet-02 will have the original specification and I'd be curious to know what numbers/metrics we're looking for to make the call for reducing the max contract size from 256 KiB to 48 KiB (or other value). Thanks! |
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.
Great PR. It seems upon a first read that we now have 3 categories of "warm";
- Cold/warm account
- Cold/warm extcodesize
- Cold/warm code
Is this correct? When do these get warm? What about current account warming (coinbase, precompiles, sender account, target account, 7702-delegated account (if targeted by tx))? I think this should be specified to self-contain the EIP.
1. Update the [EIP-170](./eip-170.md) contract code size limit of 24KB (`0x6000` bytes) to 48KB (`0xc000` bytes). | ||
2. Change the gas schedule for opcodes which load code. Specifically, the opcodes `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE` and `EXTCODECOPY` are modified so that `largeContractCost = ceil32(excess_contract_size) * GAS_CODE_LOAD_WORD_COST // 32` gas is added to the access cost if the code is cold, where `excess_contract_size = max(0, contract_size - 0x6000)`, and `GAS_CODE_LOAD_WORD_COST = 4`. (Cf. initcode metering: [EELS](https://github.com/ethereum/execution-specs/blob/1a587803e3e698407d204888b02342393f8b4fe5/src/ethereum/cancun/vm/gas.py#L269)). This introduces a new warm state for contract code - warm if the code has been loaded, cold if not. | ||
3. The cost for `EXTCODESIZE` is updated to acknowlege the potential for two database reads: once for the code hash and once for the code size associated with the code hash. | ||
with the hash. In addition to the current pricing scheme defined under [EIP-2929](./eip-2929.md), the instruction will also be subject to regular storage pricing, e.g. `COLD_SLOAD_COST` and `WARM_SLOAD_COST`. |
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.
Does querying EXTCODESIZE
make the account "code-warm", or is this another category? (warm account, warm code, warm extcodesize (?))
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 it would make the account warm and code size for the account warm, but leave the code cold.
Can further specifications be added to the EIP:
|
Hi @lightclient, would you mind summarizing the concerns / blockers that caused the decision to reduce the contract size limit increase to 48KB bytecode / 96KB initcode? As an outsider I have a hard time following from ACDE + chat logs what the exact blockers are and whether there is still a pathway to 256KB after opcode repricing / gas limit increase. Thanks! |
Echo this point by @jochem-brouwer. Current tests expect the code to be warm for the |
i think that |
i think the implementation is cleaner if there is no interaction between the revert journal and the warm code list (i.e., reverts do not clean the warm code list). but if it's better to keep consistency with 2929, that's fine - maybe ACDE should vote here or something. |
On another topic, not journaling code warming looks okay to do. |
It feels to me like we should charge this, otherwise it won't scale I think. What about charging it at the start of the transaction execution, and failing with OOG before executing any code if the starting gas is not enough to cover this large-contract extra cost? |
True, we should probably introduce the fee. |
Updating with a few things we discussed at interop:
ceil(2600 / (24676//32)) = 4
EXTCODESIZE