Skip to content

Commit 59154df

Browse files
authored
Merge pull request #215 from semiotic-ai/gusinacio/unique-and-timestamp-check
Gusinacio/unique and timestamp check
2 parents 66ec313 + 3b99cd9 commit 59154df

File tree

13 files changed

+101
-44
lines changed

13 files changed

+101
-44
lines changed

tap_core/src/adapters/mock/executor_mock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::adapters::escrow_adapter::EscrowAdapter;
55
use crate::adapters::receipt_storage_adapter::{
66
safe_truncate_receipts, ReceiptDelete, ReceiptRead, ReceiptStore, StoredReceipt,
77
};
8-
use crate::checks::TimestampCheck;
98
use crate::eip_712_signed_message::MessageId;
9+
use crate::tap_receipt::checks::TimestampCheck;
1010
use crate::tap_receipt::ReceivedReceipt;
1111
use crate::{
1212
adapters::rav_storage_adapter::{RAVRead, RAVStore},

tap_core/src/adapters/test/escrow_adapter_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod escrow_adapter_unit_test {
1313

1414
use crate::{
1515
adapters::{escrow_adapter::EscrowAdapter, executor_mock::ExecutorMock},
16-
checks::TimestampCheck,
16+
tap_receipt::checks::TimestampCheck,
1717
};
1818

1919
#[fixture]

tap_core/src/adapters/test/rav_storage_adapter_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod rav_storage_adapter_unit_test {
1313
use ethers::signers::{LocalWallet, MnemonicBuilder};
1414
use rstest::*;
1515

16-
use crate::checks::TimestampCheck;
16+
use crate::tap_receipt::checks::TimestampCheck;
1717
use crate::{
1818
adapters::{
1919
executor_mock::ExecutorMock,

tap_core/src/adapters/test/receipt_storage_adapter_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod receipt_storage_adapter_unit_test {
99
use std::str::FromStr;
1010
use std::sync::{Arc, RwLock};
1111

12-
use crate::checks::TimestampCheck;
12+
use crate::tap_receipt::checks::TimestampCheck;
1313
use crate::{
1414
adapters::{executor_mock::ExecutorMock, receipt_storage_adapter::ReceiptStore},
1515
eip_712_signed_message::EIP712SignedMessage,

tap_core/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use alloy_sol_types::eip712_domain;
1212
use thiserror::Error;
1313

1414
pub mod adapters;
15-
pub mod checks;
1615
pub mod eip_712_signed_message;
1716
mod error;
1817
pub mod receipt_aggregate_voucher;

tap_core/src/tap_manager/manager.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ use crate::{
1010
rav_storage_adapter::{RAVRead, RAVStore},
1111
receipt_storage_adapter::{ReceiptDelete, ReceiptRead, ReceiptStore},
1212
},
13-
checks::Checks,
1413
receipt_aggregate_voucher::ReceiptAggregateVoucher,
1514
tap_receipt::{
16-
CategorizedReceiptsWithState, Failed, ReceiptAuditor, ReceiptWithId, ReceiptWithState,
17-
ReceivedReceipt, Reserved,
15+
checks::{BatchTimestampCheck, CheckBatch, Checks, UniqueCheck},
16+
CategorizedReceiptsWithState, Failed, ReceiptAuditor, ReceiptWithState, ReceivedReceipt,
17+
Reserved,
1818
},
1919
Error,
2020
};
@@ -141,11 +141,21 @@ where
141141
mut reserved_receipts,
142142
} = received_receipts.into();
143143

144-
for received_receipt in checking_receipts.into_iter() {
145-
let ReceiptWithId {
146-
receipt,
147-
receipt_id: _,
148-
} = received_receipt;
144+
let checking_receipts = checking_receipts
145+
.into_iter()
146+
.map(|receipt| receipt.receipt)
147+
.collect::<Vec<_>>();
148+
149+
// check for timestamp
150+
let (checking_receipts, already_failed) =
151+
BatchTimestampCheck(min_timestamp_ns).check_batch(checking_receipts);
152+
failed_receipts.extend(already_failed);
153+
154+
// check for uniqueness
155+
let (checking_receipts, already_failed) = UniqueCheck.check_batch(checking_receipts);
156+
failed_receipts.extend(already_failed);
157+
158+
for receipt in checking_receipts.into_iter() {
149159
let receipt = receipt.finalize_receipt_checks(&self.checks).await;
150160

151161
match receipt {

tap_core/src/tap_manager/test/manager_test.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ use crate::{
1717
executor_mock::{EscrowStorage, ExecutorMock, QueryAppraisals},
1818
receipt_storage_adapter::ReceiptRead,
1919
},
20-
checks::{mock::get_full_list_of_checks, Checks, TimestampCheck},
2120
eip_712_signed_message::EIP712SignedMessage,
2221
get_current_timestamp_u64_ns, tap_eip712_domain,
23-
tap_receipt::Receipt,
22+
tap_receipt::{
23+
checks::{mock::get_full_list_of_checks, Checks, TimestampCheck},
24+
Receipt,
25+
},
2426
};
2527

2628
#[fixture]

tap_core/src/checks/mod.rs renamed to tap_core/src/tap_receipt/checks.rs

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33

44
use crate::tap_receipt::{Checking, ReceiptError, ReceiptWithState};
55
use std::{
6+
collections::HashSet,
67
ops::Deref,
78
sync::{Arc, RwLock},
89
};
910

11+
use super::Failed;
12+
1013
pub type ReceiptCheck = Arc<dyn Check + Sync + Send>;
1114

1215
pub 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]
3638
pub 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")]
74135
pub 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
}

tap_core/src/tap_receipt/mod.rs

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

4+
pub mod checks;
45
mod receipt;
56
mod receipt_auditor;
67
mod received_receipt;

tap_core/src/tap_receipt/received_receipt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use serde::{Deserialize, Serialize};
1818
use super::{receipt_auditor::ReceiptAuditor, Receipt, ReceiptError, ReceiptResult};
1919
use crate::{
2020
adapters::{escrow_adapter::EscrowAdapter, receipt_storage_adapter::StoredReceipt},
21-
checks::ReceiptCheck,
2221
eip_712_signed_message::EIP712SignedMessage,
22+
tap_receipt::checks::ReceiptCheck,
2323
};
2424

2525
#[derive(Debug, Clone)]
@@ -236,7 +236,7 @@ impl<S> ReceiptWithState<S>
236236
where
237237
S: ReceiptState,
238238
{
239-
fn perform_state_error(self, error: ReceiptError) -> ReceiptWithState<Failed> {
239+
pub(super) fn perform_state_error(self, error: ReceiptError) -> ReceiptWithState<Failed> {
240240
ReceiptWithState {
241241
signed_receipt: self.signed_receipt,
242242
_state: Failed { error },

0 commit comments

Comments
 (0)