commit aa19d0df3bc862ad94b9ba39d23da77c3e17926f
parent f7a5749be004d4ec463eff306ecbd9810ae84505
Author: Joris Hartog <jorishartog@hotmail.com>
Date: Wed, 23 Sep 2026 19:17:54 +0200
fix(mining): prioritize required hybrid anchor burn
Diffstat:
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/app/automatic_mining.rs b/src/app/automatic_mining.rs
@@ -406,7 +406,7 @@ impl NodeCore {
true,
) {
Ok((transaction, _)) => {
- self.submit_public_transaction_v2(transaction)?;
+ self.submit_prioritized_public_transaction_v2(transaction)?;
self.last_auto_anchor_burn_height = Some(current_height);
return Ok(None);
}
@@ -1085,6 +1085,10 @@ mod tests {
.apply_preverified_block_at(migration_block, u64::MAX)
.unwrap();
+ let queued_wallet_burn = ledger.build_v2_burn(&wallet, 1, 1).unwrap();
+ ledger
+ .submit_transaction_v2(queued_wallet_burn.clone())
+ .unwrap();
let pending_migration = ledger.build_v2_migration(&migrator, 1).unwrap();
ledger.submit_transaction_v2(pending_migration).unwrap();
let timestamp_ms = ledger.recovery_block_min_timestamp();
@@ -1096,6 +1100,7 @@ mod tests {
None
);
assert!(node.local_block_anchor_burn.is_none());
+ assert!(!node.ledger().pending_v2().contains(&queued_wallet_burn));
assert_eq!(
node.ledger()
.pending_v2()
diff --git a/src/app/receive.rs b/src/app/receive.rs
@@ -60,6 +60,20 @@ impl NodeCore {
Ok(transaction)
}
+ pub(super) fn submit_prioritized_public_transaction_v2(
+ &mut self,
+ transaction: TransactionV2,
+ ) -> Result<TransactionV2> {
+ let domain = self.ledger.transaction_v2_domain()?;
+ let envelope = hex_encode(transaction.encode(&domain)?);
+ let mut candidate = self.ledger.clone();
+ if candidate.prioritize_transaction_v2_for_block_building(transaction.clone())? {
+ self.ledger = candidate;
+ self.outbox.push(GossipEnvelope::TransactionV2 { envelope });
+ }
+ Ok(transaction)
+ }
+
pub fn receive_burn_bundle(&mut self, bundle: BurnBundle) -> Result<()> {
let next_height = self.ledger.height().saturating_add(1);
if bundle.height <= self.ledger.height() {
diff --git a/src/domain/ledger_mempool.rs b/src/domain/ledger_mempool.rs
@@ -10,7 +10,7 @@ use super::ledger_ops::{
use super::transaction::{Transaction, transaction_inputs_spent_by};
use super::{
Ledger, MAX_ORPHAN_TRANSACTIONS, MAX_PENDING_POOL_BYTES, MAX_PENDING_TRANSACTIONS,
- TransactionSubmitOutcome, spend_inputs_with_lineage,
+ TransactionSubmitOutcome, TransactionV2, spend_inputs_with_lineage,
};
impl Ledger {
@@ -40,6 +40,26 @@ impl Ledger {
Ok(true)
}
+ /// Inserts a required v2 anchor ahead of the current v2 mempool and then
+ /// rebuilds the displaced entries in their original order. Callers use a
+ /// cloned ledger and only publish it after the priority transaction is
+ /// admitted, so a failed replacement cannot mutate live state.
+ pub(crate) fn prioritize_transaction_v2_for_block_building(
+ &mut self,
+ transaction: TransactionV2,
+ ) -> Result<bool> {
+ let displaced = std::mem::take(&mut self.pending_v2);
+ self.pending_v2_bytes = 0;
+
+ if !self.submit_transaction_v2(transaction)?.added() {
+ return Ok(false);
+ }
+ for candidate in displaced {
+ let _ = self.submit_transaction_v2(candidate);
+ }
+ Ok(true)
+ }
+
pub(crate) fn reserve_transaction_inputs(&mut self, transaction: &Transaction) -> Result<()> {
self.validate_new_transaction(transaction)?;
let mut utxos = self.utxos.clone();