Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-3074: AUTH and AUTHCALL instructions #945

Draft
wants to merge 6 commits into
base: forks/prague
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ packages =
ethereum/cancun/vm
ethereum/cancun/vm/instructions
ethereum/cancun/vm/precompiled_contracts
ethereum/prague
ethereum/prague/utils
ethereum/prague/vm
ethereum/prague/vm/instructions
ethereum/prague/vm/precompiled_contracts


package_dir =
Expand Down
7 changes: 7 additions & 0 deletions src/ethereum/prague/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
The Prague fork.
"""

from ethereum.fork_criteria import Unscheduled

FORK_CRITERIA = Unscheduled()
105 changes: 105 additions & 0 deletions src/ethereum/prague/blocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""
A `Block` is a single link in the chain that is Ethereum. Each `Block` contains
a `Header` and zero or more transactions. Each `Header` contains associated
metadata like the block number, parent block hash, and how much gas was
consumed by its transactions.

Together, these blocks form a cryptographically secure journal recording the
history of all state transitions that have happened since the genesis of the
chain.
"""
from dataclasses import dataclass
from typing import Tuple, Union

from ..base_types import (
U64,
U256,
Bytes,
Bytes8,
Bytes32,
Uint,
slotted_freezable,
)
from ..crypto.hash import Hash32
from .fork_types import Address, Bloom, Root
from .transactions import LegacyTransaction


@slotted_freezable
@dataclass
class Withdrawal:
"""
Withdrawals that have been validated on the consensus layer.
"""

index: U64
validator_index: U64
address: Address
amount: U256


@slotted_freezable
@dataclass
class Header:
"""
Header portion of a block on the chain.
"""

parent_hash: Hash32
ommers_hash: Hash32
coinbase: Address
state_root: Root
transactions_root: Root
receipt_root: Root
bloom: Bloom
difficulty: Uint
number: Uint
gas_limit: Uint
gas_used: Uint
timestamp: U256
extra_data: Bytes
prev_randao: Bytes32
nonce: Bytes8
base_fee_per_gas: Uint
withdrawals_root: Root
blob_gas_used: U64
excess_blob_gas: U64
parent_beacon_block_root: Root


@slotted_freezable
@dataclass
class Block:
"""
A complete block.
"""

header: Header
transactions: Tuple[Union[Bytes, LegacyTransaction], ...]
ommers: Tuple[Header, ...]
withdrawals: Tuple[Withdrawal, ...]


@slotted_freezable
@dataclass
class Log:
"""
Data record produced during the execution of a transaction.
"""

address: Address
topics: Tuple[Hash32, ...]
data: bytes


@slotted_freezable
@dataclass
class Receipt:
"""
Result of a transaction.
"""

succeeded: bool
cumulative_gas_used: Uint
bloom: Bloom
logs: Tuple[Log, ...]
84 changes: 84 additions & 0 deletions src/ethereum/prague/bloom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
Ethereum Logs Bloom
^^^^^^^^^^^^^^^^^^^

.. contents:: Table of Contents
:backlinks: none
:local:

Introduction
------------

This modules defines functions for calculating bloom filters of logs. For the
general theory of bloom filters see e.g. `Wikipedia
<https://en.wikipedia.org/wiki/Bloom_filter>`_. Bloom filters are used to allow
for efficient searching of logs by address and/or topic, by rapidly
eliminating blocks and receipts from their search.
"""

from typing import Tuple

from ethereum.base_types import Uint
from ethereum.crypto.hash import keccak256

from .blocks import Log
from .fork_types import Bloom


def add_to_bloom(bloom: bytearray, bloom_entry: bytes) -> None:
"""
Add a bloom entry to the bloom filter (`bloom`).

The number of hash functions used is 3. They are calculated by taking the
least significant 11 bits from the first 3 16-bit words of the
`keccak_256()` hash of `bloom_entry`.

Parameters
----------
bloom :
The bloom filter.
bloom_entry :
An entry which is to be added to bloom filter.
"""
hash = keccak256(bloom_entry)

for idx in (0, 2, 4):
# Obtain the least significant 11 bits from the pair of bytes
# (16 bits), and set this bit in bloom bytearray.
# The obtained bit is 0-indexed in the bloom filter from the least
# significant bit to the most significant bit.
bit_to_set = Uint.from_be_bytes(hash[idx : idx + 2]) & 0x07FF
# Below is the index of the bit in the bytearray (where 0-indexed
# byte is the most significant byte)
bit_index = 0x07FF - bit_to_set

byte_index = bit_index // 8
bit_value = 1 << (7 - (bit_index % 8))
bloom[byte_index] = bloom[byte_index] | bit_value


def logs_bloom(logs: Tuple[Log, ...]) -> Bloom:
"""
Obtain the logs bloom from a list of log entries.

The address and each topic of a log are added to the bloom filter.

Parameters
----------
logs :
List of logs for which the logs bloom is to be obtained.

Returns
-------
logs_bloom : `Bloom`
The logs bloom obtained which is 256 bytes with some bits set as per
the caller address and the log topics.
"""
bloom: bytearray = bytearray(b"\x00" * 256)

for log in logs:
add_to_bloom(bloom, log.address)
for topic in log.topics:
add_to_bloom(bloom, topic)

return Bloom(bloom)
Loading
Loading