12
12
from typing import List , Union
13
13
14
14
from ethereum_types .bytes import Bytes
15
+ from ethereum_types .numeric import Uint , ulen
16
+
17
+ from ethereum .exceptions import InvalidBlock
18
+ from ethereum .utils .hexadecimal import hex_to_bytes32
15
19
16
20
from .blocks import Receipt , decode_receipt
17
21
from .utils .hexadecimal import hex_to_address
18
22
19
23
DEPOSIT_CONTRACT_ADDRESS = hex_to_address (
20
24
"0x00000000219ab540356cbb839cbe05303d7705fa"
21
25
)
26
+ DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32 (
27
+ "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"
28
+ )
22
29
DEPOSIT_REQUEST_TYPE = b"\x00 "
23
30
WITHDRAWAL_REQUEST_TYPE = b"\x01 "
24
31
CONSOLIDATION_REQUEST_TYPE = b"\x02 "
25
32
26
33
34
+ DEPOSIT_EVENT_LENGTH = Uint (576 )
35
+
36
+ PUBKEY_OFFSET = Uint (160 )
37
+ WITHDRAWAL_CREDENTIALS_OFFSET = Uint (256 )
38
+ AMOUNT_OFFSET = Uint (320 )
39
+ SIGNATURE_OFFSET = Uint (384 )
40
+ INDEX_OFFSET = Uint (512 )
41
+
42
+ PUBKEY_SIZE = Uint (48 )
43
+ WITHDRAWAL_CREDENTIALS_SIZE = Uint (32 )
44
+ AMOUNT_SIZE = Uint (8 )
45
+ SIGNATURE_SIZE = Uint (96 )
46
+ INDEX_SIZE = Uint (8 )
47
+
48
+
27
49
def extract_deposit_data (data : Bytes ) -> Bytes :
28
50
"""
29
51
Extracts Deposit Request from the DepositContract.DepositEvent data.
52
+
53
+ Raises
54
+ ------
55
+ InvalidBlock :
56
+ If the deposit contract did not produce a valid log.
30
57
"""
31
- return (
32
- data [192 :240 ] # public_key
33
- + data [288 :320 ] # withdrawal_credentials
34
- + data [352 :360 ] # amount
35
- + data [416 :512 ] # signature
36
- + data [544 :552 ] # index
58
+ if ulen (data ) != DEPOSIT_EVENT_LENGTH :
59
+ raise InvalidBlock ("Invalid deposit event data length" )
60
+
61
+ # Check that all the offsets are in order
62
+ pubkey_offset = Uint .from_be_bytes (data [0 :32 ])
63
+ if pubkey_offset != PUBKEY_OFFSET :
64
+ raise InvalidBlock ("Invalid pubkey offset in deposit log" )
65
+
66
+ withdrawal_credentials_offset = Uint .from_be_bytes (data [32 :64 ])
67
+ if withdrawal_credentials_offset != WITHDRAWAL_CREDENTIALS_OFFSET :
68
+ raise InvalidBlock (
69
+ "Invalid withdrawal credentials offset in deposit log"
70
+ )
71
+
72
+ amount_offset = Uint .from_be_bytes (data [64 :96 ])
73
+ if amount_offset != AMOUNT_OFFSET :
74
+ raise InvalidBlock ("Invalid amount offset in deposit log" )
75
+
76
+ signature_offset = Uint .from_be_bytes (data [96 :128 ])
77
+ if signature_offset != SIGNATURE_OFFSET :
78
+ raise InvalidBlock ("Invalid signature offset in deposit log" )
79
+
80
+ index_offset = Uint .from_be_bytes (data [128 :160 ])
81
+ if index_offset != INDEX_OFFSET :
82
+ raise InvalidBlock ("Invalid index offset in deposit log" )
83
+
84
+ # Check that all the sizes are in order
85
+ pubkey_size = Uint .from_be_bytes (
86
+ data [pubkey_offset : pubkey_offset + Uint (32 )]
37
87
)
88
+ if pubkey_size != PUBKEY_SIZE :
89
+ raise InvalidBlock ("Invalid pubkey size in deposit log" )
90
+
91
+ pubkey = data [
92
+ pubkey_offset + Uint (32 ) : pubkey_offset + Uint (32 ) + PUBKEY_SIZE
93
+ ]
94
+
95
+ withdrawal_credentials_size = Uint .from_be_bytes (
96
+ data [
97
+ withdrawal_credentials_offset : withdrawal_credentials_offset
98
+ + Uint (32 )
99
+ ],
100
+ )
101
+ if withdrawal_credentials_size != WITHDRAWAL_CREDENTIALS_SIZE :
102
+ raise InvalidBlock (
103
+ "Invalid withdrawal credentials size in deposit log"
104
+ )
105
+
106
+ withdrawal_credentials = data [
107
+ withdrawal_credentials_offset
108
+ + Uint (32 ) : withdrawal_credentials_offset
109
+ + Uint (32 )
110
+ + WITHDRAWAL_CREDENTIALS_SIZE
111
+ ]
112
+
113
+ amount_size = Uint .from_be_bytes (
114
+ data [amount_offset : amount_offset + Uint (32 )]
115
+ )
116
+ if amount_size != AMOUNT_SIZE :
117
+ raise InvalidBlock ("Invalid amount size in deposit log" )
118
+
119
+ amount = data [
120
+ amount_offset + Uint (32 ) : amount_offset + Uint (32 ) + AMOUNT_SIZE
121
+ ]
122
+
123
+ signature_size = Uint .from_be_bytes (
124
+ data [signature_offset : signature_offset + Uint (32 )]
125
+ )
126
+ if signature_size != SIGNATURE_SIZE :
127
+ raise InvalidBlock ("Invalid signature size in deposit log" )
128
+
129
+ signature = data [
130
+ signature_offset
131
+ + Uint (32 ) : signature_offset
132
+ + Uint (32 )
133
+ + SIGNATURE_SIZE
134
+ ]
135
+
136
+ index_size = Uint .from_be_bytes (
137
+ data [index_offset : index_offset + Uint (32 )]
138
+ )
139
+ if index_size != INDEX_SIZE :
140
+ raise InvalidBlock ("Invalid index size in deposit log" )
141
+
142
+ index = data [
143
+ index_offset + Uint (32 ) : index_offset + Uint (32 ) + INDEX_SIZE
144
+ ]
145
+
146
+ return pubkey + withdrawal_credentials + amount + signature + index
38
147
39
148
40
149
def parse_deposit_requests_from_receipt (
@@ -47,8 +156,12 @@ def parse_deposit_requests_from_receipt(
47
156
decoded_receipt = decode_receipt (receipt )
48
157
for log in decoded_receipt .logs :
49
158
if log .address == DEPOSIT_CONTRACT_ADDRESS :
50
- request = extract_deposit_data (log .data )
51
- deposit_requests += request
159
+ if (
160
+ len (log .topics ) > 0
161
+ and log .topics [0 ] == DEPOSIT_EVENT_SIGNATURE_HASH
162
+ ):
163
+ request = extract_deposit_data (log .data )
164
+ deposit_requests += request
52
165
53
166
return deposit_requests
54
167
0 commit comments