diff --git a/tap_core/src/receipt/checks.rs b/tap_core/src/receipt/checks.rs index 5a990d15..e1fe5c63 100644 --- a/tap_core/src/receipt/checks.rs +++ b/tap_core/src/receipt/checks.rs @@ -182,3 +182,84 @@ impl CheckBatch for UniqueCheck { (checking, failed) } } + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use std::time::Duration; + use std::time::SystemTime; + + use alloy_primitives::Address; + use alloy_sol_types::eip712_domain; + use alloy_sol_types::Eip712Domain; + + use ethers::signers::coins_bip39::English; + use ethers::signers::{LocalWallet, MnemonicBuilder}; + + use crate::receipt::Receipt; + use crate::signed_message::EIP712SignedMessage; + + use super::*; + + fn create_signed_receipt_with_custom_value(value: u128) -> ReceiptWithState { + let index: u32 = 0; + let wallet: LocalWallet = MnemonicBuilder::::default() + .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") + .index(index) + .unwrap() + .build() + .unwrap(); + let eip712_domain_separator: Eip712Domain = eip712_domain! { + name: "TAP", + version: "1", + chain_id: 1, + verifying_contract: Address:: from([0x11u8; 20]), + }; + + let timestamp = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Time went backwards") + .as_nanos() + + Duration::from_secs(33).as_nanos(); + let timestamp_ns = timestamp as u64; + + let value: u128 = value; + let nonce: u64 = 10; + let receipt = EIP712SignedMessage::new( + &eip712_domain_separator, + Receipt { + allocation_id: Address::from_str("0xabababababababababababababababababababab") + .unwrap(), + nonce, + timestamp_ns, + value, + }, + &wallet, + ) + .unwrap(); + ReceiptWithState::::new(receipt) + } + + #[tokio::test] + async fn test_receipt_uniqueness_check() { + let signed_receipt = create_signed_receipt_with_custom_value(10); + let signed_receipt_2 = create_signed_receipt_with_custom_value(15); + let signed_receipt_copy = signed_receipt.clone(); + let receipts_batch = vec![signed_receipt, signed_receipt_2, signed_receipt_copy]; + let (valid_receipts, invalid_receipts) = UniqueCheck.check_batch(receipts_batch); + assert_eq!(valid_receipts.len(), 2); + assert_eq!(invalid_receipts.len(), 1); + } + + #[tokio::test] + async fn test_receipt_timestamp_check() { + let signed_receipt = create_signed_receipt_with_custom_value(10); + let signed_receipt_2 = create_signed_receipt_with_custom_value(15); + let receipts_batch = vec![signed_receipt.clone(), signed_receipt_2]; + let min_time_stamp = signed_receipt.signed_receipt.message.timestamp_ns + 1; + let (valid_receipts, invalid_receipts) = + TimestampCheck(min_time_stamp).check_batch(receipts_batch); + assert_eq!(valid_receipts.len(), 1); + assert_eq!(invalid_receipts.len(), 1); + } +} diff --git a/tap_core/tests/manager_test.rs b/tap_core/tests/manager_test.rs index adfd7858..27a7dde5 100644 --- a/tap_core/tests/manager_test.rs +++ b/tap_core/tests/manager_test.rs @@ -24,6 +24,7 @@ use tap_core::{ }, Manager, }, + rav::ReceiptAggregateVoucher, receipt::{ checks::{CheckList, StatefulTimestampCheck}, Receipt, @@ -204,6 +205,39 @@ async fn manager_create_rav_request_all_valid_receipts( .is_ok()); } +#[rstest] +#[tokio::test] +async fn deny_rav_due_to_wrong_value( + keys: (LocalWallet, Address), + domain_separator: Eip712Domain, + context: ContextFixture, +) { + let ContextFixture { + context, checks, .. + } = context; + let manager = Manager::new(domain_separator.clone(), context, checks); + + let rav = ReceiptAggregateVoucher { + allocationId: Address::from_str("0xabababababababababababababababababababab").unwrap(), + timestampNs: 1232442, + valueAggregate: 20u128, + }; + + let rav_wrong_value = ReceiptAggregateVoucher { + allocationId: Address::from_str("0xabababababababababababababababababababab").unwrap(), + timestampNs: 1232442, + valueAggregate: 10u128, + }; + + let signed_rav_with_wrong_aggregate = + EIP712SignedMessage::new(&domain_separator, rav_wrong_value, &keys.0).unwrap(); + + assert!(manager + .verify_and_store_rav(rav, signed_rav_with_wrong_aggregate) + .await + .is_err()); +} + #[rstest] #[tokio::test] async fn manager_create_multiple_rav_requests_all_valid_receipts( @@ -453,3 +487,48 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim .await .is_ok()); } + +#[rstest] +#[tokio::test] +async fn manager_create_rav_and_ignore_invalid_receipts( + keys: (LocalWallet, Address), + allocation_ids: Vec
, + domain_separator: Eip712Domain, + context: ContextFixture, +) { + let ContextFixture { + context, + checks, + escrow_storage, + .. + } = context; + + let manager = Manager::new(domain_separator.clone(), context.clone(), checks); + + escrow_storage.write().unwrap().insert(keys.1, 999999); + + let mut stored_signed_receipts = Vec::new(); + //Forcing all receipts but one to be invalid by making all the same + for _ in 0..10 { + let receipt = Receipt { + allocation_id: allocation_ids[0], + timestamp_ns: 1, + nonce: 1, + value: 20u128, + }; + let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &keys.0).unwrap(); + stored_signed_receipts.push(signed_receipt.clone()); + manager + .verify_and_store_receipt(signed_receipt) + .await + .unwrap(); + } + + let rav_request = manager.create_rav_request(0, None).await.unwrap(); + + assert_eq!(rav_request.valid_receipts.len(), 1); + // All receipts but one being invalid + assert_eq!(rav_request.invalid_receipts.len(), 9); + //Rav Value corresponds only to value of one receipt + assert_eq!(rav_request.expected_rav.valueAggregate, 20); +}