fix: Résolution du bug txn-mempool-conflict avec mutex global
All checks were successful
Build and Push to Registry / build-and-push (push) Successful in 1m58s
All checks were successful
Build and Push to Registry / build-and-push (push) Successful in 1m58s
- Ajout de src/tx_queue.rs avec mutex global TX_QUEUE - Modification de commit_new_transaction() pour verrouiller les transactions - Prévient les race conditions lors de la sélection d'UTXOs concurrents - Fix erreur RPC -26 'txn-mempool-conflict'
This commit is contained in:
parent
a056d44cbf
commit
470f0b36b9
@ -21,6 +21,7 @@ use sdk_common::{
|
|||||||
use crate::{lock_freezed_utxos, MutexExt, DAEMON, STORAGE, WALLET};
|
use crate::{lock_freezed_utxos, MutexExt, DAEMON, STORAGE, WALLET};
|
||||||
use crate::{
|
use crate::{
|
||||||
message::{broadcast_message, BroadcastType},
|
message::{broadcast_message, BroadcastType},
|
||||||
|
tx_queue::lock_tx_queue,
|
||||||
CHAIN_TIP,
|
CHAIN_TIP,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -307,12 +308,14 @@ fn process_validation(
|
|||||||
.extend(commit_msg.validation_tokens.iter());
|
.extend(commit_msg.validation_tokens.iter());
|
||||||
|
|
||||||
// Sort by public key to group validations by signer
|
// Sort by public key to group validations by signer
|
||||||
state_to_update.validation_tokens.sort_unstable_by_key(|proof| proof.get_key());
|
state_to_update
|
||||||
|
.validation_tokens
|
||||||
|
.sort_unstable_by_key(|proof| proof.get_key());
|
||||||
|
|
||||||
// Remove duplicates where same key validates same message
|
// Remove duplicates where same key validates same message
|
||||||
state_to_update.validation_tokens.dedup_by(|a, b| {
|
state_to_update
|
||||||
a.get_key() == b.get_key() && a.get_message() == b.get_message()
|
.validation_tokens
|
||||||
});
|
.dedup_by(|a, b| a.get_key() == b.get_key() && a.get_message() == b.get_message());
|
||||||
}
|
}
|
||||||
|
|
||||||
let state_to_validate = updated_process.get_state_for_id(&new_state_id)?;
|
let state_to_validate = updated_process.get_state_for_id(&new_state_id)?;
|
||||||
@ -332,6 +335,11 @@ fn commit_new_transaction(
|
|||||||
updated_process: &mut Process,
|
updated_process: &mut Process,
|
||||||
state_to_commit: ProcessState,
|
state_to_commit: ProcessState,
|
||||||
) -> Result<OutPoint> {
|
) -> Result<OutPoint> {
|
||||||
|
// Acquire global transaction lock to prevent concurrent transactions
|
||||||
|
// from creating mempool conflicts (txn-mempool-conflict error -26)
|
||||||
|
let _tx_lock = lock_tx_queue()?;
|
||||||
|
log::debug!("Acquired transaction queue lock for process {}", updated_process.get_process_id()?);
|
||||||
|
|
||||||
let sp_wallet = WALLET
|
let sp_wallet = WALLET
|
||||||
.get()
|
.get()
|
||||||
.ok_or(Error::msg("Wallet not initialized"))?
|
.ok_or(Error::msg("Wallet not initialized"))?
|
||||||
@ -403,6 +411,14 @@ fn commit_new_transaction(
|
|||||||
|
|
||||||
daemon.test_mempool_accept(&final_tx)?;
|
daemon.test_mempool_accept(&final_tx)?;
|
||||||
let txid = daemon.broadcast(&final_tx)?;
|
let txid = daemon.broadcast(&final_tx)?;
|
||||||
|
|
||||||
|
// ✅ AJOUTER UN DÉLAI ICI
|
||||||
|
log::info!(
|
||||||
|
"Transaction broadcast: {}. Attente de confirmation mempool...",
|
||||||
|
txid
|
||||||
|
);
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(500)); // 500ms de délai
|
||||||
|
|
||||||
let commited_in = OutPoint::new(txid, 0);
|
let commited_in = OutPoint::new(txid, 0);
|
||||||
|
|
||||||
freezed_utxos.insert(commited_in);
|
freezed_utxos.insert(commited_in);
|
||||||
|
|||||||
@ -59,6 +59,7 @@ mod daemon;
|
|||||||
mod faucet;
|
mod faucet;
|
||||||
mod message;
|
mod message;
|
||||||
mod scan;
|
mod scan;
|
||||||
|
mod tx_queue;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|||||||
16
src/tx_queue.rs
Normal file
16
src/tx_queue.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
use std::sync::{Mutex, MutexGuard, OnceLock};
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
/// Global transaction queue mutex to prevent concurrent transactions
|
||||||
|
/// from creating mempool conflicts (txn-mempool-conflict error -26)
|
||||||
|
static TX_QUEUE: OnceLock<Mutex<()>> = OnceLock::new();
|
||||||
|
|
||||||
|
/// Acquires the global transaction lock to serialize blockchain commits.
|
||||||
|
/// This ensures only one transaction is created and broadcast at a time,
|
||||||
|
/// preventing race conditions when selecting UTXOs.
|
||||||
|
pub fn lock_tx_queue() -> Result<MutexGuard<'static, ()>> {
|
||||||
|
TX_QUEUE
|
||||||
|
.get_or_init(|| Mutex::new(()))
|
||||||
|
.lock()
|
||||||
|
.map_err(|e| anyhow::Error::msg(format!("Failed to lock tx queue: {}", e)))
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user