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