diff --git a/Cargo.lock b/Cargo.lock index 409b7d982..41dbf20fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1371,7 +1371,7 @@ dependencies = [ [[package]] name = "dlc" version = "0.4.0" -source = "git+https://github.com/get10101/rust-dlc?rev=8d9920d#8d9920d937e985c5eb3a53779dc6c43d635bf8ba" +source = "git+https://github.com/get10101/rust-dlc?rev=2545d6e#2545d6e90da92cc86eb8673a0cf6856bfb82d40d" dependencies = [ "bitcoin 0.29.2", "miniscript 8.0.2", @@ -1383,7 +1383,7 @@ dependencies = [ [[package]] name = "dlc-manager" version = "0.4.0" -source = "git+https://github.com/get10101/rust-dlc?rev=8d9920d#8d9920d937e985c5eb3a53779dc6c43d635bf8ba" +source = "git+https://github.com/get10101/rust-dlc?rev=2545d6e#2545d6e90da92cc86eb8673a0cf6856bfb82d40d" dependencies = [ "async-trait", "bitcoin 0.29.2", @@ -1399,7 +1399,7 @@ dependencies = [ [[package]] name = "dlc-messages" version = "0.4.0" -source = "git+https://github.com/get10101/rust-dlc?rev=8d9920d#8d9920d937e985c5eb3a53779dc6c43d635bf8ba" +source = "git+https://github.com/get10101/rust-dlc?rev=2545d6e#2545d6e90da92cc86eb8673a0cf6856bfb82d40d" dependencies = [ "bitcoin 0.29.2", "dlc", @@ -1412,7 +1412,7 @@ dependencies = [ [[package]] name = "dlc-trie" version = "0.4.0" -source = "git+https://github.com/get10101/rust-dlc?rev=8d9920d#8d9920d937e985c5eb3a53779dc6c43d635bf8ba" +source = "git+https://github.com/get10101/rust-dlc?rev=2545d6e#2545d6e90da92cc86eb8673a0cf6856bfb82d40d" dependencies = [ "bitcoin 0.29.2", "dlc", @@ -2816,7 +2816,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p2pd-oracle-client" version = "0.1.0" -source = "git+https://github.com/get10101/rust-dlc?rev=8d9920d#8d9920d937e985c5eb3a53779dc6c43d635bf8ba" +source = "git+https://github.com/get10101/rust-dlc?rev=2545d6e#2545d6e90da92cc86eb8673a0cf6856bfb82d40d" dependencies = [ "chrono", "dlc-manager", diff --git a/Cargo.toml b/Cargo.toml index 33e99e92a..cb1838190 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,11 +19,11 @@ resolver = "2" # We are using our own fork of `rust-dlc` at least until we can drop all the LN-DLC features. Also, # `p2pderivatives/rust-dlc#master` is missing certain patches that can only be found in the LN-DLC # branch. -dlc-manager = { git = "https://github.com/get10101/rust-dlc", rev = "8d9920d" } -dlc-messages = { git = "https://github.com/get10101/rust-dlc", rev = "8d9920d" } -dlc = { git = "https://github.com/get10101/rust-dlc", rev = "8d9920d" } -p2pd-oracle-client = { git = "https://github.com/get10101/rust-dlc", rev = "8d9920d" } -dlc-trie = { git = "https://github.com/get10101/rust-dlc", rev = "8d9920d" } +dlc-manager = { git = "https://github.com/get10101/rust-dlc", rev = "2545d6e" } +dlc-messages = { git = "https://github.com/get10101/rust-dlc", rev = "2545d6e" } +dlc = { git = "https://github.com/get10101/rust-dlc", rev = "2545d6e" } +p2pd-oracle-client = { git = "https://github.com/get10101/rust-dlc", rev = "2545d6e" } +dlc-trie = { git = "https://github.com/get10101/rust-dlc", rev = "2545d6e" } # We should usually track the `p2pderivatives/split-tx-experiment[-10101]` branch. For now we depend # on a special fork which removes a panic in `rust-lightning`. diff --git a/coordinator/src/trade/mod.rs b/coordinator/src/trade/mod.rs index 321052aae..321290c7f 100644 --- a/coordinator/src/trade/mod.rs +++ b/coordinator/src/trade/mod.rs @@ -58,6 +58,8 @@ pub mod websocket; enum TradeAction { OpenDlcChannel, + #[allow(dead_code)] + OpenSingleFundedChannel, OpenPosition { channel_id: DlcChannelId, own_payout: u64, @@ -98,6 +100,18 @@ pub struct TradeExecutor { notifier: mpsc::Sender, } +/// The funds the trader will need to provide to open a DLC channel with the coordinator. +/// +/// We can extend this enum with a `ForTradeCost` variant to denote that the trader has to pay for +/// everything except for transaction fees. +enum TraderRequiredLiquidity { + /// Pay for margin, collateral reserve, order-matching fees and transaction fees. + ForTradeCostAndTxFees, + /// Do not pay for anything. The trader has probably paid in a different way e.g. using + /// Lightning. + None, +} + impl TradeExecutor { pub fn new(node: Node, notifier: mpsc::Sender) -> Self { Self { node, notifier } @@ -212,6 +226,26 @@ impl TradeExecutor { collateral_reserve_coordinator, collateral_reserve_trader, is_stable_order, + TraderRequiredLiquidity::ForTradeCostAndTxFees, + ) + .await + .context("Failed to open DLC channel")?; + } + TradeAction::OpenSingleFundedChannel => { + let collateral_reserve_coordinator = params + .coordinator_reserve + .context("Missing coordinator collateral reserve")?; + let collateral_reserve_trader = params + .trader_reserve + .context("Missing trader collateral reserve")?; + + self.open_dlc_channel( + &mut connection, + ¶ms.trade_params, + collateral_reserve_coordinator, + collateral_reserve_trader, + is_stable_order, + TraderRequiredLiquidity::None, ) .await .context("Failed to open DLC channel")?; @@ -270,6 +304,7 @@ impl TradeExecutor { collateral_reserve_coordinator: Amount, collateral_reserve_trader: Amount, stable: bool, + trader_required_utxos: TraderRequiredLiquidity, ) -> Result<()> { let peer_id = trade_params.pubkey; @@ -337,11 +372,29 @@ impl TradeExecutor { // coordinator. let event_id = format!("{contract_symbol}{maturity_time}"); + let (offer_collateral, accept_collateral, fee_config) = match trader_required_utxos { + TraderRequiredLiquidity::ForTradeCostAndTxFees => ( + margin_coordinator + collateral_reserve_coordinator.to_sat(), + margin_trader + collateral_reserve_trader + order_matching_fee, + dlc::FeeConfig::EvenSplit, + ), + TraderRequiredLiquidity::None => ( + margin_coordinator + + collateral_reserve_coordinator.to_sat() + + margin_trader + + collateral_reserve_trader + // If the trader doesn't bring their own UTXOs, including the order matching fee + // is not strictly necessary, but it's simpler to do so. + + order_matching_fee, + 0, + dlc::FeeConfig::AllOffer, + ), + }; + let contract_input = ContractInput { - offer_collateral: margin_coordinator + collateral_reserve_coordinator.to_sat(), - // The accept party has do bring additional collateral to pay for the - // `order_matching_fee`. - accept_collateral: margin_trader + collateral_reserve_trader + order_matching_fee, + offer_collateral, + + accept_collateral, fee_rate, contract_infos: vec![ContractInputInfo { contract_descriptor, @@ -370,6 +423,7 @@ impl TradeExecutor { contract_input, trade_params.pubkey, protocol_id, + fee_config, ) .await .context("Could not propose DLC channel")?; diff --git a/crates/tests-e2e/src/setup.rs b/crates/tests-e2e/src/setup.rs index 5dad5dca9..f1f3dea10 100644 --- a/crates/tests-e2e/src/setup.rs +++ b/crates/tests-e2e/src/setup.rs @@ -157,7 +157,17 @@ impl TestSetup { // Wait for coordinator to open position. tokio::time::sleep(std::time::Duration::from_secs(10)).await; - setup.bitcoind.mine(NB_CONFIRMATIONS as u16).await.unwrap(); + if NB_CONFIRMATIONS == 0 { + // No confirmations are required to get the channel/contract `Confirmed`, but the change + // output won't be added to the on-chain balance until we get one confirmation because + // of https://github.com/get10101/10101/issues/2286. + // + // We need to know about funding transaction change outputs so that we can accurately + // assert on on-chain balance changes after DLC channels are closed on-chain. + setup.bitcoind.mine(1).await.unwrap(); + } else { + setup.bitcoind.mine(NB_CONFIRMATIONS as u16).await.unwrap(); + } tokio::time::sleep(std::time::Duration::from_secs(10)).await; diff --git a/crates/xxi-node/src/dlc_wallet.rs b/crates/xxi-node/src/dlc_wallet.rs index 9634e6467..1b235b859 100644 --- a/crates/xxi-node/src/dlc_wallet.rs +++ b/crates/xxi-node/src/dlc_wallet.rs @@ -213,6 +213,10 @@ impl dlc_manager::Wallet for DlcWallet Result, dlc_manager::error::Error> { + if amount == 0 { + return Ok(Vec::new()); + } + let network = self.on_chain_wallet.network(); let fee_rate = fee_rate.expect("always set by rust-dlc"); diff --git a/crates/xxi-node/src/node/dlc_channel.rs b/crates/xxi-node/src/node/dlc_channel.rs index 87951c3d8..5e6a89817 100644 --- a/crates/xxi-node/src/node/dlc_channel.rs +++ b/crates/xxi-node/src/node/dlc_channel.rs @@ -47,6 +47,7 @@ impl Result<(ContractId, DlcChannelId)> { tracing::info!( trader_id = %counterparty, @@ -90,6 +91,7 @@ impl {