ethereum.prague.requests

Requests were introduced in EIP-7685 as a a general purpose framework for storing contract-triggered requests. It extends the execution header and body with a single field each to store the request information. This inherently exposes the requests to the consensus layer, which can then process each one.

DEPOSIT_CONTRACT_ADDRESS

25
DEPOSIT_CONTRACT_ADDRESS = hex_to_address(
26
    "0x00000000219ab540356cbb839cbe05303d7705fa"
27
)

DEPOSIT_EVENT_SIGNATURE_HASH

28
DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32(
29
    "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"
30
)

DEPOSIT_REQUEST_TYPE

31
DEPOSIT_REQUEST_TYPE = b"\x00"

WITHDRAWAL_REQUEST_TYPE

32
WITHDRAWAL_REQUEST_TYPE = b"\x01"

CONSOLIDATION_REQUEST_TYPE

33
CONSOLIDATION_REQUEST_TYPE = b"\x02"

DEPOSIT_EVENT_LENGTH

36
DEPOSIT_EVENT_LENGTH = Uint(576)

PUBKEY_OFFSET

38
PUBKEY_OFFSET = Uint(160)

WITHDRAWAL_CREDENTIALS_OFFSET

39
WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256)

AMOUNT_OFFSET

40
AMOUNT_OFFSET = Uint(320)

SIGNATURE_OFFSET

41
SIGNATURE_OFFSET = Uint(384)

INDEX_OFFSET

42
INDEX_OFFSET = Uint(512)

PUBKEY_SIZE

44
PUBKEY_SIZE = Uint(48)

WITHDRAWAL_CREDENTIALS_SIZE

45
WITHDRAWAL_CREDENTIALS_SIZE = Uint(32)

AMOUNT_SIZE

46
AMOUNT_SIZE = Uint(8)

SIGNATURE_SIZE

47
SIGNATURE_SIZE = Uint(96)

INDEX_SIZE

48
INDEX_SIZE = Uint(8)

extract_deposit_data

Extracts Deposit Request from the DepositContract.DepositEvent data.

Raises

InvalidBlock : If the deposit contract did not produce a valid log.

def extract_deposit_data(data: Bytes) -> Bytes:
52
    """
53
    Extracts Deposit Request from the DepositContract.DepositEvent data.
54
55
    Raises
56
    ------
57
    InvalidBlock :
58
        If the deposit contract did not produce a valid log.
59
    """
60
    if ulen(data) != DEPOSIT_EVENT_LENGTH:
61
        raise InvalidBlock("Invalid deposit event data length")
62
63
    # Check that all the offsets are in order
64
    pubkey_offset = Uint.from_be_bytes(data[0:32])
65
    if pubkey_offset != PUBKEY_OFFSET:
66
        raise InvalidBlock("Invalid pubkey offset in deposit log")
67
68
    withdrawal_credentials_offset = Uint.from_be_bytes(data[32:64])
69
    if withdrawal_credentials_offset != WITHDRAWAL_CREDENTIALS_OFFSET:
70
        raise InvalidBlock(
71
            "Invalid withdrawal credentials offset in deposit log"
72
        )
73
74
    amount_offset = Uint.from_be_bytes(data[64:96])
75
    if amount_offset != AMOUNT_OFFSET:
76
        raise InvalidBlock("Invalid amount offset in deposit log")
77
78
    signature_offset = Uint.from_be_bytes(data[96:128])
79
    if signature_offset != SIGNATURE_OFFSET:
80
        raise InvalidBlock("Invalid signature offset in deposit log")
81
82
    index_offset = Uint.from_be_bytes(data[128:160])
83
    if index_offset != INDEX_OFFSET:
84
        raise InvalidBlock("Invalid index offset in deposit log")
85
86
    # Check that all the sizes are in order
87
    pubkey_size = Uint.from_be_bytes(
88
        data[pubkey_offset : pubkey_offset + Uint(32)]
89
    )
90
    if pubkey_size != PUBKEY_SIZE:
91
        raise InvalidBlock("Invalid pubkey size in deposit log")
92
93
    pubkey = data[
94
        pubkey_offset + Uint(32) : pubkey_offset + Uint(32) + PUBKEY_SIZE
95
    ]
96
97
    withdrawal_credentials_size = Uint.from_be_bytes(
98
        data[
99
            withdrawal_credentials_offset : withdrawal_credentials_offset
100
            + Uint(32)
101
        ],
102
    )
103
    if withdrawal_credentials_size != WITHDRAWAL_CREDENTIALS_SIZE:
104
        raise InvalidBlock(
105
            "Invalid withdrawal credentials size in deposit log"
106
        )
107
108
    withdrawal_credentials = data[
109
        withdrawal_credentials_offset
110
        + Uint(32) : withdrawal_credentials_offset
111
        + Uint(32)
112
        + WITHDRAWAL_CREDENTIALS_SIZE
113
    ]
114
115
    amount_size = Uint.from_be_bytes(
116
        data[amount_offset : amount_offset + Uint(32)]
117
    )
118
    if amount_size != AMOUNT_SIZE:
119
        raise InvalidBlock("Invalid amount size in deposit log")
120
121
    amount = data[
122
        amount_offset + Uint(32) : amount_offset + Uint(32) + AMOUNT_SIZE
123
    ]
124
125
    signature_size = Uint.from_be_bytes(
126
        data[signature_offset : signature_offset + Uint(32)]
127
    )
128
    if signature_size != SIGNATURE_SIZE:
129
        raise InvalidBlock("Invalid signature size in deposit log")
130
131
    signature = data[
132
        signature_offset
133
        + Uint(32) : signature_offset
134
        + Uint(32)
135
        + SIGNATURE_SIZE
136
    ]
137
138
    index_size = Uint.from_be_bytes(
139
        data[index_offset : index_offset + Uint(32)]
140
    )
141
    if index_size != INDEX_SIZE:
142
        raise InvalidBlock("Invalid index size in deposit log")
143
144
    index = data[
145
        index_offset + Uint(32) : index_offset + Uint(32) + INDEX_SIZE
146
    ]
147
148
    return pubkey + withdrawal_credentials + amount + signature + index

parse_deposit_requests

Parse deposit requests from the block output.

def parse_deposit_requests(block_output: BlockOutput) -> Bytes:
152
    """
153
    Parse deposit requests from the block output.
154
    """
155
    deposit_requests: Bytes = b""
156
    for key in block_output.receipt_keys:
157
        receipt = trie_get(block_output.receipts_trie, key)
158
        assert receipt is not None
159
        decoded_receipt = decode_receipt(receipt)
160
        for log in decoded_receipt.logs:
161
            if log.address == DEPOSIT_CONTRACT_ADDRESS:
162
                if (
163
                    len(log.topics) > 0
164
                    and log.topics[0] == DEPOSIT_EVENT_SIGNATURE_HASH
165
                ):
166
                    request = extract_deposit_data(log.data)
167
                    deposit_requests += request
168
169
    return deposit_requests

compute_requests_hash

Get the hash of the requests using the SHA2-256 algorithm.

Parameters

requests : Bytes The requests to hash.

Returns

requests_hash : Bytes The hash of the requests.

def compute_requests_hash(requests: List[Bytes]) -> Bytes:
173
    """
174
    Get the hash of the requests using the SHA2-256 algorithm.
175
176
    Parameters
177
    ----------
178
    requests : Bytes
179
        The requests to hash.
180
181
    Returns
182
    -------
183
    requests_hash : Bytes
184
        The hash of the requests.
185
    """
186
    m = sha256()
187
    for request in requests:
188
        m.update(sha256(request).digest())
189
190
    return m.digest()