|
28 | 28 | ZERO_32BYTES = b'\x00' * 32
|
29 | 29 | ZERO_8BYTES = b'\x00' * 8
|
30 | 30 | ZERO_ADDRESS = b'\x00' * 20
|
| 31 | +BLOCK_ELASTICITY_MULTIPLIER = 2 |
| 32 | +BASE_FEE_MAX_CHANGE_DENOMINATOR = 8 |
31 | 33 |
|
32 | 34 |
|
33 | 35 | @apply_to_return_value(b'|'.join)
|
@@ -89,66 +91,53 @@ def _fill_transaction(transaction, block, transaction_index, is_pending, overrid
|
89 | 91 | if overrides is None:
|
90 | 92 | overrides = {}
|
91 | 93 |
|
92 |
| - if 'nonce' in overrides: |
93 |
| - yield 'nonce', overrides['nonce'] |
94 |
| - else: |
95 |
| - yield 'nonce', 0 |
| 94 | + is_dynamic_fee_transaction = ( |
| 95 | + 'gas_price' not in transaction and any( |
| 96 | + _ in transaction for _ in ('max_fee_per_gas', 'max_priority_fee_per_gas') |
| 97 | + ) |
| 98 | + ) |
96 | 99 |
|
97 | 100 | if 'hash' in overrides:
|
98 | 101 | yield 'hash', overrides['hash']
|
99 | 102 | else:
|
100 | 103 | # calculate hash after all fields are filled
|
101 | 104 | pass
|
102 | 105 |
|
103 |
| - if 'from' in overrides: |
104 |
| - yield 'from', overrides['from'] |
105 |
| - else: |
106 |
| - yield 'from', transaction['from'] |
| 106 | + # this pattern isn't the nicest to read but it keeps things clean. Here, we yield the overrides |
| 107 | + # value if it exists, else either the transaction value if that exists, or a default value |
| 108 | + yield 'nonce', overrides.get('nonce', 0) |
| 109 | + yield 'from', overrides.get('from', transaction.get('from')) |
| 110 | + yield 'to', overrides.get('to', transaction.get('to', b'')) |
| 111 | + yield 'data', overrides.get('data', transaction.get('data', b'')) |
| 112 | + yield 'value', overrides.get('value', transaction.get('value', 0)) |
| 113 | + yield 'nonce', overrides.get('nonce', transaction.get('nonce', 0)) |
| 114 | + yield 'gas', overrides.get('gas', transaction.get('gas')) |
107 | 115 |
|
108 |
| - if 'gas' in overrides: |
109 |
| - yield 'gas', overrides['gas'] |
| 116 | + if 'gas_price' in transaction or 'gas_price' in overrides: |
| 117 | + # gas price is 1 gwei in order to be at least the base fee at the (London) genesis block |
| 118 | + yield 'gas_price', overrides.get('gas_price', transaction.get('gas_price', 1000000000)) |
110 | 119 | else:
|
111 |
| - yield 'gas', transaction['gas'] |
| 120 | + # if no gas_price specified, default to dynamic fee txn parameters |
| 121 | + is_dynamic_fee_transaction = True |
112 | 122 |
|
113 |
| - if 'gas_price' in overrides: |
114 |
| - yield 'gas_price', overrides['gas_price'] |
115 |
| - else: |
116 |
| - yield 'gas_price', transaction.get('gas_price', 1) # TODO: make configurable |
| 123 | + if is_dynamic_fee_transaction: |
| 124 | + yield 'max_fee_per_gas', overrides.get( |
| 125 | + 'max_fee_per_gas', transaction.get('max_fee_per_gas', 1000000000) |
| 126 | + ) |
| 127 | + yield 'max_priority_fee_per_gas', overrides.get( |
| 128 | + 'max_priority_fee_per_gas', transaction.get('max_priority_fee_per_gas', 1000000000) |
| 129 | + ) |
117 | 130 |
|
118 |
| - if 'to' in overrides: |
119 |
| - yield 'to', overrides['to'] |
| 131 | + if is_dynamic_fee_transaction or 'access_list' in transaction: |
| 132 | + # if is typed transaction (dynamic fee or access list transaction) |
| 133 | + yield 'chain_id', overrides.get('chain_id', transaction.get('chain_id', 131277322940537)) |
| 134 | + yield 'access_list', overrides.get('access_list', transaction.get('access_list', [])) |
| 135 | + yield 'y_parity', overrides.get('y_parity', transaction.get('y_parity', 0)) |
120 | 136 | else:
|
121 |
| - yield 'to', transaction.get('to', b'') |
| 137 | + yield 'v', overrides.get('v', transaction.get('v', 27)) |
122 | 138 |
|
123 |
| - if 'data' in overrides: |
124 |
| - yield 'data', overrides['data'] |
125 |
| - else: |
126 |
| - yield 'data', transaction.get('data', b'') |
127 |
| - |
128 |
| - if 'value' in overrides: |
129 |
| - yield 'value', overrides['value'] |
130 |
| - else: |
131 |
| - yield 'value', transaction.get('value', 0) |
132 |
| - |
133 |
| - if 'nonce' in overrides: |
134 |
| - yield 'nonce', overrides['nonce'] |
135 |
| - else: |
136 |
| - yield 'nonce', transaction.get('nonce', 0) |
137 |
| - |
138 |
| - if 'v' in overrides: |
139 |
| - yield 'v', overrides['v'] |
140 |
| - else: |
141 |
| - yield 'v', transaction.get('v', 27) |
142 |
| - |
143 |
| - if 'r' in overrides: |
144 |
| - yield 'r', overrides['r'] |
145 |
| - else: |
146 |
| - yield 'r', transaction.get('r', 12345) |
147 |
| - |
148 |
| - if 's' in overrides: |
149 |
| - yield 's', overrides['s'] |
150 |
| - else: |
151 |
| - yield 's', transaction.get('s', 67890) |
| 139 | + yield 'r', overrides.get('r', transaction.get('r', 12345)) |
| 140 | + yield 's', overrides.get('s', transaction.get('s', 67890)) |
152 | 141 |
|
153 | 142 |
|
154 | 143 | @to_dict
|
@@ -200,7 +189,7 @@ def make_log(transaction, block, transaction_index, log_index, overrides=None):
|
200 | 189 |
|
201 | 190 |
|
202 | 191 | @to_dict
|
203 |
| -def make_receipt(transaction, block, transaction_index, overrides=None): |
| 192 | +def make_receipt(transaction, block, _transaction_index, overrides=None): |
204 | 193 | if overrides is None:
|
205 | 194 | overrides = {}
|
206 | 195 |
|
@@ -253,12 +242,12 @@ def make_genesis_block(overrides=None):
|
253 | 242 | "total_difficulty": 131072,
|
254 | 243 | "size": 0,
|
255 | 244 | "extra_data": ZERO_32BYTES,
|
256 |
| - "gas_limit": 3141592, |
| 245 | + "gas_limit": 30029122, # gas limit at London fork block 12965000 on mainnet |
257 | 246 | "gas_used": 0,
|
258 | 247 | "timestamp": int(time.time()),
|
259 | 248 | "transactions": [],
|
260 | 249 | "uncles": [],
|
261 |
| - "base_fee_per_gas": 1000000000, |
| 250 | + "base_fee_per_gas": 1000000000, # base fee at London fork block 12965000 on mainnet |
262 | 251 | }
|
263 | 252 | if overrides is not None:
|
264 | 253 | genesis_block = merge_genesis_overrides(defaults=default_genesis_block,
|
@@ -369,3 +358,38 @@ def make_block_from_parent(parent_block, overrides=None):
|
369 | 358 | yield 'uncles', overrides['uncles']
|
370 | 359 | else:
|
371 | 360 | yield 'uncles', []
|
| 361 | + |
| 362 | + if 'base_fee_per_gas' in overrides: |
| 363 | + yield 'base_fee_per_gas', overrides['base_fee_per_gas'] |
| 364 | + else: |
| 365 | + yield 'base_fee_per_gas', _calculate_expected_base_fee_per_gas(parent_block) |
| 366 | + |
| 367 | + |
| 368 | +def _calculate_expected_base_fee_per_gas(parent_block) -> int: |
| 369 | + """py-evm logic for calculating the base fee from parent header""" |
| 370 | + parent_base_fee_per_gas = parent_block['base_fee_per_gas'] |
| 371 | + |
| 372 | + parent_gas_target = parent_block['gas_limit'] // BLOCK_ELASTICITY_MULTIPLIER |
| 373 | + parent_gas_used = parent_block['gas_used'] |
| 374 | + |
| 375 | + if parent_gas_used == parent_gas_target: |
| 376 | + return parent_base_fee_per_gas |
| 377 | + |
| 378 | + elif parent_gas_used > parent_gas_target: |
| 379 | + gas_used_delta = parent_gas_used - parent_gas_target |
| 380 | + overburnt_wei = parent_base_fee_per_gas * gas_used_delta |
| 381 | + base_fee_per_gas_delta = max( |
| 382 | + overburnt_wei // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR, |
| 383 | + 1, |
| 384 | + ) |
| 385 | + return parent_base_fee_per_gas + base_fee_per_gas_delta |
| 386 | + |
| 387 | + else: |
| 388 | + gas_used_delta = parent_gas_target - parent_gas_used |
| 389 | + underburnt_wei = parent_base_fee_per_gas * gas_used_delta |
| 390 | + base_fee_per_gas_delta = ( |
| 391 | + underburnt_wei |
| 392 | + // parent_gas_target |
| 393 | + // BASE_FEE_MAX_CHANGE_DENOMINATOR |
| 394 | + ) |
| 395 | + return max(parent_base_fee_per_gas - base_fee_per_gas_delta, 0) |
0 commit comments