Skip to content

Commit a49bdcf

Browse files
committed
Insert channel funding utxo before a splice
We insert a channel's funding utxo into our wallet so we can later calculate the fees for the transaction, otherwise our wallet would have incomplete information. We do it before the splice as we only really need this information for splices and not for all channels.
1 parent 31c12f9 commit a49bdcf

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,10 @@ impl Node {
13031303
Error::ChannelSplicingFailed
13041304
})?;
13051305

1306+
// insert channel's funding utxo into the wallet so we can later calculate fees
1307+
// correctly when viewing this splice-in.
1308+
self.wallet.insert_txo(funding_txo.into_bitcoin_outpoint(), funding_output)?;
1309+
13061310
let change_address = self.wallet.get_new_internal_address()?;
13071311

13081312
let contribution = SpliceContribution::SpliceIn {
@@ -1398,6 +1402,18 @@ impl Node {
13981402
},
13991403
};
14001404

1405+
let funding_txo = channel_details.funding_txo.ok_or_else(|| {
1406+
log_error!(self.logger, "Failed to splice channel: channel not yet ready",);
1407+
Error::ChannelSplicingFailed
1408+
})?;
1409+
1410+
let funding_output = channel_details.get_funding_output().ok_or_else(|| {
1411+
log_error!(self.logger, "Failed to splice channel: channel not yet ready");
1412+
Error::ChannelSplicingFailed
1413+
})?;
1414+
1415+
self.wallet.insert_txo(funding_txo.into_bitcoin_outpoint(), funding_output)?;
1416+
14011417
self.channel_manager
14021418
.splice_channel(
14031419
&channel_details.channel_id,

src/wallet/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
2626
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
2727
use bitcoin::secp256k1::{All, PublicKey, Scalar, Secp256k1, SecretKey};
2828
use bitcoin::{
29-
Address, Amount, FeeRate, ScriptBuf, Transaction, TxOut, Txid, WPubkeyHash, Weight,
29+
Address, Amount, FeeRate, OutPoint, ScriptBuf, Transaction, TxOut, Txid, WPubkeyHash, Weight,
3030
WitnessProgram, WitnessVersion,
3131
};
3232
use lightning::chain::chaininterface::BroadcasterInterface;
@@ -153,6 +153,19 @@ impl Wallet {
153153
Ok(())
154154
}
155155

156+
pub(crate) fn insert_txo(&self, outpoint: OutPoint, txout: TxOut) -> Result<(), Error> {
157+
let mut locked_wallet = self.inner.lock().unwrap();
158+
locked_wallet.insert_txout(outpoint, txout);
159+
160+
let mut locked_persister = self.persister.lock().unwrap();
161+
locked_wallet.persist(&mut locked_persister).map_err(|e| {
162+
log_error!(self.logger, "Failed to persist wallet: {}", e);
163+
Error::PersistenceFailed
164+
})?;
165+
166+
Ok(())
167+
}
168+
156169
fn update_payment_store<'a>(
157170
&self, locked_wallet: &'a mut PersistedWallet<KVStoreWalletPersister>,
158171
) -> Result<(), Error> {

tests/integration_tests_rust.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -927,10 +927,13 @@ async fn concurrent_connections_succeed() {
927927
}
928928
}
929929

930-
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
931-
async fn splice_channel() {
930+
async fn run_splice_channel_test(bitcoind_chain_source: bool) {
932931
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
933-
let chain_source = TestChainSource::Esplora(&electrsd);
932+
let chain_source = if bitcoind_chain_source {
933+
TestChainSource::BitcoindRpcSync(&bitcoind)
934+
} else {
935+
TestChainSource::Esplora(&electrsd)
936+
};
934937
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, false);
935938

936939
let address_a = node_a.onchain_payment().new_address().unwrap();
@@ -995,7 +998,7 @@ async fn splice_channel() {
995998
// Splice-in funds for Node B so that it has outbound liquidity to make a payment
996999
node_b.splice_in(&user_channel_id_b, node_a.node_id(), 4_000_000).unwrap();
9971000

998-
expect_splice_pending_event!(node_a, node_b.node_id());
1001+
let txo = expect_splice_pending_event!(node_a, node_b.node_id());
9991002
expect_splice_pending_event!(node_b, node_a.node_id());
10001003

10011004
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await;
@@ -1006,11 +1009,16 @@ async fn splice_channel() {
10061009
expect_channel_ready_event!(node_a, node_b.node_id());
10071010
expect_channel_ready_event!(node_b, node_a.node_id());
10081011

1009-
let splice_in_fee_sat = 252;
1012+
let expected_splice_in_fee_sat = 252;
1013+
1014+
let payments = node_b.list_payments();
1015+
let payment =
1016+
payments.into_iter().find(|p| p.id == PaymentId(txo.txid.to_byte_array())).unwrap();
1017+
assert_eq!(payment.fee_paid_msat, Some(expected_splice_in_fee_sat * 1_000));
10101018

10111019
assert_eq!(
10121020
node_b.list_balances().total_onchain_balance_sats,
1013-
premine_amount_sat - 4_000_000 - splice_in_fee_sat
1021+
premine_amount_sat - 4_000_000 - expected_splice_in_fee_sat
10141022
);
10151023
assert_eq!(node_b.list_balances().total_lightning_balance_sats, 4_000_000);
10161024

@@ -1033,7 +1041,7 @@ async fn splice_channel() {
10331041
let address = node_a.onchain_payment().new_address().unwrap();
10341042
node_a.splice_out(&user_channel_id_a, node_b.node_id(), &address, amount_msat / 1000).unwrap();
10351043

1036-
expect_splice_pending_event!(node_a, node_b.node_id());
1044+
let txo = expect_splice_pending_event!(node_a, node_b.node_id());
10371045
expect_splice_pending_event!(node_b, node_a.node_id());
10381046

10391047
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await;
@@ -1044,18 +1052,29 @@ async fn splice_channel() {
10441052
expect_channel_ready_event!(node_a, node_b.node_id());
10451053
expect_channel_ready_event!(node_b, node_a.node_id());
10461054

1047-
let splice_out_fee_sat = 183;
1055+
let expected_splice_out_fee_sat = 183;
1056+
1057+
let payments = node_a.list_payments();
1058+
let payment =
1059+
payments.into_iter().find(|p| p.id == PaymentId(txo.txid.to_byte_array())).unwrap();
1060+
assert_eq!(payment.fee_paid_msat, Some(expected_splice_out_fee_sat * 1_000));
10481061

10491062
assert_eq!(
10501063
node_a.list_balances().total_onchain_balance_sats,
10511064
premine_amount_sat - 4_000_000 - opening_transaction_fee_sat + amount_msat / 1000
10521065
);
10531066
assert_eq!(
10541067
node_a.list_balances().total_lightning_balance_sats,
1055-
4_000_000 - closing_transaction_fee_sat - anchor_output_sat - splice_out_fee_sat
1068+
4_000_000 - closing_transaction_fee_sat - anchor_output_sat - expected_splice_out_fee_sat
10561069
);
10571070
}
10581071

1072+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
1073+
async fn splice_channel() {
1074+
run_splice_channel_test(false).await;
1075+
run_splice_channel_test(true).await;
1076+
}
1077+
10591078
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
10601079
async fn simple_bolt12_send_receive() {
10611080
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();

0 commit comments

Comments
 (0)