Skip to content

Commit 6885d9c

Browse files
committed
feat: allow manager to interact with different rav and receipt
Signed-off-by: Gustavo Inacio <[email protected]>
1 parent eaef977 commit 6885d9c

File tree

17 files changed

+351
-201
lines changed

17 files changed

+351
-201
lines changed

tap_core/src/error.rs

Lines changed: 3 additions & 3 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)]
@@ -38,8 +38,8 @@ pub enum Error {
3838
/// Error when the received RAV does not match the expected RAV
3939
#[error("Received RAV does not match expexted RAV")]
4040
InvalidReceivedRAV {
41-
received_rav: ReceiptAggregateVoucher,
42-
expected_rav: ReceiptAggregateVoucher,
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/escrow.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Copyright 2023-, Semiotic AI, Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use alloy::{dyn_abi::Eip712Domain, primitives::Address};
4+
use alloy::{dyn_abi::Eip712Domain, primitives::Address, sol_types::SolStruct};
55
use async_trait::async_trait;
66

77
use crate::{
8-
rav::SignedRAV,
8+
manager::WithValueAndTimestamp,
99
receipt::{state::AwaitingReserve, ReceiptError, ReceiptResult, ReceiptWithState},
10+
signed_message::EIP712SignedMessage,
1011
Error,
1112
};
1213

@@ -41,9 +42,9 @@ pub trait EscrowHandler: Send + Sync {
4142
async fn verify_signer(&self, signer_address: Address) -> Result<bool, Self::AdapterError>;
4243

4344
/// Checks and reserves escrow for the received receipt
44-
async fn check_and_reserve_escrow(
45+
async fn check_and_reserve_escrow<T: SolStruct + WithValueAndTimestamp + Sync>(
4546
&self,
46-
received_receipt: &ReceiptWithState<AwaitingReserve>,
47+
received_receipt: &ReceiptWithState<AwaitingReserve, T>,
4748
domain_separator: &Eip712Domain,
4849
) -> ReceiptResult<()> {
4950
let signed_receipt = &received_receipt.signed_receipt;
@@ -55,7 +56,7 @@ pub trait EscrowHandler: Send + Sync {
5556
})?;
5657

5758
if self
58-
.subtract_escrow(receipt_signer_address, signed_receipt.message.value)
59+
.subtract_escrow(receipt_signer_address, signed_receipt.message.value())
5960
.await
6061
.is_err()
6162
{
@@ -66,9 +67,9 @@ pub trait EscrowHandler: Send + Sync {
6667
}
6768

6869
/// Checks the signature of the RAV
69-
async fn check_rav_signature(
70+
async fn check_rav_signature<R: SolStruct + Sync>(
7071
&self,
71-
signed_rav: &SignedRAV,
72+
signed_rav: &EIP712SignedMessage<R>,
7273
domain_separator: &Eip712Domain,
7374
) -> Result<(), Error> {
7475
let recovered_address = signed_rav.recover_signer(domain_separator)?;

tap_core/src/manager/adapters/rav.rs

Lines changed: 12 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,10 @@ 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>
17+
where
18+
T: SolStruct,
19+
{
1620
/// Defines the user-specified error type.
1721
///
1822
/// This error type should implement the `Error` and `Debug` traits from
@@ -25,7 +29,7 @@ pub trait RAVStore {
2529
/// This method should be implemented to store the most recent validated
2630
/// `SignedRAV` into your chosen storage system. Any errors that occur
2731
/// during this process should be captured and returned as an `AdapterError`.
28-
async fn update_last_rav(&self, rav: SignedRAV) -> Result<(), Self::AdapterError>;
32+
async fn update_last_rav(&self, rav: EIP712SignedMessage<T>) -> Result<(), Self::AdapterError>;
2933
}
3034

3135
/// Reads the RAV from storage
@@ -35,7 +39,10 @@ pub trait RAVStore {
3539
/// For example code see [crate::manager::context::memory::RAVStorage]
3640
3741
#[async_trait]
38-
pub trait RAVRead {
42+
pub trait RAVRead<T>
43+
where
44+
T: SolStruct,
45+
{
3946
/// Defines the user-specified error type.
4047
///
4148
/// This error type should implement the `Error` and `Debug` traits from
@@ -46,5 +53,5 @@ pub trait RAVRead {
4653
/// Retrieves the latest `SignedRAV` from the storage.
4754
///
4855
/// If no `SignedRAV` is available, this method should return `None`.
49-
async fn last_rav(&self) -> Result<Option<SignedRAV>, Self::AdapterError>;
56+
async fn last_rav(&self) -> Result<Option<EIP712SignedMessage<T>>, Self::AdapterError>;
5057
}

tap_core/src/manager/adapters/receipt.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33

44
use std::ops::RangeBounds;
55

6+
use alloy::sol_types::SolStruct;
67
use async_trait::async_trait;
78

8-
use crate::receipt::{
9-
state::{Checking, ReceiptState},
10-
ReceiptWithState,
9+
use crate::{
10+
manager::WithValueAndTimestamp,
11+
receipt::{
12+
state::{Checking, ReceiptState},
13+
ReceiptWithState,
14+
},
1115
};
1216

1317
/// Stores receipts in the storage.
@@ -16,7 +20,10 @@ use crate::receipt::{
1620
///
1721
/// For example code see [crate::manager::context::memory::ReceiptStorage]
1822
#[async_trait]
19-
pub trait ReceiptStore {
23+
pub trait ReceiptStore<T>
24+
where
25+
T: SolStruct,
26+
{
2027
/// Defines the user-specified error type.
2128
///
2229
/// This error type should implement the `Error` and `Debug` traits from the standard library.
@@ -29,7 +36,7 @@ pub trait ReceiptStore {
2936
/// this process should be captured and returned as an `AdapterError`.
3037
async fn store_receipt(
3138
&self,
32-
receipt: ReceiptWithState<Checking>,
39+
receipt: ReceiptWithState<Checking, T>,
3340
) -> Result<u64, Self::AdapterError>;
3441
}
3542

@@ -62,7 +69,10 @@ pub trait ReceiptDelete {
6269
///
6370
/// For example code see [crate::manager::context::memory::ReceiptStorage]
6471
#[async_trait]
65-
pub trait ReceiptRead {
72+
pub trait ReceiptRead<T>
73+
where
74+
T: SolStruct,
75+
{
6676
/// Defines the user-specified error type.
6777
///
6878
/// This error type should implement the `Error` and `Debug` traits from
@@ -92,15 +102,15 @@ pub trait ReceiptRead {
92102
&self,
93103
timestamp_range_ns: R,
94104
limit: Option<u64>,
95-
) -> Result<Vec<ReceiptWithState<Checking>>, Self::AdapterError>;
105+
) -> Result<Vec<ReceiptWithState<Checking, T>>, Self::AdapterError>;
96106
}
97107

98108
/// See [`ReceiptRead::retrieve_receipts_in_timestamp_range()`] for details.
99109
///
100110
/// WARNING: Will sort the receipts by timestamp using
101111
/// [vec::sort_unstable](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.sort_unstable).
102-
pub fn safe_truncate_receipts<T: ReceiptState>(
103-
receipts: &mut Vec<ReceiptWithState<T>>,
112+
pub fn safe_truncate_receipts<T: ReceiptState, R: SolStruct + WithValueAndTimestamp>(
113+
receipts: &mut Vec<ReceiptWithState<T, R>>,
104114
limit: u64,
105115
) {
106116
if receipts.len() <= limit as usize {
@@ -110,27 +120,26 @@ pub fn safe_truncate_receipts<T: ReceiptState>(
110120
return;
111121
}
112122

113-
receipts.sort_unstable_by_key(|rx_receipt| rx_receipt.signed_receipt().message.timestamp_ns);
123+
receipts.sort_unstable_by_key(|rx_receipt| rx_receipt.signed_receipt().message.timestamp());
114124

115125
// This one will be the last timestamp in `receipts` after naive truncation
116126
let last_timestamp = receipts[limit as usize - 1]
117127
.signed_receipt()
118128
.message
119-
.timestamp_ns;
129+
.timestamp();
120130
// This one is the timestamp that comes just after the one above
121131
let after_last_timestamp = receipts[limit as usize]
122132
.signed_receipt()
123133
.message
124-
.timestamp_ns;
134+
.timestamp();
125135

126136
receipts.truncate(limit as usize);
127137

128138
if last_timestamp == after_last_timestamp {
129139
// If the last timestamp is the same as the one that came after it, we need to
130140
// remove all the receipts with the same timestamp as the last one, because
131141
// otherwise we would leave behind part of the receipts for that timestamp.
132-
receipts.retain(|rx_receipt| {
133-
rx_receipt.signed_receipt().message.timestamp_ns != last_timestamp
134-
});
142+
receipts
143+
.retain(|rx_receipt| rx_receipt.signed_receipt().message.timestamp() != last_timestamp);
135144
}
136145
}

tap_core/src/manager/context/memory.rs

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

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

2525
pub type EscrowStorage = Arc<RwLock<HashMap<Address, u128>>>;
2626
pub type QueryAppraisals = Arc<RwLock<HashMap<MessageId, u128>>>;
27-
pub type ReceiptStorage = Arc<RwLock<HashMap<u64, ReceiptWithState<Checking>>>>;
27+
pub type ReceiptStorage = Arc<RwLock<HashMap<u64, ReceiptWithState<Checking, Receipt>>>>;
2828
pub type RAVStorage = Arc<RwLock<Option<SignedRAV>>>;
2929

3030
use thiserror::Error;
@@ -71,7 +71,7 @@ impl InMemoryContext {
7171
pub async fn retrieve_receipt_by_id(
7272
&self,
7373
receipt_id: u64,
74-
) -> Result<ReceiptWithState<Checking>, InMemoryError> {
74+
) -> Result<ReceiptWithState<Checking, Receipt>, InMemoryError> {
7575
let receipt_storage = self.receipt_storage.read().unwrap();
7676

7777
receipt_storage
@@ -85,7 +85,7 @@ impl InMemoryContext {
8585
pub async fn retrieve_receipts_by_timestamp(
8686
&self,
8787
timestamp_ns: u64,
88-
) -> Result<Vec<(u64, ReceiptWithState<Checking>)>, InMemoryError> {
88+
) -> Result<Vec<(u64, ReceiptWithState<Checking, Receipt>)>, InMemoryError> {
8989
let receipt_storage = self.receipt_storage.read().unwrap();
9090
Ok(receipt_storage
9191
.iter()
@@ -99,7 +99,7 @@ impl InMemoryContext {
9999
pub async fn retrieve_receipts_upto_timestamp(
100100
&self,
101101
timestamp_ns: u64,
102-
) -> Result<Vec<ReceiptWithState<Checking>>, InMemoryError> {
102+
) -> Result<Vec<ReceiptWithState<Checking, Receipt>>, InMemoryError> {
103103
self.retrieve_receipts_in_timestamp_range(..=timestamp_ns, None)
104104
.await
105105
}
@@ -125,7 +125,7 @@ impl InMemoryContext {
125125
}
126126

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

131131
async fn update_last_rav(&self, rav: SignedRAV) -> Result<(), Self::AdapterError> {
@@ -138,7 +138,7 @@ 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

144144
async fn last_rav(&self) -> Result<Option<SignedRAV>, Self::AdapterError> {
@@ -147,12 +147,12 @@ impl RAVRead for InMemoryContext {
147147
}
148148

149149
#[async_trait]
150-
impl ReceiptStore for InMemoryContext {
150+
impl ReceiptStore<Receipt> for InMemoryContext {
151151
type AdapterError = InMemoryError;
152152

153153
async fn store_receipt(
154154
&self,
155-
receipt: ReceiptWithState<Checking>,
155+
receipt: ReceiptWithState<Checking, Receipt>,
156156
) -> Result<u64, Self::AdapterError> {
157157
let mut id_pointer = self.unique_id.write().unwrap();
158158
let id_previous = *id_pointer;
@@ -179,15 +179,15 @@ impl ReceiptDelete for InMemoryContext {
179179
}
180180
}
181181
#[async_trait]
182-
impl ReceiptRead for InMemoryContext {
182+
impl ReceiptRead<Receipt> for InMemoryContext {
183183
type AdapterError = InMemoryError;
184184
async fn retrieve_receipts_in_timestamp_range<R: RangeBounds<u64> + std::marker::Send>(
185185
&self,
186186
timestamp_range_ns: R,
187187
limit: Option<u64>,
188-
) -> Result<Vec<ReceiptWithState<Checking>>, Self::AdapterError> {
188+
) -> Result<Vec<ReceiptWithState<Checking, Receipt>>, Self::AdapterError> {
189189
let receipt_storage = self.receipt_storage.read().unwrap();
190-
let mut receipts_in_range: Vec<ReceiptWithState<Checking>> = receipt_storage
190+
let mut receipts_in_range: Vec<ReceiptWithState<Checking, Receipt>> = receipt_storage
191191
.iter()
192192
.filter(|(_, rx_receipt)| {
193193
timestamp_range_ns.contains(&rx_receipt.signed_receipt().message.timestamp_ns)
@@ -274,7 +274,7 @@ pub mod checks {
274274
receipt::{
275275
checks::{Check, CheckError, CheckResult, ReceiptCheck},
276276
state::Checking,
277-
Context, ReceiptError, ReceiptWithState,
277+
Context, Receipt, ReceiptError, ReceiptWithState,
278278
},
279279
signed_message::MessageId,
280280
};
@@ -284,7 +284,7 @@ pub mod checks {
284284
valid_signers: HashSet<Address>,
285285
allocation_ids: Arc<RwLock<HashSet<Address>>>,
286286
_query_appraisals: Arc<RwLock<HashMap<MessageId, u128>>>,
287-
) -> Vec<ReceiptCheck> {
287+
) -> Vec<ReceiptCheck<Receipt>> {
288288
vec![
289289
// Arc::new(UniqueCheck ),
290290
// Arc::new(ValueCheck { query_appraisals }),
@@ -301,8 +301,12 @@ pub mod checks {
301301
}
302302

303303
#[async_trait::async_trait]
304-
impl Check for AllocationIdCheck {
305-
async fn check(&self, _: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult {
304+
impl Check<Receipt> for AllocationIdCheck {
305+
async fn check(
306+
&self,
307+
_: &Context,
308+
receipt: &ReceiptWithState<Checking, Receipt>,
309+
) -> CheckResult {
306310
let received_allocation_id = receipt.signed_receipt().message.allocation_id;
307311
if self
308312
.allocation_ids
@@ -328,8 +332,12 @@ pub mod checks {
328332
}
329333

330334
#[async_trait::async_trait]
331-
impl Check for SignatureCheck {
332-
async fn check(&self, _: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult {
335+
impl Check<Receipt> for SignatureCheck {
336+
async fn check(
337+
&self,
338+
_: &Context,
339+
receipt: &ReceiptWithState<Checking, Receipt>,
340+
) -> CheckResult {
333341
let recovered_address = receipt
334342
.signed_receipt()
335343
.recover_signer(&self.domain_separator)

0 commit comments

Comments
 (0)