diff --git a/roles/jd-server/src/lib/job_declarator/message_handler.rs b/roles/jd-server/src/lib/job_declarator/message_handler.rs index 96887bdd0e..0d11ffd302 100644 --- a/roles/jd-server/src/lib/job_declarator/message_handler.rs +++ b/roles/jd-server/src/lib/job_declarator/message_handler.rs @@ -7,14 +7,17 @@ use roles_logic_sv2::{ ProvideMissingTransactions, ProvideMissingTransactionsSuccess, SubmitSolutionJd, }, parsers::JobDeclaration, + utils::Mutex, }; -use std::{convert::TryInto, io::Cursor}; +use std::{convert::TryInto, io::Cursor, sync::Arc}; use stratum_common::bitcoin::{Transaction, Txid}; pub type SendTo = SendTo_, ()>; +use crate::mempool::JDsMempool; + use super::{signed_token, TransactionState}; use roles_logic_sv2::{errors::Error, parsers::PoolMessages as AllMessages}; use stratum_common::bitcoin::consensus::Decodable; -use tracing::info; +use tracing::{info, debug}; use super::JobDeclaratorDownstream; @@ -38,6 +41,31 @@ impl JobDeclaratorDownstream { } } +pub fn clear_declared_mining_job( + mining_job: DeclareMiningJob, + mempool: Arc>, +) -> Result<(), Error> { + // If there is an old declared mining job, remove its transactions from the mempool + // Retrieve necessary data from the old job + let transactions_to_remove = mining_job.tx_short_hash_list.inner_as_ref(); + if transactions_to_remove.is_empty() { + info!("No transactions to remove from mempool"); + return Ok(()); + } + let clear_transactions = |jds_mempool: &mut JDsMempool| { + for txid in transactions_to_remove { + match jds_mempool.mempool.remove(txid) { + Some(_) => info!("Transaction {:?} removed from mempool", txid), + None => debug!("Transaction {:?} not found in mempool", txid), + }; + } + }; + match mempool.safe_lock(clear_transactions) { + Ok(_) => Ok(()), + Err(e) => Err(Error::PoisonLock(e.to_string())), + } +} + impl ParseClientJobDeclarationMessages for JobDeclaratorDownstream { fn handle_allocate_mining_job_token( &mut self, @@ -61,6 +89,13 @@ impl ParseClientJobDeclarationMessages for JobDeclaratorDownstream { } fn handle_declare_mining_job(&mut self, message: DeclareMiningJob) -> Result { + { + // Clone the old declared mining job to retain its data + if let Some(old_declare_mining_job_) = self.declared_mining_job.0.clone() { + clear_declared_mining_job(old_declare_mining_job_, self.mempool.clone())?; + } + } + // the transactions that are present in the mempool are stored here, that is sent to the // mempool which use the rpc client to retrieve the whole data for each transaction. // The unknown transactions is a vector that contains the transactions that are not in the diff --git a/roles/jd-server/src/lib/mempool/mod.rs b/roles/jd-server/src/lib/mempool/mod.rs index a9aa8ecc93..57330cd597 100644 --- a/roles/jd-server/src/lib/mempool/mod.rs +++ b/roles/jd-server/src/lib/mempool/mod.rs @@ -7,7 +7,7 @@ use hashbrown::HashMap; use roles_logic_sv2::utils::Mutex; use rpc_sv2::{mini_rpc_client, mini_rpc_client::RpcError}; use std::{convert::TryInto, str::FromStr, sync::Arc}; -use stratum_common::{bitcoin, bitcoin::hash_types::Txid}; +use stratum_common::bitcoin::{self, hash_types::Txid}; #[derive(Clone, Debug)] pub struct TransactionWithHash { @@ -95,29 +95,29 @@ impl JDsMempool { } pub async fn update_mempool(self_: Arc>) -> Result<(), JdsMempoolError> { - let mut mempool_ordered: HashMap> = HashMap::new(); + + let mut new_jds_mempool: HashMap> = self_.safe_lock(|x| x.mempool.clone())?; + // the fat transactions in the jds-mempool are those declared by some downstream and we + // don't want to remove them, but we can get rid of the others + new_jds_mempool.retain(|_, val| val.is_some()); + let client = self_ .safe_lock(|x| x.get_client())? .ok_or(JdsMempoolError::NoClient)?; - - let mempool: Vec = client.get_raw_mempool().await?; - for id in &mempool { + let node_mempool: Vec = client.get_raw_mempool().await?; + // here we add all the new transactions + for id in &node_mempool { let key_id = Txid::from_str(id) .map_err(|err| JdsMempoolError::Rpc(RpcError::Deserialization(err.to_string())))?; - - let tx = self_.safe_lock(|x| match x.mempool.get(&key_id) { - Some(entry) => entry.clone(), - None => None, - })?; - - mempool_ordered.insert(key_id, tx); + // not sure if correct, check it! + new_jds_mempool.entry(key_id).or_insert(None); } - if mempool_ordered.is_empty() { + if new_jds_mempool.is_empty() { Err(JdsMempoolError::EmptyMempool) } else { - let _ = self_.safe_lock(|x| x.mempool = mempool_ordered); + let _ = self_.safe_lock(|x| x.mempool = new_jds_mempool); Ok(()) } }