Skip to content

Commit 576530e

Browse files
authored
feat: Add removal reason to db (#134)
* feat: Add removal reason to db
1 parent b9a84b7 commit 576530e

7 files changed

+88
-42
lines changed

auction-server/.sqlx/query-23f211b134ef73ab694a59738fd87ff51075c63e76f11f9f3dce49154fb04c4c.json

Lines changed: 0 additions & 15 deletions
This file was deleted.

auction-server/.sqlx/query-9fbee5f00571af6f3e883f935494c2665ee089dd3a8e9204afb650af0a243dc8.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE opportunity DROP COLUMN removal_reason;
2+
DROP TYPE IF EXISTS opportunity_removal_reason;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CREATE TYPE opportunity_removal_reason AS ENUM ('expired', 'invalid');
2+
ALTER TABLE opportunity ADD COLUMN removal_reason opportunity_removal_reason;

auction-server/src/models.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ pub struct Auction {
4949
pub submission_time: Option<PrimitiveDateTime>,
5050
}
5151

52+
#[derive(Clone, Debug, PartialEq, PartialOrd, sqlx::Type)]
53+
#[sqlx(type_name = "opportunity_removal_reason", rename_all = "lowercase")]
54+
pub enum OpportunityRemovalReason {
55+
Expired,
56+
Invalid,
57+
}
58+
5259

5360
#[derive(Clone, FromRow, Debug)]
5461
pub struct Opportunity {
@@ -62,6 +69,7 @@ pub struct Opportunity {
6269
pub removal_time: Option<PrimitiveDateTime>,
6370
pub sell_tokens: JsonValue,
6471
pub buy_tokens: JsonValue,
72+
pub removal_reason: Option<OpportunityRemovalReason>,
6573
}
6674

6775

auction-server/src/opportunity_adapter.rs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@ pub enum VerificationResult {
103103
UnableToSpoof,
104104
}
105105

106+
#[derive(Debug)]
107+
pub enum OpportunityRemovalReason {
108+
Expired,
109+
Invalid(anyhow::Error),
110+
}
111+
112+
impl From<OpportunityRemovalReason> for crate::models::OpportunityRemovalReason {
113+
fn from(val: OpportunityRemovalReason) -> Self {
114+
match val {
115+
OpportunityRemovalReason::Expired => crate::models::OpportunityRemovalReason::Expired,
116+
OpportunityRemovalReason::Invalid(_) => {
117+
crate::models::OpportunityRemovalReason::Invalid
118+
}
119+
}
120+
}
121+
}
122+
106123
pub async fn get_weth_address(
107124
adapter_contract: Address,
108125
provider: Provider<TracedClient>,
@@ -281,6 +298,7 @@ pub async fn verify_opportunity(
281298
}
282299
Ok(VerificationResult::Success)
283300
}
301+
284302
impl From<ExecutionParamsWithSignature> for eip712::TypedData {
285303
fn from(val: ExecutionParamsWithSignature) -> Self {
286304
let params = val.params;
@@ -494,31 +512,36 @@ pub async fn make_adapter_calldata(
494512
const MAX_STALE_OPPORTUNITY_MICROS: i128 = 60_000_000;
495513

496514
/// Verify an opportunity is still valid by checking staleness and simulating the execution call and checking the result
497-
/// Returns Ok(()) if the opportunity is still valid
515+
/// Returns None if the opportunity is still valid and Some(OpportunityRemovalReason) if not
498516
///
499517
/// # Arguments
500518
///
501519
/// * `opportunity`: opportunity to verify
502520
/// * `store`: server store
503-
async fn verify_with_store(opportunity: Opportunity, store: &Store) -> Result<()> {
521+
async fn verify_with_store(
522+
opportunity: Opportunity,
523+
store: &Store,
524+
) -> Option<OpportunityRemovalReason> {
504525
let OpportunityParams::V1(params) = opportunity.params;
505526
let chain_store = store
506527
.chains
507528
.get(&params.chain_id)
508-
.ok_or(anyhow!("Chain not found: {}", params.chain_id))?;
529+
.expect("Opportunity Chain not found in store");
509530
let relayer = store.relayer.address();
510531
match verify_opportunity(params.clone(), chain_store, relayer).await {
511-
Ok(VerificationResult::Success) => Ok(()),
532+
Ok(VerificationResult::Success) => None,
512533
Ok(VerificationResult::UnableToSpoof) => {
513-
let current_time =
514-
SystemTime::now().duration_since(UNIX_EPOCH)?.as_micros() as UnixTimestampMicros;
534+
let current_time = SystemTime::now()
535+
.duration_since(UNIX_EPOCH)
536+
.expect("Current time older than 1970!")
537+
.as_micros() as UnixTimestampMicros;
515538
if current_time - opportunity.creation_time > MAX_STALE_OPPORTUNITY_MICROS {
516-
Err(anyhow!("Opportunity is stale and unverifiable"))
539+
Some(OpportunityRemovalReason::Expired)
517540
} else {
518-
Ok(())
541+
None
519542
}
520543
}
521-
Err(e) => Err(e),
544+
Err(e) => Some(OpportunityRemovalReason::Invalid(e)),
522545
}
523546
}
524547

@@ -540,20 +563,14 @@ pub async fn run_verification_loop(store: Arc<Store>) -> Result<()> {
540563
for (_permission_key,opportunities) in all_opportunities.iter() {
541564
// check each of the opportunities for this permission key for validity
542565
for opportunity in opportunities.iter() {
543-
match verify_with_store(opportunity.clone(), &store).await {
544-
Ok(_) => {}
545-
Err(e) => {
546-
tracing::info!(
547-
"Removing Opportunity {} with failed verification: {}",
548-
opportunity.id,
549-
e
550-
);
551-
match store.remove_opportunity(opportunity).await {
552-
Ok(_) => {}
553-
Err(e) => {
554-
tracing::error!("Failed to remove opportunity: {}", e);
555-
}
556-
}
566+
if let Some(reason) = verify_with_store(opportunity.clone(), &store).await {
567+
tracing::info!(
568+
"Removing Opportunity {} for reason {:?}",
569+
opportunity.id,
570+
reason
571+
);
572+
if let Err(e)= store.remove_opportunity(opportunity, reason.into()).await {
573+
tracing::error!("Failed to remove opportunity: {}", e);
557574
}
558575
}
559576
}

auction-server/src/state.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ pub struct Opportunity {
177177
pub params: OpportunityParams,
178178
}
179179

180+
180181
#[derive(Clone)]
181182
pub enum SpoofInfo {
182183
Spoofed {
@@ -435,7 +436,11 @@ impl Store {
435436
Ok(())
436437
}
437438

438-
pub async fn remove_opportunity(&self, opportunity: &Opportunity) -> anyhow::Result<()> {
439+
pub async fn remove_opportunity(
440+
&self,
441+
opportunity: &Opportunity,
442+
reason: models::OpportunityRemovalReason,
443+
) -> anyhow::Result<()> {
439444
let key = match &opportunity.params {
440445
OpportunityParams::V1(params) => params.permission_key.clone(),
441446
};
@@ -451,12 +456,13 @@ impl Store {
451456
drop(write_guard);
452457
let now = OffsetDateTime::now_utc();
453458
sqlx::query!(
454-
"UPDATE opportunity SET removal_time = $1 WHERE id = $2 AND removal_time IS NULL",
459+
"UPDATE opportunity SET removal_time = $1, removal_reason = $2 WHERE id = $3 AND removal_time IS NULL",
455460
PrimitiveDateTime::new(now.date(), now.time()),
461+
reason as _,
456462
opportunity.id
457463
)
458-
.execute(&self.db)
459-
.await?;
464+
.execute(&self.db)
465+
.await?;
460466
Ok(())
461467
}
462468

0 commit comments

Comments
 (0)