From c40fb0ce4ddc9a795acb09e4f421d73ae4bded28 Mon Sep 17 00:00:00 2001 From: contractless <00.pur.ple@gmail.com> Date: Sun, 2 Aug 2026 10:40:38 -0600 Subject: [PATCH] fixed swap validations --- src/main.rs | 2 +- .../async_funcs/checks/time_checks.rs | 20 +++++++++++-------- src/verifications/async_funcs/transactions.rs | 2 +- src/verifications/async_funcs/verify_swap.rs | 11 ++++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index c812d30..e4695da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use tokio::runtime::Builder; fn main() { // Linux-specific control commands are handled before any startup work begins. match handle_control_command() { - Ok(true) => return, + Ok(true) => return, Ok(false) => {} Err(e) => { eprintln!("Control command failed: {e}"); diff --git a/src/verifications/async_funcs/checks/time_checks.rs b/src/verifications/async_funcs/checks/time_checks.rs index 47305b2..61d5df5 100644 --- a/src/verifications/async_funcs/checks/time_checks.rs +++ b/src/verifications/async_funcs/checks/time_checks.rs @@ -2,16 +2,20 @@ use crate::DateTime; use crate::Utc; pub async fn is_within_30_days(timestamp: u32) -> bool { - // Convert the on-chain timestamp into UTC and reject values that fall - // more than 30 days in the past or fail to decode as valid datetimes. - let transaction_time = DateTime::::from_timestamp(timestamp as i64, 0); + is_within_30_days_at(timestamp, Utc::now().timestamp() as u32) +} - match transaction_time { - Some(transaction_time) => { - let current_time = Utc::now(); - let duration = current_time.signed_duration_since(transaction_time); +pub fn is_within_30_days_at(timestamp: u32, as_of_timestamp: u32) -> bool { + // Convert the on-chain timestamp into UTC and reject values that fall + // more than 30 days before the supplied validation time or fail to decode. + let transaction_time = DateTime::::from_timestamp(timestamp as i64, 0); + let as_of_time = DateTime::::from_timestamp(as_of_timestamp as i64, 0); + + match (transaction_time, as_of_time) { + (Some(transaction_time), Some(as_of_time)) => { + let duration = as_of_time.signed_duration_since(transaction_time); duration.num_days() <= 30 } - None => false, + _ => false, } } diff --git a/src/verifications/async_funcs/transactions.rs b/src/verifications/async_funcs/transactions.rs index 757f134..1102f83 100644 --- a/src/verifications/async_funcs/transactions.rs +++ b/src/verifications/async_funcs/transactions.rs @@ -229,7 +229,7 @@ async fn verify_transaction( } } if let Transaction::Swap(swap_tx) = &transaction { - match swap_tx.verify(db).await { + match swap_tx.verify_at(db, block_timestamp).await { Ok(value) => { reserve_verified_transaction(db, &transaction, balance_tracker, already_in_mempool) .await?; diff --git a/src/verifications/async_funcs/verify_swap.rs b/src/verifications/async_funcs/verify_swap.rs index 69d2aed..ee2002f 100644 --- a/src/verifications/async_funcs/verify_swap.rs +++ b/src/verifications/async_funcs/verify_swap.rs @@ -9,7 +9,7 @@ use crate::records::wallet_registry::{ }; use crate::sled::Db; use crate::verifications::async_funcs::checks::balance_check::balance_checkup; -use crate::verifications::async_funcs::checks::time_checks::is_within_30_days; +use crate::verifications::async_funcs::checks::time_checks::is_within_30_days_at; use crate::verifications::async_funcs::checks::verify_db::{ db_bytes_verification, db_hex_verification, }; @@ -35,6 +35,10 @@ fn validate_swap_tip(value: u64, tip: u64, is_nft: bool, sender: &str) -> Result impl SwapTransaction { pub async fn verify(&self, db: &Db) -> Result { + self.verify_at(db, Utc::now().timestamp() as u32).await + } + + pub async fn verify_at(&self, db: &Db, as_of_timestamp: u32) -> Result { let hash = self.unsigned_swap.hash().await; // Both swap participants must provide valid wallet addresses and // matching signatures over the shared unsigned swap payload. @@ -203,14 +207,13 @@ impl SwapTransaction { // Swap offers are bounded both by signature age and by the // explicit offer-expiration window carried in the transaction. - if !is_within_30_days(self.unsigned_swap.timestamp).await { + if !is_within_30_days_at(self.unsigned_swap.timestamp, as_of_timestamp) { return Err( "Timestamp is to old. Transactions must be broadcast within 30 days of signing." .to_string(), ); } - let now = Utc::now().timestamp() as u32; let offer_expiration = self.unsigned_swap.offer_expiration; let timestamp = self.unsigned_swap.timestamp; @@ -227,7 +230,7 @@ impl SwapTransaction { ); } - if now > offer_expiration { + if as_of_timestamp > offer_expiration { return Err("This swap offer has expired.".to_string()); }