Skip to content

Commit 22368de

Browse files
committed
feat: update validtion of early and late transactions
1 parent 9b2e8fd commit 22368de

4 files changed

Lines changed: 140 additions & 177 deletions

File tree

observer/validation/fdc.py

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections.abc import Sequence
2+
from typing import TYPE_CHECKING
23

34
from py_flare_common.fsp.messaging.byte_parser import ByteParser
45
from py_flare_common.fsp.messaging.types import (
@@ -14,6 +15,9 @@
1415
from .signature import Signature
1516
from .types import ValidateFn
1617

18+
if TYPE_CHECKING:
19+
from observer.validation.validation import ExtractedEntityVotingRound
20+
1721

1822
# NOTE:(matej) stupid type cast
1923
def _check_type(f: ValidateFn[FdcSubmit1, FdcSubmit2, SubmitSignatures]):
@@ -29,7 +33,7 @@ def check_submit_1(
2933
issues = []
3034
mb = message_builder
3135

32-
# NOTE:(matej) In fdc protocol submit1 is not used.
36+
# NOTE: In fdc protocol submit1 is not used.
3337
# we perform the following checks:
3438
# - submit1 exists -> error
3539

@@ -44,23 +48,21 @@ def check_submit_2(
4448
submit_2: WParsedPayload[FdcSubmit2] | None,
4549
message_builder: MessageBuilder,
4650
round: VotingRound,
47-
extracted_round,
51+
extracted_round: "ExtractedEntityVotingRound[FdcSubmit1, FdcSubmit2, SubmitSignatures]", # noqa: E501
4852
**_,
4953
) -> Sequence[Message]:
5054
issues = []
5155
mb = message_builder
5256

53-
# NOTE:(matej) In fdc protocol submit2 is used for sending the bit vote
57+
# NOTE: In fdc protocol submit2 is used for sending the bit vote
5458
# this means that the messsage must exist. Additionally decoded bit vote must have
5559
# length matching the number of requests in the round and bit vote must dominate
5660
# consensus bit vote.
5761
# we perform the following checks:
5862
# - submit2 doesnt't exist -> error
5963
# - submit2 exists but bit vote length doesn't match number of requests -> error
6064
# - submit2 exists but bit vote does not dominate consensus bit vote -> error
61-
# NOTE: (miha) The protocol accepts the latest submit2 sent in the correct
62-
# time interval. We check if there are any submit2 sent before or after interval
63-
# and send a warning for those before and a warning for those after
65+
# - submit2 exists but was sent before or after submission window -> warning
6466

6567
if not round.fdc.consensus_bitvote:
6668
return []
@@ -112,26 +114,26 @@ def check_submit_2(
112114
)
113115
)
114116

115-
if len(extracted_round.submit_2_before) > 0:
116-
issues.append(
117-
mb.build(
118-
MessageLevel.WARNING,
119-
(
120-
"submit 2 transactions sent before correct time interval: "
121-
f"{extracted_round.submit_2_before}"
122-
),
123-
)
117+
if early := extracted_round.submit_2.early:
118+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in early])
119+
issues.append(
120+
mb.build(
121+
MessageLevel.WARNING,
122+
(
123+
"submit2 transactions sent before correct time interval: "
124+
f"{tx_hashes}"
125+
),
124126
)
125-
if len(extracted_round.submit_2_after) > 0:
126-
issues.append(
127-
mb.build(
128-
MessageLevel.WARNING,
129-
(
130-
"submit 2 transactions sent after correct time interval: "
131-
f"{extracted_round.submit_2_after}"
132-
),
133-
)
127+
)
128+
129+
if late := extracted_round.submit_2.late:
130+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in late])
131+
issues.append(
132+
mb.build(
133+
MessageLevel.WARNING,
134+
(f"submit2 transactions sent after correct time interval: {tx_hashes}"),
134135
)
136+
)
135137

136138
return issues
137139

