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