Skip to content

Commit 76a46f1

Browse files
committed
feat!: add context to checks
BREAKING CHANGE Signed-off-by: Gustavo Inacio <[email protected]>
1 parent ff856d9 commit 76a46f1

File tree

11 files changed

+70
-41
lines changed

11 files changed

+70
-41
lines changed

tap_core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ anyhow.workspace = true
1515
rand.workspace = true
1616
thiserror = "1.0.38"
1717
async-trait = "0.1.72"
18+
anymap3 = "1.0.0"
1819

1920
[dev-dependencies]
2021
criterion = { version = "0.5", features = ["async_std"] }

tap_core/src/manager/context/memory.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ pub mod checks {
263263
receipt::{
264264
checks::{Check, CheckError, CheckResult, ReceiptCheck},
265265
state::Checking,
266-
ReceiptError, ReceiptWithState,
266+
Context, ReceiptError, ReceiptWithState,
267267
},
268268
signed_message::MessageId,
269269
};
@@ -296,7 +296,7 @@ pub mod checks {
296296

297297
#[async_trait::async_trait]
298298
impl Check for AllocationIdCheck {
299-
async fn check(&self, receipt: &ReceiptWithState<Checking>) -> CheckResult {
299+
async fn check(&self, _: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult {
300300
let received_allocation_id = receipt.signed_receipt().message.allocation_id;
301301
if self
302302
.allocation_ids
@@ -323,7 +323,7 @@ pub mod checks {
323323

324324
#[async_trait::async_trait]
325325
impl Check for SignatureCheck {
326-
async fn check(&self, receipt: &ReceiptWithState<Checking>) -> CheckResult {
326+
async fn check(&self, _: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult {
327327
let recovered_address = receipt
328328
.signed_receipt()
329329
.recover_signer(&self.domain_separator)

tap_core/src/manager/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
//! ReceiptWithState,
4040
//! state::Checking,
4141
//! checks::CheckList,
42-
//! ReceiptError
42+
//! ReceiptError,
43+
//! Context
4344
//! },
4445
//! manager::{
4546
//! Manager,
@@ -70,7 +71,7 @@
7071
//! let receipt = EIP712SignedMessage::new(&domain_separator, message, &wallet).unwrap();
7172
//!
7273
//! let manager = Manager::new(domain_separator, MyContext, CheckList::empty());
73-
//! manager.verify_and_store_receipt(receipt).await.unwrap()
74+
//! manager.verify_and_store_receipt(Context::new(), receipt).await.unwrap()
7475
//! # }
7576
//! ```
7677
//!

tap_core/src/manager/tap_manager.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
receipt::{
1010
checks::{CheckBatch, CheckList, TimestampCheck, UniqueCheck},
1111
state::{Failed, Reserved},
12-
ReceiptError, ReceiptWithState, SignedReceipt,
12+
Context, ReceiptError, ReceiptWithState, SignedReceipt,
1313
},
1414
Error,
1515
};
@@ -99,6 +99,7 @@ where
9999
{
100100
async fn collect_receipts(
101101
&self,
102+
ctx: Context,
102103
timestamp_buffer_ns: u64,
103104
min_timestamp_ns: u64,
104105
limit: Option<u64>,
@@ -140,7 +141,7 @@ where
140141

141142
for receipt in checking_receipts.into_iter() {
142143
let receipt = receipt
143-
.finalize_receipt_checks(&self.checks)
144+
.finalize_receipt_checks(&ctx, &self.checks)
144145
.await
145146
.map_err(|e| Error::ReceiptError(ReceiptError::RetryableCheck(e)))?;
146147

@@ -194,7 +195,12 @@ where
194195
.unwrap_or(0);
195196

196197
let (valid_receipts, invalid_receipts) = self
197-
.collect_receipts(timestamp_buffer_ns, min_timestamp_ns, receipts_limit)
198+
.collect_receipts(
199+
Context::new(),
200+
timestamp_buffer_ns,
201+
min_timestamp_ns,
202+
receipts_limit,
203+
)
198204
.await?;
199205

200206
let expected_rav = Self::generate_expected_rav(&valid_receipts, previous_rav.clone());
@@ -271,12 +277,13 @@ where
271277
///
272278
pub async fn verify_and_store_receipt(
273279
&self,
280+
ctx: Context,
274281
signed_receipt: SignedReceipt,
275282
) -> std::result::Result<(), Error> {
276283
let mut received_receipt = ReceiptWithState::new(signed_receipt);
277284

278285
// perform checks
279-
received_receipt.perform_checks(&self.checks).await?;
286+
received_receipt.perform_checks(&ctx, &self.checks).await?;
280287

281288
// store the receipt
282289
self.context

tap_core/src/rav.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
//! 1. Create a [`RAVRequest`] with the valid receipts and the previous RAV.
2727
//! 2. Send the request to the aggregator.
2828
//! 3. The aggregator will verify the request and increment the total amount that
29-
//! has been aggregated.
29+
//! has been aggregated.
3030
//! 4. The aggregator will return a [`SignedRAV`].
3131
//! 5. Store the [`SignedRAV`].
3232
//! 6. Repeat the process until the allocation is closed.

tap_core/src/receipt/checks.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
//! # use std::sync::Arc;
1313
//! use tap_core::{
1414
//! receipt::checks::{Check, CheckResult, ReceiptCheck},
15-
//! receipt::{ReceiptWithState, state::Checking}
15+
//! receipt::{Context, ReceiptWithState, state::Checking}
1616
//! };
1717
//! # use async_trait::async_trait;
1818
//!
1919
//! struct MyCheck;
2020
//!
2121
//! #[async_trait]
2222
//! impl Check for MyCheck {
23-
//! async fn check(&self, receipt: &ReceiptWithState<Checking>) -> CheckResult {
23+
//! async fn check(&self, ctx: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult {
2424
//! // Implement your check here
2525
//! Ok(())
2626
//! }
@@ -33,7 +33,7 @@ use crate::signed_message::{SignatureBytes, SignatureBytesExt};
3333

3434
use super::{
3535
state::{Checking, Failed},
36-
ReceiptError, ReceiptWithState,
36+
Context, ReceiptError, ReceiptWithState,
3737
};
3838
use std::{
3939
collections::HashSet,
@@ -80,7 +80,7 @@ impl Deref for CheckList {
8080
/// Check trait is implemented by the lib user to validate receipts before they are stored.
8181
#[async_trait::async_trait]
8282
pub trait Check {
83-
async fn check(&self, receipt: &ReceiptWithState<Checking>) -> CheckResult;
83+
async fn check(&self, ctx: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult;
8484
}
8585

8686
/// CheckBatch is mostly used by the lib to implement checks
@@ -119,7 +119,7 @@ impl StatefulTimestampCheck {
119119

120120
#[async_trait::async_trait]
121121
impl Check for StatefulTimestampCheck {
122-
async fn check(&self, receipt: &ReceiptWithState<Checking>) -> CheckResult {
122+
async fn check(&self, _: &Context, receipt: &ReceiptWithState<Checking>) -> CheckResult {
123123
let min_timestamp_ns = *self.min_timestamp_ns.read().unwrap();
124124
let signed_receipt = receipt.signed_receipt();
125125
if signed_receipt.message.timestamp_ns <= min_timestamp_ns {

tap_core/src/receipt/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ pub type SignedReceipt = EIP712SignedMessage<Receipt>;
3636

3737
/// Result type for receipt
3838
pub type ReceiptResult<T> = Result<T, ReceiptError>;
39+
40+
pub type Context = anymap3::Map<dyn std::any::Any + Send + Sync>;

tap_core/src/receipt/received_receipt.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use alloy::dyn_abi::Eip712Domain;
1717

1818
use super::checks::CheckError;
19-
use super::{Receipt, ReceiptError, ReceiptResult, SignedReceipt};
19+
use super::{Context, Receipt, ReceiptError, ReceiptResult, SignedReceipt};
2020
use crate::receipt::state::{AwaitingReserve, Checking, Failed, ReceiptState, Reserved};
2121
use crate::{
2222
manager::adapters::EscrowHandler, receipt::checks::ReceiptCheck,
@@ -28,16 +28,15 @@ pub type ResultReceipt<S> = std::result::Result<ReceiptWithState<S>, ReceiptWith
2828
/// Typestate pattern for tracking the state of a receipt
2929
///
3030
/// - The [ `ReceiptState` ] trait represents the different states a receipt
31-
/// can be in.
31+
/// can be in.
3232
/// - The [ `Checking` ] state is used to represent a receipt that is currently
33-
/// being checked.
33+
/// being checked.
3434
/// - The [ `Failed` ] state is used to represent a receipt that has failed a
35-
/// check or validation.
35+
/// check or validation.
3636
/// - The [ `AwaitingReserve` ] state is used to represent a receipt that has
37-
/// passed all checks and is
38-
/// awaiting escrow reservation.
37+
/// passed all checks and is awaiting escrow reservation.
3938
/// - The [ `Reserved` ] state is used to represent a receipt that has
40-
/// successfully reserved escrow.
39+
/// successfully reserved escrow.
4140
#[derive(Debug, Clone)]
4241
pub struct ReceiptWithState<S>
4342
where
@@ -90,10 +89,14 @@ impl ReceiptWithState<Checking> {
9089
/// cannot be comleted in the receipts current internal state.
9190
/// All other checks must be complete before `CheckAndReserveEscrow`.
9291
///
93-
pub async fn perform_checks(&mut self, checks: &[ReceiptCheck]) -> ReceiptResult<()> {
92+
pub async fn perform_checks(
93+
&mut self,
94+
ctx: &Context,
95+
checks: &[ReceiptCheck],
96+
) -> ReceiptResult<()> {
9497
for check in checks {
9598
// return early on an error
96-
check.check(self).await.map_err(|e| match e {
99+
check.check(ctx, self).await.map_err(|e| match e {
97100
CheckError::Retryable(e) => ReceiptError::RetryableCheck(e.to_string()),
98101
CheckError::Failed(e) => ReceiptError::CheckFailure(e.to_string()),
99102
})?;
@@ -108,9 +111,10 @@ impl ReceiptWithState<Checking> {
108111
///
109112
pub async fn finalize_receipt_checks(
110113
mut self,
114+
ctx: &Context,
111115
checks: &[ReceiptCheck],
112116
) -> Result<ResultReceipt<AwaitingReserve>, String> {
113-
let all_checks_passed = self.perform_checks(checks).await;
117+
let all_checks_passed = self.perform_checks(ctx, checks).await;
114118
if let Err(ReceiptError::RetryableCheck(e)) = all_checks_passed {
115119
Err(e.to_string())
116120
} else if let Err(e) = all_checks_passed {

tap_core/tests/manager_test.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use tap_core::{
2727
receipt::{
2828
checks::{Check, CheckError, CheckList, StatefulTimestampCheck},
2929
state::Checking,
30-
Receipt, ReceiptWithState,
30+
Context, Receipt, ReceiptWithState,
3131
},
3232
signed_message::EIP712SignedMessage,
3333
tap_eip712_domain,
@@ -145,7 +145,7 @@ async fn manager_verify_and_store_varying_initial_checks(
145145
.insert(signer.address(), 999999);
146146

147147
assert!(manager
148-
.verify_and_store_receipt(signed_receipt)
148+
.verify_and_store_receipt(Context::new(), signed_receipt)
149149
.await
150150
.is_ok());
151151
}
@@ -184,7 +184,7 @@ async fn manager_create_rav_request_all_valid_receipts(
184184
stored_signed_receipts.push(signed_receipt.clone());
185185
query_appraisals.write().unwrap().insert(query_id, value);
186186
assert!(manager
187-
.verify_and_store_receipt(signed_receipt)
187+
.verify_and_store_receipt(Context::new(), signed_receipt)
188188
.await
189189
.is_ok());
190190
}
@@ -279,7 +279,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts(
279279
stored_signed_receipts.push(signed_receipt.clone());
280280
query_appraisals.write().unwrap().insert(query_id, value);
281281
assert!(manager
282-
.verify_and_store_receipt(signed_receipt)
282+
.verify_and_store_receipt(Context::new(), signed_receipt)
283283
.await
284284
.is_ok());
285285
expected_accumulated_value += value;
@@ -323,7 +323,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts(
323323
stored_signed_receipts.push(signed_receipt.clone());
324324
query_appraisals.write().unwrap().insert(query_id, value);
325325
assert!(manager
326-
.verify_and_store_receipt(signed_receipt)
326+
.verify_and_store_receipt(Context::new(), signed_receipt)
327327
.await
328328
.is_ok());
329329
expected_accumulated_value += value;
@@ -391,7 +391,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim
391391
stored_signed_receipts.push(signed_receipt.clone());
392392
query_appraisals.write().unwrap().insert(query_id, value);
393393
assert!(manager
394-
.verify_and_store_receipt(signed_receipt)
394+
.verify_and_store_receipt(Context::new(), signed_receipt)
395395
.await
396396
.is_ok());
397397
expected_accumulated_value += value;
@@ -438,7 +438,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim
438438
stored_signed_receipts.push(signed_receipt.clone());
439439
query_appraisals.write().unwrap().insert(query_id, value);
440440
assert!(manager
441-
.verify_and_store_receipt(signed_receipt)
441+
.verify_and_store_receipt(Context::new(), signed_receipt)
442442
.await
443443
.is_ok());
444444
expected_accumulated_value += value;
@@ -518,7 +518,7 @@ async fn manager_create_rav_and_ignore_invalid_receipts(
518518
let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &signer).unwrap();
519519
stored_signed_receipts.push(signed_receipt.clone());
520520
manager
521-
.verify_and_store_receipt(signed_receipt)
521+
.verify_and_store_receipt(Context::new(), signed_receipt)
522522
.await
523523
.unwrap();
524524
}
@@ -544,7 +544,11 @@ async fn test_retryable_checks(
544544

545545
#[async_trait::async_trait]
546546
impl Check for RetryableCheck {
547-
async fn check(&self, receipt: &ReceiptWithState<Checking>) -> Result<(), CheckError> {
547+
async fn check(
548+
&self,
549+
_: &Context,
550+
receipt: &ReceiptWithState<Checking>,
551+
) -> Result<(), CheckError> {
548552
// we want to fail only if nonce is 5 and if is create rav step
549553
if self.0.load(std::sync::atomic::Ordering::SeqCst)
550554
&& receipt.signed_receipt().message.nonce == 5
@@ -591,7 +595,7 @@ async fn test_retryable_checks(
591595
let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &signer).unwrap();
592596
stored_signed_receipts.push(signed_receipt.clone());
593597
manager
594-
.verify_and_store_receipt(signed_receipt)
598+
.verify_and_store_receipt(Context::new(), signed_receipt)
595599
.await
596600
.unwrap();
597601
}

tap_core/tests/received_receipt_test.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use tap_core::{
1515
},
1616
receipt::{
1717
checks::{ReceiptCheck, StatefulTimestampCheck},
18-
Receipt, ReceiptWithState,
18+
Context, Receipt, ReceiptWithState,
1919
},
2020
signed_message::EIP712SignedMessage,
2121
tap_eip712_domain,
@@ -138,7 +138,9 @@ async fn partial_then_full_check_valid_receipt(
138138

139139
let mut received_receipt = ReceiptWithState::new(signed_receipt);
140140

141-
let result = received_receipt.perform_checks(&checks).await;
141+
let result = received_receipt
142+
.perform_checks(&Context::new(), &checks)
143+
.await;
142144
assert!(result.is_ok());
143145
}
144146

@@ -180,7 +182,9 @@ async fn partial_then_finalize_valid_receipt(
180182

181183
let received_receipt = ReceiptWithState::new(signed_receipt);
182184

183-
let awaiting_escrow_receipt = received_receipt.finalize_receipt_checks(&checks).await;
185+
let awaiting_escrow_receipt = received_receipt
186+
.finalize_receipt_checks(&Context::new(), &checks)
187+
.await;
184188
assert!(awaiting_escrow_receipt.is_ok());
185189

186190
let awaiting_escrow_receipt = awaiting_escrow_receipt.unwrap();
@@ -230,7 +234,9 @@ async fn standard_lifetime_valid_receipt(
230234

231235
let received_receipt = ReceiptWithState::new(signed_receipt);
232236

233-
let awaiting_escrow_receipt = received_receipt.finalize_receipt_checks(&checks).await;
237+
let awaiting_escrow_receipt = received_receipt
238+
.finalize_receipt_checks(&Context::new(), &checks)
239+
.await;
234240
assert!(awaiting_escrow_receipt.is_ok());
235241

236242
let awaiting_escrow_receipt = awaiting_escrow_receipt.unwrap();

0 commit comments

Comments
 (0)