Skip to content

Commit

Permalink
Upgrade to a customized version of LDK v120
Browse files Browse the repository at this point in the history
We upgrade to LDK v120 because we need the new blinded route features within.
On top of that we add the changes in a small PR we submitted, which we need in
order to send an onion message across along a specified path for LNDK's
integration tests: lightningdevkit/rust-lightning#2868
  • Loading branch information
orbitalturtle committed Feb 2, 2024
1 parent 1624431 commit afb1547
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 164 deletions.
287 changes: 199 additions & 88 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 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 = { git = "https://github.com/orbitalturtle/rust-lightning", branch = "v0.0.118-custom", features = ["max_level_trace"] }
lightning-block-sync = { git = "https://github.com/orbitalturtle/rust-lightning", branch = "v0.0.118-custom", features = [ "rpc-client", "tokio" ] }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "06f9dd7", features = ["max_level_trace", "_test_utils"] }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "06f9dd7", features = [ "rpc-client", "tokio" ] }
lightning-invoice = { version = "0.25.0" }
lightning-net-tokio = { git = "https://github.com/orbitalturtle/rust-lightning", branch = "v0.0.118-custom" }
lightning-persister = { git = "https://github.com/orbitalturtle/rust-lightning", branch = "v0.0.118-custom" }
lightning-background-processor = { git = "https://github.com/orbitalturtle/rust-lightning", branch = "v0.0.118-custom", features = [ "futures" ] }
lightning-rapid-gossip-sync = { git = "https://github.com/orbitalturtle/rust-lightning", branch = "v0.0.118-custom" }
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "06f9dd7" }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "06f9dd7" }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "06f9dd7", features = [ "futures" ] }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "06f9dd7" }

