Skip to content

Commit

Permalink
Add swap expiry timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
dangeross authored and hydra-yse committed Dec 24, 2024
1 parent 6782e8b commit 944211e
Show file tree
Hide file tree
Showing 27 changed files with 402 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ typedef struct wire_cst_ln_url_info {
typedef struct wire_cst_PaymentDetails_Lightning {
struct wire_cst_list_prim_u_8_strict *swap_id;
struct wire_cst_list_prim_u_8_strict *description;
uint32_t *expiry_timestamp;
struct wire_cst_list_prim_u_8_strict *preimage;
struct wire_cst_list_prim_u_8_strict *bolt11;
struct wire_cst_list_prim_u_8_strict *bolt12_offer;
Expand All @@ -489,6 +490,7 @@ typedef struct wire_cst_PaymentDetails_Liquid {
typedef struct wire_cst_PaymentDetails_Bitcoin {
struct wire_cst_list_prim_u_8_strict *swap_id;
struct wire_cst_list_prim_u_8_strict *description;
uint32_t *expiry_timestamp;
struct wire_cst_list_prim_u_8_strict *refund_tx_id;
uint64_t *refund_tx_amount_sat;
} wire_cst_PaymentDetails_Bitcoin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ class SwapUpdatedTask : TaskProtocol {
func getSwapId(details: PaymentDetails?) -> String? {
if let details = details {
switch details {
case let .bitcoin(swapId, _, _, _):
case let .bitcoin(swapId, _, _, _, _):
return swapId
case let .lightning(swapId, _, _, _, _, _, _, _, _):
case let .lightning(swapId, _, _, _, _, _, _, _, _, _):
return swapId
default:
break
Expand Down
4 changes: 2 additions & 2 deletions lib/bindings/src/breez_sdk_liquid.udl
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,9 @@ dictionary LnUrlInfo {

[Enum]
interface PaymentDetails {
Lightning(string swap_id, string description, string? preimage, string? bolt11, string? bolt12_offer, string? payment_hash, LnUrlInfo? lnurl_info, string? refund_tx_id, u64? refund_tx_amount_sat);
Lightning(string swap_id, string description, u32? expiry_timestamp, string? preimage, string? bolt11, string? bolt12_offer, string? payment_hash, LnUrlInfo? lnurl_info, string? refund_tx_id, u64? refund_tx_amount_sat);
Liquid(string destination, string description);
Bitcoin(string swap_id, string description, string? refund_tx_id, u64? refund_tx_amount_sat);
Bitcoin(string swap_id, string description, u32? expiry_timestamp, string? refund_tx_id, u64? refund_tx_amount_sat);
};

dictionary Payment {
Expand Down
2 changes: 2 additions & 0 deletions lib/core/src/chain/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use crate::{
prelude::Utxo,
};

pub(crate) const ESTIMATED_BITCOIN_BLOCK_TIME_SEC: u32 = 600;

/// Trait implemented by types that can fetch data from a blockchain data source.
#[allow(dead_code)]
#[async_trait]
Expand Down
8 changes: 5 additions & 3 deletions lib/core/src/chain/liquid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use async_trait::async_trait;
use boltz_client::ToHex;
use log::{info, warn};
use lwk_wollet::elements::hex::FromHex;
use lwk_wollet::elements::BlockHeader;
use lwk_wollet::{
elements::{
pset::serialize::Serialize, Address, BlockHash, OutPoint, Script, Transaction, Txid,
Expand All @@ -22,11 +23,12 @@ use crate::{
};

const LIQUID_ESPLORA_URL: &str = "https://lq1.breez.technology/liquid/api";
pub(crate) const ESTIMATED_LIQUID_BLOCK_TIME_SEC: u32 = 60;

#[async_trait]
pub trait LiquidChainService: Send + Sync {
/// Get the blockchain latest block
async fn tip(&mut self) -> Result<u32>;
async fn tip(&mut self) -> Result<BlockHeader>;

/// Broadcast a transaction
async fn broadcast(&self, tx: &Transaction, swap_id: Option<&str>) -> Result<Txid>;
Expand Down Expand Up @@ -99,8 +101,8 @@ impl HybridLiquidChainService {

#[async_trait]
impl LiquidChainService for HybridLiquidChainService {
async fn tip(&mut self) -> Result<u32> {
Ok(self.electrum_client.tip()?.height)
async fn tip(&mut self) -> Result<BlockHeader> {
Ok(self.electrum_client.tip()?)
}

async fn broadcast(&self, tx: &Transaction, swap_id: Option<&str>) -> Result<Txid> {
Expand Down
16 changes: 16 additions & 0 deletions lib/core/src/frb_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3619,6 +3619,7 @@ impl SseDecode for crate::model::PaymentDetails {
0 => {
let mut var_swapId = <String>::sse_decode(deserializer);
let mut var_description = <String>::sse_decode(deserializer);
let mut var_expiryTimestamp = <Option<u32>>::sse_decode(deserializer);
let mut var_preimage = <Option<String>>::sse_decode(deserializer);
let mut var_bolt11 = <Option<String>>::sse_decode(deserializer);
let mut var_bolt12Offer = <Option<String>>::sse_decode(deserializer);
Expand All @@ -3629,6 +3630,7 @@ impl SseDecode for crate::model::PaymentDetails {
return crate::model::PaymentDetails::Lightning {
swap_id: var_swapId,
description: var_description,
expiry_timestamp: var_expiryTimestamp,
preimage: var_preimage,
bolt11: var_bolt11,
bolt12_offer: var_bolt12Offer,
Expand All @@ -3649,11 +3651,13 @@ impl SseDecode for crate::model::PaymentDetails {
2 => {
let mut var_swapId = <String>::sse_decode(deserializer);
let mut var_description = <String>::sse_decode(deserializer);
let mut var_expiryTimestamp = <Option<u32>>::sse_decode(deserializer);
let mut var_refundTxId = <Option<String>>::sse_decode(deserializer);
let mut var_refundTxAmountSat = <Option<u64>>::sse_decode(deserializer);
return crate::model::PaymentDetails::Bitcoin {
swap_id: var_swapId,
description: var_description,
expiry_timestamp: var_expiryTimestamp,
refund_tx_id: var_refundTxId,
refund_tx_amount_sat: var_refundTxAmountSat,
};
Expand Down Expand Up @@ -5687,6 +5691,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PaymentDetails {
crate::model::PaymentDetails::Lightning {
swap_id,
description,
expiry_timestamp,
preimage,
bolt11,
bolt12_offer,
Expand All @@ -5698,6 +5703,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PaymentDetails {
0.into_dart(),
swap_id.into_into_dart().into_dart(),
description.into_into_dart().into_dart(),
expiry_timestamp.into_into_dart().into_dart(),
preimage.into_into_dart().into_dart(),
bolt11.into_into_dart().into_dart(),
bolt12_offer.into_into_dart().into_dart(),
Expand All @@ -5719,12 +5725,14 @@ impl flutter_rust_bridge::IntoDart for crate::model::PaymentDetails {
crate::model::PaymentDetails::Bitcoin {
swap_id,
description,
expiry_timestamp,
refund_tx_id,
refund_tx_amount_sat,
} => [
2.into_dart(),
swap_id.into_into_dart().into_dart(),
description.into_into_dart().into_dart(),
expiry_timestamp.into_into_dart().into_dart(),
refund_tx_id.into_into_dart().into_dart(),
refund_tx_amount_sat.into_into_dart().into_dart(),
]
Expand Down Expand Up @@ -7743,6 +7751,7 @@ impl SseEncode for crate::model::PaymentDetails {
crate::model::PaymentDetails::Lightning {
swap_id,
description,
expiry_timestamp,
preimage,
bolt11,
bolt12_offer,
Expand All @@ -7754,6 +7763,7 @@ impl SseEncode for crate::model::PaymentDetails {
<i32>::sse_encode(0, serializer);
<String>::sse_encode(swap_id, serializer);
<String>::sse_encode(description, serializer);
<Option<u32>>::sse_encode(expiry_timestamp, serializer);
<Option<String>>::sse_encode(preimage, serializer);
<Option<String>>::sse_encode(bolt11, serializer);
<Option<String>>::sse_encode(bolt12_offer, serializer);
Expand All @@ -7773,12 +7783,14 @@ impl SseEncode for crate::model::PaymentDetails {
crate::model::PaymentDetails::Bitcoin {
swap_id,
description,
expiry_timestamp,
refund_tx_id,
refund_tx_amount_sat,
} => {
<i32>::sse_encode(2, serializer);
<String>::sse_encode(swap_id, serializer);
<String>::sse_encode(description, serializer);
<Option<u32>>::sse_encode(expiry_timestamp, serializer);
<Option<String>>::sse_encode(refund_tx_id, serializer);
<Option<u64>>::sse_encode(refund_tx_amount_sat, serializer);
}
Expand Down Expand Up @@ -9758,6 +9770,7 @@ mod io {
crate::model::PaymentDetails::Lightning {
swap_id: ans.swap_id.cst_decode(),
description: ans.description.cst_decode(),
expiry_timestamp: ans.expiry_timestamp.cst_decode(),
preimage: ans.preimage.cst_decode(),
bolt11: ans.bolt11.cst_decode(),
bolt12_offer: ans.bolt12_offer.cst_decode(),
Expand All @@ -9779,6 +9792,7 @@ mod io {
crate::model::PaymentDetails::Bitcoin {
swap_id: ans.swap_id.cst_decode(),
description: ans.description.cst_decode(),
expiry_timestamp: ans.expiry_timestamp.cst_decode(),
refund_tx_id: ans.refund_tx_id.cst_decode(),
refund_tx_amount_sat: ans.refund_tx_amount_sat.cst_decode(),
}
Expand Down Expand Up @@ -13201,6 +13215,7 @@ mod io {
pub struct wire_cst_PaymentDetails_Lightning {
swap_id: *mut wire_cst_list_prim_u_8_strict,
description: *mut wire_cst_list_prim_u_8_strict,
expiry_timestamp: *mut u32,
preimage: *mut wire_cst_list_prim_u_8_strict,
bolt11: *mut wire_cst_list_prim_u_8_strict,
bolt12_offer: *mut wire_cst_list_prim_u_8_strict,
Expand All @@ -13220,6 +13235,7 @@ mod io {
pub struct wire_cst_PaymentDetails_Bitcoin {
swap_id: *mut wire_cst_list_prim_u_8_strict,
description: *mut wire_cst_list_prim_u_8_strict,
expiry_timestamp: *mut u32,
refund_tx_id: *mut wire_cst_list_prim_u_8_strict,
refund_tx_amount_sat: *mut u64,
}
Expand Down
34 changes: 32 additions & 2 deletions lib/core/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ pub(crate) struct ChainSwap {
/// Persisted as soon as a refund tx is broadcast
pub(crate) refund_tx_id: Option<String>,
pub(crate) created_at: u32,
pub(crate) expiry_at: Option<u32>,
pub(crate) state: PaymentState,
pub(crate) claim_private_key: String,
pub(crate) refund_private_key: String,
Expand Down Expand Up @@ -879,6 +880,7 @@ pub(crate) struct SendSwap {
/// Persisted as soon as a refund tx is broadcast
pub(crate) refund_tx_id: Option<String>,
pub(crate) created_at: u32,
pub(crate) expiry_at: Option<u32>,
pub(crate) state: PaymentState,
pub(crate) refund_private_key: String,
}
Expand Down Expand Up @@ -972,6 +974,7 @@ pub(crate) struct ReceiveSwap {
/// Until the lockup tx is seen in the mempool, it contains the swap creation time.
/// Afterwards, it shows the lockup tx creation time.
pub(crate) created_at: u32,
pub(crate) expiry_at: Option<u32>,
pub(crate) state: PaymentState,
}
impl ReceiveSwap {
Expand Down Expand Up @@ -1122,6 +1125,13 @@ pub enum PaymentState {
/// When the refund tx is broadcast, `refund_tx_id` is set in the swap.
RefundPending = 6,
}

impl PaymentState {
pub(crate) fn is_ongoing(&self) -> bool {
matches!(self, Self::Created | Self::Pending)
}
}

impl ToSql for PaymentState {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
Ok(rusqlite::types::ToSqlOutput::from(*self as i8))
Expand Down Expand Up @@ -1238,6 +1248,9 @@ pub struct PaymentSwapData {
/// Swap creation timestamp
pub created_at: u32,

/// Swap expiry timestamp
pub expiry_at: Option<u32>,

pub preimage: Option<String>,
pub bolt11: Option<String>,
pub bolt12_offer: Option<String>,
Expand Down Expand Up @@ -1288,7 +1301,10 @@ pub enum PaymentDetails {
/// Represents the invoice description
description: String,

/// In case of a Send swap, this is the preimage of the paid invoice (proof of payment).
/// The estimated swap expiry
expiry_timestamp: Option<u32>,

/// The preimage of the paid invoice (proof of payment).
preimage: Option<String>,

/// Represents the Bolt11 invoice associated with a payment
Expand Down Expand Up @@ -1325,6 +1341,9 @@ pub enum PaymentDetails {
/// Represents the invoice description
description: String,

/// The estimated swap expiry
expiry_timestamp: Option<u32>,

/// For a Send swap which was refunded, this is the refund tx id
refund_tx_id: Option<String>,

Expand Down Expand Up @@ -1434,7 +1453,18 @@ impl Payment {
swapper_fees_sat: Some(swap.swapper_fees_sat),
payment_type,
status: swap.status,
details: payment_details,
details: PaymentDetails::Lightning {
swap_id: swap.swap_id,
preimage: swap.preimage,
bolt11: swap.bolt11,
bolt12_offer: swap.bolt12_offer,
payment_hash: swap.payment_hash,
description: swap.description,
expiry_timestamp: swap.expiry_at,
lnurl_info: None,
refund_tx_id: swap.refund_tx_id,
refund_tx_amount_sat: swap.refund_tx_amount_sat,
},
}
}

Expand Down
12 changes: 9 additions & 3 deletions lib/core/src/persist/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ impl Persister {
refund_private_key,
claim_fees_sat,
created_at,
expiry_at,
state
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT DO NOTHING",
(
&chain_swap.id,
Expand All @@ -54,6 +55,7 @@ impl Persister {
&chain_swap.refund_private_key,
&chain_swap.claim_fees_sat,
&chain_swap.created_at,
&chain_swap.expiry_at,
&chain_swap.state,
),
)?;
Expand All @@ -71,6 +73,7 @@ impl Persister {
claim_tx_id = :claim_tx_id,
refund_tx_id = :refund_tx_id,
pair_fees_json = :pair_fees_json,
expiry_at = :expiry_at,
state = :state
WHERE
id = :id",
Expand All @@ -86,6 +89,7 @@ impl Persister {
":claim_tx_id": &chain_swap.claim_tx_id,
":refund_tx_id": &chain_swap.refund_tx_id,
":pair_fees_json": &chain_swap.pair_fees_json,
":expiry_at": &chain_swap.expiry_at,
":state": &chain_swap.state,
},
)?;
Expand Down Expand Up @@ -134,6 +138,7 @@ impl Persister {
claim_tx_id,
refund_tx_id,
created_at,
expiry_at,
state,
pair_fees_json
FROM chain_swaps
Expand Down Expand Up @@ -183,8 +188,9 @@ impl Persister {
claim_tx_id: row.get(16)?,
refund_tx_id: row.get(17)?,
created_at: row.get(18)?,
state: row.get(19)?,
pair_fees_json: row.get(20)?,
expiry_at: row.get(19)?,
state: row.get(20)?,
pair_fees_json: row.get(21)?,
})
}

Expand Down
5 changes: 5 additions & 0 deletions lib/core/src/persist/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,10 @@ pub(crate) fn current_migrations() -> Vec<&'static str> {
) STRICT;",
"ALTER TABLE receive_swaps DROP COLUMN mrh_script_pubkey;",
"ALTER TABLE payment_details ADD COLUMN lnurl_info_json TEXT;",
"
ALTER TABLE receive_swaps ADD COLUMN expiry_at INTEGER;
ALTER TABLE send_swaps ADD COLUMN expiry_at INTEGER;
ALTER TABLE chain_swaps ADD COLUMN expiry_at INTEGER;
",
]
}
Loading

0 comments on commit 944211e

Please sign in to comment.