From 92627cfd463f9d69ab7c701de48c9c2435f26a74 Mon Sep 17 00:00:00 2001 From: usagi32 Date: Fri, 25 Oct 2024 00:21:47 +0530 Subject: [PATCH 1/5] feat: event emitter will now emit new_txid in-case a tx replaces another --- stackslib/src/chainstate/stacks/miner.rs | 8 +++--- stackslib/src/core/mempool.rs | 6 ++--- testnet/stacks-node/src/event_dispatcher.rs | 28 +++++++++++++++------ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index 7fb08335a2..d9a7851636 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -1406,8 +1406,8 @@ impl<'a> StacksMicroblockBuilder<'a> { self.runtime.num_mined = num_txs; mem_pool.drop_txs(&invalidated_txs)?; - event_dispatcher.mempool_txs_dropped(invalidated_txs, MemPoolDropReason::TOO_EXPENSIVE); - event_dispatcher.mempool_txs_dropped(to_drop_and_blacklist, MemPoolDropReason::PROBLEMATIC); + event_dispatcher.mempool_txs_dropped(invalidated_txs, None, MemPoolDropReason::TOO_EXPENSIVE); + event_dispatcher.mempool_txs_dropped(to_drop_and_blacklist, None, MemPoolDropReason::PROBLEMATIC); if blocked { debug!( @@ -2505,8 +2505,8 @@ impl StacksBlockBuilder { mempool.drop_txs(&invalidated_txs)?; if let Some(observer) = event_observer { - observer.mempool_txs_dropped(invalidated_txs, MemPoolDropReason::TOO_EXPENSIVE); - observer.mempool_txs_dropped(to_drop_and_blacklist, MemPoolDropReason::PROBLEMATIC); + observer.mempool_txs_dropped(invalidated_txs, None, MemPoolDropReason::TOO_EXPENSIVE); + observer.mempool_txs_dropped(to_drop_and_blacklist, None, MemPoolDropReason::PROBLEMATIC); } if let Err(e) = result { diff --git a/stackslib/src/core/mempool.rs b/stackslib/src/core/mempool.rs index bf2b5aff57..b2d8831de2 100644 --- a/stackslib/src/core/mempool.rs +++ b/stackslib/src/core/mempool.rs @@ -390,7 +390,7 @@ pub trait ProposalCallbackReceiver: Send { pub trait MemPoolEventDispatcher { fn get_proposal_callback_receiver(&self) -> Option>; - fn mempool_txs_dropped(&self, txids: Vec, reason: MemPoolDropReason); + fn mempool_txs_dropped(&self, txids: Vec, new_txid: Option, reason: MemPoolDropReason); fn mined_block_event( &self, target_burn_height: u64, @@ -2222,7 +2222,7 @@ impl MemPoolDB { // broadcast drop event if a tx is being replaced if let (Some(prior_tx), Some(event_observer)) = (prior_tx, event_observer) { - event_observer.mempool_txs_dropped(vec![prior_tx.txid], replace_reason); + event_observer.mempool_txs_dropped(vec![prior_tx.txid], Some(txid), replace_reason); }; Ok(()) @@ -2290,7 +2290,7 @@ impl MemPoolDB { if let Some(event_observer) = event_observer { let sql = "SELECT txid FROM mempool WHERE height < ?1"; let txids = query_rows(tx, sql, args)?; - event_observer.mempool_txs_dropped(txids, MemPoolDropReason::STALE_COLLECT); + event_observer.mempool_txs_dropped(txids, None, MemPoolDropReason::STALE_COLLECT); } let sql = "DELETE FROM mempool WHERE height < ?1"; diff --git a/testnet/stacks-node/src/event_dispatcher.rs b/testnet/stacks-node/src/event_dispatcher.rs index bb05cd6128..a789c095ee 100644 --- a/testnet/stacks-node/src/event_dispatcher.rs +++ b/testnet/stacks-node/src/event_dispatcher.rs @@ -941,9 +941,9 @@ impl ProposalCallbackReceiver for ProposalCallbackHandler { } impl MemPoolEventDispatcher for EventDispatcher { - fn mempool_txs_dropped(&self, txids: Vec, reason: MemPoolDropReason) { + fn mempool_txs_dropped(&self, txids: Vec, new_txid: Option, reason: MemPoolDropReason) { if !txids.is_empty() { - self.process_dropped_mempool_txs(txids, reason) + self.process_dropped_mempool_txs(txids, new_txid, reason) } } @@ -1554,7 +1554,7 @@ impl EventDispatcher { } } - pub fn process_dropped_mempool_txs(&self, txs: Vec, reason: MemPoolDropReason) { + pub fn process_dropped_mempool_txs(&self, txs: Vec, new_txid: Option, reason: MemPoolDropReason) { // lazily assemble payload only if we have observers let interested_observers = self.filter_observers(&self.mempool_observers_lookup, true); @@ -1566,11 +1566,23 @@ impl EventDispatcher { .into_iter() .map(|tx| serde_json::Value::String(format!("0x{}", &tx))) .collect(); - - let payload = json!({ - "dropped_txids": serde_json::Value::Array(dropped_txids), - "reason": reason.to_string(), - }); + + let payload = match new_txid{ + Some(id) => { + json!({ + "dropped_txids": serde_json::Value::Array(dropped_txids), + "reason": reason.to_string(), + "new_txid": format!("0x{}", &id), + }) + }, + None => { + json!({ + "dropped_txids": serde_json::Value::Array(dropped_txids), + "reason": reason.to_string(), + "new_txid": null, + }) + } + }; for observer in interested_observers.iter() { observer.send_dropped_mempool_txs(&payload); From 82c87017867c2374046e604a1bd4df8044ad9820 Mon Sep 17 00:00:00 2001 From: Brice Dobry Date: Wed, 20 Nov 2024 22:39:15 -0500 Subject: [PATCH 2/5] chore: formatting --- stackslib/src/chainstate/stacks/miner.rs | 18 +++++++++++++++--- stackslib/src/core/mempool.rs | 7 ++++++- testnet/stacks-node/src/event_dispatcher.rs | 20 +++++++++++++++----- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index 2282a38fad..834b39336d 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -1406,8 +1406,16 @@ impl<'a> StacksMicroblockBuilder<'a> { self.runtime.num_mined = num_txs; mem_pool.drop_txs(&invalidated_txs)?; - event_dispatcher.mempool_txs_dropped(invalidated_txs, None, MemPoolDropReason::TOO_EXPENSIVE); - event_dispatcher.mempool_txs_dropped(to_drop_and_blacklist, None, MemPoolDropReason::PROBLEMATIC); + event_dispatcher.mempool_txs_dropped( + invalidated_txs, + None, + MemPoolDropReason::TOO_EXPENSIVE, + ); + event_dispatcher.mempool_txs_dropped( + to_drop_and_blacklist, + None, + MemPoolDropReason::PROBLEMATIC, + ); if blocked { debug!( @@ -2506,7 +2514,11 @@ impl StacksBlockBuilder { if let Some(observer) = event_observer { observer.mempool_txs_dropped(invalidated_txs, None, MemPoolDropReason::TOO_EXPENSIVE); - observer.mempool_txs_dropped(to_drop_and_blacklist, None, MemPoolDropReason::PROBLEMATIC); + observer.mempool_txs_dropped( + to_drop_and_blacklist, + None, + MemPoolDropReason::PROBLEMATIC, + ); } if let Err(e) = result { diff --git a/stackslib/src/core/mempool.rs b/stackslib/src/core/mempool.rs index b2d8831de2..0e1824176a 100644 --- a/stackslib/src/core/mempool.rs +++ b/stackslib/src/core/mempool.rs @@ -390,7 +390,12 @@ pub trait ProposalCallbackReceiver: Send { pub trait MemPoolEventDispatcher { fn get_proposal_callback_receiver(&self) -> Option>; - fn mempool_txs_dropped(&self, txids: Vec, new_txid: Option, reason: MemPoolDropReason); + fn mempool_txs_dropped( + &self, + txids: Vec, + new_txid: Option, + reason: MemPoolDropReason, + ); fn mined_block_event( &self, target_burn_height: u64, diff --git a/testnet/stacks-node/src/event_dispatcher.rs b/testnet/stacks-node/src/event_dispatcher.rs index 0517739152..27103c7eda 100644 --- a/testnet/stacks-node/src/event_dispatcher.rs +++ b/testnet/stacks-node/src/event_dispatcher.rs @@ -951,7 +951,12 @@ impl ProposalCallbackReceiver for ProposalCallbackHandler { } impl MemPoolEventDispatcher for EventDispatcher { - fn mempool_txs_dropped(&self, txids: Vec, new_txid: Option, reason: MemPoolDropReason) { + fn mempool_txs_dropped( + &self, + txids: Vec, + new_txid: Option, + reason: MemPoolDropReason, + ) { if !txids.is_empty() { self.process_dropped_mempool_txs(txids, new_txid, reason) } @@ -1572,7 +1577,12 @@ impl EventDispatcher { } } - pub fn process_dropped_mempool_txs(&self, txs: Vec, new_txid: Option, reason: MemPoolDropReason) { + pub fn process_dropped_mempool_txs( + &self, + txs: Vec, + new_txid: Option, + reason: MemPoolDropReason, + ) { // lazily assemble payload only if we have observers let interested_observers = self.filter_observers(&self.mempool_observers_lookup, true); @@ -1584,15 +1594,15 @@ impl EventDispatcher { .into_iter() .map(|tx| serde_json::Value::String(format!("0x{}", &tx))) .collect(); - - let payload = match new_txid{ + + let payload = match new_txid { Some(id) => { json!({ "dropped_txids": serde_json::Value::Array(dropped_txids), "reason": reason.to_string(), "new_txid": format!("0x{}", &id), }) - }, + } None => { json!({ "dropped_txids": serde_json::Value::Array(dropped_txids), From 732946166cbc0a909417e49291321e6f91f2429b Mon Sep 17 00:00:00 2001 From: Jeff Bencin Date: Mon, 25 Nov 2024 09:24:56 -0500 Subject: [PATCH 3/5] fix: Builds again after merging `develop` --- stackslib/src/core/mempool.rs | 2 +- stackslib/src/net/api/tests/postblock_proposal.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/stackslib/src/core/mempool.rs b/stackslib/src/core/mempool.rs index ad0672a4ff..78eb7da115 100644 --- a/stackslib/src/core/mempool.rs +++ b/stackslib/src/core/mempool.rs @@ -2280,7 +2280,7 @@ impl MemPoolDB { if let Some(event_observer) = event_observer { let sql = "SELECT txid FROM mempool WHERE accept_time < ?1"; let txids = query_rows(tx, sql, args)?; - event_observer.mempool_txs_dropped(txids, MemPoolDropReason::STALE_COLLECT); + event_observer.mempool_txs_dropped(txids, None, MemPoolDropReason::STALE_COLLECT); } let sql = "DELETE FROM mempool WHERE accept_time < ?1"; diff --git a/stackslib/src/net/api/tests/postblock_proposal.rs b/stackslib/src/net/api/tests/postblock_proposal.rs index a8087bf36a..f22fabf7c9 100644 --- a/stackslib/src/net/api/tests/postblock_proposal.rs +++ b/stackslib/src/net/api/tests/postblock_proposal.rs @@ -186,7 +186,13 @@ impl MemPoolEventDispatcher for ProposalTestObserver { Some(Box::new(Arc::clone(&self.proposal_observer))) } - fn mempool_txs_dropped(&self, txids: Vec, reason: mempool::MemPoolDropReason) {} + fn mempool_txs_dropped( + &self, + txids: Vec, + new_txid: Option, + reason: mempool::MemPoolDropReason, + ) { + } fn mined_block_event( &self, From 1467cd78692753c397ddca6fe4ee9626c2f8982b Mon Sep 17 00:00:00 2001 From: Hank Stoever Date: Wed, 18 Dec 2024 11:56:20 -0800 Subject: [PATCH 4/5] fix: changelog, check errors --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 387cc1d9eb..082cd357b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ## [Unreleased] +- When a transaction is dropped due to replace-by-fee, the `/drop_mempool_tx` event observer payload now includes `new_txid`, which is the transaction that replaced this dropped transaction. When a transaction is dropped for other reasons, `new_txid` is `null`. [#5381](https://github.com/stacks-network/stacks-core/pull/5381) + ### Added - Add `tenure_timeout_secs` to the miner for determining when a time-based tenure extend should be attempted. From fec6a68f619e4b6a740c93e4cb4ffe88a3341144 Mon Sep 17 00:00:00 2001 From: Hank Stoever Date: Thu, 19 Dec 2024 07:34:48 -0800 Subject: [PATCH 5/5] fix: move changelog entry under "changed" --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 082cd357b2..a0cb92b25b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,13 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ## [Unreleased] -- When a transaction is dropped due to replace-by-fee, the `/drop_mempool_tx` event observer payload now includes `new_txid`, which is the transaction that replaced this dropped transaction. When a transaction is dropped for other reasons, `new_txid` is `null`. [#5381](https://github.com/stacks-network/stacks-core/pull/5381) - ### Added - Add `tenure_timeout_secs` to the miner for determining when a time-based tenure extend should be attempted. ### Changed +- When a transaction is dropped due to replace-by-fee, the `/drop_mempool_tx` event observer payload now includes `new_txid`, which is the transaction that replaced this dropped transaction. When a transaction is dropped for other reasons, `new_txid` is `null`. [#5381](https://github.com/stacks-network/stacks-core/pull/5381) + ## [3.1.0.0.1] ### Added