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,59 @@ impl Check for TimestampCheck {
7078 }
7179}
7280
81+ /// Timestamp Check verifies if the receipt is **greater or equal** than the minimum timestamp provided.
82+ pub struct BatchTimestampCheck ( pub u64 ) ;
83+
84+ impl CheckBatch for BatchTimestampCheck {
85+ fn check_batch (
86+ & self ,
87+ receipts : Vec < ReceiptWithState < Checking > > ,
88+ ) -> (
89+ Vec < ReceiptWithState < Checking > > ,
90+ Vec < ReceiptWithState < Failed > > ,
91+ ) {
92+ let ( mut checking, mut failed) = ( vec ! [ ] , vec ! [ ] ) ;
93+ for receipt in receipts. into_iter ( ) {
94+ let receipt_timestamp_ns = receipt. signed_receipt ( ) . message . timestamp_ns ;
95+ let min_timestamp_ns = self . 0 ;
96+ if receipt_timestamp_ns >= min_timestamp_ns {
97+ checking. push ( receipt) ;
98+ } else {
99+ failed. push ( receipt. perform_state_error ( ReceiptError :: InvalidTimestamp {
100+ received_timestamp : receipt_timestamp_ns,
101+ timestamp_min : min_timestamp_ns,
102+ } ) ) ;
103+ }
104+ }
105+ ( checking, failed)
106+ }
107+ }
108+
109+ pub struct UniqueCheck ;
110+
111+ impl CheckBatch for UniqueCheck {
112+ fn check_batch (
113+ & self ,
114+ receipts : Vec < ReceiptWithState < Checking > > ,
115+ ) -> (
116+ Vec < ReceiptWithState < Checking > > ,
117+ Vec < ReceiptWithState < Failed > > ,
118+ ) {
119+ let mut signatures: HashSet < ethers:: types:: Signature > = HashSet :: new ( ) ;
120+ let ( mut checking, mut failed) = ( vec ! [ ] , vec ! [ ] ) ;
121+
122+ for received_receipt in receipts. into_iter ( ) {
123+ let signature = received_receipt. signed_receipt . signature ;
124+ if signatures. insert ( signature) {
125+ checking. push ( received_receipt) ;
126+ } else {
127+ failed. push ( received_receipt. perform_state_error ( ReceiptError :: NonUniqueReceipt ) ) ;
128+ }
129+ }
130+ ( checking, failed)
131+ }
132+ }
133+
73134#[ cfg( feature = "mock" ) ]
74135pub mod mock {
75136
@@ -96,26 +157,6 @@ pub mod mock {
96157 ]
97158 }
98159
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-
119160 struct ValueCheck {
120161 query_appraisals : Arc < RwLock < HashMap < MessageId , u128 > > > ,
121162 }
0 commit comments