11// Copyright 2023-, Semiotic AI, Inc.
22// SPDX-License-Identifier: Apache-2.0
33
4- use alloy:: dyn_abi:: Eip712Domain ;
4+ use std:: marker:: PhantomData ;
5+
6+ use alloy:: { dyn_abi:: Eip712Domain , sol_types:: SolStruct } ;
57
68use super :: adapters:: {
7- RAVRead , RAVStore , ReceiptDelete , ReceiptRead , ReceiptStore , SignatureChecker ,
9+ RavRead , RavStore , ReceiptDelete , ReceiptRead , ReceiptStore , SignatureChecker ,
810} ;
911use crate :: {
10- rav:: { RavRequest , ReceiptAggregateVoucher , SignedRAV } ,
12+ rav:: { Aggregate , RavRequest } ,
1113 receipt:: {
1214 checks:: { CheckBatch , CheckList , TimestampCheck , UniqueCheck } ,
1315 state:: { Checked , Failed } ,
14- Context , ReceiptError , ReceiptWithState , SignedReceipt , WithUniqueId ,
15- WithValueAndTimestamp ,
16+ Context , ReceiptError , ReceiptWithState , WithUniqueId , WithValueAndTimestamp ,
1617 } ,
18+ signed_message:: EIP712SignedMessage ,
1719 Error ,
1820} ;
1921
20- pub struct Manager < E , Rcpt > {
22+ pub struct Manager < E , Rcpt , Rav > {
2123 /// Context that implements adapters
2224 context : E ,
2325
@@ -27,9 +29,11 @@ pub struct Manager<E, Rcpt> {
2729 /// Struct responsible for doing checks for receipt. Ownership stays with manager allowing manager
2830 /// to update configuration ( like minimum timestamp ).
2931 domain_separator : Eip712Domain ,
32+
33+ _phantom : PhantomData < Rav > ,
3034}
3135
32- impl < E , Rcpt > Manager < E , Rcpt > {
36+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav > {
3337 /// Creates new manager with provided `adapters`, any receipts received by this manager
3438 /// will complete all `required_checks` before being accepted or declined from RAV.
3539 /// `starting_min_timestamp` will be used as min timestamp until the first RAV request is created.
@@ -43,13 +47,15 @@ impl<E, Rcpt> Manager<E, Rcpt> {
4347 context,
4448 domain_separator,
4549 checks : checks. into ( ) ,
50+ _phantom : PhantomData ,
4651 }
4752 }
4853}
4954
50- impl < E , Rcpt > Manager < E , Rcpt >
55+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav >
5156where
52- E : RAVStore + SignatureChecker ,
57+ E : RavStore < Rav > + SignatureChecker ,
58+ Rav : SolStruct + PartialEq < Rav > + Sync + std:: fmt:: Debug ,
5359{
5460 /// Verify `signed_rav` matches all values on `expected_rav`, and that `signed_rav` has a valid signer.
5561 ///
@@ -59,17 +65,17 @@ where
5965 ///
6066 pub async fn verify_and_store_rav (
6167 & self ,
62- expected_rav : ReceiptAggregateVoucher ,
63- signed_rav : SignedRAV ,
68+ expected_rav : Rav ,
69+ signed_rav : EIP712SignedMessage < Rav > ,
6470 ) -> std:: result:: Result < ( ) , Error > {
6571 self . context
6672 . check_signature ( & signed_rav, & self . domain_separator )
6773 . await ?;
6874
6975 if signed_rav. message != expected_rav {
70- return Err ( Error :: InvalidReceivedRAV {
71- received_rav : signed_rav. message ,
72- expected_rav,
76+ return Err ( Error :: InvalidReceivedRav {
77+ received_rav : format ! ( "{:?}" , signed_rav. message) ,
78+ expected_rav : format ! ( "{:?}" , expected_rav ) ,
7379 } ) ;
7480 }
7581
@@ -84,11 +90,12 @@ where
8490 }
8591}
8692
87- impl < E , Rcpt > Manager < E , Rcpt >
93+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav >
8894where
89- E : RAVRead ,
95+ E : RavRead < Rav > ,
96+ Rav : SolStruct ,
9097{
91- async fn get_previous_rav ( & self ) -> Result < Option < SignedRAV > , Error > {
98+ async fn get_previous_rav ( & self ) -> Result < Option < EIP712SignedMessage < Rav > > , Error > {
9299 let previous_rav = self
93100 . context
94101 . last_rav ( )
@@ -100,7 +107,7 @@ where
100107 }
101108}
102109
103- impl < E , Rcpt > Manager < E , Rcpt >
110+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav >
104111where
105112 E : ReceiptRead < Rcpt > + SignatureChecker ,
106113 Rcpt : WithUniqueId + WithValueAndTimestamp + Sync ,
@@ -162,11 +169,11 @@ where
162169 }
163170}
164171
165- // TODO make create_rav_request generic over receipt
166- impl < E > Manager < E , SignedReceipt >
172+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav >
167173where
168- E : ReceiptRead < SignedReceipt > + RAVRead + SignatureChecker ,
169- //Rcpt: WithUniqueId + WithValueAndTimestamp + Sync,
174+ E : ReceiptRead < Rcpt > + RavRead < Rav > + SignatureChecker ,
175+ Rav : SolStruct + WithValueAndTimestamp + Clone + Aggregate < Rcpt > ,
176+ Rcpt : WithUniqueId + WithValueAndTimestamp + Sync ,
170177{
171178 /// Completes remaining checks on all receipts up to
172179 /// (current time - `timestamp_buffer_ns`). Returns them in two lists
@@ -188,18 +195,18 @@ where
188195 ctx : & Context ,
189196 timestamp_buffer_ns : u64 ,
190197 receipts_limit : Option < u64 > ,
191- ) -> Result < RavRequest < SignedReceipt > , Error > {
198+ ) -> Result < RavRequest < Rcpt , Rav > , Error > {
192199 let previous_rav = self . get_previous_rav ( ) . await ?;
193200 let min_timestamp_ns = previous_rav
194201 . as_ref ( )
195- . map ( |rav| rav. message . timestampNs + 1 )
202+ . map ( |rav| rav. message . timestamp_ns ( ) + 1 )
196203 . unwrap_or ( 0 ) ;
197204
198205 let ( valid_receipts, invalid_receipts) = self
199206 . collect_receipts ( ctx, timestamp_buffer_ns, min_timestamp_ns, receipts_limit)
200207 . await ?;
201208
202- let expected_rav = Self :: generate_expected_rav ( & valid_receipts, previous_rav. clone ( ) ) ;
209+ let expected_rav = Rav :: aggregate_receipts ( & valid_receipts, previous_rav. clone ( ) ) ;
203210
204211 Ok ( RavRequest {
205212 valid_receipts,
@@ -208,30 +215,12 @@ where
208215 expected_rav,
209216 } )
210217 }
211-
212- fn generate_expected_rav (
213- receipts : & [ ReceiptWithState < Checked , SignedReceipt > ] ,
214- previous_rav : Option < SignedRAV > ,
215- ) -> Result < ReceiptAggregateVoucher , Error > {
216- if receipts. is_empty ( ) {
217- return Err ( Error :: NoValidReceiptsForRavRequest ) ;
218- }
219- let allocation_id = receipts[ 0 ] . signed_receipt ( ) . message . allocation_id ;
220- let receipts = receipts
221- . iter ( )
222- . map ( |rx_receipt| rx_receipt. signed_receipt ( ) . clone ( ) )
223- . collect :: < Vec < _ > > ( ) ;
224- ReceiptAggregateVoucher :: aggregate_receipts (
225- allocation_id,
226- receipts. as_slice ( ) ,
227- previous_rav,
228- )
229- }
230218}
231219
232- impl < E , Rcpt > Manager < E , Rcpt >
220+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav >
233221where
234- E : ReceiptDelete + RAVRead ,
222+ E : ReceiptDelete + RavRead < Rav > ,
223+ Rav : SolStruct + WithValueAndTimestamp ,
235224{
236225 /// Removes obsolete receipts from storage. Obsolete receipts are receipts
237226 /// that are older than the last RAV, and therefore already aggregated into the RAV.
@@ -247,7 +236,7 @@ where
247236 match self . get_previous_rav ( ) . await ? {
248237 Some ( last_rav) => {
249238 self . context
250- . remove_receipts_in_timestamp_range ( ..=last_rav. message . timestampNs )
239+ . remove_receipts_in_timestamp_range ( ..=last_rav. message . timestamp_ns ( ) )
251240 . await
252241 . map_err ( |err| Error :: AdapterError {
253242 source_error : anyhow:: Error :: new ( err) ,
@@ -259,7 +248,7 @@ where
259248 }
260249}
261250
262- impl < E , Rcpt > Manager < E , Rcpt >
251+ impl < E , Rcpt , Rav > Manager < E , Rcpt , Rav >
263252where
264253 E : ReceiptStore < Rcpt > ,
265254{
0 commit comments