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
65 changes: 59 additions & 6 deletions src/maker/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ use tungstenite::Message;
use std::{
io::ErrorKind,
net::{Ipv4Addr, TcpListener, TcpStream},
sync::{atomic::Ordering::Relaxed, Arc},
sync::{
atomic::Ordering::{self, Relaxed},
Arc,
},
thread::{self, sleep},
time::Duration,
};
Expand Down Expand Up @@ -73,7 +76,7 @@ fn network_bootstrap(maker: Arc<Maker>) -> Result<String, MakerError> {
.as_ref()
.track_and_update_unconfirmed_fidelity_bonds()?;

manage_fidelity_bonds(maker.as_ref(), &maker_address)?;
manage_fidelity_bonds(maker, &maker_address, true)?;

Ok(maker_address)
}
Expand All @@ -83,13 +86,63 @@ fn network_bootstrap(maker: Arc<Maker>) -> Result<String, MakerError> {
/// It performs the following operations:
/// 1. Redeems all expired fidelity bonds in the maker's wallet, if any are found.
/// 2. Creates a new fidelity bond if no valid bonds remain after redemption.
fn manage_fidelity_bonds(maker: &Maker, maker_addr: &str) -> Result<(), MakerError> {
fn manage_fidelity_bonds(
maker: Arc<Maker>,
maker_addr: &str,
spawn_nostr: bool,
) -> Result<(), MakerError> {
maker
.wallet
.write()?
.redeem_expired_fidelity_bonds(AddressType::P2WPKH)?;
let fidelity = setup_fidelity_bond(maker, maker_addr)?;
broadcast_bond_on_nostr(fidelity)?;

let fidelity = setup_fidelity_bond(maker.as_ref(), maker_addr)?;

if spawn_nostr {
spawn_nostr_broadcast_task(fidelity, maker)?;
}

Ok(())
}
fn spawn_nostr_broadcast_task(
fidelity: FidelityProof,
maker: Arc<Maker>,
) -> Result<(), MakerError> {
log::info!("Spawning nostr background task for maker");
let maker_clone = maker.clone();

let handle = thread::Builder::new()
.name("nostr-event-thread".to_string())
.spawn(move || {
if let Err(e) = broadcast_bond_on_nostr(fidelity.clone()) {
log::warn!("initial nostr broadcast failed: {:?}", e);
}

let interval = Duration::from_secs(30 * 60);
let tick = Duration::from_secs(2);
let mut elapsed = Duration::ZERO;

while !maker_clone.shutdown.load(Ordering::Acquire) {
thread::sleep(tick);
elapsed += tick;

if elapsed < interval {
continue;
}

elapsed = Duration::ZERO;

log::debug!("re-pinging nostr relays with bond announcement");

if let Err(e) = broadcast_bond_on_nostr(fidelity.clone()) {
log::warn!("nostr re-ping failed: {:?}", e);
}
}

log::info!("nostr background task stopped");
})?;

maker.thread_pool.add_thread(handle);
Ok(())
}

Expand Down Expand Up @@ -571,7 +624,7 @@ pub fn start_maker_server(maker: Arc<Maker>) -> Result<(), MakerError> {
// potentially aborting the swap.
if maker.ongoing_swap_state.lock()?.is_empty() {
if interval_tracker.is_multiple_of(FIDELITY_BOND_UPDATE_INTERVAL) {
manage_fidelity_bonds(maker.as_ref(), &maker_addr)?;
manage_fidelity_bonds(maker.clone(), &maker_addr, false)?;
interval_tracker = 0;
}

Expand Down
62 changes: 56 additions & 6 deletions src/maker/server2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use nostr::{
use std::{
io::ErrorKind,
net::{Ipv4Addr, TcpListener, TcpStream},
sync::{atomic::Ordering::Relaxed, Arc},
sync::{
atomic::Ordering::{self, Relaxed},
Arc,
},
thread::{self, sleep},
time::{Duration, Instant},
};
Expand Down Expand Up @@ -65,24 +68,71 @@ fn network_bootstrap_taproot(maker: Arc<Maker>) -> Result<String, MakerError> {
.as_ref()
.track_and_update_unconfirmed_fidelity_bonds()?;

manage_fidelity_bonds_taproot(maker.as_ref(), &maker_address)?;
manage_fidelity_bonds_taproot(maker, &maker_address, true)?;

Ok(maker_address)
}

/// Setup's maker fidelity
fn manage_fidelity_bonds_taproot(maker: &Maker, maker_addr: &str) -> Result<(), MakerError> {
fn manage_fidelity_bonds_taproot(
maker: Arc<Maker>,
maker_addr: &str,
spawn_nostr: bool,
) -> Result<(), MakerError> {
// Redeem expired fidelity bonds first
maker
.wallet()
.write()?
.redeem_expired_fidelity_bonds(AddressType::P2TR)?;

// Create or get existing fidelity proof for taproot maker
let fidelity_proof = setup_fidelity_bond_taproot(maker, maker_addr)?;
let fidelity = setup_fidelity_bond_taproot(maker.as_ref(), maker_addr)?;

if spawn_nostr {
spawn_nostr_broadcast_task(fidelity, maker)?;
}

Ok(())
}

fn spawn_nostr_broadcast_task(
fidelity: FidelityProof,
maker: Arc<Maker>,
) -> Result<(), MakerError> {
log::info!("Spawning nostr background task for maker");
let maker_clone = maker.clone();

let handle = thread::Builder::new()
.name("nostr-event-thread".to_string())
.spawn(move || {
if let Err(e) = broadcast_bond_on_nostr(fidelity.clone()) {
log::warn!("initial nostr broadcast failed: {:?}", e);
}

let interval = Duration::from_secs(30 * 60);
let tick = Duration::from_secs(2);
let mut elapsed = Duration::ZERO;

while !maker_clone.shutdown.load(Ordering::Acquire) {
thread::sleep(tick);
elapsed += tick;

if elapsed < interval {
continue;
}

elapsed = Duration::ZERO;

broadcast_bond_on_nostr(fidelity_proof)?;
log::debug!("re-pinging nostr relays with bond announcement");

if let Err(e) = broadcast_bond_on_nostr(fidelity.clone()) {
log::warn!("nostr re-ping failed: {:?}", e);
}
}

log::info!("nostr background task stopped");
})?;

maker.thread_pool.add_thread(handle);
Ok(())
}

Expand Down
5 changes: 5 additions & 0 deletions src/taker/api2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,11 @@ impl Taker {
log::info!("Taproot swap recovery completed");
Ok(())
}

/// Indicates if offerbook syncing is in progress or not.
pub fn is_offerbook_syncing(&self) -> bool {
self.offer_sync_handle.is_syncing()
}
}

impl Role for Taker {
Expand Down
2 changes: 1 addition & 1 deletion src/taker/offers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use crate::{
use super::error::TakerError;

#[cfg(not(feature = "integration-test"))]
const OFFER_SYNC_INTERVAL: Duration = Duration::from_secs(5 * 60);
const OFFER_SYNC_INTERVAL: Duration = Duration::from_secs(15 * 60);

#[cfg(feature = "integration-test")]
const OFFER_SYNC_INTERVAL: Duration = Duration::from_secs(10);
Expand Down
45 changes: 20 additions & 25 deletions src/watch_tower/registry_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,36 +97,31 @@ impl FileRegistry {

/// Flushes the in-memory registry to the persistent CBOR file on disk.
fn flush(&self) {
// Ensure parent directory exists
if let Some(parent) = self.path.parent() {
if let Err(e) = std::fs::create_dir_all(parent) {
log::error!("Failed to create registry directory {:?}: {}", parent, e);
return;
}
let parent = match self.path.parent() {
Some(p) => p,
None => return,
};

if let Err(e) = std::fs::create_dir_all(parent) {
log::error!("Failed to create registry directory {:?}: {}", parent, e);
return;
}

let tmp = self.path.with_extension("tmp");
if let Ok(data) = self.data.lock() {
let bytes = match serde_cbor::to_vec(&*data) {
Ok(b) => b,
Err(e) => {
log::error!("Failed to serialize registry data: {}", e);
return;
}
};
let data = match self.data.lock() {
Ok(data) => data,
Err(_) => return,
};

if let Err(e) = std::fs::write(&tmp, &bytes) {
log::error!("Failed to write tmp registry file {:?}: {}", tmp, e);
let bytes = match serde_cbor::to_vec(&*data) {
Ok(bytes) => bytes,
Err(e) => {
log::error!("Failed to serialize registry data: {}", e);
return;
}
if let Err(e) = std::fs::rename(&tmp, &self.path) {
log::error!(
"Failed to rename registry file {:?} -> {:?}: {}",
tmp,
self.path,
e
);
}
};

if let Err(e) = std::fs::write(&self.path, &bytes) {
log::error!("Failed to write registry file {:?}: {}", self.path, e);
}
}
}
Expand Down