@@ -141,7 +143,7 @@ def check_submit_signatures(
141143
submit_2: WParsedPayload[FdcSubmit2] | None,
142144
submit_signatures: WParsedPayload[SubmitSignatures] | None,
143145
finalization: ProtocolMessageRelayed | None,
144-
extracted_round,
146+
extracted_round: "ExtractedEntityVotingRound[FdcSubmit1, FdcSubmit2, SubmitSignatures]", # noqa: E501
145147
message_builder: MessageBuilder,
146148
entity: Entity,
147149
round: VotingRound,
@@ -161,9 +163,7 @@ def check_submit_signatures(
161163
# dominates consensus bit vote -> reveal offence
162164
# - submitSignature was sent after the deadline -> warning
163165
# - signature doesn't match finalization -> error
164-
# NOTE: (miha) The protocol accepts the latest submitSignatures sent in the correct
165-
# time interval. We check if there are any submitSignatures sent before or after
166-
# this interval and send a warning for those before and a warning for those after
166+
# - submitSignature exists but was sent before or after submission window -> warning
167167

168168
if not round.fdc.consensus_bitvote:
169169
return []
@@ -218,27 +218,6 @@ def check_submit_signatures(
218218
)
219219
)
220220

221-
if len(extracted_round.submit_signatures_before) > 0:
222-
issues.append(
223-
mb.build(
224-
MessageLevel.WARNING,
225-
(
226-
"submit signatures transactions sent before correct time "
227-
f"interval: {extracted_round.submit_signatures_before}"
228-
),
229-
)
230-
)
231-
if len(extracted_round.submit_signatures_after) > 0:
232-
issues.append(
233-
mb.build(
234-
MessageLevel.WARNING,
235-
(
236-
"submit signatures transactions sent after correct time "
237-
f"interval: {extracted_round.submit_signatures_after}"
238-
),
239-
)
240-
)
241-
242221
if submit_signatures is not None and finalization is not None:
243222
s = Signature.from_parsed_signature(
244223
submit_signatures.parsed_payload.payload.signature
@@ -255,6 +234,18 @@ def check_submit_signatures(
255234
),
256235
)
257236

237+
if early := extracted_round.submit_signatures.early:
238+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in early])
239+
issues.append(
240+
mb.build(
241+
MessageLevel.WARNING,
242+
(
243+
"submit signatures transactions sent before correct time "
244+
f"interval: {tx_hashes}"
245+
),
246+
)
247+
)
248+
258249
if len(issues) == 0:
259250
round.submitted_signatures = True
260251

observer/validation/ftso.py

Lines changed: 59 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections.abc import Sequence
2+
from typing import TYPE_CHECKING
23

34
from py_flare_common.fsp.messaging import parse_generic_tx
45
from py_flare_common.fsp.messaging.byte_parser import ByteParser
@@ -16,6 +17,9 @@
1617
from .signature import Signature
1718
from .types import ValidateFn
1819

20+
if TYPE_CHECKING:
21+
from observer.validation.validation import ExtractedEntityVotingRound
22+
1923

2024
# NOTE:(matej) stupid type cast
2125
def _check_type(f: ValidateFn[FtsoSubmit1, FtsoSubmit2, SubmitSignatures]):
@@ -26,7 +30,7 @@ def _check_type(f: ValidateFn[FtsoSubmit1, FtsoSubmit2, SubmitSignatures]):
2630
def check_submit_1(
2731
submit_1: WParsedPayload[FtsoSubmit1] | None,
2832
message_builder: MessageBuilder,
29-
extracted_round,
33+
extracted_round: "ExtractedEntityVotingRound[FtsoSubmit1, FtsoSubmit2, SubmitSignatures]", # noqa: E501
3034
**_,
3135
) -> Sequence[Message]:
3236
issues = []
@@ -37,9 +41,7 @@ def check_submit_1(
3741
# we perform the following checks:
3842
# - submit1 doesn't exist -> error
3943
# - submit1 exists but commit hash length isn't 32 -> error
40-
# NOTE: (miha) The protocol accepts the latest submit1 sent in the correct
41-
# time interval. We check if there are any submit1 sent before or after interval
42-
# and send a warning for those before and a warning for those after
44+
# - submit1 exists but was sent before or after submission window -> warning
4345

4446
if submit_1 is None:
4547
issues.append(mb.build(MessageLevel.ERROR, "no submit1 transaction"))
@@ -53,26 +55,27 @@ def check_submit_1(
5355
f"submit1 commit hash unexpeted length ({hash_len}), expected 32",
5456
)
5557
)
56-
if len(extracted_round.submit_1_before) > 0:
57-
issues.append(
58-
mb.build(
59-
MessageLevel.WARNING,
60-
(
61-
"submit 1 transactions sent before correct time interval: "
62-
f"{extracted_round.submit_2_before}"
63-
),
64-
)
58+
59+
if early := extracted_round.submit_1.early:
60+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in early])
61+
issues.append(
62+
mb.build(
63+
MessageLevel.WARNING,
64+
(
65+
"submit1 transactions sent before correct time interval: "
66+
f"{tx_hashes}"
67+
),
6568
)
66-
if len(extracted_round.submit_1_after) > 0:
67-
issues.append(
68-
mb.build(
69-
MessageLevel.WARNING,
70-
(
71-
"submit 1 transactions sent after correct time interval: "
72-
f"{extracted_round.submit_2_after}"
73-
),
74-
)
69+
)
70+
71+
if late := extracted_round.submit_1.late:
72+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in late])
73+
issues.append(
74+
mb.build(
75+
MessageLevel.WARNING,
76+
(f"submit1 transactions sent after correct time interval: {tx_hashes}"),
7577
)
78+
)
7679

7780
return issues
7881

