33
44use crate :: tap_receipt:: { Checking , ReceiptError , ReceiptWithState } ;
55use std:: {
6+ collections:: HashSet ,
67 ops:: Deref ,
78 sync:: { Arc , RwLock } ,
89} ;
910
11+ use super :: Failed ;
12+
1013pub type ReceiptCheck = Arc < dyn Check + Sync + Send > ;
1114
1215pub type CheckResult = anyhow:: Result < ( ) > ;
@@ -32,9 +35,14 @@ pub trait Check {
3235 async fn check ( & self , receipt : & ReceiptWithState < Checking > ) -> CheckResult ;
3336}
3437
35- #[ async_trait:: async_trait]
3638pub trait CheckBatch {
37- async fn check_batch ( & self , receipts : & [ ReceiptWithState < Checking > ] ) -> Vec < CheckResult > ;
39+ fn check_batch (
40+ & self ,
41+ receipts : Vec < ReceiptWithState < Checking > > ,
42+ ) -> (
43+ Vec < ReceiptWithState < Checking > > ,
44+ Vec < ReceiptWithState < Failed > > ,
45+ ) ;
3846}
3947
4048#[ derive( Debug ) ]
@@ -70,6 +78,58 @@ impl Check for TimestampCheck {
7078 }
7179}
7280
81+ pub struct BatchTimestampCheck ( pub u64 ) ;
82+
83+ impl CheckBatch for BatchTimestampCheck {
84+ fn check_batch (
85+ & self ,
86+ receipts : Vec < ReceiptWithState < Checking > > ,
87+ ) -> (
88+ Vec < ReceiptWithState < Checking > > ,
89+ Vec < ReceiptWithState < Failed > > ,
90+ ) {
91+ let ( mut checking, mut failed) = ( vec ! [ ] , vec ! [ ] ) ;
92+ for receipt in receipts. into_iter ( ) {
93+ let receipt_timestamp_ns = receipt. signed_receipt ( ) . message . timestamp_ns ;
94+ let min_timestamp_ns = self . 0 ;
95+ if receipt_timestamp_ns >= min_timestamp_ns {
96+ checking. push ( receipt) ;
97+ } else {
98+ failed. push ( receipt. perform_state_error ( ReceiptError :: InvalidTimestamp {
99+ received_timestamp : receipt_timestamp_ns,
100+ timestamp_min : min_timestamp_ns,
101+ } ) ) ;
102+ }
103+ }
104+ ( checking, failed)
105+ }
106+ }
107+
108+ pub struct UniqueCheck ;
109+
110+ impl CheckBatch for UniqueCheck {
111+ fn check_batch (
112+ & self ,
113+ receipts : Vec < ReceiptWithState < Checking > > ,
114+ ) -> (
115+ Vec < ReceiptWithState < Checking > > ,
116+ Vec < ReceiptWithState < Failed > > ,
117+ ) {
118+ let mut signatures: HashSet < ethers:: types:: Signature > = HashSet :: new ( ) ;
119+ let ( mut checking, mut failed) = ( vec ! [ ] , vec ! [ ] ) ;
120+
121+ for received_receipt in receipts. into_iter ( ) {
122+ let signature = received_receipt. signed_receipt . signature ;
123+ if signatures. insert ( signature) {
124+ checking. push ( received_receipt) ;
125+ } else {
126+ failed. push ( received_receipt. perform_state_error ( ReceiptError :: NonUniqueReceipt ) ) ;
127+ }
128+ }
129+ ( checking, failed)
130+ }
131+ }
132+
73133#[ cfg( feature = "mock" ) ]
74134pub mod mock {
75135
@@ -96,26 +156,6 @@ pub mod mock {
96156 ]
97157 }
98158
99- struct UniqueCheck ;
100-
101- #[ async_trait:: async_trait]
102- impl CheckBatch for UniqueCheck {
103- async fn check_batch ( & self , receipts : & [ ReceiptWithState < Checking > ] ) -> Vec < CheckResult > {
104- let mut signatures: HashSet < ethers:: types:: Signature > = HashSet :: new ( ) ;
105- let mut results = Vec :: new ( ) ;
106-
107- for received_receipt in receipts {
108- let signature = received_receipt. signed_receipt . signature ;
109- if signatures. insert ( signature) {
110- results. push ( Ok ( ( ) ) ) ;
111- } else {
112- results. push ( Err ( ReceiptError :: NonUniqueReceipt . into ( ) ) ) ;
113- }
114- }
115- results
116- }
117- }
118-
119159 struct ValueCheck {
120160 query_appraisals : Arc < RwLock < HashMap < MessageId , u128 > > > ,
121161 }
0 commit comments