Skip to content

Commit 1fc51a3

Browse files
authored
refactor!: make manager generic over rav (#267)
* refactor!: make manager generic over rav Signed-off-by: Gustavo Inacio <[email protected]> * chore: remove todo Signed-off-by: Gustavo Inacio <[email protected]> * refactor!: rename RAVStore and RAVRead to RavStore and RavRead Signed-off-by: Gustavo Inacio <[email protected]> * refactor!: rename SignedRAV to SignedRav Signed-off-by: Gustavo Inacio <[email protected]> --------- Signed-off-by: Gustavo Inacio <[email protected]>
1 parent 25a3316 commit 1fc51a3

File tree

13 files changed

+138
-97
lines changed

13 files changed

+138
-97
lines changed

tap_aggregator/src/grpc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl From<u128> for Uint128 {
114114
impl RavRequest {
115115
pub fn new(
116116
receipts: Vec<tap_core::receipt::SignedReceipt>,
117-
previous_rav: Option<tap_core::rav::SignedRAV>,
117+
previous_rav: Option<tap_core::rav::SignedRav>,
118118
) -> Self {
119119
Self {
120120
receipts: receipts.into_iter().map(Into::into).collect(),
@@ -124,8 +124,8 @@ impl RavRequest {
124124
}
125125

126126
impl RavResponse {
127-
pub fn signed_rav(mut self) -> anyhow::Result<tap_core::rav::SignedRAV> {
128-
let signed_rav: tap_core::rav::SignedRAV = self
127+
pub fn signed_rav(mut self) -> anyhow::Result<tap_core::rav::SignedRav> {
128+
let signed_rav: tap_core::rav::SignedRav = self
129129
.rav
130130
.take()
131131
.ok_or(anyhow!("Couldn't find rav"))?

tap_aggregator/tests/aggregate_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ async fn aggregation_test() {
6464

6565
let rav_request = RavRequest::new(receipts.clone(), None);
6666
let res = client.aggregate_receipts(rav_request).await.unwrap();
67-
let signed_rav: tap_core::rav::SignedRAV = res.into_inner().signed_rav().unwrap();
67+
let signed_rav: tap_core::rav::SignedRav = res.into_inner().signed_rav().unwrap();
6868

6969
let sender_aggregator = HttpClientBuilder::default().build(&endpoint).unwrap();
7070

71-
let previous_rav: Option<tap_core::rav::SignedRAV> = None;
71+
let previous_rav: Option<tap_core::rav::SignedRav> = None;
7272

7373
let response: JsonRpcResponse<EIP712SignedMessage<ReceiptAggregateVoucher>> = sender_aggregator
7474
.request(

tap_core/src/error.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::result::Result as StdResult;
99
use alloy::primitives::{Address, SignatureError};
1010
use thiserror::Error as ThisError;
1111

12-
use crate::{rav::ReceiptAggregateVoucher, receipt::ReceiptError};
12+
use crate::receipt::ReceiptError;
1313

1414
/// Error type for the TAP protocol
1515
#[derive(ThisError, Debug)]
@@ -36,10 +36,10 @@ pub enum Error {
3636
},
3737

3838
/// Error when the received RAV does not match the expected RAV
39-
#[error("Received RAV does not match expexted RAV")]
40-
InvalidReceivedRAV {
41-
received_rav: ReceiptAggregateVoucher,
42-
expected_rav: ReceiptAggregateVoucher,
39+
#[error("Received RAV does not match expected RAV")]
40+
InvalidReceivedRav {
41+
received_rav: String,
42+
expected_rav: String,
4343
},
4444
/// Generic error from the adapter
4545
#[error("Error from adapter.\n Caused by: {source_error}")]

tap_core/src/manager/adapters/rav.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Copyright 2023-, Semiotic AI, Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use alloy::sol_types::SolStruct;
45
use async_trait::async_trait;
56

6-
use crate::rav::SignedRAV;
7+
use crate::signed_message::EIP712SignedMessage;
78

89
/// Stores the latest RAV in the storage.
910
///
@@ -12,7 +13,7 @@ use crate::rav::SignedRAV;
1213
/// For example code see [crate::manager::context::memory::RAVStorage]
1314
1415
#[async_trait]
15-
pub trait RAVStore {
16+
pub trait RavStore<T: SolStruct> {
1617
/// Defines the user-specified error type.
1718
///
1819
/// This error type should implement the `Error` and `Debug` traits from
@@ -25,7 +26,7 @@ pub trait RAVStore {
2526
/// This method should be implemented to store the most recent validated
2627
/// `SignedRAV` into your chosen storage system. Any errors that occur
2728
/// during this process should be captured and returned as an `AdapterError`.
28-
async fn update_last_rav(&self, rav: SignedRAV) -> Result<(), Self::AdapterError>;
29+
async fn update_last_rav(&self, rav: EIP712SignedMessage<T>) -> Result<(), Self::AdapterError>;
2930
}
3031

3132
/// Reads the RAV from storage
@@ -35,7 +36,7 @@ pub trait RAVStore {
3536
/// For example code see [crate::manager::context::memory::RAVStorage]
3637
3738
#[async_trait]
38-
pub trait RAVRead {
39+
pub trait RavRead<T: SolStruct> {
3940
/// Defines the user-specified error type.
4041
///
4142
/// This error type should implement the `Error` and `Debug` traits from
@@ -46,5 +47,5 @@ pub trait RAVRead {
4647
/// Retrieves the latest `SignedRAV` from the storage.
4748
///
4849
/// If no `SignedRAV` is available, this method should return `None`.
49-
async fn last_rav(&self) -> Result<Option<SignedRAV>, Self::AdapterError>;
50+
async fn last_rav(&self) -> Result<Option<EIP712SignedMessage<T>>, Self::AdapterError>;
5051
}

tap_core/src/manager/context/memory.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ use async_trait::async_trait;
1717

1818
use crate::{
1919
manager::adapters::*,
20-
rav::SignedRAV,
20+
rav::{ReceiptAggregateVoucher, SignedRav},
2121
receipt::{checks::StatefulTimestampCheck, state::Checking, ReceiptWithState, SignedReceipt},
2222
signed_message::MessageId,
2323
};
2424

2525
pub type EscrowStorage = Arc<RwLock<HashMap<Address, u128>>>;
2626
pub type QueryAppraisals = Arc<RwLock<HashMap<MessageId, u128>>>;
2727
pub type ReceiptStorage = Arc<RwLock<HashMap<u64, ReceiptWithState<Checking, SignedReceipt>>>>;
28-
pub type RAVStorage = Arc<RwLock<Option<SignedRAV>>>;
28+
pub type RAVStorage = Arc<RwLock<Option<SignedRav>>>;
2929

3030
use thiserror::Error;
3131

@@ -125,10 +125,10 @@ impl InMemoryContext {
125125
}
126126

127127
#[async_trait]
128-
impl RAVStore for InMemoryContext {
128+
impl RavStore<ReceiptAggregateVoucher> for InMemoryContext {
129129
type AdapterError = InMemoryError;
130130

131-
async fn update_last_rav(&self, rav: SignedRAV) -> Result<(), Self::AdapterError> {
131+
async fn update_last_rav(&self, rav: SignedRav) -> Result<(), Self::AdapterError> {
132132
let mut rav_storage = self.rav_storage.write().unwrap();
133133
let timestamp = rav.message.timestampNs;
134134
*rav_storage = Some(rav);
@@ -138,10 +138,10 @@ impl RAVStore for InMemoryContext {
138138
}
139139

140140
#[async_trait]
141-
impl RAVRead for InMemoryContext {
141+
impl RavRead<ReceiptAggregateVoucher> for InMemoryContext {
142142
type AdapterError = InMemoryError;
143143

144-
async fn last_rav(&self) -> Result<Option<SignedRAV>, Self::AdapterError> {
144+
async fn last_rav(&self) -> Result<Option<SignedRav>, Self::AdapterError> {
145145
Ok(self.rav_storage.read().unwrap().clone())
146146
}
147147
}

tap_core/src/manager/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
//! ReceiptError,
4343
//! Context
4444
//! },
45+
//! rav::ReceiptAggregateVoucher,
4546
//! manager::{
4647
//! Manager,
4748
//! adapters::ReceiptStore
@@ -70,7 +71,7 @@
7071
//!
7172
//! let receipt = EIP712SignedMessage::new(&domain_separator, message, &wallet).unwrap();
7273
//!
73-
//! let manager = Manager::new(domain_separator, MyContext, CheckList::empty());
74+
//! let manager = Manager::<_, _, ReceiptAggregateVoucher>::new(domain_separator, MyContext, CheckList::empty());
7475
//! manager.verify_and_store_receipt(&Context::new(), receipt).await.unwrap()
7576
//! # }
7677
//! ```

tap_core/src/manager/tap_manager.rs

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
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

68
use super::adapters::{
7-
RAVRead, RAVStore, ReceiptDelete, ReceiptRead, ReceiptStore, SignatureChecker,
9+
RavRead, RavStore, ReceiptDelete, ReceiptRead, ReceiptStore, SignatureChecker,
810
};
911
use 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>
5156
where
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>
8894
where
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>
104111
where
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>
167173
where
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>
233221
where
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>
263252
where
264253
E: ReceiptStore<Rcpt>,
265254
{

0 commit comments

Comments
 (0)