@@ -84,7 +87,7 @@ def check_submit_2(
8487
message_builder: MessageBuilder,
8588
entity: Entity,
8689
round: VotingRound,
87-
extracted_round,
90+
extracted_round: "ExtractedEntityVotingRound[FtsoSubmit1, FtsoSubmit2, SubmitSignatures]", # noqa: E501
8891
**_,
8992
) -> Sequence[Message]:
9093
issues = []
@@ -101,9 +104,7 @@ def check_submit_2(
101104
# - ftso values have null values -> warning
102105
# - ftso value have values that aren't in range of minimal conditions -> warning
103106
# - ftso values have incorrect length -> warning
104-
# NOTE: (miha) The protocol accepts the latest submit2 sent in the correct
105-
# time interval. We check if there are any submit2 sent before or after interval
106-
# and send a warning for those before and a warning for those after
107+
# - submit2 exists but was sent before or after submission window -> warning
107108

108109
if submit_1 is None and submit_2 is None:
109110
issues.append(mb.build(MessageLevel.ERROR, "no submit2 transaction"))
@@ -181,26 +182,26 @@ def check_submit_2(
181182
# )
182183
# )
183184

184-
if len(extracted_round.submit_2_before) > 0:
185-
issues.append(
186-
mb.build(
187-
MessageLevel.WARNING,
188-
(
189-
"submit 2 transactions sent before correct time interval: "
190-
f"{extracted_round.submit_2_before}"
191-
),
192-
)
185+
if early := extracted_round.submit_2.early:
186+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in early])
187+
issues.append(
188+
mb.build(
189+
MessageLevel.WARNING,
190+
(
191+
"submit2 transactions sent before correct time interval: "
192+
f"{tx_hashes}"
193+
),
193194
)
194-
if len(extracted_round.submit_2_after) > 0:
195-
issues.append(
196-
mb.build(
197-
MessageLevel.WARNING,
198-
(
199-
"submit 2 transactions sent after correct time interval: "
200-
f"{extracted_round.submit_2_after}"
201-
),
202-
)
195+
)
196+
197+
if late := extracted_round.submit_2.late:
198+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in late])
199+
issues.append(
200+
mb.build(
201+
MessageLevel.WARNING,
202+
(f"submit2 transactions sent after correct time interval: {tx_hashes}"),
203203
)
204+
)
204205

205206
return issues
206207

@@ -212,7 +213,7 @@ def check_submit_signatures(
212213
message_builder: MessageBuilder,
213214
entity: Entity,
214215
round: VotingRound,
215-
extracted_round,
216+
extracted_round: "ExtractedEntityVotingRound[FtsoSubmit1, FtsoSubmit2, SubmitSignatures]", # noqa: E501
216217
**_,
217218
) -> Sequence[Message]:
218219
issues = []
@@ -227,9 +228,7 @@ def check_submit_signatures(
227228
# - submitSignatures doesn't exist -> error
228229
# - submitSignature was sent after the deadline -> warning
229230
# - signature doesn't match finalization -> error
230-
# NOTE: (miha) The protocol accepts the latest submitSignatures sent in the correct
231-
# time interval. We check if there are any submitSignatures sent before or after
232-
# this interval and send a warning for those before and a warning for those after
231+
# - submitSignature exists but was sent before or after submission window -> warning
233232

234233
if submit_signatures is None:
235234
issues.append(
@@ -250,27 +249,6 @@ def check_submit_signatures(
250249
)
251250
)
252251

253-
if len(extracted_round.submit_signatures_before) > 0:
254-
issues.append(
255-
mb.build(
256-
MessageLevel.WARNING,
257-
(
258-
"submit signatures transactions sent before correct time "
259-
f"interval: {extracted_round.submit_signatures_before}"
260-
),
261-
)
262-
)
263-
if len(extracted_round.submit_signatures_after) > 0:
264-
issues.append(
265-
mb.build(
266-
MessageLevel.WARNING,
267-
(
268-
"submit signatures transactions sent after correct time "
269-
f"interval: {extracted_round.submit_signatures_after}"
270-
),
271-
)
272-
)
273-
274252
if submit_signatures is not None and finalization is not None:
275253
s = Signature.from_parsed_signature(
276254
submit_signatures.parsed_payload.payload.signature
@@ -287,4 +265,16 @@ def check_submit_signatures(
287265
),
288266
)
289267

268+
if early := extracted_round.submit_signatures.early:
269+
tx_hashes = ", ".join([tx.wtx_data.hash.to_0x_hex() for tx in early])
270+
issues.append(
271+
mb.build(
272+
MessageLevel.WARNING,
273+
(
274+
"submit signatures transactions sent before correct time "
275+
f"interval: {tx_hashes}"
276+
),
277+
)
278+
)
279+
290280
return issues

0 commit comments

Comments
 (0)