base64 = "0.13.0"
bitcoin = "0.29.0"
bitcoin = "0.30.2"
bitcoin-bech32 = "0.12"
bech32 = "0.8"
libc = "0.2"
Expand Down
73 changes: 43 additions & 30 deletions src/bitcoind_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ use crate::convert::{
use crate::disk::FilesystemLogger;
use crate::hex_utils;
use base64;
use bitcoin::address::{Address, Payload, WitnessVersion};
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::util::address::{Address, Payload, WitnessVersion};
use bitcoin::{OutPoint, Script, TxOut, WPubkeyHash, XOnlyPublicKey};
use bitcoin::key::XOnlyPublicKey;
use bitcoin::psbt::PartiallySignedTransaction;
use bitcoin::{Network, OutPoint, TxOut, WPubkeyHash};
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
use lightning::events::bump_transaction::{Utxo, WalletSource};
use lightning::log_error;
Expand All @@ -28,6 +31,7 @@ use std::time::Duration;

pub struct BitcoindClient {
pub(crate) bitcoind_rpc_client: Arc<RpcClient>,
network: Network,
host: String,
port: u16,
rpc_user: String,
Expand Down Expand Up @@ -60,7 +64,7 @@ const MIN_FEERATE: u32 = 253;

impl BitcoindClient {
pub(crate) async fn new(
host: String, port: u16, rpc_user: String, rpc_password: String,
host: String, port: u16, rpc_user: String, rpc_password: String, network: Network,
handle: tokio::runtime::Handle, logger: Arc<FilesystemLogger>,
) -> std::io::Result<Self> {
let http_endpoint = HttpEndpoint::for_host(host.clone()).with_port(port);
Expand All @@ -76,10 +80,6 @@ impl BitcoindClient {
})?;
let mut fees: HashMap<ConfirmationTarget, AtomicU32> = HashMap::new();
fees.insert(ConfirmationTarget::OnChainSweep, AtomicU32::new(5000));
fees.insert(
ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee,
AtomicU32::new(25 * 250),
);
fees.insert(
ConfirmationTarget::MinAllowedAnchorChannelRemoteFee,
AtomicU32::new(MIN_FEERATE),
Expand All @@ -98,6 +98,7 @@ impl BitcoindClient {
port,
rpc_user,
rpc_password,
network,
fees: Arc::new(fees),
handle: handle.clone(),
logger,
Expand Down Expand Up @@ -178,9 +179,6 @@ impl BitcoindClient {
fees.get(&ConfirmationTarget::OnChainSweep)
.unwrap()
.store(high_prio_estimate, Ordering::Release);
fees.get(&ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee)
.unwrap()
.store(std::cmp::max(25 * 250, high_prio_estimate * 10), Ordering::Release);
fees.get(&ConfirmationTarget::MinAllowedAnchorChannelRemoteFee)
.unwrap()
.store(mempoolmin_estimate, Ordering::Release);
Expand Down Expand Up @@ -264,7 +262,7 @@ impl BitcoindClient {
.call_method::<NewAddress>("getnewaddress", &addr_args)
.await
.unwrap();
Address::from_str(addr.0.as_str()).unwrap()
Address::from_str(addr.0.as_str()).unwrap().require_network(self.network).unwrap()
}

pub async fn get_blockchain_info(&self) -> BlockchainInfo {
Expand Down Expand Up @@ -328,23 +326,38 @@ impl WalletSource for BitcoindClient {
.into_iter()
.filter_map(|utxo| {
let outpoint = OutPoint { txid: utxo.txid, vout: utxo.vout };
match utxo.address.payload {
Payload::WitnessProgram { version, ref program } => match version {
WitnessVersion::V0 => WPubkeyHash::from_slice(program)
.map(|wpkh| Utxo::new_v0_p2wpkh(outpoint, utxo.amount, &wpkh))
.ok(),
match utxo.address.payload.clone() {
Payload::WitnessProgram(wp) => match wp.version() {
WitnessVersion::V0 => {
bitcoin::hashes::hash160::Hash::from_slice(wp.program().as_bytes())
.map(|hash| {
Utxo::new_v0_p2wpkh(
outpoint,
utxo.amount,
&WPubkeyHash::from_raw_hash(hash),
)
})
.ok()
}
// TODO: Add `Utxo::new_v1_p2tr` upstream.
WitnessVersion::V1 => XOnlyPublicKey::from_slice(program)
.map(|_| Utxo {
outpoint,
output: TxOut {
value: utxo.amount,
script_pubkey: Script::new_witness_program(version, program),
},
satisfaction_weight: 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64 +
1 /* witness items */ + 1 /* schnorr sig len */ + 64, /* schnorr sig */
})
.ok(),
WitnessVersion::V1 => {
bitcoin::hashes::hash160::Hash::from_slice(wp.program().as_bytes())
.map(|wp_hash| {
let _pubkey =
XOnlyPublicKey::from_slice(wp_hash.as_byte_array())
.expect("Invalid pubkey length");
Utxo {
outpoint,
output: TxOut {
value: utxo.amount,
script_pubkey: ScriptBuf::new_witness_program(&wp),
},
satisfaction_weight: 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64 +
1 /* witness items */ + 1 /* schnorr sig len */ + 64, /* schnorr sig */
}
})
.ok()
}
_ => None,
},
_ => None,
Expand All @@ -353,15 +366,15 @@ impl WalletSource for BitcoindClient {
.collect())
}

fn get_change_script(&self) -> Result<Script, ()> {
fn get_change_script(&self) -> Result<ScriptBuf, ()> {
tokio::task::block_in_place(move || {
Ok(self.handle.block_on(async move { self.get_new_address().await.script_pubkey() }))
})
}

fn sign_tx(&self, tx: Transaction) -> Result<Transaction, ()> {
fn sign_psbt(&self, tx: PartiallySignedTransaction) -> Result<Transaction, ()> {
let mut tx_bytes = Vec::new();
let _ = tx.consensus_encode(&mut tx_bytes).map_err(|_| ());
let _ = tx.unsigned_tx.consensus_encode(&mut tx_bytes).map_err(|_| ());
let tx_hex = hex_utils::hex_str(&tx_bytes);
let signed_tx = tokio::task::block_in_place(move || {
self.handle.block_on(async move { self.sign_raw_transaction_with_wallet(tx_hex).await })
Expand Down
29 changes: 21 additions & 8 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use lightning::sign::{EntropySource, KeysManager};
use lightning::util::config::{ChannelHandshakeConfig, ChannelHandshakeLimits, UserConfig};
use lightning::util::persist::KVStore;
use lightning::util::ser::{Writeable, Writer};
use lightning_invoice::payment::pay_invoice;
use lightning_invoice::{utils, Bolt11Invoice, Currency};
use lightning_persister::fs_store::FilesystemStore;
use std::env;
Expand All @@ -43,6 +42,7 @@ pub(crate) struct LdkUserInfo {
pub(crate) network: Network,
}

#[derive(Debug)]
struct UserOnionMessageContents {
tlv_type: u64,
data: Vec<u8>,
Expand Down Expand Up @@ -672,7 +672,7 @@ fn open_channel(
..Default::default()
};

match channel_manager.create_channel(peer_pubkey, channel_amt_sat, 0, 0, Some(config)) {
match channel_manager.create_channel(peer_pubkey, channel_amt_sat, 0, 0, None, Some(config)) {
Ok(_) => {
println!("EVENT: initiated channel with peer {}. ", peer_pubkey);
return Ok(());
Expand All @@ -688,7 +688,8 @@ fn send_payment(
channel_manager: &ChannelManager, invoice: &Bolt11Invoice,
outbound_payments: &mut OutboundPaymentInfoStorage, fs_store: Arc<FilesystemStore>,
) {
let payment_id = PaymentId((*invoice.payment_hash()).into_inner());
let payment_id = PaymentId((*invoice.payment_hash()).to_byte_array());
let payment_hash = PaymentHash((*invoice.payment_hash()).to_byte_array());
let payment_secret = Some(*invoice.payment_secret());
outbound_payments.payments.insert(
payment_id,
Expand All @@ -700,8 +701,20 @@ fn send_payment(
},
);
fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound_payments.encode()).unwrap();
match pay_invoice(invoice, Retry::Timeout(Duration::from_secs(10)), channel_manager) {
Ok(_payment_id) => {

let mut recipient_onion = RecipientOnionFields::secret_only(*invoice.payment_secret());
recipient_onion.payment_metadata = invoice.payment_metadata().map(|v| v.clone());
let mut payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(),
invoice.min_final_cltv_expiry_delta() as u32)
.with_expiry_time(invoice.duration_since_epoch().as_secs() + invoice.expiry_time().as_secs())
.with_route_hints(invoice.route_hints()).unwrap();
if let Some(features) = invoice.features() {
payment_params = payment_params.with_bolt11_features(features.clone()).unwrap();
}
let route_params = RouteParameters::from_payment_params_and_value(payment_params, invoice.amount_milli_satoshis().unwrap_or_default());

match channel_manager.send_payment(payment_hash, recipient_onion, payment_id, route_params, Retry::Timeout(Duration::from_secs(10))) {
Ok(_) => {
let payee_pubkey = invoice.recover_payee_pub_key();
let amt_msat = invoice.amount_milli_satoshis().unwrap();
println!("EVENT: initiated sending {} msats to {}", amt_msat, payee_pubkey);
Expand All @@ -721,7 +734,7 @@ fn keysend<E: EntropySource>(
outbound_payments: &mut OutboundPaymentInfoStorage, fs_store: Arc<FilesystemStore>,
) {
let payment_preimage = PaymentPreimage(entropy_source.get_secure_random_bytes());
let payment_id = PaymentId(Sha256::hash(&payment_preimage.0[..]).into_inner());
let payment_id = PaymentId(Sha256::hash(&payment_preimage.0[..]).to_byte_array());

let route_params = RouteParameters::from_payment_params_and_value(
PaymentParameters::for_keysend(payee_pubkey, 40, false),
Expand Down Expand Up @@ -764,9 +777,9 @@ fn get_invoice(
) {
let currency = match network {
Network::Bitcoin => Currency::Bitcoin,
Network::Testnet => Currency::BitcoinTestnet,
Network::Regtest => Currency::Regtest,
Network::Signet => Currency::Signet,
Network::Testnet | _ => Currency::BitcoinTestnet,
};
let invoice = match utils::create_invoice_from_channelmanager(
channel_manager,
Expand All @@ -788,7 +801,7 @@ fn get_invoice(
}
};

let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
inbound_payments.payments.insert(
payment_hash,
PaymentInfo {
Expand Down
6 changes: 3 additions & 3 deletions src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bitcoin::hashes::hex::FromHex;
use bitcoin::address::NetworkUnchecked;
use bitcoin::{Address, BlockHash, Txid};
use lightning_block_sync::http::JsonResponse;
use std::convert::TryInto;
Expand Down Expand Up @@ -111,7 +111,7 @@ impl TryInto<BlockchainInfo> for JsonResponse {
fn try_into(self) -> std::io::Result<BlockchainInfo> {
Ok(BlockchainInfo {
latest_height: self.0["blocks"].as_u64().unwrap() as usize,
latest_blockhash: BlockHash::from_hex(self.0["bestblockhash"].as_str().unwrap())
latest_blockhash: BlockHash::from_str(self.0["bestblockhash"].as_str().unwrap())
.unwrap(),
chain: self.0["chain"].as_str().unwrap().to_string(),
})
Expand All @@ -122,7 +122,7 @@ pub struct ListUnspentUtxo {
pub txid: Txid,
pub vout: u32,
pub amount: u64,
pub address: Address,
pub address: Address<NetworkUnchecked>,
}

pub struct ListUnspentResponse(pub Vec<ListUnspentUtxo>);
Expand Down
2 changes: 1 addition & 1 deletion src/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl FilesystemLogger {
}
}
impl Logger for FilesystemLogger {
fn log(&self, record: &Record) {
fn log(&self, record: Record) {
if record.level < self.level {
return;
}
Expand Down
Loading

0 comments on commit afb1547

Please sign in to comment.