Skip to content

Commit 3676248

Browse files
authored
Merge pull request #136 from TheBlueMatt/main
Upgrade to LDK 0.0.125
2 parents eb7ba30 + 7ca1088 commit 3676248

File tree

7 files changed

+218
-220
lines changed

7 files changed

+218
-220
lines changed

Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ edition = "2018"
88
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
99

1010
[dependencies]
11-
lightning = { version = "0.0.123", features = ["max_level_trace"] }
12-
lightning-block-sync = { version = "0.0.123", features = [ "rpc-client", "tokio" ] }
13-
lightning-invoice = { version = "0.31.0" }
14-
lightning-net-tokio = { version = "0.0.123" }
15-
lightning-persister = { version = "0.0.123" }
16-
lightning-background-processor = { version = "0.0.123", features = [ "futures" ] }
17-
lightning-rapid-gossip-sync = { version = "0.0.123" }
11+
lightning = { version = "0.0.125", features = ["max_level_trace"] }
12+
lightning-block-sync = { version = "0.0.125", features = [ "rpc-client", "tokio" ] }
13+
lightning-invoice = { version = "0.32.0" }
14+
lightning-net-tokio = { version = "0.0.125" }
15+
lightning-persister = { version = "0.0.125" }
16+
lightning-background-processor = { version = "0.0.125", features = [ "futures" ] }
17+
lightning-rapid-gossip-sync = { version = "0.0.125" }
1818

1919
base64 = "0.13.0"
20-
bitcoin = "0.30.2"
20+
bitcoin = "0.32"
2121
bitcoin-bech32 = "0.12"
2222
bech32 = "0.8"
2323
libc = "0.2"

src/args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cli::LdkUserInfo;
2-
use bitcoin::network::constants::Network;
2+
use bitcoin::network::Network;
33
use lightning::ln::msgs::SocketAddress;
44
use std::collections::HashMap;
55
use std::env;

