Skip to content

Commit

Permalink
Merge pull request #215 from semiotic-ai/gusinacio/unique-and-timesta…
Browse files Browse the repository at this point in the history
…mp-check

Gusinacio/unique and timestamp check
  • Loading branch information
gusinacio committed Mar 11, 2024
2 parents 66ec313 + 3b99cd9 commit 59154df
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 44 deletions.
2 changes: 1 addition & 1 deletion tap_core/src/adapters/mock/executor_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::adapters::escrow_adapter::EscrowAdapter;
use crate::adapters::receipt_storage_adapter::{
safe_truncate_receipts, ReceiptDelete, ReceiptRead, ReceiptStore, StoredReceipt,
};
use crate::checks::TimestampCheck;
use crate::eip_712_signed_message::MessageId;
use crate::tap_receipt::checks::TimestampCheck;
use crate::tap_receipt::ReceivedReceipt;
use crate::{
adapters::rav_storage_adapter::{RAVRead, RAVStore},
Expand Down
2 changes: 1 addition & 1 deletion tap_core/src/adapters/test/escrow_adapter_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod escrow_adapter_unit_test {

use crate::{
adapters::{escrow_adapter::EscrowAdapter, executor_mock::ExecutorMock},
checks::TimestampCheck,
tap_receipt::checks::TimestampCheck,
};

#[fixture]
Expand Down
2 changes: 1 addition & 1 deletion tap_core/src/adapters/test/rav_storage_adapter_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod rav_storage_adapter_unit_test {
use ethers::signers::{LocalWallet, MnemonicBuilder};
use rstest::*;

use crate::checks::TimestampCheck;
use crate::tap_receipt::checks::TimestampCheck;
use crate::{
adapters::{
executor_mock::ExecutorMock,
Expand Down
2 changes: 1 addition & 1 deletion tap_core/src/adapters/test/receipt_storage_adapter_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod receipt_storage_adapter_unit_test {
use std::str::FromStr;
use std::sync::{Arc, RwLock};

use crate::checks::TimestampCheck;
use crate::tap_receipt::checks::TimestampCheck;
use crate::{
adapters::{executor_mock::ExecutorMock, receipt_storage_adapter::ReceiptStore},
eip_712_signed_message::EIP712SignedMessage,
Expand Down
1 change: 0 additions & 1 deletion tap_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use alloy_sol_types::eip712_domain;
use thiserror::Error;

pub mod adapters;
pub mod checks;
pub mod eip_712_signed_message;
mod error;
pub mod receipt_aggregate_voucher;
Expand Down
26 changes: 18 additions & 8 deletions tap_core/src/tap_manager/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use crate::{
rav_storage_adapter::{RAVRead, RAVStore},
receipt_storage_adapter::{ReceiptDelete, ReceiptRead, ReceiptStore},
},
checks::Checks,
receipt_aggregate_voucher::ReceiptAggregateVoucher,
tap_receipt::{
CategorizedReceiptsWithState, Failed, ReceiptAuditor, ReceiptWithId, ReceiptWithState,
ReceivedReceipt, Reserved,
checks::{BatchTimestampCheck, CheckBatch, Checks, UniqueCheck},
CategorizedReceiptsWithState, Failed, ReceiptAuditor, ReceiptWithState, ReceivedReceipt,
Reserved,
},
Error,
};
Expand Down Expand Up @@ -141,11 +141,21 @@ where
mut reserved_receipts,
} = received_receipts.into();

for received_receipt in checking_receipts.into_iter() {
let ReceiptWithId {
receipt,
receipt_id: _,
} = received_receipt;
let checking_receipts = checking_receipts
.into_iter()
.map(|receipt| receipt.receipt)
.collect::<Vec<_>>();

// check for timestamp
let (checking_receipts, already_failed) =
BatchTimestampCheck(min_timestamp_ns).check_batch(checking_receipts);
failed_receipts.extend(already_failed);

// check for uniqueness
let (checking_receipts, already_failed) = UniqueCheck.check_batch(checking_receipts);
failed_receipts.extend(already_failed);

for receipt in checking_receipts.into_iter() {
let receipt = receipt.finalize_receipt_checks(&self.checks).await;

match receipt {
Expand Down
6 changes: 4 additions & 2 deletions tap_core/src/tap_manager/test/manager_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ use crate::{
executor_mock::{EscrowStorage, ExecutorMock, QueryAppraisals},
receipt_storage_adapter::ReceiptRead,
},
checks::{mock::get_full_list_of_checks, Checks, TimestampCheck},
eip_712_signed_message::EIP712SignedMessage,
get_current_timestamp_u64_ns, tap_eip712_domain,
tap_receipt::Receipt,
tap_receipt::{
checks::{mock::get_full_list_of_checks, Checks, TimestampCheck},
Receipt,
},
};

#[fixture]
Expand Down
85 changes: 63 additions & 22 deletions tap_core/src/checks/mod.rs → tap_core/src/tap_receipt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@

use crate::tap_receipt::{Checking, ReceiptError, ReceiptWithState};
use std::{
collections::HashSet,
ops::Deref,
sync::{Arc, RwLock},
};

use super::Failed;

pub type ReceiptCheck = Arc<dyn Check + Sync + Send>;

pub type CheckResult = anyhow::Result<()>;
Expand All @@ -32,9 +35,14 @@ pub trait Check {
async fn check(&self, receipt: &ReceiptWithState<Checking>) -> CheckResult;
}

#[async_trait::async_trait]
pub trait CheckBatch {
async fn check_batch(&self, receipts: &[ReceiptWithState<Checking>]) -> Vec<CheckResult>;
fn check_batch(
&self,
receipts: Vec<ReceiptWithState<Checking>>,
) -> (
Vec<ReceiptWithState<Checking>>,
Vec<ReceiptWithState<Failed>>,
);
}

#[derive(Debug)]
Expand Down Expand Up @@ -70,6 +78,59 @@ impl Check for TimestampCheck {
}
}

/// Timestamp Check verifies if the receipt is **greater or equal** than the minimum timestamp provided.
pub struct BatchTimestampCheck(pub u64);

impl CheckBatch for BatchTimestampCheck {
fn check_batch(
&self,
receipts: Vec<ReceiptWithState<Checking>>,
) -> (
Vec<ReceiptWithState<Checking>>,
Vec<ReceiptWithState<Failed>>,
) {
let (mut checking, mut failed) = (vec![], vec![]);
for receipt in receipts.into_iter() {
let receipt_timestamp_ns = receipt.signed_receipt().message.timestamp_ns;
let min_timestamp_ns = self.0;
if receipt_timestamp_ns >= min_timestamp_ns {
checking.push(receipt);
} else {
failed.push(receipt.perform_state_error(ReceiptError::InvalidTimestamp {
received_timestamp: receipt_timestamp_ns,
timestamp_min: min_timestamp_ns,
}));
}
}
(checking, failed)
}
}

pub struct UniqueCheck;

impl CheckBatch for UniqueCheck {
fn check_batch(
&self,
receipts: Vec<ReceiptWithState<Checking>>,
) -> (
Vec<ReceiptWithState<Checking>>,
Vec<ReceiptWithState<Failed>>,
) {
let mut signatures: HashSet<ethers::types::Signature> = HashSet::new();
let (mut checking, mut failed) = (vec![], vec![]);

for received_receipt in receipts.into_iter() {
let signature = received_receipt.signed_receipt.signature;
if signatures.insert(signature) {
checking.push(received_receipt);
} else {
failed.push(received_receipt.perform_state_error(ReceiptError::NonUniqueReceipt));
}
}
(checking, failed)
}
}

#[cfg(feature = "mock")]
pub mod mock {

Expand All @@ -96,26 +157,6 @@ pub mod mock {
]
}

struct UniqueCheck;

#[async_trait::async_trait]
impl CheckBatch for UniqueCheck {
async fn check_batch(&self, receipts: &[ReceiptWithState<Checking>]) -> Vec<CheckResult> {
let mut signatures: HashSet<ethers::types::Signature> = HashSet::new();
let mut results = Vec::new();

for received_receipt in receipts {
let signature = received_receipt.signed_receipt.signature;
if signatures.insert(signature) {
results.push(Ok(()));
} else {
results.push(Err(ReceiptError::NonUniqueReceipt.into()));
}
}
results
}
}

struct ValueCheck {
query_appraisals: Arc<RwLock<HashMap<MessageId, u128>>>,
}
Expand Down
1 change: 1 addition & 0 deletions tap_core/src/tap_receipt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2023-, Semiotic AI, Inc.
// SPDX-License-Identifier: Apache-2.0

pub mod checks;
mod receipt;
mod receipt_auditor;
mod received_receipt;
Expand Down
4 changes: 2 additions & 2 deletions tap_core/src/tap_receipt/received_receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use serde::{Deserialize, Serialize};
use super::{receipt_auditor::ReceiptAuditor, Receipt, ReceiptError, ReceiptResult};
use crate::{
adapters::{escrow_adapter::EscrowAdapter, receipt_storage_adapter::StoredReceipt},
checks::ReceiptCheck,
eip_712_signed_message::EIP712SignedMessage,
tap_receipt::checks::ReceiptCheck,
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -236,7 +236,7 @@ impl<S> ReceiptWithState<S>
where
S: ReceiptState,
{
fn perform_state_error(self, error: ReceiptError) -> ReceiptWithState<Failed> {
pub(super) fn perform_state_error(self, error: ReceiptError) -> ReceiptWithState<Failed> {
ReceiptWithState {
signed_receipt: self.signed_receipt,
_state: Failed { error },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ use rstest::*;

use crate::{
adapters::executor_mock::{EscrowStorage, ExecutorMock, QueryAppraisals},
checks::{mock::get_full_list_of_checks, ReceiptCheck, TimestampCheck},
eip_712_signed_message::EIP712SignedMessage,
tap_eip712_domain,
tap_receipt::{Receipt, ReceiptAuditor, ReceivedReceipt},
tap_receipt::{
checks::{mock::get_full_list_of_checks, ReceiptCheck, TimestampCheck},
Receipt, ReceiptAuditor, ReceivedReceipt,
},
};

#[fixture]
Expand Down
2 changes: 1 addition & 1 deletion tap_integration_tests/tests/indexer_mock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use tap_core::{
rav_storage_adapter::{RAVRead, RAVStore},
receipt_storage_adapter::{ReceiptRead, ReceiptStore},
},
checks::Checks,
tap_manager::{Manager, SignedRAV, SignedReceipt},
tap_receipt::checks::Checks,
};
/// Rpc trait represents a JSON-RPC server that has a single async method `request`.
/// This method is designed to handle incoming JSON-RPC requests.
Expand Down
6 changes: 4 additions & 2 deletions tap_integration_tests/tests/showcase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ use rstest::*;
use tap_aggregator::{jsonrpsee_helpers, server as agg_server};
use tap_core::{
adapters::executor_mock::{ExecutorMock, QueryAppraisals},
checks::{mock::get_full_list_of_checks, Checks, TimestampCheck},
eip_712_signed_message::{EIP712SignedMessage, MessageId},
tap_eip712_domain,
tap_manager::SignedRAV,
tap_receipt::Receipt,
tap_receipt::{
checks::{mock::get_full_list_of_checks, Checks, TimestampCheck},
Receipt,
},
};

use crate::indexer_mock;
Expand Down

0 comments on commit 59154df

Please sign in to comment.