Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
37d3003
use maker_lock_duration as min_final_cltv_expiry for maker lightning …
shamardy Nov 14, 2022
c5240e0
fix an issue where an invoice payment were not saved in db by the sid…
shamardy Nov 15, 2022
35fa410
use max_total_cltv_expiry_delta for send_taker_payment
shamardy Nov 16, 2022
74f1673
Make taker swap locktime when LightningCoin is Taker 24 hours and mak…
shamardy Nov 17, 2022
9a5f5d4
Merge remote-tracking branch 'origin/dev' into ln-locktime
shamardy Nov 17, 2022
9681cf7
validated min_final_cltv_expiry, add invoice expiry to swap invoices
shamardy Nov 18, 2022
88ab774
Merge remote-tracking branch 'origin/dev' into ln-locktime
shamardy Nov 21, 2022
c3371fc
Some fixes and refactors for lightning swaps locktimes
shamardy Nov 22, 2022
2d51395
retry taker payment on multiple routes
shamardy Nov 23, 2022
5df22cc
Merge remote-tracking branch 'origin/dev' into ln-locktime
shamardy Nov 23, 2022
1fe599a
lightning maker swap
shamardy Nov 24, 2022
b9f3309
refactor test_lightning_swaps
shamardy Nov 25, 2022
6ad031b
Merge remote-tracking branch 'origin/dev' into ln-locktime
shamardy Nov 25, 2022
76a3759
Merge remote-tracking branch 'origin/dev' into ln-locktime
shamardy Nov 25, 2022
9a5e5b2
fix rustfmt warnings
shamardy Nov 25, 2022
8eeca9e
remove unneeded todos and write better todos for next sprints
shamardy Nov 25, 2022
8dcd87f
fix wasm tests
shamardy Nov 25, 2022
680b570
fix max_total_cltv_expiry_delta in send_taker_payment to use blocks
shamardy Nov 28, 2022
c5f1180
Merge remote-tracking branch 'origin/dev' into ln-locktime
shamardy Nov 28, 2022
2a2a77c
Review fixes: use MmError::err, fix long todo msgs, avoid using error…
shamardy Nov 29, 2022
40364c2
Review fixes: use casting for created_at/updated_at instead of TryInto
shamardy Nov 29, 2022
de0fa05
Review fixes: fix some error messages,other refactors
shamardy Dec 7, 2022
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
25 changes: 23 additions & 2 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,15 +1110,36 @@ impl SwapOps for EthCoin {
Ok(())
}

