Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to LDK 0.0.125 #136

Merged
merged 5 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lightning = { version = "0.0.123", features = ["max_level_trace"] }
lightning-block-sync = { version = "0.0.123", features = [ "rpc-client", "tokio" ] }
lightning-invoice = { version = "0.31.0" }
lightning-net-tokio = { version = "0.0.123" }
lightning-persister = { version = "0.0.123" }
lightning-background-processor = { version = "0.0.123", features = [ "futures" ] }
lightning-rapid-gossip-sync = { version = "0.0.123" }
lightning = { version = "0.0.125", features = ["max_level_trace"] }
lightning-block-sync = { version = "0.0.125", features = [ "rpc-client", "tokio" ] }
lightning-invoice = { version = "0.32.0" }
lightning-net-tokio = { version = "0.0.125" }
lightning-persister = { version = "0.0.125" }
lightning-background-processor = { version = "0.0.125", features = [ "futures" ] }
lightning-rapid-gossip-sync = { version = "0.0.125" }

base64 = "0.13.0"
bitcoin = "0.30.2"
bitcoin = "0.32"
bitcoin-bech32 = "0.12"
bech32 = "0.8"
libc = "0.2"
Expand Down
2 changes: 1 addition & 1 deletion src/args.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cli::LdkUserInfo;
use bitcoin::network::constants::Network;
use bitcoin::network::Network;
use lightning::ln::msgs::SocketAddress;
use std::collections::HashMap;
use std::env;
Expand Down
117 changes: 77 additions & 40 deletions src/bitcoind_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ use crate::convert::{
use crate::disk::FilesystemLogger;
use crate::hex_utils;
use base64;
use bitcoin::address::{Address, Payload, WitnessVersion};
use bitcoin::address::Address;
use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
use bitcoin::blockdata::script::ScriptBuf;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::consensus::{encode, Decodable, Encodable};
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::Hash;
use bitcoin::key::XOnlyPublicKey;
use bitcoin::psbt::PartiallySignedTransaction;
use bitcoin::psbt::Psbt;
use bitcoin::{Network, OutPoint, TxOut, WPubkeyHash};
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
use lightning::events::bump_transaction::{Utxo, WalletSource};
Expand Down Expand Up @@ -80,7 +80,8 @@ impl BitcoindClient {
"Failed to make initial call to bitcoind - please check your RPC user/password and access settings")
})?;
let mut fees: HashMap<ConfirmationTarget, AtomicU32> = HashMap::new();
fees.insert(ConfirmationTarget::OnChainSweep, AtomicU32::new(5000));
fees.insert(ConfirmationTarget::MaximumFeeEstimate, AtomicU32::new(50000));
fees.insert(ConfirmationTarget::UrgentOnChainSweep, AtomicU32::new(5000));
fees.insert(
ConfirmationTarget::MinAllowedAnchorChannelRemoteFee,
AtomicU32::new(MIN_FEERATE),
Expand All @@ -92,6 +93,7 @@ impl BitcoindClient {
fees.insert(ConfirmationTarget::AnchorChannelFee, AtomicU32::new(MIN_FEERATE));
fees.insert(ConfirmationTarget::NonAnchorChannelFee, AtomicU32::new(2000));
fees.insert(ConfirmationTarget::ChannelCloseMinimum, AtomicU32::new(MIN_FEERATE));
fees.insert(ConfirmationTarget::OutputSpendingFee, AtomicU32::new(MIN_FEERATE));

let client = Self {
bitcoind_rpc_client: Arc::new(bitcoind_rpc_client),
Expand Down Expand Up @@ -177,7 +179,27 @@ impl BitcoindClient {
}
};

fees.get(&ConfirmationTarget::OnChainSweep)
let very_high_prio_estimate = {
let high_prio_conf_target = serde_json::json!(2);
let high_prio_estimate_mode = serde_json::json!("CONSERVATIVE");
let resp = rpc_client
.call_method::<FeeResponse>(
"estimatesmartfee",
&vec![high_prio_conf_target, high_prio_estimate_mode],
)
.await
.unwrap();

match resp.feerate_sat_per_kw {
Some(feerate) => std::cmp::max(feerate, MIN_FEERATE),
None => 50000,
}
};

fees.get(&ConfirmationTarget::MaximumFeeEstimate)
.unwrap()
.store(very_high_prio_estimate, Ordering::Release);
fees.get(&ConfirmationTarget::UrgentOnChainSweep)
.unwrap()
.store(high_prio_estimate, Ordering::Release);
fees.get(&ConfirmationTarget::MinAllowedAnchorChannelRemoteFee)
Expand All @@ -195,6 +217,9 @@ impl BitcoindClient {
fees.get(&ConfirmationTarget::ChannelCloseMinimum)
.unwrap()
.store(background_estimate, Ordering::Release);
fees.get(&ConfirmationTarget::OutputSpendingFee)
.unwrap()
.store(background_estimate, Ordering::Release);

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

impl BroadcasterInterface for BitcoindClient {
fn broadcast_transactions(&self, txs: &[&Transaction]) {
// TODO: Rather than calling `sendrawtransaction` in a a loop, we should probably use
// `submitpackage` once it becomes available.
for tx in txs {
let bitcoind_rpc_client = Arc::clone(&self.bitcoind_rpc_client);
let tx_serialized = encode::serialize_hex(tx);
let tx_json = serde_json::json!(tx_serialized);
let logger = Arc::clone(&self.logger);
self.handle.spawn(async move {
// This may error due to RL calling `broadcast_transactions` with the same transaction
// multiple times, but the error is safe to ignore.
match bitcoind_rpc_client
.call_method::<Txid>("sendrawtransaction", &vec![tx_json])
// As of Bitcoin Core 28, using `submitpackage` allows us to broadcast multiple
// transactions at once and have them propagate through the network as a whole, avoiding
// some pitfalls with anchor channels where the first transaction doesn't make it into the
// mempool at all. Several older versions of Bitcoin Core also support `submitpackage`,
// however, so we just use it unconditionally here.
// Sadly, Bitcoin Core has an arbitrary restriction on `submitpackage` - it must actually
// contain a package (see https://github.com/bitcoin/bitcoin/issues/31085).
let txn = txs.iter().map(|tx| encode::serialize_hex(tx)).collect::<Vec<_>>();
let bitcoind_rpc_client = Arc::clone(&self.bitcoind_rpc_client);
let logger = Arc::clone(&self.logger);
self.handle.spawn(async move {
let res = if txn.len() == 1 {
let tx_json = serde_json::json!(txn[0]);
bitcoind_rpc_client
.call_method::<serde_json::Value>("sendrawtransaction", &[tx_json])
.await
{
Ok(_) => {}
Err(e) => {
let err_str = e.get_ref().unwrap().to_string();
log_error!(logger,
"Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\nTransaction: {}",
err_str,
tx_serialized);
print!("Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\n> ", err_str);
}
}
});
}
} else {
let tx_json = serde_json::json!(txn);
bitcoind_rpc_client
.call_method::<serde_json::Value>("submitpackage", &[tx_json])
.await
};
// This may error due to RL calling `broadcast_transactions` with the same transaction
// multiple times, but the error is safe to ignore.
match res {
Ok(_) => {}
Err(e) => {
let err_str = e.get_ref().unwrap().to_string();
log_error!(logger,
"Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\nTransactions: {:?}",
err_str,
txn);
print!("Warning, failed to broadcast a transaction, this is likely okay but may indicate an error: {}\n> ", err_str);
}
}
});
}
}

Expand All @@ -335,24 +370,26 @@ impl WalletSource for BitcoindClient {
.into_iter()
.filter_map(|utxo| {
let outpoint = OutPoint { txid: utxo.txid, vout: utxo.vout };
match utxo.address.payload.clone() {
Payload::WitnessProgram(wp) => match wp.version() {
WitnessVersion::V0 => WPubkeyHash::from_slice(wp.program().as_bytes())
.map(|wpkh| Utxo::new_v0_p2wpkh(outpoint, utxo.amount, &wpkh))
.ok(),
let value = bitcoin::Amount::from_sat(utxo.amount);
match utxo.address.witness_program() {
Some(prog) if prog.is_p2wpkh() => {
WPubkeyHash::from_slice(prog.program().as_bytes())
.map(|wpkh| Utxo::new_v0_p2wpkh(outpoint, value, &wpkh))
.ok()
},
Some(prog) if prog.is_p2tr() => {
// TODO: Add `Utxo::new_v1_p2tr` upstream.
WitnessVersion::V1 => XOnlyPublicKey::from_slice(wp.program().as_bytes())
XOnlyPublicKey::from_slice(prog.program().as_bytes())
.map(|_| Utxo {
outpoint,
output: TxOut {
value: utxo.amount,
script_pubkey: ScriptBuf::new_witness_program(&wp),
value,
script_pubkey: utxo.address.script_pubkey(),
},
satisfaction_weight: 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64 +
1 /* witness items */ + 1 /* schnorr sig len */ + 64, /* schnorr sig */
})
.ok(),
_ => None,
.ok()
},
_ => None,
}
Expand All @@ -366,7 +403,7 @@ impl WalletSource for BitcoindClient {
})
}

fn sign_psbt(&self, tx: PartiallySignedTransaction) -> Result<Transaction, ()> {
fn sign_psbt(&self, tx: Psbt) -> Result<Transaction, ()> {
let mut tx_bytes = Vec::new();
let _ = tx.unsigned_tx.consensus_encode(&mut tx_bytes).map_err(|_| ());
let tx_hex = hex_utils::hex_str(&tx_bytes);
Expand Down
Loading
Loading