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