Skip to content

Commit f4711cf

Browse files
authored
Merge pull request #5605 from stacks-network/feat/replacement_tx_id_fork
feat: event emitter will now emit new_txid in-case a tx replaces another
2 parents e88623c + 8f234a2 commit f4711cf

File tree

5 files changed

+63
-16
lines changed

5 files changed

+63
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
88
## [Unreleased]
99

1010
### Added
11+
1112
- Add `tenure_timeout_secs` to the miner for determining when a time-based tenure extend should be attempted.
1213

1314
### Changed
1415

16+
- 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)
1517
- Nodes will assume that all PoX anchor blocks exist by default, and stall initial block download indefinitely to await their arrival (#5502)
1618

1719
## [3.1.0.0.1]

stackslib/src/chainstate/stacks/miner.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,8 +1427,16 @@ impl<'a> StacksMicroblockBuilder<'a> {
14271427
self.runtime.num_mined = num_txs;
14281428

14291429
mem_pool.drop_txs(&invalidated_txs)?;
1430-
event_dispatcher.mempool_txs_dropped(invalidated_txs, MemPoolDropReason::TOO_EXPENSIVE);
1431-
event_dispatcher.mempool_txs_dropped(to_drop_and_blacklist, MemPoolDropReason::PROBLEMATIC);
1430+
event_dispatcher.mempool_txs_dropped(
1431+
invalidated_txs,
1432+
None,
1433+
MemPoolDropReason::TOO_EXPENSIVE,
1434+
);
1435+
event_dispatcher.mempool_txs_dropped(
1436+
to_drop_and_blacklist,
1437+
None,
1438+
MemPoolDropReason::PROBLEMATIC,
1439+
);
14321440

14331441
if blocked {
14341442
debug!(
@@ -2543,8 +2551,12 @@ impl StacksBlockBuilder {
25432551
mempool.drop_txs(&invalidated_txs)?;
25442552

25452553
if let Some(observer) = event_observer {
2546-
observer.mempool_txs_dropped(invalidated_txs, MemPoolDropReason::TOO_EXPENSIVE);
2547-
observer.mempool_txs_dropped(to_drop_and_blacklist, MemPoolDropReason::PROBLEMATIC);
2554+
observer.mempool_txs_dropped(invalidated_txs, None, MemPoolDropReason::TOO_EXPENSIVE);
2555+
observer.mempool_txs_dropped(
2556+
to_drop_and_blacklist,
2557+
None,
2558+
MemPoolDropReason::PROBLEMATIC,
2559+
);
25482560
}
25492561

25502562
if let Err(e) = result {

stackslib/src/core/mempool.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,12 @@ pub trait ProposalCallbackReceiver: Send {
390390

391391
pub trait MemPoolEventDispatcher {
392392
fn get_proposal_callback_receiver(&self) -> Option<Box<dyn ProposalCallbackReceiver>>;
393-
fn mempool_txs_dropped(&self, txids: Vec<Txid>, reason: MemPoolDropReason);
393+
fn mempool_txs_dropped(
394+
&self,
395+
txids: Vec<Txid>,
396+
new_txid: Option<Txid>,
397+
reason: MemPoolDropReason,
398+
);
394399
fn mined_block_event(
395400
&self,
396401
target_burn_height: u64,
@@ -2229,7 +2234,7 @@ impl MemPoolDB {
22292234

22302235
// broadcast drop event if a tx is being replaced
22312236
if let (Some(prior_tx), Some(event_observer)) = (prior_tx, event_observer) {
2232-
event_observer.mempool_txs_dropped(vec![prior_tx.txid], replace_reason);
2237+
event_observer.mempool_txs_dropped(vec![prior_tx.txid], Some(txid), replace_reason);
22332238
};
22342239

22352240
Ok(())
@@ -2275,7 +2280,7 @@ impl MemPoolDB {
22752280
if let Some(event_observer) = event_observer {
22762281
let sql = "SELECT txid FROM mempool WHERE accept_time < ?1";
22772282
let txids = query_rows(tx, sql, args)?;
2278-
event_observer.mempool_txs_dropped(txids, MemPoolDropReason::STALE_COLLECT);
2283+
event_observer.mempool_txs_dropped(txids, None, MemPoolDropReason::STALE_COLLECT);
22792284
}
22802285

22812286
let sql = "DELETE FROM mempool WHERE accept_time < ?1";
@@ -2297,7 +2302,7 @@ impl MemPoolDB {
22972302
if let Some(event_observer) = event_observer {
22982303
let sql = "SELECT txid FROM mempool WHERE height < ?1";
22992304
let txids = query_rows(tx, sql, args)?;
2300-
event_observer.mempool_txs_dropped(txids, MemPoolDropReason::STALE_COLLECT);
2305+
event_observer.mempool_txs_dropped(txids, None, MemPoolDropReason::STALE_COLLECT);
23012306
}
23022307

23032308
let sql = "DELETE FROM mempool WHERE height < ?1";

stackslib/src/net/api/tests/postblock_proposal.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,13 @@ impl MemPoolEventDispatcher for ProposalTestObserver {
186186
Some(Box::new(Arc::clone(&self.proposal_observer)))
187187
}
188188

189-
fn mempool_txs_dropped(&self, txids: Vec<Txid>, reason: mempool::MemPoolDropReason) {}
189+
fn mempool_txs_dropped(
190+
&self,
191+
txids: Vec<Txid>,
192+
new_txid: Option<Txid>,
193+
reason: mempool::MemPoolDropReason,
194+
) {
195+
}
190196

191197
fn mined_block_event(
192198
&self,

testnet/stacks-node/src/event_dispatcher.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -952,9 +952,14 @@ impl ProposalCallbackReceiver for ProposalCallbackHandler {
952952
}
953953

954954
impl MemPoolEventDispatcher for EventDispatcher {
955-
fn mempool_txs_dropped(&self, txids: Vec<Txid>, reason: MemPoolDropReason) {
955+
fn mempool_txs_dropped(
956+
&self,
957+
txids: Vec<Txid>,
958+
new_txid: Option<Txid>,
959+
reason: MemPoolDropReason,
960+
) {
956961
if !txids.is_empty() {
957-
self.process_dropped_mempool_txs(txids, reason)
962+
self.process_dropped_mempool_txs(txids, new_txid, reason)
958963
}
959964
}
960965

@@ -1582,7 +1587,12 @@ impl EventDispatcher {
15821587
}
15831588
}
15841589

1585-
pub fn process_dropped_mempool_txs(&self, txs: Vec<Txid>, reason: MemPoolDropReason) {
1590+
pub fn process_dropped_mempool_txs(
1591+
&self,
1592+
txs: Vec<Txid>,
1593+
new_txid: Option<Txid>,
1594+
reason: MemPoolDropReason,
1595+
) {
15861596
// lazily assemble payload only if we have observers
15871597
let interested_observers = self.filter_observers(&self.mempool_observers_lookup, true);
15881598

@@ -1595,10 +1605,22 @@ impl EventDispatcher {
15951605
.map(|tx| serde_json::Value::String(format!("0x{tx}")))
15961606
.collect();
15971607

1598-
let payload = json!({
1599-
"dropped_txids": serde_json::Value::Array(dropped_txids),
1600-
"reason": reason.to_string(),
1601-
});
1608+
let payload = match new_txid {
1609+
Some(id) => {
1610+
json!({
1611+
"dropped_txids": serde_json::Value::Array(dropped_txids),
1612+
"reason": reason.to_string(),
1613+
"new_txid": format!("0x{}", &id),
1614+
})
1615+
}
1616+
None => {
1617+
json!({
1618+
"dropped_txids": serde_json::Value::Array(dropped_txids),
1619+
"reason": reason.to_string(),
1620+
"new_txid": null,
1621+
})
1622+
}
1623+
};
16021624

16031625
for observer in interested_observers.iter() {
16041626
observer.send_dropped_mempool_txs(&payload);

0 commit comments

Comments
 (0)