ethereum.berlin.fork
Ethereum Specification ^^^^^^^^^^^^^^^^^^^^^^
.. contents:: Table of Contents :backlinks: none :local:
Introduction
Entry point for the Ethereum specification.
1""" 2Ethereum Specification 3^^^^^^^^^^^^^^^^^^^^^^ 4 5.. contents:: Table of Contents 6 :backlinks: none 7 :local: 8 9Introduction 10------------ 11 12Entry point for the Ethereum specification. 13""" 14 15from dataclasses import dataclass 16from typing import List, Optional, Set, Tuple, Union 17 18from ethereum.base_types import Bytes0 19from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover 20from ethereum.crypto.hash import Hash32, keccak256 21from ethereum.ethash import dataset_size, generate_cache, hashimoto_light 22from ethereum.exceptions import InvalidBlock 23from ethereum.utils.ensure import ensure 24 25from .. import rlp 26from ..base_types import U64, U256, U256_CEIL_VALUE, Bytes, Uint 27from . import vm 28from .bloom import logs_bloom 29from .fork_types import ( 30 TX_ACCESS_LIST_ADDRESS_COST, 31 TX_ACCESS_LIST_STORAGE_KEY_COST, 32 TX_BASE_COST, 33 TX_CREATE_COST, 34 TX_DATA_COST_PER_NON_ZERO, 35 TX_DATA_COST_PER_ZERO, 36 AccessListTransaction, 37 Address, 38 Block, 39 Bloom, 40 Header, 41 LegacyTransaction, 42 Log, 43 Receipt, 44 Root, 45 Transaction, 46 decode_transaction, 47 encode_transaction, 48) 49from .state import ( 50 State, 51 account_exists_and_is_empty, 52 create_ether, 53 destroy_account, 54 get_account, 55 increment_nonce, 56 set_account_balance, 57 state_root, 58) 59from .trie import Trie, root, trie_set 60from .utils.message import prepare_message 61from .vm.interpreter import process_message_call 62 63BLOCK_REWARD = U256(2 * 10**18) 64GAS_LIMIT_ADJUSTMENT_FACTOR = 1024 65GAS_LIMIT_MINIMUM = 5000 66MINIMUM_DIFFICULTY = Uint(131072) 67MAX_OMMER_DEPTH = 6 68BOMB_DELAY_BLOCKS = 9000000 69EMPTY_OMMER_HASH = keccak256(rlp.encode([])) 70 71 72@dataclass 73class BlockChain: 74 """ 75 History and current state of the block chain. 76 """ 77 78 blocks: List[Block] 79 state: State 80 chain_id: U64 81 82 83def apply_fork(old: BlockChain) -> BlockChain: 84 """ 85 Transforms the state from the previous hard fork (`old`) into the block 86 chain object for this hard fork and returns it. 87 88 When forks need to implement an irregular state transition, this function 89 is used to handle the irregularity. See the :ref:`DAO Fork <dao-fork>` for 90 an example. 91 92 Parameters 93 ---------- 94 old : 95 Previous block chain object. 96 97 Returns 98 ------- 99 new : `BlockChain` 100 Upgraded block chain object for this hard fork. 101 """ 102 return old 103 104 105def get_last_256_block_hashes(chain: BlockChain) -> List[Hash32]: 106 """ 107 Obtain the list of hashes of the previous 256 blocks in order of 108 increasing block number. 109 110 This function will return less hashes for the first 256 blocks. 111 112 The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain, 113 therefore this function retrieves them. 114 115 Parameters 116 ---------- 117 chain : 118 History and current state. 119 120 Returns 121 ------- 122 recent_block_hashes : `List[Hash32]` 123 Hashes of the recent 256 blocks in order of increasing block number. 124 """ 125 recent_blocks = chain.blocks[-255:] 126 # TODO: This function has not been tested rigorously 127 if len(recent_blocks) == 0: 128 return [] 129 130 recent_block_hashes = [] 131 132 for block in recent_blocks: 133 prev_block_hash = block.header.parent_hash 134 recent_block_hashes.append(prev_block_hash) 135 136 # We are computing the hash only for the most recent block and not for 137 # the rest of the blocks as they have successors which have the hash of 138 # the current block as parent hash. 139 most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header)) 140 recent_block_hashes.append(most_recent_block_hash) 141 142 return recent_block_hashes 143 144 145def state_transition(chain: BlockChain, block: Block) -> None: 146 """ 147 Attempts to apply a block to an existing block chain. 148 149 All parts of the block's contents need to be verified before being added 150 to the chain. Blocks are verified by ensuring that the contents of the 151 block make logical sense with the contents of the parent block. The 152 information in the block's header must also match the corresponding 153 information in the block. 154 155 To implement Ethereum, in theory clients are only required to store the 156 most recent 255 blocks of the chain since as far as execution is 157 concerned, only those blocks are accessed. Practically, however, clients 158 should store more blocks to handle reorgs. 159 160 Parameters 161 ---------- 162 chain : 163 History and current state. 164 block : 165 Block to apply to `chain`. 166 """ 167 parent_header = chain.blocks[-1].header 168 validate_header(block.header, parent_header) 169 validate_ommers(block.ommers, block.header, chain) 170 ( 171 gas_used, 172 transactions_root, 173 receipt_root, 174 block_logs_bloom, 175 state, 176 ) = apply_body( 177 chain.state, 178 get_last_256_block_hashes(chain), 179 block.header.coinbase, 180 block.header.number, 181 block.header.gas_limit, 182 block.header.timestamp, 183 block.header.difficulty, 184 block.transactions, 185 block.ommers, 186 chain.chain_id, 187 ) 188 ensure(gas_used == block.header.gas_used, InvalidBlock) 189 ensure(transactions_root == block.header.transactions_root, InvalidBlock) 190 ensure(state_root(state) == block.header.state_root, InvalidBlock) 191 ensure(receipt_root == block.header.receipt_root, InvalidBlock) 192 ensure(block_logs_bloom == block.header.bloom, InvalidBlock) 193 194 chain.blocks.append(block) 195 if len(chain.blocks) > 255: 196 # Real clients have to store more blocks to deal with reorgs, but the 197 # protocol only requires the last 255 198 chain.blocks = chain.blocks[-255:] 199 200 201def validate_header(header: Header, parent_header: Header) -> None: 202 """ 203 Verifies a block header. 204 205 In order to consider a block's header valid, the logic for the 206 quantities in the header should match the logic for the block itself. 207 For example the header timestamp should be greater than the block's parent 208 timestamp because the block was created *after* the parent block. 209 Additionally, the block's number should be directly following the parent 210 block's number since it is the next block in the sequence. 211 212 Parameters 213 ---------- 214 header : 215 Header to check for correctness. 216 parent_header : 217 Parent Header of the header to check for correctness 218 """ 219 parent_has_ommers = parent_header.ommers_hash != EMPTY_OMMER_HASH 220 ensure(header.timestamp > parent_header.timestamp, InvalidBlock) 221 ensure(header.number == parent_header.number + 1, InvalidBlock) 222 ensure( 223 check_gas_limit(header.gas_limit, parent_header.gas_limit), 224 InvalidBlock, 225 ) 226 ensure(len(header.extra_data) <= 32, InvalidBlock) 227 228 block_difficulty = calculate_block_difficulty( 229 header.number, 230 header.timestamp, 231 parent_header.timestamp, 232 parent_header.difficulty, 233 parent_has_ommers, 234 ) 235 ensure(header.difficulty == block_difficulty, InvalidBlock) 236 237 block_parent_hash = keccak256(rlp.encode(parent_header)) 238 ensure(header.parent_hash == block_parent_hash, InvalidBlock) 239 240 validate_proof_of_work(header) 241 242 243def generate_header_hash_for_pow(header: Header) -> Hash32: 244 """ 245 Generate rlp hash of the header which is to be used for Proof-of-Work 246 verification. 247 248 In other words, the PoW artefacts `mix_digest` and `nonce` are ignored 249 while calculating this hash. 250 251 A particular PoW is valid for a single hash, that hash is computed by 252 this function. The `nonce` and `mix_digest` are omitted from this hash 253 because they are being changed by miners in their search for a sufficient 254 proof-of-work. 255 256 Parameters 257 ---------- 258 header : 259 The header object for which the hash is to be generated. 260 261 Returns 262 ------- 263 hash : `Hash32` 264 The PoW valid rlp hash of the passed in header. 265 """ 266 header_data_without_pow_artefacts = [ 267 header.parent_hash, 268 header.ommers_hash, 269 header.coinbase, 270 header.state_root, 271 header.transactions_root, 272 header.receipt_root, 273 header.bloom, 274 header.difficulty, 275 header.number, 276 header.gas_limit, 277 header.gas_used, 278 header.timestamp, 279 header.extra_data, 280 ] 281 282 return rlp.rlp_hash(header_data_without_pow_artefacts) 283 284 285def validate_proof_of_work(header: Header) -> None: 286 """ 287 Validates the Proof of Work constraints. 288 289 In order to verify that a miner's proof-of-work is valid for a block, a 290 ``mix-digest`` and ``result`` are calculated using the ``hashimoto_light`` 291 hash function. The mix digest is a hash of the header and the nonce that 292 is passed through and it confirms whether or not proof-of-work was done 293 on the correct block. The result is the actual hash value of the block. 294 295 Parameters 296 ---------- 297 header : 298 Header of interest. 299 """ 300 header_hash = generate_header_hash_for_pow(header) 301 # TODO: Memoize this somewhere and read from that data instead of 302 # calculating cache for every block validation. 303 cache = generate_cache(header.number) 304 mix_digest, result = hashimoto_light( 305 header_hash, header.nonce, cache, dataset_size(header.number) 306 ) 307 308 ensure(mix_digest == header.mix_digest, InvalidBlock) 309 ensure( 310 Uint.from_be_bytes(result) <= (U256_CEIL_VALUE // header.difficulty), 311 InvalidBlock, 312 ) 313 314 315def check_transaction( 316 tx: Transaction, 317 gas_available: Uint, 318 chain_id: U64, 319) -> Address: 320 """ 321 Check if the transaction is includable in the block. 322 323 Parameters 324 ---------- 325 tx : 326 The transaction. 327 gas_available : 328 The gas remaining in the block. 329 chain_id : 330 The ID of the current chain. 331 332 Returns 333 ------- 334 sender_address : 335 The sender of the transaction. 336 337 Raises 338 ------ 339 InvalidBlock : 340 If the transaction is not includable. 341 """ 342 ensure(tx.gas <= gas_available, InvalidBlock) 343 sender_address = recover_sender(chain_id, tx) 344 345 return sender_address 346 347 348def make_receipt( 349 tx: Transaction, 350 error: Optional[Exception], 351 cumulative_gas_used: Uint, 352 logs: Tuple[Log, ...], 353) -> Union[Bytes, Receipt]: 354 """ 355 Make the receipt for a transaction that was executed. 356 357 Parameters 358 ---------- 359 tx : 360 The executed transaction. 361 error : 362 Error in the top level frame of the transaction, if any. 363 cumulative_gas_used : 364 The total gas used so far in the block after the transaction was 365 executed. 366 logs : 367 The logs produced by the transaction. 368 369 Returns 370 ------- 371 receipt : 372 The receipt for the transaction. 373 """ 374 receipt = Receipt( 375 succeeded=error is None, 376 cumulative_gas_used=cumulative_gas_used, 377 bloom=logs_bloom(logs), 378 logs=logs, 379 ) 380 381 if isinstance(tx, AccessListTransaction): 382 return b"\x01" + rlp.encode(receipt) 383 else: 384 return receipt 385 386 387def apply_body( 388 state: State, 389 block_hashes: List[Hash32], 390 coinbase: Address, 391 block_number: Uint, 392 block_gas_limit: Uint, 393 block_time: U256, 394 block_difficulty: Uint, 395 transactions: Tuple[Union[LegacyTransaction, Bytes], ...], 396 ommers: Tuple[Header, ...], 397 chain_id: U64, 398) -> Tuple[Uint, Root, Root, Bloom, State]: 399 """ 400 Executes a block. 401 402 Many of the contents of a block are stored in data structures called 403 tries. There is a transactions trie which is similar to a ledger of the 404 transactions stored in the current block. There is also a receipts trie 405 which stores the results of executing a transaction, like the post state 406 and gas used. This function creates and executes the block that is to be 407 added to the chain. 408 409 Parameters 410 ---------- 411 state : 412 Current account state. 413 block_hashes : 414 List of hashes of the previous 256 blocks in the order of 415 increasing block number. 416 coinbase : 417 Address of account which receives block reward and transaction fees. 418 block_number : 419 Position of the block within the chain. 420 block_gas_limit : 421 Initial amount of gas available for execution in this block. 422 block_time : 423 Time the block was produced, measured in seconds since the epoch. 424 block_difficulty : 425 Difficulty of the block. 426 transactions : 427 Transactions included in the block. 428 ommers : 429 Headers of ancestor blocks which are not direct parents (formerly 430 uncles.) 431 chain_id : 432 ID of the executing chain. 433 434 Returns 435 ------- 436 block_gas_used : `ethereum.base_types.Uint` 437 Gas used for executing all transactions. 438 transactions_root : `ethereum.fork_types.Root` 439 Trie root of all the transactions in the block. 440 receipt_root : `ethereum.fork_types.Root` 441 Trie root of all the receipts in the block. 442 block_logs_bloom : `Bloom` 443 Logs bloom of all the logs included in all the transactions of the 444 block. 445 state : `ethereum.fork_types.State` 446 State after all transactions have been executed. 447 """ 448 gas_available = block_gas_limit 449 transactions_trie: Trie[ 450 Bytes, Optional[Union[Bytes, LegacyTransaction]] 451 ] = Trie(secured=False, default=None) 452 receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = Trie( 453 secured=False, default=None 454 ) 455 block_logs: Tuple[Log, ...] = () 456 457 for i, tx in enumerate(map(decode_transaction, transactions)): 458 trie_set( 459 transactions_trie, rlp.encode(Uint(i)), encode_transaction(tx) 460 ) 461 462 sender_address = check_transaction(tx, gas_available, chain_id) 463 464 env = vm.Environment( 465 caller=sender_address, 466 origin=sender_address, 467 block_hashes=block_hashes, 468 coinbase=coinbase, 469 number=block_number, 470 gas_limit=block_gas_limit, 471 gas_price=tx.gas_price, 472 time=block_time, 473 difficulty=block_difficulty, 474 state=state, 475 chain_id=chain_id, 476 traces=[], 477 ) 478 479 gas_used, logs, error = process_transaction(env, tx) 480 gas_available -= gas_used 481 482 receipt = make_receipt( 483 tx, error, (block_gas_limit - gas_available), logs 484 ) 485 486 trie_set( 487 receipts_trie, 488 rlp.encode(Uint(i)), 489 receipt, 490 ) 491 492 block_logs += logs 493 494 pay_rewards(state, block_number, coinbase, ommers) 495 496 block_gas_used = block_gas_limit - gas_available 497 498 block_logs_bloom = logs_bloom(block_logs) 499 500 return ( 501 block_gas_used, 502 root(transactions_trie), 503 root(receipts_trie), 504 block_logs_bloom, 505 state, 506 ) 507 508 509def validate_ommers( 510 ommers: Tuple[Header, ...], block_header: Header, chain: BlockChain 511) -> None: 512 """ 513 Validates the ommers mentioned in the block. 514 515 An ommer block is a block that wasn't canonically added to the 516 blockchain because it wasn't validated as fast as the canonical block 517 but was mined at the same time. 518 519 To be considered valid, the ommers must adhere to the rules defined in 520 the Ethereum protocol. The maximum amount of ommers is 2 per block and 521 there cannot be duplicate ommers in a block. Many of the other ommer 522 constraints are listed in the in-line comments of this function. 523 524 Parameters 525 ---------- 526 ommers : 527 List of ommers mentioned in the current block. 528 block_header: 529 The header of current block. 530 chain : 531 History and current state. 532 """ 533 block_hash = rlp.rlp_hash(block_header) 534 535 ensure(rlp.rlp_hash(ommers) == block_header.ommers_hash, InvalidBlock) 536 537 if len(ommers) == 0: 538 # Nothing to validate 539 return 540 541 # Check that each ommer satisfies the constraints of a header 542 for ommer in ommers: 543 ensure(1 <= ommer.number < block_header.number, InvalidBlock) 544 ommer_parent_header = chain.blocks[ 545 -(block_header.number - ommer.number) - 1 546 ].header 547 validate_header(ommer, ommer_parent_header) 548 549 # Check that there can be only at most 2 ommers for a block. 550 ensure(len(ommers) <= 2, InvalidBlock) 551 552 ommers_hashes = [rlp.rlp_hash(ommer) for ommer in ommers] 553 # Check that there are no duplicates in the ommers of current block 554 ensure(len(ommers_hashes) == len(set(ommers_hashes)), InvalidBlock) 555 556 recent_canonical_blocks = chain.blocks[-(MAX_OMMER_DEPTH + 1) :] 557 recent_canonical_block_hashes = { 558 rlp.rlp_hash(block.header) for block in recent_canonical_blocks 559 } 560 recent_ommers_hashes: Set[Hash32] = set() 561 for block in recent_canonical_blocks: 562 recent_ommers_hashes = recent_ommers_hashes.union( 563 {rlp.rlp_hash(ommer) for ommer in block.ommers} 564 ) 565 566 for ommer_index, ommer in enumerate(ommers): 567 ommer_hash = ommers_hashes[ommer_index] 568 # The current block shouldn't be the ommer 569 ensure(ommer_hash != block_hash, InvalidBlock) 570 571 # Ommer shouldn't be one of the recent canonical blocks 572 ensure(ommer_hash not in recent_canonical_block_hashes, InvalidBlock) 573 574 # Ommer shouldn't be one of the uncles mentioned in the recent 575 # canonical blocks 576 ensure(ommer_hash not in recent_ommers_hashes, InvalidBlock) 577 578 # Ommer age with respect to the current block. For example, an age of 579 # 1 indicates that the ommer is a sibling of previous block. 580 ommer_age = block_header.number - ommer.number 581 ensure(1 <= ommer_age <= MAX_OMMER_DEPTH, InvalidBlock) 582 583 ensure( 584 ommer.parent_hash in recent_canonical_block_hashes, InvalidBlock 585 ) 586 ensure(ommer.parent_hash != block_header.parent_hash, InvalidBlock) 587 588 589def pay_rewards( 590 state: State, 591 block_number: Uint, 592 coinbase: Address, 593 ommers: Tuple[Header, ...], 594) -> None: 595 """ 596 Pay rewards to the block miner as well as the ommers miners. 597 598 The miner of the canonical block is rewarded with the predetermined 599 block reward, ``BLOCK_REWARD``, plus a variable award based off of the 600 number of ommer blocks that were mined around the same time, and included 601 in the canonical block's header. An ommer block is a block that wasn't 602 added to the canonical blockchain because it wasn't validated as fast as 603 the accepted block but was mined at the same time. Although not all blocks 604 that are mined are added to the canonical chain, miners are still paid a 605 reward for their efforts. This reward is called an ommer reward and is 606 calculated based on the number associated with the ommer block that they 607 mined. 608 609 Parameters 610 ---------- 611 state : 612 Current account state. 613 block_number : 614 Position of the block within the chain. 615 coinbase : 616 Address of account which receives block reward and transaction fees. 617 ommers : 618 List of ommers mentioned in the current block. 619 """ 620 miner_reward = BLOCK_REWARD + (len(ommers) * (BLOCK_REWARD // 32)) 621 create_ether(state, coinbase, miner_reward) 622 623 for ommer in ommers: 624 # Ommer age with respect to the current block. 625 ommer_age = U256(block_number - ommer.number) 626 ommer_miner_reward = ((8 - ommer_age) * BLOCK_REWARD) // 8 627 create_ether(state, ommer.coinbase, ommer_miner_reward) 628 629 630def process_transaction( 631 env: vm.Environment, tx: Transaction 632) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]: 633 """ 634 Execute a transaction against the provided environment. 635 636 This function processes the actions needed to execute a transaction. 637 It decrements the sender's account after calculating the gas fee and 638 refunds them the proper amount after execution. Calling contracts, 639 deploying code, and incrementing nonces are all examples of actions that 640 happen within this function or from a call made within this function. 641 642 Accounts that are marked for deletion are processed and destroyed after 643 execution. 644 645 Parameters 646 ---------- 647 env : 648 Environment for the Ethereum Virtual Machine. 649 tx : 650 Transaction to execute. 651 652 Returns 653 ------- 654 gas_left : `ethereum.base_types.U256` 655 Remaining gas after execution. 656 logs : `Tuple[ethereum.fork_types.Log, ...]` 657 Logs generated during execution. 658 """ 659 ensure(validate_transaction(tx), InvalidBlock) 660 661 sender = env.origin 662 sender_account = get_account(env.state, sender) 663 gas_fee = tx.gas * tx.gas_price 664 ensure(sender_account.nonce == tx.nonce, InvalidBlock) 665 ensure(sender_account.balance >= gas_fee + tx.value, InvalidBlock) 666 ensure(sender_account.code == bytearray(), InvalidBlock) 667 668 gas = tx.gas - calculate_intrinsic_cost(tx) 669 increment_nonce(env.state, sender) 670 sender_balance_after_gas_fee = sender_account.balance - gas_fee 671 set_account_balance(env.state, sender, sender_balance_after_gas_fee) 672 673 preaccessed_addresses = set() 674 preaccessed_storage_keys = set() 675 if isinstance(tx, AccessListTransaction): 676 for address, keys in tx.access_list: 677 preaccessed_addresses.add(address) 678 for key in keys: 679 preaccessed_storage_keys.add((address, key)) 680 681 message = prepare_message( 682 sender, 683 tx.to, 684 tx.value, 685 tx.data, 686 gas, 687 env, 688 preaccessed_addresses=frozenset(preaccessed_addresses), 689 preaccessed_storage_keys=frozenset(preaccessed_storage_keys), 690 ) 691 692 output = process_message_call(message, env) 693 694 gas_used = tx.gas - output.gas_left 695 gas_refund = min(gas_used // 2, output.refund_counter) 696 gas_refund_amount = (output.gas_left + gas_refund) * tx.gas_price 697 transaction_fee = (tx.gas - output.gas_left - gas_refund) * tx.gas_price 698 total_gas_used = gas_used - gas_refund 699 700 # refund gas 701 sender_balance_after_refund = ( 702 get_account(env.state, sender).balance + gas_refund_amount 703 ) 704 set_account_balance(env.state, sender, sender_balance_after_refund) 705 706 # transfer miner fees 707 coinbase_balance_after_mining_fee = ( 708 get_account(env.state, env.coinbase).balance + transaction_fee 709 ) 710 if coinbase_balance_after_mining_fee != 0: 711 set_account_balance( 712 env.state, env.coinbase, coinbase_balance_after_mining_fee 713 ) 714 elif account_exists_and_is_empty(env.state, env.coinbase): 715 destroy_account(env.state, env.coinbase) 716 717 for address in output.accounts_to_delete: 718 destroy_account(env.state, address) 719 720 for address in output.touched_accounts: 721 if account_exists_and_is_empty(env.state, address): 722 destroy_account(env.state, address) 723 724 return total_gas_used, output.logs, output.error 725 726 727def validate_transaction(tx: Transaction) -> bool: 728 """ 729 Verifies a transaction. 730 731 The gas in a transaction gets used to pay for the intrinsic cost of 732 operations, therefore if there is insufficient gas then it would not 733 be possible to execute a transaction and it will be declared invalid. 734 735 Additionally, the nonce of a transaction must not equal or exceed the 736 limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_. 737 In practice, defining the limit as ``2**64-1`` has no impact because 738 sending ``2**64-1`` transactions is improbable. It's not strictly 739 impossible though, ``2**64-1`` transactions is the entire capacity of the 740 Ethereum blockchain at 2022 gas limits for a little over 22 years. 741 742 Parameters 743 ---------- 744 tx : 745 Transaction to validate. 746 747 Returns 748 ------- 749 verified : `bool` 750 True if the transaction can be executed, or False otherwise. 751 """ 752 return calculate_intrinsic_cost(tx) <= tx.gas and tx.nonce < 2**64 - 1 753 754 755def calculate_intrinsic_cost(tx: Transaction) -> Uint: 756 """ 757 Calculates the gas that is charged before execution is started. 758 759 The intrinsic cost of the transaction is charged before execution has 760 begun. Functions/operations in the EVM cost money to execute so this 761 intrinsic cost is for the operations that need to be paid for as part of 762 the transaction. Data transfer, for example, is part of this intrinsic 763 cost. It costs ether to send data over the wire and that ether is 764 accounted for in the intrinsic cost calculated in this function. This 765 intrinsic cost must be calculated and paid for before execution in order 766 for all operations to be implemented. 767 768 Parameters 769 ---------- 770 tx : 771 Transaction to compute the intrinsic cost of. 772 773 Returns 774 ------- 775 verified : `ethereum.base_types.Uint` 776 The intrinsic cost of the transaction. 777 """ 778 data_cost = 0 779 780 for byte in tx.data: 781 if byte == 0: 782 data_cost += TX_DATA_COST_PER_ZERO 783 else: 784 data_cost += TX_DATA_COST_PER_NON_ZERO 785 786 if tx.to == Bytes0(b""): 787 create_cost = TX_CREATE_COST 788 else: 789 create_cost = 0 790 791 access_list_cost = 0 792 if isinstance(tx, AccessListTransaction): 793 for _address, keys in tx.access_list: 794 access_list_cost += TX_ACCESS_LIST_ADDRESS_COST 795 access_list_cost += len(keys) * TX_ACCESS_LIST_STORAGE_KEY_COST 796 797 return Uint(TX_BASE_COST + data_cost + create_cost + access_list_cost) 798 799 800def recover_sender(chain_id: U64, tx: Transaction) -> Address: 801 """ 802 Extracts the sender address from a transaction. 803 804 The v, r, and s values are the three parts that make up the signature 805 of a transaction. In order to recover the sender of a transaction the two 806 components needed are the signature (``v``, ``r``, and ``s``) and the 807 signing hash of the transaction. The sender's public key can be obtained 808 with these two values and therefore the sender address can be retrieved. 809 810 Parameters 811 ---------- 812 tx : 813 Transaction of interest. 814 chain_id : 815 ID of the executing chain. 816 817 Returns 818 ------- 819 sender : `ethereum.fork_types.Address` 820 The address of the account that signed the transaction. 821 """ 822 r, s = tx.r, tx.s 823 824 ensure(0 < r and r < SECP256K1N, InvalidBlock) 825 ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock) 826 827 if isinstance(tx, LegacyTransaction): 828 v = tx.v 829 if v == 27 or v == 28: 830 public_key = secp256k1_recover( 831 r, s, v - 27, signing_hash_pre155(tx) 832 ) 833 else: 834 ensure( 835 v == 35 + chain_id * 2 or v == 36 + chain_id * 2, InvalidBlock 836 ) 837 public_key = secp256k1_recover( 838 r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id) 839 ) 840 elif isinstance(tx, AccessListTransaction): 841 public_key = secp256k1_recover( 842 r, s, tx.y_parity, signing_hash_2930(tx) 843 ) 844 845 return Address(keccak256(public_key)[12:32]) 846 847 848def signing_hash_pre155(tx: Transaction) -> Hash32: 849 """ 850 Compute the hash of a transaction used in a legacy (pre EIP 155) signature. 851 852 Parameters 853 ---------- 854 tx : 855 Transaction of interest. 856 857 Returns 858 ------- 859 hash : `ethereum.crypto.hash.Hash32` 860 Hash of the transaction. 861 """ 862 return keccak256( 863 rlp.encode( 864 ( 865 tx.nonce, 866 tx.gas_price, 867 tx.gas, 868 tx.to, 869 tx.value, 870 tx.data, 871 ) 872 ) 873 ) 874 875 876def signing_hash_155(tx: Transaction, chain_id: U64) -> Hash32: 877 """ 878 Compute the hash of a transaction used in a EIP 155 signature. 879 880 Parameters 881 ---------- 882 tx : 883 Transaction of interest. 884 chain_id : 885 The id of the current chain. 886 887 Returns 888 ------- 889 hash : `ethereum.crypto.hash.Hash32` 890 Hash of the transaction. 891 """ 892 return keccak256( 893 rlp.encode( 894 ( 895 tx.nonce, 896 tx.gas_price, 897 tx.gas, 898 tx.to, 899 tx.value, 900 tx.data, 901 chain_id, 902 Uint(0), 903 Uint(0), 904 ) 905 ) 906 ) 907 908 909def signing_hash_2930(tx: AccessListTransaction) -> Hash32: 910 """ 911 Compute the hash of a transaction used in a EIP 2930 signature. 912 913 Parameters 914 ---------- 915 tx : 916 Transaction of interest. 917 918 Returns 919 ------- 920 hash : `ethereum.crypto.hash.Hash32` 921 Hash of the transaction. 922 """ 923 return keccak256( 924 b"\x01" 925 + rlp.encode( 926 ( 927 tx.chain_id, 928 tx.nonce, 929 tx.gas_price, 930 tx.gas, 931 tx.to, 932 tx.value, 933 tx.data, 934 tx.access_list, 935 ) 936 ) 937 ) 938 939 940def compute_header_hash(header: Header) -> Hash32: 941 """ 942 Computes the hash of a block header. 943 944 The header hash of a block is the canonical hash that is used to refer 945 to a specific block and completely distinguishes a block from another. 946 947 ``keccak256`` is a function that produces a 256 bit hash of any input. 948 It also takes in any number of bytes as an input and produces a single 949 hash for them. A hash is a completely unique output for a single input. 950 So an input corresponds to one unique hash that can be used to identify 951 the input exactly. 952 953 Prior to using the ``keccak256`` hash function, the header must be 954 encoded using the Recursive-Length Prefix. See :ref:`rlp`. 955 RLP encoding the header converts it into a space-efficient format that 956 allows for easy transfer of data between nodes. The purpose of RLP is to 957 encode arbitrarily nested arrays of binary data, and RLP is the primary 958 encoding method used to serialize objects in Ethereum's execution layer. 959 The only purpose of RLP is to encode structure; encoding specific data 960 types (e.g. strings, floats) is left up to higher-order protocols. 961 962 Parameters 963 ---------- 964 header : 965 Header of interest. 966 967 Returns 968 ------- 969 hash : `ethereum.crypto.hash.Hash32` 970 Hash of the header. 971 """ 972 return keccak256(rlp.encode(header)) 973 974 975def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: 976 """ 977 Validates the gas limit for a block. 978 979 The bounds of the gas limit, ``max_adjustment_delta``, is set as the 980 quotient of the parent block's gas limit and the 981 ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is 982 passed through as a parameter is greater than or equal to the *sum* of 983 the parent's gas and the adjustment delta then the limit for gas is too 984 high and fails this function's check. Similarly, if the limit is less 985 than or equal to the *difference* of the parent's gas and the adjustment 986 delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's 987 check fails because the gas limit doesn't allow for a sufficient or 988 reasonable amount of gas to be used on a block. 989 990 Parameters 991 ---------- 992 gas_limit : 993 Gas limit to validate. 994 995 parent_gas_limit : 996 Gas limit of the parent block. 997 998 Returns 999 ------- 1000 check : `bool` 1001 True if gas limit constraints are satisfied, False otherwise. 1002 """ 1003 max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR 1004 if gas_limit >= parent_gas_limit + max_adjustment_delta: 1005 return False 1006 if gas_limit <= parent_gas_limit - max_adjustment_delta: 1007 return False 1008 if gas_limit < GAS_LIMIT_MINIMUM: 1009 return False 1010 1011 return True 1012 1013 1014def calculate_block_difficulty( 1015 block_number: Uint, 1016 block_timestamp: U256, 1017 parent_timestamp: U256, 1018 parent_difficulty: Uint, 1019 parent_has_ommers: bool, 1020) -> Uint: 1021 """ 1022 Computes difficulty of a block using its header and parent header. 1023 1024 The difficulty is determined by the time the block was created after its 1025 parent. The ``offset`` is calculated using the parent block's difficulty, 1026 ``parent_difficulty``, and the timestamp between blocks. This offset is 1027 then added to the parent difficulty and is stored as the ``difficulty`` 1028 variable. If the time between the block and its parent is too short, the 1029 offset will result in a positive number thus making the sum of 1030 ``parent_difficulty`` and ``offset`` to be a greater value in order to 1031 avoid mass forking. But, if the time is long enough, then the offset 1032 results in a negative value making the block less difficult than 1033 its parent. 1034 1035 The base standard for a block's difficulty is the predefined value 1036 set for the genesis block since it has no parent. So, a block 1037 can't be less difficult than the genesis block, therefore each block's 1038 difficulty is set to the maximum value between the calculated 1039 difficulty and the ``GENESIS_DIFFICULTY``. 1040 1041 Parameters 1042 ---------- 1043 block_number : 1044 Block number of the block. 1045 block_timestamp : 1046 Timestamp of the block. 1047 parent_timestamp : 1048 Timestamp of the parent block. 1049 parent_difficulty : 1050 difficulty of the parent block. 1051 parent_has_ommers: 1052 does the parent have ommers. 1053 1054 Returns 1055 ------- 1056 difficulty : `ethereum.base_types.Uint` 1057 Computed difficulty for a block. 1058 """ 1059 offset = ( 1060 int(parent_difficulty) 1061 // 2048 1062 * max( 1063 (2 if parent_has_ommers else 1) 1064 - int(block_timestamp - parent_timestamp) // 9, 1065 -99, 1066 ) 1067 ) 1068 difficulty = int(parent_difficulty) + offset 1069 # Historical Note: The difficulty bomb was not present in Ethereum at the 1070 # start of Frontier, but was added shortly after launch. However since the 1071 # bomb has no effect prior to block 200000 we pretend it existed from 1072 # genesis. 1073 # See https://github.com/ethereum/go-ethereum/pull/1588 1074 num_bomb_periods = ((int(block_number) - BOMB_DELAY_BLOCKS) // 100000) - 2 1075 if num_bomb_periods >= 0: 1076 difficulty += 2**num_bomb_periods 1077 1078 # Some clients raise the difficulty to `MINIMUM_DIFFICULTY` prior to adding 1079 # the bomb. This bug does not matter because the difficulty is always much 1080 # greater than `MINIMUM_DIFFICULTY` on Mainnet. 1081 return Uint(max(difficulty, MINIMUM_DIFFICULTY))
73@dataclass 74class BlockChain: 75 """ 76 History and current state of the block chain. 77 """ 78 79 blocks: List[Block] 80 state: State 81 chain_id: U64
History and current state of the block chain.
84def apply_fork(old: BlockChain) -> BlockChain: 85 """ 86 Transforms the state from the previous hard fork (`old`) into the block 87 chain object for this hard fork and returns it. 88 89 When forks need to implement an irregular state transition, this function 90 is used to handle the irregularity. See the :ref:`DAO Fork <dao-fork>` for 91 an example. 92 93 Parameters 94 ---------- 95 old : 96 Previous block chain object. 97 98 Returns 99 ------- 100 new : `BlockChain` 101 Upgraded block chain object for this hard fork. 102 """ 103 return old
Transforms the state from the previous hard fork (old
) into the block
chain object for this hard fork and returns it.
When forks need to implement an irregular state transition, this function
is used to handle the irregularity. See the :ref:DAO Fork <dao-fork>
for
an example.
Parameters
old : Previous block chain object.
Returns
new : BlockChain
Upgraded block chain object for this hard fork.
106def get_last_256_block_hashes(chain: BlockChain) -> List[Hash32]: 107 """ 108 Obtain the list of hashes of the previous 256 blocks in order of 109 increasing block number. 110 111 This function will return less hashes for the first 256 blocks. 112 113 The ``BLOCKHASH`` opcode needs to access the latest hashes on the chain, 114 therefore this function retrieves them. 115 116 Parameters 117 ---------- 118 chain : 119 History and current state. 120 121 Returns 122 ------- 123 recent_block_hashes : `List[Hash32]` 124 Hashes of the recent 256 blocks in order of increasing block number. 125 """ 126 recent_blocks = chain.blocks[-255:] 127 # TODO: This function has not been tested rigorously 128 if len(recent_blocks) == 0: 129 return [] 130 131 recent_block_hashes = [] 132 133 for block in recent_blocks: 134 prev_block_hash = block.header.parent_hash 135 recent_block_hashes.append(prev_block_hash) 136 137 # We are computing the hash only for the most recent block and not for 138 # the rest of the blocks as they have successors which have the hash of 139 # the current block as parent hash. 140 most_recent_block_hash = keccak256(rlp.encode(recent_blocks[-1].header)) 141 recent_block_hashes.append(most_recent_block_hash) 142 143 return recent_block_hashes
Obtain the list of hashes of the previous 256 blocks in order of increasing block number.
This function will return less hashes for the first 256 blocks.
The BLOCKHASH
opcode needs to access the latest hashes on the chain,
therefore this function retrieves them.
Parameters
chain : History and current state.
Returns
recent_block_hashes : List[Hash32]
Hashes of the recent 256 blocks in order of increasing block number.
146def state_transition(chain: BlockChain, block: Block) -> None: 147 """ 148 Attempts to apply a block to an existing block chain. 149 150 All parts of the block's contents need to be verified before being added 151 to the chain. Blocks are verified by ensuring that the contents of the 152 block make logical sense with the contents of the parent block. The 153 information in the block's header must also match the corresponding 154 information in the block. 155 156 To implement Ethereum, in theory clients are only required to store the 157 most recent 255 blocks of the chain since as far as execution is 158 concerned, only those blocks are accessed. Practically, however, clients 159 should store more blocks to handle reorgs. 160 161 Parameters 162 ---------- 163 chain : 164 History and current state. 165 block : 166 Block to apply to `chain`. 167 """ 168 parent_header = chain.blocks[-1].header 169 validate_header(block.header, parent_header) 170 validate_ommers(block.ommers, block.header, chain) 171 ( 172 gas_used, 173 transactions_root, 174 receipt_root, 175 block_logs_bloom, 176 state, 177 ) = apply_body( 178 chain.state, 179 get_last_256_block_hashes(chain), 180 block.header.coinbase, 181 block.header.number, 182 block.header.gas_limit, 183 block.header.timestamp, 184 block.header.difficulty, 185 block.transactions, 186 block.ommers, 187 chain.chain_id, 188 ) 189 ensure(gas_used == block.header.gas_used, InvalidBlock) 190 ensure(transactions_root == block.header.transactions_root, InvalidBlock) 191 ensure(state_root(state) == block.header.state_root, InvalidBlock) 192 ensure(receipt_root == block.header.receipt_root, InvalidBlock) 193 ensure(block_logs_bloom == block.header.bloom, InvalidBlock) 194 195 chain.blocks.append(block) 196 if len(chain.blocks) > 255: 197 # Real clients have to store more blocks to deal with reorgs, but the 198 # protocol only requires the last 255 199 chain.blocks = chain.blocks[-255:]
Attempts to apply a block to an existing block chain.
All parts of the block's contents need to be verified before being added to the chain. Blocks are verified by ensuring that the contents of the block make logical sense with the contents of the parent block. The information in the block's header must also match the corresponding information in the block.
To implement Ethereum, in theory clients are only required to store the most recent 255 blocks of the chain since as far as execution is concerned, only those blocks are accessed. Practically, however, clients should store more blocks to handle reorgs.
Parameters
chain :
History and current state.
block :
Block to apply to chain
.
202def validate_header(header: Header, parent_header: Header) -> None: 203 """ 204 Verifies a block header. 205 206 In order to consider a block's header valid, the logic for the 207 quantities in the header should match the logic for the block itself. 208 For example the header timestamp should be greater than the block's parent 209 timestamp because the block was created *after* the parent block. 210 Additionally, the block's number should be directly following the parent 211 block's number since it is the next block in the sequence. 212 213 Parameters 214 ---------- 215 header : 216 Header to check for correctness. 217 parent_header : 218 Parent Header of the header to check for correctness 219 """ 220 parent_has_ommers = parent_header.ommers_hash != EMPTY_OMMER_HASH 221 ensure(header.timestamp > parent_header.timestamp, InvalidBlock) 222 ensure(header.number == parent_header.number + 1, InvalidBlock) 223 ensure( 224 check_gas_limit(header.gas_limit, parent_header.gas_limit), 225 InvalidBlock, 226 ) 227 ensure(len(header.extra_data) <= 32, InvalidBlock) 228 229 block_difficulty = calculate_block_difficulty( 230 header.number, 231 header.timestamp, 232 parent_header.timestamp, 233 parent_header.difficulty, 234 parent_has_ommers, 235 ) 236 ensure(header.difficulty == block_difficulty, InvalidBlock) 237 238 block_parent_hash = keccak256(rlp.encode(parent_header)) 239 ensure(header.parent_hash == block_parent_hash, InvalidBlock) 240 241 validate_proof_of_work(header)
Verifies a block header.
In order to consider a block's header valid, the logic for the quantities in the header should match the logic for the block itself. For example the header timestamp should be greater than the block's parent timestamp because the block was created after the parent block. Additionally, the block's number should be directly following the parent block's number since it is the next block in the sequence.
Parameters
header : Header to check for correctness. parent_header : Parent Header of the header to check for correctness
244def generate_header_hash_for_pow(header: Header) -> Hash32: 245 """ 246 Generate rlp hash of the header which is to be used for Proof-of-Work 247 verification. 248 249 In other words, the PoW artefacts `mix_digest` and `nonce` are ignored 250 while calculating this hash. 251 252 A particular PoW is valid for a single hash, that hash is computed by 253 this function. The `nonce` and `mix_digest` are omitted from this hash 254 because they are being changed by miners in their search for a sufficient 255 proof-of-work. 256 257 Parameters 258 ---------- 259 header : 260 The header object for which the hash is to be generated. 261 262 Returns 263 ------- 264 hash : `Hash32` 265 The PoW valid rlp hash of the passed in header. 266 """ 267 header_data_without_pow_artefacts = [ 268 header.parent_hash, 269 header.ommers_hash, 270 header.coinbase, 271 header.state_root, 272 header.transactions_root, 273 header.receipt_root, 274 header.bloom, 275 header.difficulty, 276 header.number, 277 header.gas_limit, 278 header.gas_used, 279 header.timestamp, 280 header.extra_data, 281 ] 282 283 return rlp.rlp_hash(header_data_without_pow_artefacts)
Generate rlp hash of the header which is to be used for Proof-of-Work verification.
In other words, the PoW artefacts mix_digest
and nonce
are ignored
while calculating this hash.
A particular PoW is valid for a single hash, that hash is computed by
this function. The nonce
and mix_digest
are omitted from this hash
because they are being changed by miners in their search for a sufficient
proof-of-work.
Parameters
header : The header object for which the hash is to be generated.
Returns
hash : Hash32
The PoW valid rlp hash of the passed in header.
286def validate_proof_of_work(header: Header) -> None: 287 """ 288 Validates the Proof of Work constraints. 289 290 In order to verify that a miner's proof-of-work is valid for a block, a 291 ``mix-digest`` and ``result`` are calculated using the ``hashimoto_light`` 292 hash function. The mix digest is a hash of the header and the nonce that 293 is passed through and it confirms whether or not proof-of-work was done 294 on the correct block. The result is the actual hash value of the block. 295 296 Parameters 297 ---------- 298 header : 299 Header of interest. 300 """ 301 header_hash = generate_header_hash_for_pow(header) 302 # TODO: Memoize this somewhere and read from that data instead of 303 # calculating cache for every block validation. 304 cache = generate_cache(header.number) 305 mix_digest, result = hashimoto_light( 306 header_hash, header.nonce, cache, dataset_size(header.number) 307 ) 308 309 ensure(mix_digest == header.mix_digest, InvalidBlock) 310 ensure( 311 Uint.from_be_bytes(result) <= (U256_CEIL_VALUE // header.difficulty), 312 InvalidBlock, 313 )
Validates the Proof of Work constraints.
In order to verify that a miner's proof-of-work is valid for a block, a
mix-digest
and result
are calculated using the hashimoto_light
hash function. The mix digest is a hash of the header and the nonce that
is passed through and it confirms whether or not proof-of-work was done
on the correct block. The result is the actual hash value of the block.
Parameters
header : Header of interest.
316def check_transaction( 317 tx: Transaction, 318 gas_available: Uint, 319 chain_id: U64, 320) -> Address: 321 """ 322 Check if the transaction is includable in the block. 323 324 Parameters 325 ---------- 326 tx : 327 The transaction. 328 gas_available : 329 The gas remaining in the block. 330 chain_id : 331 The ID of the current chain. 332 333 Returns 334 ------- 335 sender_address : 336 The sender of the transaction. 337 338 Raises 339 ------ 340 InvalidBlock : 341 If the transaction is not includable. 342 """ 343 ensure(tx.gas <= gas_available, InvalidBlock) 344 sender_address = recover_sender(chain_id, tx) 345 346 return sender_address
Check if the transaction is includable in the block.
Parameters
tx : The transaction. gas_available : The gas remaining in the block. chain_id : The ID of the current chain.
Returns
sender_address : The sender of the transaction.
Raises
InvalidBlock : If the transaction is not includable.
349def make_receipt( 350 tx: Transaction, 351 error: Optional[Exception], 352 cumulative_gas_used: Uint, 353 logs: Tuple[Log, ...], 354) -> Union[Bytes, Receipt]: 355 """ 356 Make the receipt for a transaction that was executed. 357 358 Parameters 359 ---------- 360 tx : 361 The executed transaction. 362 error : 363 Error in the top level frame of the transaction, if any. 364 cumulative_gas_used : 365 The total gas used so far in the block after the transaction was 366 executed. 367 logs : 368 The logs produced by the transaction. 369 370 Returns 371 ------- 372 receipt : 373 The receipt for the transaction. 374 """ 375 receipt = Receipt( 376 succeeded=error is None, 377 cumulative_gas_used=cumulative_gas_used, 378 bloom=logs_bloom(logs), 379 logs=logs, 380 ) 381 382 if isinstance(tx, AccessListTransaction): 383 return b"\x01" + rlp.encode(receipt) 384 else: 385 return receipt
Make the receipt for a transaction that was executed.
Parameters
tx : The executed transaction. error : Error in the top level frame of the transaction, if any. cumulative_gas_used : The total gas used so far in the block after the transaction was executed. logs : The logs produced by the transaction.
Returns
receipt : The receipt for the transaction.
388def apply_body( 389 state: State, 390 block_hashes: List[Hash32], 391 coinbase: Address, 392 block_number: Uint, 393 block_gas_limit: Uint, 394 block_time: U256, 395 block_difficulty: Uint, 396 transactions: Tuple[Union[LegacyTransaction, Bytes], ...], 397 ommers: Tuple[Header, ...], 398 chain_id: U64, 399) -> Tuple[Uint, Root, Root, Bloom, State]: 400 """ 401 Executes a block. 402 403 Many of the contents of a block are stored in data structures called 404 tries. There is a transactions trie which is similar to a ledger of the 405 transactions stored in the current block. There is also a receipts trie 406 which stores the results of executing a transaction, like the post state 407 and gas used. This function creates and executes the block that is to be 408 added to the chain. 409 410 Parameters 411 ---------- 412 state : 413 Current account state. 414 block_hashes : 415 List of hashes of the previous 256 blocks in the order of 416 increasing block number. 417 coinbase : 418 Address of account which receives block reward and transaction fees. 419 block_number : 420 Position of the block within the chain. 421 block_gas_limit : 422 Initial amount of gas available for execution in this block. 423 block_time : 424 Time the block was produced, measured in seconds since the epoch. 425 block_difficulty : 426 Difficulty of the block. 427 transactions : 428 Transactions included in the block. 429 ommers : 430 Headers of ancestor blocks which are not direct parents (formerly 431 uncles.) 432 chain_id : 433 ID of the executing chain. 434 435 Returns 436 ------- 437 block_gas_used : `ethereum.base_types.Uint` 438 Gas used for executing all transactions. 439 transactions_root : `ethereum.fork_types.Root` 440 Trie root of all the transactions in the block. 441 receipt_root : `ethereum.fork_types.Root` 442 Trie root of all the receipts in the block. 443 block_logs_bloom : `Bloom` 444 Logs bloom of all the logs included in all the transactions of the 445 block. 446 state : `ethereum.fork_types.State` 447 State after all transactions have been executed. 448 """ 449 gas_available = block_gas_limit 450 transactions_trie: Trie[ 451 Bytes, Optional[Union[Bytes, LegacyTransaction]] 452 ] = Trie(secured=False, default=None) 453 receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = Trie( 454 secured=False, default=None 455 ) 456 block_logs: Tuple[Log, ...] = () 457 458 for i, tx in enumerate(map(decode_transaction, transactions)): 459 trie_set( 460 transactions_trie, rlp.encode(Uint(i)), encode_transaction(tx) 461 ) 462 463 sender_address = check_transaction(tx, gas_available, chain_id) 464 465 env = vm.Environment( 466 caller=sender_address, 467 origin=sender_address, 468 block_hashes=block_hashes, 469 coinbase=coinbase, 470 number=block_number, 471 gas_limit=block_gas_limit, 472 gas_price=tx.gas_price, 473 time=block_time, 474 difficulty=block_difficulty, 475 state=state, 476 chain_id=chain_id, 477 traces=[], 478 ) 479 480 gas_used, logs, error = process_transaction(env, tx) 481 gas_available -= gas_used 482 483 receipt = make_receipt( 484 tx, error, (block_gas_limit - gas_available), logs 485 ) 486 487 trie_set( 488 receipts_trie, 489 rlp.encode(Uint(i)), 490 receipt, 491 ) 492 493 block_logs += logs 494 495 pay_rewards(state, block_number, coinbase, ommers) 496 497 block_gas_used = block_gas_limit - gas_available 498 499 block_logs_bloom = logs_bloom(block_logs) 500 501 return ( 502 block_gas_used, 503 root(transactions_trie), 504 root(receipts_trie), 505 block_logs_bloom, 506 state, 507 )
Executes a block.
Many of the contents of a block are stored in data structures called tries. There is a transactions trie which is similar to a ledger of the transactions stored in the current block. There is also a receipts trie which stores the results of executing a transaction, like the post state and gas used. This function creates and executes the block that is to be added to the chain.
Parameters
state : Current account state. block_hashes : List of hashes of the previous 256 blocks in the order of increasing block number. coinbase : Address of account which receives block reward and transaction fees. block_number : Position of the block within the chain. block_gas_limit : Initial amount of gas available for execution in this block. block_time : Time the block was produced, measured in seconds since the epoch. block_difficulty : Difficulty of the block. transactions : Transactions included in the block. ommers : Headers of ancestor blocks which are not direct parents (formerly uncles.) chain_id : ID of the executing chain.
Returns
block_gas_used : ethereum.base_types.Uint
Gas used for executing all transactions.
transactions_root : ethereum.fork_types.Root
Trie root of all the transactions in the block.
receipt_root : ethereum.fork_types.Root
Trie root of all the receipts in the block.
block_logs_bloom : Bloom
Logs bloom of all the logs included in all the transactions of the
block.
state : ethereum.fork_types.State
State after all transactions have been executed.
510def validate_ommers( 511 ommers: Tuple[Header, ...], block_header: Header, chain: BlockChain 512) -> None: 513 """ 514 Validates the ommers mentioned in the block. 515 516 An ommer block is a block that wasn't canonically added to the 517 blockchain because it wasn't validated as fast as the canonical block 518 but was mined at the same time. 519 520 To be considered valid, the ommers must adhere to the rules defined in 521 the Ethereum protocol. The maximum amount of ommers is 2 per block and 522 there cannot be duplicate ommers in a block. Many of the other ommer 523 constraints are listed in the in-line comments of this function. 524 525 Parameters 526 ---------- 527 ommers : 528 List of ommers mentioned in the current block. 529 block_header: 530 The header of current block. 531 chain : 532 History and current state. 533 """ 534 block_hash = rlp.rlp_hash(block_header) 535 536 ensure(rlp.rlp_hash(ommers) == block_header.ommers_hash, InvalidBlock) 537 538 if len(ommers) == 0: 539 # Nothing to validate 540 return 541 542 # Check that each ommer satisfies the constraints of a header 543 for ommer in ommers: 544 ensure(1 <= ommer.number < block_header.number, InvalidBlock) 545 ommer_parent_header = chain.blocks[ 546 -(block_header.number - ommer.number) - 1 547 ].header 548 validate_header(ommer, ommer_parent_header) 549 550 # Check that there can be only at most 2 ommers for a block. 551 ensure(len(ommers) <= 2, InvalidBlock) 552 553 ommers_hashes = [rlp.rlp_hash(ommer) for ommer in ommers] 554 # Check that there are no duplicates in the ommers of current block 555 ensure(len(ommers_hashes) == len(set(ommers_hashes)), InvalidBlock) 556 557 recent_canonical_blocks = chain.blocks[-(MAX_OMMER_DEPTH + 1) :] 558 recent_canonical_block_hashes = { 559 rlp.rlp_hash(block.header) for block in recent_canonical_blocks 560 } 561 recent_ommers_hashes: Set[Hash32] = set() 562 for block in recent_canonical_blocks: 563 recent_ommers_hashes = recent_ommers_hashes.union( 564 {rlp.rlp_hash(ommer) for ommer in block.ommers} 565 ) 566 567 for ommer_index, ommer in enumerate(ommers): 568 ommer_hash = ommers_hashes[ommer_index] 569 # The current block shouldn't be the ommer 570 ensure(ommer_hash != block_hash, InvalidBlock) 571 572 # Ommer shouldn't be one of the recent canonical blocks 573 ensure(ommer_hash not in recent_canonical_block_hashes, InvalidBlock) 574 575 # Ommer shouldn't be one of the uncles mentioned in the recent 576 # canonical blocks 577 ensure(ommer_hash not in recent_ommers_hashes, InvalidBlock) 578 579 # Ommer age with respect to the current block. For example, an age of 580 # 1 indicates that the ommer is a sibling of previous block. 581 ommer_age = block_header.number - ommer.number 582 ensure(1 <= ommer_age <= MAX_OMMER_DEPTH, InvalidBlock) 583 584 ensure( 585 ommer.parent_hash in recent_canonical_block_hashes, InvalidBlock 586 ) 587 ensure(ommer.parent_hash != block_header.parent_hash, InvalidBlock)
Validates the ommers mentioned in the block.
An ommer block is a block that wasn't canonically added to the blockchain because it wasn't validated as fast as the canonical block but was mined at the same time.
To be considered valid, the ommers must adhere to the rules defined in the Ethereum protocol. The maximum amount of ommers is 2 per block and there cannot be duplicate ommers in a block. Many of the other ommer constraints are listed in the in-line comments of this function.
Parameters
ommers : List of ommers mentioned in the current block. block_header: The header of current block. chain : History and current state.
590def pay_rewards( 591 state: State, 592 block_number: Uint, 593 coinbase: Address, 594 ommers: Tuple[Header, ...], 595) -> None: 596 """ 597 Pay rewards to the block miner as well as the ommers miners. 598 599 The miner of the canonical block is rewarded with the predetermined 600 block reward, ``BLOCK_REWARD``, plus a variable award based off of the 601 number of ommer blocks that were mined around the same time, and included 602 in the canonical block's header. An ommer block is a block that wasn't 603 added to the canonical blockchain because it wasn't validated as fast as 604 the accepted block but was mined at the same time. Although not all blocks 605 that are mined are added to the canonical chain, miners are still paid a 606 reward for their efforts. This reward is called an ommer reward and is 607 calculated based on the number associated with the ommer block that they 608 mined. 609 610 Parameters 611 ---------- 612 state : 613 Current account state. 614 block_number : 615 Position of the block within the chain. 616 coinbase : 617 Address of account which receives block reward and transaction fees. 618 ommers : 619 List of ommers mentioned in the current block. 620 """ 621 miner_reward = BLOCK_REWARD + (len(ommers) * (BLOCK_REWARD // 32)) 622 create_ether(state, coinbase, miner_reward) 623 624 for ommer in ommers: 625 # Ommer age with respect to the current block. 626 ommer_age = U256(block_number - ommer.number) 627 ommer_miner_reward = ((8 - ommer_age) * BLOCK_REWARD) // 8 628 create_ether(state, ommer.coinbase, ommer_miner_reward)
Pay rewards to the block miner as well as the ommers miners.
The miner of the canonical block is rewarded with the predetermined
block reward, BLOCK_REWARD
, plus a variable award based off of the
number of ommer blocks that were mined around the same time, and included
in the canonical block's header. An ommer block is a block that wasn't
added to the canonical blockchain because it wasn't validated as fast as
the accepted block but was mined at the same time. Although not all blocks
that are mined are added to the canonical chain, miners are still paid a
reward for their efforts. This reward is called an ommer reward and is
calculated based on the number associated with the ommer block that they
mined.
Parameters
state : Current account state. block_number : Position of the block within the chain. coinbase : Address of account which receives block reward and transaction fees. ommers : List of ommers mentioned in the current block.
631def process_transaction( 632 env: vm.Environment, tx: Transaction 633) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]: 634 """ 635 Execute a transaction against the provided environment. 636 637 This function processes the actions needed to execute a transaction. 638 It decrements the sender's account after calculating the gas fee and 639 refunds them the proper amount after execution. Calling contracts, 640 deploying code, and incrementing nonces are all examples of actions that 641 happen within this function or from a call made within this function. 642 643 Accounts that are marked for deletion are processed and destroyed after 644 execution. 645 646 Parameters 647 ---------- 648 env : 649 Environment for the Ethereum Virtual Machine. 650 tx : 651 Transaction to execute. 652 653 Returns 654 ------- 655 gas_left : `ethereum.base_types.U256` 656 Remaining gas after execution. 657 logs : `Tuple[ethereum.fork_types.Log, ...]` 658 Logs generated during execution. 659 """ 660 ensure(validate_transaction(tx), InvalidBlock) 661 662 sender = env.origin 663 sender_account = get_account(env.state, sender) 664 gas_fee = tx.gas * tx.gas_price 665 ensure(sender_account.nonce == tx.nonce, InvalidBlock) 666 ensure(sender_account.balance >= gas_fee + tx.value, InvalidBlock) 667 ensure(sender_account.code == bytearray(), InvalidBlock) 668 669 gas = tx.gas - calculate_intrinsic_cost(tx) 670 increment_nonce(env.state, sender) 671 sender_balance_after_gas_fee = sender_account.balance - gas_fee 672 set_account_balance(env.state, sender, sender_balance_after_gas_fee) 673 674 preaccessed_addresses = set() 675 preaccessed_storage_keys = set() 676 if isinstance(tx, AccessListTransaction): 677 for address, keys in tx.access_list: 678 preaccessed_addresses.add(address) 679 for key in keys: 680 preaccessed_storage_keys.add((address, key)) 681 682 message = prepare_message( 683 sender, 684 tx.to, 685 tx.value, 686 tx.data, 687 gas, 688 env, 689 preaccessed_addresses=frozenset(preaccessed_addresses), 690 preaccessed_storage_keys=frozenset(preaccessed_storage_keys), 691 ) 692 693 output = process_message_call(message, env) 694 695 gas_used = tx.gas - output.gas_left 696 gas_refund = min(gas_used // 2, output.refund_counter) 697 gas_refund_amount = (output.gas_left + gas_refund) * tx.gas_price 698 transaction_fee = (tx.gas - output.gas_left - gas_refund) * tx.gas_price 699 total_gas_used = gas_used - gas_refund 700 701 # refund gas 702 sender_balance_after_refund = ( 703 get_account(env.state, sender).balance + gas_refund_amount 704 ) 705 set_account_balance(env.state, sender, sender_balance_after_refund) 706 707 # transfer miner fees 708 coinbase_balance_after_mining_fee = ( 709 get_account(env.state, env.coinbase).balance + transaction_fee 710 ) 711 if coinbase_balance_after_mining_fee != 0: 712 set_account_balance( 713 env.state, env.coinbase, coinbase_balance_after_mining_fee 714 ) 715 elif account_exists_and_is_empty(env.state, env.coinbase): 716 destroy_account(env.state, env.coinbase) 717 718 for address in output.accounts_to_delete: 719 destroy_account(env.state, address) 720 721 for address in output.touched_accounts: 722 if account_exists_and_is_empty(env.state, address): 723 destroy_account(env.state, address) 724 725 return total_gas_used, output.logs, output.error
Execute a transaction against the provided environment.
This function processes the actions needed to execute a transaction. It decrements the sender's account after calculating the gas fee and refunds them the proper amount after execution. Calling contracts, deploying code, and incrementing nonces are all examples of actions that happen within this function or from a call made within this function.
Accounts that are marked for deletion are processed and destroyed after execution.
Parameters
env : Environment for the Ethereum Virtual Machine. tx : Transaction to execute.
Returns
gas_left : ethereum.base_types.U256
Remaining gas after execution.
logs : Tuple[ethereum.fork_types.Log, ...]
Logs generated during execution.
728def validate_transaction(tx: Transaction) -> bool: 729 """ 730 Verifies a transaction. 731 732 The gas in a transaction gets used to pay for the intrinsic cost of 733 operations, therefore if there is insufficient gas then it would not 734 be possible to execute a transaction and it will be declared invalid. 735 736 Additionally, the nonce of a transaction must not equal or exceed the 737 limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_. 738 In practice, defining the limit as ``2**64-1`` has no impact because 739 sending ``2**64-1`` transactions is improbable. It's not strictly 740 impossible though, ``2**64-1`` transactions is the entire capacity of the 741 Ethereum blockchain at 2022 gas limits for a little over 22 years. 742 743 Parameters 744 ---------- 745 tx : 746 Transaction to validate. 747 748 Returns 749 ------- 750 verified : `bool` 751 True if the transaction can be executed, or False otherwise. 752 """ 753 return calculate_intrinsic_cost(tx) <= tx.gas and tx.nonce < 2**64 - 1
Verifies a transaction.
The gas in a transaction gets used to pay for the intrinsic cost of operations, therefore if there is insufficient gas then it would not be possible to execute a transaction and it will be declared invalid.
Additionally, the nonce of a transaction must not equal or exceed the
limit defined in EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>
_.
In practice, defining the limit as 2**64-1
has no impact because
sending 2**64-1
transactions is improbable. It's not strictly
impossible though, 2**64-1
transactions is the entire capacity of the
Ethereum blockchain at 2022 gas limits for a little over 22 years.
Parameters
tx : Transaction to validate.
Returns
verified : bool
True if the transaction can be executed, or False otherwise.
756def calculate_intrinsic_cost(tx: Transaction) -> Uint: 757 """ 758 Calculates the gas that is charged before execution is started. 759 760 The intrinsic cost of the transaction is charged before execution has 761 begun. Functions/operations in the EVM cost money to execute so this 762 intrinsic cost is for the operations that need to be paid for as part of 763 the transaction. Data transfer, for example, is part of this intrinsic 764 cost. It costs ether to send data over the wire and that ether is 765 accounted for in the intrinsic cost calculated in this function. This 766 intrinsic cost must be calculated and paid for before execution in order 767 for all operations to be implemented. 768 769 Parameters 770 ---------- 771 tx : 772 Transaction to compute the intrinsic cost of. 773 774 Returns 775 ------- 776 verified : `ethereum.base_types.Uint` 777 The intrinsic cost of the transaction. 778 """ 779 data_cost = 0 780 781 for byte in tx.data: 782 if byte == 0: 783 data_cost += TX_DATA_COST_PER_ZERO 784 else: 785 data_cost += TX_DATA_COST_PER_NON_ZERO 786 787 if tx.to == Bytes0(b""): 788 create_cost = TX_CREATE_COST 789 else: 790 create_cost = 0 791 792 access_list_cost = 0 793 if isinstance(tx, AccessListTransaction): 794 for _address, keys in tx.access_list: 795 access_list_cost += TX_ACCESS_LIST_ADDRESS_COST 796 access_list_cost += len(keys) * TX_ACCESS_LIST_STORAGE_KEY_COST 797 798 return Uint(TX_BASE_COST + data_cost + create_cost + access_list_cost)
Calculates the gas that is charged before execution is started.
The intrinsic cost of the transaction is charged before execution has begun. Functions/operations in the EVM cost money to execute so this intrinsic cost is for the operations that need to be paid for as part of the transaction. Data transfer, for example, is part of this intrinsic cost. It costs ether to send data over the wire and that ether is accounted for in the intrinsic cost calculated in this function. This intrinsic cost must be calculated and paid for before execution in order for all operations to be implemented.
Parameters
tx : Transaction to compute the intrinsic cost of.
Returns
verified : ethereum.base_types.Uint
The intrinsic cost of the transaction.
801def recover_sender(chain_id: U64, tx: Transaction) -> Address: 802 """ 803 Extracts the sender address from a transaction. 804 805 The v, r, and s values are the three parts that make up the signature 806 of a transaction. In order to recover the sender of a transaction the two 807 components needed are the signature (``v``, ``r``, and ``s``) and the 808 signing hash of the transaction. The sender's public key can be obtained 809 with these two values and therefore the sender address can be retrieved. 810 811 Parameters 812 ---------- 813 tx : 814 Transaction of interest. 815 chain_id : 816 ID of the executing chain. 817 818 Returns 819 ------- 820 sender : `ethereum.fork_types.Address` 821 The address of the account that signed the transaction. 822 """ 823 r, s = tx.r, tx.s 824 825 ensure(0 < r and r < SECP256K1N, InvalidBlock) 826 ensure(0 < s and s <= SECP256K1N // 2, InvalidBlock) 827 828 if isinstance(tx, LegacyTransaction): 829 v = tx.v 830 if v == 27 or v == 28: 831 public_key = secp256k1_recover( 832 r, s, v - 27, signing_hash_pre155(tx) 833 ) 834 else: 835 ensure( 836 v == 35 + chain_id * 2 or v == 36 + chain_id * 2, InvalidBlock 837 ) 838 public_key = secp256k1_recover( 839 r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id) 840 ) 841 elif isinstance(tx, AccessListTransaction): 842 public_key = secp256k1_recover( 843 r, s, tx.y_parity, signing_hash_2930(tx) 844 ) 845 846 return Address(keccak256(public_key)[12:32])
Extracts the sender address from a transaction.
The v, r, and s values are the three parts that make up the signature
of a transaction. In order to recover the sender of a transaction the two
components needed are the signature (v
, r
, and s
) and the
signing hash of the transaction. The sender's public key can be obtained
with these two values and therefore the sender address can be retrieved.
Parameters
tx : Transaction of interest. chain_id : ID of the executing chain.
Returns
sender : ethereum.fork_types.Address
The address of the account that signed the transaction.
849def signing_hash_pre155(tx: Transaction) -> Hash32: 850 """ 851 Compute the hash of a transaction used in a legacy (pre EIP 155) signature. 852 853 Parameters 854 ---------- 855 tx : 856 Transaction of interest. 857 858 Returns 859 ------- 860 hash : `ethereum.crypto.hash.Hash32` 861 Hash of the transaction. 862 """ 863 return keccak256( 864 rlp.encode( 865 ( 866 tx.nonce, 867 tx.gas_price, 868 tx.gas, 869 tx.to, 870 tx.value, 871 tx.data, 872 ) 873 ) 874 )
Compute the hash of a transaction used in a legacy (pre EIP 155) signature.
Parameters
tx : Transaction of interest.
Returns
hash : ethereum.crypto.hash.Hash32
Hash of the transaction.
877def signing_hash_155(tx: Transaction, chain_id: U64) -> Hash32: 878 """ 879 Compute the hash of a transaction used in a EIP 155 signature. 880 881 Parameters 882 ---------- 883 tx : 884 Transaction of interest. 885 chain_id : 886 The id of the current chain. 887 888 Returns 889 ------- 890 hash : `ethereum.crypto.hash.Hash32` 891 Hash of the transaction. 892 """ 893 return keccak256( 894 rlp.encode( 895 ( 896 tx.nonce, 897 tx.gas_price, 898 tx.gas, 899 tx.to, 900 tx.value, 901 tx.data, 902 chain_id, 903 Uint(0), 904 Uint(0), 905 ) 906 ) 907 )
Compute the hash of a transaction used in a EIP 155 signature.
Parameters
tx : Transaction of interest. chain_id : The id of the current chain.
Returns
hash : ethereum.crypto.hash.Hash32
Hash of the transaction.
910def signing_hash_2930(tx: AccessListTransaction) -> Hash32: 911 """ 912 Compute the hash of a transaction used in a EIP 2930 signature. 913 914 Parameters 915 ---------- 916 tx : 917 Transaction of interest. 918 919 Returns 920 ------- 921 hash : `ethereum.crypto.hash.Hash32` 922 Hash of the transaction. 923 """ 924 return keccak256( 925 b"\x01" 926 + rlp.encode( 927 ( 928 tx.chain_id, 929 tx.nonce, 930 tx.gas_price, 931 tx.gas, 932 tx.to, 933 tx.value, 934 tx.data, 935 tx.access_list, 936 ) 937 ) 938 )
Compute the hash of a transaction used in a EIP 2930 signature.
Parameters
tx : Transaction of interest.
Returns
hash : ethereum.crypto.hash.Hash32
Hash of the transaction.
941def compute_header_hash(header: Header) -> Hash32: 942 """ 943 Computes the hash of a block header. 944 945 The header hash of a block is the canonical hash that is used to refer 946 to a specific block and completely distinguishes a block from another. 947 948 ``keccak256`` is a function that produces a 256 bit hash of any input. 949 It also takes in any number of bytes as an input and produces a single 950 hash for them. A hash is a completely unique output for a single input. 951 So an input corresponds to one unique hash that can be used to identify 952 the input exactly. 953 954 Prior to using the ``keccak256`` hash function, the header must be 955 encoded using the Recursive-Length Prefix. See :ref:`rlp`. 956 RLP encoding the header converts it into a space-efficient format that 957 allows for easy transfer of data between nodes. The purpose of RLP is to 958 encode arbitrarily nested arrays of binary data, and RLP is the primary 959 encoding method used to serialize objects in Ethereum's execution layer. 960 The only purpose of RLP is to encode structure; encoding specific data 961 types (e.g. strings, floats) is left up to higher-order protocols. 962 963 Parameters 964 ---------- 965 header : 966 Header of interest. 967 968 Returns 969 ------- 970 hash : `ethereum.crypto.hash.Hash32` 971 Hash of the header. 972 """ 973 return keccak256(rlp.encode(header))
Computes the hash of a block header.
The header hash of a block is the canonical hash that is used to refer to a specific block and completely distinguishes a block from another.
keccak256
is a function that produces a 256 bit hash of any input.
It also takes in any number of bytes as an input and produces a single
hash for them. A hash is a completely unique output for a single input.
So an input corresponds to one unique hash that can be used to identify
the input exactly.
Prior to using the keccak256
hash function, the header must be
encoded using the Recursive-Length Prefix. See :ref:rlp
.
RLP encoding the header converts it into a space-efficient format that
allows for easy transfer of data between nodes. The purpose of RLP is to
encode arbitrarily nested arrays of binary data, and RLP is the primary
encoding method used to serialize objects in Ethereum's execution layer.
The only purpose of RLP is to encode structure; encoding specific data
types (e.g. strings, floats) is left up to higher-order protocols.
Parameters
header : Header of interest.
Returns
hash : ethereum.crypto.hash.Hash32
Hash of the header.
976def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: 977 """ 978 Validates the gas limit for a block. 979 980 The bounds of the gas limit, ``max_adjustment_delta``, is set as the 981 quotient of the parent block's gas limit and the 982 ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is 983 passed through as a parameter is greater than or equal to the *sum* of 984 the parent's gas and the adjustment delta then the limit for gas is too 985 high and fails this function's check. Similarly, if the limit is less 986 than or equal to the *difference* of the parent's gas and the adjustment 987 delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's 988 check fails because the gas limit doesn't allow for a sufficient or 989 reasonable amount of gas to be used on a block. 990 991 Parameters 992 ---------- 993 gas_limit : 994 Gas limit to validate. 995 996 parent_gas_limit : 997 Gas limit of the parent block. 998 999 Returns 1000 ------- 1001 check : `bool` 1002 True if gas limit constraints are satisfied, False otherwise. 1003 """ 1004 max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR 1005 if gas_limit >= parent_gas_limit + max_adjustment_delta: 1006 return False 1007 if gas_limit <= parent_gas_limit - max_adjustment_delta: 1008 return False 1009 if gas_limit < GAS_LIMIT_MINIMUM: 1010 return False 1011 1012 return True
Validates the gas limit for a block.
The bounds of the gas limit, max_adjustment_delta
, is set as the
quotient of the parent block's gas limit and the
GAS_LIMIT_ADJUSTMENT_FACTOR
. Therefore, if the gas limit that is
passed through as a parameter is greater than or equal to the sum of
the parent's gas and the adjustment delta then the limit for gas is too
high and fails this function's check. Similarly, if the limit is less
than or equal to the difference of the parent's gas and the adjustment
delta or the predefined GAS_LIMIT_MINIMUM
then this function's
check fails because the gas limit doesn't allow for a sufficient or
reasonable amount of gas to be used on a block.
Parameters
gas_limit : Gas limit to validate.
parent_gas_limit : Gas limit of the parent block.
Returns
check : bool
True if gas limit constraints are satisfied, False otherwise.
1015def calculate_block_difficulty( 1016 block_number: Uint, 1017 block_timestamp: U256, 1018 parent_timestamp: U256, 1019 parent_difficulty: Uint, 1020 parent_has_ommers: bool, 1021) -> Uint: 1022 """ 1023 Computes difficulty of a block using its header and parent header. 1024 1025 The difficulty is determined by the time the block was created after its 1026 parent. The ``offset`` is calculated using the parent block's difficulty, 1027 ``parent_difficulty``, and the timestamp between blocks. This offset is 1028 then added to the parent difficulty and is stored as the ``difficulty`` 1029 variable. If the time between the block and its parent is too short, the 1030 offset will result in a positive number thus making the sum of 1031 ``parent_difficulty`` and ``offset`` to be a greater value in order to 1032 avoid mass forking. But, if the time is long enough, then the offset 1033 results in a negative value making the block less difficult than 1034 its parent. 1035 1036 The base standard for a block's difficulty is the predefined value 1037 set for the genesis block since it has no parent. So, a block 1038 can't be less difficult than the genesis block, therefore each block's 1039 difficulty is set to the maximum value between the calculated 1040 difficulty and the ``GENESIS_DIFFICULTY``. 1041 1042 Parameters 1043 ---------- 1044 block_number : 1045 Block number of the block. 1046 block_timestamp : 1047 Timestamp of the block. 1048 parent_timestamp : 1049 Timestamp of the parent block. 1050 parent_difficulty : 1051 difficulty of the parent block. 1052 parent_has_ommers: 1053 does the parent have ommers. 1054 1055 Returns 1056 ------- 1057 difficulty : `ethereum.base_types.Uint` 1058 Computed difficulty for a block. 1059 """ 1060 offset = ( 1061 int(parent_difficulty) 1062 // 2048 1063 * max( 1064 (2 if parent_has_ommers else 1) 1065 - int(block_timestamp - parent_timestamp) // 9, 1066 -99, 1067 ) 1068 ) 1069 difficulty = int(parent_difficulty) + offset 1070 # Historical Note: The difficulty bomb was not present in Ethereum at the 1071 # start of Frontier, but was added shortly after launch. However since the 1072 # bomb has no effect prior to block 200000 we pretend it existed from 1073 # genesis. 1074 # See https://github.com/ethereum/go-ethereum/pull/1588 1075 num_bomb_periods = ((int(block_number) - BOMB_DELAY_BLOCKS) // 100000) - 2 1076 if num_bomb_periods >= 0: 1077 difficulty += 2**num_bomb_periods 1078 1079 # Some clients raise the difficulty to `MINIMUM_DIFFICULTY` prior to adding 1080 # the bomb. This bug does not matter because the difficulty is always much 1081 # greater than `MINIMUM_DIFFICULTY` on Mainnet. 1082 return Uint(max(difficulty, MINIMUM_DIFFICULTY))
Computes difficulty of a block using its header and parent header.
The difficulty is determined by the time the block was created after its
parent. The offset
is calculated using the parent block's difficulty,
parent_difficulty
, and the timestamp between blocks. This offset is
then added to the parent difficulty and is stored as the difficulty
variable. If the time between the block and its parent is too short, the
offset will result in a positive number thus making the sum of
parent_difficulty
and offset
to be a greater value in order to
avoid mass forking. But, if the time is long enough, then the offset
results in a negative value making the block less difficult than
its parent.
The base standard for a block's difficulty is the predefined value
set for the genesis block since it has no parent. So, a block
can't be less difficult than the genesis block, therefore each block's
difficulty is set to the maximum value between the calculated
difficulty and the GENESIS_DIFFICULTY
.
Parameters
block_number : Block number of the block. block_timestamp : Timestamp of the block. parent_timestamp : Timestamp of the parent block. parent_difficulty : difficulty of the parent block. parent_has_ommers: does the parent have ommers.
Returns
difficulty : ethereum.base_types.Uint
Computed difficulty for a block.