diff --git a/lib/core/src/persist/chain.rs b/lib/core/src/persist/chain.rs index d58ddae9f..a1db3240b 100644 --- a/lib/core/src/persist/chain.rs +++ b/lib/core/src/persist/chain.rs @@ -8,6 +8,7 @@ use crate::ensure_sdk; use crate::error::PaymentError; use crate::model::*; use crate::persist::{get_where_clause_state_in, Persister}; +use crate::sync::model::data::ChainSyncData; use crate::sync::model::RecordType; impl Persister { @@ -98,13 +99,21 @@ impl Persister { } pub(crate) fn insert_or_update_chain_swap(&self, chain_swap: &ChainSwap) -> Result<()> { + let maybe_swap = self.fetch_chain_swap_by_id(&chain_swap.id)?; + let updated_fields = ChainSyncData::updated_fields(maybe_swap, chain_swap); + let mut con = self.get_connection()?; let tx = con.transaction_with_behavior(TransactionBehavior::Immediate)?; Self::insert_or_update_chain_swap_inner(&tx, chain_swap)?; - self.commit_outgoing(&tx, &chain_swap.id, RecordType::Chain, None)?; - tx.commit()?; - self.sync_trigger.try_send(())?; + // Trigger a sync if: + // - updated_fields is None (swap is inserted, not updated) + // - updated_fields in a non empty list of updated fields + if updated_fields.as_ref().map_or(true, |u| !u.is_empty()) { + self.commit_outgoing(&tx, &chain_swap.id, RecordType::Chain, updated_fields)?; + tx.commit()?; + self.sync_trigger.try_send(())?; + } Ok(()) } diff --git a/lib/core/src/persist/receive.rs b/lib/core/src/persist/receive.rs index e1f57580f..74f7dd5a1 100644 --- a/lib/core/src/persist/receive.rs +++ b/lib/core/src/persist/receive.rs @@ -8,6 +8,7 @@ use crate::ensure_sdk; use crate::error::PaymentError; use crate::model::*; use crate::persist::{get_where_clause_state_in, Persister}; +use crate::sync::model::data::ReceiveSyncData; use crate::sync::model::RecordType; impl Persister { @@ -87,13 +88,21 @@ impl Persister { } pub(crate) fn insert_or_update_receive_swap(&self, receive_swap: &ReceiveSwap) -> Result<()> { + let maybe_swap = self.fetch_receive_swap_by_id(&receive_swap.id)?; + let updated_fields = ReceiveSyncData::updated_fields(maybe_swap, receive_swap); + let mut con = self.get_connection()?; let tx = con.transaction_with_behavior(TransactionBehavior::Immediate)?; Self::insert_or_update_receive_swap_inner(&tx, receive_swap)?; - self.commit_outgoing(&tx, &receive_swap.id, RecordType::Receive, None)?; - tx.commit()?; - self.sync_trigger.try_send(())?; + // Trigger a sync if: + // - updated_fields is None (swap is inserted, not updated) + // - updated_fields in a non empty list of updated fields + if updated_fields.as_ref().map_or(true, |u| !u.is_empty()) { + self.commit_outgoing(&tx, &receive_swap.id, RecordType::Receive, updated_fields)?; + tx.commit()?; + self.sync_trigger.try_send(())?; + } Ok(()) } diff --git a/lib/core/src/persist/send.rs b/lib/core/src/persist/send.rs index c63b3ae62..7b7c1e81c 100644 --- a/lib/core/src/persist/send.rs +++ b/lib/core/src/persist/send.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::error::PaymentError; use crate::model::*; use crate::persist::{get_where_clause_state_in, Persister}; +use crate::sync::model::data::SendSyncData; use crate::sync::model::RecordType; use crate::{ensure_sdk, get_updated_fields}; @@ -79,13 +80,21 @@ impl Persister { } pub(crate) fn insert_or_update_send_swap(&self, send_swap: &SendSwap) -> Result<()> { + let maybe_swap = self.fetch_send_swap_by_id(&send_swap.id)?; + let updated_fields = SendSyncData::updated_fields(maybe_swap, send_swap); + let mut con = self.get_connection()?; let tx = con.transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)?; Self::insert_or_update_send_swap_inner(&tx, send_swap)?; - self.commit_outgoing(&tx, &send_swap.id, RecordType::Send, None)?; - tx.commit()?; - self.sync_trigger.try_send(())?; + // Trigger a sync if: + // - updated_fields is None (swap is inserted, not updated) + // - updated_fields in a non empty list of updated fields + if updated_fields.as_ref().map_or(true, |u| !u.is_empty()) { + self.commit_outgoing(&tx, &send_swap.id, RecordType::Send, updated_fields)?; + tx.commit()?; + self.sync_trigger.try_send(())?; + } Ok(()) } diff --git a/lib/core/src/sync/model/data.rs b/lib/core/src/sync/model/data.rs index 8f434ba21..a03b98496 100644 --- a/lib/core/src/sync/model/data.rs +++ b/lib/core/src/sync/model/data.rs @@ -40,6 +40,32 @@ impl ChainSyncData { } } } + + pub(crate) fn updated_fields( + swap: Option, + update: &ChainSwap, + ) -> Option> { + match swap { + Some(swap) => { + let mut updated_fields = vec![]; + if update.accept_zero_conf != swap.accept_zero_conf { + updated_fields.push("accept_zero_conf".to_string()); + } + if update.payer_amount_sat != swap.payer_amount_sat { + updated_fields.push("payer_amount_sat".to_string()); + } + if update.receiver_amount_sat != swap.receiver_amount_sat { + updated_fields.push("receiver_amount_sat".to_string()); + } + if !matches!(update.expiry_at, Some(u) if swap.expiry_at.map_or(false, |s| s == u)) + { + updated_fields.push("expiry_at".to_string()); + } + Some(updated_fields) + } + None => None, + } + } } impl From for ChainSyncData { @@ -122,6 +148,24 @@ impl SendSyncData { } } } + + pub(crate) fn updated_fields(swap: Option, update: &SendSwap) -> Option> { + match swap { + Some(swap) => { + let mut updated_fields = vec![]; + if !matches!(update.preimage.clone(), Some(u) if swap.preimage.map_or(false, |s| s == u)) + { + updated_fields.push("preimage".to_string()); + } + if !matches!(update.expiry_at, Some(u) if swap.expiry_at.map_or(false, |s| s == u)) + { + updated_fields.push("expiry_at".to_string()); + } + Some(updated_fields) + } + None => None, + } + } } impl From for SendSyncData { @@ -195,6 +239,23 @@ impl ReceiveSyncData { } } } + + pub(crate) fn updated_fields( + swap: Option, + update: &ReceiveSwap, + ) -> Option> { + match swap { + Some(swap) => { + let mut updated_fields = vec![]; + if !matches!(update.expiry_at, Some(u) if swap.expiry_at.map_or(false, |s| s == u)) + { + updated_fields.push("expiry_at".to_string()); + } + Some(updated_fields) + } + None => None, + } + } } impl From for ReceiveSyncData {