Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
## [Unreleased]

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

## [3.1.0.0.1]
Expand Down
20 changes: 16 additions & 4 deletions stackslib/src/chainstate/stacks/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,8 +1427,16 @@ 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!(
Expand Down Expand Up @@ -2543,8 +2551,12 @@ 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 {
Expand Down
13 changes: 9 additions & 4 deletions stackslib/src/core/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,12 @@ pub trait ProposalCallbackReceiver: Send {

pub trait MemPoolEventDispatcher {
fn get_proposal_callback_receiver(&self) -> Option<Box<dyn ProposalCallbackReceiver>>;
fn mempool_txs_dropped(&self, txids: Vec<Txid>, reason: MemPoolDropReason);
fn mempool_txs_dropped(
&self,
txids: Vec<Txid>,
new_txid: Option<Txid>,
reason: MemPoolDropReason,
);
fn mined_block_event(
&self,
target_burn_height: u64,
Expand Down Expand Up @@ -2229,7 +2234,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(())
Expand Down Expand Up @@ -2275,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";
Expand All @@ -2297,7 +2302,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";
Expand Down
8 changes: 7 additions & 1 deletion stackslib/src/net/api/tests/postblock_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,13 @@ impl MemPoolEventDispatcher for ProposalTestObserver {
Some(Box::new(Arc::clone(&self.proposal_observer)))
}

fn mempool_txs_dropped(&self, txids: Vec<Txid>, reason: mempool::MemPoolDropReason) {}
fn mempool_txs_dropped(
&self,
txids: Vec<Txid>,
new_txid: Option<Txid>,
reason: mempool::MemPoolDropReason,
) {
}

fn mined_block_event(
&self,
Expand Down
36 changes: 29 additions & 7 deletions testnet/stacks-node/src/event_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,9 +952,14 @@ impl ProposalCallbackReceiver for ProposalCallbackHandler {
}

impl MemPoolEventDispatcher for EventDispatcher {
fn mempool_txs_dropped(&self, txids: Vec<Txid>, reason: MemPoolDropReason) {
fn mempool_txs_dropped(
&self,
txids: Vec<Txid>,
new_txid: Option<Txid>,
reason: MemPoolDropReason,
) {
if !txids.is_empty() {
self.process_dropped_mempool_txs(txids, reason)
self.process_dropped_mempool_txs(txids, new_txid, reason)
}
}

Expand Down Expand Up @@ -1582,7 +1587,12 @@ impl EventDispatcher {
}
}

pub fn process_dropped_mempool_txs(&self, txs: Vec<Txid>, reason: MemPoolDropReason) {
pub fn process_dropped_mempool_txs(
&self,
txs: Vec<Txid>,
new_txid: Option<Txid>,
reason: MemPoolDropReason,
) {
// lazily assemble payload only if we have observers
let interested_observers = self.filter_observers(&self.mempool_observers_lookup, true);

Expand All @@ -1595,10 +1605,22 @@ impl EventDispatcher {
.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);
Expand Down