async fn payment_instructions(
async fn maker_payment_instructions(
&self,
_secret_hash: &[u8],
_amount: &BigDecimal,
_maker_lock_duration: u64,
_expires_in: u64,
) -> Result<Option<Vec<u8>>, MmError<PaymentInstructionsErr>> {
Ok(None)
}

fn validate_instructions(
async fn taker_payment_instructions(
&self,
_secret_hash: &[u8],
_amount: &BigDecimal,
_expires_in: u64,
) -> Result<Option<Vec<u8>>, MmError<PaymentInstructionsErr>> {
Ok(None)
}

fn validate_maker_payment_instructions(
&self,
_instructions: &[u8],
_secret_hash: &[u8],
_amount: BigDecimal,
_maker_lock_duration: u64,
) -> Result<PaymentInstructions, MmError<ValidateInstructionsErr>> {
MmError::err(ValidateInstructionsErr::UnsupportedCoin(self.ticker().to_string()))
}

fn validate_taker_payment_instructions(
&self,
_instructions: &[u8],
_secret_hash: &[u8],
Expand Down
414 changes: 260 additions & 154 deletions mm2src/coins/lightning.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions mm2src/coins/lightning/ln_conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct PlatformCoinConfirmationTargets {
pub struct LightningProtocolConf {
pub platform_coin_ticker: String,
pub network: BlockchainNetwork,
pub avg_block_time: u64,
pub confirmation_targets: PlatformCoinConfirmationTargets,
}

Expand Down
139 changes: 81 additions & 58 deletions mm2src/coins/lightning/ln_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use utxo_signer::with_key_pair::sign_tx;
const TRY_LOOP_INTERVAL: f64 = 60.;
/// 1 second.
const CRITICAL_FUTURE_TIMEOUT: f64 = 1.0;
pub const SUCCESSFUL_CLAIM_LOG: &str = "Successfully claimed payment";
pub const SUCCESSFUL_SEND_LOG: &str = "Successfully sent payment";

pub struct LightningEventHandler {
platform: Arc<Platform>,
Expand Down Expand Up @@ -53,7 +55,7 @@ impl EventHandler for LightningEventHandler {
payment_hash,
amount_msat,
purpose,
} => self.handle_payment_received(payment_hash, *amount_msat, purpose),
} => self.handle_payment_received(*payment_hash, *amount_msat, purpose.clone()),

Event::PaymentSent {
payment_preimage,
Expand All @@ -62,7 +64,7 @@ impl EventHandler for LightningEventHandler {
..
} => self.handle_payment_sent(*payment_preimage, *payment_hash, *fee_paid_msat),

Event::PaymentClaimed { payment_hash, amount_msat, purpose } => self.handle_payment_claimed(*payment_hash, *amount_msat, purpose),
Event::PaymentClaimed { payment_hash, amount_msat, .. } => self.handle_payment_claimed(*payment_hash, *amount_msat),

Event::PaymentFailed { payment_hash, .. } => self.handle_payment_failed(*payment_hash),

Expand Down Expand Up @@ -333,19 +335,40 @@ impl LightningEventHandler {
self.platform.spawner().spawn_with_settings(fut, settings);
}

fn handle_payment_received(&self, payment_hash: &PaymentHash, received_amount: u64, purpose: &PaymentPurpose) {
fn handle_payment_received(&self, payment_hash: PaymentHash, received_amount: u64, purpose: PaymentPurpose) {
info!(
"Handling PaymentReceived event for payment_hash: {} with amount {}",
hex::encode(payment_hash.0),
received_amount
);
let db = self.db.clone();
let payment_preimage = match purpose {
PaymentPurpose::InvoicePayment { payment_preimage, .. } => match payment_preimage {
Some(preimage) => *preimage,
PaymentPurpose::InvoicePayment {
payment_preimage,
payment_secret,
} => match payment_preimage {
Some(preimage) => {
let fut = async move {
if let Ok(Some(mut payment_info)) =
db.get_payment_from_db(payment_hash).await.error_log_passthrough()
{
payment_info.preimage = Some(preimage);
payment_info.secret = Some(payment_secret);
payment_info.status = HTLCStatus::Received;
payment_info.last_updated = (now_ms() / 1000) as i64;
db.add_or_update_payment_in_db(payment_info)
.await
.error_log_with_msg("Unable to update payment information in DB!");
}
};
let settings = AbortSettings::default().critical_timout_s(CRITICAL_FUTURE_TIMEOUT);
self.platform.spawner().spawn_with_settings(fut, settings);
preimage
},
// This is a swap related payment since we don't have the preimage yet
None => {
let payment_info = PaymentInfo {
payment_hash: *payment_hash,
payment_hash,
payment_type: PaymentType::InboundPayment,
description: "Swap Payment".into(),
preimage: None,
Expand All @@ -357,14 +380,9 @@ impl LightningEventHandler {
),
fee_paid_msat: None,
status: HTLCStatus::Received,
created_at: (now_ms() / 1000)
.try_into()
.expect("created_at shouldn't exceed i64::MAX"),
last_updated: (now_ms() / 1000)
.try_into()
.expect("last_updated shouldn't exceed i64::MAX"),
created_at: (now_ms() / 1000) as i64,
last_updated: (now_ms() / 1000) as i64,
};
let db = self.db.clone();
let fut = async move {
db.add_or_update_payment_in_db(payment_info)
.await
Expand All @@ -377,58 +395,62 @@ impl LightningEventHandler {
return;
},
},
PaymentPurpose::SpontaneousPayment(preimage) => *preimage,
};
self.channel_manager.claim_funds(payment_preimage);
}

fn handle_payment_claimed(&self, payment_hash: PaymentHash, amount_msat: u64, purpose: &PaymentPurpose) {
info!(
"Received an amount of {} millisatoshis for payment hash {}",
amount_msat,
hex::encode(payment_hash.0)
);
let db = self.db.clone();
match *purpose {
PaymentPurpose::InvoicePayment { payment_preimage, .. } => {
let fut = async move {
if let Ok(Some(mut payment_info)) =
db.get_payment_from_db(payment_hash).await.error_log_passthrough()
{
payment_info.preimage = payment_preimage;
payment_info.status = HTLCStatus::Succeeded;
payment_info.amt_msat = Some(amount_msat as i64);
payment_info.last_updated = (now_ms() / 1000) as i64;
db.add_or_update_payment_in_db(payment_info)
.await
.error_log_with_msg("Unable to update payment information in DB!");
}
};
let settings = AbortSettings::default().critical_timout_s(CRITICAL_FUTURE_TIMEOUT);
self.platform.spawner().spawn_with_settings(fut, settings);
},
PaymentPurpose::SpontaneousPayment(payment_preimage) => {
PaymentPurpose::SpontaneousPayment(preimage) => {
let payment_info = PaymentInfo {
payment_hash,
payment_type: PaymentType::InboundPayment,
description: "".into(),
preimage: Some(payment_preimage),
description: "keysend".into(),
preimage: Some(preimage),
secret: None,
amt_msat: Some(amount_msat as i64),
amt_msat: Some(
received_amount
.try_into()
.expect("received_amount shouldn't exceed i64::MAX"),
),
fee_paid_msat: None,
status: HTLCStatus::Succeeded,
status: HTLCStatus::Received,
created_at: (now_ms() / 1000) as i64,
last_updated: (now_ms() / 1000) as i64,
};
let fut = async move {
db.add_or_update_payment_in_db(payment_info)
.await
.error_log_with_msg("Unable to update payment information in DB!");
.error_log_with_msg("Unable to add payment information to DB!");
};

let settings = AbortSettings::default().critical_timout_s(CRITICAL_FUTURE_TIMEOUT);
self.platform.spawner().spawn_with_settings(fut, settings);
preimage
},
}
};
self.channel_manager.claim_funds(payment_preimage);
}

fn handle_payment_claimed(&self, payment_hash: PaymentHash, amount_msat: u64) {
info!(
"Received an amount of {} millisatoshis for payment hash {}",
amount_msat,
hex::encode(payment_hash.0)
);
let db = self.db.clone();
let fut = async move {
if let Ok(Some(mut payment_info)) = db.get_payment_from_db(payment_hash).await.error_log_passthrough() {
payment_info.status = HTLCStatus::Succeeded;
payment_info.last_updated = (now_ms() / 1000) as i64;
let amt_msat = payment_info.amt_msat;
match db.add_or_update_payment_in_db(payment_info).await {
Ok(_) => info!(
"{} of {} millisatoshis with payment hash {}",
SUCCESSFUL_CLAIM_LOG,
amt_msat.unwrap_or_default(),
hex::encode(payment_hash.0),
),
Err(e) => error!("Unable to update payment information in DB error: {}", e),
}
}
};
let settings = AbortSettings::default().critical_timout_s(CRITICAL_FUTURE_TIMEOUT);
self.platform.spawner().spawn_with_settings(fut, settings);
}

fn handle_payment_sent(
Expand All @@ -449,14 +471,15 @@ impl LightningEventHandler {
payment_info.fee_paid_msat = fee_paid_msat.map(|f| f as i64);
payment_info.last_updated = (now_ms() / 1000) as i64;
let amt_msat = payment_info.amt_msat;
db.add_or_update_payment_in_db(payment_info)
.await
.error_log_with_msg("Unable to update payment information in DB!");
info!(
"Successfully sent payment of {} millisatoshis with payment hash {}",
amt_msat.unwrap_or_default(),
hex::encode(payment_hash.0)
);
match db.add_or_update_payment_in_db(payment_info).await {
Ok(_) => info!(
"{} of {} millisatoshis with payment hash {}",
SUCCESSFUL_SEND_LOG,
amt_msat.unwrap_or_default(),
hex::encode(payment_hash.0)
),
Err(e) => error!("Unable to update payment information in DB error: {}", e),
}
}
};
let settings = AbortSettings::default().critical_timout_s(CRITICAL_FUTURE_TIMEOUT);
Expand Down
4 changes: 4 additions & 0 deletions mm2src/coins/lightning/ln_platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ pub struct Platform {
pub coin: UtxoStandardCoin,
/// Main/testnet/signet/regtest Needed for lightning node to know which network to connect to
pub network: BlockchainNetwork,
/// The average time in seconds needed to mine a new block for the blockchain network.
pub avg_block_time: u64,
/// The best block height.
pub best_block_height: AtomicU64,
/// Number of blocks for every Confirmation target. This is used in the FeeEstimator.
Expand All @@ -176,6 +178,7 @@ impl Platform {
pub fn new(
coin: UtxoStandardCoin,
network: BlockchainNetwork,
avg_block_time: u64,
confirmations_targets: PlatformCoinConfirmationTargets,
) -> EnableLightningResult<Self> {
// Create an abortable system linked to the base `coin` so if the base coin is disabled,
Expand All @@ -185,6 +188,7 @@ impl Platform {
Ok(Platform {
coin,
network,
avg_block_time,
best_block_height: AtomicU64::new(0),
confirmations_targets,
latest_fees: LatestFees {
Expand Down
Loading