1
- from typing import (
2
- Sequence ,
3
- )
4
-
5
1
from eth_typing import (
6
2
Hash32
7
3
)
8
4
from eth_utils import (
9
5
ValidationError ,
10
6
)
7
+ from eth .constants import (
8
+ ZERO_HASH32 ,
9
+ )
11
10
12
11
13
12
from eth .beacon .helpers import (
14
13
get_block_hash ,
15
14
)
16
15
from eth .beacon .types .states import BeaconState # noqa: F401
16
+ from eth .beacon .types .attestations import Attestation # noqa: F401
17
+ from eth .beacon .types .attestation_data import AttestationData # noqa: F401
17
18
18
19
19
20
#
20
21
# Attestation validation
21
22
#
22
23
def validate_attestation (state : BeaconState ,
23
- attestation : 'AttestationRecord' ,
24
+ attestation : Attestation ,
24
25
epoch_length : int ,
25
26
min_attestation_inclusion_delay : int ,
26
27
is_validating_signatures : bool = True ) -> None :
@@ -54,18 +55,22 @@ def validate_attestation(state: BeaconState,
54
55
)
55
56
56
57
validate_attestation_latest_crosslink_root (
57
- attestation ,
58
- state .latest_crosslinks [attestation .data .shard ].shard_block_root ,
58
+ attestation_data = attestation .data ,
59
+ latest_crosslink_shard_block_root = (
60
+ state .latest_crosslinks [attestation .data .shard ].shard_block_root
61
+ ),
59
62
)
60
63
64
+ validate_attestation_shard_block_root (attestation_data = attestation .data )
65
+
61
66
if is_validating_signatures :
62
67
validate_attestation_aggregate_signature (
63
68
state ,
64
69
attestation ,
65
70
)
66
71
67
72
68
- def validate_attestation_slot (attestation_data : ' AttestationData' ,
73
+ def validate_attestation_slot (attestation_data : AttestationData ,
69
74
current_slot : int ,
70
75
epoch_length : int ,
71
76
min_attestation_inclusion_delay : int ) -> None :
@@ -97,35 +102,43 @@ def validate_attestation_slot(attestation_data: 'AttestationData',
97
102
)
98
103
99
104
100
- def validate_attestation_justified_slot (attestation_data : ' AttestationData' ,
105
+ def validate_attestation_justified_slot (attestation_data : AttestationData ,
101
106
current_slot : int ,
102
107
previous_justified_slot : int ,
103
108
justified_slot : int ,
104
109
epoch_length : int ) -> None :
110
+ """
111
+ Validate ``justified_slot`` field of ``attestation_data``.
112
+ Raise ``ValidationError`` if it's invalid.
113
+ """
105
114
if attestation_data .slot >= current_slot - (current_slot % epoch_length ):
106
115
if attestation_data .justified_slot != justified_slot :
107
116
raise ValidationError (
108
- "Attestation slot is after recent epoch transition but "
109
- "is not targeting the justified slot :\n "
117
+ "Attestation `` slot`` is after recent epoch transition but attestation "
118
+ "``justified_slot`` is not targeting the ``justified_slot`` :\n "
110
119
"\t Found: %s, Expected %s" %
111
120
(attestation_data .justified_slot , justified_slot )
112
121
)
113
122
else :
114
123
if attestation_data .justified_slot != previous_justified_slot :
115
124
raise ValidationError (
116
- "Attestation slot is before recent epoch transition but "
117
- "is not targeting the previous justified slot :\n "
125
+ "Attestation `` slot`` is before recent epoch transition but attestation "
126
+ "``justified_slot`` is not targeting the ``previous_justified_slot :\n "
118
127
"\t Found: %s, Expected %s" %
119
128
(attestation_data .justified_slot , previous_justified_slot )
120
129
)
121
130
122
131
123
- def validate_attestation_justified_block_root (attestation_data : ' AttestationData' ,
132
+ def validate_attestation_justified_block_root (attestation_data : AttestationData ,
124
133
justified_block_root : Hash32 ) -> None :
134
+ """
135
+ Validate ``justified_block_hash`` field of ``attestation_data``.
136
+ Raise ``ValidationError`` if it's invalid.
137
+ """
125
138
if attestation_data .justified_block_hash != justified_block_root :
126
139
raise ValidationError (
127
- "Attestation justified block root is not equal to the block root at the "
128
- "justified slot :\n "
140
+ "Attestation ``justified_block_hash`` is not equal to the "
141
+ "``justified_block_root`` at the ``justified_slot`` :\n "
129
142
"\t Found: %s, Expected %s at slot %s" %
130
143
(
131
144
attestation_data .justified_block_hash ,
@@ -135,11 +148,49 @@ def validate_attestation_justified_block_root(attestation_data: 'AttestationData
135
148
)
136
149
137
150
138
- def validate_attestation_latest_crosslink_root (attestation_data : ' AttestationData' ,
151
+ def validate_attestation_latest_crosslink_root (attestation_data : AttestationData ,
139
152
latest_crosslink_shard_block_root : Hash32 ) -> None :
140
- pass
153
+ """
154
+ Validate that either the ``latest_crosslink_hash`` or ``shard_block_hash``
155
+ field of ``attestation_data`` is the provided ``latest_crosslink_shard_block_root``.
156
+ Raise ``ValidationError`` if it's invalid.
157
+ """
158
+ acceptable_shard_block_roots = [
159
+ attestation_data .latest_crosslink_hash ,
160
+ attestation_data .shard_block_hash ,
161
+ ]
162
+ if latest_crosslink_shard_block_root not in acceptable_shard_block_roots :
163
+ raise ValidationError (
164
+ "Neither the attestation ``latest_crosslink_hash`` nor the attestation "
165
+ "``shard_block_hash`` are equal to the ``latest_crosslink_shard_block_root``.\n "
166
+ "\t Found: %s and %s, Expected %s" %
167
+ (
168
+ attestation_data .latest_crosslink_hash ,
169
+ attestation_data .shard_block_hash ,
170
+ latest_crosslink_shard_block_root ,
171
+ )
172
+ )
173
+
174
+
175
+ def validate_attestation_shard_block_root (attestation_data : AttestationData ) -> None :
176
+ """
177
+ Validate ``shard_block_hash`` field of `attestation_data`.
178
+ Raise ``ValidationError`` if it's invalid.
179
+
180
+ Note: This is the Phase 0 version of ``shard_block_hash`` validation.
181
+ This is a built-in stub and will be changed in phase 1.
182
+ """
183
+ if attestation_data .shard_block_hash != ZERO_HASH32 :
184
+ raise ValidationError (
185
+ "Attestation ``shard_block_hash`` is not ZERO_HASH32.\n "
186
+ "\t Found: %s, Expected %s" %
187
+ (
188
+ attestation_data .shard_block_hash ,
189
+ ZERO_HASH32 ,
190
+ )
191
+ )
141
192
142
193
143
194
def validate_attestation_aggregate_signature (state : BeaconState ,
144
- attestation : 'AttestationRecord' ) -> None :
195
+ attestation : Attestation ) -> None :
145
196
pass
0 commit comments