src/bitcoind_client.rs

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ use crate::convert::{
55
use crate::disk::FilesystemLogger;
66
use crate::hex_utils;
77
use base64;
8-
use bitcoin::address::{Address, Payload, WitnessVersion};
8+
use bitcoin::address::Address;
99
use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
1010
use bitcoin::blockdata::script::ScriptBuf;
1111
use bitcoin::blockdata::transaction::Transaction;
1212
use bitcoin::consensus::{encode, Decodable, Encodable};
1313
use bitcoin::hash_types::{BlockHash, Txid};
1414
use bitcoin::hashes::Hash;
1515
use bitcoin::key::XOnlyPublicKey;
16-
use bitcoin::psbt::PartiallySignedTransaction;
16+
use bitcoin::psbt::Psbt;
1717
use bitcoin::{Network, OutPoint, TxOut, WPubkeyHash};
1818
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
1919
use lightning::events::bump_transaction::{Utxo, WalletSource};
@@ -80,7 +80,8 @@ impl BitcoindClient {
8080
"Failed to make initial call to bitcoind - please check your RPC user/password and access settings")
8181
})?;
8282
let mut fees: HashMap<ConfirmationTarget, AtomicU32> = HashMap::new();
83-
fees.insert(ConfirmationTarget::OnChainSweep, AtomicU32::new(5000));
83+
fees.insert(ConfirmationTarget::MaximumFeeEstimate, AtomicU32::new(50000));
84+
fees.insert(ConfirmationTarget::UrgentOnChainSweep, AtomicU32::new(5000));
8485
fees.insert(
8586
ConfirmationTarget::MinAllowedAnchorChannelRemoteFee,
8687
AtomicU32::new(MIN_FEERATE),
@@ -92,6 +93,7 @@ impl BitcoindClient {
9293
fees.insert(ConfirmationTarget::AnchorChannelFee, AtomicU32::new(MIN_FEERATE));
9394
fees.insert(ConfirmationTarget::NonAnchorChannelFee, AtomicU32::new(2000));
9495
fees.insert(ConfirmationTarget::ChannelCloseMinimum, AtomicU32::new(MIN_FEERATE));
96+
fees.insert(ConfirmationTarget::OutputSpendingFee, AtomicU32::new(MIN_FEERATE));
9597

9698
let client = Self {
9799
bitcoind_rpc_client: Arc::new(bitcoind_rpc_client),
@@ -177,7 +179,27 @@ impl BitcoindClient {
177179
}
178180
};
179181

180-
fees.get(&ConfirmationTarget::OnChainSweep)
182+
let very_high_prio_estimate = {
183+
let high_prio_conf_target = serde_json::json!(2);
184+
let high_prio_estimate_mode = serde_json::json!("CONSERVATIVE");
185+
let resp = rpc_client
186+
.call_method::<FeeResponse>(
187+
"estimatesmartfee",
188+
&vec![high_prio_conf_target, high_prio_estimate_mode],
189+
)
190+
.await
191+
.unwrap();
192+
193+
match resp.feerate_sat_per_kw {
194+
Some(feerate) => std::cmp::max(feerate, MIN_FEERATE),
195+
None => 50000,
196+
}
197+
};
198+
199+
fees.get(&ConfirmationTarget::MaximumFeeEstimate)
200+
.unwrap()
201+
.store(very_high_prio_estimate, Ordering::Release);
202+
fees.get(&ConfirmationTarget::UrgentOnChainSweep)
181203
.unwrap()
182204
.store(high_prio_estimate, Ordering::Release);
183205
fees.get(&ConfirmationTarget::MinAllowedAnchorChannelRemoteFee)
@@ -195,6 +217,9 @@ impl BitcoindClient {
195217
fees.get(&ConfirmationTarget::ChannelCloseMinimum)
196218
.unwrap()
197219
.store(background_estimate, Ordering::Release);
220+
fees.get(&ConfirmationTarget::OutputSpendingFee)
221+
.unwrap()
222+
.store(background_estimate, Ordering::Release);
198223

199224
tokio::time::sleep(Duration::from_secs(60)).await;
200225
}
@@ -289,32 +314,42 @@ impl FeeEstimator for BitcoindClient {
289314

290315
impl BroadcasterInterface for BitcoindClient {
291316
fn broadcast_transactions(&self, txs: &[&Transaction]) {
292-
// TODO: Rather than calling `sendrawtransaction` in a a loop, we should probably use
293-
// `submitpackage` once it becomes available.
294-
for tx in txs {
295-
let bitcoind_rpc_client = Arc::clone(&self.bitcoind_rpc_client);
296-
let tx_serialized = encode::serialize_hex(tx);
297-
let tx_json = serde_json::json!(tx_serialized);
298-
let logger = Arc::clone(&self.logger);
299-
self.handle.spawn(async move {
300-
// This may error due to RL calling `broadcast_transactions` with the same transaction
301-
// multiple times, but the error is safe to ignore.
302-
match bitcoind_rpc_client
303-
.call_method::<Txid>("sendrawtransaction", &vec![tx_json])
317+
// As of Bitcoin Core 28, using `submitpackage` allows us to broadcast multiple
318+
// transactions at once and have them propagate through the network as a whole, avoiding
319+
// some pitfalls with anchor channels where the first transaction doesn't make it into the
320+
// mempool at all. Several older versions of Bitcoin Core also support `submitpackage`,
321+
// however, so we just use it unconditionally here.
322+
// Sadly, Bitcoin Core has an arbitrary restriction on `submitpackage` - it must actually
323+
// contain a package (see https://github.com/bitcoin/bitcoin/issues/31085).
324+
let txn = txs.iter().map(|tx| encode::serialize_hex(tx)).collect::<Vec<_>>();
325+
let bitcoind_rpc_client = Arc::clone(&self.bitcoind_rpc_client);
326+
let logger = Arc::clone(&self.logger);
327+
self.handle.spawn(async move {
328+
let res = if txn.len() == 1 {
329+
let tx_json = serde_json::json!(txn[0]);
330+
bitcoind_rpc_client
331+
.call_method::<serde_json::Value>("sendrawtransaction", &[tx_json])
304332
.await
305-
{
306-
Ok(_) => {}
307-
Err(e) => {
308-
let err_str = e.get_ref().unwrap().to_string();
309-
log_error!(logger,
310-
"Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\nTransaction: {}",
311-
err_str,
312-
tx_serialized);
313-
print!("Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\n> ", err_str);
314-
}
315-
}
316-
});
317-
}
333+
} else {
334+
let tx_json = serde_json::json!(txn);
335+
bitcoind_rpc_client
336+
.call_method::<serde_json::Value>("submitpackage", &[tx_json])
337+
.await
338+
};
339+
// This may error due to RL calling `broadcast_transactions` with the same transaction
340+
// multiple times, but the error is safe to ignore.
341+
match res {
342+
Ok(_) => {}
343+
Err(e) => {
344+
let err_str = e.get_ref().unwrap().to_string();
345+
log_error!(logger,
346+
"Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\nTransactions: {:?}",
347+
err_str,
348+
txn);
349+
print!("Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\n> ", err_str);
350+
}
351+
}
352+
});
318353
}
319354
}
320355

@@ -335,24 +370,26 @@ impl WalletSource for BitcoindClient {
335370
.into_iter()
336371
.filter_map(|utxo| {
337372
let outpoint = OutPoint { txid: utxo.txid, vout: utxo.vout };
338-
match utxo.address.payload.clone() {
339-
Payload::WitnessProgram(wp) => match wp.version() {
340-
WitnessVersion::V0 => WPubkeyHash::from_slice(wp.program().as_bytes())
341-
.map(|wpkh| Utxo::new_v0_p2wpkh(outpoint, utxo.amount, &wpkh))
342-
.ok(),
373+
let value = bitcoin::Amount::from_sat(utxo.amount);
374+
match utxo.address.witness_program() {
375+
Some(prog) if prog.is_p2wpkh() => {
376+
WPubkeyHash::from_slice(prog.program().as_bytes())
377+
.map(|wpkh| Utxo::new_v0_p2wpkh(outpoint, value, &wpkh))
378+
.ok()
379+
},
380+
Some(prog) if prog.is_p2tr() => {
343381
// TODO: Add `Utxo::new_v1_p2tr` upstream.
344-
WitnessVersion::V1 => XOnlyPublicKey::from_slice(wp.program().as_bytes())
382+
XOnlyPublicKey::from_slice(prog.program().as_bytes())
345383
.map(|_| Utxo {
346384
outpoint,
347385
output: TxOut {
348-
value: utxo.amount,
349-
script_pubkey: ScriptBuf::new_witness_program(&wp),
386+
value,
387+
script_pubkey: utxo.address.script_pubkey(),
350388
},
351389
satisfaction_weight: 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64 +
352390
1 /* witness items */ + 1 /* schnorr sig len */ + 64, /* schnorr sig */
353391
})
354-
.ok(),
355-
_ => None,
392+
.ok()
356393
},
357394
_ => None,
358395
}
@@ -366,7 +403,7 @@ impl WalletSource for BitcoindClient {
366403
})
367404
}
368405

369-
fn sign_psbt(&self, tx: PartiallySignedTransaction) -> Result<Transaction, ()> {
406+
fn sign_psbt(&self, tx: Psbt) -> Result<Transaction, ()> {
370407
let mut tx_bytes = Vec::new();
371408
let _ = tx.unsigned_tx.consensus_encode(&mut tx_bytes).map_err(|_| ());
372409
let tx_hex = hex_utils::hex_str(&tx_bytes);

0 commit comments

Comments
 (0)