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