Skip to content

Commit

Permalink
Merge pull request #136 from TheBlueMatt/main
Browse files Browse the repository at this point in the history
Upgrade to LDK 0.0.125
  • Loading branch information
tnull authored Oct 28, 2024
2 parents eb7ba30 + 7ca1088 commit 3676248
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 220 deletions.
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

0 comments on commit 3676248

Please sign in to comment.