From b5365099a4e256b66967d2fa1040f84939e2e42a Mon Sep 17 00:00:00 2001 From: silverpill Date: Thu, 9 Mar 2023 01:05:45 +0000 Subject: [PATCH] Store NFT monitor state in database --- CHANGELOG.md | 4 ++++ src/ethereum/nft.rs | 33 +++++++++++++++++++++++++++------ src/job_queue/periodic_tasks.rs | 5 ----- src/job_queue/scheduler.rs | 3 --- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f276182..2ca1e48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Changed + +- Store NFT monitor state in database. + ## [1.16.0] - 2023-03-08 ### Added diff --git a/src/ethereum/nft.rs b/src/ethereum/nft.rs index a57e2ef..242eb6c 100644 --- a/src/ethereum/nft.rs +++ b/src/ethereum/nft.rs @@ -14,18 +14,27 @@ use mitra_config::EthereumConfig; use crate::database::{get_database_client, DatabaseError, DbPool}; use crate::ipfs::utils::parse_ipfs_url; -use crate::models::posts::queries::{ - get_post_by_ipfs_cid, - get_token_waitlist, - set_post_token_id, - set_post_token_tx_id, +use crate::models::{ + posts::queries::{ + get_post_by_ipfs_cid, + get_token_waitlist, + set_post_token_id, + set_post_token_tx_id, + }, + properties::queries::{ + get_internal_property, + set_internal_property, + }, }; use super::errors::EthereumError; use super::signatures::{sign_contract_call, CallArgs, SignatureData}; use super::sync::SyncState; use super::utils::parse_address; +const TOKEN_WAITLIST_MAP_PROPERTY_NAME: &str = "token_waitlist_map"; + const TOKEN_WAIT_TIME: i64 = 10; // in minutes +const TOKEN_WAIT_RESET_TIME: i64 = 12 * 60; // in minutes /// Finds posts awaiting tokenization /// and looks for corresponding Mint events @@ -34,11 +43,18 @@ pub async fn process_nft_events( contract: &Contract, sync_state: &mut SyncState, db_pool: &DbPool, - token_waitlist_map: &mut HashMap>, ) -> Result<(), EthereumError> { let db_client = &**get_database_client(db_pool).await?; // Create/update token waitlist map + let mut token_waitlist_map: HashMap> = + get_internal_property(db_client, TOKEN_WAITLIST_MAP_PROPERTY_NAME) + .await?.unwrap_or_default(); + token_waitlist_map.retain(|_, waiting_since| { + // Re-add token to waitlist if waiting for too long + let duration = Utc::now() - *waiting_since; + duration.num_minutes() < TOKEN_WAIT_RESET_TIME + }); let token_waitlist = get_token_waitlist(db_client).await?; for post_id in token_waitlist { if !token_waitlist_map.contains_key(&post_id) { @@ -121,6 +137,11 @@ pub async fn process_nft_events( }; }; + set_internal_property( + db_client, + TOKEN_WAITLIST_MAP_PROPERTY_NAME, + &token_waitlist_map, + ).await?; sync_state.update(&contract.address(), to_block)?; Ok(()) } diff --git a/src/job_queue/periodic_tasks.rs b/src/job_queue/periodic_tasks.rs index 3fe513a..ddd5bb4 100644 --- a/src/job_queue/periodic_tasks.rs +++ b/src/job_queue/periodic_tasks.rs @@ -1,9 +1,6 @@ -use std::collections::HashMap; use std::time::Duration; use anyhow::Error; -use chrono::{DateTime, Utc}; -use uuid::Uuid; use mitra_config::Config; use mitra_utils::datetime::days_before_now; @@ -34,7 +31,6 @@ use crate::models::{ pub async fn nft_monitor( maybe_blockchain: Option<&mut Blockchain>, db_pool: &DbPool, - token_waitlist_map: &mut HashMap>, ) -> Result<(), Error> { let blockchain = match maybe_blockchain { Some(blockchain) => blockchain, @@ -49,7 +45,6 @@ pub async fn nft_monitor( collectible, &mut blockchain.sync_state, db_pool, - token_waitlist_map, ).await?; Ok(()) } diff --git a/src/job_queue/scheduler.rs b/src/job_queue/scheduler.rs index c7bda08..3e771a5 100644 --- a/src/job_queue/scheduler.rs +++ b/src/job_queue/scheduler.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use std::time::Duration; use chrono::{DateTime, Utc}; -use uuid::Uuid; use mitra_config::Config; @@ -70,7 +69,6 @@ pub fn run( }; let mut interval = tokio::time::interval(Duration::from_secs(5)); - let mut token_waitlist_map: HashMap> = HashMap::new(); loop { interval.tick().await; @@ -83,7 +81,6 @@ pub fn run( nft_monitor( maybe_blockchain.as_mut(), &db_pool, - &mut token_waitlist_map, ).await }, PeriodicTask::EthereumSubscriptionMonitor => {