@@ -110,16 +110,20 @@ def test_xcall(
110110 )
111111
112112 initcode , factory_address , factory_caller_address = (
113- deploy_max_contract_factory (pre , fork )
113+ _deploy_max_contract_factory (pre , fork )
114114 )
115115
116+ # Deploy num_contracts via multiple txs (each capped by tx gas limit).
116117 with TestPhaseManager .setup ():
117- # We require deploying num_contracts by calling the factory contract. Each call can only
118- # use up to the transaction gas limit cap, thus we need to split the deployment into
119- # multiple transactions. The factory contract uses a storage slot to keep track of the last
120- # seed used to generate bytecodes, so it is safe to call it multiple times in different txs.
121- num_contracts_per_tx = (
122- 3 # TODO: Try generalizing for any tx gas limit cap. For 17M is 3.
118+ # Rough estimate (rounded down) of contracts per tx based on dominant
119+ # cost factor only. E.g., 17M gas limit + 24KiB contracts = ~3 per tx.
120+ # The goal is to involve the minimum amount of gas pricing to avoid
121+ # complexity and potential brittleness.
122+ # If this estimation is incorrect in the future (i.e. tx gas limit cap)
123+ # is increased or cost per byte, the post-state check will detect it
124+ # and can be adjusted with a more complex formula.
125+ num_contracts_per_tx = fork .transaction_gas_limit_cap () // (
126+ gas_costs .G_CODE_DEPOSIT_BYTE * max_contract_size
123127 )
124128 attack_txs = math .ceil (num_contracts / num_contracts_per_tx )
125129
@@ -181,7 +185,8 @@ def test_xcall(
181185 remainder = attack_gas_limit % tx_gas_cap
182186
183187 num_targeted_contracts_per_full_tx = (
184- # Base available gas = TX_GAS_LIMIT - intrinsic - (out of loop MSTOREs)
188+ # Base available gas:
189+ # TX_GAS_LIMIT - intrinsic - (out of loop MSTOREs)
185190 tx_gas_cap - intrinsic_gas_cost_calc () - gas_costs .G_VERY_LOW * 4
186191 ) // loop_cost
187192 contract_start_index = 0
@@ -219,7 +224,7 @@ def test_xcall(
219224 )
220225
221226
222- def deploy_max_contract_factory (
227+ def _deploy_max_contract_factory (
223228 pre : Alloc ,
224229 fork : Fork ,
225230) -> tuple [Bytecode , Address , Address ]:
0 commit comments