diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd9b9f63553..bb57c0b9506 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ jobs: include: - toolchain: stable build-net-tokio: true + check-fmt: true - toolchain: beta build-net-tokio: true - toolchain: 1.39.0 @@ -32,6 +33,9 @@ jobs: toolchain: ${{ matrix.toolchain }} override: true profile: minimal + - name: Check formatting + if: matrix.check-fmt + run: rustup component add rustfmt && cargo fmt --all -- --check && cd fuzz && cargo fmt --all -- --check - name: Build on Rust ${{ matrix.toolchain }} with net-tokio if: matrix.build-net-tokio run: RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always diff --git a/.travis.yml b/.travis.yml index 0c36806c63c..4408674aec9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,8 @@ before_install: - sudo apt-get install -y binutils-dev libunwind8-dev libcurl4-openssl-dev libelf-dev libdw-dev cmake gcc binutils-dev libiberty-dev script: + # Check formatting + - if [ "$(rustup show | grep stable)" != "" ]; then rustup component add rustfmt && cargo fmt --all -- --check && cd fuzz && cargo fmt --all -- --check && cd ../ ; fi # Support lightning-net-tokio only on Rust stable, beta, and 1.39.0 - if [ "$(rustup show | grep default | grep '1.39.0')" != "" ]; then export BUILD_NET_TOKIO=1; fi - if [ "$(rustup show | grep default | grep '1\.')" == "" ]; then export BUILD_NET_TOKIO=1; fi diff --git a/fuzz/rustfmt.toml b/fuzz/rustfmt.toml new file mode 100644 index 00000000000..c087967944a --- /dev/null +++ b/fuzz/rustfmt.toml @@ -0,0 +1,5 @@ +hard_tabs = true # use tab characters for indentation, spaces for alignment +use_field_init_shorthand = true +max_width = 120 +use_small_heuristics = "Max" +fn_args_layout = "Compressed" diff --git a/fuzz/src/bin/chanmon_consistency_target.rs b/fuzz/src/bin/chanmon_consistency_target.rs index ff082497a67..38313e66d7b 100644 --- a/fuzz/src/bin/chanmon_consistency_target.rs +++ b/fuzz/src/bin/chanmon_consistency_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::chanmon_consistency::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { chanmon_consistency_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { chanmon_consistency_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/chanmon_deser_target.rs b/fuzz/src/bin/chanmon_deser_target.rs index 45df25199e1..f84c9e16751 100644 --- a/fuzz/src/bin/chanmon_deser_target.rs +++ b/fuzz/src/bin/chanmon_deser_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::chanmon_deser::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { chanmon_deser_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { chanmon_deser_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/full_stack_target.rs b/fuzz/src/bin/full_stack_target.rs index 7ad5d148ecd..8890713f4ea 100644 --- a/fuzz/src/bin/full_stack_target.rs +++ b/fuzz/src/bin/full_stack_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::full_stack::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { full_stack_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { full_stack_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_accept_channel_target.rs b/fuzz/src/bin/msg_accept_channel_target.rs index dcd799af3c0..4c6f3fca9ad 100644 --- a/fuzz/src/bin/msg_accept_channel_target.rs +++ b/fuzz/src/bin/msg_accept_channel_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_accept_channel::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_accept_channel_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_accept_channel_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_announcement_signatures_target.rs b/fuzz/src/bin/msg_announcement_signatures_target.rs index 60124e928c2..22a8fb52e7d 100644 --- a/fuzz/src/bin/msg_announcement_signatures_target.rs +++ b/fuzz/src/bin/msg_announcement_signatures_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_announcement_signatures::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_announcement_signatures_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_announcement_signatures_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_channel_announcement_target.rs b/fuzz/src/bin/msg_channel_announcement_target.rs index c20a62a3f93..aa95ab19b22 100644 --- a/fuzz/src/bin/msg_channel_announcement_target.rs +++ b/fuzz/src/bin/msg_channel_announcement_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_channel_announcement::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_channel_announcement_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_channel_announcement_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_channel_reestablish_target.rs b/fuzz/src/bin/msg_channel_reestablish_target.rs index 99301da6b73..567420e35c1 100644 --- a/fuzz/src/bin/msg_channel_reestablish_target.rs +++ b/fuzz/src/bin/msg_channel_reestablish_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_channel_reestablish::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_channel_reestablish_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_channel_reestablish_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_channel_update_target.rs b/fuzz/src/bin/msg_channel_update_target.rs index 2ccc1e3fa3d..c8d58ad9adb 100644 --- a/fuzz/src/bin/msg_channel_update_target.rs +++ b/fuzz/src/bin/msg_channel_update_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_channel_update::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_channel_update_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_channel_update_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_closing_signed_target.rs b/fuzz/src/bin/msg_closing_signed_target.rs index 5e676be3914..3de420bf944 100644 --- a/fuzz/src/bin/msg_closing_signed_target.rs +++ b/fuzz/src/bin/msg_closing_signed_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_closing_signed::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_closing_signed_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_closing_signed_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_commitment_signed_target.rs b/fuzz/src/bin/msg_commitment_signed_target.rs index c37f0030ee4..35cf7082d70 100644 --- a/fuzz/src/bin/msg_commitment_signed_target.rs +++ b/fuzz/src/bin/msg_commitment_signed_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_commitment_signed::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_commitment_signed_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_commitment_signed_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs b/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs index ae025cc68f9..d929743a34e 100644 --- a/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs +++ b/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_decoded_onion_error_packet::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_decoded_onion_error_packet_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_decoded_onion_error_packet_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_error_message_target.rs b/fuzz/src/bin/msg_error_message_target.rs index a72fe53339f..dae325b493c 100644 --- a/fuzz/src/bin/msg_error_message_target.rs +++ b/fuzz/src/bin/msg_error_message_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_error_message::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_error_message_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_error_message_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_funding_created_target.rs b/fuzz/src/bin/msg_funding_created_target.rs index 4e885b64684..fbc233794f7 100644 --- a/fuzz/src/bin/msg_funding_created_target.rs +++ b/fuzz/src/bin/msg_funding_created_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_funding_created::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_funding_created_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_funding_created_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_funding_locked_target.rs b/fuzz/src/bin/msg_funding_locked_target.rs index 0dc343c67db..af58e6c2c20 100644 --- a/fuzz/src/bin/msg_funding_locked_target.rs +++ b/fuzz/src/bin/msg_funding_locked_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_funding_locked::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_funding_locked_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_funding_locked_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_funding_signed_target.rs b/fuzz/src/bin/msg_funding_signed_target.rs index 0fb95103515..f25b5057606 100644 --- a/fuzz/src/bin/msg_funding_signed_target.rs +++ b/fuzz/src/bin/msg_funding_signed_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_funding_signed::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_funding_signed_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_funding_signed_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_init_target.rs b/fuzz/src/bin/msg_init_target.rs index 70730523132..464b15cea4b 100644 --- a/fuzz/src/bin/msg_init_target.rs +++ b/fuzz/src/bin/msg_init_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_init::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_init_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_init_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_node_announcement_target.rs b/fuzz/src/bin/msg_node_announcement_target.rs index 1a5484169d4..16ceffc239f 100644 --- a/fuzz/src/bin/msg_node_announcement_target.rs +++ b/fuzz/src/bin/msg_node_announcement_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_node_announcement::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_node_announcement_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_node_announcement_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_onion_hop_data_target.rs b/fuzz/src/bin/msg_onion_hop_data_target.rs index 75a5c19c271..16968d5e29c 100644 --- a/fuzz/src/bin/msg_onion_hop_data_target.rs +++ b/fuzz/src/bin/msg_onion_hop_data_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_onion_hop_data::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_onion_hop_data_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_onion_hop_data_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_open_channel_target.rs b/fuzz/src/bin/msg_open_channel_target.rs index f5843b7c36d..c755d3dd972 100644 --- a/fuzz/src/bin/msg_open_channel_target.rs +++ b/fuzz/src/bin/msg_open_channel_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_open_channel::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_open_channel_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_open_channel_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_ping_target.rs b/fuzz/src/bin/msg_ping_target.rs index b0dd707ea67..db4d7c0cd36 100644 --- a/fuzz/src/bin/msg_ping_target.rs +++ b/fuzz/src/bin/msg_ping_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_ping::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_ping_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_ping_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_pong_target.rs b/fuzz/src/bin/msg_pong_target.rs index 6f9ae4e06bd..eab12e991fc 100644 --- a/fuzz/src/bin/msg_pong_target.rs +++ b/fuzz/src/bin/msg_pong_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_pong::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_pong_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_pong_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_revoke_and_ack_target.rs b/fuzz/src/bin/msg_revoke_and_ack_target.rs index dcf3e99f8c8..0f12ffd0d5c 100644 --- a/fuzz/src/bin/msg_revoke_and_ack_target.rs +++ b/fuzz/src/bin/msg_revoke_and_ack_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_revoke_and_ack::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_revoke_and_ack_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_revoke_and_ack_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_shutdown_target.rs b/fuzz/src/bin/msg_shutdown_target.rs index cb6f4e8d7c0..24b9c61dbc1 100644 --- a/fuzz/src/bin/msg_shutdown_target.rs +++ b/fuzz/src/bin/msg_shutdown_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_shutdown::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_shutdown_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_shutdown_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_update_add_htlc_target.rs b/fuzz/src/bin/msg_update_add_htlc_target.rs index b4b9bc9f34d..cf30a6c151d 100644 --- a/fuzz/src/bin/msg_update_add_htlc_target.rs +++ b/fuzz/src/bin/msg_update_add_htlc_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_update_add_htlc::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_update_add_htlc_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_update_add_htlc_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_update_fail_htlc_target.rs b/fuzz/src/bin/msg_update_fail_htlc_target.rs index 557c22912e0..4bf82dff1ed 100644 --- a/fuzz/src/bin/msg_update_fail_htlc_target.rs +++ b/fuzz/src/bin/msg_update_fail_htlc_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_update_fail_htlc::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_update_fail_htlc_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_update_fail_htlc_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs b/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs index c62aa7633f6..52adda0a273 100644 --- a/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs +++ b/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_update_fail_malformed_htlc::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_update_fail_malformed_htlc_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_update_fail_malformed_htlc_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_update_fee_target.rs b/fuzz/src/bin/msg_update_fee_target.rs index 887843a6584..f5eb6cd9756 100644 --- a/fuzz/src/bin/msg_update_fee_target.rs +++ b/fuzz/src/bin/msg_update_fee_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_update_fee::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_update_fee_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_update_fee_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/msg_update_fulfill_htlc_target.rs b/fuzz/src/bin/msg_update_fulfill_htlc_target.rs index 1f9d9c910a3..2f1cf3b3e39 100644 --- a/fuzz/src/bin/msg_update_fulfill_htlc_target.rs +++ b/fuzz/src/bin/msg_update_fulfill_htlc_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::msg_targets::msg_update_fulfill_htlc::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { msg_update_fulfill_htlc_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { msg_update_fulfill_htlc_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/peer_crypt_target.rs b/fuzz/src/bin/peer_crypt_target.rs index b30c33ab2af..e75c52a279c 100644 --- a/fuzz/src/bin/peer_crypt_target.rs +++ b/fuzz/src/bin/peer_crypt_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::peer_crypt::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { peer_crypt_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { peer_crypt_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/router_target.rs b/fuzz/src/bin/router_target.rs index 588c811c65d..51946a46cbb 100644 --- a/fuzz/src/bin/router_target.rs +++ b/fuzz/src/bin/router_target.rs @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::router::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { router_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { router_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/bin/target_template.txt b/fuzz/src/bin/target_template.txt index 2dcf22712cb..1944987d7b2 100644 --- a/fuzz/src/bin/target_template.txt +++ b/fuzz/src/bin/target_template.txt @@ -7,7 +7,8 @@ extern crate lightning_fuzz; use lightning_fuzz::TARGET_MOD::*; #[cfg(feature = "afl")] -#[macro_use] extern crate afl; +#[macro_use] +extern crate afl; #[cfg(feature = "afl")] fn main() { fuzz!(|data| { @@ -16,7 +17,8 @@ fn main() { } #[cfg(feature = "honggfuzz")] -#[macro_use] extern crate honggfuzz; +#[macro_use] +extern crate honggfuzz; #[cfg(feature = "honggfuzz")] fn main() { loop { @@ -27,7 +29,8 @@ fn main() { } #[cfg(feature = "libfuzzer_fuzz")] -#[macro_use] extern crate libfuzzer_sys; +#[macro_use] +extern crate libfuzzer_sys; #[cfg(feature = "libfuzzer_fuzz")] fuzz_target!(|data: &[u8]| { TARGET_NAME_run(data.as_ptr(), data.len()); @@ -44,9 +47,9 @@ fn main() { #[test] fn run_test_cases() { + use lightning_fuzz::utils::test_logger::StringBuffer; use std::fs; use std::io::Read; - use lightning_fuzz::utils::test_logger::StringBuffer; use std::sync::{atomic, Arc}; { @@ -64,20 +67,25 @@ fn run_test_cases() { let thread_count_ref = Arc::clone(&threads_running); let main_thread_ref = std::thread::current(); - threads.push((path.file_name().unwrap().to_str().unwrap().to_string(), + threads.push(( + path.file_name().unwrap().to_str().unwrap().to_string(), std::thread::spawn(move || { let string_logger = StringBuffer::new(); let panic_logger = string_logger.clone(); let res = if ::std::panic::catch_unwind(move || { TARGET_NAME_test(&data, panic_logger); - }).is_err() { + }) + .is_err() + { Some(string_logger.into_string()) - } else { None }; + } else { + None + }; thread_count_ref.fetch_sub(1, atomic::Ordering::AcqRel); main_thread_ref.unpark(); res - }) + }), )); while threads_running.load(atomic::Ordering::Acquire) > 32 { std::thread::park(); diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 135249f7414..1758e9cf6f3 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -9,45 +9,49 @@ //! send-side handling is correct, other peers. We consider it a failure if any action results in a //! channel being force-closed. -use bitcoin::BitcoinHash; use bitcoin::blockdata::block::BlockHeader; -use bitcoin::blockdata::transaction::{Transaction, TxOut}; -use bitcoin::blockdata::script::{Builder, Script}; use bitcoin::blockdata::opcodes; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::transaction::{Transaction, TxOut}; use bitcoin::network::constants::Network; +use bitcoin::BitcoinHash; -use bitcoin::hashes::Hash as TraitImport; -use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hash_types::{BlockHash, WPubkeyHash}; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::Hash as TraitImport; use lightning::chain::chaininterface; +use lightning::chain::chaininterface::{ + BroadcasterInterface, ChainListener, ChainWatchInterfaceUtil, ConfirmationTarget, FeeEstimator, +}; +use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface}; use lightning::chain::transaction::OutPoint; -use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil}; -use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys}; +use lightning::ln::channelmanager::{ + ChannelManager, ChannelManagerReadArgs, PaymentHash, PaymentPreimage, PaymentSecret, +}; use lightning::ln::channelmonitor; use lightning::ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, HTLCUpdate}; -use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, ChannelManagerReadArgs}; -use lightning::ln::router::{Route, RouteHop}; use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; -use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, UpdateAddHTLC, Init}; +use lightning::ln::msgs::{ChannelMessageHandler, CommitmentUpdate, ErrorAction, Init, UpdateAddHTLC}; +use lightning::ln::router::{Route, RouteHop}; +use lightning::util::config::UserConfig; use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; use lightning::util::events; -use lightning::util::logger::Logger; -use lightning::util::config::UserConfig; use lightning::util::events::{EventsProvider, MessageSendEventsProvider}; +use lightning::util::logger::Logger; use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer}; use utils::test_logger; -use bitcoin::secp256k1::key::{PublicKey,SecretKey}; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; use bitcoin::secp256k1::Secp256k1; -use std::mem; use std::cmp::Ordering; -use std::collections::{HashSet, hash_map, HashMap}; -use std::sync::{Arc,Mutex}; -use std::sync::atomic; +use std::collections::{hash_map, HashMap, HashSet}; use std::io::Cursor; +use std::mem; +use std::sync::atomic; +use std::sync::{Arc, Mutex}; struct FuzzEstimator {} impl FeeEstimator for FuzzEstimator { @@ -58,7 +62,7 @@ impl FeeEstimator for FuzzEstimator { pub struct TestBroadcaster {} impl BroadcasterInterface for TestBroadcaster { - fn broadcast_transaction(&self, _tx: &Transaction) { } + fn broadcast_transaction(&self, _tx: &Transaction) {} } pub struct VecWriter(pub Vec); @@ -74,7 +78,14 @@ impl Writer for VecWriter { struct TestChannelMonitor { pub logger: Arc, - pub simple_monitor: Arc, Arc>>, + pub simple_monitor: Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, pub update_ret: Mutex>, // If we reload a node with an old copy of ChannelMonitors, the ChannelManager deserialization // logic will automatically force-close our channels for us (as we don't have an up-to-date @@ -85,9 +96,17 @@ struct TestChannelMonitor { pub should_update_manager: atomic::AtomicBool, } impl TestChannelMonitor { - pub fn new(chain_monitor: Arc, broadcaster: Arc, logger: Arc, feeest: Arc) -> Self { + pub fn new( + chain_monitor: Arc, broadcaster: Arc, + logger: Arc, feeest: Arc, + ) -> Self { Self { - simple_monitor: Arc::new(channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger.clone(), feeest)), + simple_monitor: Arc::new(channelmonitor::SimpleManyChannelMonitor::new( + chain_monitor, + broadcaster, + logger.clone(), + feeest, + )), logger, update_ret: Mutex::new(Ok(())), latest_monitors: Mutex::new(HashMap::new()), @@ -96,10 +115,14 @@ impl TestChannelMonitor { } } impl channelmonitor::ManyChannelMonitor for TestChannelMonitor { - fn add_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> { + fn add_monitor( + &self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor, + ) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> { let mut ser = VecWriter(Vec::new()); monitor.write_for_disk(&mut ser).unwrap(); - if let Some(_) = self.latest_monitors.lock().unwrap().insert(funding_txo, (monitor.get_latest_update_id(), ser.0)) { + if let Some(_) = + self.latest_monitors.lock().unwrap().insert(funding_txo, (monitor.get_latest_update_id(), ser.0)) + { panic!("Already had monitor pre-add_monitor"); } self.should_update_manager.store(true, atomic::Ordering::Relaxed); @@ -107,14 +130,20 @@ impl channelmonitor::ManyChannelMonitor for TestChannelMon self.update_ret.lock().unwrap().clone() } - fn update_monitor(&self, funding_txo: OutPoint, update: channelmonitor::ChannelMonitorUpdate) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> { + fn update_monitor( + &self, funding_txo: OutPoint, update: channelmonitor::ChannelMonitorUpdate, + ) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> { let mut map_lock = self.latest_monitors.lock().unwrap(); let mut map_entry = match map_lock.entry(funding_txo) { hash_map::Entry::Occupied(entry) => entry, hash_map::Entry::Vacant(_) => panic!("Didn't have monitor on update call"), }; - let mut deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor)>:: - read(&mut Cursor::new(&map_entry.get().1), Arc::clone(&self.logger)).unwrap().1; + let mut deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor)>::read( + &mut Cursor::new(&map_entry.get().1), + Arc::clone(&self.logger), + ) + .unwrap() + .1; deserialized_monitor.update_monitor(update.clone(), &&TestBroadcaster {}).unwrap(); let mut ser = VecWriter(Vec::new()); deserialized_monitor.write_for_disk(&mut ser).unwrap(); @@ -136,22 +165,31 @@ struct KeyProvider { impl KeysInterface for KeyProvider { type ChanKeySigner = EnforcingChannelKeys; + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_node_secret(&self) -> SecretKey { SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_id]).unwrap() } fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); + + #[cfg_attr(rustfmt, rustfmt_skip)] let channel_monitor_claim_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, self.node_id]).unwrap(); - let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() + let our_channel_monitor_claim_key_hash = + WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&our_channel_monitor_claim_key_hash[..]) + .into_script() } + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_shutdown_pubkey(&self) -> PublicKey { let secp_ctx = Secp256k1::signing_only(); PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, self.node_id]).unwrap()) } + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> EnforcingChannelKeys { let secp_ctx = Secp256k1::signing_only(); EnforcingChannelKeys::new(InMemoryChannelKeys::new( @@ -166,12 +204,14 @@ impl KeysInterface for KeyProvider { )) } + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { let id = self.session_id.fetch_add(1, atomic::Ordering::Relaxed); (SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id, 10, self.node_id]).unwrap(), [0; 32]) } + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_channel_id(&self) -> [u8; 32] { let id = self.channel_id.fetch_add(1, atomic::Ordering::Relaxed); [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id, 11, self.node_id] @@ -180,9 +220,10 @@ impl KeysInterface for KeyProvider { #[inline] pub fn do_test(data: &[u8], out: Out) { - let fee_est = Arc::new(FuzzEstimator{}); - let broadcast = Arc::new(TestBroadcaster{}); + let fee_est = Arc::new(FuzzEstimator {}); + let broadcast = Arc::new(TestBroadcaster {}); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! make_node { ($node_id: expr) => { { let logger: Arc = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone())); @@ -199,6 +240,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! reload_node { ($ser: expr, $node_id: expr, $old_monitors: expr) => { { let logger: Arc = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone())); @@ -237,6 +279,7 @@ pub fn do_test(data: &[u8], out: Out) { } let mut channel_txn = Vec::new(); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! make_channel { ($source: expr, $dest: expr, $chan_id: expr) => { { $source.create_channel($dest.get_our_node_id(), 10000000, 42, 0, None).unwrap(); @@ -300,6 +343,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! confirm_txn { ($node: expr) => { { let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; @@ -317,6 +361,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! lock_fundings { ($nodes: expr) => { { let mut node_events = Vec::new(); @@ -379,6 +424,7 @@ pub fn do_test(data: &[u8], out: Out) { let mut node_c_ser = VecWriter(Vec::new()); nodes[2].write(&mut node_c_ser).unwrap(); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_return { () => { { assert_eq!(nodes[0].list_channels().len(), 1); @@ -389,6 +435,7 @@ pub fn do_test(data: &[u8], out: Out) { } let mut read_pos = 0; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_slice { ($len: expr) => { { @@ -403,6 +450,7 @@ pub fn do_test(data: &[u8], out: Out) { } loop { + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! send_payment { ($source: expr, $dest: expr) => { { let payment_hash = Sha256::hash(&[payment_id; 1]); @@ -446,6 +494,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! send_payment_with_secret { ($source: expr, $middle: expr, $dest: expr) => { { let payment_hash = Sha256::hash(&[payment_id; 1]); @@ -489,6 +538,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! process_msg_events { ($node: expr, $corrupt_forward: expr) => { { let events = if $node == 1 { @@ -562,6 +612,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! drain_msg_events_on_disconnect { ($counterparty_id: expr) => { { if $counterparty_id == 0 { @@ -615,6 +666,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! process_events { ($node: expr, $fail: expr) => { { // In case we get 256 payments we may have a hash collision, resulting in the @@ -671,22 +723,22 @@ pub fn do_test(data: &[u8], out: Out) { if let Some((id, _)) = monitor_a.latest_monitors.lock().unwrap().get(&chan_1_funding) { nodes[0].channel_monitor_updated(&chan_1_funding, *id); } - }, + } 0x07 => { if let Some((id, _)) = monitor_b.latest_monitors.lock().unwrap().get(&chan_1_funding) { nodes[1].channel_monitor_updated(&chan_1_funding, *id); } - }, + } 0x24 => { if let Some((id, _)) = monitor_b.latest_monitors.lock().unwrap().get(&chan_2_funding) { nodes[1].channel_monitor_updated(&chan_2_funding, *id); } - }, + } 0x08 => { if let Some((id, _)) = monitor_c.latest_monitors.lock().unwrap().get(&chan_2_funding) { nodes[2].channel_monitor_updated(&chan_2_funding, *id); } - }, + } 0x09 => send_payment!(nodes[0], (&nodes[1], chan_a)), 0x0a => send_payment!(nodes[1], (&nodes[0], chan_a)), 0x0b => send_payment!(nodes[1], (&nodes[2], chan_b)), @@ -700,7 +752,7 @@ pub fn do_test(data: &[u8], out: Out) { chan_a_disconnected = true; drain_msg_events_on_disconnect!(0); } - }, + } 0x10 => { if !chan_b_disconnected { nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false); @@ -708,21 +760,21 @@ pub fn do_test(data: &[u8], out: Out) { chan_b_disconnected = true; drain_msg_events_on_disconnect!(2); } - }, + } 0x11 => { if chan_a_disconnected { nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() }); nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() }); chan_a_disconnected = false; } - }, + } 0x12 => { if chan_b_disconnected { nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() }); nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() }); chan_b_disconnected = false; } - }, + } 0x13 => process_msg_events!(0, true), 0x14 => process_msg_events!(0, false), 0x15 => process_events!(0, true), @@ -745,7 +797,7 @@ pub fn do_test(data: &[u8], out: Out) { node_a = Arc::new(new_node_a); nodes[0] = node_a.clone(); monitor_a = new_monitor_a; - }, + } 0x20 => { if !chan_a_disconnected { nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false); @@ -763,7 +815,7 @@ pub fn do_test(data: &[u8], out: Out) { node_b = Arc::new(new_node_b); nodes[1] = node_b.clone(); monitor_b = new_monitor_b; - }, + } 0x21 => { if !chan_b_disconnected { nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false); @@ -774,7 +826,7 @@ pub fn do_test(data: &[u8], out: Out) { node_c = Arc::new(new_node_c); nodes[2] = node_c.clone(); monitor_c = new_monitor_c; - }, + } 0x22 => send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)), 0x23 => send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)), // 0x24 defined above @@ -799,5 +851,5 @@ pub fn chanmon_consistency_test(data: &[u8], out: Out) #[no_mangle] pub extern "C" fn chanmon_consistency_run(data: *const u8, datalen: usize) { - do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{}); + do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {}); } diff --git a/fuzz/src/chanmon_deser.rs b/fuzz/src/chanmon_deser.rs index 52caf36e1b9..171ef715b36 100644 --- a/fuzz/src/chanmon_deser.rs +++ b/fuzz/src/chanmon_deser.rs @@ -3,8 +3,8 @@ use bitcoin::hash_types::BlockHash; -use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; use lightning::ln::channelmonitor; +use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; use lightning::util::ser::{ReadableArgs, Writer}; use utils::test_logger; @@ -26,10 +26,17 @@ impl Writer for VecWriter { #[inline] pub fn do_test(data: &[u8], out: Out) { let logger = Arc::new(test_logger::TestLogger::new("".to_owned(), out)); - if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(data), logger.clone()) { + if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor)>::read( + &mut Cursor::new(data), + logger.clone(), + ) { let mut w = VecWriter(Vec::new()); monitor.write_for_disk(&mut w).unwrap(); - let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(&w.0), logger.clone()).unwrap(); + let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor)>::read( + &mut Cursor::new(&w.0), + logger.clone(), + ) + .unwrap(); assert!(latest_block_hash == deserialized_copy.0); assert!(monitor == deserialized_copy.1); } @@ -41,5 +48,5 @@ pub fn chanmon_deser_test(data: &[u8], out: Out) { #[no_mangle] pub extern "C" fn chanmon_deser_run(data: *const u8, datalen: usize) { - do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{}); + do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {}); } diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index d8d4abf9c7a..d3505a5034e 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -5,73 +5,78 @@ //! This test has been very useful, though due to its complexity good starting inputs are critical. use bitcoin::blockdata::block::BlockHeader; -use bitcoin::blockdata::transaction::{Transaction, TxOut}; -use bitcoin::blockdata::script::{Builder, Script}; use bitcoin::blockdata::opcodes; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::transaction::{Transaction, TxOut}; use bitcoin::consensus::encode::deserialize; use bitcoin::network::constants::Network; use bitcoin::util::hash::BitcoinHash; +use bitcoin::hash_types::{BlockHash, Txid, WPubkeyHash}; +use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash as TraitImport; use bitcoin::hashes::HashEngine as TraitImportEngine; -use bitcoin::hashes::sha256::Hash as Sha256; -use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash}; -use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil}; -use lightning::chain::transaction::OutPoint; +use lightning::chain::chaininterface::{ + BroadcasterInterface, ChainListener, ChainWatchInterfaceUtil, ConfirmationTarget, FeeEstimator, +}; use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface}; -use lightning::ln::channelmonitor; +use lightning::chain::transaction::OutPoint; use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret}; -use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; +use lightning::ln::channelmonitor; +use lightning::ln::peer_handler::{MessageHandler, PeerManager, SocketDescriptor}; use lightning::ln::router::Router; -use lightning::util::events::{EventsProvider,Event}; +use lightning::util::config::UserConfig; use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; +use lightning::util::events::{Event, EventsProvider}; use lightning::util::logger::Logger; -use lightning::util::config::UserConfig; use utils::test_logger; -use bitcoin::secp256k1::key::{PublicKey,SecretKey}; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; use bitcoin::secp256k1::Secp256k1; use std::cell::RefCell; -use std::collections::{HashMap, hash_map}; use std::cmp; +use std::collections::{hash_map, HashMap}; +use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; use std::sync::Arc; -use std::sync::atomic::{AtomicU64,AtomicUsize,Ordering}; #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] pub fn slice_to_be16(v: &[u8]) -> u16 { - ((v[0] as u16) << 8*1) | - ((v[1] as u16) << 8*0) + ((v[0] as u16) << 8 * 1) | + ((v[1] as u16) << 8 * 0) } #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] pub fn slice_to_be24(v: &[u8]) -> u32 { - ((v[0] as u32) << 8*2) | - ((v[1] as u32) << 8*1) | - ((v[2] as u32) << 8*0) + ((v[0] as u32) << 8 * 2) | + ((v[1] as u32) << 8 * 1) | + ((v[2] as u32) << 8 * 0) } #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] pub fn slice_to_be32(v: &[u8]) -> u32 { - ((v[0] as u32) << 8*3) | - ((v[1] as u32) << 8*2) | - ((v[2] as u32) << 8*1) | - ((v[3] as u32) << 8*0) + ((v[0] as u32) << 8 * 3) | + ((v[1] as u32) << 8 * 2) | + ((v[2] as u32) << 8 * 1) | + ((v[3] as u32) << 8 * 0) } #[inline] pub fn be64_to_array(u: u64) -> [u8; 8] { let mut v = [0; 8]; - v[0] = ((u >> 8*7) & 0xff) as u8; - v[1] = ((u >> 8*6) & 0xff) as u8; - v[2] = ((u >> 8*5) & 0xff) as u8; - v[3] = ((u >> 8*4) & 0xff) as u8; - v[4] = ((u >> 8*3) & 0xff) as u8; - v[5] = ((u >> 8*2) & 0xff) as u8; - v[6] = ((u >> 8*1) & 0xff) as u8; - v[7] = ((u >> 8*0) & 0xff) as u8; + v[0] = ((u >> 8 * 7) & 0xff) as u8; + v[1] = ((u >> 8 * 6) & 0xff) as u8; + v[2] = ((u >> 8 * 5) & 0xff) as u8; + v[3] = ((u >> 8 * 4) & 0xff) as u8; + v[4] = ((u >> 8 * 3) & 0xff) as u8; + v[5] = ((u >> 8 * 2) & 0xff) as u8; + v[6] = ((u >> 8 * 1) & 0xff) as u8; + v[7] = ((u >> 8 * 0) & 0xff) as u8; v } @@ -97,7 +102,7 @@ impl FeeEstimator for FuzzEstimator { //TODO: We should actually be testing at least much more than 64k... match self.input.get_slice(2) { Some(slice) => cmp::max(slice_to_be16(slice) as u64, 253), - None => 253 + None => 253, } } } @@ -128,15 +133,55 @@ impl<'a> PartialEq for Peer<'a> { } impl<'a> Eq for Peer<'a> {} impl<'a> std::hash::Hash for Peer<'a> { - fn hash(&self, h: &mut H) { + fn hash(&self, h: &mut H) { self.id.hash(h) } } struct MoneyLossDetector<'a> { - manager: Arc, Arc>>, Arc, Arc, Arc>>, - monitor: Arc, Arc>>, - handler: PeerManager, Arc, Arc>>, Arc, Arc, Arc>>>, + manager: Arc< + ChannelManager< + EnforcingChannelKeys, + Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, + Arc, + Arc, + Arc, + >, + >, + monitor: Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, + handler: PeerManager< + Peer<'a>, + Arc< + ChannelManager< + EnforcingChannelKeys, + Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, + Arc, + Arc, + Arc, + >, + >, + >, peers: &'a RefCell<[bool; 256]>, funding_txn: Vec, @@ -147,10 +192,52 @@ struct MoneyLossDetector<'a> { blocks_connected: u32, } impl<'a> MoneyLossDetector<'a> { - pub fn new(peers: &'a RefCell<[bool; 256]>, - manager: Arc, Arc>>, Arc, Arc, Arc>>, - monitor: Arc, Arc>>, - handler: PeerManager, Arc, Arc>>, Arc, Arc, Arc>>>) -> Self { + pub fn new( + peers: &'a RefCell<[bool; 256]>, + manager: Arc< + ChannelManager< + EnforcingChannelKeys, + Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, + Arc, + Arc, + Arc, + >, + >, + monitor: Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, + handler: PeerManager< + Peer<'a>, + Arc< + ChannelManager< + EnforcingChannelKeys, + Arc< + channelmonitor::SimpleManyChannelMonitor< + OutPoint, + EnforcingChannelKeys, + Arc, + Arc, + >, + >, + Arc, + Arc, + Arc, + >, + >, + >, + ) -> Self { MoneyLossDetector { manager, monitor, @@ -176,12 +263,19 @@ impl<'a> MoneyLossDetector<'a> { e.insert(self.height); txn.push(tx); txn_idxs.push(idx as u32 + 1); - }, - _ => {}, + } + _ => {} } } - let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: self.blocks_connected, bits: 42, nonce: 42 }; + let header = BlockHeader { + version: 0x20000000, + prev_blockhash: self.header_hashes[self.height], + merkle_root: Default::default(), + time: self.blocks_connected, + bits: 42, + nonce: 42, + }; self.height += 1; self.blocks_connected += 1; self.manager.block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]); @@ -197,14 +291,19 @@ impl<'a> MoneyLossDetector<'a> { fn disconnect_block(&mut self) { if self.height > 0 && (self.max_height < 6 || self.height >= self.max_height - 6) { - let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + let header = BlockHeader { + version: 0x20000000, + prev_blockhash: self.header_hashes[self.height], + merkle_root: Default::default(), + time: 42, + bits: 42, + nonce: 42, + }; self.manager.block_disconnected(&header, self.height as u32); self.monitor.block_disconnected(&header, self.height as u32); self.height -= 1; let removal_height = self.height; - self.txids_confirmed.retain(|_, height| { - removal_height != *height - }); + self.txids_confirmed.retain(|_, height| removal_height != *height); } } } @@ -215,7 +314,7 @@ impl<'a> Drop for MoneyLossDetector<'a> { // Disconnect all peers for (idx, peer) in self.peers.borrow().iter().enumerate() { if *peer { - self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers}); + self.handler.socket_disconnected(&Peer { id: idx as u8, peers_connected: &self.peers }); } } @@ -238,14 +337,27 @@ impl KeysInterface for KeyProvider { fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); - let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); - let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() + let channel_monitor_claim_key = SecretKey::from_slice( + &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..], + ) + .unwrap(); + let our_channel_monitor_claim_key_hash = + WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&our_channel_monitor_claim_key_hash[..]) + .into_script() } fn get_shutdown_pubkey(&self) -> PublicKey { let secp_ctx = Secp256k1::signing_only(); - PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap()) + PublicKey::from_secret_key( + &secp_ctx, + &SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]) + .unwrap(), + ) } fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> EnforcingChannelKeys { @@ -254,22 +366,52 @@ impl KeysInterface for KeyProvider { EnforcingChannelKeys::new(if inbound { InMemoryChannelKeys::new( &secp_ctx, - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr, + ]) + .unwrap(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr], channel_value_satoshis, ) } else { InMemoryChannelKeys::new( &secp_ctx, - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, ctr]).unwrap(), - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, ctr, + ]) + .unwrap(), + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr, + ]) + .unwrap(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr], channel_value_satoshis, ) @@ -278,10 +420,16 @@ impl KeysInterface for KeyProvider { fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8; - (SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, ctr]).unwrap(), - [0; 32]) + ( + SecretKey::from_slice(&[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, ctr, + ]) + .unwrap(), + [0; 32], + ) } + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_channel_id(&self) -> [u8; 32] { let ctr = self.counter.fetch_add(1, Ordering::Relaxed); [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -291,14 +439,10 @@ impl KeysInterface for KeyProvider { #[inline] pub fn do_test(data: &[u8], logger: &Arc) { - let input = Arc::new(InputData { - data: data.to_vec(), - read_pos: AtomicUsize::new(0), - }); - let fee_est = Arc::new(FuzzEstimator { - input: input.clone(), - }); + let input = Arc::new(InputData { data: data.to_vec(), read_pos: AtomicUsize::new(0) }); + let fee_est = Arc::new(FuzzEstimator { input: input.clone() }); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_slice { ($len: expr) => { match input.get_slice($len as usize) { @@ -308,6 +452,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_pubkey { () => { match PublicKey::from_slice(get_slice!(33)) { @@ -323,22 +468,50 @@ pub fn do_test(data: &[u8], logger: &Arc) { }; let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger))); - let broadcast = Arc::new(TestBroadcaster{}); - let monitor = Arc::new(channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone(), Arc::clone(&logger), fee_est.clone())); + let broadcast = Arc::new(TestBroadcaster {}); + let monitor = Arc::new(channelmonitor::SimpleManyChannelMonitor::new( + watch.clone(), + broadcast.clone(), + Arc::clone(&logger), + fee_est.clone(), + )); let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), counter: AtomicU64::new(0) }); let mut config = UserConfig::default(); - config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4)); + config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4)); config.channel_options.announced_channel = get_slice!(1)[0] != 0; config.peer_channel_config_limits.min_dust_limit_satoshis = 0; - let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap()); - let router = Arc::new(Router::new(PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret()), watch.clone(), Arc::clone(&logger))); + let channelmanager = Arc::new( + ChannelManager::new( + Network::Bitcoin, + fee_est.clone(), + monitor.clone(), + broadcast.clone(), + Arc::clone(&logger), + keys_manager.clone(), + config, + 0, + ) + .unwrap(), + ); + let router = Arc::new(Router::new( + PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret()), + watch.clone(), + Arc::clone(&logger), + )); let peers = RefCell::new([false; 256]); - let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler { - chan_handler: channelmanager.clone(), - route_handler: router.clone(), - }, our_network_key, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger))); + let mut loss_detector = MoneyLossDetector::new( + &peers, + channelmanager.clone(), + monitor.clone(), + PeerManager::new( + MessageHandler { chan_handler: channelmanager.clone(), route_handler: router.clone() }, + our_network_key, + &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], + Arc::clone(&logger), + ), + ); let mut should_forward = false; let mut payments_received: Vec<(PaymentHash, Option, u64)> = Vec::new(); @@ -352,41 +525,60 @@ pub fn do_test(data: &[u8], logger: &Arc) { 0 => { let mut new_id = 0; for i in 1..256 { - if !peers.borrow()[i-1] { + if !peers.borrow()[i - 1] { new_id = i; break; } } - if new_id == 0 { return; } - loss_detector.handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap(); + if new_id == 0 { + return; + } + loss_detector + .handler + .new_outbound_connection(get_pubkey!(), Peer { id: (new_id - 1) as u8, peers_connected: &peers }) + .unwrap(); peers.borrow_mut()[new_id - 1] = true; - }, + } 1 => { let mut new_id = 0; for i in 1..256 { - if !peers.borrow()[i-1] { + if !peers.borrow()[i - 1] { new_id = i; break; } } - if new_id == 0 { return; } - loss_detector.handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap(); + if new_id == 0 { + return; + } + loss_detector + .handler + .new_inbound_connection(Peer { id: (new_id - 1) as u8, peers_connected: &peers }) + .unwrap(); peers.borrow_mut()[new_id - 1] = true; - }, + } 2 => { let peer_id = get_slice!(1)[0]; - if !peers.borrow()[peer_id as usize] { return; } - loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers}); + if !peers.borrow()[peer_id as usize] { + return; + } + loss_detector.handler.socket_disconnected(&Peer { id: peer_id, peers_connected: &peers }); peers.borrow_mut()[peer_id as usize] = false; - }, + } 3 => { let peer_id = get_slice!(1)[0]; - if !peers.borrow()[peer_id as usize] { return; } - match loss_detector.handler.read_event(&mut Peer{id: peer_id, peers_connected: &peers}, get_slice!(get_slice!(1)[0])) { + if !peers.borrow()[peer_id as usize] { + return; + } + match loss_detector + .handler + .read_event(&mut Peer { id: peer_id, peers_connected: &peers }, get_slice!(get_slice!(1)[0])) + { Ok(res) => assert!(!res), - Err(_) => { peers.borrow_mut()[peer_id as usize] = false; } + Err(_) => { + peers.borrow_mut()[peer_id as usize] = false; + } } - }, + } 4 => { let value = slice_to_be24(get_slice!(3)) as u64; let route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) { @@ -400,10 +592,10 @@ pub fn do_test(data: &[u8], logger: &Arc) { payment_hash.0 = Sha256::from_engine(sha).into_inner(); payments_sent += 1; match channelmanager.send_payment(&route, payment_hash, &None) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return, } - }, + } 15 => { let value = slice_to_be24(get_slice!(3)) as u64; let mut route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) { @@ -421,31 +613,39 @@ pub fn do_test(data: &[u8], logger: &Arc) { payment_secret.0[0..8].copy_from_slice(&be64_to_array(payments_sent)); payments_sent += 1; match channelmanager.send_payment(&route, payment_hash, &Some(payment_secret)) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return, } - }, + } 5 => { let peer_id = get_slice!(1)[0]; - if !peers.borrow()[peer_id as usize] { return; } + if !peers.borrow()[peer_id as usize] { + return; + } let their_key = get_pubkey!(); let chan_value = slice_to_be24(get_slice!(3)) as u64; let push_msat_value = slice_to_be24(get_slice!(3)) as u64; - if channelmanager.create_channel(their_key, chan_value, push_msat_value, 0, None).is_err() { return; } - }, + if channelmanager.create_channel(their_key, chan_value, push_msat_value, 0, None).is_err() { + return; + } + } 6 => { let mut channels = channelmanager.list_channels(); let channel_id = get_slice!(1)[0] as usize; - if channel_id >= channels.len() { return; } - channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) }); - if channelmanager.close_channel(&channels[channel_id].channel_id).is_err() { return; } - }, + if channel_id >= channels.len() { + return; + } + channels.sort_by(|a, b| a.channel_id.cmp(&b.channel_id)); + if channelmanager.close_channel(&channels[channel_id].channel_id).is_err() { + return; + } + } 7 => { if should_forward { channelmanager.process_pending_htlc_forwards(); should_forward = false; } - }, + } 8 => { for (payment, payment_secret, amt) in payments_received.drain(..) { // SHA256 is defined as XOR of all input bytes placed in the first byte, and 0s @@ -460,17 +660,20 @@ pub fn do_test(data: &[u8], logger: &Arc) { channelmanager.claim_funds(payment_preimage, &payment_secret, amt); } } - }, + } 9 => { for (payment, payment_secret, _) in payments_received.drain(..) { channelmanager.fail_htlc_backwards(&payment, &payment_secret); } - }, + } 10 => { 'outer_loop: for funding_generation in pending_funding_generation.drain(..) { - let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut { - value: funding_generation.1, script_pubkey: funding_generation.2, - }] }; + let mut tx = Transaction { + version: 0, + lock_time: 0, + input: Vec::new(), + output: vec![TxOut { value: funding_generation.1, script_pubkey: funding_generation.2 }], + }; let funding_output = 'search_loop: loop { let funding_txid = tx.txid(); if let None = loss_detector.txids_confirmed.get(&funding_txid) { @@ -491,7 +694,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone()); pending_funding_signatures.insert(funding_output, tx); } - }, + } 11 => { if !pending_funding_relay.is_empty() { loss_detector.connect_block(&pending_funding_relay[..]); @@ -502,7 +705,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { for tx in pending_funding_relay.drain(..) { loss_detector.funding_txn.push(tx); } - }, + } 12 => { let txlen = slice_to_be16(get_slice!(2)); if txlen == 0 { @@ -512,48 +715,56 @@ pub fn do_test(data: &[u8], logger: &Arc) { if let Ok(tx) = txres { let mut output_val = 0; for out in tx.output.iter() { - if out.value > 21_000_000_0000_0000 { return; } + if out.value > 21_000_000_0000_0000 { + return; + } output_val += out.value; - if output_val > 21_000_000_0000_0000 { return; } + if output_val > 21_000_000_0000_0000 { + return; + } } loss_detector.connect_block(&[tx]); } else { return; } } - }, + } 13 => { loss_detector.disconnect_block(); - }, + } 14 => { let mut channels = channelmanager.list_channels(); let channel_id = get_slice!(1)[0] as usize; - if channel_id >= channels.len() { return; } - channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) }); + if channel_id >= channels.len() { + return; + } + channels.sort_by(|a, b| a.channel_id.cmp(&b.channel_id)); channelmanager.force_close_channel(&channels[channel_id].channel_id); - }, + } // 15 is above _ => return, } loss_detector.handler.process_events(); for event in loss_detector.manager.get_and_clear_pending_events() { match event { - Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => { + Event::FundingGenerationReady { + temporary_channel_id, channel_value_satoshis, output_script, .. + } => { pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script)); - }, + } Event::FundingBroadcastSafe { funding_txo, .. } => { pending_funding_relay.push(pending_funding_signatures.remove(&funding_txo).unwrap()); - }, + } Event::PaymentReceived { payment_hash, payment_secret, amt } => { //TODO: enhance by fetching random amounts from fuzz input? payments_received.push((payment_hash, payment_secret, amt)); - }, - Event::PaymentSent {..} => {}, - Event::PaymentFailed {..} => {}, - Event::PendingHTLCsForwardable {..} => { + } + Event::PaymentSent { .. } => {} + Event::PaymentFailed { .. } => {} + Event::PendingHTLCsForwardable { .. } => { should_forward = true; - }, - Event::SpendableOutputs {..} => {}, + } + Event::SpendableOutputs { .. } => {} } } } @@ -582,8 +793,20 @@ mod tests { } impl Logger for TrackingLogger { fn log(&self, record: &Record) { - *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1; - println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args); + *self + .lines + .lock() + .unwrap() + .entry((record.module_path.to_string(), format!("{}", record.args))) + .or_insert(0) += 1; + println!( + "{:<5} [{} : {}, {}] {}", + record.level.to_string(), + record.module_path, + record.file, + record.line, + record.args + ); } } @@ -598,7 +821,7 @@ mod tests { // What each byte represents is broken down below, and then everything is concatenated into // one large test at the end (you want %s/ -.*//g %s/\n\| \|\t\|\///g). - // Following BOLT 8, lightning message on the wire are: 2-byte encrypted message length + + // Following BOLT 8, lightning message on the wire are: 2-byte encrypted message length + // 16-byte MAC of the encrypted message length + encrypted Lightning message + 16-byte MAC // of the Lightning message // I.e 2nd inbound read, len 18 : 0006 (encrypted message length) + 03000000000000000000000000000000 (MAC of the encrypted message length) @@ -881,15 +1104,25 @@ mod tests { super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000603000000000000000000000000000000030016001000000000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d0000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001030132000300000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003014200030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000300000000000000000000000000000003011200060100000000000000000000000000000003011600100000000001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e8000000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013900000000000000000000000000000000000000000000000000000000000000000000000000000080020001000000000000220020bb000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c000000000000000000000000000000000000000500002000fd00fd0c005e0200000001d600000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f600000000000000000000000000000000000000000000000000000000000000000000000c00000c000000fd0c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); let log_entries = logger.lines.lock().unwrap(); - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 8 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2)); // 9 - assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000d6:0) in 000000000000000000000000000000000000000000000000000000000000006f resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10 + // 1 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); + // 2 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); + // 3 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); + // 4 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); + // 5 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); + // 6 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); + // 7 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); + // 8 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); + // 9 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2)); + // 10 + assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000d6:0) in 000000000000000000000000000000000000000000000000000000000000006f resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); } } diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index dbda28acf44..b7deea081f7 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -1,11 +1,11 @@ extern crate bitcoin; -extern crate lightning; extern crate hex; +extern crate lightning; pub mod utils; -pub mod chanmon_deser; pub mod chanmon_consistency; +pub mod chanmon_deser; pub mod full_stack; pub mod peer_crypt; pub mod router; diff --git a/fuzz/src/msg_targets/gen_target.sh b/fuzz/src/msg_targets/gen_target.sh index 0121e4eb821..ed4c6aa5d91 100755 --- a/fuzz/src/msg_targets/gen_target.sh +++ b/fuzz/src/msg_targets/gen_target.sh @@ -7,35 +7,33 @@ GEN_TEST() { echo "pub mod $tn;" >> mod.rs } -echo "mod utils;" > mod.rs +echo "mod utils; +" > mod.rs # Note when adding new targets here you should add a similar line in src/bin/gen_target.sh GEN_TEST AcceptChannel test_msg "" GEN_TEST AnnouncementSignatures test_msg "" +GEN_TEST ChannelAnnouncement test_msg_exact "" GEN_TEST ChannelReestablish test_msg "" +GEN_TEST ChannelUpdate test_msg_exact "" GEN_TEST ClosingSigned test_msg "" GEN_TEST CommitmentSigned test_msg "" GEN_TEST DecodedOnionErrorPacket test_msg "" +GEN_TEST ErrorMessage test_msg_hole ", 32, 2" GEN_TEST FundingCreated test_msg "" GEN_TEST FundingLocked test_msg "" GEN_TEST FundingSigned test_msg "" +GEN_TEST Init test_msg_simple "" +GEN_TEST NodeAnnouncement test_msg_exact "" +GEN_TEST OnionHopData test_msg_simple "" GEN_TEST OpenChannel test_msg "" +GEN_TEST Ping test_msg_simple "" +GEN_TEST Pong test_msg_simple "" GEN_TEST RevokeAndACK test_msg "" GEN_TEST Shutdown test_msg "" +GEN_TEST UpdateAddHTLC test_msg_hole ", 85, 33" GEN_TEST UpdateFailHTLC test_msg "" GEN_TEST UpdateFailMalformedHTLC test_msg "" GEN_TEST UpdateFee test_msg "" GEN_TEST UpdateFulfillHTLC test_msg "" - -GEN_TEST ChannelAnnouncement test_msg_exact "" -GEN_TEST ChannelUpdate test_msg_exact "" -GEN_TEST NodeAnnouncement test_msg_exact "" - -GEN_TEST UpdateAddHTLC test_msg_hole ", 85, 33" -GEN_TEST ErrorMessage test_msg_hole ", 32, 2" - -GEN_TEST Init test_msg_simple "" -GEN_TEST OnionHopData test_msg_simple "" -GEN_TEST Ping test_msg_simple "" -GEN_TEST Pong test_msg_simple "" diff --git a/fuzz/src/msg_targets/mod.rs b/fuzz/src/msg_targets/mod.rs index 69fc4e74219..269ea1c933d 100644 --- a/fuzz/src/msg_targets/mod.rs +++ b/fuzz/src/msg_targets/mod.rs @@ -1,26 +1,27 @@ mod utils; + pub mod msg_accept_channel; pub mod msg_announcement_signatures; +pub mod msg_channel_announcement; pub mod msg_channel_reestablish; +pub mod msg_channel_update; pub mod msg_closing_signed; pub mod msg_commitment_signed; pub mod msg_decoded_onion_error_packet; +pub mod msg_error_message; pub mod msg_funding_created; pub mod msg_funding_locked; pub mod msg_funding_signed; +pub mod msg_init; +pub mod msg_node_announcement; +pub mod msg_onion_hop_data; pub mod msg_open_channel; +pub mod msg_ping; +pub mod msg_pong; pub mod msg_revoke_and_ack; pub mod msg_shutdown; +pub mod msg_update_add_htlc; pub mod msg_update_fail_htlc; pub mod msg_update_fail_malformed_htlc; pub mod msg_update_fee; pub mod msg_update_fulfill_htlc; -pub mod msg_channel_announcement; -pub mod msg_channel_update; -pub mod msg_node_announcement; -pub mod msg_update_add_htlc; -pub mod msg_error_message; -pub mod msg_init; -pub mod msg_onion_hop_data; -pub mod msg_ping; -pub mod msg_pong; diff --git a/fuzz/src/msg_targets/utils.rs b/fuzz/src/msg_targets/utils.rs index 6125e5afd61..c7c97bf1d65 100644 --- a/fuzz/src/msg_targets/utils.rs +++ b/fuzz/src/msg_targets/utils.rs @@ -23,6 +23,7 @@ impl Writer for VecWriter { // Tests a message that must survive roundtrip exactly, though may not empty the read buffer // entirely #[macro_export] +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_msg { ($MsgType: path, $data: ident) => { { @@ -43,6 +44,7 @@ macro_rules! test_msg { // Tests a message that may lose data on roundtrip, but shoulnd't lose data compared to our // re-serialization. #[macro_export] +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_msg_simple { ($MsgType: path, $data: ident) => { { @@ -64,6 +66,7 @@ macro_rules! test_msg_simple { // Tests a message that must survive roundtrip exactly, and must exactly empty the read buffer and // split it back out on re-serialization. #[macro_export] +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_msg_exact { ($MsgType: path, $data: ident) => { { @@ -81,6 +84,7 @@ macro_rules! test_msg_exact { // Tests a message that must survive roundtrip exactly, modulo one "hole" which may be set to 0s on // re-serialization. #[macro_export] +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_msg_hole { ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => { { diff --git a/fuzz/src/peer_crypt.rs b/fuzz/src/peer_crypt.rs index 0d200d83a19..0914d29e702 100644 --- a/fuzz/src/peer_crypt.rs +++ b/fuzz/src/peer_crypt.rs @@ -1,10 +1,11 @@ use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor; -use bitcoin::secp256k1::key::{PublicKey,SecretKey}; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; use utils::test_logger; #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] fn slice_to_be16(v: &[u8]) -> u16 { ((v[0] as u16) << 8*1) | ((v[1] as u16) << 8*0) @@ -13,6 +14,7 @@ fn slice_to_be16(v: &[u8]) -> u16 { #[inline] pub fn do_test(data: &[u8]) { let mut read_pos = 0; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_slice { ($len: expr) => { { @@ -43,7 +45,7 @@ pub fn do_test(data: &[u8]) { let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key); crypter.get_act_one(); match crypter.process_act_two(get_slice!(50), &our_network_key) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return, } assert!(crypter.is_ready_for_encryption()); @@ -51,11 +53,11 @@ pub fn do_test(data: &[u8]) { } else { let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key); match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return, } match crypter.process_act_three(get_slice!(66)) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return, } assert!(crypter.is_ready_for_encryption()); @@ -65,12 +67,12 @@ pub fn do_test(data: &[u8]) { if get_slice!(1)[0] == 0 { crypter.encrypt_message(get_slice!(slice_to_be16(get_slice!(2)))); } else { - let len = match crypter.decrypt_length_header(get_slice!(16+2)) { + let len = match crypter.decrypt_length_header(get_slice!(16 + 2)) { Ok(len) => len, Err(_) => return, }; match crypter.decrypt_message(get_slice!(len as usize + 16)) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return, } } diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 2ff160e4ec8..f61928f84cd 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -1,14 +1,14 @@ -use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::block::Block; +use bitcoin::blockdata::script::{Builder, Script}; use bitcoin::blockdata::transaction::Transaction; -use bitcoin::hash_types::{Txid, BlockHash}; +use bitcoin::hash_types::{BlockHash, Txid}; -use lightning::chain::chaininterface::{ChainError,ChainWatchInterface}; +use lightning::chain::chaininterface::{ChainError, ChainWatchInterface}; use lightning::ln::channelmanager::ChannelDetails; use lightning::ln::features::InitFeatures; use lightning::ln::msgs; use lightning::ln::msgs::RoutingMessageHandler; -use lightning::ln::router::{Router, RouteHint}; +use lightning::ln::router::{RouteHint, Router}; use lightning::util::logger::Logger; use lightning::util::ser::Readable; @@ -16,36 +16,38 @@ use bitcoin::secp256k1::key::PublicKey; use utils::test_logger; -use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] pub fn slice_to_be16(v: &[u8]) -> u16 { - ((v[0] as u16) << 8*1) | - ((v[1] as u16) << 8*0) + ((v[0] as u16) << 8 * 1) | + ((v[1] as u16) << 8 * 0) } #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] pub fn slice_to_be32(v: &[u8]) -> u32 { - ((v[0] as u32) << 8*3) | - ((v[1] as u32) << 8*2) | - ((v[2] as u32) << 8*1) | - ((v[3] as u32) << 8*0) + ((v[0] as u32) << 8 * 3) | + ((v[1] as u32) << 8 * 2) | + ((v[2] as u32) << 8 * 1) | + ((v[3] as u32) << 8 * 0) } #[inline] +#[cfg_attr(rustfmt, rustfmt_skip)] pub fn slice_to_be64(v: &[u8]) -> u64 { - ((v[0] as u64) << 8*7) | - ((v[1] as u64) << 8*6) | - ((v[2] as u64) << 8*5) | - ((v[3] as u64) << 8*4) | - ((v[4] as u64) << 8*3) | - ((v[5] as u64) << 8*2) | - ((v[6] as u64) << 8*1) | - ((v[7] as u64) << 8*0) + ((v[0] as u64) << 8 * 7) | + ((v[1] as u64) << 8 * 6) | + ((v[2] as u64) << 8 * 5) | + ((v[3] as u64) << 8 * 4) | + ((v[4] as u64) << 8 * 3) | + ((v[5] as u64) << 8 * 2) | + ((v[6] as u64) << 8 * 1) | + ((v[7] as u64) << 8 * 0) } - struct InputData { data: Vec, read_pos: AtomicUsize, @@ -72,15 +74,19 @@ struct DummyChainWatcher { } impl ChainWatchInterface for DummyChainWatcher { - fn install_watch_tx(&self, _txid: &Txid, _script_pub_key: &Script) { } - fn install_watch_outpoint(&self, _outpoint: (Txid, u32), _out_script: &Script) { } - fn watch_all_txn(&self) { } + fn install_watch_tx(&self, _txid: &Txid, _script_pub_key: &Script) {} + fn install_watch_outpoint(&self, _outpoint: (Txid, u32), _out_script: &Script) {} + fn watch_all_txn(&self) {} fn filter_block<'a>(&self, _block: &'a Block) -> (Vec<&'a Transaction>, Vec) { (Vec::new(), Vec::new()) } - fn reentered(&self) -> usize { 0 } + fn reentered(&self) -> usize { + 0 + } - fn get_chain_utxo(&self, _genesis_hash: BlockHash, _unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError> { + fn get_chain_utxo( + &self, _genesis_hash: BlockHash, _unspent_tx_output_identifier: u64, + ) -> Result<(Script, u64), ChainError> { match self.input.get_slice(2) { Some(&[0, _]) => Err(ChainError::NotSupported), Some(&[1, _]) => Err(ChainError::NotWatched), @@ -94,10 +100,8 @@ impl ChainWatchInterface for DummyChainWatcher { #[inline] pub fn do_test(data: &[u8], out: Out) { - let input = Arc::new(InputData { - data: data.to_vec(), - read_pos: AtomicUsize::new(0), - }); + let input = Arc::new(InputData { data: data.to_vec(), read_pos: AtomicUsize::new(0) }); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_slice_nonadvancing { ($len: expr) => { match input.get_slice_nonadvancing($len as usize) { @@ -106,6 +110,7 @@ pub fn do_test(data: &[u8], out: Out) { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_slice { ($len: expr) => { match input.get_slice($len as usize) { @@ -115,6 +120,7 @@ pub fn do_test(data: &[u8], out: Out) { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! decode_msg { ($MsgType: path, $len: expr) => {{ let mut reader = ::std::io::Cursor::new(get_slice!($len)); @@ -132,6 +138,7 @@ pub fn do_test(data: &[u8], out: Out) { }} } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! decode_msg_with_len16 { ($MsgType: path, $begin_len: expr, $excess: expr) => { { @@ -141,6 +148,7 @@ pub fn do_test(data: &[u8], out: Out) { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_pubkey { () => { match PublicKey::from_slice(get_slice!(33)) { @@ -151,9 +159,7 @@ pub fn do_test(data: &[u8], out: Out) { } let logger: Arc = Arc::new(test_logger::TestLogger::new("".to_owned(), out)); - let chain_monitor = Arc::new(DummyChainWatcher { - input: Arc::clone(&input), - }); + let chain_monitor = Arc::new(DummyChainWatcher { input: Arc::clone(&input) }); let our_pubkey = get_pubkey!(); let router = Router::new(our_pubkey.clone(), chain_monitor, Arc::clone(&logger)); @@ -162,29 +168,38 @@ pub fn do_test(data: &[u8], out: Out) { match get_slice!(1)[0] { 0 => { let start_len = slice_to_be16(&get_slice_nonadvancing!(64 + 2)[64..64 + 2]) as usize; - let addr_len = slice_to_be16(&get_slice_nonadvancing!(64+start_len+2 + 74)[64+start_len+2 + 72..64+start_len+2 + 74]); - if addr_len > (37+1)*4 { + let addr_len = slice_to_be16( + &get_slice_nonadvancing!(64 + start_len + 2 + 74)[64 + start_len + 2 + 72..64 + start_len + 2 + 74], + ); + if addr_len > (37 + 1) * 4 { return; } let _ = router.handle_node_announcement(&decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288)); - }, + } 1 => { - let _ = router.handle_channel_announcement(&decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4)); - }, + let _ = router.handle_channel_announcement(&decode_msg_with_len16!( + msgs::ChannelAnnouncement, + 64 * 4, + 32 + 8 + 33 * 4 + )); + } 2 => { let _ = router.handle_channel_update(&decode_msg!(msgs::ChannelUpdate, 128)); - }, - 3 => { - match get_slice!(1)[0] { - 0 => { - router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {msg: decode_msg!(msgs::ChannelUpdate, 128)}); - }, - 1 => { - let short_channel_id = slice_to_be64(get_slice!(8)); - router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed {short_channel_id, is_permanent: false}); - }, - _ => return, + } + 3 => match get_slice!(1)[0] { + 0 => { + router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { + msg: decode_msg!(msgs::ChannelUpdate, 128), + }); } + 1 => { + let short_channel_id = slice_to_be64(get_slice!(8)); + router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { + short_channel_id, + is_permanent: false, + }); + } + _ => return, }, 4 => { let target = get_pubkey!(); @@ -207,7 +222,7 @@ pub fn do_test(data: &[u8], out: Out) { }); } Some(&first_hops_vec[..]) - }, + } _ => return, }; let mut last_hops_vec = Vec::new(); @@ -225,8 +240,14 @@ pub fn do_test(data: &[u8], out: Out) { } &last_hops_vec[..] }; - let _ = router.get_route(&target, first_hops, last_hops, slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4))); - }, + let _ = router.get_route( + &target, + first_hops, + last_hops, + slice_to_be64(get_slice!(8)), + slice_to_be32(get_slice!(4)), + ); + } _ => return, } } diff --git a/fuzz/src/utils/test_logger.rs b/fuzz/src/utils/test_logger.rs index cd037ad8187..c1363b0b717 100644 --- a/fuzz/src/utils/test_logger.rs +++ b/fuzz/src/utils/test_logger.rs @@ -1,8 +1,8 @@ use lightning::util::logger::{Logger, Record}; -use std::sync::{Arc, Mutex}; use std::io::Write; +use std::sync::{Arc, Mutex}; -pub trait Output : Clone + Sync + Send + 'static { +pub trait Output: Clone + Sync + Send + 'static { fn locked_write(&self, data: &[u8]); } @@ -27,7 +27,7 @@ impl StringBuffer { } } -pub struct TestLogger { +pub struct TestLogger { id: String, out: Out, } @@ -43,13 +43,23 @@ impl<'a, Out: Output> Write for LockedWriteAdapter<'a, Out> { self.0.locked_write(data); Ok(data.len()) } - fn flush(&mut self) -> Result<(), std::io::Error> { Ok(()) } + fn flush(&mut self) -> Result<(), std::io::Error> { + Ok(()) + } } impl Logger for TestLogger { fn log(&self, record: &Record) { - write!(LockedWriteAdapter(&self.out), - "{:<5} {} [{} : {}, {}] {}\n", record.level.to_string(), self.id, record.module_path, record.file, record.line, record.args) - .unwrap(); + write!( + LockedWriteAdapter(&self.out), + "{:<5} {} [{} : {}, {}] {}\n", + record.level.to_string(), + self.id, + record.module_path, + record.file, + record.line, + record.args + ) + .unwrap(); } } diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index e460df25e54..79150a8f926 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -61,21 +61,21 @@ use bitcoin::secp256k1::key::PublicKey; +use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::net::TcpStream; -use tokio::{io, time}; use tokio::sync::mpsc; -use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; +use tokio::{io, time}; +use lightning::ln::msgs::ChannelMessageHandler; use lightning::ln::peer_handler; use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait; -use lightning::ln::msgs::ChannelMessageHandler; -use std::{task, thread}; +use std::hash::Hash; use std::net::SocketAddr; -use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::{Arc, Mutex, MutexGuard}; use std::time::Duration; -use std::hash::Hash; +use std::{task, thread}; static ID_COUNTER: AtomicU64 = AtomicU64::new(0); @@ -113,15 +113,19 @@ struct Connection { impl Connection { fn event_trigger(us: &mut MutexGuard) { match us.event_notify.try_send(()) { - Ok(_) => {}, + Ok(_) => {} Err(mpsc::error::TrySendError::Full(_)) => { // Ignore full errors as we just need the user to poll after this point, so if they // haven't received the last send yet, it doesn't matter. - }, - _ => panic!() + } + _ => panic!(), } } - async fn schedule_read(peer_manager: Arc>>, us: Arc>, mut reader: io::ReadHalf, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) { + async fn schedule_read( + peer_manager: Arc>>, us: Arc>, + mut reader: io::ReadHalf, mut read_wake_receiver: mpsc::Receiver<()>, + mut write_avail_receiver: mpsc::Receiver<()>, + ) { let peer_manager_ref = peer_manager.clone(); // 8KB is nice and big but also should never cause any issues with stack overflowing. let mut buf = [0; 8192]; @@ -138,9 +142,10 @@ impl Connection { // closed. // In this case, we do need to call peer_manager.socket_disconnected() to inform // Rust-Lightning that the socket is gone. - PeerDisconnected + PeerDisconnected, }; let disconnect_type = loop { + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! shutdown_socket { ($err: expr, $need_disconnect: expr) => { { println!("Disconnecting peer due to {}!", $err); @@ -148,6 +153,7 @@ impl Connection { } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! prepare_read_write_call { () => { { let mut us_lock = us.lock().unwrap(); @@ -201,7 +207,9 @@ impl Connection { } } - fn new(event_notify: mpsc::Sender<()>, stream: TcpStream) -> (io::ReadHalf, mpsc::Receiver<()>, mpsc::Receiver<()>, Arc>) { + fn new( + event_notify: mpsc::Sender<()>, stream: TcpStream, + ) -> (io::ReadHalf, mpsc::Receiver<()>, mpsc::Receiver<()>, Arc>) { // We only ever need a channel of depth 1 here: if we returned a non-full write to the // PeerManager, we will eventually get notified that there is room in the socket to write // new bytes, which will generate an event. That event will be popped off the queue before @@ -214,12 +222,21 @@ impl Connection { let (read_waker, read_receiver) = mpsc::channel(1); let (reader, writer) = io::split(stream); - (reader, write_receiver, read_receiver, - Arc::new(Mutex::new(Self { - writer: Some(writer), event_notify, write_avail, read_waker, read_paused: false, - block_disconnect_socket: false, rl_requested_disconnect: false, - id: ID_COUNTER.fetch_add(1, Ordering::AcqRel) - }))) + ( + reader, + write_receiver, + read_receiver, + Arc::new(Mutex::new(Self { + writer: Some(writer), + event_notify, + write_avail, + read_waker, + read_paused: false, + block_disconnect_socket: false, + rl_requested_disconnect: false, + id: ID_COUNTER.fetch_add(1, Ordering::AcqRel), + })), + ) } } @@ -231,7 +248,10 @@ impl Connection { /// not need to poll the provided future in order to make progress. /// /// See the module-level documentation for how to handle the event_notify mpsc::Sender. -pub fn setup_inbound(peer_manager: Arc>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future { +pub fn setup_inbound( + peer_manager: Arc>>, event_notify: mpsc::Sender<()>, + stream: TcpStream, +) -> impl std::future::Future { let (reader, write_receiver, read_receiver, us) = Connection::new(event_notify, stream); #[cfg(debug_assertions)] let last_us = Arc::clone(&us); @@ -270,12 +290,17 @@ pub fn setup_inbound(peer_manager: Arc(peer_manager: Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future { +pub fn setup_outbound( + peer_manager: Arc>>, event_notify: mpsc::Sender<()>, + their_node_id: PublicKey, stream: TcpStream, +) -> impl std::future::Future { let (reader, mut write_receiver, read_receiver, us) = Connection::new(event_notify, stream); #[cfg(debug_assertions)] let last_us = Arc::clone(&us); - let handle_opt = if let Ok(initial_send) = peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone())) { + let handle_opt = if let Ok(initial_send) = + peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone())) + { Some(tokio::spawn(async move { // We should essentially always have enough room in a TCP socket buffer to send the // initial 10s of bytes. However, tokio running in single-threaded mode will always @@ -291,7 +316,7 @@ pub fn setup_outbound(peer_manager: Arc { eprintln!("Failed to write first full message to socket!"); peer_manager.socket_disconnected(&SocketDescriptor::new(Arc::clone(&us))); @@ -299,7 +324,9 @@ pub fn setup_outbound(peer_manager: Arc(peer_manager: Arc(peer_manager: Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option> { +pub async fn connect_outbound( + peer_manager: Arc>>, event_notify: mpsc::Sender<()>, + their_node_id: PublicKey, addr: SocketAddr, +) -> Option> { if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), TcpStream::connect(&addr)).await { Some(setup_outbound(peer_manager, event_notify, their_node_id, stream)) - } else { None } + } else { + None + } } const SOCK_WAKER_VTABLE: task::RawWakerVTable = @@ -406,7 +438,9 @@ impl peer_handler::SocketDescriptor for SocketDescriptor { us.read_paused = false; let _ = us.read_waker.try_send(()); } - if data.is_empty() { return 0; } + if data.is_empty() { + return 0; + } let waker = unsafe { task::Waker::from_raw(write_avail_to_waker(&us.write_avail)) }; let mut ctx = task::Context::from_waker(&waker); let mut written_len = 0; @@ -418,8 +452,10 @@ impl peer_handler::SocketDescriptor for SocketDescriptor { // instead): assert_ne!(res, 0); written_len += res; - if written_len == data.len() { return written_len; } - }, + if written_len == data.len() { + return written_len; + } + } task::Poll::Ready(Err(e)) => { // The tokio docs *seem* to indicate this can't happen, and I certainly don't // know how to handle it if it does (cause it should be a Poll::Pending @@ -428,14 +464,14 @@ impl peer_handler::SocketDescriptor for SocketDescriptor { // Probably we've already been closed, just return what we have and let the // read thread handle closing logic. return written_len; - }, + } task::Poll::Pending => { // We're queued up for a write event now, but we need to make sure we also // pause read given we're now waiting on the remote end to ACK (and in // accordance with the send_data() docs). us.read_paused = true; return written_len; - }, + } } } } @@ -448,7 +484,9 @@ impl peer_handler::SocketDescriptor for SocketDescriptor { // Wake up the sending thread, assuming it is still alive let _ = us.write_avail.try_send(()); // Happy-path return: - if !us.block_disconnect_socket { return; } + if !us.block_disconnect_socket { + return; + } } while self.conn.lock().unwrap().block_disconnect_socket { thread::yield_now(); @@ -457,10 +495,7 @@ impl peer_handler::SocketDescriptor for SocketDescriptor { } impl Clone for SocketDescriptor { fn clone(&self) -> Self { - Self { - conn: Arc::clone(&self.conn), - id: self.id, - } + Self { conn: Arc::clone(&self.conn), id: self.id } } } impl Eq for SocketDescriptor {} @@ -477,11 +512,11 @@ impl Hash for SocketDescriptor { #[cfg(test)] mod tests { + use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; use lightning::ln::features::*; use lightning::ln::msgs::*; use lightning::ln::peer_handler::{MessageHandler, PeerManager}; use lightning::util::events::*; - use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; use tokio::sync::mpsc; @@ -492,28 +527,54 @@ mod tests { pub struct TestLogger(); impl lightning::util::logger::Logger for TestLogger { fn log(&self, record: &lightning::util::logger::Record) { - println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args); + println!( + "{:<5} [{} : {}, {}] {}", + record.level.to_string(), + record.module_path, + record.file, + record.line, + record.args + ); } } - struct MsgHandler{ + struct MsgHandler { expected_pubkey: PublicKey, pubkey_connected: mpsc::Sender<()>, pubkey_disconnected: mpsc::Sender<()>, msg_events: Mutex>, } impl RoutingMessageHandler for MsgHandler { - fn handle_node_announcement(&self, _msg: &NodeAnnouncement) -> Result { Ok(false) } - fn handle_channel_announcement(&self, _msg: &ChannelAnnouncement) -> Result { Ok(false) } - fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result { Ok(false) } - fn handle_htlc_fail_channel_update(&self, _update: &HTLCFailChannelUpdate) { } - fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(ChannelAnnouncement, Option, Option)> { Vec::new() } - fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec { Vec::new() } - fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool { false } + fn handle_node_announcement(&self, _msg: &NodeAnnouncement) -> Result { + Ok(false) + } + fn handle_channel_announcement(&self, _msg: &ChannelAnnouncement) -> Result { + Ok(false) + } + fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result { + Ok(false) + } + fn handle_htlc_fail_channel_update(&self, _update: &HTLCFailChannelUpdate) {} + fn get_next_channel_announcements( + &self, _starting_point: u64, _batch_amount: u8, + ) -> Vec<(ChannelAnnouncement, Option, Option)> { + Vec::new() + } + fn get_next_node_announcements( + &self, _starting_point: Option<&PublicKey>, _batch_amount: u8, + ) -> Vec { + Vec::new() + } + fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool { + false + } } impl ChannelMessageHandler for MsgHandler { fn handle_open_channel(&self, _their_node_id: &PublicKey, _their_features: InitFeatures, _msg: &OpenChannel) {} - fn handle_accept_channel(&self, _their_node_id: &PublicKey, _their_features: InitFeatures, _msg: &AcceptChannel) {} + fn handle_accept_channel( + &self, _their_node_id: &PublicKey, _their_features: InitFeatures, _msg: &AcceptChannel, + ) { + } fn handle_funding_created(&self, _their_node_id: &PublicKey, _msg: &FundingCreated) {} fn handle_funding_signed(&self, _their_node_id: &PublicKey, _msg: &FundingSigned) {} fn handle_funding_locked(&self, _their_node_id: &PublicKey, _msg: &FundingLocked) {} @@ -563,10 +624,15 @@ mod tests { pubkey_disconnected: a_disconnected_sender, msg_events: Mutex::new(Vec::new()), }); - let a_manager = Arc::new(PeerManager::new(MessageHandler { - chan_handler: Arc::clone(&a_handler), - route_handler: Arc::clone(&a_handler) as Arc, - }, a_key.clone(), &[1; 32], Arc::new(TestLogger()))); + let a_manager = Arc::new(PeerManager::new( + MessageHandler { + chan_handler: Arc::clone(&a_handler), + route_handler: Arc::clone(&a_handler) as Arc, + }, + a_key.clone(), + &[1; 32], + Arc::new(TestLogger()), + )); let (b_connected_sender, mut b_connected) = mpsc::channel(1); let (b_disconnected_sender, mut b_disconnected) = mpsc::channel(1); @@ -576,10 +642,15 @@ mod tests { pubkey_disconnected: b_disconnected_sender, msg_events: Mutex::new(Vec::new()), }); - let b_manager = Arc::new(PeerManager::new(MessageHandler { - chan_handler: Arc::clone(&b_handler), - route_handler: Arc::clone(&b_handler) as Arc, - }, b_key.clone(), &[2; 32], Arc::new(TestLogger()))); + let b_manager = Arc::new(PeerManager::new( + MessageHandler { + chan_handler: Arc::clone(&b_handler), + route_handler: Arc::clone(&b_handler) as Arc, + }, + b_key.clone(), + &[2; 32], + Arc::new(TestLogger()), + )); // We bind on localhost, hoping the environment is properly configured with a local // address. This may not always be the case in containers and the like, so if this test is @@ -591,18 +662,27 @@ mod tests { (std::net::TcpStream::connect("127.0.0.1:9999").unwrap(), listener.accept().unwrap().0) } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:46926") { (std::net::TcpStream::connect("127.0.0.1:46926").unwrap(), listener.accept().unwrap().0) - } else { panic!("Failed to bind to v4 localhost on common ports"); }; + } else { + panic!("Failed to bind to v4 localhost on common ports"); + }; let (sender, _receiver) = mpsc::channel(2); - let fut_a = super::setup_outbound(Arc::clone(&a_manager), sender.clone(), b_pub, tokio::net::TcpStream::from_std(conn_a).unwrap()); + let fut_a = super::setup_outbound( + Arc::clone(&a_manager), + sender.clone(), + b_pub, + tokio::net::TcpStream::from_std(conn_a).unwrap(), + ); let fut_b = super::setup_inbound(b_manager, sender, tokio::net::TcpStream::from_std(conn_b).unwrap()); tokio::time::timeout(Duration::from_secs(10), a_connected.recv()).await.unwrap(); tokio::time::timeout(Duration::from_secs(1), b_connected.recv()).await.unwrap(); - a_handler.msg_events.lock().unwrap().push(MessageSendEvent::HandleError { - node_id: b_pub, action: ErrorAction::DisconnectPeer { msg: None } - }); + a_handler + .msg_events + .lock() + .unwrap() + .push(MessageSendEvent::HandleError { node_id: b_pub, action: ErrorAction::DisconnectPeer { msg: None } }); assert!(a_disconnected.try_recv().is_err()); assert!(b_disconnected.try_recv().is_err()); diff --git a/lightning/src/chain/chaininterface.rs b/lightning/src/chain/chaininterface.rs index 814193af003..84de64c4768 100644 --- a/lightning/src/chain/chaininterface.rs +++ b/lightning/src/chain/chaininterface.rs @@ -5,21 +5,21 @@ //! disconnections, transaction broadcasting, and feerate information requests. use bitcoin::blockdata::block::{Block, BlockHeader}; -use bitcoin::blockdata::transaction::Transaction; -use bitcoin::blockdata::script::Script; use bitcoin::blockdata::constants::genesis_block; -use bitcoin::util::hash::BitcoinHash; +use bitcoin::blockdata::script::Script; +use bitcoin::blockdata::transaction::Transaction; +use bitcoin::hash_types::{BlockHash, Txid}; use bitcoin::network::constants::Network; -use bitcoin::hash_types::{Txid, BlockHash}; +use bitcoin::util::hash::BitcoinHash; use util::logger::Logger; -use std::sync::{Mutex, MutexGuard, Arc}; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::collections::HashSet; -use std::ops::Deref; use std::marker::PhantomData; +use std::ops::Deref; use std::ptr; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex, MutexGuard}; /// Used to give chain error details upstream #[derive(Clone)] @@ -53,7 +53,9 @@ pub trait ChainWatchInterface: Sync + Send { /// short_channel_id (aka unspent_tx_output_identier). For BTC/tBTC channels the top three /// bytes are the block height, the next 3 the transaction index within the block, and the /// final two the output within the transaction. - fn get_chain_utxo(&self, genesis_hash: BlockHash, unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError>; + fn get_chain_utxo( + &self, genesis_hash: BlockHash, unspent_tx_output_identifier: u64, + ) -> Result<(Script, u64), ChainError>; /// Gets the list of transactions and transaction indices that the ChainWatchInterface is /// watching for. @@ -88,7 +90,9 @@ pub trait ChainListener: Sync + Send { /// /// This also means those counting confirmations using block_connected callbacks should watch /// for duplicate headers and not count them towards confirmations! - fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]); + fn block_connected( + &self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32], + ); /// Notifies a listener that a block was disconnected. /// Unlike block_connected, this *must* never be called twice for the same disconnect event. /// Height must be the one of the block which was disconnected (not new height of the best chain) @@ -145,17 +149,15 @@ pub struct ChainWatchedUtil { impl ChainWatchedUtil { /// Constructs an empty (watches nothing) ChainWatchedUtil pub fn new() -> Self { - Self { - watch_all: false, - watched_txn: HashSet::new(), - watched_outpoints: HashSet::new(), - } + Self { watch_all: false, watched_txn: HashSet::new(), watched_outpoints: HashSet::new() } } /// Registers a tx for monitoring, returning true if it was a new tx and false if we'd already /// been watching for it. pub fn register_tx(&mut self, txid: &Txid, script_pub_key: &Script) -> bool { - if self.watch_all { return false; } + if self.watch_all { + return false; + } #[cfg(test)] { self.watched_txn.insert((txid.clone(), script_pub_key.clone())) @@ -170,14 +172,18 @@ impl ChainWatchedUtil { /// Registers an outpoint for monitoring, returning true if it was a new outpoint and false if /// we'd already been watching for it pub fn register_outpoint(&mut self, outpoint: (Txid, u32), _script_pub_key: &Script) -> bool { - if self.watch_all { return false; } + if self.watch_all { + return false; + } self.watched_outpoints.insert(outpoint) } /// Sets us to match all transactions, returning true if this is a new setting and false if /// we'd already been set to match everything. pub fn watch_all(&mut self) -> bool { - if self.watch_all { return false; } + if self.watch_all { + return false; + } self.watch_all = true; true } @@ -247,11 +253,7 @@ pub struct BlockNotifier<'a, CL: Deref + 'a> { impl<'a, CL: Deref + 'a> BlockNotifier<'a, CL> { /// Constructs a new BlockNotifier without any listeners. pub fn new(chain_monitor: Arc) -> BlockNotifier<'a, CL> { - BlockNotifier { - listeners: Mutex::new(Vec::new()), - chain_monitor, - phantom: PhantomData, - } + BlockNotifier { listeners: Mutex::new(Vec::new()), chain_monitor, phantom: PhantomData } } /// Register the given listener to receive events. @@ -269,7 +271,7 @@ impl<'a, CL: Deref + 'a> BlockNotifier<'a, CL> { let mut vec = self.listeners.lock().unwrap(); // item is a ref to an abstract thing that dereferences to a ChainListener, // so dereference it twice to get the ChainListener itself - vec.retain(|item | !ptr::eq(&(**item), &(*listener))); + vec.retain(|item| !ptr::eq(&(**item), &(*listener))); } /// Notify listeners that a block was connected given a full, unfiltered block. @@ -280,7 +282,8 @@ impl<'a, CL: Deref + 'a> BlockNotifier<'a, CL> { let mut reentered = true; while reentered { let (matched, matched_index) = self.chain_monitor.filter_block(block); - reentered = self.block_connected_checked(&block.header, height, matched.as_slice(), matched_index.as_slice()); + reentered = + self.block_connected_checked(&block.header, height, matched.as_slice(), matched_index.as_slice()); } } @@ -290,7 +293,9 @@ impl<'a, CL: Deref + 'a> BlockNotifier<'a, CL> { /// Returns true if notified listeners registered additional watch data (implying that the /// block must be re-scanned and this function called again prior to further block_connected /// calls, see ChainListener::block_connected for more info). - pub fn block_connected_checked(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> bool { + pub fn block_connected_checked( + &self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32], + ) -> bool { let last_seen = self.chain_monitor.reentered(); let listeners = self.listeners.lock().unwrap(); @@ -325,8 +330,7 @@ pub struct ChainWatchInterfaceUtil { #[cfg(test)] impl PartialEq for ChainWatchInterfaceUtil { fn eq(&self, o: &Self) -> bool { - self.network == o.network && - *self.watched.lock().unwrap() == *o.watched.lock().unwrap() + self.network == o.network && *self.watched.lock().unwrap() == *o.watched.lock().unwrap() } } @@ -353,7 +357,9 @@ impl ChainWatchInterface for ChainWatchInterfaceUtil { } } - fn get_chain_utxo(&self, genesis_hash: BlockHash, _unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError> { + fn get_chain_utxo( + &self, genesis_hash: BlockHash, _unspent_tx_output_identifier: u64, + ) -> Result<(Script, u64), ChainError> { if genesis_hash != genesis_block(self.network).header.bitcoin_hash() { return Err(ChainError::NotWatched); } @@ -384,17 +390,17 @@ impl ChainWatchInterfaceUtil { /// Creates a new ChainWatchInterfaceUtil for the given network pub fn new(network: Network, logger: Arc) -> ChainWatchInterfaceUtil { ChainWatchInterfaceUtil { - network: network, + network, watched: Mutex::new(ChainWatchedUtil::new()), reentered: AtomicUsize::new(1), - logger: logger, + logger, } } /// Checks if a given transaction matches the current filter. pub fn does_match_tx(&self, tx: &Transaction) -> bool { let watched = self.watched.lock().unwrap(); - self.does_match_tx_unguarded (tx, &watched) + self.does_match_tx_unguarded(tx, &watched) } fn does_match_tx_unguarded(&self, tx: &Transaction, watched: &MutexGuard) -> bool { @@ -404,8 +410,8 @@ impl ChainWatchInterfaceUtil { #[cfg(test)] mod tests { - use ln::functional_test_utils::{create_chanmon_cfgs, create_node_cfgs}; use super::{BlockNotifier, ChainListener}; + use ln::functional_test_utils::{create_chanmon_cfgs, create_node_cfgs}; use std::ptr; #[test] diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index ce865107abc..c75ca645581 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -2,35 +2,37 @@ //! spendable on-chain outputs which the user owns and is responsible for using just as any other //! on-chain output which is theirs. -use bitcoin::blockdata::transaction::{Transaction, OutPoint, TxOut}; -use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::opcodes; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut}; use bitcoin::network::constants::Network; -use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber}; use bitcoin::util::bip143; +use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey}; -use bitcoin::hashes::{Hash, HashEngine}; -use bitcoin::hashes::sha256::HashEngine as Sha256State; +use bitcoin::hash_types::WPubkeyHash; use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::sha256::HashEngine as Sha256State; use bitcoin::hashes::sha256d::Hash as Sha256dHash; -use bitcoin::hash_types::WPubkeyHash; +use bitcoin::hashes::{Hash, HashEngine}; -use bitcoin::secp256k1::key::{SecretKey, PublicKey}; -use bitcoin::secp256k1::{Secp256k1, Signature, Signing}; use bitcoin::secp256k1; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; +use bitcoin::secp256k1::{Secp256k1, Signature, Signing}; use util::byte_utils; use util::logger::Logger; -use util::ser::{Writeable, Writer, Readable}; +use util::ser::{Readable, Writeable, Writer}; use ln::chan_utils; -use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction}; +use ln::chan_utils::{ + make_funding_redeemscript, ChannelPublicKeys, HTLCOutputInCommitment, LocalCommitmentTransaction, TxCreationKeys, +}; use ln::msgs; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::io::Error; use ln::msgs::DecodeError; +use std::io::Error; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; /// When on-chain outputs are created by rust-lightning (which our counterparty is not able to /// claim at any point in the future) an event is generated which you must track and be able to @@ -86,7 +88,7 @@ pub enum SpendableOutputDescriptor { key: SecretKey, /// The output which is reference by the given outpoint output: TxOut, - } + }, } impl Writeable for SpendableOutputDescriptor { @@ -96,21 +98,27 @@ impl Writeable for SpendableOutputDescriptor { 0u8.write(writer)?; outpoint.write(writer)?; output.write(writer)?; - }, - &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref key, ref witness_script, ref to_self_delay, ref output } => { + } + &SpendableOutputDescriptor::DynamicOutputP2WSH { + ref outpoint, + ref key, + ref witness_script, + ref to_self_delay, + ref output, + } => { 1u8.write(writer)?; outpoint.write(writer)?; key.write(writer)?; witness_script.write(writer)?; to_self_delay.write(writer)?; output.write(writer)?; - }, + } &SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => { 2u8.write(writer)?; outpoint.write(writer)?; key.write(writer)?; output.write(writer)?; - }, + } } Ok(()) } @@ -143,7 +151,7 @@ impl Readable for SpendableOutputDescriptor { /// A trait to describe an object which can get user secrets and key material. pub trait KeysInterface: Send + Sync { /// A type which implements ChannelKeys which will be returned by get_channel_keys. - type ChanKeySigner : ChannelKeys; + type ChanKeySigner: ChannelKeys; /// Get node secret key (aka node_id or network_key) fn get_node_secret(&self) -> SecretKey; @@ -189,7 +197,7 @@ pub trait KeysInterface: Send + Sync { // routine). // TODO: We should remove Clone by instead requesting a new ChannelKeys copy when we create // ChannelMonitors instead of expecting to clone the one out of the Channel into the monitors. -pub trait ChannelKeys : Send+Clone { +pub trait ChannelKeys: Send + Clone { /// Gets the private key for the anchor tx fn funding_key<'a>(&'a self) -> &'a SecretKey; /// Gets the local secret key for blinded revocation pubkey @@ -213,7 +221,10 @@ pub trait ChannelKeys : Send+Clone { // TODO: Document the things someone using this interface should enforce before signing. // TODO: Add more input vars to enable better checking (preferably removing commitment_tx and // making the callee generate it via some util function we expose)! - fn sign_remote_commitment(&self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()>; + fn sign_remote_commitment( + &self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, + htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1, + ) -> Result<(Signature, Vec), ()>; /// Create a signature for a local commitment transaction. This will only ever be called with /// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees @@ -221,14 +232,18 @@ pub trait ChannelKeys : Send+Clone { // // TODO: Document the things someone using this interface should enforce before signing. // TODO: Add more input vars to enable better checking (preferably removing commitment_tx and - fn sign_local_commitment(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1) -> Result; + fn sign_local_commitment( + &self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1, + ) -> Result; /// Same as sign_local_commitment, but exists only for tests to get access to local commitment /// transactions which will be broadcasted later, after the channel has moved on to a newer /// state. Thus, needs its own method as sign_local_commitment may enforce that we only ever /// get called once. #[cfg(test)] - fn unsafe_sign_local_commitment(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1) -> Result; + fn unsafe_sign_local_commitment( + &self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1, + ) -> Result; /// Create a signature for each HTLC transaction spending a local commitment transaction. /// @@ -243,13 +258,17 @@ pub trait ChannelKeys : Send+Clone { /// (implying they were considered dust at the time the commitment transaction was negotiated), /// a corresponding None should be included in the return value. All other positions in the /// return value must contain a signature. - fn sign_local_commitment_htlc_transactions(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1) -> Result>, ()>; + fn sign_local_commitment_htlc_transactions( + &self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1, + ) -> Result>, ()>; /// Create a signature for a (proposed) closing transaction. /// /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have /// chosen to forgo their output as dust. - fn sign_closing_transaction(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1) -> Result; + fn sign_closing_transaction( + &self, closing_tx: &Transaction, secp_ctx: &Secp256k1, + ) -> Result; /// Signs a channel announcement message with our funding key, proving it comes from one /// of the channel participants. @@ -257,7 +276,9 @@ pub trait ChannelKeys : Send+Clone { /// Note that if this fails or is rejected, the channel will not be publicly announced and /// our counterparty may (though likely will not) close the channel on us for violating the /// protocol. - fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1) -> Result; + fn sign_channel_announcement( + &self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1, + ) -> Result; /// Set the remote channel basepoints. This is done immediately on incoming channels /// and as soon as the channel is accepted on outgoing channels. @@ -292,18 +313,18 @@ pub struct InMemoryChannelKeys { impl InMemoryChannelKeys { /// Create a new InMemoryChannelKeys pub fn new( - secp_ctx: &Secp256k1, - funding_key: SecretKey, - revocation_base_key: SecretKey, - payment_base_key: SecretKey, - delayed_payment_base_key: SecretKey, - htlc_base_key: SecretKey, - commitment_seed: [u8; 32], - channel_value_satoshis: u64) -> InMemoryChannelKeys { - let local_channel_pubkeys = - InMemoryChannelKeys::make_local_keys(secp_ctx, &funding_key, &revocation_base_key, - &payment_base_key, &delayed_payment_base_key, - &htlc_base_key); + secp_ctx: &Secp256k1, funding_key: SecretKey, revocation_base_key: SecretKey, payment_base_key: SecretKey, + delayed_payment_base_key: SecretKey, htlc_base_key: SecretKey, commitment_seed: [u8; 32], + channel_value_satoshis: u64, + ) -> InMemoryChannelKeys { + let local_channel_pubkeys = InMemoryChannelKeys::make_local_keys( + secp_ctx, + &funding_key, + &revocation_base_key, + &payment_base_key, + &delayed_payment_base_key, + &htlc_base_key, + ); InMemoryChannelKeys { funding_key, revocation_base_key, @@ -317,12 +338,10 @@ impl InMemoryChannelKeys { } } - fn make_local_keys(secp_ctx: &Secp256k1, - funding_key: &SecretKey, - revocation_base_key: &SecretKey, - payment_base_key: &SecretKey, - delayed_payment_base_key: &SecretKey, - htlc_base_key: &SecretKey) -> ChannelPublicKeys { + fn make_local_keys( + secp_ctx: &Secp256k1, funding_key: &SecretKey, revocation_base_key: &SecretKey, + payment_base_key: &SecretKey, delayed_payment_base_key: &SecretKey, htlc_base_key: &SecretKey, + ) -> ChannelPublicKeys { let from_secret = |s: &SecretKey| PublicKey::from_secret_key(secp_ctx, s); ChannelPublicKeys { funding_pubkey: from_secret(&funding_key), @@ -335,22 +354,49 @@ impl InMemoryChannelKeys { } impl ChannelKeys for InMemoryChannelKeys { - fn funding_key(&self) -> &SecretKey { &self.funding_key } - fn revocation_base_key(&self) -> &SecretKey { &self.revocation_base_key } - fn payment_base_key(&self) -> &SecretKey { &self.payment_base_key } - fn delayed_payment_base_key(&self) -> &SecretKey { &self.delayed_payment_base_key } - fn htlc_base_key(&self) -> &SecretKey { &self.htlc_base_key } - fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed } - fn pubkeys<'a>(&'a self) -> &'a ChannelPublicKeys { &self.local_channel_pubkeys } + fn funding_key(&self) -> &SecretKey { + &self.funding_key + } + fn revocation_base_key(&self) -> &SecretKey { + &self.revocation_base_key + } + fn payment_base_key(&self) -> &SecretKey { + &self.payment_base_key + } + fn delayed_payment_base_key(&self) -> &SecretKey { + &self.delayed_payment_base_key + } + fn htlc_base_key(&self) -> &SecretKey { + &self.htlc_base_key + } + fn commitment_seed(&self) -> &[u8; 32] { + &self.commitment_seed + } + fn pubkeys<'a>(&'a self) -> &'a ChannelPublicKeys { + &self.local_channel_pubkeys + } - fn sign_remote_commitment(&self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { - if commitment_tx.input.len() != 1 { return Err(()); } + fn sign_remote_commitment( + &self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, + htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1, + ) -> Result<(Signature, Vec), ()> { + if commitment_tx.input.len() != 1 { + return Err(()); + } let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); - let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); - let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); - - let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]); + let remote_channel_pubkeys = + self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); + let channel_funding_redeemscript = + make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); + + let commitment_sighash = hash_to_message!( + &bip143::SighashComponents::new(&commitment_tx).sighash_all( + &commitment_tx.input[0], + &channel_funding_redeemscript, + self.channel_value_satoshis + )[..] + ); let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key); let commitment_txid = commitment_tx.txid(); @@ -358,13 +404,27 @@ impl ChannelKeys for InMemoryChannelKeys { let mut htlc_sigs = Vec::with_capacity(htlcs.len()); for ref htlc in htlcs { if let Some(_) = htlc.transaction_output_index { - let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, feerate_per_kw, to_self_delay, htlc, &keys.a_delayed_payment_key, &keys.revocation_key); + let htlc_tx = chan_utils::build_htlc_transaction( + &commitment_txid, + feerate_per_kw, + to_self_delay, + htlc, + &keys.a_delayed_payment_key, + &keys.revocation_key, + ); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys); - let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]); - let our_htlc_key = match chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key) { - Ok(s) => s, - Err(_) => return Err(()), - }; + let htlc_sighash = hash_to_message!( + &bip143::SighashComponents::new(&htlc_tx).sighash_all( + &htlc_tx.input[0], + &htlc_redeemscript, + htlc.amount_msat / 1000 + )[..] + ); + let our_htlc_key = + match chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key) { + Ok(s) => s, + Err(_) => return Err(()), + }; htlc_sigs.push(secp_ctx.sign(&htlc_sighash, &our_htlc_key)); } } @@ -372,42 +432,79 @@ impl ChannelKeys for InMemoryChannelKeys { Ok((commitment_sig, htlc_sigs)) } - fn sign_local_commitment(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1) -> Result { + fn sign_local_commitment( + &self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1, + ) -> Result { let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); - let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); - let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); - - Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx)) + let remote_channel_pubkeys = + self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); + let channel_funding_redeemscript = + make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); + + Ok(local_commitment_tx.get_local_sig( + &self.funding_key, + &channel_funding_redeemscript, + self.channel_value_satoshis, + secp_ctx, + )) } #[cfg(test)] - fn unsafe_sign_local_commitment(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1) -> Result { + fn unsafe_sign_local_commitment( + &self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1, + ) -> Result { let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); - let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); - let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); - - Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx)) + let remote_channel_pubkeys = + self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); + let channel_funding_redeemscript = + make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); + + Ok(local_commitment_tx.get_local_sig( + &self.funding_key, + &channel_funding_redeemscript, + self.channel_value_satoshis, + secp_ctx, + )) } - fn sign_local_commitment_htlc_transactions(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1) -> Result>, ()> { + fn sign_local_commitment_htlc_transactions( + &self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1, + ) -> Result>, ()> { local_commitment_tx.get_htlc_sigs(&self.htlc_base_key, local_csv, secp_ctx) } - fn sign_closing_transaction(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1) -> Result { - if closing_tx.input.len() != 1 { return Err(()); } - if closing_tx.input[0].witness.len() != 0 { return Err(()); } - if closing_tx.output.len() > 2 { return Err(()); } + fn sign_closing_transaction( + &self, closing_tx: &Transaction, secp_ctx: &Secp256k1, + ) -> Result { + if closing_tx.input.len() != 1 { + return Err(()); + } + if closing_tx.input[0].witness.len() != 0 { + return Err(()); + } + if closing_tx.output.len() > 2 { + return Err(()); + } - let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); + let remote_channel_pubkeys = + self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing"); let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); - let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); - - let sighash = hash_to_message!(&bip143::SighashComponents::new(closing_tx) - .sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]); + let channel_funding_redeemscript = + make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey); + + let sighash = hash_to_message!( + &bip143::SighashComponents::new(closing_tx).sighash_all( + &closing_tx.input[0], + &channel_funding_redeemscript, + self.channel_value_satoshis + )[..] + ); Ok(secp_ctx.sign(&sighash, &self.funding_key)) } - fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1) -> Result { + fn sign_channel_announcement( + &self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1, + ) -> Result { let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]); Ok(secp_ctx.sign(&msghash, &self.funding_key)) } @@ -444,10 +541,14 @@ impl Readable for InMemoryChannelKeys { let remote_channel_pubkeys = Readable::read(reader)?; let channel_value_satoshis = Readable::read(reader)?; let secp_ctx = Secp256k1::signing_only(); - let local_channel_pubkeys = - InMemoryChannelKeys::make_local_keys(&secp_ctx, &funding_key, &revocation_base_key, - &payment_base_key, &delayed_payment_base_key, - &htlc_base_key); + let local_channel_pubkeys = InMemoryChannelKeys::make_local_keys( + &secp_ctx, + &funding_key, + &revocation_base_key, + &payment_base_key, + &delayed_payment_base_key, + &htlc_base_key, + ); Ok(InMemoryChannelKeys { funding_key, @@ -458,7 +559,7 @@ impl Readable for InMemoryChannelKeys { commitment_seed, channel_value_satoshis, local_channel_pubkeys, - remote_channel_pubkeys + remote_channel_pubkeys, }) } } @@ -506,27 +607,43 @@ impl KeysManager { /// Note that until the 0.1 release there is no guarantee of backward compatibility between /// versions. Once the library is more fully supported, the docs will be updated to include a /// detailed description of the guarantee. - pub fn new(seed: &[u8; 32], network: Network, logger: Arc, starting_time_secs: u64, starting_time_nanos: u32) -> KeysManager { + pub fn new( + seed: &[u8; 32], network: Network, logger: Arc, starting_time_secs: u64, starting_time_nanos: u32, + ) -> KeysManager { let secp_ctx = Secp256k1::signing_only(); match ExtendedPrivKey::new_master(network.clone(), seed) { Ok(master_key) => { - let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap()).expect("Your RNG is busted").private_key.key; - let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1).unwrap()) { - Ok(destination_key) => { - let wpubkey_hash = WPubkeyHash::hash(&ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.to_bytes()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0) - .push_slice(&wpubkey_hash.into_inner()) - .into_script() - }, - Err(_) => panic!("Your RNG is busted"), - }; + let node_secret = master_key + .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap()) + .expect("Your RNG is busted") + .private_key + .key; + let destination_script = + match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1).unwrap()) { + Ok(destination_key) => { + let wpubkey_hash = WPubkeyHash::hash( + &ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.to_bytes(), + ); + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&wpubkey_hash.into_inner()) + .into_script() + } + Err(_) => panic!("Your RNG is busted"), + }; let shutdown_pubkey = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2).unwrap()) { Ok(shutdown_key) => ExtendedPubKey::from_private(&secp_ctx, &shutdown_key).public_key.key, Err(_) => panic!("Your RNG is busted"), }; - let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()).expect("Your RNG is busted"); - let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted"); - let channel_id_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted"); + let channel_master_key = master_key + .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()) + .expect("Your RNG is busted"); + let session_master_key = master_key + .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()) + .expect("Your RNG is busted"); + let channel_id_master_key = master_key + .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()) + .expect("Your RNG is busted"); let mut unique_start = Sha256::engine(); unique_start.input(&byte_utils::be64_to_array(starting_time_secs)); @@ -548,7 +665,7 @@ impl KeysManager { unique_start, logger, } - }, + } Err(_) => panic!("Your rng is busted"), } } @@ -576,7 +693,10 @@ impl KeysInterface for KeysManager { let mut sha = self.unique_start.clone(); let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel); - let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted"); + let child_privkey = self + .channel_master_key + .ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")) + .expect("Your RNG is busted"); sha.input(&child_privkey.private_key.key[..]); let seed = Sha256::from_engine(sha).into_inner(); @@ -587,6 +707,7 @@ impl KeysInterface for KeysManager { sha.input(&b"commitment seed"[..]); Sha256::from_engine(sha).into_inner() }; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! key_step { ($info: expr, $prev_key: expr) => {{ let mut sha = Sha256::engine(); @@ -610,7 +731,7 @@ impl KeysInterface for KeysManager { delayed_payment_base_key, htlc_base_key, commitment_seed, - channel_value_satoshis + channel_value_satoshis, ) } @@ -618,7 +739,10 @@ impl KeysInterface for KeysManager { let mut sha = self.unique_start.clone(); let child_ix = self.session_child_index.fetch_add(1, Ordering::AcqRel); - let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted"); + let child_privkey = self + .session_master_key + .ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")) + .expect("Your RNG is busted"); sha.input(&child_privkey.private_key.key[..]); let mut rng_seed = sha.clone(); @@ -626,15 +750,20 @@ impl KeysInterface for KeysManager { // ChaCha so it is another step harder to break. rng_seed.input(b"RNG Seed Salt"); sha.input(b"Session Key Salt"); - (SecretKey::from_slice(&Sha256::from_engine(sha).into_inner()).expect("Your RNG is busted"), - Sha256::from_engine(rng_seed).into_inner()) + ( + SecretKey::from_slice(&Sha256::from_engine(sha).into_inner()).expect("Your RNG is busted"), + Sha256::from_engine(rng_seed).into_inner(), + ) } fn get_channel_id(&self) -> [u8; 32] { let mut sha = self.unique_start.clone(); let child_ix = self.channel_id_child_index.fetch_add(1, Ordering::AcqRel); - let child_privkey = self.channel_id_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted"); + let child_privkey = self + .channel_id_master_key + .ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")) + .expect("Your RNG is busted"); sha.input(&child_privkey.private_key.key[..]); Sha256::from_engine(sha).into_inner() diff --git a/lightning/src/chain/mod.rs b/lightning/src/chain/mod.rs index ffa5ed968be..7eb0d950048 100644 --- a/lightning/src/chain/mod.rs +++ b/lightning/src/chain/mod.rs @@ -1,5 +1,5 @@ //! Structs and traits which allow other parts of rust-lightning to interact with the blockchain. pub mod chaininterface; -pub mod transaction; pub mod keysinterface; +pub mod transaction; diff --git a/lightning/src/chain/transaction.rs b/lightning/src/chain/transaction.rs index 33b9c7244a3..a271a6ea00e 100644 --- a/lightning/src/chain/transaction.rs +++ b/lightning/src/chain/transaction.rs @@ -1,7 +1,7 @@ //! Contains simple structs describing parts of transactions on the chain. -use bitcoin::hash_types::Txid; use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint; +use bitcoin::hash_types::Txid; /// A reference to a transaction output. /// @@ -32,10 +32,7 @@ impl OutPoint { /// Converts this OutPoint into the OutPoint field as used by rust-bitcoin pub fn into_bitcoin_outpoint(self) -> BitcoinOutPoint { - BitcoinOutPoint { - txid: self.txid, - vout: self.index as u32, - } + BitcoinOutPoint { txid: self.txid, vout: self.index as u32 } } } @@ -53,13 +50,13 @@ mod tests { #[test] fn test_channel_id_calculation() { let tx: Transaction = encode::deserialize(&hex::decode("020000000001010e0adef48412e4361325ac1c6e36411299ab09d4f083b9d8ddb55fbc06e1b0c00000000000feffffff0220a1070000000000220020f81d95e040bd0a493e38bae27bff52fe2bb58b93b293eb579c01c31b05c5af1dc072cfee54a3000016001434b1d6211af5551905dc2642d05f5b04d25a8fe80247304402207f570e3f0de50546aad25a872e3df059d277e776dda4269fa0d2cc8c2ee6ec9a022054e7fae5ca94d47534c86705857c24ceea3ad51c69dd6051c5850304880fc43a012103cb11a1bacc223d98d91f1946c6752e358a5eb1a1c983b3e6fb15378f453b76bd00000000").unwrap()[..]).unwrap(); - assert_eq!(&OutPoint { - txid: tx.txid(), - index: 0 - }.to_channel_id(), &hex::decode("3e88dd7165faf7be58b3c5bb2c9c452aebef682807ea57080f62e6f6e113c25e").unwrap()[..]); - assert_eq!(&OutPoint { - txid: tx.txid(), - index: 1 - }.to_channel_id(), &hex::decode("3e88dd7165faf7be58b3c5bb2c9c452aebef682807ea57080f62e6f6e113c25f").unwrap()[..]); + assert_eq!( + &OutPoint { txid: tx.txid(), index: 0 }.to_channel_id(), + &hex::decode("3e88dd7165faf7be58b3c5bb2c9c452aebef682807ea57080f62e6f6e113c25e").unwrap()[..] + ); + assert_eq!( + &OutPoint { txid: tx.txid(), index: 1 }.to_channel_id(), + &hex::decode("3e88dd7165faf7be58b3c5bb2c9c452aebef682807ea57080f62e6f6e113c25f").unwrap()[..] + ); } } diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index 039f2f3aca1..755c2172239 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -11,7 +11,6 @@ #![cfg_attr(not(feature = "fuzztarget"), deny(missing_docs))] #![forbid(unsafe_code)] - // In general, rust is absolutely horrid at supporting users doing things like, // for example, compiling Rust code for real environments. Disable useless lints // that don't do anything but annoy us and cant actually ever be resolved. @@ -19,8 +18,10 @@ #![allow(ellipsis_inclusive_range_patterns)] extern crate bitcoin; -#[cfg(test)] extern crate rand; -#[cfg(test)] extern crate hex; +#[cfg(test)] +extern crate hex; +#[cfg(test)] +extern crate rand; #[macro_use] pub mod util; diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 9be3f38a78e..b0abe531658 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -2,29 +2,29 @@ //! largely of interest for those implementing chain::keysinterface::ChannelKeys message signing //! by hand. -use bitcoin::blockdata::script::{Script,Builder}; use bitcoin::blockdata::opcodes; -use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, SigHashType}; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::transaction::{OutPoint, SigHashType, Transaction, TxIn, TxOut}; use bitcoin::consensus::encode::{self, Decodable, Encodable}; use bitcoin::util::bip143; -use bitcoin::hashes::{Hash, HashEngine}; -use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hash_types::{PubkeyHash, Txid}; use bitcoin::hashes::ripemd160::Hash as Ripemd160; -use bitcoin::hash_types::{Txid, PubkeyHash}; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::{Hash, HashEngine}; use ln::channelmanager::{PaymentHash, PaymentPreimage}; use ln::msgs::DecodeError; -use util::ser::{Readable, Writeable, Writer, WriterWriteAdaptor}; use util::byte_utils; +use util::ser::{Readable, Writeable, Writer, WriterWriteAdaptor}; -use bitcoin::secp256k1::key::{SecretKey, PublicKey}; -use bitcoin::secp256k1::{Secp256k1, Signature}; use bitcoin::secp256k1; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; +use bitcoin::secp256k1::{Secp256k1, Signature}; use std::{cmp, mem}; -const MAX_ALLOC_SIZE: usize = 64*1024; +const MAX_ALLOC_SIZE: usize = 64 * 1024; pub(super) const HTLC_SUCCESS_TX_WEIGHT: u64 = 703; pub(super) const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663; @@ -32,12 +32,12 @@ pub(super) const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663; #[derive(PartialEq)] pub(crate) enum HTLCType { AcceptedHTLC, - OfferedHTLC + OfferedHTLC, } impl HTLCType { /// Check if a given tx witnessScript len matchs one of a pre-signed HTLC - pub(crate) fn scriptlen_to_htlctype(witness_script_len: usize) -> Option { + pub(crate) fn scriptlen_to_htlctype(witness_script_len: usize) -> Option { if witness_script_len == 133 { Some(HTLCType::OfferedHTLC) } else if witness_script_len >= 136 && witness_script_len <= 139 { @@ -75,9 +75,11 @@ pub(super) struct CounterpartyCommitmentSecrets { impl PartialEq for CounterpartyCommitmentSecrets { fn eq(&self, other: &Self) -> bool { - for (&(ref secret, ref idx), &(ref o_secret, ref o_idx)) in self.old_secrets.iter().zip(other.old_secrets.iter()) { + for (&(ref secret, ref idx), &(ref o_secret, ref o_idx)) in + self.old_secrets.iter().zip(other.old_secrets.iter()) + { if secret != o_secret || idx != o_idx { - return false + return false; } } true @@ -86,14 +88,14 @@ impl PartialEq for CounterpartyCommitmentSecrets { impl CounterpartyCommitmentSecrets { pub(super) fn new() -> Self { - Self { old_secrets: [([0; 32], 1 << 48); 49], } + Self { old_secrets: [([0; 32], 1 << 48); 49] } } #[inline] fn place_secret(idx: u64) -> u8 { for i in 0..48 { if idx & (1 << i) == (1 << i) { - return i + return i; } } 48 @@ -142,7 +144,7 @@ impl CounterpartyCommitmentSecrets { pub(super) fn get_secret(&self, idx: u64) -> Option<[u8; 32]> { for i in 0..self.old_secrets.len() { if (idx & (!((1 << i) - 1))) == self.old_secrets[i].1 { - return Some(Self::derive_secret(self.old_secrets[i].0, i as u8, idx)) + return Some(Self::derive_secret(self.old_secrets[i].0, i as u8, idx)); } } assert!(idx < self.get_min_seen_secret()); @@ -173,7 +175,9 @@ impl Readable for CounterpartyCommitmentSecrets { /// Derives a per-commitment-transaction private key (eg an htlc key or payment key) from the base /// private key for that type of key and the per_commitment_point (available in TxCreationKeys) -pub fn derive_private_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result { +pub fn derive_private_key( + secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_secret: &SecretKey, +) -> Result { let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); sha.input(&PublicKey::from_secret_key(&secp_ctx, &base_secret).serialize()); @@ -184,7 +188,9 @@ pub fn derive_private_key(secp_ctx: &Secp256k1, per_co Ok(key) } -pub(super) fn derive_public_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result { +pub(super) fn derive_public_key( + secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, base_point: &PublicKey, +) -> Result { let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); sha.input(&base_point.serialize()); @@ -197,7 +203,9 @@ pub(super) fn derive_public_key(secp_ctx: &Secp256k1, /// Derives a revocation key from its constituent parts. /// Note that this is infallible iff we trust that at least one of the two input keys are randomly /// generated (ie our own). -pub(super) fn derive_private_revocation_key(secp_ctx: &Secp256k1, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result { +pub(super) fn derive_private_revocation_key( + secp_ctx: &Secp256k1, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey, +) -> Result { let revocation_base_point = PublicKey::from_secret_key(&secp_ctx, &revocation_base_secret); let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret); @@ -224,7 +232,9 @@ pub(super) fn derive_private_revocation_key(secp_ctx: &Se Ok(part_a) } -pub(super) fn derive_public_revocation_key(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result { +pub(super) fn derive_public_revocation_key( + secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey, +) -> Result { let rev_append_commit_hash_key = { let mut sha = Sha256::engine(); sha.input(&revocation_base_point.serialize()); @@ -299,9 +309,11 @@ impl_writeable!(ChannelPublicKeys, 33*5, { htlc_basepoint }); - impl TxCreationKeys { - pub(crate) fn new(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_payment_base: &PublicKey, b_htlc_base: &PublicKey) -> Result { + pub(crate) fn new( + secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, + a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_payment_base: &PublicKey, b_htlc_base: &PublicKey, + ) -> Result { Ok(TxCreationKeys { per_commitment_point: per_commitment_point.clone(), revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?, @@ -315,17 +327,20 @@ impl TxCreationKeys { /// Gets the "to_local" output redeemscript, ie the script which is time-locked or spendable by /// the revocation key -pub(super) fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script { - Builder::new().push_opcode(opcodes::all::OP_IF) - .push_slice(&revocation_key.serialize()) - .push_opcode(opcodes::all::OP_ELSE) - .push_int(to_self_delay as i64) - .push_opcode(opcodes::all::OP_CSV) - .push_opcode(opcodes::all::OP_DROP) - .push_slice(&delayed_payment_key.serialize()) - .push_opcode(opcodes::all::OP_ENDIF) - .push_opcode(opcodes::all::OP_CHECKSIG) - .into_script() +pub(super) fn get_revokeable_redeemscript( + revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey, +) -> Script { + Builder::new() + .push_opcode(opcodes::all::OP_IF) + .push_slice(&revocation_key.serialize()) + .push_opcode(opcodes::all::OP_ELSE) + .push_int(to_self_delay as i64) + .push_opcode(opcodes::all::OP_CSV) + .push_opcode(opcodes::all::OP_DROP) + .push_slice(&delayed_payment_key.serialize()) + .push_opcode(opcodes::all::OP_ENDIF) + .push_opcode(opcodes::all::OP_CHECKSIG) + .into_script() } #[derive(Clone, PartialEq)] @@ -358,67 +373,71 @@ impl_writeable!(HTLCOutputInCommitment, 1 + 8 + 4 + 32 + 5, { }); #[inline] -pub(crate) fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, a_htlc_key: &PublicKey, b_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script { +pub(crate) fn get_htlc_redeemscript_with_explicit_keys( + htlc: &HTLCOutputInCommitment, a_htlc_key: &PublicKey, b_htlc_key: &PublicKey, revocation_key: &PublicKey, +) -> Script { let payment_hash160 = Ripemd160::hash(&htlc.payment_hash.0[..]).into_inner(); if htlc.offered { - Builder::new().push_opcode(opcodes::all::OP_DUP) - .push_opcode(opcodes::all::OP_HASH160) - .push_slice(&PubkeyHash::hash(&revocation_key.serialize())[..]) - .push_opcode(opcodes::all::OP_EQUAL) - .push_opcode(opcodes::all::OP_IF) - .push_opcode(opcodes::all::OP_CHECKSIG) - .push_opcode(opcodes::all::OP_ELSE) - .push_slice(&b_htlc_key.serialize()[..]) - .push_opcode(opcodes::all::OP_SWAP) - .push_opcode(opcodes::all::OP_SIZE) - .push_int(32) - .push_opcode(opcodes::all::OP_EQUAL) - .push_opcode(opcodes::all::OP_NOTIF) - .push_opcode(opcodes::all::OP_DROP) - .push_int(2) - .push_opcode(opcodes::all::OP_SWAP) - .push_slice(&a_htlc_key.serialize()[..]) - .push_int(2) - .push_opcode(opcodes::all::OP_CHECKMULTISIG) - .push_opcode(opcodes::all::OP_ELSE) - .push_opcode(opcodes::all::OP_HASH160) - .push_slice(&payment_hash160) - .push_opcode(opcodes::all::OP_EQUALVERIFY) - .push_opcode(opcodes::all::OP_CHECKSIG) - .push_opcode(opcodes::all::OP_ENDIF) - .push_opcode(opcodes::all::OP_ENDIF) - .into_script() + Builder::new() + .push_opcode(opcodes::all::OP_DUP) + .push_opcode(opcodes::all::OP_HASH160) + .push_slice(&PubkeyHash::hash(&revocation_key.serialize())[..]) + .push_opcode(opcodes::all::OP_EQUAL) + .push_opcode(opcodes::all::OP_IF) + .push_opcode(opcodes::all::OP_CHECKSIG) + .push_opcode(opcodes::all::OP_ELSE) + .push_slice(&b_htlc_key.serialize()[..]) + .push_opcode(opcodes::all::OP_SWAP) + .push_opcode(opcodes::all::OP_SIZE) + .push_int(32) + .push_opcode(opcodes::all::OP_EQUAL) + .push_opcode(opcodes::all::OP_NOTIF) + .push_opcode(opcodes::all::OP_DROP) + .push_int(2) + .push_opcode(opcodes::all::OP_SWAP) + .push_slice(&a_htlc_key.serialize()[..]) + .push_int(2) + .push_opcode(opcodes::all::OP_CHECKMULTISIG) + .push_opcode(opcodes::all::OP_ELSE) + .push_opcode(opcodes::all::OP_HASH160) + .push_slice(&payment_hash160) + .push_opcode(opcodes::all::OP_EQUALVERIFY) + .push_opcode(opcodes::all::OP_CHECKSIG) + .push_opcode(opcodes::all::OP_ENDIF) + .push_opcode(opcodes::all::OP_ENDIF) + .into_script() } else { - Builder::new().push_opcode(opcodes::all::OP_DUP) - .push_opcode(opcodes::all::OP_HASH160) - .push_slice(&PubkeyHash::hash(&revocation_key.serialize())[..]) - .push_opcode(opcodes::all::OP_EQUAL) - .push_opcode(opcodes::all::OP_IF) - .push_opcode(opcodes::all::OP_CHECKSIG) - .push_opcode(opcodes::all::OP_ELSE) - .push_slice(&b_htlc_key.serialize()[..]) - .push_opcode(opcodes::all::OP_SWAP) - .push_opcode(opcodes::all::OP_SIZE) - .push_int(32) - .push_opcode(opcodes::all::OP_EQUAL) - .push_opcode(opcodes::all::OP_IF) - .push_opcode(opcodes::all::OP_HASH160) - .push_slice(&payment_hash160) - .push_opcode(opcodes::all::OP_EQUALVERIFY) - .push_int(2) - .push_opcode(opcodes::all::OP_SWAP) - .push_slice(&a_htlc_key.serialize()[..]) - .push_int(2) - .push_opcode(opcodes::all::OP_CHECKMULTISIG) - .push_opcode(opcodes::all::OP_ELSE) - .push_opcode(opcodes::all::OP_DROP) - .push_int(htlc.cltv_expiry as i64) - .push_opcode(opcodes::all::OP_CLTV) - .push_opcode(opcodes::all::OP_DROP) - .push_opcode(opcodes::all::OP_CHECKSIG) - .push_opcode(opcodes::all::OP_ENDIF) - .push_opcode(opcodes::all::OP_ENDIF) - .into_script() + Builder::new() + .push_opcode(opcodes::all::OP_DUP) + .push_opcode(opcodes::all::OP_HASH160) + .push_slice(&PubkeyHash::hash(&revocation_key.serialize())[..]) + .push_opcode(opcodes::all::OP_EQUAL) + .push_opcode(opcodes::all::OP_IF) + .push_opcode(opcodes::all::OP_CHECKSIG) + .push_opcode(opcodes::all::OP_ELSE) + .push_slice(&b_htlc_key.serialize()[..]) + .push_opcode(opcodes::all::OP_SWAP) + .push_opcode(opcodes::all::OP_SIZE) + .push_int(32) + .push_opcode(opcodes::all::OP_EQUAL) + .push_opcode(opcodes::all::OP_IF) + .push_opcode(opcodes::all::OP_HASH160) + .push_slice(&payment_hash160) + .push_opcode(opcodes::all::OP_EQUALVERIFY) + .push_int(2) + .push_opcode(opcodes::all::OP_SWAP) + .push_slice(&a_htlc_key.serialize()[..]) + .push_int(2) + .push_opcode(opcodes::all::OP_CHECKMULTISIG) + .push_opcode(opcodes::all::OP_ELSE) + .push_opcode(opcodes::all::OP_DROP) + .push_int(htlc.cltv_expiry as i64) + .push_opcode(opcodes::all::OP_CLTV) + .push_opcode(opcodes::all::OP_DROP) + .push_opcode(opcodes::all::OP_CHECKSIG) + .push_opcode(opcodes::all::OP_ENDIF) + .push_opcode(opcodes::all::OP_ENDIF) + .into_script() } } @@ -437,16 +456,20 @@ pub fn make_funding_redeemscript(a: &PublicKey, b: &PublicKey) -> Script { let builder = Builder::new().push_opcode(opcodes::all::OP_PUSHNUM_2); if our_funding_key[..] < their_funding_key[..] { - builder.push_slice(&our_funding_key) - .push_slice(&their_funding_key) + builder.push_slice(&our_funding_key).push_slice(&their_funding_key) } else { - builder.push_slice(&their_funding_key) - .push_slice(&our_funding_key) - }.push_opcode(opcodes::all::OP_PUSHNUM_2).push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script() + builder.push_slice(&their_funding_key).push_slice(&our_funding_key) + } + .push_opcode(opcodes::all::OP_PUSHNUM_2) + .push_opcode(opcodes::all::OP_CHECKMULTISIG) + .into_script() } /// panics if htlc.transaction_output_index.is_none()! -pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u64, to_self_delay: u16, htlc: &HTLCOutputInCommitment, a_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction { +pub fn build_htlc_transaction( + prev_hash: &Txid, feerate_per_kw: u64, to_self_delay: u16, htlc: &HTLCOutputInCommitment, + a_delayed_payment_key: &PublicKey, revocation_key: &PublicKey, +) -> Transaction { let mut txins: Vec = Vec::new(); txins.push(TxIn { previous_output: OutPoint { @@ -459,23 +482,18 @@ pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u64, to_self_del }); let total_fee = if htlc.offered { - feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000 - } else { - feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000 - }; + feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000 + } else { + feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000 + }; let mut txouts: Vec = Vec::new(); txouts.push(TxOut { script_pubkey: get_revokeable_redeemscript(revocation_key, to_self_delay, a_delayed_payment_key).to_v0_p2wsh(), - value: htlc.amount_msat / 1000 - total_fee //TODO: BOLT 3 does not specify if we should add amount_msat before dividing or if we should divide by 1000 before subtracting (as we do here) + value: htlc.amount_msat / 1000 - total_fee, //TODO: BOLT 3 does not specify if we should add amount_msat before dividing or if we should divide by 1000 before subtracting (as we do here) }); - Transaction { - version: 2, - lock_time: if htlc.offered { htlc.cltv_expiry } else { 0 }, - input: txins, - output: txouts, - } + Transaction { version: 2, lock_time: if htlc.offered { htlc.cltv_expiry } else { 0 }, input: txins, output: txouts } } #[derive(Clone)] @@ -512,43 +530,43 @@ impl LocalCommitmentTransaction { #[cfg(test)] pub fn dummy() -> Self { let dummy_input = TxIn { - previous_output: OutPoint { - txid: Default::default(), - vout: 0, - }, + previous_output: OutPoint { txid: Default::default(), vout: 0 }, script_sig: Default::default(), sequence: 0, - witness: vec![] + witness: vec![], }; let dummy_key = PublicKey::from_secret_key(&Secp256k1::new(), &SecretKey::from_slice(&[42; 32]).unwrap()); - let dummy_sig = Secp256k1::new().sign(&secp256k1::Message::from_slice(&[42; 32]).unwrap(), &SecretKey::from_slice(&[42; 32]).unwrap()); + let dummy_sig = Secp256k1::new() + .sign(&secp256k1::Message::from_slice(&[42; 32]).unwrap(), &SecretKey::from_slice(&[42; 32]).unwrap()); Self { - unsigned_tx: Transaction { - version: 2, - input: vec![dummy_input], - output: Vec::new(), - lock_time: 0, - }, + unsigned_tx: Transaction { version: 2, input: vec![dummy_input], output: Vec::new(), lock_time: 0 }, their_sig: dummy_sig, our_sig_first: false, local_keys: TxCreationKeys { - per_commitment_point: dummy_key.clone(), - revocation_key: dummy_key.clone(), - a_htlc_key: dummy_key.clone(), - b_htlc_key: dummy_key.clone(), - a_delayed_payment_key: dummy_key.clone(), - b_payment_key: dummy_key.clone(), - }, + per_commitment_point: dummy_key.clone(), + revocation_key: dummy_key.clone(), + a_htlc_key: dummy_key.clone(), + b_htlc_key: dummy_key.clone(), + a_delayed_payment_key: dummy_key.clone(), + b_payment_key: dummy_key.clone(), + }, feerate_per_kw: 0, - per_htlc: Vec::new() + per_htlc: Vec::new(), } } /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction, /// remote signature and both parties keys - pub(crate) fn new_missing_local_sig(unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u64, htlc_data: Vec<(HTLCOutputInCommitment, Option)>) -> LocalCommitmentTransaction { - if unsigned_tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); } - if unsigned_tx.input[0].witness.len() != 0 { panic!("Tried to store a signed commitment transaction?"); } + pub(crate) fn new_missing_local_sig( + unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, + local_keys: TxCreationKeys, feerate_per_kw: u64, htlc_data: Vec<(HTLCOutputInCommitment, Option)>, + ) -> LocalCommitmentTransaction { + if unsigned_tx.input.len() != 1 { + panic!("Tried to store a commitment transaction that had input count != 1!"); + } + if unsigned_tx.input[0].witness.len() != 0 { + panic!("Tried to store a signed commitment transaction?"); + } Self { unsigned_tx, @@ -574,9 +592,17 @@ impl LocalCommitmentTransaction { /// between your own funding key and your counterparty's. Currently, this is provided in /// ChannelKeys::sign_local_commitment() calls directly. /// Channel value is amount locked in funding_outpoint. - pub fn get_local_sig(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1) -> Signature { - let sighash = hash_to_message!(&bip143::SighashComponents::new(&self.unsigned_tx) - .sighash_all(&self.unsigned_tx.input[0], funding_redeemscript, channel_value_satoshis)[..]); + pub fn get_local_sig( + &self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, + secp_ctx: &Secp256k1, + ) -> Signature { + let sighash = hash_to_message!( + &bip143::SighashComponents::new(&self.unsigned_tx).sighash_all( + &self.unsigned_tx.input[0], + funding_redeemscript, + channel_value_satoshis + )[..] + ); secp_ctx.sign(&sighash, funding_key) } @@ -605,18 +631,39 @@ impl LocalCommitmentTransaction { /// The returned Vec has one entry for each HTLC, and in the same order. For HTLCs which were /// considered dust and not included, a None entry exists, for all others a signature is /// included. - pub fn get_htlc_sigs(&self, htlc_base_key: &SecretKey, local_csv: u16, secp_ctx: &Secp256k1) -> Result>, ()> { + pub fn get_htlc_sigs( + &self, htlc_base_key: &SecretKey, local_csv: u16, secp_ctx: &Secp256k1, + ) -> Result>, ()> { let txid = self.txid(); let mut ret = Vec::with_capacity(self.per_htlc.len()); - let our_htlc_key = derive_private_key(secp_ctx, &self.local_keys.per_commitment_point, htlc_base_key).map_err(|_| ())?; + let our_htlc_key = + derive_private_key(secp_ctx, &self.local_keys.per_commitment_point, htlc_base_key).map_err(|_| ())?; for this_htlc in self.per_htlc.iter() { if this_htlc.0.transaction_output_index.is_some() { - let htlc_tx = build_htlc_transaction(&txid, self.feerate_per_kw, local_csv, &this_htlc.0, &self.local_keys.a_delayed_payment_key, &self.local_keys.revocation_key); - - let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &self.local_keys.a_htlc_key, &self.local_keys.b_htlc_key, &self.local_keys.revocation_key); - - let sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, this_htlc.0.amount_msat / 1000)[..]); + let htlc_tx = build_htlc_transaction( + &txid, + self.feerate_per_kw, + local_csv, + &this_htlc.0, + &self.local_keys.a_delayed_payment_key, + &self.local_keys.revocation_key, + ); + + let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys( + &this_htlc.0, + &self.local_keys.a_htlc_key, + &self.local_keys.b_htlc_key, + &self.local_keys.revocation_key, + ); + + let sighash = hash_to_message!( + &bip143::SighashComponents::new(&htlc_tx).sighash_all( + &htlc_tx.input[0], + &htlc_redeemscript, + this_htlc.0.amount_msat / 1000 + )[..] + ); ret.push(Some(secp_ctx.sign(&sighash, &our_htlc_key))); } else { ret.push(None); @@ -626,21 +673,39 @@ impl LocalCommitmentTransaction { } /// Gets a signed HTLC transaction given a preimage (for !htlc.offered) and the local HTLC transaction signature. - pub(crate) fn get_signed_htlc_tx(&self, htlc_index: usize, signature: &Signature, preimage: &Option, local_csv: u16) -> Transaction { + pub(crate) fn get_signed_htlc_tx( + &self, htlc_index: usize, signature: &Signature, preimage: &Option, local_csv: u16, + ) -> Transaction { let txid = self.txid(); let this_htlc = &self.per_htlc[htlc_index]; assert!(this_htlc.0.transaction_output_index.is_some()); // if we don't have preimage for an HTLC-Success, we can't generate an HTLC transaction. - if !this_htlc.0.offered && preimage.is_none() { unreachable!(); } + if !this_htlc.0.offered && preimage.is_none() { + unreachable!(); + } // Further, we should never be provided the preimage for an HTLC-Timeout transaction. - if this_htlc.0.offered && preimage.is_some() { unreachable!(); } + if this_htlc.0.offered && preimage.is_some() { + unreachable!(); + } - let mut htlc_tx = build_htlc_transaction(&txid, self.feerate_per_kw, local_csv, &this_htlc.0, &self.local_keys.a_delayed_payment_key, &self.local_keys.revocation_key); + let mut htlc_tx = build_htlc_transaction( + &txid, + self.feerate_per_kw, + local_csv, + &this_htlc.0, + &self.local_keys.a_delayed_payment_key, + &self.local_keys.revocation_key, + ); // Channel should have checked that we have a remote signature for this HTLC at // creation, and we should have a sensible htlc transaction: assert!(this_htlc.1.is_some()); - let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &self.local_keys.a_htlc_key, &self.local_keys.b_htlc_key, &self.local_keys.revocation_key); + let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys( + &this_htlc.0, + &self.local_keys.a_htlc_key, + &self.local_keys.b_htlc_key, + &self.local_keys.revocation_key, + ); // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element. htlc_tx.input[0].witness.push(Vec::new()); @@ -701,7 +766,10 @@ impl Readable for LocalCommitmentTransaction { let local_keys = Readable::read(reader)?; let feerate_per_kw = Readable::read(reader)?; let htlcs_count: u64 = Readable::read(reader)?; - let mut per_htlc = Vec::with_capacity(cmp::min(htlcs_count as usize, MAX_ALLOC_SIZE / mem::size_of::<(HTLCOutputInCommitment, Option)>())); + let mut per_htlc = Vec::with_capacity(cmp::min( + htlcs_count as usize, + MAX_ALLOC_SIZE / mem::size_of::<(HTLCOutputInCommitment, Option)>(), + )); for _ in 0..htlcs_count { let htlc: HTLCOutputInCommitment = Readable::read(reader)?; let sigs = Readable::read(reader)?; @@ -712,14 +780,7 @@ impl Readable for LocalCommitmentTransaction { // Ensure tx didn't hit the 0-input ambiguity case. return Err(DecodeError::InvalidValue); } - Ok(Self { - unsigned_tx, - their_sig, - our_sig_first, - local_keys, - feerate_per_kw, - per_htlc, - }) + Ok(Self { unsigned_tx, their_sig, our_sig_first, local_keys, feerate_per_kw, per_htlc }) } } @@ -734,6 +795,7 @@ mod tests { let mut secrets: Vec<[u8; 32]> = Vec::new(); let mut monitor; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_secrets { () => { let mut idx = 281474976710655; @@ -752,42 +814,58 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap(), + ); monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap(), + ); monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap(), + ); monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap(), + ); monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); } @@ -798,12 +876,16 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); assert!(monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).is_err()); } @@ -813,22 +895,30 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("dddc3a8d14fddf2b68fa8c7fbad2748274937479dd0f8930d5ebb4ab6bd866a3").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("dddc3a8d14fddf2b68fa8c7fbad2748274937479dd0f8930d5ebb4ab6bd866a3").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); assert!(monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).is_err()); } @@ -838,22 +928,30 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c51a18b13e8527e579ec56365482c62f180b7d5760b46e9477dae59e87ed423a").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c51a18b13e8527e579ec56365482c62f180b7d5760b46e9477dae59e87ed423a").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); assert!(monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).is_err()); } @@ -863,42 +961,58 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("dddc3a8d14fddf2b68fa8c7fbad2748274937479dd0f8930d5ebb4ab6bd866a3").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("dddc3a8d14fddf2b68fa8c7fbad2748274937479dd0f8930d5ebb4ab6bd866a3").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c51a18b13e8527e579ec56365482c62f180b7d5760b46e9477dae59e87ed423a").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c51a18b13e8527e579ec56365482c62f180b7d5760b46e9477dae59e87ed423a").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("ba65d7b0ef55a3ba300d4e87af29868f394f8f138d78a7011669c79b37b936f4").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("ba65d7b0ef55a3ba300d4e87af29868f394f8f138d78a7011669c79b37b936f4").unwrap(), + ); monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap(), + ); monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap(), + ); monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap(), + ); monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap(), + ); assert!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).is_err()); } @@ -908,32 +1022,44 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("631373ad5f9ef654bb3dade742d09504c567edd24320d2fcd68e3cc47e2ff6a6").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("631373ad5f9ef654bb3dade742d09504c567edd24320d2fcd68e3cc47e2ff6a6").unwrap(), + ); monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap(), + ); assert!(monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).is_err()); } @@ -943,42 +1069,58 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("631373ad5f9ef654bb3dade742d09504c567edd24320d2fcd68e3cc47e2ff6a6").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("631373ad5f9ef654bb3dade742d09504c567edd24320d2fcd68e3cc47e2ff6a6").unwrap(), + ); monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("b7e76a83668bde38b373970155c868a653304308f9896692f904a23731224bb1").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("b7e76a83668bde38b373970155c868a653304308f9896692f904a23731224bb1").unwrap(), + ); monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap(), + ); monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap(), + ); assert!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).is_err()); } @@ -988,42 +1130,58 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap(), + ); monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap(), + ); monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("e7971de736e01da8ed58b94c2fc216cb1dca9e326f3a96e7194fe8ea8af6c0a3").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("e7971de736e01da8ed58b94c2fc216cb1dca9e326f3a96e7194fe8ea8af6c0a3").unwrap(), + ); monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap(), + ); assert!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).is_err()); } @@ -1033,42 +1191,58 @@ mod tests { secrets.clear(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap(), + ); monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap(), + ); monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap(), + ); monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap(), + ); monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap(), + ); monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap(), + ); monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap(), + ); monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap(); test_secrets!(); secrets.push([0; 32]); - secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex::decode("a7efbc61aac46d34f77778bac22c8a20c6a46ca460addc49009bda875ec88fa4").unwrap()); + secrets.last_mut().unwrap()[0..32].clone_from_slice( + &hex::decode("a7efbc61aac46d34f77778bac22c8a20c6a46ca460addc49009bda875ec88fa4").unwrap(), + ); assert!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).is_err()); } } diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 411c12d990d..d0304c033c7 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -4,13 +4,13 @@ //! here. See also the chanmon_fail_consistency fuzz test. use chain::transaction::OutPoint; -use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure}; +use ln::channelmanager::{PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, RAACommitmentOrder}; use ln::channelmonitor::ChannelMonitorUpdateErr; use ln::features::InitFeatures; use ln::msgs; use ln::msgs::{ChannelMessageHandler, ErrorAction, RoutingMessageHandler}; -use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; use util::errors::APIError; +use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; @@ -26,7 +26,10 @@ fn test_simple_monitor_permanent_update_fail() { let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (_, payment_hash_1) = get_payment_preimage_hash!(&nodes[0]); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::PermanentFailure); @@ -36,7 +39,7 @@ fn test_simple_monitor_permanent_update_fail() { let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 2); match events_1[0] { - MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + MessageSendEvent::BroadcastChannelUpdate { .. } => {} _ => panic!("Unexpected event"), }; match events_1[1] { @@ -59,12 +62,20 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(&nodes[0]); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &None), false, APIError::MonitorUpdateFailed, {}); + unwrap_send_err!( + nodes[0].node.send_payment(&route, payment_hash_1, &None), + false, + APIError::MonitorUpdateFailed, + {} + ); check_added_monitors!(nodes[0], 1); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); @@ -78,7 +89,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { } *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[0].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[0], 0); @@ -98,7 +110,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { assert_eq!(payment_hash_1, *payment_hash); assert_eq!(*payment_secret, None); assert_eq!(amt, 1000000); - }, + } _ => panic!("Unexpected event"), } @@ -107,7 +119,12 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { // Now set it to failed again... let (_, payment_hash_2) = get_payment_preimage_hash!(&nodes[0]); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &None), false, APIError::MonitorUpdateFailed, {}); + unwrap_send_err!( + nodes[0].node.send_payment(&route, payment_hash_2, &None), + false, + APIError::MonitorUpdateFailed, + {} + ); check_added_monitors!(nodes[0], 1); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); @@ -166,11 +183,19 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000); // Now try to send a second payment which will fail to send - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); - unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &None), false, APIError::MonitorUpdateFailed, {}); + unwrap_send_err!( + nodes[0].node.send_payment(&route, payment_hash_2, &None), + false, + APIError::MonitorUpdateFailed, + {} + ); check_added_monitors!(nodes[0], 1); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); @@ -184,7 +209,18 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { let events_2 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); let (bs_initial_fulfill, bs_initial_commitment_signed) = match events_2[0] { - MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => { + MessageSendEvent::UpdateHTLCs { + ref node_id, + updates: + msgs::CommitmentUpdate { + ref update_add_htlcs, + ref update_fulfill_htlcs, + ref update_fail_htlcs, + ref update_fail_malformed_htlcs, + ref update_fee, + ref commitment_signed, + }, + } => { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); assert!(update_add_htlcs.is_empty()); assert_eq!(update_fulfill_htlcs.len(), 1); @@ -199,18 +235,22 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { match events_3[0] { Event::PaymentSent { ref payment_preimage } => { assert_eq!(*payment_preimage, payment_preimage_1); - }, + } _ => panic!("Unexpected event"), } nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), commitment_signed); check_added_monitors!(nodes[0], 1); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Previous monitor update failure prevented generation of RAA".to_string(), 1); + nodes[0].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Previous monitor update failure prevented generation of RAA".to_string(), + 1, + ); } (update_fulfill_htlcs[0].clone(), commitment_signed.clone()) - }, + } _ => panic!("Unexpected event"), }; @@ -221,10 +261,12 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { // Now fix monitor updating... *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[0].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[0], 0); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! disconnect_reconnect_peers { () => { { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); @@ -285,18 +327,25 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { assert!(as_resp.1.is_none()); - nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_resp.2.as_ref().unwrap().update_fulfill_htlcs[0]); + nodes[0].node.handle_update_fulfill_htlc( + &nodes[1].node.get_our_node_id(), + &bs_resp.2.as_ref().unwrap().update_fulfill_htlcs[0], + ); let events_3 = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events_3.len(), 1); match events_3[0] { Event::PaymentSent { ref payment_preimage } => { assert_eq!(*payment_preimage, payment_preimage_1); - }, + } _ => panic!("Unexpected event"), } - nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_resp.2.as_ref().unwrap().commitment_signed); - let as_resp_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + nodes[0].node.handle_commitment_signed( + &nodes[1].node.get_our_node_id(), + &bs_resp.2.as_ref().unwrap().commitment_signed, + ); + let as_resp_raa = + get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); @@ -305,7 +354,8 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { } if disconnect_count & !disconnect_flags > 1 { - let (second_reestablish_1, second_reestablish_2, second_as_resp, second_bs_resp) = disconnect_reconnect_peers!(); + let (second_reestablish_1, second_reestablish_2, second_as_resp, second_bs_resp) = + disconnect_reconnect_peers!(); if (disconnect_count & 16) == 0 { assert!(reestablish_1 == second_reestablish_1); @@ -319,20 +369,24 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { } else { let mut events_4 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_4.len(), 2); - (SendEvent::from_event(events_4.remove(0)), match events_4[0] { - MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { - assert_eq!(*node_id, nodes[1].node.get_our_node_id()); - msg.clone() + ( + SendEvent::from_event(events_4.remove(0)), + match events_4[0] { + MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { + assert_eq!(*node_id, nodes[1].node.get_our_node_id()); + msg.clone() + } + _ => panic!("Unexpected event"), }, - _ => panic!("Unexpected event"), - }) + ) }; assert_eq!(payment_event.node_id, nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg); - let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + let bs_revoke_and_ack = + get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); // nodes[1] is awaiting an RAA from nodes[0] still so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); @@ -349,6 +403,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { let as_commitment_update; let bs_second_commitment_update; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! handle_bs_raa { () => { nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack); as_commitment_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); @@ -360,6 +415,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { check_added_monitors!(nodes[0], 1); } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! handle_initial_raa { () => { nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &initial_revoke_and_ack); bs_second_commitment_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); @@ -425,13 +481,17 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { } } - nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_update.commitment_signed); - let as_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + nodes[0] + .node + .handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_update.commitment_signed); + let as_revoke_and_ack = + get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_update.commitment_signed); - let bs_second_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + let bs_second_revoke_and_ack = + get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); @@ -452,7 +512,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { assert_eq!(payment_hash_2, *payment_hash); assert_eq!(*payment_secret, None); assert_eq!(amt, 1000000); - }, + } _ => panic!("Unexpected event"), } @@ -495,7 +555,10 @@ fn test_monitor_update_fail_cs() { let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -506,12 +569,17 @@ fn test_monitor_update_fail_cs() { *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &send_event.commitment_msg); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); let responses = nodes[1].node.get_and_clear_pending_msg_events(); @@ -522,7 +590,7 @@ fn test_monitor_update_fail_cs() { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &msg); check_added_monitors!(nodes[0], 1); - }, + } _ => panic!("Unexpected event"), } match responses[1] { @@ -537,15 +605,20 @@ fn test_monitor_update_fail_cs() { *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &updates.commitment_signed); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[0].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[0], 1); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - }, + } _ => panic!("Unexpected event"), } *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[0].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[0], 0); @@ -562,7 +635,7 @@ fn test_monitor_update_fail_cs() { assert_eq!(payment_hash, our_payment_hash); assert_eq!(payment_secret, None); assert_eq!(amt, 1000000); - }, + } _ => panic!("Unexpected event"), }; @@ -580,7 +653,10 @@ fn test_monitor_update_fail_no_rebroadcast() { let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_1, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -592,13 +668,18 @@ fn test_monitor_update_fail_no_rebroadcast() { *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &bs_raa); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); check_added_monitors!(nodes[1], 1); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 0); @@ -609,7 +690,7 @@ fn test_monitor_update_fail_no_rebroadcast() { match events[0] { Event::PaymentReceived { payment_hash, .. } => { assert_eq!(payment_hash, our_payment_hash); - }, + } _ => panic!("Unexpected event"), } @@ -628,13 +709,20 @@ fn test_monitor_update_raa_while_paused() { send_payment(&nodes[0], &[&nodes[1]], 5000000, 5_000_000); - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_1, our_payment_hash_1) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, our_payment_hash_1, &None).unwrap(); check_added_monitors!(nodes[0], 1); let send_event_1 = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0)); - let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[0].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[1].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); + let (payment_preimage_2, our_payment_hash_2) = get_payment_preimage_hash!(nodes[0]); nodes[1].node.send_payment(&route, our_payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[1], 1); @@ -649,16 +737,25 @@ fn test_monitor_update_raa_while_paused() { nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &send_event_2.msgs[0]); nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &send_event_2.commitment_msg); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[0].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[0], 1); nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_raa); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Previous monitor update failure prevented responses to RAA".to_string(), 1); + nodes[0].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Previous monitor update failure prevented responses to RAA".to_string(), + 1, + ); check_added_monitors!(nodes[0], 1); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[0].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[0], 0); @@ -717,13 +814,17 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { assert!(updates.update_fee.is_none()); nodes[1].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &updates.update_fail_htlcs[0]); - let bs_revoke_and_ack = commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false, true, false, true); + let bs_revoke_and_ack = + commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false, true, false, true); check_added_monitors!(nodes[0], 0); // While the second channel is AwaitingRAA, forward a second payment to get it into the // holding cell. let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); - let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[2].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -739,7 +840,11 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); nodes[1].node.handle_revoke_and_ack(&nodes[2].node.get_our_node_id(), &bs_revoke_and_ack); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); @@ -748,7 +853,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { // for forwarding. let (_, payment_hash_3) = get_payment_preimage_hash!(nodes[0]); - let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let vec = &Vec::new(); + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); nodes[0].node.send_payment(&route, payment_hash_3, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -775,10 +881,12 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { let msg_events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(msg_events.len(), 1); match msg_events[0] { - MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }} => { + MessageSendEvent::PaymentFailureNetworkUpdate { + update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }, + } => { assert_eq!(msg.contents.short_channel_id, chan_2.0.contents.short_channel_id); assert_eq!(msg.contents.flags & 2, 2); // temp disabled - }, + } _ => panic!("Unexpected event"), } @@ -787,15 +895,19 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { if let Event::PaymentFailed { payment_hash, rejected_by_dest, .. } = events[0] { assert_eq!(payment_hash, payment_hash_3); assert!(!rejected_by_dest); - } else { panic!("Unexpected event!"); } - }, + } else { + panic!("Unexpected event!"); + } + } _ => panic!("Unexpected event type!"), }; let (payment_preimage_4, payment_hash_4) = if test_ignore_second_cs { // Try to route another payment backwards from 2 to make sure 1 holds off on responding let (payment_preimage_4, payment_hash_4) = get_payment_preimage_hash!(nodes[0]); - let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[0].node.get_our_node_id(); + let vec = &Vec::new(); + let route = nodes[2].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); nodes[2].node.send_payment(&route, payment_hash_4, &None).unwrap(); check_added_monitors!(nodes[2], 1); @@ -804,16 +916,23 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { nodes[1].node.handle_commitment_signed(&nodes[2].node.get_our_node_id(), &send_event.commitment_msg); check_added_monitors!(nodes[1], 1); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Previous monitor update failure prevented generation of RAA".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Previous monitor update failure prevented generation of RAA".to_string(), + 1, + ); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); (Some(payment_preimage_4), Some(payment_hash_4)) - } else { (None, None) }; + } else { + (None, None) + }; // Restore monitor updating, ensuring we immediately get a fail-back update and a // update_add update. *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_2.2).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_2.2).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); expect_pending_htlcs_forwardable!(nodes[1]); @@ -837,7 +956,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { assert!(updates.update_add_htlcs.is_empty()); assert!(updates.update_fee.is_none()); (updates.update_fail_htlcs.remove(0), updates.commitment_signed) - }, + } _ => panic!("Unexpected event type!"), }; let raa = if test_ignore_second_cs { @@ -845,10 +964,12 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { MessageSendEvent::SendRevokeAndACK { node_id, msg } => { assert_eq!(node_id, nodes[2].node.get_our_node_id()); Some(msg.clone()) - }, + } _ => panic!("Unexpected event"), } - } else { None }; + } else { + None + }; let send_event_b = SendEvent::from_event(events_3.remove(0)); assert_eq!(send_event_b.node_id, nodes[2].node.get_our_node_id()); @@ -861,13 +982,16 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { if let Event::PaymentFailed { payment_hash, rejected_by_dest, .. } = events_4[0] { assert_eq!(payment_hash, payment_hash_1); assert!(rejected_by_dest); - } else { panic!("Unexpected event!"); } + } else { + panic!("Unexpected event!"); + } nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &send_event_b.msgs[0]); if test_ignore_second_cs { nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &send_event_b.commitment_msg); check_added_monitors!(nodes[2], 1); - let bs_revoke_and_ack = get_event_msg!(nodes[2], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + let bs_revoke_and_ack = + get_event_msg!(nodes[2], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); nodes[2].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &raa.unwrap()); check_added_monitors!(nodes[2], 1); let bs_cs = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id()); @@ -892,7 +1016,8 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &as_cs.commitment_signed); check_added_monitors!(nodes[2], 1); - let bs_second_raa = get_event_msg!(nodes[2], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + let bs_second_raa = + get_event_msg!(nodes[2], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); nodes[2].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_raa); check_added_monitors!(nodes[2], 1); @@ -910,7 +1035,9 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) { let events_6 = nodes[2].node.get_and_clear_pending_events(); assert_eq!(events_6.len(), 1); match events_6[0] { - Event::PaymentReceived { payment_hash, .. } => { assert_eq!(payment_hash, payment_hash_2); }, + Event::PaymentReceived { payment_hash, .. } => { + assert_eq!(payment_hash, payment_hash_2); + } _ => panic!("Unexpected event"), }; @@ -978,14 +1105,20 @@ fn test_monitor_update_fail_reestablish() { nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); - let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); + let as_reestablish = + get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); + let bs_reestablish = + get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); @@ -994,8 +1127,14 @@ fn test_monitor_update_fail_reestablish() { nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - assert!(as_reestablish == get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id())); - assert!(bs_reestablish == get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id())); + assert!( + as_reestablish + == get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()) + ); + assert!( + bs_reestablish + == get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()) + ); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish); @@ -1004,7 +1143,8 @@ fn test_monitor_update_fail_reestablish() { assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); @@ -1037,7 +1177,10 @@ fn raa_no_response_awaiting_raa_state() { let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]); let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); let (payment_preimage_3, payment_hash_3) = get_payment_preimage_hash!(nodes[0]); @@ -1077,16 +1220,25 @@ fn raa_no_response_awaiting_raa_state() { nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_raa); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Previous monitor update failure prevented responses to RAA".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Previous monitor update failure prevented responses to RAA".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); // nodes[1] should be AwaitingRAA here! check_added_monitors!(nodes[1], 0); @@ -1166,8 +1318,10 @@ fn claim_while_disconnected_monitor_update_fail() { nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - let as_reconnect = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); - let bs_reconnect = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); + let as_reconnect = + get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); + let bs_reconnect = + get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reconnect); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); @@ -1178,13 +1332,20 @@ fn claim_while_disconnected_monitor_update_fail() { nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reconnect); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); // Send a second payment from A to B, resulting in a commitment update that gets swallowed with // the monitor still failed - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1194,14 +1355,19 @@ fn claim_while_disconnected_monitor_update_fail() { nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_updates.commitment_signed); check_added_monitors!(nodes[1], 1); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Previous monitor update failure prevented generation of RAA".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Previous monitor update failure prevented generation of RAA".to_string(), + 1, + ); // Note that nodes[1] not updating monitor here is OK - it wont take action on the new HTLC // until we've channel_monitor_update'd and updated for the new commitment transaction. // Now un-fail the monitor, which will result in B sending its original commitment update, // receiving the commitment update from A, and the resulting commitment dances. *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); @@ -1211,14 +1377,16 @@ fn claim_while_disconnected_monitor_update_fail() { match bs_msgs[0] { MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); - nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]); + nodes[0] + .node + .handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]); nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &updates.commitment_signed); check_added_monitors!(nodes[0], 1); let as_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_raa); check_added_monitors!(nodes[1], 1); - }, + } _ => panic!("Unexpected event"), } @@ -1227,7 +1395,7 @@ fn claim_while_disconnected_monitor_update_fail() { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), msg); check_added_monitors!(nodes[0], 1); - }, + } _ => panic!("Unexpected event"), } @@ -1255,7 +1423,7 @@ fn claim_while_disconnected_monitor_update_fail() { match events[0] { Event::PaymentSent { ref payment_preimage } => { assert_eq!(*payment_preimage, payment_preimage_1); - }, + } _ => panic!("Unexpected event"), } @@ -1276,7 +1444,10 @@ fn monitor_failed_no_reestablish_response() { // Route the payment and deliver the initial commitment_signed (with a monitor update failure // on receipt). - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1288,7 +1459,11 @@ fn monitor_failed_no_reestablish_response() { nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); // Now disconnect and immediately reconnect, delivering the channel_reestablish while nodes[1] @@ -1299,14 +1474,17 @@ fn monitor_failed_no_reestablish_response() { nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - let as_reconnect = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); - let bs_reconnect = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); + let as_reconnect = + get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); + let bs_reconnect = + get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reconnect); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reconnect); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); let bs_responses = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); @@ -1346,7 +1524,10 @@ fn first_message_on_recv_ordering() { // Route the first payment outbound, holding the last RAA for B until we are set up so that we // can deliver it and fail the monitor update. - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1368,7 +1549,10 @@ fn first_message_on_recv_ordering() { let as_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); // Route the second payment, generating an update_add_htlc/commitment_signed - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1384,7 +1568,11 @@ fn first_message_on_recv_ordering() { // to the next message also tests resetting the delivery order. nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_raa); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[1], 1); // Now deliver the update_add_htlc/commitment_signed for the second payment, which does need an @@ -1394,10 +1582,15 @@ fn first_message_on_recv_ordering() { nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg); check_added_monitors!(nodes[1], 1); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Previous monitor update failure prevented generation of RAA".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Previous monitor update failure prevented generation of RAA".to_string(), + 1, + ); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); @@ -1444,7 +1637,10 @@ fn test_monitor_update_fail_claim() { assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000)); check_added_monitors!(nodes[1], 1); - let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[0].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[2].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (_, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); nodes[2].node.send_payment(&route, payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[2], 1); @@ -1459,7 +1655,11 @@ fn test_monitor_update_fail_claim() { nodes[1].node.handle_update_add_htlc(&nodes[2].node.get_our_node_id(), &payment_event.msgs[0]); let events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 0); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Temporary failure claiming HTLC, treating as success: Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Temporary failure claiming HTLC, treating as success: Failed to update ChannelMonitor".to_string(), + 1, + ); commitment_signed_dance!(nodes[1], nodes[2], payment_event.commitment_msg, false, true); let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id()); @@ -1469,10 +1669,12 @@ fn test_monitor_update_fail_claim() { let msg_events = nodes[2].node.get_and_clear_pending_msg_events(); assert_eq!(msg_events.len(), 1); match msg_events[0] { - MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }} => { + MessageSendEvent::PaymentFailureNetworkUpdate { + update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }, + } => { assert_eq!(msg.contents.short_channel_id, chan_1.0.contents.short_channel_id); assert_eq!(msg.contents.flags & 2, 2); // temp disabled - }, + } _ => panic!("Unexpected event"), } @@ -1481,22 +1683,29 @@ fn test_monitor_update_fail_claim() { if let Event::PaymentFailed { payment_hash, rejected_by_dest, .. } = events[0] { assert_eq!(payment_hash, payment_hash_2); assert!(!rejected_by_dest); - } else { panic!("Unexpected event!"); } + } else { + panic!("Unexpected event!"); + } // Now restore monitor updating on the 0<->1 channel and claim the funds on B. - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); let bs_fulfill_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); - nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_fulfill_update.update_fulfill_htlcs[0]); + nodes[0] + .node + .handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_fulfill_update.update_fulfill_htlcs[0]); commitment_signed_dance!(nodes[0], nodes[1], bs_fulfill_update.commitment_signed, false); let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); if let Event::PaymentSent { payment_preimage, .. } = events[0] { assert_eq!(payment_preimage, payment_preimage_1); - } else { panic!("Unexpected event!"); } + } else { + panic!("Unexpected event!"); + } } #[test] @@ -1525,7 +1734,10 @@ fn test_monitor_update_on_pending_forwards() { commitment_signed_dance!(nodes[1], nodes[2], cs_fail_update.commitment_signed, true, true); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[0].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[2].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); nodes[2].node.send_payment(&route, payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[2], 1); @@ -1540,10 +1752,15 @@ fn test_monitor_update_on_pending_forwards() { expect_pending_htlcs_forwardable!(nodes[1]); check_added_monitors!(nodes[1], 1); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_1.2).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); @@ -1557,9 +1774,11 @@ fn test_monitor_update_on_pending_forwards() { if let Event::PaymentFailed { payment_hash, rejected_by_dest, .. } = events[0] { assert_eq!(payment_hash, payment_hash_1); assert!(rejected_by_dest); - } else { panic!("Unexpected event!"); } + } else { + panic!("Unexpected event!"); + } match events[1] { - Event::PendingHTLCsForwardable { .. } => { }, + Event::PendingHTLCsForwardable { .. } => {} _ => panic!("Unexpected event"), }; nodes[0].node.process_pending_htlc_forwards(); @@ -1584,7 +1803,10 @@ fn monitor_update_claim_fail_no_response() { let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000); // Now start forwarding a second payment, skipping the last RAA so B is in AwaitingRAA - let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap(); + let id = &nodes[1].node.get_our_node_id(); + let vec = &Vec::new(); + let amt = 1000000; + let route = nodes[0].router.get_route(id, None, vec, amt, TEST_FINAL_CLTV).unwrap(); let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]); nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1600,10 +1822,15 @@ fn monitor_update_claim_fail_no_response() { check_added_monitors!(nodes[1], 1); let events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 0); - nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Temporary failure claiming HTLC, treating as success: Failed to update ChannelMonitor".to_string(), 1); + nodes[1].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Temporary failure claiming HTLC, treating as success: Failed to update ChannelMonitor".to_string(), + 1, + ); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); @@ -1622,7 +1849,7 @@ fn monitor_update_claim_fail_no_response() { match events[0] { Event::PaymentSent { ref payment_preimage } => { assert_eq!(*payment_preimage, payment_preimage_1); - }, + } _ => panic!("Unexpected event"), } @@ -1640,8 +1867,16 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap(); - nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id())); - nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())); + nodes[1].node.handle_open_channel( + &nodes[0].node.get_our_node_id(), + InitFeatures::known(), + &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()), + ); + nodes[0].node.handle_accept_channel( + &nodes[1].node.get_our_node_id(), + InitFeatures::known(), + &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()), + ); let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 43); @@ -1649,19 +1884,30 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: check_added_monitors!(nodes[0], 0); *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); - let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); - let channel_id = OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index }.to_channel_id(); + let funding_created_msg = + get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); + let channel_id = + OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index } + .to_channel_id(); nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg); check_added_monitors!(nodes[1], 1); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure); - nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id())); + nodes[0].node.handle_funding_signed( + &nodes[1].node.get_our_node_id(), + &get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id()), + ); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1); + nodes[0].logger.assert_log( + "lightning::ln::channelmanager".to_string(), + "Failed to update ChannelMonitor".to_string(), + 1, + ); check_added_monitors!(nodes[0], 1); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[0].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[0], 0); @@ -1671,13 +1917,16 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => { assert_eq!(user_channel_id, 43); assert_eq!(*funding_txo, funding_output); - }, + } _ => panic!("Unexpected event"), }; if confirm_a_first { confirm_transaction(&nodes[0].block_notifier, &nodes[0].chain_monitor, &funding_tx, funding_tx.version); - nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id())); + nodes[1].node.handle_funding_locked( + &nodes[0].node.get_our_node_id(), + &get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id()), + ); } else { assert!(!restore_b_before_conf); confirm_transaction(&nodes[1].block_notifier, &nodes[1].chain_monitor, &funding_tx, funding_tx.version); @@ -1698,12 +1947,16 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: } *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); - let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone(); nodes[1].node.channel_monitor_updated(&outpoint, latest_update); check_added_monitors!(nodes[1], 0); let (channel_id, (announcement, as_update, bs_update)) = if !confirm_a_first { - nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingLocked, nodes[0].node.get_our_node_id())); + nodes[0].node.handle_funding_locked( + &nodes[1].node.get_our_node_id(), + &get_event_msg!(nodes[1], MessageSendEvent::SendFundingLocked, nodes[0].node.get_our_node_id()), + ); confirm_transaction(&nodes[0].block_notifier, &nodes[0].chain_monitor, &funding_tx, funding_tx.version); let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]); @@ -1741,14 +1994,25 @@ fn test_path_paused_mpp() { let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs); - let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id; - let (chan_2_ann, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::known(), InitFeatures::known()); - let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id; - let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id; + let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()) + .0 + .contents + .short_channel_id; + let (chan_2_ann, _, chan_2_id, _) = + create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::known(), InitFeatures::known()); + let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::known(), InitFeatures::known()) + .0 + .contents + .short_channel_id; + let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known()) + .0 + .contents + .short_channel_id; let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]); let payment_secret = PaymentSecret([0xdb; 32]); - let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); + let mut route = + nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); // Set us up to take multiple routes, one 0 -> 1 -> 3 and one 0 -> 2 -> 3: let path = route.paths[0].clone(); @@ -1768,26 +2032,60 @@ fn test_path_paused_mpp() { // Now check that we get the right return value, indicating that the first path succeeded but // the second got a MonitorUpdateFailed err. This implies PaymentSendFailure::PartialFailure as // some paths succeeded, preventing retry. - if let Err(PaymentSendFailure::PartialFailure(results)) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) { + if let Err(PaymentSendFailure::PartialFailure(results)) = + nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) + { assert_eq!(results.len(), 2); - if let Ok(()) = results[0] {} else { panic!(); } - if let Err(APIError::MonitorUpdateFailed) = results[1] {} else { panic!(); } - } else { panic!(); } + if let Ok(()) = results[0] { + } else { + panic!(); + } + if let Err(APIError::MonitorUpdateFailed) = results[1] { + } else { + panic!(); + } + } else { + panic!(); + } check_added_monitors!(nodes[0], 2); *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); // Pass the first HTLC of the payment along to nodes[3]. let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); - pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 0, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), false); + pass_along_path( + &nodes[0], + &[&nodes[1], &nodes[3]], + 0, + payment_hash.clone(), + Some(payment_secret), + events.pop().unwrap(), + false, + ); // And check that, after we successfully update the monitor for chan_2 we can pass the second // HTLC along to nodes[3] and claim the whole payment back to nodes[0]. - let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_2_id).unwrap().clone(); + let (outpoint, latest_update) = + nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_2_id).unwrap().clone(); nodes[0].node.channel_monitor_updated(&outpoint, latest_update); let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); - pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), true); - - claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage, Some(payment_secret), 200_000); + pass_along_path( + &nodes[0], + &[&nodes[2], &nodes[3]], + 200_000, + payment_hash.clone(), + Some(payment_secret), + events.pop().unwrap(), + true, + ); + + claim_payment_along_route_with_secret( + &nodes[0], + &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], + false, + payment_preimage, + Some(payment_secret), + 200_000, + ); } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 469698356af..bac0d662792 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1,40 +1,46 @@ use bitcoin::blockdata::block::BlockHeader; -use bitcoin::blockdata::script::{Script,Builder}; -use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType}; use bitcoin::blockdata::opcodes; -use bitcoin::util::hash::BitcoinHash; -use bitcoin::util::bip143; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::transaction::{SigHashType, Transaction, TxIn, TxOut}; use bitcoin::consensus::encode; +use bitcoin::util::bip143; +use bitcoin::util::hash::BitcoinHash; -use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hash_types::{BlockHash, Txid, WPubkeyHash}; use bitcoin::hashes::sha256::Hash as Sha256; -use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash}; +use bitcoin::hashes::{Hash, HashEngine}; -use bitcoin::secp256k1::key::{PublicKey,SecretKey}; -use bitcoin::secp256k1::{Secp256k1,Signature}; use bitcoin::secp256k1; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; +use bitcoin::secp256k1::{Secp256k1, Signature}; +use chain::chaininterface::{ConfirmationTarget, FeeEstimator}; +use chain::keysinterface::{ChannelKeys, KeysInterface}; +use chain::transaction::OutPoint; +use ln::chan_utils; +use ln::chan_utils::{ + make_funding_redeemscript, ChannelPublicKeys, CounterpartyCommitmentSecrets, HTLCOutputInCommitment, + LocalCommitmentTransaction, TxCreationKeys, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, +}; +use ln::channelmanager::{ + HTLCFailReason, HTLCFailureMsg, HTLCSource, PaymentHash, PaymentPreimage, PendingHTLCInfo, PendingHTLCStatus, + RAACommitmentOrder, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT, +}; +use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER}; use ln::features::{ChannelFeatures, InitFeatures}; use ln::msgs; -use ln::msgs::{DecodeError, OptionalField, DataLossProtect}; -use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER}; -use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT}; -use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys}; -use ln::chan_utils; -use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; -use chain::transaction::OutPoint; -use chain::keysinterface::{ChannelKeys, KeysInterface}; -use util::transaction_utils; -use util::ser::{Readable, ReadableArgs, Writeable, Writer}; -use util::logger::{Logger, LogHolder}; +use ln::msgs::{DataLossProtect, DecodeError, OptionalField}; +use util::config::{ChannelConfig, UserConfig}; use util::errors::APIError; -use util::config::{UserConfig,ChannelConfig}; +use util::logger::{LogHolder, Logger}; +use util::ser::{Readable, ReadableArgs, Writeable, Writer}; +use util::transaction_utils; use std; use std::default::Default; -use std::{cmp,mem,fmt}; -use std::sync::{Arc}; use std::ops::Deref; +use std::sync::Arc; +use std::{cmp, fmt, mem}; #[cfg(test)] pub struct ChannelValueStat { @@ -133,7 +139,8 @@ struct OutboundHTLCOutput { /// See AwaitingRemoteRevoke ChannelState for more info enum HTLCUpdateAwaitingACK { - AddHTLC { // TODO: Time out if we're getting close to cltv_expiry + AddHTLC { + // TODO: Time out if we're getting close to cltv_expiry // always outbound amount_msat: u64, cltv_expiry: u32, @@ -207,7 +214,8 @@ enum ChannelState { ShutdownComplete = 4096, } const BOTH_SIDES_SHUTDOWN_MASK: u32 = ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32; -const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32; +const MULTI_STATE_FLAGS: u32 = + BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32; const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; @@ -252,7 +260,6 @@ pub(super) struct Channel { // Our commitment numbers start at 2^48-1 and count down, whereas the ones used in transaction // generation start at 0 and count up...this simplifies some parts of implementation at the // cost of others, but should really just be changed. - cur_local_commitment_transaction_number: u64, cur_remote_commitment_transaction_number: u64, value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees @@ -389,10 +396,7 @@ pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24; pub(super) enum ChannelError { Ignore(&'static str), Close(&'static str), - CloseDelayBroadcast { - msg: &'static str, - update: ChannelMonitorUpdate, - }, + CloseDelayBroadcast { msg: &'static str, update: ChannelMonitorUpdate }, } impl fmt::Debug for ChannelError { @@ -400,11 +404,12 @@ impl fmt::Debug for ChannelError { match self { &ChannelError::Ignore(e) => write!(f, "Ignore : {}", e), &ChannelError::Close(e) => write!(f, "Close : {}", e), - &ChannelError::CloseDelayBroadcast { msg, .. } => write!(f, "CloseDelayBroadcast : {}", msg) + &ChannelError::CloseDelayBroadcast { msg, .. } => write!(f, "CloseDelayBroadcast : {}", msg), } } } +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! secp_check { ($res: expr, $err: expr) => { match $res { @@ -429,44 +434,58 @@ impl Channel { } fn derive_our_dust_limit_satoshis(at_open_background_feerate: u64) -> u64 { - cmp::max(at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000, 546) //TODO + cmp::max(at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000, 546) + //TODO } // Constructors: - pub fn new_outbound(fee_estimator: &F, keys_provider: &K, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc, config: &UserConfig) -> Result, APIError> - where K::Target: KeysInterface, - F::Target: FeeEstimator, + pub fn new_outbound( + fee_estimator: &F, keys_provider: &K, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, + user_id: u64, logger: Arc, config: &UserConfig, + ) -> Result, APIError> + where + K::Target: KeysInterface, + F::Target: FeeEstimator, { let chan_keys = keys_provider.get_channel_keys(false, channel_value_satoshis); if channel_value_satoshis >= MAX_FUNDING_SATOSHIS { - return Err(APIError::APIMisuseError{err: "funding value > 2^24"}); + return Err(APIError::APIMisuseError { err: "funding value > 2^24" }); } if push_msat > channel_value_satoshis * 1000 { - return Err(APIError::APIMisuseError{err: "push value > channel value"}); + return Err(APIError::APIMisuseError { err: "push value > channel value" }); } if config.own_channel_config.our_to_self_delay < BREAKDOWN_TIMEOUT { - return Err(APIError::APIMisuseError{err: "Configured with an unreasonable our_to_self_delay putting user funds at risks"}); + return Err(APIError::APIMisuseError { + err: "Configured with an unreasonable our_to_self_delay putting user funds at risks", + }); } - let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background); - if Channel::::get_our_channel_reserve_satoshis(channel_value_satoshis) < Channel::::derive_our_dust_limit_satoshis(background_feerate) { - return Err(APIError::FeeRateTooHigh{err: format!("Not enough reserve above dust limit can be found at current fee rate({})", background_feerate), feerate: background_feerate}); + if Channel::::get_our_channel_reserve_satoshis(channel_value_satoshis) + < Channel::::derive_our_dust_limit_satoshis(background_feerate) + { + return Err(APIError::FeeRateTooHigh { + err: format!( + "Not enough reserve above dust limit can be found at current fee rate({})", + background_feerate + ), + feerate: background_feerate, + }); } let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal); Ok(Channel { - user_id: user_id, + user_id, config: config.channel_options.clone(), channel_id: keys_provider.get_channel_id(), channel_state: ChannelState::OurInitSent as u32, channel_outbound: true, secp_ctx: Secp256k1::new(), - channel_value_satoshis: channel_value_satoshis, + channel_value_satoshis, latest_monitor_update_id: 0, @@ -496,9 +515,15 @@ impl Channel { monitor_pending_failures: Vec::new(), #[cfg(debug_assertions)] - max_commitment_tx_output_local: ::std::sync::Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)), + max_commitment_tx_output_local: ::std::sync::Mutex::new(( + channel_value_satoshis * 1000 - push_msat, + push_msat, + )), #[cfg(debug_assertions)] - max_commitment_tx_output_remote: ::std::sync::Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)), + max_commitment_tx_output_remote: ::std::sync::Mutex::new(( + channel_value_satoshis * 1000 - push_msat, + push_msat, + )), last_sent_closing_fee: None, @@ -514,7 +539,11 @@ impl Channel { their_max_htlc_value_in_flight_msat: 0, their_channel_reserve_satoshis: 0, their_htlc_minimum_msat: 0, - our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat }, + our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { + 1 + } else { + config.own_channel_config.our_htlc_minimum_msat + }, their_to_self_delay: 0, our_to_self_delay: config.own_channel_config.our_to_self_delay, their_max_accepted_htlcs: 0, @@ -524,7 +553,7 @@ impl Channel { their_cur_commitment_point: None, their_prev_commitment_point: None, - their_node_id: their_node_id, + their_node_id, their_shutdown_scriptpubkey: None, @@ -538,7 +567,8 @@ impl Channel { } fn check_remote_fee(fee_estimator: &F, feerate_per_kw: u32) -> Result<(), ChannelError> - where F::Target: FeeEstimator + where + F::Target: FeeEstimator, { if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) { return Err(ChannelError::Close("Peer's feerate much too low")); @@ -551,9 +581,13 @@ impl Channel { /// Creates a new channel from a remote sides' request for one. /// Assumes chain_hash has already been checked and corresponds with what we expect! - pub fn new_from_req(fee_estimator: &F, keys_provider: &K, their_node_id: PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc, config: &UserConfig) -> Result, ChannelError> - where K::Target: KeysInterface, - F::Target: FeeEstimator + pub fn new_from_req( + fee_estimator: &F, keys_provider: &K, their_node_id: PublicKey, their_features: InitFeatures, + msg: &msgs::OpenChannel, user_id: u64, logger: Arc, config: &UserConfig, + ) -> Result, ChannelError> + where + K::Target: KeysInterface, + F::Target: FeeEstimator, { let mut chan_keys = keys_provider.get_channel_keys(true, msg.funding_satoshis); let their_pubkeys = ChannelPublicKeys { @@ -561,13 +595,15 @@ impl Channel { revocation_basepoint: msg.revocation_basepoint, payment_basepoint: msg.payment_basepoint, delayed_payment_basepoint: msg.delayed_payment_basepoint, - htlc_basepoint: msg.htlc_basepoint + htlc_basepoint: msg.htlc_basepoint, }; chan_keys.set_remote_channel_pubkeys(&their_pubkeys); let mut local_config = (*config).channel_options.clone(); if config.own_channel_config.our_to_self_delay < BREAKDOWN_TIMEOUT { - return Err(ChannelError::Close("Configured with an unreasonable our_to_self_delay putting user funds at risks")); + return Err(ChannelError::Close( + "Configured with an unreasonable our_to_self_delay putting user funds at risks", + )); } // Check sanity of message fields: @@ -591,7 +627,9 @@ impl Channel { } Channel::::check_remote_fee(fee_estimator, msg.feerate_per_kw)?; - if msg.to_self_delay > config.peer_channel_config_limits.their_to_self_delay || msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT { + if msg.to_self_delay > config.peer_channel_config_limits.their_to_self_delay + || msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT + { return Err(ChannelError::Close("They wanted our payments to be delayed by a needlessly long period")); } if msg.max_accepted_htlcs < 1 { @@ -629,7 +667,9 @@ impl Channel { let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false }; if config.peer_channel_config_limits.force_announced_channel_preference { if local_config.announced_channel != their_announce { - return Err(ChannelError::Close("Peer tried to open channel but their announcement preference is different from ours")); + return Err(ChannelError::Close( + "Peer tried to open channel but their announcement preference is different from ours", + )); } } // we either accept their preference or the preferences match @@ -638,7 +678,8 @@ impl Channel { let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background); let our_dust_limit_satoshis = Channel::::derive_our_dust_limit_satoshis(background_feerate); - let our_channel_reserve_satoshis = Channel::::get_our_channel_reserve_satoshis(msg.funding_satoshis); + let our_channel_reserve_satoshis = + Channel::::get_our_channel_reserve_satoshis(msg.funding_satoshis); if our_channel_reserve_satoshis < our_dust_limit_satoshis { return Err(ChannelError::Close("Suitable channel reserve not found. aborting")); } @@ -658,7 +699,8 @@ impl Channel { let to_local_msat = msg.push_msat; let to_remote_msat = funders_amount_msat - background_feerate * COMMITMENT_TX_BASE_WEIGHT; - if to_local_msat <= msg.channel_reserve_satoshis * 1000 && to_remote_msat <= our_channel_reserve_satoshis * 1000 { + if to_local_msat <= msg.channel_reserve_satoshis * 1000 && to_remote_msat <= our_channel_reserve_satoshis * 1000 + { return Err(ChannelError::Close("Insufficient funding amount for initial commitment")); } @@ -673,18 +715,22 @@ impl Channel { None // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel } else { - return Err(ChannelError::Close("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format")); + return Err(ChannelError::Close( + "Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format", + )); } - }, + } // Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel &OptionalField::Absent => { return Err(ChannelError::Close("Peer is signaling upfront_shutdown but we don't get any script. Use 0-length script to opt-out")); } } - } else { None }; + } else { + None + }; let chan = Channel { - user_id: user_id, + user_id, config: local_config, channel_id: msg.temporary_channel_id, @@ -720,9 +766,15 @@ impl Channel { monitor_pending_failures: Vec::new(), #[cfg(debug_assertions)] - max_commitment_tx_output_local: ::std::sync::Mutex::new((msg.push_msat, msg.funding_satoshis * 1000 - msg.push_msat)), + max_commitment_tx_output_local: ::std::sync::Mutex::new(( + msg.push_msat, + msg.funding_satoshis * 1000 - msg.push_msat, + )), #[cfg(debug_assertions)] - max_commitment_tx_output_remote: ::std::sync::Mutex::new((msg.push_msat, msg.funding_satoshis * 1000 - msg.push_msat)), + max_commitment_tx_output_remote: ::std::sync::Mutex::new(( + msg.push_msat, + msg.funding_satoshis * 1000 - msg.push_msat, + )), last_sent_closing_fee: None, @@ -735,11 +787,18 @@ impl Channel { feerate_per_kw: msg.feerate_per_kw as u64, channel_value_satoshis: msg.funding_satoshis, their_dust_limit_satoshis: msg.dust_limit_satoshis, - our_dust_limit_satoshis: our_dust_limit_satoshis, - their_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000), + our_dust_limit_satoshis, + their_max_htlc_value_in_flight_msat: cmp::min( + msg.max_htlc_value_in_flight_msat, + msg.funding_satoshis * 1000, + ), their_channel_reserve_satoshis: msg.channel_reserve_satoshis, their_htlc_minimum_msat: msg.htlc_minimum_msat, - our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat }, + our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { + 1 + } else { + config.own_channel_config.our_htlc_minimum_msat + }, their_to_self_delay: msg.to_self_delay, our_to_self_delay: config.own_channel_config.our_to_self_delay, their_max_accepted_htlcs: msg.max_accepted_htlcs, @@ -749,7 +808,7 @@ impl Channel { their_cur_commitment_point: Some(msg.first_per_commitment_point), their_prev_commitment_point: None, - their_node_id: their_node_id, + their_node_id, their_shutdown_scriptpubkey, @@ -773,6 +832,7 @@ impl Channel { // Utilities to build transactions: + #[cfg_attr(rustfmt, rustfmt_skip)] fn get_commitment_transaction_number_obscure_factor(&self) -> u64 { let mut sha = Sha256::engine(); let our_payment_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key()); @@ -787,12 +847,12 @@ impl Channel { } let res = Sha256::from_engine(sha).into_inner(); - ((res[26] as u64) << 5*8) | - ((res[27] as u64) << 4*8) | - ((res[28] as u64) << 3*8) | - ((res[29] as u64) << 2*8) | - ((res[30] as u64) << 1*8) | - ((res[31] as u64) << 0*8) + ((res[26] as u64) << 5 * 8) | + ((res[27] as u64) << 4 * 8) | + ((res[28] as u64) << 3 * 8) | + ((res[29] as u64) << 2 * 8) | + ((res[30] as u64) << 1 * 8) | + ((res[31] as u64) << 0 * 8) } /// Transaction nomenclature is somewhat confusing here as there are many different cases - a @@ -813,21 +873,26 @@ impl Channel { /// Note that below-dust HTLCs are included in the third return value, but not the second, and /// sources are provided only for outbound HTLCs in the third return value. #[inline] - fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, usize, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>) { - let obscured_commitment_transaction_number = self.get_commitment_transaction_number_obscure_factor() ^ (INITIAL_COMMITMENT_NUMBER - commitment_number); + fn build_commitment_transaction( + &self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, + feerate_per_kw: u64, + ) -> (Transaction, usize, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>) { + let obscured_commitment_transaction_number = + self.get_commitment_transaction_number_obscure_factor() ^ (INITIAL_COMMITMENT_NUMBER - commitment_number); let txins = { let mut ins: Vec = Vec::new(); ins.push(TxIn { previous_output: self.funding_txo.unwrap().into_bitcoin_outpoint(), script_sig: Script::new(), - sequence: ((0x80 as u32) << 8*3) | ((obscured_commitment_transaction_number >> 3*8) as u32), + sequence: ((0x80 as u32) << 8 * 3) | ((obscured_commitment_transaction_number >> 3 * 8) as u32), witness: Vec::new(), }); ins }; - let mut txouts: Vec<(TxOut, Option<(HTLCOutputInCommitment, Option<&HTLCSource>)>)> = Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2); + let mut txouts: Vec<(TxOut, Option<(HTLCOutputInCommitment, Option<&HTLCSource>)>)> = + Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2); let mut included_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)> = Vec::new(); let dust_limit_satoshis = if local { self.our_dust_limit_satoshis } else { self.their_dust_limit_satoshis }; @@ -835,8 +900,18 @@ impl Channel { let mut local_htlc_total_msat = 0; let mut value_to_self_msat_offset = 0; - log_trace!(self, "Building commitment transaction number {} (really {} xor {}) for {}, generated by {} with fee {}...", commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number), self.get_commitment_transaction_number_obscure_factor(), if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw); + log_trace!( + self, + "Building commitment transaction number {} (really {} xor {}) for {}, generated by {} with fee {}...", + commitment_number, + (INITIAL_COMMITMENT_NUMBER - commitment_number), + self.get_commitment_transaction_number_obscure_factor(), + if local { "us" } else { "remote" }, + if generated_by_local { "us" } else { "remote" }, + feerate_per_kw + ); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! get_htlc_in_commitment { ($htlc: expr, $offered: expr) => { HTLCOutputInCommitment { @@ -849,6 +924,7 @@ impl Channel { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! add_htlc_output { ($htlc: expr, $outbound: expr, $source: expr, $state_name: expr) => { if $outbound == local { // "offered HTLC output" @@ -882,7 +958,9 @@ impl Channel { for ref htlc in self.pending_inbound_htlcs.iter() { let (include, state_name) = match htlc.state { InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"), - InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => (!generated_by_local, "AwaitingRemoteRevokeToAnnounce"), + InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => { + (!generated_by_local, "AwaitingRemoteRevokeToAnnounce") + } InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => (true, "AwaitingAnnouncedRemoteRevoke"), InboundHTLCState::Committed => (true, "Committed"), InboundHTLCState::LocalRemoved(_) => (!generated_by_local, "LocalRemoved"), @@ -892,7 +970,14 @@ impl Channel { add_htlc_output!(htlc, false, None, state_name); remote_htlc_total_msat += htlc.amount_msat; } else { - log_trace!(self, " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, log_bytes!(htlc.payment_hash.0), htlc.amount_msat, state_name); + log_trace!( + self, + " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", + htlc.htlc_id, + log_bytes!(htlc.payment_hash.0), + htlc.amount_msat, + state_name + ); match &htlc.state { &InboundHTLCState::LocalRemoved(ref reason) => { if generated_by_local { @@ -900,8 +985,8 @@ impl Channel { value_to_self_msat_offset += htlc.amount_msat as i64; } } - }, - _ => {}, + } + _ => {} } } } @@ -911,7 +996,9 @@ impl Channel { OutboundHTLCState::LocalAnnounced(_) => (generated_by_local, "LocalAnnounced"), OutboundHTLCState::Committed => (true, "Committed"), OutboundHTLCState::RemoteRemoved(_) => (generated_by_local, "RemoteRemoved"), - OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => (generated_by_local, "AwaitingRemoteRevokeToRemove"), + OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => { + (generated_by_local, "AwaitingRemoteRevokeToRemove") + } OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => (false, "AwaitingRemovedRemoteRevoke"), }; @@ -919,28 +1006,40 @@ impl Channel { add_htlc_output!(htlc, true, Some(&htlc.source), state_name); local_htlc_total_msat += htlc.amount_msat; } else { - log_trace!(self, " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, log_bytes!(htlc.payment_hash.0), htlc.amount_msat, state_name); + log_trace!( + self, + " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})", + htlc.htlc_id, + log_bytes!(htlc.payment_hash.0), + htlc.amount_msat, + state_name + ); match htlc.state { - OutboundHTLCState::AwaitingRemoteRevokeToRemove(None)|OutboundHTLCState::AwaitingRemovedRemoteRevoke(None) => { + OutboundHTLCState::AwaitingRemoteRevokeToRemove(None) + | OutboundHTLCState::AwaitingRemovedRemoteRevoke(None) => { value_to_self_msat_offset -= htlc.amount_msat as i64; - }, + } OutboundHTLCState::RemoteRemoved(None) => { if !generated_by_local { value_to_self_msat_offset -= htlc.amount_msat as i64; } - }, - _ => {}, + } + _ => {} } } } - let value_to_self_msat: i64 = (self.value_to_self_msat - local_htlc_total_msat) as i64 + value_to_self_msat_offset; + let value_to_self_msat: i64 = + (self.value_to_self_msat - local_htlc_total_msat) as i64 + value_to_self_msat_offset; assert!(value_to_self_msat >= 0); // Note that in case they have several just-awaiting-last-RAA fulfills in-progress (ie // AwaitingRemoteRevokeToRemove or AwaitingRemovedRemoteRevoke) we may have allowed them to // "violate" their reserve value by couting those against it. Thus, we have to convert // everything to i64 before subtracting as otherwise we can overflow. - let value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 - (self.value_to_self_msat as i64) - (remote_htlc_total_msat as i64) - value_to_self_msat_offset; + let value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 + - (self.value_to_self_msat as i64) + - (remote_htlc_total_msat as i64) + - value_to_self_msat_offset; assert!(value_to_remote_msat >= 0); #[cfg(debug_assertions)] @@ -952,13 +1051,21 @@ impl Channel { } else { self.max_commitment_tx_output_remote.lock().unwrap() }; - debug_assert!(max_commitment_tx_output.0 <= value_to_self_msat as u64 || value_to_self_msat / 1000 >= self.their_channel_reserve_satoshis as i64); + debug_assert!( + max_commitment_tx_output.0 <= value_to_self_msat as u64 + || value_to_self_msat / 1000 >= self.their_channel_reserve_satoshis as i64 + ); max_commitment_tx_output.0 = cmp::max(max_commitment_tx_output.0, value_to_self_msat as u64); - debug_assert!(max_commitment_tx_output.1 <= value_to_remote_msat as u64 || value_to_remote_msat / 1000 >= Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis) as i64); + debug_assert!( + max_commitment_tx_output.1 <= value_to_remote_msat as u64 + || value_to_remote_msat / 1000 + >= Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis) as i64 + ); max_commitment_tx_output.1 = cmp::max(max_commitment_tx_output.1, value_to_remote_msat as u64); } - let total_fee: u64 = feerate_per_kw * (COMMITMENT_TX_BASE_WEIGHT + (txouts.len() as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000; + let total_fee: u64 = + feerate_per_kw * (COMMITMENT_TX_BASE_WEIGHT + (txouts.len() as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000; let (value_to_self, value_to_remote) = if self.channel_outbound { (value_to_self_msat / 1000 - total_fee as i64, value_to_remote_msat / 1000) } else { @@ -969,41 +1076,69 @@ impl Channel { let value_to_b = if local { value_to_remote } else { value_to_self }; if value_to_a >= (dust_limit_satoshis as i64) { - log_trace!(self, " ...including {} output with value {}", if local { "to_local" } else { "to_remote" }, value_to_a); - txouts.push((TxOut { - script_pubkey: chan_utils::get_revokeable_redeemscript(&keys.revocation_key, - if local { self.their_to_self_delay } else { self.our_to_self_delay }, - &keys.a_delayed_payment_key).to_v0_p2wsh(), - value: value_to_a as u64 - }, None)); + log_trace!( + self, + " ...including {} output with value {}", + if local { "to_local" } else { "to_remote" }, + value_to_a + ); + txouts.push(( + TxOut { + script_pubkey: chan_utils::get_revokeable_redeemscript( + &keys.revocation_key, + if local { self.their_to_self_delay } else { self.our_to_self_delay }, + &keys.a_delayed_payment_key, + ) + .to_v0_p2wsh(), + value: value_to_a as u64, + }, + None, + )); } if value_to_b >= (dust_limit_satoshis as i64) { - log_trace!(self, " ...including {} output with value {}", if local { "to_remote" } else { "to_local" }, value_to_b); - txouts.push((TxOut { - script_pubkey: Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0) - .push_slice(&WPubkeyHash::hash(&keys.b_payment_key.serialize())[..]) - .into_script(), - value: value_to_b as u64 - }, None)); + log_trace!( + self, + " ...including {} output with value {}", + if local { "to_remote" } else { "to_local" }, + value_to_b + ); + txouts.push(( + TxOut { + script_pubkey: Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&WPubkeyHash::hash(&keys.b_payment_key.serialize())[..]) + .into_script(), + value: value_to_b as u64, + }, + None, + )); } transaction_utils::sort_outputs(&mut txouts, |a, b| { if let &Some(ref a_htlc) = a { if let &Some(ref b_htlc) = b { - a_htlc.0.cltv_expiry.cmp(&b_htlc.0.cltv_expiry) + a_htlc + .0 + .cltv_expiry + .cmp(&b_htlc.0.cltv_expiry) // Note that due to hash collisions, we have to have a fallback comparison // here for fuzztarget mode (otherwise at least chanmon_fail_consistency // may fail)! .then(a_htlc.0.payment_hash.0.cmp(&b_htlc.0.payment_hash.0)) // For non-HTLC outputs, if they're copying our SPK we don't really care if we // close the channel due to mismatches - they're doing something dumb: - } else { cmp::Ordering::Equal } - } else { cmp::Ordering::Equal } + } else { + cmp::Ordering::Equal + } + } else { + cmp::Ordering::Equal + } }); let mut outputs: Vec = Vec::with_capacity(txouts.len()); - let mut htlcs_included: Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)> = Vec::with_capacity(txouts.len() + included_dust_htlcs.len()); + let mut htlcs_included: Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)> = + Vec::with_capacity(txouts.len() + included_dust_htlcs.len()); for (idx, mut out) in txouts.drain(..).enumerate() { outputs.push(out.0); if let Some((mut htlc, source_option)) = out.1.take() { @@ -1014,27 +1149,37 @@ impl Channel { let non_dust_htlc_count = htlcs_included.len(); htlcs_included.append(&mut included_dust_htlcs); - (Transaction { - version: 2, - lock_time: ((0x20 as u32) << 8*3) | ((obscured_commitment_transaction_number & 0xffffffu64) as u32), - input: txins, - output: outputs, - }, non_dust_htlc_count, htlcs_included) + ( + Transaction { + version: 2, + lock_time: ((0x20 as u32) << 8 * 3) | ((obscured_commitment_transaction_number & 0xffffffu64) as u32), + input: txins, + output: outputs, + }, + non_dust_htlc_count, + htlcs_included, + ) } #[inline] fn get_closing_scriptpubkey(&self) -> Script { let our_channel_close_key_hash = WPubkeyHash::hash(&self.shutdown_pubkey.serialize()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_close_key_hash[..]).into_script() + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&our_channel_close_key_hash[..]) + .into_script() } #[inline] fn get_closing_transaction_weight(a_scriptpubkey: &Script, b_scriptpubkey: &Script) -> u64 { - (4 + 1 + 36 + 4 + 1 + 1 + 2*(8+1) + 4 + a_scriptpubkey.len() as u64 + b_scriptpubkey.len() as u64)*4 + 2 + 1 + 1 + 2*(1 + 72) + (4 + 1 + 36 + 4 + 1 + 1 + 2 * (8 + 1) + 4 + a_scriptpubkey.len() as u64 + b_scriptpubkey.len() as u64) * 4 + + 2 + 1 + 1 + 2 * (1 + 72) } #[inline] - fn build_closing_transaction(&self, proposed_total_fee_satoshis: u64, skip_remote_output: bool) -> (Transaction, u64) { + fn build_closing_transaction( + &self, proposed_total_fee_satoshis: u64, skip_remote_output: bool, + ) -> (Transaction, u64) { let txins = { let mut ins: Vec = Vec::new(); ins.push(TxIn { @@ -1051,8 +1196,10 @@ impl Channel { let mut txouts: Vec<(TxOut, ())> = Vec::new(); let mut total_fee_satoshis = proposed_total_fee_satoshis; - let value_to_self: i64 = (self.value_to_self_msat as i64) / 1000 - if self.channel_outbound { total_fee_satoshis as i64 } else { 0 }; - let value_to_remote: i64 = ((self.channel_value_satoshis * 1000 - self.value_to_self_msat) as i64 / 1000) - if self.channel_outbound { 0 } else { total_fee_satoshis as i64 }; + let value_to_self: i64 = + (self.value_to_self_msat as i64) / 1000 - if self.channel_outbound { total_fee_satoshis as i64 } else { 0 }; + let value_to_remote: i64 = ((self.channel_value_satoshis * 1000 - self.value_to_self_msat) as i64 / 1000) + - if self.channel_outbound { 0 } else { total_fee_satoshis as i64 }; if value_to_self < 0 { assert!(self.channel_outbound); @@ -1063,32 +1210,27 @@ impl Channel { } if !skip_remote_output && value_to_remote as u64 > self.our_dust_limit_satoshis { - txouts.push((TxOut { - script_pubkey: self.their_shutdown_scriptpubkey.clone().unwrap(), - value: value_to_remote as u64 - }, ())); + txouts.push(( + TxOut { + script_pubkey: self.their_shutdown_scriptpubkey.clone().unwrap(), + value: value_to_remote as u64, + }, + (), + )); } if value_to_self as u64 > self.our_dust_limit_satoshis { - txouts.push((TxOut { - script_pubkey: self.get_closing_scriptpubkey(), - value: value_to_self as u64 - }, ())); + txouts.push((TxOut { script_pubkey: self.get_closing_scriptpubkey(), value: value_to_self as u64 }, ())); } - transaction_utils::sort_outputs(&mut txouts, |_, _| { cmp::Ordering::Equal }); // Ordering doesnt matter if they used our pubkey... + transaction_utils::sort_outputs(&mut txouts, |_, _| cmp::Ordering::Equal); // Ordering doesnt matter if they used our pubkey... let mut outputs: Vec = Vec::new(); for out in txouts.drain(..) { outputs.push(out.0); } - (Transaction { - version: 2, - lock_time: 0, - input: txins, - output: outputs, - }, total_fee_satoshis) + (Transaction { version: 2, lock_time: 0, input: txins, output: outputs }, total_fee_satoshis) } #[inline] @@ -1098,12 +1240,25 @@ impl Channel { /// The result is a transaction which we can revoke ownership of (ie a "local" transaction) /// TODO Some magic rust shit to compile-time check this? fn build_local_transaction_keys(&self, commitment_number: u64) -> Result { - let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(commitment_number)); - let delayed_payment_base = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()); + let per_commitment_point = + PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(commitment_number)); + let delayed_payment_base = + PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()); let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()); let their_pubkeys = self.their_pubkeys.as_ref().unwrap(); - Ok(secp_check!(TxCreationKeys::new(&self.secp_ctx, &per_commitment_point, &delayed_payment_base, &htlc_basepoint, &their_pubkeys.revocation_basepoint, &their_pubkeys.payment_basepoint, &their_pubkeys.htlc_basepoint), "Local tx keys generation got bogus keys")) + Ok(secp_check!( + TxCreationKeys::new( + &self.secp_ctx, + &per_commitment_point, + &delayed_payment_base, + &htlc_basepoint, + &their_pubkeys.revocation_basepoint, + &their_pubkeys.payment_basepoint, + &their_pubkeys.htlc_basepoint + ), + "Local tx keys generation got bogus keys" + )) } #[inline] @@ -1118,7 +1273,18 @@ impl Channel { let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()); let their_pubkeys = self.their_pubkeys.as_ref().unwrap(); - Ok(secp_check!(TxCreationKeys::new(&self.secp_ctx, &self.their_cur_commitment_point.unwrap(), &their_pubkeys.delayed_payment_basepoint, &their_pubkeys.htlc_basepoint, &revocation_basepoint, &payment_basepoint, &htlc_basepoint), "Remote tx keys generation got bogus keys")) + Ok(secp_check!( + TxCreationKeys::new( + &self.secp_ctx, + &self.their_cur_commitment_point.unwrap(), + &their_pubkeys.delayed_payment_basepoint, + &their_pubkeys.htlc_basepoint, + &revocation_basepoint, + &payment_basepoint, + &htlc_basepoint + ), + "Remote tx keys generation got bogus keys" + )) } /// Gets the redeemscript for the funding transaction output (ie the funding transaction output @@ -1132,8 +1298,17 @@ impl Channel { /// Builds the htlc-success or htlc-timeout transaction which spends a given HTLC output /// @local is used only to convert relevant internal structures which refer to remote vs local /// to decide value of outputs and direction of HTLCs. - fn build_htlc_transaction(&self, prev_hash: &Txid, htlc: &HTLCOutputInCommitment, local: bool, keys: &TxCreationKeys, feerate_per_kw: u64) -> Transaction { - chan_utils::build_htlc_transaction(prev_hash, feerate_per_kw, if local { self.their_to_self_delay } else { self.our_to_self_delay }, htlc, &keys.a_delayed_payment_key, &keys.revocation_key) + fn build_htlc_transaction( + &self, prev_hash: &Txid, htlc: &HTLCOutputInCommitment, local: bool, keys: &TxCreationKeys, feerate_per_kw: u64, + ) -> Transaction { + chan_utils::build_htlc_transaction( + prev_hash, + feerate_per_kw, + if local { self.their_to_self_delay } else { self.our_to_self_delay }, + htlc, + &keys.a_delayed_payment_key, + &keys.revocation_key, + ) } /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made. @@ -1142,7 +1317,9 @@ impl Channel { /// /// Note that it is still possible to hit these assertions in case we find a preimage on-chain /// but then have a reorg which settles on an HTLC-failure on chain. - fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage) -> Result<(Option, Option), ChannelError> { + fn get_update_fulfill_htlc( + &mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage, + ) -> Result<(Option, Option), ChannelError> { // Either ChannelFunded got set (which means it won't be unset) or there is no way any // caller thought we could have something claimed (cause we wouldn't have accepted in an // incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us, @@ -1163,7 +1340,7 @@ impl Channel { if htlc.htlc_id == htlc_id_arg { assert_eq!(htlc.payment_hash, payment_hash_calc); match htlc.state { - InboundHTLCState::Committed => {}, + InboundHTLCState::Committed => {} InboundHTLCState::LocalRemoved(ref reason) => { if let &InboundHTLCRemovalReason::Fulfill(_) = reason { } else { @@ -1171,7 +1348,7 @@ impl Channel { } debug_assert!(false, "Tried to fulfill an HTLC that was already fail/fulfilled"); return Ok((None, None)); - }, + } _ => { debug_assert!(false, "Have an inbound HTLC we tried to claim before it was fully committed to"); // Don't return in release mode here so that we can update channel_monitor @@ -1192,13 +1369,16 @@ impl Channel { self.latest_monitor_update_id += 1; let monitor_update = ChannelMonitorUpdate { update_id: self.latest_monitor_update_id, - updates: vec![ChannelMonitorUpdateStep::PaymentPreimage { - payment_preimage: payment_preimage_arg.clone(), - }], + updates: vec![ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_arg.clone() }], }; self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap(); - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 { + if (self.channel_state + & (ChannelState::AwaitingRemoteRevoke as u32 + | ChannelState::PeerDisconnected as u32 + | ChannelState::MonitorUpdateFailed as u32)) + != 0 + { for pending_update in self.holding_cell_htlc_updates.iter() { match pending_update { &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => { @@ -1208,22 +1388,27 @@ impl Channel { debug_assert!(false, "Tried to fulfill an HTLC that was already fulfilled"); return Ok((None, None)); } - }, + } &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, .. } => { if htlc_id_arg == htlc_id { - log_warn!(self, "Have preimage and want to fulfill HTLC with pending failure against channel {}", log_bytes!(self.channel_id())); + log_warn!( + self, + "Have preimage and want to fulfill HTLC with pending failure against channel {}", + log_bytes!(self.channel_id()) + ); // TODO: We may actually be able to switch to a fulfill here, though its // rare enough it may not be worth the complexity burden. debug_assert!(false, "Tried to fulfill an HTLC that was already failed"); return Ok((None, Some(monitor_update))); } - }, + } _ => {} } } log_trace!(self, "Adding HTLC claim to holding_cell! Current state: {}", self.channel_state); self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC { - payment_preimage: payment_preimage_arg, htlc_id: htlc_id_arg, + payment_preimage: payment_preimage_arg, + htlc_id: htlc_id_arg, }); return Ok((None, Some(monitor_update))); } @@ -1236,17 +1421,24 @@ impl Channel { return Ok((None, Some(monitor_update))); } log_trace!(self, "Upgrading HTLC {} to LocalRemoved with a Fulfill!", log_bytes!(htlc.payment_hash.0)); - htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone())); + htlc.state = + InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone())); } - Ok((Some(msgs::UpdateFulfillHTLC { - channel_id: self.channel_id(), - htlc_id: htlc_id_arg, - payment_preimage: payment_preimage_arg, - }), Some(monitor_update))) + Ok(( + Some(msgs::UpdateFulfillHTLC { + channel_id: self.channel_id(), + htlc_id: htlc_id_arg, + payment_preimage: payment_preimage_arg, + }), + Some(monitor_update), + )) } - pub fn get_update_fulfill_htlc_and_commit(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option), ChannelError> { + pub fn get_update_fulfill_htlc_and_commit( + &mut self, htlc_id: u64, payment_preimage: PaymentPreimage, + ) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option), ChannelError> + { match self.get_update_fulfill_htlc(htlc_id, payment_preimage)? { (Some(update_fulfill_htlc), Some(mut monitor_update)) => { let (commitment, mut additional_update) = self.send_commitment_no_status_check()?; @@ -1255,13 +1447,13 @@ impl Channel { self.latest_monitor_update_id = monitor_update.update_id; monitor_update.updates.append(&mut additional_update.updates); Ok((Some((update_fulfill_htlc, commitment)), Some(monitor_update))) - }, + } (Some(update_fulfill_htlc), None) => { let (commitment, monitor_update) = self.send_commitment_no_status_check()?; Ok((Some((update_fulfill_htlc, commitment)), Some(monitor_update))) - }, + } (None, Some(monitor_update)) => Ok((None, Some(monitor_update))), - (None, None) => Ok((None, None)) + (None, None) => Ok((None, None)), } } @@ -1271,7 +1463,9 @@ impl Channel { /// /// Note that it is still possible to hit these assertions in case we find a preimage on-chain /// but then have a reorg which settles on an HTLC-failure on chain. - pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket) -> Result, ChannelError> { + pub fn get_update_fail_htlc( + &mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, + ) -> Result, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { panic!("Was asked to fail an HTLC when channel was not in an operational state"); } @@ -1285,14 +1479,16 @@ impl Channel { for (idx, htlc) in self.pending_inbound_htlcs.iter().enumerate() { if htlc.htlc_id == htlc_id_arg { match htlc.state { - InboundHTLCState::Committed => {}, + InboundHTLCState::Committed => {} InboundHTLCState::LocalRemoved(_) => { debug_assert!(false, "Tried to fail an HTLC that was already fail/fulfilled"); return Ok(None); - }, + } _ => { debug_assert!(false, "Have an inbound HTLC we tried to claim before it was fully committed to"); - return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID")); + return Err(ChannelError::Ignore( + "Unable to find a pending HTLC which matched the given HTLC ID", + )); } } pending_idx = idx; @@ -1303,28 +1499,34 @@ impl Channel { } // Now update local state: - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 { + if (self.channel_state + & (ChannelState::AwaitingRemoteRevoke as u32 + | ChannelState::PeerDisconnected as u32 + | ChannelState::MonitorUpdateFailed as u32)) + != 0 + { for pending_update in self.holding_cell_htlc_updates.iter() { match pending_update { &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => { if htlc_id_arg == htlc_id { debug_assert!(false, "Tried to fail an HTLC that was already fulfilled"); - return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID")); + return Err(ChannelError::Ignore( + "Unable to find a pending HTLC which matched the given HTLC ID", + )); } - }, + } &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, .. } => { if htlc_id_arg == htlc_id { debug_assert!(false, "Tried to fail an HTLC that was already failed"); - return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID")); + return Err(ChannelError::Ignore( + "Unable to find a pending HTLC which matched the given HTLC ID", + )); } - }, + } _ => {} } } - self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::FailHTLC { - htlc_id: htlc_id_arg, - err_packet, - }); + self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::FailHTLC { htlc_id: htlc_id_arg, err_packet }); return Ok(None); } @@ -1333,16 +1535,14 @@ impl Channel { htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(err_packet.clone())); } - Ok(Some(msgs::UpdateFailHTLC { - channel_id: self.channel_id(), - htlc_id: htlc_id_arg, - reason: err_packet - })) + Ok(Some(msgs::UpdateFailHTLC { channel_id: self.channel_id(), htlc_id: htlc_id_arg, reason: err_packet })) } // Message handlers: - pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_features: InitFeatures) -> Result<(), ChannelError> { + pub fn accept_channel( + &mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_features: InitFeatures, + ) -> Result<(), ChannelError> { // Check sanity of message fields: if !self.channel_outbound { return Err(ChannelError::Close("Got an accept_channel message from an inbound peer")); @@ -1362,13 +1562,17 @@ impl Channel { if msg.channel_reserve_satoshis < self.our_dust_limit_satoshis { return Err(ChannelError::Close("Peer never wants payout outputs?")); } - if msg.dust_limit_satoshis > Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis) { + if msg.dust_limit_satoshis + > Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis) + { return Err(ChannelError::Close("Dust limit is bigger than our channel reverse")); } if msg.htlc_minimum_msat >= (self.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000 { return Err(ChannelError::Close("Minimum htlc value is full channel value")); } - if msg.to_self_delay > config.peer_channel_config_limits.their_to_self_delay || msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT { + if msg.to_self_delay > config.peer_channel_config_limits.their_to_self_delay + || msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT + { return Err(ChannelError::Close("They wanted our payments to be delayed by a needlessly long period")); } if msg.max_accepted_htlcs < 1 { @@ -1412,18 +1616,23 @@ impl Channel { None // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel } else { - return Err(ChannelError::Close("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format")); + return Err(ChannelError::Close( + "Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format", + )); } - }, + } // Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel &OptionalField::Absent => { return Err(ChannelError::Close("Peer is signaling upfront_shutdown but we don't get any script. Use 0-length script to opt-out")); } } - } else { None }; + } else { + None + }; self.their_dust_limit_satoshis = msg.dust_limit_satoshis; - self.their_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000); + self.their_max_htlc_value_in_flight_msat = + cmp::min(msg.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000); self.their_channel_reserve_satoshis = msg.channel_reserve_satoshis; self.their_htlc_minimum_msat = msg.htlc_minimum_msat; self.their_to_self_delay = msg.to_self_delay; @@ -1435,7 +1644,7 @@ impl Channel { revocation_basepoint: msg.revocation_basepoint, payment_basepoint: msg.payment_basepoint, delayed_payment_basepoint: msg.delayed_payment_basepoint, - htlc_basepoint: msg.htlc_basepoint + htlc_basepoint: msg.htlc_basepoint, }; self.local_keys.set_remote_channel_pubkeys(&their_pubkeys); @@ -1449,22 +1658,67 @@ impl Channel { Ok(()) } - fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, LocalCommitmentTransaction, Signature), ChannelError> { + fn funding_created_signature( + &mut self, sig: &Signature, + ) -> Result<(Transaction, LocalCommitmentTransaction, Signature), ChannelError> { let funding_script = self.get_funding_redeemscript(); let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?; - let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0; - let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]); + let local_initial_commitment_tx = self + .build_commitment_transaction( + self.cur_local_commitment_transaction_number, + &local_keys, + true, + false, + self.feerate_per_kw, + ) + .0; + let local_sighash = hash_to_message!( + &bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all( + &local_initial_commitment_tx.input[0], + &funding_script, + self.channel_value_satoshis + )[..] + ); // They sign the "local" commitment transaction... - secp_check!(self.secp_ctx.verify(&local_sighash, &sig, self.their_funding_pubkey()), "Invalid funding_created signature from peer"); + secp_check!( + self.secp_ctx.verify(&local_sighash, &sig, self.their_funding_pubkey()), + "Invalid funding_created signature from peer" + ); - let localtx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, sig.clone(), &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey(), local_keys, self.feerate_per_kw, Vec::new()); + let localtx = LocalCommitmentTransaction::new_missing_local_sig( + local_initial_commitment_tx, + sig.clone(), + &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), + self.their_funding_pubkey(), + local_keys, + self.feerate_per_kw, + Vec::new(), + ); let remote_keys = self.build_remote_transaction_keys()?; - let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0; - let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) - .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0; + let remote_initial_commitment_tx = self + .build_commitment_transaction( + self.cur_remote_commitment_transaction_number, + &remote_keys, + false, + false, + self.feerate_per_kw, + ) + .0; + let remote_signature = self + .local_keys + .sign_remote_commitment( + self.feerate_per_kw, + &remote_initial_commitment_tx, + &remote_keys, + &Vec::new(), + self.our_to_self_delay, + &self.secp_ctx, + ) + .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))? + .0; // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish. Ok((remote_initial_commitment_tx, localtx, remote_signature)) @@ -1474,7 +1728,9 @@ impl Channel { &self.their_pubkeys.as_ref().expect("their_funding_pubkey() only allowed after accept_channel").funding_pubkey } - pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), ChannelError> { + pub fn funding_created( + &mut self, msg: &msgs::FundingCreated, + ) -> Result<(msgs::FundingSigned, ChannelMonitor), ChannelError> { if self.channel_outbound { return Err(ChannelError::Close("Received funding_created for an outbound channel?")); } @@ -1484,28 +1740,31 @@ impl Channel { // channel. return Err(ChannelError::Close("Received funding_created after we got the channel!")); } - if self.commitment_secrets.get_min_seen_secret() != (1 << 48) || - self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER || - self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER { + if self.commitment_secrets.get_min_seen_secret() != (1 << 48) + || self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER + || self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER + { panic!("Should not have advanced channel commitment tx numbers prior to funding_created"); } let funding_txo = OutPoint::new(msg.funding_txid, msg.funding_output_index); self.funding_txo = Some(funding_txo.clone()); - let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature) { - Ok(res) => res, - Err(e) => { - self.funding_txo = None; - return Err(e); - } - }; + let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature) = + match self.funding_created_signature(&msg.signature) { + Ok(res) => res, + Err(e) => { + self.funding_txo = None; + return Err(e); + } + }; // Now that we're past error-generating stuff, update our local state: let their_pubkeys = self.their_pubkeys.as_ref().unwrap(); let funding_redeemscript = self.get_funding_redeemscript(); let funding_txo_script = funding_redeemscript.to_v0_p2wsh(); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! create_monitor { () => { { let mut channel_monitor = ChannelMonitor::new(self.local_keys.clone(), @@ -1530,10 +1789,7 @@ impl Channel { self.cur_remote_commitment_transaction_number -= 1; self.cur_local_commitment_transaction_number -= 1; - Ok((msgs::FundingSigned { - channel_id: self.channel_id, - signature: our_signature - }, channel_monitor)) + Ok((msgs::FundingSigned { channel_id: self.channel_id, signature: our_signature }, channel_monitor)) } /// Handles a funding_signed message from the remote end. @@ -1545,20 +1801,43 @@ impl Channel { if self.channel_state & !(ChannelState::MonitorUpdateFailed as u32) != ChannelState::FundingCreated as u32 { return Err(ChannelError::Close("Received funding_signed in strange state!")); } - if self.commitment_secrets.get_min_seen_secret() != (1 << 48) || - self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER || - self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER { + if self.commitment_secrets.get_min_seen_secret() != (1 << 48) + || self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER + || self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER + { panic!("Should not have advanced channel commitment tx numbers prior to funding_created"); } let funding_script = self.get_funding_redeemscript(); let remote_keys = self.build_remote_transaction_keys()?; - let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0; + let remote_initial_commitment_tx = self + .build_commitment_transaction( + self.cur_remote_commitment_transaction_number, + &remote_keys, + false, + false, + self.feerate_per_kw, + ) + .0; let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?; - let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0; - let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]); + let local_initial_commitment_tx = self + .build_commitment_transaction( + self.cur_local_commitment_transaction_number, + &local_keys, + true, + false, + self.feerate_per_kw, + ) + .0; + let local_sighash = hash_to_message!( + &bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all( + &local_initial_commitment_tx.input[0], + &funding_script, + self.channel_value_satoshis + )[..] + ); let their_funding_pubkey = &self.their_pubkeys.as_ref().unwrap().funding_pubkey; @@ -1571,6 +1850,7 @@ impl Channel { let funding_redeemscript = self.get_funding_redeemscript(); let funding_txo = self.funding_txo.as_ref().unwrap(); let funding_txo_script = funding_redeemscript.to_v0_p2wsh(); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! create_monitor { () => { { let local_commitment_tx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx.clone(), msg.signature.clone(), &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), their_funding_pubkey, local_keys.clone(), self.feerate_per_kw, Vec::new()); @@ -1618,7 +1898,8 @@ impl Channel { self.cur_remote_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1) || // If we reconnected before sending our funding locked they may still resend theirs: (self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) == - (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32)) { + (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32)) + { if self.their_cur_commitment_point != Some(msg.next_per_commitment_point) { return Err(ChannelError::Close("Peer sent a reconnect funding_locked with a different point")); } @@ -1667,12 +1948,23 @@ impl Channel { /// corner case properly. pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) { // Note that we have to handle overflow due to the above case. - (cmp::min(self.channel_value_satoshis as i64 * 1000 - self.value_to_self_msat as i64 - self.get_inbound_pending_htlc_stats().1 as i64, 0) as u64, - cmp::min(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64) + ( + cmp::min( + self.channel_value_satoshis as i64 * 1000 + - self.value_to_self_msat as i64 + - self.get_inbound_pending_htlc_stats().1 as i64, + 0, + ) as u64, + cmp::min(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64, + ) } - pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingHTLCStatus) -> Result<(), ChannelError> { - if (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32) { + pub fn update_add_htlc( + &mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingHTLCStatus, + ) -> Result<(), ChannelError> { + if (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) + != (ChannelState::ChannelFunded as u32) + { return Err(ChannelError::Close("Got add HTLC message when channel was not in an operational state")); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { @@ -1693,7 +1985,9 @@ impl Channel { return Err(ChannelError::Close("Remote tried to push more than our max accepted HTLCs")); } // Check our_max_htlc_value_in_flight_msat - if htlc_inbound_value_msat + msg.amount_msat > Channel::::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) { + if htlc_inbound_value_msat + msg.amount_msat + > Channel::::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) + { return Err(ChannelError::Close("Remote HTLC add would put them over our max HTLC value")); } // Check our_channel_reserve_satoshis (we're getting paid, so they have to at least meet @@ -1716,7 +2010,11 @@ impl Channel { removed_outbound_total_msat += htlc.amount_msat; } } - if htlc_inbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 + removed_outbound_total_msat { + if htlc_inbound_value_msat + msg.amount_msat + self.value_to_self_msat + > (self.channel_value_satoshis + - Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) + * 1000 + removed_outbound_total_msat + { return Err(ChannelError::Close("Remote HTLC add would put them over their reserve value")); } if self.next_remote_htlc_id != msg.htlc_id { @@ -1746,24 +2044,35 @@ impl Channel { /// Marks an outbound HTLC which we have received update_fail/fulfill/malformed #[inline] - fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option, fail_reason: Option) -> Result<&HTLCSource, ChannelError> { + fn mark_outbound_htlc_removed( + &mut self, htlc_id: u64, check_preimage: Option, fail_reason: Option, + ) -> Result<&HTLCSource, ChannelError> { for htlc in self.pending_outbound_htlcs.iter_mut() { if htlc.htlc_id == htlc_id { match check_preimage { - None => {}, - Some(payment_hash) => + None => {} + Some(payment_hash) => { if payment_hash != htlc.payment_hash { return Err(ChannelError::Close("Remote tried to fulfill HTLC with an incorrect preimage")); } + } }; match htlc.state { - OutboundHTLCState::LocalAnnounced(_) => - return Err(ChannelError::Close("Remote tried to fulfill/fail HTLC before it had been committed")), + OutboundHTLCState::LocalAnnounced(_) => { + return Err(ChannelError::Close( + "Remote tried to fulfill/fail HTLC before it had been committed", + )) + } OutboundHTLCState::Committed => { htlc.state = OutboundHTLCState::RemoteRemoved(fail_reason); - }, - OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) | OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) | OutboundHTLCState::RemoteRemoved(_) => - return Err(ChannelError::Close("Remote tried to fulfill/fail HTLC that they'd already fulfilled/failed")), + } + OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) + | OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) + | OutboundHTLCState::RemoteRemoved(_) => { + return Err(ChannelError::Close( + "Remote tried to fulfill/fail HTLC that they'd already fulfilled/failed", + )) + } } return Ok(&htlc.source); } @@ -1783,7 +2092,9 @@ impl Channel { self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|source| source.clone()) } - pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> { + pub fn update_fail_htlc( + &mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason, + ) -> Result<(), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got fail HTLC message when channel was not in an operational state")); } @@ -1795,32 +2106,58 @@ impl Channel { Ok(()) } - pub fn update_fail_malformed_htlc<'a>(&mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> { + pub fn update_fail_malformed_htlc<'a>( + &mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason, + ) -> Result<(), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { - return Err(ChannelError::Close("Got fail malformed HTLC message when channel was not in an operational state")); + return Err(ChannelError::Close( + "Got fail malformed HTLC message when channel was not in an operational state", + )); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err(ChannelError::Close("Peer sent update_fail_malformed_htlc when we needed a channel_reestablish")); + return Err(ChannelError::Close( + "Peer sent update_fail_malformed_htlc when we needed a channel_reestablish", + )); } self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason))?; Ok(()) } - pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned, fee_estimator: &F) -> Result<(msgs::RevokeAndACK, Option, Option, ChannelMonitorUpdate), (Option, ChannelError)> where F::Target: FeeEstimator { + pub fn commitment_signed( + &mut self, msg: &msgs::CommitmentSigned, fee_estimator: &F, + ) -> Result< + (msgs::RevokeAndACK, Option, Option, ChannelMonitorUpdate), + (Option, ChannelError), + > + where + F::Target: FeeEstimator, + { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { - return Err((None, ChannelError::Close("Got commitment signed message when channel was not in an operational state"))); + return Err(( + None, + ChannelError::Close("Got commitment signed message when channel was not in an operational state"), + )); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err((None, ChannelError::Close("Peer sent commitment_signed when we needed a channel_reestablish"))); + return Err(( + None, + ChannelError::Close("Peer sent commitment_signed when we needed a channel_reestablish"), + )); } - if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK && self.last_sent_closing_fee.is_some() { - return Err((None, ChannelError::Close("Peer sent commitment_signed after we'd started exchanging closing_signeds"))); + if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK + && self.last_sent_closing_fee.is_some() + { + return Err(( + None, + ChannelError::Close("Peer sent commitment_signed after we'd started exchanging closing_signeds"), + )); } let funding_script = self.get_funding_redeemscript(); - let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number).map_err(|e| (None, e))?; + let local_keys = + self.build_local_transaction_keys(self.cur_local_commitment_transaction_number).map_err(|e| (None, e))?; let mut update_fee = false; let feerate_per_kw = if !self.channel_outbound && self.pending_update_fee.is_some() { @@ -1831,13 +2168,33 @@ impl Channel { }; let mut local_commitment_tx = { - let mut commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, feerate_per_kw); - let htlcs_cloned: Vec<_> = commitment_tx.2.drain(..).map(|htlc| (htlc.0, htlc.1.map(|h| h.clone()))).collect(); + let mut commitment_tx = self.build_commitment_transaction( + self.cur_local_commitment_transaction_number, + &local_keys, + true, + false, + feerate_per_kw, + ); + let htlcs_cloned: Vec<_> = + commitment_tx.2.drain(..).map(|htlc| (htlc.0, htlc.1.map(|h| h.clone()))).collect(); (commitment_tx.0, commitment_tx.1, htlcs_cloned) }; let local_commitment_txid = local_commitment_tx.0.txid(); - let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all(&local_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]); - log_trace!(self, "Checking commitment tx signature {} by key {} against tx {} with redeemscript {}", log_bytes!(msg.signature.serialize_compact()[..]), log_bytes!(self.their_funding_pubkey().serialize()), encode::serialize_hex(&local_commitment_tx.0), encode::serialize_hex(&funding_script)); + let local_sighash = hash_to_message!( + &bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all( + &local_commitment_tx.0.input[0], + &funding_script, + self.channel_value_satoshis + )[..] + ); + log_trace!( + self, + "Checking commitment tx signature {} by key {} against tx {} with redeemscript {}", + log_bytes!(msg.signature.serialize_compact()[..]), + log_bytes!(self.their_funding_pubkey().serialize()), + encode::serialize_hex(&local_commitment_tx.0), + encode::serialize_hex(&funding_script) + ); if let Err(_) = self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey()) { return Err((None, ChannelError::Close("Invalid commitment tx signature from peer"))); } @@ -1845,9 +2202,13 @@ impl Channel { //If channel fee was updated by funder confirm funder can afford the new fee rate when applied to the current local commitment transaction if update_fee { let num_htlcs = local_commitment_tx.1; - let total_fee: u64 = feerate_per_kw as u64 * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000; + let total_fee: u64 = feerate_per_kw as u64 + * (COMMITMENT_TX_BASE_WEIGHT + (num_htlcs as u64) * COMMITMENT_TX_WEIGHT_PER_HTLC) + / 1000; - if self.channel_value_satoshis - self.value_to_self_msat / 1000 < total_fee + self.their_channel_reserve_satoshis { + if self.channel_value_satoshis - self.value_to_self_msat / 1000 + < total_fee + self.their_channel_reserve_satoshis + { return Err((None, ChannelError::Close("Funding remote cannot afford proposed new fee"))); } } @@ -1862,10 +2223,24 @@ impl Channel { let mut htlcs_and_sigs = Vec::with_capacity(local_commitment_tx.2.len()); for (idx, (htlc, source)) in local_commitment_tx.2.drain(..).enumerate() { if let Some(_) = htlc.transaction_output_index { - let htlc_tx = self.build_htlc_transaction(&local_commitment_txid, &htlc, true, &local_keys, feerate_per_kw); + let htlc_tx = + self.build_htlc_transaction(&local_commitment_txid, &htlc, true, &local_keys, feerate_per_kw); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &local_keys); - log_trace!(self, "Checking HTLC tx signature {} by key {} against tx {} with redeemscript {}", log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(local_keys.b_htlc_key.serialize()), encode::serialize_hex(&htlc_tx), encode::serialize_hex(&htlc_redeemscript)); - let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]); + log_trace!( + self, + "Checking HTLC tx signature {} by key {} against tx {} with redeemscript {}", + log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), + log_bytes!(local_keys.b_htlc_key.serialize()), + encode::serialize_hex(&htlc_tx), + encode::serialize_hex(&htlc_redeemscript) + ); + let htlc_sighash = hash_to_message!( + &bip143::SighashComponents::new(&htlc_tx).sighash_all( + &htlc_tx.input[0], + &htlc_redeemscript, + htlc.amount_msat / 1000 + )[..] + ); if let Err(_) = self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key) { return Err((None, ChannelError::Close("Invalid HTLC tx signature from peer"))); } @@ -1877,8 +2252,14 @@ impl Channel { } } - let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)); - let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), self.cur_local_commitment_transaction_number + 1); + let next_per_commitment_point = PublicKey::from_secret_key( + &self.secp_ctx, + &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1), + ); + let per_commitment_secret = chan_utils::build_commitment_secret( + self.local_keys.commitment_seed(), + self.cur_local_commitment_transaction_number + 1, + ); // Update state now that we've passed all the can-fail calls... let mut need_our_commitment = false; @@ -1901,25 +2282,38 @@ impl Channel { let mut monitor_update = ChannelMonitorUpdate { update_id: self.latest_monitor_update_id, updates: vec![ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { - commitment_tx: LocalCommitmentTransaction::new_missing_local_sig(local_commitment_tx.0, msg.signature.clone(), &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), &their_funding_pubkey, local_keys, self.feerate_per_kw, htlcs_without_source), - htlc_outputs: htlcs_and_sigs - }] + commitment_tx: LocalCommitmentTransaction::new_missing_local_sig( + local_commitment_tx.0, + msg.signature.clone(), + &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), + &their_funding_pubkey, + local_keys, + self.feerate_per_kw, + htlcs_without_source, + ), + htlc_outputs: htlcs_and_sigs, + }], }; self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap(); for htlc in self.pending_inbound_htlcs.iter_mut() { let new_forward = if let &InboundHTLCState::RemoteAnnounced(ref forward_info) = &htlc.state { Some(forward_info.clone()) - } else { None }; + } else { + None + }; if let Some(forward_info) = new_forward { htlc.state = InboundHTLCState::AwaitingRemoteRevokeToAnnounce(forward_info); need_our_commitment = true; } } for htlc in self.pending_outbound_htlcs.iter_mut() { - if let Some(fail_reason) = if let &mut OutboundHTLCState::RemoteRemoved(ref mut fail_reason) = &mut htlc.state { - Some(fail_reason.take()) - } else { None } { + if let Some(fail_reason) = + if let &mut OutboundHTLCState::RemoteRemoved(ref mut fail_reason) = &mut htlc.state { + Some(fail_reason.take()) + } else { + None + } { htlc.state = OutboundHTLCState::AwaitingRemoteRevokeToRemove(fail_reason); need_our_commitment = true; } @@ -1947,36 +2341,50 @@ impl Channel { } // TODO: Call maybe_propose_first_closing_signed on restoration (or call it here and // re-send the message on restoration) - return Err((Some(monitor_update), ChannelError::Ignore("Previous monitor update failure prevented generation of RAA"))); - } - - let (our_commitment_signed, closing_signed) = if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 { - // If we're AwaitingRemoteRevoke we can't send a new commitment here, but that's ok - - // we'll send one right away when we get the revoke_and_ack when we - // free_holding_cell_htlcs(). - let (msg, mut additional_update) = self.send_commitment_no_status_check().map_err(|e| (None, e))?; - // send_commitment_no_status_check may bump latest_monitor_id but we want them to be - // strictly increasing by one, so decrement it here. - self.latest_monitor_update_id = monitor_update.update_id; - monitor_update.updates.append(&mut additional_update.updates); - (Some(msg), None) - } else if !need_our_commitment { - (None, self.maybe_propose_first_closing_signed(fee_estimator)) - } else { (None, None) }; - - Ok((msgs::RevokeAndACK { - channel_id: self.channel_id, - per_commitment_secret: per_commitment_secret, - next_per_commitment_point: next_per_commitment_point, - }, our_commitment_signed, closing_signed, monitor_update)) + return Err(( + Some(monitor_update), + ChannelError::Ignore("Previous monitor update failure prevented generation of RAA"), + )); + } + + let (our_commitment_signed, closing_signed) = + if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 { + // If we're AwaitingRemoteRevoke we can't send a new commitment here, but that's ok - + // we'll send one right away when we get the revoke_and_ack when we + // free_holding_cell_htlcs(). + let (msg, mut additional_update) = self.send_commitment_no_status_check().map_err(|e| (None, e))?; + // send_commitment_no_status_check may bump latest_monitor_id but we want them to be + // strictly increasing by one, so decrement it here. + self.latest_monitor_update_id = monitor_update.update_id; + monitor_update.updates.append(&mut additional_update.updates); + (Some(msg), None) + } else if !need_our_commitment { + (None, self.maybe_propose_first_closing_signed(fee_estimator)) + } else { + (None, None) + }; + + Ok(( + msgs::RevokeAndACK { channel_id: self.channel_id, per_commitment_secret, next_per_commitment_point }, + our_commitment_signed, + closing_signed, + monitor_update, + )) } /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them /// fulfilling or failing the last pending HTLC) - fn free_holding_cell_htlcs(&mut self) -> Result, ChannelError> { + fn free_holding_cell_htlcs( + &mut self, + ) -> Result, ChannelError> { assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0); if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() { - log_trace!(self, "Freeing holding cell with {} HTLC updates{}", self.holding_cell_htlc_updates.len(), if self.holding_cell_update_fee.is_some() { " and a fee update" } else { "" }); + log_trace!( + self, + "Freeing holding cell with {} HTLC updates{}", + self.holding_cell_htlc_updates.len(), + if self.holding_cell_update_fee.is_some() { " and a fee update" } else { "" } + ); let mut monitor_update = ChannelMonitorUpdate { update_id: self.latest_monitor_update_id + 1, // We don't increment this yet! @@ -1995,26 +2403,45 @@ impl Channel { // the limit. In case it's less rare than I anticipate, we may want to revisit // handling this case better and maybe fulfilling some of the HTLCs while attempting // to rebalance channels. - if err.is_some() { // We're back to AwaitingRemoteRevoke (or are about to fail the channel) + if err.is_some() { + // We're back to AwaitingRemoteRevoke (or are about to fail the channel) self.holding_cell_htlc_updates.push(htlc_update); } else { match &htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => { - match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) { + &HTLCUpdateAwaitingACK::AddHTLC { + amount_msat, + cltv_expiry, + ref payment_hash, + ref source, + ref onion_routing_packet, + .. + } => { + match self.send_htlc( + amount_msat, + *payment_hash, + cltv_expiry, + source.clone(), + onion_routing_packet.clone(), + ) { Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), Err(e) => { match e { ChannelError::Ignore(ref msg) => { - log_info!(self, "Failed to send HTLC with payment_hash {} due to {}", log_bytes!(payment_hash.0), msg); - }, + log_info!( + self, + "Failed to send HTLC with payment_hash {} due to {}", + log_bytes!(payment_hash.0), + msg + ); + } _ => { log_info!(self, "Failed to send HTLC with payment_hash {} resulting in a channel closure during holding_cell freeing", log_bytes!(payment_hash.0)); - }, + } } err = Some(e); } } - }, + } &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => { match self.get_update_fulfill_htlc(htlc_id, *payment_preimage) { Ok((update_fulfill_msg_option, additional_monitor_update_opt)) => { @@ -2022,26 +2449,26 @@ impl Channel { if let Some(mut additional_monitor_update) = additional_monitor_update_opt { monitor_update.updates.append(&mut additional_monitor_update.updates); } - }, + } Err(e) => { - if let ChannelError::Ignore(_) = e {} - else { + if let ChannelError::Ignore(_) = e { + } else { panic!("Got a non-IgnoreError action trying to fulfill holding cell HTLC"); } } } - }, + } &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => { match self.get_update_fail_htlc(htlc_id, err_packet.clone()) { Ok(update_fail_msg_option) => update_fail_htlcs.push(update_fail_msg_option.unwrap()), Err(e) => { - if let ChannelError::Ignore(_) = e {} - else { + if let ChannelError::Ignore(_) = e { + } else { panic!("Got a non-IgnoreError action trying to fail holding cell HTLC"); } } } - }, + } } if err.is_some() { self.holding_cell_htlc_updates.push(htlc_update); @@ -2057,21 +2484,22 @@ impl Channel { //fail it back the route, if it's a temporary issue we can ignore it... match err { None => { - if update_add_htlcs.is_empty() && update_fulfill_htlcs.is_empty() && update_fail_htlcs.is_empty() && self.holding_cell_update_fee.is_none() { + if update_add_htlcs.is_empty() + && update_fulfill_htlcs.is_empty() + && update_fail_htlcs.is_empty() + && self.holding_cell_update_fee.is_none() + { // This should never actually happen and indicates we got some Errs back // from update_fulfill_htlc/update_fail_htlc, but we handle it anyway in // case there is some strange way to hit duplicate HTLC removes. return Ok(None); } let update_fee = if let Some(feerate) = self.holding_cell_update_fee { - self.pending_update_fee = self.holding_cell_update_fee.take(); - Some(msgs::UpdateFee { - channel_id: self.channel_id, - feerate_per_kw: feerate as u32, - }) - } else { - None - }; + self.pending_update_fee = self.holding_cell_update_fee.take(); + Some(msgs::UpdateFee { channel_id: self.channel_id, feerate_per_kw: feerate as u32 }) + } else { + None + }; let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check()?; // send_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id @@ -2079,16 +2507,19 @@ impl Channel { self.latest_monitor_update_id = monitor_update.update_id; monitor_update.updates.append(&mut additional_update.updates); - Ok(Some((msgs::CommitmentUpdate { - update_add_htlcs, - update_fulfill_htlcs, - update_fail_htlcs, - update_fail_malformed_htlcs: Vec::new(), - update_fee: update_fee, - commitment_signed, - }, monitor_update))) - }, - Some(e) => Err(e) + Ok(Some(( + msgs::CommitmentUpdate { + update_add_htlcs, + update_fulfill_htlcs, + update_fail_htlcs, + update_fail_malformed_htlcs: Vec::new(), + update_fee, + commitment_signed, + }, + monitor_update, + ))) + } + Some(e) => Err(e), } } else { Ok(None) @@ -2100,8 +2531,20 @@ impl Channel { /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail, /// generating an appropriate error *after* the channel state has been updated based on the /// revoke_and_ack message. - pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &F) -> Result<(Option, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option, ChannelMonitorUpdate), ChannelError> - where F::Target: FeeEstimator + pub fn revoke_and_ack( + &mut self, msg: &msgs::RevokeAndACK, fee_estimator: &F, + ) -> Result< + ( + Option, + Vec<(PendingHTLCInfo, u64)>, + Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, + Option, + ChannelMonitorUpdate, + ), + ChannelError, + > + where + F::Target: FeeEstimator, { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got revoke/ACK message when channel was not in an operational state")); @@ -2109,13 +2552,24 @@ impl Channel { if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent revoke_and_ack when we needed a channel_reestablish")); } - if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK && self.last_sent_closing_fee.is_some() { + if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK + && self.last_sent_closing_fee.is_some() + { return Err(ChannelError::Close("Peer sent revoke_and_ack after we'd started exchanging closing_signeds")); } if let Some(their_prev_commitment_point) = self.their_prev_commitment_point { - if PublicKey::from_secret_key(&self.secp_ctx, &secp_check!(SecretKey::from_slice(&msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret")) != their_prev_commitment_point { - return Err(ChannelError::Close("Got a revoke commitment secret which didn't correspond to their current pubkey")); + if PublicKey::from_secret_key( + &self.secp_ctx, + &secp_check!( + SecretKey::from_slice(&msg.per_commitment_secret), + "Peer provided an invalid per_commitment_secret" + ), + ) != their_prev_commitment_point + { + return Err(ChannelError::Close( + "Got a revoke commitment secret which didn't correspond to their current pubkey", + )); } } @@ -2130,7 +2584,8 @@ impl Channel { return Err(ChannelError::Close("Received an unexpected revoke_and_ack")); } - self.commitment_secrets.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret) + self.commitment_secrets + .provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret) .map_err(|_| ChannelError::Close("Previous secrets did not match new one"))?; self.latest_monitor_update_id += 1; let mut monitor_update = ChannelMonitorUpdate { @@ -2173,28 +2628,47 @@ impl Channel { value_to_self_msat_diff += htlc.amount_msat as i64; } false - } else { true } + } else { + true + } }); pending_outbound_htlcs.retain(|htlc| { if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref fail_reason) = &htlc.state { - log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", log_bytes!(htlc.payment_hash.0)); - if let Some(reason) = fail_reason.clone() { // We really want take() here, but, again, non-mut ref :( + log_trace!( + logger, + " ...removing outbound AwaitingRemovedRemoteRevoke {}", + log_bytes!(htlc.payment_hash.0) + ); + if let Some(reason) = fail_reason.clone() { + // We really want take() here, but, again, non-mut ref :( revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason)); } else { // They fulfilled, so we sent them money value_to_self_msat_diff -= htlc.amount_msat as i64; } false - } else { true } + } else { + true + } }); for htlc in pending_inbound_htlcs.iter_mut() { let swap = if let &InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) = &htlc.state { - log_trace!(logger, " ...promoting inbound AwaitingRemoteRevokeToAnnounce {} to Committed", log_bytes!(htlc.payment_hash.0)); + log_trace!( + logger, + " ...promoting inbound AwaitingRemoteRevokeToAnnounce {} to Committed", + log_bytes!(htlc.payment_hash.0) + ); true } else if let &InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) = &htlc.state { - log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed", log_bytes!(htlc.payment_hash.0)); + log_trace!( + logger, + " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed", + log_bytes!(htlc.payment_hash.0) + ); true - } else { false }; + } else { + false + }; if swap { let mut state = InboundHTLCState::Committed; mem::swap(&mut state, &mut htlc.state); @@ -2208,15 +2682,21 @@ impl Channel { require_commitment = true; match fail_msg { HTLCFailureMsg::Relay(msg) => { - htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(msg.reason.clone())); + htlc.state = InboundHTLCState::LocalRemoved( + InboundHTLCRemovalReason::FailRelay(msg.reason.clone()), + ); update_fail_htlcs.push(msg) - }, + } HTLCFailureMsg::Malformed(msg) => { - htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailMalformed((msg.sha256_of_onion, msg.failure_code))); + htlc.state = + InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailMalformed(( + msg.sha256_of_onion, + msg.failure_code, + ))); update_fail_malformed_htlcs.push(msg) - }, + } } - }, + } PendingHTLCStatus::Forward(forward_info) => { to_forward_infos.push((forward_info, htlc.htlc_id)); htlc.state = InboundHTLCState::Committed; @@ -2227,13 +2707,24 @@ impl Channel { } for htlc in pending_outbound_htlcs.iter_mut() { if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { - log_trace!(logger, " ...promoting outbound LocalAnnounced {} to Committed", log_bytes!(htlc.payment_hash.0)); + log_trace!( + logger, + " ...promoting outbound LocalAnnounced {} to Committed", + log_bytes!(htlc.payment_hash.0) + ); htlc.state = OutboundHTLCState::Committed; } - if let Some(fail_reason) = if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut fail_reason) = &mut htlc.state { - Some(fail_reason.take()) - } else { None } { - log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", log_bytes!(htlc.payment_hash.0)); + if let Some(fail_reason) = + if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut fail_reason) = &mut htlc.state { + Some(fail_reason.take()) + } else { + None + } { + log_trace!( + logger, + " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", + log_bytes!(htlc.payment_hash.0) + ); htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(fail_reason); require_commitment = true; } @@ -2275,7 +2766,7 @@ impl Channel { } self.monitor_pending_forwards.append(&mut to_forward_infos); self.monitor_pending_failures.append(&mut revoked_htlcs); - return Ok((None, Vec::new(), Vec::new(), None, monitor_update)) + return Ok((None, Vec::new(), Vec::new(), None, monitor_update)); } match self.free_holding_cell_htlcs()? { @@ -2295,7 +2786,7 @@ impl Channel { monitor_update.updates.append(&mut additional_update.updates); Ok((Some(commitment_update), to_forward_infos, revoked_htlcs, None, monitor_update)) - }, + } None => { if require_commitment { let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check()?; @@ -2305,20 +2796,31 @@ impl Channel { self.latest_monitor_update_id = monitor_update.update_id; monitor_update.updates.append(&mut additional_update.updates); - Ok((Some(msgs::CommitmentUpdate { - update_add_htlcs: Vec::new(), - update_fulfill_htlcs: Vec::new(), - update_fail_htlcs, - update_fail_malformed_htlcs, - update_fee: None, - commitment_signed - }), to_forward_infos, revoked_htlcs, None, monitor_update)) + Ok(( + Some(msgs::CommitmentUpdate { + update_add_htlcs: Vec::new(), + update_fulfill_htlcs: Vec::new(), + update_fail_htlcs, + update_fail_malformed_htlcs, + update_fee: None, + commitment_signed, + }), + to_forward_infos, + revoked_htlcs, + None, + monitor_update, + )) } else { - Ok((None, to_forward_infos, revoked_htlcs, self.maybe_propose_first_closing_signed(fee_estimator), monitor_update)) + Ok(( + None, + to_forward_infos, + revoked_htlcs, + self.maybe_propose_first_closing_signed(fee_estimator), + monitor_update, + )) } } } - } /// Adds a pending update to this channel. See the doc for send_htlc for @@ -2335,7 +2837,9 @@ impl Channel { panic!("Cannot update fee while peer is disconnected/we're awaiting a monitor update (ChannelManager should have caught this)"); } - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) { + if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) + == (ChannelState::AwaitingRemoteRevoke as u32) + { self.holding_cell_update_fee = Some(feerate_per_kw); return None; } @@ -2343,19 +2847,18 @@ impl Channel { debug_assert!(self.pending_update_fee.is_none()); self.pending_update_fee = Some(feerate_per_kw); - Some(msgs::UpdateFee { - channel_id: self.channel_id, - feerate_per_kw: feerate_per_kw as u32, - }) + Some(msgs::UpdateFee { channel_id: self.channel_id, feerate_per_kw: feerate_per_kw as u32 }) } - pub fn send_update_fee_and_commit(&mut self, feerate_per_kw: u64) -> Result, ChannelError> { + pub fn send_update_fee_and_commit( + &mut self, feerate_per_kw: u64, + ) -> Result, ChannelError> { match self.send_update_fee(feerate_per_kw) { Some(update_fee) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?; Ok(Some((update_fee, commitment_signed, monitor_update))) - }, - None => Ok(None) + } + None => Ok(None), } } @@ -2386,13 +2889,14 @@ impl Channel { // this HTLC accordingly inbound_drop_count += 1; false - }, - InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_)|InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => { + } + InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) + | InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => { // We received a commitment_signed updating this HTLC and (at least hopefully) // sent a revoke_and_ack (which we can re-transmit) and have heard nothing // in response to it yet, so don't touch it. true - }, + } InboundHTLCState::Committed => true, InboundHTLCState::LocalRemoved(_) => { // We (hopefully) sent a commitment_signed updating this HTLC (which we can @@ -2400,7 +2904,7 @@ impl Channel { // (that we missed). Keep this around for now and if they tell us they missed // the commitment_signed we can re-transmit the update then. true - }, + } } }); self.next_remote_htlc_id -= inbound_drop_count; @@ -2414,14 +2918,12 @@ impl Channel { } } - self.holding_cell_htlc_updates.retain(|htlc_update| { - match htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { - outbound_drops.push((source.clone(), payment_hash.clone())); - false - }, - &HTLCUpdateAwaitingACK::ClaimHTLC {..} | &HTLCUpdateAwaitingACK::FailHTLC {..} => true, + self.holding_cell_htlc_updates.retain(|htlc_update| match htlc_update { + &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { + outbound_drops.push((source.clone(), payment_hash.clone())); + false } + &HTLCUpdateAwaitingACK::ClaimHTLC { .. } | &HTLCUpdateAwaitingACK::FailHTLC { .. } => true, }); self.channel_state |= ChannelState::PeerDisconnected as u32; log_debug!(self, "Peer disconnection resulted in {} remote-announced HTLC drops and {} waiting-to-locally-announced HTLC drops on channel {}", outbound_drops.len(), inbound_drop_count, log_bytes!(self.channel_id())); @@ -2434,7 +2936,10 @@ impl Channel { /// which failed. The messages which were generated from that call which generated the /// monitor update failure must *not* have been sent to the remote end, and must instead /// have been dropped. They will be regenerated when monitor_updating_restored is called. - pub fn monitor_update_failed(&mut self, resend_raa: bool, resend_commitment: bool, mut pending_forwards: Vec<(PendingHTLCInfo, u64)>, mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>) { + pub fn monitor_update_failed( + &mut self, resend_raa: bool, resend_commitment: bool, mut pending_forwards: Vec<(PendingHTLCInfo, u64)>, + mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, + ) { assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0); self.monitor_pending_revoke_and_ack = resend_raa; self.monitor_pending_commitment_signed = resend_commitment; @@ -2448,11 +2953,25 @@ impl Channel { /// Indicates that the latest ChannelMonitor update has been committed by the client /// successfully and we should restore normal operation. Returns messages which should be sent /// to the remote side. - pub fn monitor_updating_restored(&mut self) -> (Option, Option, RAACommitmentOrder, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, bool, Option) { - assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, ChannelState::MonitorUpdateFailed as u32); + pub fn monitor_updating_restored( + &mut self, + ) -> ( + Option, + Option, + RAACommitmentOrder, + Vec<(PendingHTLCInfo, u64)>, + Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, + bool, + Option, + ) { + assert_eq!( + self.channel_state & ChannelState::MonitorUpdateFailed as u32, + ChannelState::MonitorUpdateFailed as u32 + ); self.channel_state &= !(ChannelState::MonitorUpdateFailed as u32); - let needs_broadcast_safe = self.channel_state & (ChannelState::FundingSent as u32) != 0 && self.channel_outbound; + let needs_broadcast_safe = + self.channel_state & (ChannelState::FundingSent as u32) != 0 && self.channel_outbound; // Because we will never generate a FundingBroadcastSafe event when we're in // MonitorUpdateFailed, if we assume the user only broadcast the funding transaction when @@ -2463,13 +2982,13 @@ impl Channel { let funding_locked = if self.monitor_pending_funding_locked { assert!(!self.channel_outbound, "Funding transaction broadcast without FundingBroadcastSafe!"); self.monitor_pending_funding_locked = false; - let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); + let next_per_commitment_secret = + self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret); - Some(msgs::FundingLocked { - channel_id: self.channel_id(), - next_per_commitment_point: next_per_commitment_point, - }) - } else { None }; + Some(msgs::FundingLocked { channel_id: self.channel_id(), next_per_commitment_point }) + } else { + None + }; let mut forwards = Vec::new(); mem::swap(&mut forwards, &mut self.monitor_pending_forwards); @@ -2479,29 +2998,41 @@ impl Channel { if self.channel_state & (ChannelState::PeerDisconnected as u32) != 0 { self.monitor_pending_revoke_and_ack = false; self.monitor_pending_commitment_signed = false; - return (None, None, RAACommitmentOrder::RevokeAndACKFirst, forwards, failures, needs_broadcast_safe, funding_locked); + return ( + None, + None, + RAACommitmentOrder::RevokeAndACKFirst, + forwards, + failures, + needs_broadcast_safe, + funding_locked, + ); } - let raa = if self.monitor_pending_revoke_and_ack { - Some(self.get_last_revoke_and_ack()) - } else { None }; - let commitment_update = if self.monitor_pending_commitment_signed { - Some(self.get_last_commitment_update()) - } else { None }; + let raa = if self.monitor_pending_revoke_and_ack { Some(self.get_last_revoke_and_ack()) } else { None }; + let commitment_update = + if self.monitor_pending_commitment_signed { Some(self.get_last_commitment_update()) } else { None }; self.monitor_pending_revoke_and_ack = false; self.monitor_pending_commitment_signed = false; let order = self.resend_order.clone(); - log_trace!(self, "Restored monitor updating resulting in {}{} commitment update and {} RAA, with {} first", + log_trace!( + self, + "Restored monitor updating resulting in {}{} commitment update and {} RAA, with {} first", if needs_broadcast_safe { "a funding broadcast safe, " } else { "" }, if commitment_update.is_some() { "a" } else { "no" }, if raa.is_some() { "an" } else { "no" }, - match order { RAACommitmentOrder::CommitmentFirst => "commitment", RAACommitmentOrder::RevokeAndACKFirst => "RAA"}); + match order { + RAACommitmentOrder::CommitmentFirst => "commitment", + RAACommitmentOrder::RevokeAndACKFirst => "RAA", + } + ); (raa, commitment_update, order, forwards, failures, needs_broadcast_safe, funding_locked) } pub fn update_fee(&mut self, fee_estimator: &F, msg: &msgs::UpdateFee) -> Result<(), ChannelError> - where F::Target: FeeEstimator + where + F::Target: FeeEstimator, { if self.channel_outbound { return Err(ChannelError::Close("Non-funding remote tried to update channel fee")); @@ -2516,13 +3047,15 @@ impl Channel { } fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK { - let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number)); - let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), self.cur_local_commitment_transaction_number + 2); - msgs::RevokeAndACK { - channel_id: self.channel_id, - per_commitment_secret, - next_per_commitment_point, - } + let next_per_commitment_point = PublicKey::from_secret_key( + &self.secp_ctx, + &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number), + ); + let per_commitment_secret = chan_utils::build_commitment_secret( + self.local_keys.commitment_seed(), + self.cur_local_commitment_transaction_number + 2, + ); + msgs::RevokeAndACK { channel_id: self.channel_id, per_commitment_secret, next_per_commitment_point } } fn get_last_commitment_update(&self) -> msgs::CommitmentUpdate { @@ -2551,9 +3084,9 @@ impl Channel { update_fail_htlcs.push(msgs::UpdateFailHTLC { channel_id: self.channel_id(), htlc_id: htlc.htlc_id, - reason: err_packet.clone() + reason: err_packet.clone(), }); - }, + } &InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => { update_fail_malformed_htlcs.push(msgs::UpdateFailMalformedHTLC { channel_id: self.channel_id(), @@ -2561,14 +3094,14 @@ impl Channel { sha256_of_onion: sha256_of_onion.clone(), failure_code: failure_code.clone(), }); - }, + } &InboundHTLCRemovalReason::Fulfill(ref payment_preimage) => { update_fulfill_htlcs.push(msgs::UpdateFulfillHTLC { channel_id: self.channel_id(), htlc_id: htlc.htlc_id, payment_preimage: payment_preimage.clone(), }); - }, + } } } } @@ -2576,15 +3109,33 @@ impl Channel { log_trace!(self, "Regenerated latest commitment update with {} update_adds, {} update_fulfills, {} update_fails, and {} update_fail_malformeds", update_add_htlcs.len(), update_fulfill_htlcs.len(), update_fail_htlcs.len(), update_fail_malformed_htlcs.len()); msgs::CommitmentUpdate { - update_add_htlcs, update_fulfill_htlcs, update_fail_htlcs, update_fail_malformed_htlcs, + update_add_htlcs, + update_fulfill_htlcs, + update_fail_htlcs, + update_fail_malformed_htlcs, update_fee: None, - commitment_signed: self.send_commitment_no_state_update().expect("It looks like we failed to re-generate a commitment_signed we had previously sent?").0, + commitment_signed: self + .send_commitment_no_state_update() + .expect("It looks like we failed to re-generate a commitment_signed we had previously sent?") + .0, } } /// May panic if some calls other than message-handling calls (which will all Err immediately) /// have been called between remove_uncommitted_htlcs_and_mark_paused and this call. - pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, Option, RAACommitmentOrder, Option), ChannelError> { + pub fn channel_reestablish( + &mut self, msg: &msgs::ChannelReestablish, + ) -> Result< + ( + Option, + Option, + Option, + Option, + RAACommitmentOrder, + Option, + ), + ChannelError, + > { if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 { // While BOLT 2 doesn't indicate explicitly we should error this channel here, it // almost certainly indicates we are going to end up out-of-sync in some way, so we @@ -2592,24 +3143,32 @@ impl Channel { return Err(ChannelError::Close("Peer sent a loose channel_reestablish not after reconnect")); } - if msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER || - msg.next_local_commitment_number == 0 { + if msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER + || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER + || msg.next_local_commitment_number == 0 + { return Err(ChannelError::Close("Peer sent a garbage channel_reestablish")); } if msg.next_remote_commitment_number > 0 { match msg.data_loss_protect { OptionalField::Present(ref data_loss) => { - if chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1) != data_loss.your_last_per_commitment_secret { + if chan_utils::build_commitment_secret( + self.local_keys.commitment_seed(), + INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1, + ) != data_loss.your_last_per_commitment_secret + { return Err(ChannelError::Close("Peer sent a garbage channel_reestablish with secret key not matching the commitment height provided")); } - if msg.next_remote_commitment_number > INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number { + if msg.next_remote_commitment_number + > INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number + { self.latest_monitor_update_id += 1; let monitor_update = ChannelMonitorUpdate { update_id: self.latest_monitor_update_id, updates: vec![ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { - their_current_per_commitment_point: data_loss.my_current_per_commitment_point - }] + their_current_per_commitment_point: data_loss.my_current_per_commitment_point, + }], }; self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap(); return Err(ChannelError::CloseDelayBroadcast { @@ -2617,7 +3176,7 @@ impl Channel { update: monitor_update }); } - }, + } OptionalField::Absent => {} } } @@ -2627,37 +3186,48 @@ impl Channel { self.channel_state &= !(ChannelState::PeerDisconnected as u32); let shutdown_msg = if self.channel_state & (ChannelState::LocalShutdownSent as u32) != 0 { - Some(msgs::Shutdown { - channel_id: self.channel_id, - scriptpubkey: self.get_closing_scriptpubkey(), - }) - } else { None }; + Some(msgs::Shutdown { channel_id: self.channel_id, scriptpubkey: self.get_closing_scriptpubkey() }) + } else { + None + }; if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 { // If we're waiting on a monitor update, we shouldn't re-send any funding_locked's. - if self.channel_state & (ChannelState::OurFundingLocked as u32) == 0 || - self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 { + if self.channel_state & (ChannelState::OurFundingLocked as u32) == 0 + || self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 + { if msg.next_remote_commitment_number != 0 { - return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet")); + return Err(ChannelError::Close( + "Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet", + )); } // Short circuit the whole handler as there is nothing we can resend them return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg)); } // We have OurFundingLocked set! - let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); + let next_per_commitment_secret = + self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret); - return Ok((Some(msgs::FundingLocked { - channel_id: self.channel_id(), - next_per_commitment_point: next_per_commitment_point, - }), None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg)); - } - - let required_revoke = if msg.next_remote_commitment_number + 1 == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number { + return Ok(( + Some(msgs::FundingLocked { channel_id: self.channel_id(), next_per_commitment_point }), + None, + None, + None, + RAACommitmentOrder::CommitmentFirst, + shutdown_msg, + )); + } + + let required_revoke = if msg.next_remote_commitment_number + 1 + == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number + { // Remote isn't waiting on any RevokeAndACK from us! // Note that if we need to repeat our FundingLocked we'll do that in the next if block. None - } else if msg.next_remote_commitment_number + 1 == (INITIAL_COMMITMENT_NUMBER - 1) - self.cur_local_commitment_transaction_number { + } else if msg.next_remote_commitment_number + 1 + == (INITIAL_COMMITMENT_NUMBER - 1) - self.cur_local_commitment_transaction_number + { if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 { self.monitor_pending_revoke_and_ack = true; None @@ -2665,24 +3235,30 @@ impl Channel { Some(self.get_last_revoke_and_ack()) } } else { - return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old local commitment transaction")); + return Err(ChannelError::Close( + "Peer attempted to reestablish channel with a very old local commitment transaction", + )); }; // We increment cur_remote_commitment_transaction_number only upon receipt of // revoke_and_ack, not on sending commitment_signed, so we add one if have // AwaitingRemoteRevoke set, which indicates we sent a commitment_signed but haven't gotten // the corresponding revoke_and_ack back yet. - let our_next_remote_commitment_number = INITIAL_COMMITMENT_NUMBER - self.cur_remote_commitment_transaction_number + if (self.channel_state & ChannelState::AwaitingRemoteRevoke as u32) != 0 { 1 } else { 0 }; + let our_next_remote_commitment_number = INITIAL_COMMITMENT_NUMBER + - self.cur_remote_commitment_transaction_number + + if (self.channel_state & ChannelState::AwaitingRemoteRevoke as u32) != 0 { 1 } else { 0 }; - let resend_funding_locked = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number == 1 { + let resend_funding_locked = if msg.next_local_commitment_number == 1 + && INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number == 1 + { // We should never have to worry about MonitorUpdateFailed resending FundingLocked - let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); + let next_per_commitment_secret = + self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret); - Some(msgs::FundingLocked { - channel_id: self.channel_id(), - next_per_commitment_point: next_per_commitment_point, - }) - } else { None }; + Some(msgs::FundingLocked { channel_id: self.channel_id(), next_per_commitment_point }) + } else { + None + }; if msg.next_local_commitment_number == our_next_remote_commitment_number { if required_revoke.is_some() { @@ -2691,25 +3267,63 @@ impl Channel { log_debug!(self, "Reconnected channel {} with no loss", log_bytes!(self.channel_id())); } - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) == 0 { + if (self.channel_state + & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) + == 0 + { // We're up-to-date and not waiting on a remote revoke (if we are our // channel_reestablish should result in them sending a revoke_and_ack), but we may // have received some updates while we were disconnected. Free the holding cell // now! match self.free_holding_cell_htlcs() { Err(ChannelError::Close(msg)) => return Err(ChannelError::Close(msg)), - Err(ChannelError::Ignore(_)) | Err(ChannelError::CloseDelayBroadcast { .. }) => panic!("Got non-channel-failing result from free_holding_cell_htlcs"), - Ok(Some((commitment_update, monitor_update))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), shutdown_msg)), - Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg)), + Err(ChannelError::Ignore(_)) | Err(ChannelError::CloseDelayBroadcast { .. }) => { + panic!("Got non-channel-failing result from free_holding_cell_htlcs") + } + Ok(Some((commitment_update, monitor_update))) => { + return Ok(( + resend_funding_locked, + required_revoke, + Some(commitment_update), + Some(monitor_update), + self.resend_order.clone(), + shutdown_msg, + )) + } + Ok(None) => { + return Ok(( + resend_funding_locked, + required_revoke, + None, + None, + self.resend_order.clone(), + shutdown_msg, + )) + } } } else { - return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg)); + return Ok(( + resend_funding_locked, + required_revoke, + None, + None, + self.resend_order.clone(), + shutdown_msg, + )); } } else if msg.next_local_commitment_number == our_next_remote_commitment_number - 1 { if required_revoke.is_some() { - log_debug!(self, "Reconnected channel {} with lost outbound RAA and lost remote commitment tx", log_bytes!(self.channel_id())); + log_debug!( + self, + "Reconnected channel {} with lost outbound RAA and lost remote commitment tx", + log_bytes!(self.channel_id()) + ); } else { - log_debug!(self, "Reconnected channel {} with only lost remote commitment tx", log_bytes!(self.channel_id())); + log_debug!( + self, + "Reconnected channel {} with only lost remote commitment tx", + log_bytes!(self.channel_id()) + ); } if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 { @@ -2717,18 +3331,33 @@ impl Channel { return Ok((resend_funding_locked, None, None, None, self.resend_order.clone(), shutdown_msg)); } - return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update()), None, self.resend_order.clone(), shutdown_msg)); + return Ok(( + resend_funding_locked, + required_revoke, + Some(self.get_last_commitment_update()), + None, + self.resend_order.clone(), + shutdown_msg, + )); } else { - return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old remote commitment transaction")); + return Err(ChannelError::Close( + "Peer attempted to reestablish channel with a very old remote commitment transaction", + )); } } fn maybe_propose_first_closing_signed(&mut self, fee_estimator: &F) -> Option - where F::Target: FeeEstimator + where + F::Target: FeeEstimator, { - if !self.channel_outbound || !self.pending_inbound_htlcs.is_empty() || !self.pending_outbound_htlcs.is_empty() || - self.channel_state & (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32) != BOTH_SIDES_SHUTDOWN_MASK || - self.last_sent_closing_fee.is_some() || self.pending_update_fee.is_some() { + if !self.channel_outbound + || !self.pending_inbound_htlcs.is_empty() + || !self.pending_outbound_htlcs.is_empty() + || self.channel_state & (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32) + != BOTH_SIDES_SHUTDOWN_MASK + || self.last_sent_closing_fee.is_some() + || self.pending_update_fee.is_some() + { return None; } @@ -2736,14 +3365,17 @@ impl Channel { if self.feerate_per_kw > proposed_feerate { proposed_feerate = self.feerate_per_kw; } - let tx_weight = Self::get_closing_transaction_weight(&self.get_closing_scriptpubkey(), self.their_shutdown_scriptpubkey.as_ref().unwrap()); + let tx_weight = Self::get_closing_transaction_weight( + &self.get_closing_scriptpubkey(), + self.their_shutdown_scriptpubkey.as_ref().unwrap(), + ); let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 1000; let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(proposed_total_fee_satoshis, false); - let our_sig = self.local_keys - .sign_closing_transaction(&closing_tx, &self.secp_ctx) - .ok(); - if our_sig.is_none() { return None; } + let our_sig = self.local_keys.sign_closing_transaction(&closing_tx, &self.secp_ctx).ok(); + if our_sig.is_none() { + return None; + } self.last_sent_closing_fee = Some((proposed_feerate, total_fee_satoshis, our_sig.clone().unwrap())); Some(msgs::ClosingSigned { @@ -2753,8 +3385,11 @@ impl Channel { }) } - pub fn shutdown(&mut self, fee_estimator: &F, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, PaymentHash)>), ChannelError> - where F::Target: FeeEstimator + pub fn shutdown( + &mut self, fee_estimator: &F, msg: &msgs::Shutdown, + ) -> Result<(Option, Option, Vec<(HTLCSource, PaymentHash)>), ChannelError> + where + F::Target: FeeEstimator, { if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent shutdown when we needed a channel_reestablish")); @@ -2779,13 +3414,19 @@ impl Channel { } //Check shutdown_scriptpubkey form as BOLT says we must - if !msg.scriptpubkey.is_p2pkh() && !msg.scriptpubkey.is_p2sh() && !msg.scriptpubkey.is_v0_p2wpkh() && !msg.scriptpubkey.is_v0_p2wsh() { + if !msg.scriptpubkey.is_p2pkh() + && !msg.scriptpubkey.is_p2sh() + && !msg.scriptpubkey.is_v0_p2wpkh() + && !msg.scriptpubkey.is_v0_p2wsh() + { return Err(ChannelError::Close("Got a nonstandard scriptpubkey from remote peer")); } if self.their_shutdown_scriptpubkey.is_some() { if Some(&msg.scriptpubkey) != self.their_shutdown_scriptpubkey.as_ref() { - return Err(ChannelError::Close("Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey")); + return Err(ChannelError::Close( + "Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey", + )); } } else { self.their_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone()); @@ -2801,26 +3442,23 @@ impl Channel { // cell HTLCs and return them to fail the payment. self.holding_cell_update_fee = None; let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len()); - self.holding_cell_htlc_updates.retain(|htlc_update| { - match htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { - dropped_outbound_htlcs.push((source.clone(), payment_hash.clone())); - false - }, - _ => true + self.holding_cell_htlc_updates.retain(|htlc_update| match htlc_update { + &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { + dropped_outbound_htlcs.push((source.clone(), payment_hash.clone())); + false } + _ => true, }); // If we have any LocalAnnounced updates we'll probably just get back a update_fail_htlc // immediately after the commitment dance, but we can send a Shutdown cause we won't send // any further commitment updates after we set LocalShutdownSent. - let our_shutdown = if (self.channel_state & ChannelState::LocalShutdownSent as u32) == ChannelState::LocalShutdownSent as u32 { + let our_shutdown = if (self.channel_state & ChannelState::LocalShutdownSent as u32) + == ChannelState::LocalShutdownSent as u32 + { None } else { - Some(msgs::Shutdown { - channel_id: self.channel_id, - scriptpubkey: self.get_closing_scriptpubkey(), - }) + Some(msgs::Shutdown { channel_id: self.channel_id, scriptpubkey: self.get_closing_scriptpubkey() }) }; self.channel_state |= ChannelState::LocalShutdownSent as u32; @@ -2830,9 +3468,15 @@ impl Channel { } fn build_signed_closing_transaction(&self, tx: &mut Transaction, their_sig: &Signature, our_sig: &Signature) { - if tx.input.len() != 1 { panic!("Tried to sign closing transaction that had input count != 1!"); } - if tx.input[0].witness.len() != 0 { panic!("Tried to re-sign closing transaction"); } - if tx.output.len() > 2 { panic!("Tried to sign bogus closing transaction"); } + if tx.input.len() != 1 { + panic!("Tried to sign closing transaction that had input count != 1!"); + } + if tx.input[0].witness.len() != 0 { + panic!("Tried to re-sign closing transaction"); + } + if tx.output.len() > 2 { + panic!("Tried to sign bogus closing transaction"); + } tx.input[0].witness.push(Vec::new()); // First is the multisig dummy @@ -2851,40 +3495,65 @@ impl Channel { tx.input[0].witness.push(self.get_funding_redeemscript().into_bytes()); } - pub fn closing_signed(&mut self, fee_estimator: &F, msg: &msgs::ClosingSigned) -> Result<(Option, Option), ChannelError> - where F::Target: FeeEstimator + pub fn closing_signed( + &mut self, fee_estimator: &F, msg: &msgs::ClosingSigned, + ) -> Result<(Option, Option), ChannelError> + where + F::Target: FeeEstimator, { if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != BOTH_SIDES_SHUTDOWN_MASK { - return Err(ChannelError::Close("Remote end sent us a closing_signed before both sides provided a shutdown")); + return Err(ChannelError::Close( + "Remote end sent us a closing_signed before both sides provided a shutdown", + )); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent closing_signed when we needed a channel_reestablish")); } if !self.pending_inbound_htlcs.is_empty() || !self.pending_outbound_htlcs.is_empty() { - return Err(ChannelError::Close("Remote end sent us a closing_signed while there were still pending HTLCs")); + return Err(ChannelError::Close( + "Remote end sent us a closing_signed while there were still pending HTLCs", + )); } - if msg.fee_satoshis > 21000000 * 10000000 { //this is required to stop potential overflow in build_closing_transaction + if msg.fee_satoshis > 21000000 * 10000000 { + //this is required to stop potential overflow in build_closing_transaction return Err(ChannelError::Close("Remote tried to send us a closing tx with > 21 million BTC fee")); } let funding_redeemscript = self.get_funding_redeemscript(); let (mut closing_tx, used_total_fee) = self.build_closing_transaction(msg.fee_satoshis, false); if used_total_fee != msg.fee_satoshis { - return Err(ChannelError::Close("Remote sent us a closing_signed with a fee greater than the value they can claim")); - } - let mut sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]); + return Err(ChannelError::Close( + "Remote sent us a closing_signed with a fee greater than the value they can claim", + )); + } + let mut sighash = hash_to_message!( + &bip143::SighashComponents::new(&closing_tx).sighash_all( + &closing_tx.input[0], + &funding_redeemscript, + self.channel_value_satoshis + )[..] + ); let their_funding_pubkey = &self.their_pubkeys.as_ref().unwrap().funding_pubkey; match self.secp_ctx.verify(&sighash, &msg.signature, their_funding_pubkey) { - Ok(_) => {}, + Ok(_) => {} Err(_e) => { // The remote end may have decided to revoke their output due to inconsistent dust // limits, so check for that case by re-checking the signature here. closing_tx = self.build_closing_transaction(msg.fee_satoshis, true).0; - sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]); - secp_check!(self.secp_ctx.verify(&sighash, &msg.signature, self.their_funding_pubkey()), "Invalid closing tx signature from peer"); - }, + sighash = hash_to_message!( + &bip143::SighashComponents::new(&closing_tx).sighash_all( + &closing_tx.input[0], + &funding_redeemscript, + self.channel_value_satoshis + )[..] + ); + secp_check!( + self.secp_ctx.verify(&sighash, &msg.signature, self.their_funding_pubkey()), + "Invalid closing tx signature from peer" + ); + } }; if let Some((_, last_fee, our_sig)) = self.last_sent_closing_fee { @@ -2896,6 +3565,7 @@ impl Channel { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! propose_new_feerate { ($new_feerate: expr) => { let closing_tx_max_weight = Self::get_closing_transaction_weight(&self.get_closing_scriptpubkey(), self.their_shutdown_scriptpubkey.as_ref().unwrap()); @@ -2935,7 +3605,8 @@ impl Channel { } } - let our_sig = self.local_keys + let our_sig = self + .local_keys .sign_closing_transaction(&closing_tx, &self.secp_ctx) .map_err(|_| ChannelError::Close("External signer refused to sign closing transaction"))?; self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig); @@ -2943,11 +3614,14 @@ impl Channel { self.channel_state = ChannelState::ShutdownComplete as u32; self.update_time_counter += 1; - Ok((Some(msgs::ClosingSigned { - channel_id: self.channel_id, - fee_satoshis: msg.fee_satoshis, - signature: our_sig, - }), Some(closing_tx))) + Ok(( + Some(msgs::ClosingSigned { + channel_id: self.channel_id, + fee_satoshis: msg.fee_satoshis, + signature: our_sig, + }), + Some(closing_tx), + )) } // Public utilities: @@ -3016,7 +3690,8 @@ impl Channel { } pub fn get_cur_remote_commitment_transaction_number(&self) -> u64 { - self.cur_remote_commitment_transaction_number + 1 - if self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32) != 0 { 1 } else { 0 } + self.cur_remote_commitment_transaction_number + 1 + - if self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32) != 0 { 1 } else { 0 } } pub fn get_revoked_remote_commitment_transaction_number(&self) -> u64 { @@ -3034,13 +3709,21 @@ impl Channel { value_to_self_msat: self.value_to_self_msat, channel_value_msat: self.channel_value_satoshis * 1000, channel_reserve_msat: self.their_channel_reserve_satoshis * 1000, - pending_outbound_htlcs_amount_msat: self.pending_outbound_htlcs.iter().map(|ref h| h.amount_msat).sum::(), - pending_inbound_htlcs_amount_msat: self.pending_inbound_htlcs.iter().map(|ref h| h.amount_msat).sum::(), + pending_outbound_htlcs_amount_msat: self + .pending_outbound_htlcs + .iter() + .map(|ref h| h.amount_msat) + .sum::(), + pending_inbound_htlcs_amount_msat: self + .pending_inbound_htlcs + .iter() + .map(|ref h| h.amount_msat) + .sum::(), holding_cell_outbound_amount_msat: { let mut res = 0; for h in self.holding_cell_htlc_updates.iter() { match h { - &HTLCUpdateAwaitingACK::AddHTLC{amount_msat, .. } => { + &HTLCUpdateAwaitingACK::AddHTLC { amount_msat, .. } => { res += amount_msat; } _ => {} @@ -3072,7 +3755,8 @@ impl Channel { /// Gets the fee we'd want to charge for adding an HTLC output to this Channel /// Allowed in any state (including after shutdown) pub fn get_our_fee_base_msat(&self, fee_estimator: &F) -> u32 - where F::Target: FeeEstimator + where + F::Target: FeeEstimator, { // For lack of a better metric, we calculate what it would cost to consolidate the new HTLC // output value back into a transaction with the regular channel output: @@ -3086,7 +3770,9 @@ impl Channel { } // + the marginal cost of an input which spends the HTLC-Success/HTLC-Timeout output: - res += fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal) * SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT / 1000; + res += fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal) + * SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT + / 1000; res as u32 } @@ -3107,7 +3793,9 @@ impl Channel { /// is_usable() and considers things like the channel being temporarily disabled. /// Allowed in any state (including after shutdown) pub fn is_live(&self) -> bool { - self.is_usable() && (self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) == 0) + self.is_usable() + && (self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) + == 0) } /// Returns true if this channel has been marked as awaiting a monitor update to move forward. @@ -3125,10 +3813,12 @@ impl Channel { /// may/will be taken on this channel, and thus this object should be freed. Any future changes /// will be handled appropriately by the chain monitor. pub fn is_shutdown(&self) -> bool { - if (self.channel_state & ChannelState::ShutdownComplete as u32) == ChannelState::ShutdownComplete as u32 { + if (self.channel_state & ChannelState::ShutdownComplete as u32) == ChannelState::ShutdownComplete as u32 { assert!(self.channel_state == ChannelState::ShutdownComplete as u32); true - } else { false } + } else { + false + } } pub fn to_disabled_staged(&mut self) { @@ -3165,18 +3855,20 @@ impl Channel { /// /// May return some HTLCs (and their payment_hash) which have timed out and should be failed /// back. - pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<(Option, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> { + pub fn block_connected( + &mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32], + ) -> Result<(Option, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> { let mut timed_out_htlcs = Vec::new(); - self.holding_cell_htlc_updates.retain(|htlc_update| { - match htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, ref cltv_expiry, .. } => { - if *cltv_expiry <= height + HTLC_FAIL_BACK_BUFFER { - timed_out_htlcs.push((source.clone(), payment_hash.clone())); - false - } else { true } - }, - _ => true + self.holding_cell_htlc_updates.retain(|htlc_update| match htlc_update { + &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, ref cltv_expiry, .. } => { + if *cltv_expiry <= height + HTLC_FAIL_BACK_BUFFER { + timed_out_htlcs.push((source.clone(), payment_hash.clone())); + false + } else { + true + } } + _ => true, }); let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS); if header.bitcoin_hash() != self.last_block_connected { @@ -3188,8 +3880,10 @@ impl Channel { for (ref tx, index_in_block) in txn_matched.iter().zip(indexes_of_txn_matched) { if tx.txid() == self.funding_txo.unwrap().txid { let txo_idx = self.funding_txo.unwrap().index as usize; - if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() || - tx.output[txo_idx].value != self.channel_value_satoshis { + if txo_idx >= tx.output.len() + || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() + || tx.output[txo_idx].value != self.channel_value_satoshis + { if self.channel_outbound { // If we generated the funding transaction and it doesn't match what it // should, the client is really broken and we should just panic and @@ -3197,13 +3891,15 @@ impl Channel { // probability in fuzztarget mode, if we're fuzzing we just close the // channel and move on. #[cfg(not(feature = "fuzztarget"))] - panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!"); + panic!( + "Client called ChannelManager::funding_transaction_generated with bogus transaction!" + ); } self.channel_state = ChannelState::ShutdownComplete as u32; self.update_time_counter += 1; return Err(msgs::ErrorMessage { channel_id: self.channel_id(), - data: "funding tx had wrong script/value".to_owned() + data: "funding tx had wrong script/value".to_owned(), }); } else { if self.channel_outbound { @@ -3217,9 +3913,11 @@ impl Channel { } } self.funding_tx_confirmations = 1; - self.short_channel_id = Some(((height as u64) << (5*8)) | - ((*index_in_block as u64) << (2*8)) | - ((txo_idx as u64) << (0*8))); + self.short_channel_id = Some( + ((height as u64) << (5 * 8)) + | ((*index_in_block as u64) << (2 * 8)) + | ((txo_idx as u64) << (0 * 8)), + ); } } } @@ -3235,11 +3933,16 @@ impl Channel { let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 { self.channel_state |= ChannelState::OurFundingLocked as u32; true - } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) { - self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS); + } else if non_shutdown_state + == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) + { + self.channel_state = + ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS); self.update_time_counter += 1; true - } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) { + } else if non_shutdown_state + == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) + { // We got a reorg but not enough to trigger a force close, just update // funding_tx_confirmed_in and return. false @@ -3258,12 +3961,14 @@ impl Channel { //a protocol oversight, but I assume I'm just missing something. if need_commitment_update { if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 { - let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); - let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret); - return Ok((Some(msgs::FundingLocked { - channel_id: self.channel_id, - next_per_commitment_point: next_per_commitment_point, - }), timed_out_htlcs)); + let next_per_commitment_secret = + self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); + let next_per_commitment_point = + PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret); + return Ok(( + Some(msgs::FundingLocked { channel_id: self.channel_id, next_per_commitment_point }), + timed_out_htlcs, + )); } else { self.monitor_pending_funding_locked = true; return Ok((None, timed_out_htlcs)); @@ -3299,7 +4004,8 @@ impl Channel { // something in the handler for the message that prompted this message): pub fn get_open_channel(&self, chain_hash: BlockHash, fee_estimator: &F) -> msgs::OpenChannel - where F::Target: FeeEstimator + where + F::Target: FeeEstimator, { if !self.channel_outbound { panic!("Tried to open a channel for an inbound channel?"); @@ -3315,13 +4021,17 @@ impl Channel { let local_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number); msgs::OpenChannel { - chain_hash: chain_hash, + chain_hash, temporary_channel_id: self.channel_id, funding_satoshis: self.channel_value_satoshis, push_msat: self.channel_value_satoshis * 1000 - self.value_to_self_msat, dust_limit_satoshis: self.our_dust_limit_satoshis, - max_htlc_value_in_flight_msat: Channel::::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis), - channel_reserve_satoshis: Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis), + max_htlc_value_in_flight_msat: Channel::::get_our_max_htlc_value_in_flight_msat( + self.channel_value_satoshis, + ), + channel_reserve_satoshis: Channel::::get_our_channel_reserve_satoshis( + self.channel_value_satoshis, + ), htlc_minimum_msat: self.our_htlc_minimum_msat, feerate_per_kw: fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) as u32, to_self_delay: self.our_to_self_delay, @@ -3329,11 +4039,18 @@ impl Channel { funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), revocation_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.revocation_base_key()), payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key()), - delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()), + delayed_payment_basepoint: PublicKey::from_secret_key( + &self.secp_ctx, + self.local_keys.delayed_payment_base_key(), + ), htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()), first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret), - channel_flags: if self.config.announced_channel {1} else {0}, - shutdown_scriptpubkey: OptionalField::Present(if self.config.commit_upfront_shutdown_pubkey { self.get_closing_scriptpubkey() } else { Builder::new().into_script() }) + channel_flags: if self.config.announced_channel { 1 } else { 0 }, + shutdown_scriptpubkey: OptionalField::Present(if self.config.commit_upfront_shutdown_pubkey { + self.get_closing_scriptpubkey() + } else { + Builder::new().into_script() + }), } } @@ -3353,8 +4070,12 @@ impl Channel { msgs::AcceptChannel { temporary_channel_id: self.channel_id, dust_limit_satoshis: self.our_dust_limit_satoshis, - max_htlc_value_in_flight_msat: Channel::::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis), - channel_reserve_satoshis: Channel::::get_our_channel_reserve_satoshis(self.channel_value_satoshis), + max_htlc_value_in_flight_msat: Channel::::get_our_max_htlc_value_in_flight_msat( + self.channel_value_satoshis, + ), + channel_reserve_satoshis: Channel::::get_our_channel_reserve_satoshis( + self.channel_value_satoshis, + ), htlc_minimum_msat: self.our_htlc_minimum_msat, minimum_depth: self.minimum_depth, to_self_delay: self.our_to_self_delay, @@ -3362,19 +4083,44 @@ impl Channel { funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), revocation_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.revocation_base_key()), payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key()), - delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()), + delayed_payment_basepoint: PublicKey::from_secret_key( + &self.secp_ctx, + self.local_keys.delayed_payment_base_key(), + ), htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()), first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret), - shutdown_scriptpubkey: OptionalField::Present(if self.config.commit_upfront_shutdown_pubkey { self.get_closing_scriptpubkey() } else { Builder::new().into_script() }) + shutdown_scriptpubkey: OptionalField::Present(if self.config.commit_upfront_shutdown_pubkey { + self.get_closing_scriptpubkey() + } else { + Builder::new().into_script() + }), } } /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) fn get_outbound_funding_created_signature(&mut self) -> Result { let remote_keys = self.build_remote_transaction_keys()?; - let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0; - Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) - .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0) + let remote_initial_commitment_tx = self + .build_commitment_transaction( + self.cur_remote_commitment_transaction_number, + &remote_keys, + false, + false, + self.feerate_per_kw, + ) + .0; + Ok(self + .local_keys + .sign_remote_commitment( + self.feerate_per_kw, + &remote_initial_commitment_tx, + &remote_keys, + &Vec::new(), + self.our_to_self_delay, + &self.secp_ctx, + ) + .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))? + .0) } /// Updates channel state with knowledge of the funding transaction's txid/index, and generates @@ -3384,16 +4130,19 @@ impl Channel { /// Note that channel_id changes during this call! /// Do NOT broadcast the funding transaction until after a successful funding_signed call! /// If an Err is returned, it is a ChannelError::Close. - pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result { + pub fn get_outbound_funding_created( + &mut self, funding_txo: OutPoint, + ) -> Result { if !self.channel_outbound { panic!("Tried to create outbound funding_created message on an inbound channel!"); } if self.channel_state != (ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32) { panic!("Tried to get a funding_created messsage at a time other than immediately after initial handshake completion (or tried to get funding_created twice)"); } - if self.commitment_secrets.get_min_seen_secret() != (1 << 48) || - self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER || - self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER { + if self.commitment_secrets.get_min_seen_secret() != (1 << 48) + || self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER + || self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER + { panic!("Should not have advanced channel commitment tx numbers prior to funding_created"); } @@ -3418,7 +4167,7 @@ impl Channel { temporary_channel_id, funding_txid: funding_txo.txid, funding_output_index: funding_txo.index, - signature: our_signature + signature: our_signature, }) } @@ -3430,14 +4179,19 @@ impl Channel { /// closing). /// Note that the "channel must be funded" requirement is stricter than BOLT 7 requires - see /// https://github.com/lightningnetwork/lightning-rfc/issues/468 - pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: BlockHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> { + pub fn get_channel_announcement( + &self, our_node_id: PublicKey, chain_hash: BlockHash, + ) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> { if !self.config.announced_channel { return Err(ChannelError::Ignore("Channel is not available for public announcements")); } if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 { - return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement until the channel funding has been locked")); + return Err(ChannelError::Ignore( + "Cannot get a ChannelAnnouncement until the channel funding has been locked", + )); } - if (self.channel_state & (ChannelState::LocalShutdownSent as u32 | ChannelState::ShutdownComplete as u32)) != 0 { + if (self.channel_state & (ChannelState::LocalShutdownSent as u32 | ChannelState::ShutdownComplete as u32)) != 0 + { return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement once the channel is closing")); } @@ -3446,7 +4200,7 @@ impl Channel { let msg = msgs::UnsignedChannelAnnouncement { features: ChannelFeatures::known(), - chain_hash: chain_hash, + chain_hash, short_channel_id: self.get_short_channel_id().unwrap(), node_id_1: if were_node_one { our_node_id } else { self.get_their_node_id() }, node_id_2: if were_node_one { self.get_their_node_id() } else { our_node_id }, @@ -3455,7 +4209,9 @@ impl Channel { excess_data: Vec::new(), }; - let sig = self.local_keys.sign_channel_announcement(&msg, &self.secp_ctx) + let sig = self + .local_keys + .sign_channel_announcement(&msg, &self.secp_ctx) .map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement"))?; Ok((msg, sig)) @@ -3467,17 +4223,28 @@ impl Channel { assert_eq!(self.channel_state & ChannelState::PeerDisconnected as u32, ChannelState::PeerDisconnected as u32); assert_ne!(self.cur_remote_commitment_transaction_number, INITIAL_COMMITMENT_NUMBER); let data_loss_protect = if self.cur_remote_commitment_transaction_number + 1 < INITIAL_COMMITMENT_NUMBER { - let remote_last_secret = self.commitment_secrets.get_secret(self.cur_remote_commitment_transaction_number + 2).unwrap(); - log_trace!(self, "Enough info to generate a Data Loss Protect with per_commitment_secret {}", log_bytes!(remote_last_secret)); + let remote_last_secret = + self.commitment_secrets.get_secret(self.cur_remote_commitment_transaction_number + 2).unwrap(); + log_trace!( + self, + "Enough info to generate a Data Loss Protect with per_commitment_secret {}", + log_bytes!(remote_last_secret) + ); OptionalField::Present(DataLossProtect { your_last_per_commitment_secret: remote_last_secret, - my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1)) + my_current_per_commitment_point: PublicKey::from_secret_key( + &self.secp_ctx, + &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1), + ), }) } else { log_info!(self, "Sending a data_loss_protect with no previous remote per_commitment_secret"); OptionalField::Present(DataLossProtect { - your_last_per_commitment_secret: [0;32], - my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1)) + your_last_per_commitment_secret: [0; 32], + my_current_per_commitment_point: PublicKey::from_secret_key( + &self.secp_ctx, + &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1), + ), }) }; msgs::ChannelReestablish { @@ -3499,12 +4266,13 @@ impl Channel { // cur_remote_commitment_transaction_number is INITIAL_COMMITMENT_NUMBER we will have // dropped this channel on disconnect as it hasn't yet reached FundingSent so we can't // overflow here. - next_remote_commitment_number: INITIAL_COMMITMENT_NUMBER - self.cur_remote_commitment_transaction_number - 1, + next_remote_commitment_number: INITIAL_COMMITMENT_NUMBER + - self.cur_remote_commitment_transaction_number + - 1, data_loss_protect, } } - // Send stuff to our remote peers: /// Adds a pending outbound HTLC to this channel, note that you probably want @@ -3514,9 +4282,16 @@ impl Channel { /// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed. /// You MUST call send_commitment prior to any other calls on this Channel /// If an Err is returned, it's a ChannelError::Ignore! - pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { - if (self.channel_state & (ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelFunded as u32) { - return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down")); + pub fn send_htlc( + &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, + ) -> Result, ChannelError> { + if (self.channel_state & (ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK)) + != (ChannelState::ChannelFunded as u32) + { + return Err(ChannelError::Ignore( + "Cannot send HTLC until channel is fully established and we haven't started shutting down", + )); } if amount_msat > self.channel_value_satoshis * 1000 { @@ -3531,14 +4306,18 @@ impl Channel { return Err(ChannelError::Ignore("Cannot send less than their minimum HTLC value")); } - if (self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 { + if (self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) + != 0 + { // Note that this should never really happen, if we're !is_live() on receipt of an // incoming HTLC for relay will result in us rejecting the HTLC and we won't allow // the user to send directly into a !is_live() channel. However, if we // disconnected during the time the previous hop was doing the commitment dance we may // end up getting here after the forwarding delay. In any case, returning an // IgnoreError will get ChannelManager to do the right thing and fail backwards now. - return Err(ChannelError::Ignore("Cannot send an HTLC while disconnected/frozen for channel monitor update")); + return Err(ChannelError::Ignore( + "Cannot send an HTLC while disconnected/frozen for channel monitor update", + )); } let (outbound_htlc_count, htlc_outbound_value_msat) = self.get_outbound_pending_htlc_stats(); @@ -3547,32 +4326,37 @@ impl Channel { } // Check their_max_htlc_value_in_flight_msat if htlc_outbound_value_msat + amount_msat > self.their_max_htlc_value_in_flight_msat { - return Err(ChannelError::Ignore("Cannot send value that would put us over the max HTLC value in flight our peer will accept")); + return Err(ChannelError::Ignore( + "Cannot send value that would put us over the max HTLC value in flight our peer will accept", + )); } // Check self.their_channel_reserve_satoshis (the amount we must keep as // reserve for them to have something to claim if we misbehave) - if self.value_to_self_msat < self.their_channel_reserve_satoshis * 1000 + amount_msat + htlc_outbound_value_msat { + if self.value_to_self_msat < self.their_channel_reserve_satoshis * 1000 + amount_msat + htlc_outbound_value_msat + { return Err(ChannelError::Ignore("Cannot send value that would put us over their reserve value")); } // Now update local state: - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) { + if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) + == (ChannelState::AwaitingRemoteRevoke as u32) + { self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::AddHTLC { - amount_msat: amount_msat, - payment_hash: payment_hash, - cltv_expiry: cltv_expiry, + amount_msat, + payment_hash, + cltv_expiry, source, - onion_routing_packet: onion_routing_packet, + onion_routing_packet, }); return Ok(None); } self.pending_outbound_htlcs.push(OutboundHTLCOutput { htlc_id: self.next_local_htlc_id, - amount_msat: amount_msat, + amount_msat, payment_hash: payment_hash.clone(), - cltv_expiry: cltv_expiry, + cltv_expiry, state: OutboundHTLCState::LocalAnnounced(Box::new(onion_routing_packet.clone())), source, }); @@ -3580,10 +4364,10 @@ impl Channel { let res = msgs::UpdateAddHTLC { channel_id: self.channel_id, htlc_id: self.next_local_htlc_id, - amount_msat: amount_msat, - payment_hash: payment_hash, - cltv_expiry: cltv_expiry, - onion_routing_packet: onion_routing_packet, + amount_msat, + payment_hash, + cltv_expiry, + onion_routing_packet, }; self.next_local_htlc_id += 1; @@ -3598,13 +4382,17 @@ impl Channel { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { panic!("Cannot create commitment tx until channel is fully established"); } - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) { + if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) + == (ChannelState::AwaitingRemoteRevoke as u32) + { panic!("Cannot create commitment tx until remote revokes their previous commitment"); } if (self.channel_state & (ChannelState::PeerDisconnected as u32)) == (ChannelState::PeerDisconnected as u32) { panic!("Cannot create commitment tx while disconnected, as send_htlc will have returned an Err so a send_commitment precondition has been violated"); } - if (self.channel_state & (ChannelState::MonitorUpdateFailed as u32)) == (ChannelState::MonitorUpdateFailed as u32) { + if (self.channel_state & (ChannelState::MonitorUpdateFailed as u32)) + == (ChannelState::MonitorUpdateFailed as u32) + { panic!("Cannot create commitment tx while awaiting monitor update unfreeze, as send_htlc will have returned an Err so a send_commitment precondition has been violated"); } let mut have_updates = self.pending_update_fee.is_some(); @@ -3612,13 +4400,17 @@ impl Channel { if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { have_updates = true; } - if have_updates { break; } + if have_updates { + break; + } } for htlc in self.pending_inbound_htlcs.iter() { if let InboundHTLCState::LocalRemoved(_) = htlc.state { have_updates = true; } - if have_updates { break; } + if have_updates { + break; + } } if !have_updates { panic!("Cannot create commitment tx until we have some updates to send"); @@ -3626,22 +4418,29 @@ impl Channel { self.send_commitment_no_status_check() } /// Only fails in case of bad keys - fn send_commitment_no_status_check(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> { + fn send_commitment_no_status_check( + &mut self, + ) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> { // We can upgrade the status of some HTLCs that are waiting on a commitment, even if we // fail to generate this, we still are at least at a position where upgrading their status // is acceptable. for htlc in self.pending_inbound_htlcs.iter_mut() { let new_state = if let &InboundHTLCState::AwaitingRemoteRevokeToAnnounce(ref forward_info) = &htlc.state { Some(InboundHTLCState::AwaitingAnnouncedRemoteRevoke(forward_info.clone())) - } else { None }; + } else { + None + }; if let Some(state) = new_state { htlc.state = state; } } for htlc in self.pending_outbound_htlcs.iter_mut() { - if let Some(fail_reason) = if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut fail_reason) = &mut htlc.state { - Some(fail_reason.take()) - } else { None } { + if let Some(fail_reason) = + if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut fail_reason) = &mut htlc.state { + Some(fail_reason.take()) + } else { + None + } { htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(fail_reason); } } @@ -3650,10 +4449,12 @@ impl Channel { let (res, remote_commitment_tx, htlcs) = match self.send_commitment_no_state_update() { Ok((res, (remote_commitment_tx, mut htlcs))) => { // Update state now that we've passed all the can-fail calls... - let htlcs_no_ref: Vec<(HTLCOutputInCommitment, Option>)> = - htlcs.drain(..).map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect(); + let htlcs_no_ref: Vec<(HTLCOutputInCommitment, Option>)> = htlcs + .drain(..) + .map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))) + .collect(); (res, remote_commitment_tx, htlcs_no_ref) - }, + } Err(e) => return Err(e), }; @@ -3664,8 +4465,8 @@ impl Channel { unsigned_commitment_tx: remote_commitment_tx.clone(), htlc_outputs: htlcs.clone(), commitment_number: self.cur_remote_commitment_transaction_number, - their_revocation_point: self.their_cur_commitment_point.unwrap() - }] + their_revocation_point: self.their_cur_commitment_point.unwrap(), + }], }; self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap(); self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32; @@ -3674,7 +4475,10 @@ impl Channel { /// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation /// when we shouldn't change HTLC/channel state. - fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> { + fn send_commitment_no_state_update( + &self, + ) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> + { let mut feerate_per_kw = self.feerate_per_kw; if let Some(feerate) = self.pending_update_fee { if self.channel_outbound { @@ -3683,7 +4487,13 @@ impl Channel { } let remote_keys = self.build_remote_transaction_keys()?; - let remote_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, true, feerate_per_kw); + let remote_commitment_tx = self.build_commitment_transaction( + self.cur_remote_commitment_transaction_number, + &remote_keys, + false, + true, + feerate_per_kw, + ); let (signature, htlc_signatures); { @@ -3692,43 +4502,67 @@ impl Channel { htlcs.push(htlc); } - let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, self.our_to_self_delay, &self.secp_ctx) + let res = self + .local_keys + .sign_remote_commitment( + feerate_per_kw, + &remote_commitment_tx.0, + &remote_keys, + &htlcs, + self.our_to_self_delay, + &self.secp_ctx, + ) .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?; signature = res.0; htlc_signatures = res.1; - log_trace!(self, "Signed remote commitment tx {} with redeemscript {} -> {}", + log_trace!( + self, + "Signed remote commitment tx {} with redeemscript {} -> {}", encode::serialize_hex(&remote_commitment_tx.0), encode::serialize_hex(&self.get_funding_redeemscript()), - log_bytes!(signature.serialize_compact()[..])); + log_bytes!(signature.serialize_compact()[..]) + ); for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) { - log_trace!(self, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}", - encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)), + log_trace!( + self, + "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}", + encode::serialize_hex(&chan_utils::build_htlc_transaction( + &remote_commitment_tx.0.txid(), + feerate_per_kw, + self.our_to_self_delay, + htlc, + &remote_keys.a_delayed_payment_key, + &remote_keys.revocation_key + )), encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)), log_bytes!(remote_keys.a_htlc_key.serialize()), - log_bytes!(htlc_sig.serialize_compact()[..])); + log_bytes!(htlc_sig.serialize_compact()[..]) + ); } } - Ok((msgs::CommitmentSigned { - channel_id: self.channel_id, - signature, - htlc_signatures, - }, (remote_commitment_tx.0, remote_commitment_tx.2))) + Ok(( + msgs::CommitmentSigned { channel_id: self.channel_id, signature, htlc_signatures }, + (remote_commitment_tx.0, remote_commitment_tx.2), + )) } /// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction /// to send to the remote peer in one go. /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for /// more info. - pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { + pub fn send_htlc_and_commit( + &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, + ) -> Result, ChannelError> { match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet)? { Some(update_add_htlc) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?; Ok(Some((update_add_htlc, commitment_signed, monitor_update))) - }, - None => Ok(None) + } + None => Ok(None), } } @@ -3737,19 +4571,23 @@ impl Channel { pub fn get_shutdown(&mut self) -> Result<(msgs::Shutdown, Vec<(HTLCSource, PaymentHash)>), APIError> { for htlc in self.pending_outbound_htlcs.iter() { if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { - return Err(APIError::APIMisuseError{err: "Cannot begin shutdown with pending HTLCs. Process pending events first"}); + return Err(APIError::APIMisuseError { + err: "Cannot begin shutdown with pending HTLCs. Process pending events first", + }); } } if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != 0 { if (self.channel_state & ChannelState::LocalShutdownSent as u32) == ChannelState::LocalShutdownSent as u32 { - return Err(APIError::APIMisuseError{err: "Shutdown already in progress"}); - } - else if (self.channel_state & ChannelState::RemoteShutdownSent as u32) == ChannelState::RemoteShutdownSent as u32 { - return Err(APIError::ChannelUnavailable{err: "Shutdown already in progress by remote"}); + return Err(APIError::APIMisuseError { err: "Shutdown already in progress" }); + } else if (self.channel_state & ChannelState::RemoteShutdownSent as u32) + == ChannelState::RemoteShutdownSent as u32 + { + return Err(APIError::ChannelUnavailable { err: "Shutdown already in progress by remote" }); } } assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0); - if self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) != 0 { + if self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) != 0 + { return Err(APIError::ChannelUnavailable{err: "Cannot begin shutdown while peer is disconnected or we're waiting on a monitor update, maybe force-close instead?"}); } @@ -3767,20 +4605,15 @@ impl Channel { // our shutdown until we've committed all of the pending changes. self.holding_cell_update_fee = None; let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len()); - self.holding_cell_htlc_updates.retain(|htlc_update| { - match htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { - dropped_outbound_htlcs.push((source.clone(), payment_hash.clone())); - false - }, - _ => true + self.holding_cell_htlc_updates.retain(|htlc_update| match htlc_update { + &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { + dropped_outbound_htlcs.push((source.clone(), payment_hash.clone())); + false } + _ => true, }); - Ok((msgs::Shutdown { - channel_id: self.channel_id, - scriptpubkey: our_closing_script, - }, dropped_outbound_htlcs)) + Ok((msgs::Shutdown { channel_id: self.channel_id, scriptpubkey: our_closing_script }, dropped_outbound_htlcs)) } /// Gets the latest commitment transaction and any dependent transactions for relay (forcing @@ -3788,7 +4621,9 @@ impl Channel { /// those explicitly stated to be allowed after shutdown completes, eg some simple getters). /// Also returns the list of payment_hashes for channels which we can safely fail backwards /// immediately (others we will have to allow to time out). - pub fn force_shutdown(&mut self, should_broadcast: bool) -> (Option, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>) { + pub fn force_shutdown( + &mut self, should_broadcast: bool, + ) -> (Option, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>) { assert!(self.channel_state != ChannelState::ShutdownComplete as u32); // We go ahead and "free" any holding cell HTLCs or HTLCs we haven't yet committed to and @@ -3798,7 +4633,7 @@ impl Channel { match htlc_update { HTLCUpdateAwaitingACK::AddHTLC { source, payment_hash, .. } => { dropped_outbound_htlcs.push((source, payment_hash)); - }, + } _ => {} } } @@ -3812,10 +4647,14 @@ impl Channel { self.channel_state = ChannelState::ShutdownComplete as u32; self.update_time_counter += 1; self.latest_monitor_update_id += 1; - (self.funding_txo.clone(), ChannelMonitorUpdate { - update_id: self.latest_monitor_update_id, - updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }], - }, dropped_outbound_htlcs) + ( + self.funding_txo.clone(), + ChannelMonitorUpdate { + update_id: self.latest_monitor_update_id, + updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }], + }, + dropped_outbound_htlcs, + ) } } @@ -3828,16 +4667,16 @@ impl Writeable for InboundHTLCRemovalReason { &InboundHTLCRemovalReason::FailRelay(ref error_packet) => { 0u8.write(writer)?; error_packet.write(writer)?; - }, + } &InboundHTLCRemovalReason::FailMalformed((ref onion_hash, ref err_code)) => { 1u8.write(writer)?; onion_hash.write(writer)?; err_code.write(writer)?; - }, + } &InboundHTLCRemovalReason::Fulfill(ref payment_preimage) => { 2u8.write(writer)?; payment_preimage.write(writer)?; - }, + } } Ok(()) } @@ -3900,18 +4739,18 @@ impl Writeable for Channel { &InboundHTLCState::AwaitingRemoteRevokeToAnnounce(ref htlc_state) => { 1u8.write(writer)?; htlc_state.write(writer)?; - }, + } &InboundHTLCState::AwaitingAnnouncedRemoteRevoke(ref htlc_state) => { 2u8.write(writer)?; htlc_state.write(writer)?; - }, + } &InboundHTLCState::Committed => { 3u8.write(writer)?; - }, + } &InboundHTLCState::LocalRemoved(ref removal_reason) => { 4u8.write(writer)?; removal_reason.write(writer)?; - }, + } } } @@ -3926,41 +4765,47 @@ impl Writeable for Channel { &OutboundHTLCState::LocalAnnounced(ref onion_packet) => { 0u8.write(writer)?; onion_packet.write(writer)?; - }, + } &OutboundHTLCState::Committed => { 1u8.write(writer)?; - }, + } &OutboundHTLCState::RemoteRemoved(ref fail_reason) => { 2u8.write(writer)?; fail_reason.write(writer)?; - }, + } &OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref fail_reason) => { 3u8.write(writer)?; fail_reason.write(writer)?; - }, + } &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref fail_reason) => { 4u8.write(writer)?; fail_reason.write(writer)?; - }, + } } } (self.holding_cell_htlc_updates.len() as u64).write(writer)?; for update in self.holding_cell_htlc_updates.iter() { match update { - &HTLCUpdateAwaitingACK::AddHTLC { ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet } => { + &HTLCUpdateAwaitingACK::AddHTLC { + ref amount_msat, + ref cltv_expiry, + ref payment_hash, + ref source, + ref onion_routing_packet, + } => { 0u8.write(writer)?; amount_msat.write(writer)?; cltv_expiry.write(writer)?; payment_hash.write(writer)?; source.write(writer)?; onion_routing_packet.write(writer)?; - }, + } &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, ref htlc_id } => { 1u8.write(writer)?; payment_preimage.write(writer)?; htlc_id.write(writer)?; - }, + } &HTLCUpdateAwaitingACK::FailHTLC { ref htlc_id, ref err_packet } => { 2u8.write(writer)?; htlc_id.write(writer)?; @@ -4005,7 +4850,7 @@ impl Writeable for Channel { feerate.write(writer)?; fee.write(writer)?; sig.write(writer)?; - }, + } None => 0u8.write(writer)?, } @@ -4043,7 +4888,7 @@ impl Writeable for Channel { } impl ReadableArgs> for Channel { - fn read(reader: &mut R, logger: Arc) -> Result { + fn read(reader: &mut R, logger: Arc) -> Result { let _ver: u8 = Readable::read(reader)?; let min_ver: u8 = Readable::read(reader)?; if min_ver > SERIALIZATION_VERSION { @@ -4069,7 +4914,8 @@ impl ReadableArgs> for Channel ReadableArgs> for Channel ReadableArgs> for Channel::read(reader)? { 0 => HTLCUpdateAwaitingACK::AddHTLC { @@ -4140,13 +4988,15 @@ impl ReadableArgs> for Channel ReadableArgs> for Channel u64 { @@ -4325,8 +5178,10 @@ mod tests { #[test] fn test_max_funding_satoshis() { - assert!(MAX_FUNDING_SATOSHIS <= 21_000_000 * 100_000_000, - "MAX_FUNDING_SATOSHIS is greater than all satoshis in existence"); + assert!( + MAX_FUNDING_SATOSHIS <= 21_000_000 * 100_000_000, + "MAX_FUNDING_SATOSHIS is greater than all satoshis in existence" + ); } struct Keys { @@ -4335,25 +5190,41 @@ mod tests { impl KeysInterface for Keys { type ChanKeySigner = InMemoryChannelKeys; - fn get_node_secret(&self) -> SecretKey { panic!(); } + fn get_node_secret(&self) -> SecretKey { + panic!(); + } fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); - let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); - let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() + let channel_monitor_claim_key = SecretKey::from_slice( + &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..], + ) + .unwrap(); + let our_channel_monitor_claim_key_hash = + WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&our_channel_monitor_claim_key_hash[..]) + .into_script() } fn get_shutdown_pubkey(&self) -> PublicKey { let secp_ctx = Secp256k1::signing_only(); - let channel_close_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); + let channel_close_key = SecretKey::from_slice( + &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..], + ) + .unwrap(); PublicKey::from_secret_key(&secp_ctx, &channel_close_key) } fn get_channel_keys(&self, _inbound: bool, _channel_value_satoshis: u64) -> InMemoryChannelKeys { self.chan_keys.clone() } - fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { panic!(); } - fn get_channel_id(&self) -> [u8; 32] { [0; 32] } + fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { + panic!(); + } + fn get_channel_id(&self) -> [u8; 32] { + [0; 32] + } } fn public_from_secret_hex(secp_ctx: &Secp256k1, hex: &str) -> PublicKey { @@ -4362,8 +5233,8 @@ mod tests { #[test] fn channel_reestablish_no_updates() { - let feeest = TestFeeEstimator{fee_est: 15000}; - let logger : Arc = Arc::new(test_utils::TestLogger::new()); + let feeest = TestFeeEstimator { fee_est: 15000 }; + let logger: Arc = Arc::new(test_utils::TestLogger::new()); let secp_ctx = Secp256k1::new(); let mut seed = [0; 32]; let mut rng = thread_rng(); @@ -4376,12 +5247,32 @@ mod tests { // Create Node A's channel let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_a_node_id, 10000000, 100000, 42, Arc::clone(&logger), &config).unwrap(); + let mut node_a_chan = Channel::::new_outbound( + &&feeest, + &&keys_provider, + node_a_node_id, + 10000000, + 100000, + 42, + Arc::clone(&logger), + &config, + ) + .unwrap(); // Create Node B's channel by receiving Node A's open_channel message let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.bitcoin_hash(), &&feeest); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); - let mut node_b_chan = Channel::::new_from_req(&&feeest, &&keys_provider, node_b_node_id, InitFeatures::known(), &open_channel_msg, 7, logger, &config).unwrap(); + let mut node_b_chan = Channel::::new_from_req( + &&feeest, + &&keys_provider, + node_b_node_id, + InitFeatures::known(), + &open_channel_msg, + 7, + logger, + &config, + ) + .unwrap(); // Node B --> Node A: accept channel let accept_channel_msg = node_b_chan.get_accept_channel(); @@ -4389,9 +5280,12 @@ mod tests { // Node A --> Node B: funding created let output_script = node_a_chan.get_funding_redeemscript(); - let tx = Transaction { version: 1, lock_time: 0, input: Vec::new(), output: vec![TxOut { - value: 10000000, script_pubkey: output_script.clone(), - }]}; + let tx = Transaction { + version: 1, + lock_time: 0, + input: Vec::new(), + output: vec![TxOut { value: 10000000, script_pubkey: output_script.clone() }], + }; let funding_outpoint = OutPoint::new(tx.txid(), 0); let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint).unwrap(); let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg).unwrap(); @@ -4402,94 +5296,166 @@ mod tests { // Now disconnect the two nodes and check that the commitment point in // Node B's channel_reestablish message is sane. node_b_chan.remove_uncommitted_htlcs_and_mark_paused(); - let expected_commitment_point = PublicKey::from_secret_key(&secp_ctx, &node_b_chan.build_local_commitment_secret(node_b_chan.cur_local_commitment_transaction_number + 1)); + let expected_commitment_point = PublicKey::from_secret_key( + &secp_ctx, + &node_b_chan.build_local_commitment_secret(node_b_chan.cur_local_commitment_transaction_number + 1), + ); let msg = node_b_chan.get_channel_reestablish(); match msg.data_loss_protect { OptionalField::Present(DataLossProtect { my_current_per_commitment_point, .. }) => { assert_eq!(expected_commitment_point, my_current_per_commitment_point); - }, - _ => panic!() + } + _ => panic!(), } // Check that the commitment point in Node A's channel_reestablish message // is sane. node_a_chan.remove_uncommitted_htlcs_and_mark_paused(); - let expected_commitment_point = PublicKey::from_secret_key(&secp_ctx, &node_a_chan.build_local_commitment_secret(node_a_chan.cur_local_commitment_transaction_number + 1)); + let expected_commitment_point = PublicKey::from_secret_key( + &secp_ctx, + &node_a_chan.build_local_commitment_secret(node_a_chan.cur_local_commitment_transaction_number + 1), + ); let msg = node_a_chan.get_channel_reestablish(); match msg.data_loss_protect { OptionalField::Present(DataLossProtect { my_current_per_commitment_point, .. }) => { assert_eq!(expected_commitment_point, my_current_per_commitment_point); - }, - _ => panic!() + } + _ => panic!(), } } #[test] fn outbound_commitment_test() { // Test vectors from BOLT 3 Appendix C: - let feeest = TestFeeEstimator{fee_est: 15000}; - let logger : Arc = Arc::new(test_utils::TestLogger::new()); + let feeest = TestFeeEstimator { fee_est: 15000 }; + let logger: Arc = Arc::new(test_utils::TestLogger::new()); let secp_ctx = Secp256k1::new(); let mut chan_keys = InMemoryChannelKeys::new( &secp_ctx, - SecretKey::from_slice(&hex::decode("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(), - SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), - SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(), - SecretKey::from_slice(&hex::decode("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap(), - SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(), - + SecretKey::from_slice( + &hex::decode("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..], + ) + .unwrap(), + SecretKey::from_slice( + &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..], + ) + .unwrap(), + SecretKey::from_slice( + &hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..], + ) + .unwrap(), + SecretKey::from_slice( + &hex::decode("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..], + ) + .unwrap(), + SecretKey::from_slice( + &hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..], + ) + .unwrap(), // These aren't set in the test vectors: - [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], 10_000_000, ); - assert_eq!(PublicKey::from_secret_key(&secp_ctx, chan_keys.funding_key()).serialize()[..], - hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]); + assert_eq!( + PublicKey::from_secret_key(&secp_ctx, chan_keys.funding_key()).serialize()[..], + hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..] + ); let keys_provider = Keys { chan_keys: chan_keys.clone() }; let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let mut config = UserConfig::default(); config.channel_options.announced_channel = false; - let mut chan = Channel::::new_outbound(&&feeest, &&keys_provider, their_node_id, 10_000_000, 100000, 42, Arc::clone(&logger), &config).unwrap(); // Nothing uses their network key in this test + let mut chan = Channel::::new_outbound( + &&feeest, + &&keys_provider, + their_node_id, + 10_000_000, + 100000, + 42, + Arc::clone(&logger), + &config, + ) + .unwrap(); // Nothing uses their network key in this test chan.their_to_self_delay = 144; chan.our_dust_limit_satoshis = 546; - let funding_info = OutPoint::new(Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0); + let funding_info = OutPoint::new( + Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), + 0, + ); chan.funding_txo = Some(funding_info); let their_pubkeys = ChannelPublicKeys { - funding_pubkey: public_from_secret_hex(&secp_ctx, "1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13"), - revocation_basepoint: PublicKey::from_slice(&hex::decode("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27").unwrap()[..]).unwrap(), - payment_basepoint: public_from_secret_hex(&secp_ctx, "4444444444444444444444444444444444444444444444444444444444444444"), - delayed_payment_basepoint: public_from_secret_hex(&secp_ctx, "1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13"), - htlc_basepoint: public_from_secret_hex(&secp_ctx, "4444444444444444444444444444444444444444444444444444444444444444") + funding_pubkey: public_from_secret_hex( + &secp_ctx, + "1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13", + ), + revocation_basepoint: PublicKey::from_slice( + &hex::decode("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27").unwrap()[..], + ) + .unwrap(), + payment_basepoint: public_from_secret_hex( + &secp_ctx, + "4444444444444444444444444444444444444444444444444444444444444444", + ), + delayed_payment_basepoint: public_from_secret_hex( + &secp_ctx, + "1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13", + ), + htlc_basepoint: public_from_secret_hex( + &secp_ctx, + "4444444444444444444444444444444444444444444444444444444444444444", + ), }; chan_keys.set_remote_channel_pubkeys(&their_pubkeys); - assert_eq!(their_pubkeys.payment_basepoint.serialize()[..], - hex::decode("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..]); + assert_eq!( + their_pubkeys.payment_basepoint.serialize()[..], + hex::decode("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..] + ); - assert_eq!(their_pubkeys.funding_pubkey.serialize()[..], - hex::decode("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1").unwrap()[..]); + assert_eq!( + their_pubkeys.funding_pubkey.serialize()[..], + hex::decode("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1").unwrap()[..] + ); - assert_eq!(their_pubkeys.htlc_basepoint.serialize()[..], - hex::decode("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..]); + assert_eq!( + their_pubkeys.htlc_basepoint.serialize()[..], + hex::decode("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..] + ); // We can't just use build_local_transaction_keys here as the per_commitment_secret is not // derived from a commitment_seed, so instead we copy it here and call // build_commitment_transaction. let delayed_payment_base = PublicKey::from_secret_key(&secp_ctx, chan.local_keys.delayed_payment_base_key()); - let per_commitment_secret = SecretKey::from_slice(&hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap(); + let per_commitment_secret = SecretKey::from_slice( + &hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..], + ) + .unwrap(); let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret); let htlc_basepoint = PublicKey::from_secret_key(&secp_ctx, chan.local_keys.htlc_base_key()); - let keys = TxCreationKeys::new(&secp_ctx, &per_commitment_point, &delayed_payment_base, &htlc_basepoint, &their_pubkeys.revocation_basepoint, &their_pubkeys.payment_basepoint, &their_pubkeys.htlc_basepoint).unwrap(); + let keys = TxCreationKeys::new( + &secp_ctx, + &per_commitment_point, + &delayed_payment_base, + &htlc_basepoint, + &their_pubkeys.revocation_basepoint, + &their_pubkeys.payment_basepoint, + &their_pubkeys.htlc_basepoint, + ) + .unwrap(); chan.their_pubkeys = Some(their_pubkeys); let mut unsigned_tx: (Transaction, Vec); let mut localtx; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! test_commitment { ( $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr, { $( { $htlc_idx: expr, $their_htlc_sig_hex: expr, $our_htlc_sig_hex: expr, $htlc_tx_hex: expr } ), * @@ -4569,29 +5535,33 @@ mod tests { } chan.pending_inbound_htlcs.push({ - let mut out = InboundHTLCOutput{ + let mut out = InboundHTLCOutput { htlc_id: 0, amount_msat: 1000000, cltv_expiry: 500, payment_hash: PaymentHash([0; 32]), state: InboundHTLCState::Committed, }; - out.payment_hash.0 = Sha256::hash(&hex::decode("0000000000000000000000000000000000000000000000000000000000000000").unwrap()).into_inner(); + out.payment_hash.0 = + Sha256::hash(&hex::decode("0000000000000000000000000000000000000000000000000000000000000000").unwrap()) + .into_inner(); out }); chan.pending_inbound_htlcs.push({ - let mut out = InboundHTLCOutput{ + let mut out = InboundHTLCOutput { htlc_id: 1, amount_msat: 2000000, cltv_expiry: 501, payment_hash: PaymentHash([0; 32]), state: InboundHTLCState::Committed, }; - out.payment_hash.0 = Sha256::hash(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()).into_inner(); + out.payment_hash.0 = + Sha256::hash(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()) + .into_inner(); out }); chan.pending_outbound_htlcs.push({ - let mut out = OutboundHTLCOutput{ + let mut out = OutboundHTLCOutput { htlc_id: 2, amount_msat: 2000000, cltv_expiry: 502, @@ -4599,11 +5569,13 @@ mod tests { state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), }; - out.payment_hash.0 = Sha256::hash(&hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).into_inner(); + out.payment_hash.0 = + Sha256::hash(&hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap()) + .into_inner(); out }); chan.pending_outbound_htlcs.push({ - let mut out = OutboundHTLCOutput{ + let mut out = OutboundHTLCOutput { htlc_id: 3, amount_msat: 3000000, cltv_expiry: 503, @@ -4611,18 +5583,22 @@ mod tests { state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), }; - out.payment_hash.0 = Sha256::hash(&hex::decode("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).into_inner(); + out.payment_hash.0 = + Sha256::hash(&hex::decode("0303030303030303030303030303030303030303030303030303030303030303").unwrap()) + .into_inner(); out }); chan.pending_inbound_htlcs.push({ - let mut out = InboundHTLCOutput{ + let mut out = InboundHTLCOutput { htlc_id: 4, amount_msat: 4000000, cltv_expiry: 504, payment_hash: PaymentHash([0; 32]), state: InboundHTLCState::Committed, }; - out.payment_hash.0 = Sha256::hash(&hex::decode("0404040404040404040404040404040404040404040404040404040404040404").unwrap()).into_inner(); + out.payment_hash.0 = + Sha256::hash(&hex::decode("0404040404040404040404040404040404040404040404040404040404040404").unwrap()) + .into_inner(); out }); @@ -4665,33 +5641,33 @@ mod tests { chan.feerate_per_kw = 647; test_commitment!("3045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b", - "304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d1163", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e09c6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040048304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d116301483045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "30440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab343740", - "304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a", - "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab3437400147304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000"}, - - { 1, - "304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b0", - "304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac", - "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60100000000000000000124060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b00147304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, - - { 2, - "304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d833", - "3045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877", - "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6020000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d83301483045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"}, - - { 3, - "30450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d", - "3045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb", - "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6030000000000000000010c0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d01483045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 4, - "3045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f0", - "304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f", - "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb604000000000000000001da0d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f00147304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + "304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d1163", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8007e80300000000000022002052bfef0479d7b293c27e0f1eb294bea154c63a3294ef092c19af51409bce0e2ad007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110e09c6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040048304502210094bfd8f5572ac0157ec76a9551b6c5216a4538c07cd13a51af4a54cb26fa14320220768efce8ce6f4a5efac875142ff19237c011343670adf9c7ac69704a120d116301483045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "30440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab343740", + "304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a", + "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220385a5afe75632f50128cbb029ee95c80156b5b4744beddc729ad339c9ca432c802202ba5f48550cad3379ac75b9b4fedb86a35baa6947f16ba5037fb8b11ab3437400147304402205999590b8a79fa346e003a68fd40366397119b2b0cdf37b149968d6bc6fbcc4702202b1e1fb5ab7864931caed4e732c359e0fe3d86a548b557be2246efb1708d579a012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000"}, + + { 1, + "304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b0", + "304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac", + "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb60100000000000000000124060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207ceb6678d4db33d2401fdc409959e57c16a6cb97a30261d9c61f29b8c58d34b90220084b4a17b4ca0e86f2d798b3698ca52de5621f2ce86f80bed79afa66874511b00147304402207ff03eb0127fc7c6cae49cc29e2a586b98d1e8969cf4a17dfa50b9c2647720b902205e2ecfda2252956c0ca32f175080e75e4e390e433feb1f8ce9f2ba55648a1dac01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, + + { 2, + "304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d833", + "3045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877", + "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6020000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a401b29a0dff0d18ec903502c13d83e7ec019450113f4a7655a4ce40d1f65ba0220217723a084e727b6ca0cc8b6c69c014a7e4a01fcdcba3e3993f462a3c574d83301483045022100d50d067ca625d54e62df533a8f9291736678d0b86c28a61bb2a80cf42e702d6e02202373dde7e00218eacdafb9415fe0e1071beec1857d1af3c6a201a44cbc47c877012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"}, + + { 3, + "30450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d", + "3045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb", + "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb6030000000000000000010c0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009b1c987ba599ee3bde1dbca776b85481d70a78b681a8d84206723e2795c7cac002207aac84ad910f8598c4d1c0ea2e3399cf6627a4e3e90131315bc9f038451ce39d01483045022100db9dc65291077a52728c622987e9895b7241d4394d6dcb916d7600a3e8728c22022036ee3ee717ba0bb5c45ee84bc7bbf85c0f90f26ae4e4a25a6b4241afa8a3f1cb01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 4, + "3045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f0", + "304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f", + "020000000001018323148ce2419f21ca3d6780053747715832e18ac780931a514b187768882bb604000000000000000001da0d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100cc28030b59f0914f45b84caa983b6f8effa900c952310708c2b5b00781117022022027ba2ccdf94d03c6d48b327f183f6e28c8a214d089b9227f94ac4f85315274f00147304402202d1a3c0d31200265d2a2def2753ead4959ae20b4083e19553acfffa5dfab60bf022020ede134149504e15b88ab261a066de49848411e15e70f9e6a5462aec2949f8f012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with six outputs untrimmed (minimum feerate) @@ -4699,28 +5675,28 @@ mod tests { chan.feerate_per_kw = 648; test_commitment!("3044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b057", - "3045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431104e9d6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de01473044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b05701475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "3044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada8", - "3045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc098", - "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10000000000000000000123060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada801483045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc09801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, - - { 1, - "3045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d4", - "304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0", - "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10100000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d40147304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"}, - - { 2, - "3045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c2", - "304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda3", - "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd1020000000000000000010b0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c20147304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda301008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 3, - "3044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f", - "304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6", - "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd103000000000000000001d90d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f0147304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + "3045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431104e9d6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100a2270d5950c89ae0841233f6efea9c951898b301b2e89e0adbd2c687b9f32efa02207943d90f95b9610458e7c65a576e149750ff3accaacad004cd85e70b235e27de01473044022072714e2fbb93cdd1c42eb0828b4f2eff143f717d8f26e79d6ada4f0dcb681bbe02200911be4e5161dd6ebe59ff1c58e1997c4aea804f81db6b698821db6093d7b05701475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "3044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada8", + "3045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc098", + "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10000000000000000000123060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022062ef2e77591409d60d7817d9bb1e71d3c4a2931d1a6c7c8307422c84f001a251022022dad9726b0ae3fe92bda745a06f2c00f92342a186d84518588cf65f4dfaada801483045022100a4c574f00411dd2f978ca5cdc1b848c311cd7849c087ad2f21a5bce5e8cc5ae90220090ae39a9bce2fb8bc879d7e9f9022df249f41e25e51f1a9bf6447a9eeffc09801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, + + { 1, + "3045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d4", + "304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0", + "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd10100000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e968cbbb5f402ed389fdc7f6cd2a80ed650bb42c79aeb2a5678444af94f6c78502204b47a1cb24ab5b0b6fe69fe9cfc7dba07b9dd0d8b95f372c1d9435146a88f8d40147304402207679cf19790bea76a733d2fa0672bd43ab455687a068f815a3d237581f57139a0220683a1a799e102071c206b207735ca80f627ab83d6616b4bcd017c5d79ef3e7d0012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"}, + + { 2, + "3045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c2", + "304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda3", + "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd1020000000000000000010b0a0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100aa91932e305292cf9969cc23502bbf6cef83a5df39c95ad04a707c4f4fed5c7702207099fc0f3a9bfe1e7683c0e9aa5e76c5432eb20693bf4cb182f04d383dc9c8c20147304402200df76fea718745f3c529bac7fd37923e7309ce38b25c0781e4cf514dd9ef8dc802204172295739dbae9fe0474dcee3608e3433b4b2af3a2e6787108b02f894dcdda301008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 3, + "3044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f", + "304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6", + "02000000000101579c183eca9e8236a5d7f5dcd79cfec32c497fdc0ec61533cde99ecd436cadd103000000000000000001d90d0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022035cac88040a5bba420b1c4257235d5015309113460bc33f2853cd81ca36e632402202fc94fd3e81e9d34a9d01782a0284f3044370d03d60f3fc041e2da088d2de58f0147304402200daf2eb7afd355b4caf6fb08387b5f031940ea29d1a9f35071288a839c9039e4022067201b562456e7948616c13acb876b386b511599b58ac1d94d127f91c50463a6012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with six outputs untrimmed (maximum feerate) @@ -4728,28 +5704,28 @@ mod tests { chan.feerate_per_kw = 2069; test_commitment!("3044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb4", - "304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311077956a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea01473044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb401475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "3045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f992", - "3044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae66402", - "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0000000000000000000175020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f99201473044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae6640201008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, - - { 1, - "3045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f4", - "3045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f", - "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0100000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f401483045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"}, - - { 2, - "3045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef18", - "304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f9", - "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a020000000000000000015d060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef180147304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f901008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 3, - "30450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c", - "304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5", - "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a03000000000000000001f2090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c0147304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000" } + "304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8006d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2db80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311077956a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203ca8f31c6a47519f83255dc69f1894d9a6d7476a19f498d31eaf0cd3a85eeb63022026fd92dc752b33905c4c838c528b692a8ad4ced959990b5d5ee2ff940fa90eea01473044022001d55e488b8b035b2dd29d50b65b530923a416d47f377284145bc8767b1b6a75022019bb53ddfe1cefaf156f924777eaaf8fdca1810695a7d0a247ad2afba8232eb401475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "3045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f992", + "3044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae66402", + "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0000000000000000000175020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d1cf354de41c1369336cf85b225ed033f1f8982a01be503668df756a7e668b66022001254144fb4d0eecc61908fccc3388891ba17c5d7a1a8c62bdd307e5a513f99201473044022056eb1af429660e45a1b0b66568cb8c4a3aa7e4c9c292d5d6c47f86ebf2c8838f022065c3ac4ebe980ca7a41148569be4ad8751b0a724a41405697ec55035dae6640201008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, + + { 1, + "3045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f4", + "3045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f", + "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a0100000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d065569dcb94f090345402736385efeb8ea265131804beac06dd84d15dd2d6880220664feb0b4b2eb985fadb6ec7dc58c9334ea88ce599a9be760554a2d4b3b5d9f401483045022100914bb232cd4b2690ee3d6cb8c3713c4ac9c4fb925323068d8b07f67c8541f8d9022057152f5f1615b793d2d45aac7518989ae4fe970f28b9b5c77504799d25433f7f012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"}, + + { 2, + "3045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef18", + "304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f9", + "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a020000000000000000015d060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d4e69d363de993684eae7b37853c40722a4c1b4a7b588ad7b5d8a9b5006137a102207a069c628170ee34be5612747051bdcc087466dbaa68d5756ea81c10155aef180147304402200e362443f7af830b419771e8e1614fc391db3a4eb799989abfc5ab26d6fcd032022039ab0cad1c14dfbe9446bf847965e56fe016e0cbcf719fd18c1bfbf53ecbd9f901008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 3, + "30450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c", + "304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5", + "02000000000101ca94a9ad516ebc0c4bdd7b6254871babfa978d5accafb554214137d398bfcf6a03000000000000000001f2090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221008ec888e36e4a4b3dc2ed6b823319855b2ae03006ca6ae0d9aa7e24bfc1d6f07102203b0f78885472a67ff4fe5916c0bb669487d659527509516fc3a08e87a2cc0a7c0147304402202c3e14282b84b02705dfd00a6da396c9fe8a8bcb1d3fdb4b20a4feba09440e8b02202b058b39aa9b0c865b22095edcd9ff1f71bbfe20aa4993755e54d042755ed0d5012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000" } }); // commitment tx with five outputs untrimmed (minimum feerate) @@ -4757,23 +5733,23 @@ mod tests { chan.feerate_per_kw = 2070; test_commitment!("3045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f37526", - "30440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd0", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110da966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd001483045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f3752601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "3045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f891", - "3045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb8", - "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a2180000000000000000000174020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f89101483045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, - - { 1, - "3044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf6", - "3045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d", - "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a218010000000000000000015c060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf601483045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 2, - "3045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a4", - "304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04", - "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a21802000000000000000001f1090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a40147304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + "30440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd0", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110da966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e04004730440220443cb07f650aebbba14b8bc8d81e096712590f524c5991ac0ed3bbc8fd3bd0c7022028a635f548e3ca64b19b69b1ea00f05b22752f91daf0b6dab78e62ba52eb7fd001483045022100f2377f7a67b7fc7f4e2c0c9e3a7de935c32417f5668eda31ea1db401b7dc53030220415fdbc8e91d0f735e70c21952342742e25249b0d062d43efbfc564499f3752601475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "3045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f891", + "3045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb8", + "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a2180000000000000000000174020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100eed143b1ee4bed5dc3cde40afa5db3e7354cbf9c44054b5f713f729356f08cf7022077161d171c2bbd9badf3c9934de65a4918de03bbac1450f715275f75b103f89101483045022100a0d043ed533e7fb1911e0553d31a8e2f3e6de19dbc035257f29d747c5e02f1f5022030cd38d8e84282175d49c1ebe0470db3ebd59768cf40780a784e248a43904fb801008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, + + { 1, + "3044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf6", + "3045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d", + "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a218010000000000000000015c060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022071e9357619fd8d29a411dc053b326a5224c5d11268070e88ecb981b174747c7a02202b763ae29a9d0732fa8836dd8597439460b50472183f420021b768981b4f7cf601483045022100adb1d679f65f96178b59f23ed37d3b70443118f345224a07ecb043eee2acc157022034d24524fe857144a3bcfff3065a9994d0a6ec5f11c681e49431d573e242612d01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 2, + "3045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a4", + "304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04", + "0200000000010140a83ce364747ff277f4d7595d8d15f708418798922c40bc2b056aca5485a21802000000000000000001f1090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100c9458a4d2cbb741705577deb0a890e5cb90ee141be0400d3162e533727c9cb2102206edcf765c5dc5e5f9b976ea8149bf8607b5a0efb30691138e1231302b640d2a40147304402200831422aa4e1ee6d55e0b894201770a8f8817a189356f2d70be76633ffa6a6f602200dd1b84a4855dc6727dd46c98daae43dfc70889d1ba7ef0087529a57c06e5e04012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with five outputs untrimmed (maximum feerate) @@ -4781,23 +5757,23 @@ mod tests { chan.feerate_per_kw = 2194; test_commitment!("3045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec86203953348", - "304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f7061", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311040966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f706101483045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec8620395334801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "30450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf44", - "3044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f", - "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf4401473044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, - - { 1, - "30440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d", - "304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c915", - "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a010000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d0147304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c91501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 2, - "3045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a", - "3045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0", - "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a020000000000000000019a090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a01483045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + "304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f7061", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020403d394747cae42e98ff01734ad5c08f82ba123d3d9a620abda88989651e2ab5b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311040966a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b1b010c109c2ecbe7feb2d259b9c4126bd5dc99ee693c422ec0a5781fe161ba0220571fe4e2c649dea9c7aaf7e49b382962f6a3494963c97d80fef9a430ca3f706101483045022100d33c4e541aa1d255d41ea9a3b443b3b822ad8f7f86862638aac1f69f8f760577022007e2a18e6931ce3d3a804b1c78eda1de17dbe1fb7a95488c9a4ec8620395334801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "30450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf44", + "3044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f", + "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004830450221009ed2f0a67f99e29c3c8cf45c08207b765980697781bb727fe0b1416de0e7622902206052684229bc171419ed290f4b615c943f819c0262414e43c5b91dcf72ddcf4401473044022004ad5f04ae69c71b3b141d4db9d0d4c38d84009fb3cfeeae6efdad414487a9a0022042d3fe1388c1ff517d1da7fb4025663d372c14728ed52dc88608363450ff6a2f01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"}, + + { 1, + "30440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d", + "304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c915", + "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a010000000000000000010a060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220155d3b90c67c33a8321996a9be5b82431b0c126613be751d400669da9d5c696702204318448bcd48824439d2c6a70be6e5747446be47ff45977cf41672bdc9b6b12d0147304402201707050c870c1f77cc3ed58d6d71bf281de239e9eabd8ef0955bad0d7fe38dcc02204d36d80d0019b3a71e646a08fa4a5607761d341ae8be371946ebe437c289c91501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 2, + "3045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a", + "3045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0", + "02000000000101fb824d4e4dafc0f567789dee3a6bce8d411fe80f5563d8cdfdcc7d7e4447d43a020000000000000000019a090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a12a9a473ece548584aabdd051779025a5ed4077c4b7aa376ec7a0b1645e5a48022039490b333f53b5b3e2ddde1d809e492cba2b3e5fc3a436cd3ffb4cd3d500fa5a01483045022100ff200bc934ab26ce9a559e998ceb0aee53bc40368e114ab9d3054d9960546e2802202496856ca163ac12c143110b6b3ac9d598df7254f2e17b3b94c3ab5301f4c3b0012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with four outputs untrimmed (minimum feerate) @@ -4805,18 +5781,18 @@ mod tests { chan.feerate_per_kw = 2195; test_commitment!("304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb7924298", - "304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a5429", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110b8976a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a54290147304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb792429801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "3045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc", - "3045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc704390", - "020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0000000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc01483045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc70439001008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 1, - "3045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92", - "30440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8", - "020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0100000000000000000199090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92014730440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + "304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a5429", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110b8976a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402203b12d44254244b8ff3bb4129b0920fd45120ab42f553d9976394b099d500c99e02205e95bb7a3164852ef0c48f9e0eaf145218f8e2c41251b231f03cbdc4f29a54290147304402205e2f76d4657fb732c0dfc820a18a7301e368f5799e06b7828007633741bda6df0220458009ae59d0c6246065c419359e05eb2a4b4ef4a1b310cc912db44eb792429801475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "3045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc", + "3045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc704390", + "020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0000000000000000000109060000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100a8a78fa1016a5c5c3704f2e8908715a3cef66723fb95f3132ec4d2d05cd84fb4022025ac49287b0861ec21932405f5600cbce94313dbde0e6c5d5af1b3366d8afbfc01483045022100be6ae1977fd7b630a53623f3f25c542317ccfc2b971782802a4f1ef538eb22b402207edc4d0408f8f38fd3c7365d1cfc26511b7cd2d4fecd8b005fba3cd5bc70439001008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 1, + "3045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92", + "30440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8", + "020000000001014e16c488fa158431c1a82e8f661240ec0a71ba0ce92f2721a6538c510226ad5c0100000000000000000199090000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100e769cb156aa2f7515d126cef7a69968629620ce82afcaa9e210969de6850df4602200b16b3f3486a229a48aadde520dbee31ae340dbadaffae74fbb56681fef27b92014730440220665b9cb4a978c09d1ca8977a534999bc8a49da624d0c5439451dd69cde1a003d022070eae0620f01f3c1bd029cc1488da13fb40fdab76f396ccd335479a11c5276d8012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with four outputs untrimmed (maximum feerate) @@ -4824,18 +5800,18 @@ mod tests { chan.feerate_per_kw = 3702; test_commitment!("3045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c1", - "304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b0", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431106f916a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b001483045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c101475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - - { 0, - "3045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb", - "304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a", - "02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb0147304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, - - { 1, - "3045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9", - "30440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c", - "02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30100000000000000000176050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9014730440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + "304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b0", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8004b80b000000000000220020c20b5d1f8584fd90443e7b7b720136174fa4b9333c261d04dbbd012635c0f419a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431106f916a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402200e930a43c7951162dc15a2b7344f48091c74c70f7024e7116e900d8bcfba861c022066fa6cbda3929e21daa2e7e16a4b948db7e8919ef978402360d1095ffdaff7b001483045022100c1a3b0b60ca092ed5080121f26a74a20cec6bdee3f8e47bae973fcdceb3eda5502207d467a9873c939bf3aa758014ae67295fedbca52412633f7e5b2670fc7c381c101475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + + { 0, + "3045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb", + "304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a", + "02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100dfb73b4fe961b31a859b2bb1f4f15cabab9265016dd0272323dc6a9e85885c54022059a7b87c02861ee70662907f25ce11597d7b68d3399443a831ae40e777b76bdb0147304402202765b9c9ece4f127fa5407faf66da4c5ce2719cdbe47cd3175fc7d48b482e43d02205605125925e07bad1e41c618a4b434d72c88a164981c4b8af5eaf4ee9142ec3a01008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"}, + + { 1, + "3045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9", + "30440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c", + "02000000000101b8de11eb51c22498fe39722c7227b6e55ff1a94146cf638458cb9bc6a060d3a30100000000000000000176050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100ea9dc2a7c3c3640334dab733bb4e036e32a3106dc707b24227874fa4f7da746802204d672f7ac0fe765931a8df10b81e53a3242dd32bd9dc9331eb4a596da87954e9014730440220048a41c660c4841693de037d00a407810389f4574b3286afb7bc392a438fa3f802200401d71fa87c64fe621b49ac07e3bf85157ac680acb977124da28652cc7f1a5c012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with three outputs untrimmed (minimum feerate) @@ -4843,13 +5819,13 @@ mod tests { chan.feerate_per_kw = 3703; test_commitment!("30450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb0", - "3044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110eb936a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506014830450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + "3044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110eb936a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022047305531dd44391dce03ae20f8735005c615eb077a974edb0059ea1a311857d602202e0ed6972fbdd1e8cb542b06e0929bc41b2ddf236e04cb75edd56151f4197506014830450221008b7c191dd46893b67b628e618d2dc8e81169d38bade310181ab77d7c94c6675e02203b4dd131fd7c9deb299560983dcdc485545c98f989f7ae8180c28289f9e6bdb001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - { 0, - "3044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd", - "3045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724", - "020000000001011c076aa7fb3d7460d10df69432c904227ea84bbf3134d4ceee5fb0f135ef206d0000000000000000000175050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd01483045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + { 0, + "3044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd", + "3045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724", + "020000000001011c076aa7fb3d7460d10df69432c904227ea84bbf3134d4ceee5fb0f135ef206d0000000000000000000175050000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500473044022044f65cf833afdcb9d18795ca93f7230005777662539815b8a601eeb3e57129a902206a4bf3e53392affbba52640627defa8dc8af61c958c9e827b2798ab45828abdd01483045022100b94d931a811b32eeb885c28ddcf999ae1981893b21dd1329929543fe87ce793002206370107fdd151c5f2384f9ceb71b3107c69c74c8ed5a28a94a4ab2d27d3b0724012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with three outputs untrimmed (maximum feerate) @@ -4857,13 +5833,13 @@ mod tests { chan.feerate_per_kw = 4914; test_commitment!("304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e", - "304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe26", - "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { + "304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe26", + "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", { - { 0, - "3045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf", - "304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68", - "0200000000010110a3fdcbcd5db477cd3ad465e7f501ffa8c437e8301f00a6061138590add757f0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf0148304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} + { 0, + "3045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf", + "304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68", + "0200000000010110a3fdcbcd5db477cd3ad465e7f501ffa8c437e8301f00a6061138590add757f0000000000000000000122020000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100fcb38506bfa11c02874092a843d0cc0a8613c23b639832564a5f69020cb0f6ba02206508b9e91eaa001425c190c68ee5f887e1ad5b1b314002e74db9dbd9e42dbecf0148304502210086e76b460ddd3cea10525fba298405d3fe11383e56966a5091811368362f689a02200f72ee75657915e0ede89c28709acd113ede9e1b7be520e3bc5cda425ecd6e68012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"} }); // commitment tx with two outputs untrimmed (minimum feerate) @@ -4904,23 +5880,39 @@ mod tests { // Test vectors from BOLT 3 Appendix D: let mut seed = [0; 32]; - seed[0..32].clone_from_slice(&hex::decode("0000000000000000000000000000000000000000000000000000000000000000").unwrap()); - assert_eq!(chan_utils::build_commitment_secret(&seed, 281474976710655), - hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap()[..]); + seed[0..32].clone_from_slice( + &hex::decode("0000000000000000000000000000000000000000000000000000000000000000").unwrap(), + ); + assert_eq!( + chan_utils::build_commitment_secret(&seed, 281474976710655), + hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap()[..] + ); - seed[0..32].clone_from_slice(&hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap()); - assert_eq!(chan_utils::build_commitment_secret(&seed, 281474976710655), - hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..]); + seed[0..32].clone_from_slice( + &hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap(), + ); + assert_eq!( + chan_utils::build_commitment_secret(&seed, 281474976710655), + hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..] + ); - assert_eq!(chan_utils::build_commitment_secret(&seed, 0xaaaaaaaaaaa), - hex::decode("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..]); + assert_eq!( + chan_utils::build_commitment_secret(&seed, 0xaaaaaaaaaaa), + hex::decode("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..] + ); - assert_eq!(chan_utils::build_commitment_secret(&seed, 0x555555555555), - hex::decode("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..]); + assert_eq!( + chan_utils::build_commitment_secret(&seed, 0x555555555555), + hex::decode("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..] + ); - seed[0..32].clone_from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()); - assert_eq!(chan_utils::build_commitment_secret(&seed, 1), - hex::decode("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..]); + seed[0..32].clone_from_slice( + &hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap(), + ); + assert_eq!( + chan_utils::build_commitment_secret(&seed, 1), + hex::decode("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..] + ); } #[test] @@ -4928,25 +5920,53 @@ mod tests { // Test vectors from BOLT 3 Appendix E: let secp_ctx = Secp256k1::new(); - let base_secret = SecretKey::from_slice(&hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap()[..]).unwrap(); - let per_commitment_secret = SecretKey::from_slice(&hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap(); + let base_secret = SecretKey::from_slice( + &hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f").unwrap()[..], + ) + .unwrap(); + let per_commitment_secret = SecretKey::from_slice( + &hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..], + ) + .unwrap(); let base_point = PublicKey::from_secret_key(&secp_ctx, &base_secret); - assert_eq!(base_point.serialize()[..], hex::decode("036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2").unwrap()[..]); + assert_eq!( + base_point.serialize()[..], + hex::decode("036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2").unwrap()[..] + ); let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret); - assert_eq!(per_commitment_point.serialize()[..], hex::decode("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486").unwrap()[..]); + assert_eq!( + per_commitment_point.serialize()[..], + hex::decode("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486").unwrap()[..] + ); - assert_eq!(chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &base_point).unwrap().serialize()[..], - hex::decode("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..]); + assert_eq!( + chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &base_point).unwrap().serialize()[..], + hex::decode("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..] + ); - assert_eq!(chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &base_secret).unwrap(), - SecretKey::from_slice(&hex::decode("cbced912d3b21bf196a766651e436aff192362621ce317704ea2f75d87e7be0f").unwrap()[..]).unwrap()); + assert_eq!( + chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &base_secret).unwrap(), + SecretKey::from_slice( + &hex::decode("cbced912d3b21bf196a766651e436aff192362621ce317704ea2f75d87e7be0f").unwrap()[..] + ) + .unwrap() + ); - assert_eq!(chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &base_point).unwrap().serialize()[..], - hex::decode("02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0").unwrap()[..]); + assert_eq!( + chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &base_point) + .unwrap() + .serialize()[..], + hex::decode("02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0").unwrap()[..] + ); - assert_eq!(chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_secret, &base_secret).unwrap(), - SecretKey::from_slice(&hex::decode("d09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110").unwrap()[..]).unwrap()); + assert_eq!( + chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_secret, &base_secret).unwrap(), + SecretKey::from_slice( + &hex::decode("d09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110").unwrap()[..] + ) + .unwrap() + ); } } diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 08b28cc0f55..7a43ba56c0f 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -9,48 +9,51 @@ //! imply it needs to fail HTLCs/payments/channels it manages). use bitcoin::blockdata::block::BlockHeader; -use bitcoin::blockdata::transaction::Transaction; use bitcoin::blockdata::constants::genesis_block; +use bitcoin::blockdata::transaction::Transaction; use bitcoin::network::constants::Network; use bitcoin::util::hash::BitcoinHash; -use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hash_types::BlockHash; +use bitcoin::hashes::cmp::fixed_time_eq; use bitcoin::hashes::hmac::{Hmac, HmacEngine}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::sha256d::Hash as Sha256dHash; -use bitcoin::hashes::cmp::fixed_time_eq; -use bitcoin::hash_types::BlockHash; +use bitcoin::hashes::{Hash, HashEngine}; -use bitcoin::secp256k1::key::{SecretKey,PublicKey}; -use bitcoin::secp256k1::Secp256k1; -use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1; +use bitcoin::secp256k1::ecdh::SharedSecret; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; +use bitcoin::secp256k1::Secp256k1; -use chain::chaininterface::{BroadcasterInterface,ChainListener,FeeEstimator}; +use chain::chaininterface::{BroadcasterInterface, ChainListener, FeeEstimator}; +use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys, KeysInterface, KeysManager}; use chain::transaction::OutPoint; use ln::channel::{Channel, ChannelError}; -use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, ManyChannelMonitor, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; +use ln::channelmonitor::{ + ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, ManyChannelMonitor, ANTI_REORG_DELAY, + CLTV_CLAIM_BUFFER, HTLC_FAIL_BACK_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, +}; use ln::features::{InitFeatures, NodeFeatures}; -use ln::router::{Route, RouteHop}; use ln::msgs; -use ln::onion_utils; use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError}; -use chain::keysinterface::{ChannelKeys, KeysInterface, KeysManager, InMemoryChannelKeys}; -use util::config::UserConfig; -use util::{byte_utils, events}; -use util::ser::{Readable, ReadableArgs, Writeable, Writer}; +use ln::onion_utils; +use ln::router::{Route, RouteHop}; use util::chacha20::{ChaCha20, ChaChaReader}; -use util::logger::Logger; +use util::config::UserConfig; use util::errors::APIError; +use util::logger::Logger; +use util::ser::{Readable, ReadableArgs, Writeable, Writer}; +use util::{byte_utils, events}; -use std::{cmp, mem}; -use std::collections::{HashMap, hash_map, HashSet}; +use std::collections::{hash_map, HashMap, HashSet}; use std::io::{Cursor, Read}; -use std::sync::{Arc, Mutex, MutexGuard, RwLock}; +use std::marker::{Send, Sync}; +use std::ops::Deref; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex, MutexGuard, RwLock}; use std::time::Duration; -use std::marker::{Sync, Send}; -use std::ops::Deref; +use std::{cmp, mem}; // We hold various information about HTLC relay in the HTLC objects in Channel itself: // @@ -104,15 +107,8 @@ pub(super) enum PendingHTLCStatus { } pub(super) enum HTLCForwardInfo { - AddHTLC { - prev_short_channel_id: u64, - prev_htlc_id: u64, - forward_info: PendingHTLCInfo, - }, - FailHTLC { - htlc_id: u64, - err_packet: msgs::OnionErrorPacket, - }, + AddHTLC { prev_short_channel_id: u64, prev_htlc_id: u64, forward_info: PendingHTLCInfo }, + FailHTLC { htlc_id: u64, err_packet: msgs::OnionErrorPacket }, } /// Tracks the inbound corresponding to an outbound HTLC @@ -159,24 +155,19 @@ impl HTLCSource { #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug pub(super) enum HTLCFailReason { - LightningError { - err: msgs::OnionErrorPacket, - }, - Reason { - failure_code: u16, - data: Vec, - } + LightningError { err: msgs::OnionErrorPacket }, + Reason { failure_code: u16, data: Vec }, } /// payment_hash type, use to cross-lock hop #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] -pub struct PaymentHash(pub [u8;32]); +pub struct PaymentHash(pub [u8; 32]); /// payment_preimage type, use to route payment between hop #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] -pub struct PaymentPreimage(pub [u8;32]); +pub struct PaymentPreimage(pub [u8; 32]); /// payment_secret type, use to authenticate sender to the receiver and tie MPP HTLCs together #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] -pub struct PaymentSecret(pub [u8;32]); +pub struct PaymentSecret(pub [u8; 32]); type ShutdownResult = (Option, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>); @@ -197,10 +188,7 @@ impl MsgHandleErrInternal { err: LightningError { err, action: msgs::ErrorAction::SendErrorMessage { - msg: msgs::ErrorMessage { - channel_id, - data: err.to_string() - }, + msg: msgs::ErrorMessage { channel_id, data: err.to_string() }, }, }, shutdown_finish: None, @@ -208,28 +196,22 @@ impl MsgHandleErrInternal { } #[inline] fn ignore_no_close(err: &'static str) -> Self { - Self { - err: LightningError { - err, - action: msgs::ErrorAction::IgnoreError, - }, - shutdown_finish: None, - } + Self { err: LightningError { err, action: msgs::ErrorAction::IgnoreError }, shutdown_finish: None } } #[inline] fn from_no_close(err: msgs::LightningError) -> Self { Self { err, shutdown_finish: None } } #[inline] - fn from_finish_shutdown(err: &'static str, channel_id: [u8; 32], shutdown_res: ShutdownResult, channel_update: Option) -> Self { + fn from_finish_shutdown( + err: &'static str, channel_id: [u8; 32], shutdown_res: ShutdownResult, + channel_update: Option, + ) -> Self { Self { err: LightningError { err, action: msgs::ErrorAction::SendErrorMessage { - msg: msgs::ErrorMessage { - channel_id, - data: err.to_string() - }, + msg: msgs::ErrorMessage { channel_id, data: err.to_string() }, }, }, shutdown_finish: Some((shutdown_res, channel_update)), @@ -239,26 +221,17 @@ impl MsgHandleErrInternal { fn from_chan_no_close(err: ChannelError, channel_id: [u8; 32]) -> Self { Self { err: match err { - ChannelError::Ignore(msg) => LightningError { - err: msg, - action: msgs::ErrorAction::IgnoreError, - }, + ChannelError::Ignore(msg) => LightningError { err: msg, action: msgs::ErrorAction::IgnoreError }, ChannelError::Close(msg) => LightningError { err: msg, action: msgs::ErrorAction::SendErrorMessage { - msg: msgs::ErrorMessage { - channel_id, - data: msg.to_string() - }, + msg: msgs::ErrorMessage { channel_id, data: msg.to_string() }, }, }, ChannelError::CloseDelayBroadcast { msg, .. } => LightningError { err: msg, action: msgs::ErrorAction::SendErrorMessage { - msg: msgs::ErrorMessage { - channel_id, - data: msg.to_string() - }, + msg: msgs::ErrorMessage { channel_id, data: msg.to_string() }, }, }, }, @@ -321,7 +294,8 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum /// issues such as overly long function definitions. Note that the ChannelManager can take any /// type that implements KeysInterface for its keys manager, but this type alias chooses the /// concrete type of the KeysManager. -pub type SimpleArcChannelManager = Arc, Arc, Arc, Arc>>; +pub type SimpleArcChannelManager = + Arc, Arc, Arc, Arc>>; /// SimpleRefChannelManager is a type alias for a ChannelManager reference, and is the reference /// counterpart to the SimpleArcChannelManager type alias. Use this type by default when you don't @@ -331,7 +305,8 @@ pub type SimpleArcChannelManager = Arc = ChannelManager; +pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, M, T, F> = + ChannelManager; /// Manager which keeps track of a number of channels and sends messages to the appropriate /// channel, also tracking HTLC preimages and forwarding onion packets appropriately. @@ -370,10 +345,11 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, M, T, F> = ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { default_configuration: UserConfig, genesis_hash: BlockHash, @@ -439,13 +415,17 @@ pub(super) const CLTV_FAR_FAR_AWAY: u32 = 6 * 24 * 7; //TODO? // LATENCY_GRACE_PERIOD_BLOCKS. #[deny(const_err)] #[allow(dead_code)] -const CHECK_CLTV_EXPIRY_SANITY: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - CLTV_CLAIM_BUFFER - ANTI_REORG_DELAY - LATENCY_GRACE_PERIOD_BLOCKS; +const CHECK_CLTV_EXPIRY_SANITY: u32 = CLTV_EXPIRY_DELTA as u32 + - LATENCY_GRACE_PERIOD_BLOCKS + - CLTV_CLAIM_BUFFER + - ANTI_REORG_DELAY + - LATENCY_GRACE_PERIOD_BLOCKS; // Check for ability of an attacker to make us fail on-chain by delaying inbound claim. See // ChannelMontior::would_broadcast_at_height for a description of why this is needed. #[deny(const_err)] #[allow(dead_code)] -const CHECK_CLTV_EXPIRY_SANITY_2: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2*CLTV_CLAIM_BUFFER; +const CHECK_CLTV_EXPIRY_SANITY_2: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2 * CLTV_CLAIM_BUFFER; /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels pub struct ChannelDetails { @@ -519,6 +499,7 @@ pub enum PaymentSendFailure { PartialFailure(Vec>), } +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! handle_error { ($self: ident, $internal: expr, $their_node_id: expr) => { match $internal { @@ -562,6 +543,7 @@ macro_rules! handle_error { } } +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! break_chan_entry { ($self: ident, $res: expr, $channel_state: expr, $entry: expr) => { match $res { @@ -581,6 +563,7 @@ macro_rules! break_chan_entry { } } +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! try_chan_entry { ($self: ident, $res: expr, $channel_state: expr, $entry: expr) => { match $res { @@ -619,6 +602,7 @@ macro_rules! try_chan_entry { } } +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! handle_monitor_err { ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => { handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment, Vec::new(), Vec::new()) @@ -669,6 +653,7 @@ macro_rules! handle_monitor_err { } } +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! return_monitor_err { ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => { return handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment); @@ -679,6 +664,7 @@ macro_rules! return_monitor_err { } // Does not break in case of TemporaryFailure! +#[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! maybe_break_monitor_err { ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => { match (handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment), $err) { @@ -691,10 +677,11 @@ macro_rules! maybe_break_monitor_err { } impl ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { /// Constructs a new ChannelManager to hold several channels and route between them. /// @@ -714,7 +701,10 @@ impl ChannelMan /// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's /// `block_(dis)connected` methods, which will notify all registered listeners in one /// go. - pub fn new(network: Network, fee_est: F, monitor: M, tx_broadcaster: T, logger: Arc, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Result, secp256k1::Error> { + pub fn new( + network: Network, fee_est: F, monitor: M, tx_broadcaster: T, logger: Arc, keys_manager: K, + config: UserConfig, current_blockchain_height: usize, + ) -> Result, secp256k1::Error> { let secp_ctx = Secp256k1::new(); let res = ChannelManager { @@ -728,7 +718,7 @@ impl ChannelMan last_block_hash: Mutex::new(Default::default()), secp_ctx, - channel_state: Mutex::new(ChannelHolder{ + channel_state: Mutex::new(ChannelHolder { by_id: HashMap::new(), short_to_id: HashMap::new(), forward_htlcs: HashMap::new(), @@ -764,13 +754,26 @@ impl ChannelMan /// /// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat is /// greater than channel_value_satoshis * 1k or channel_value_satoshis is < 1000. - pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, override_config: Option) -> Result<(), APIError> { + pub fn create_channel( + &self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, + override_config: Option, + ) -> Result<(), APIError> { if channel_value_satoshis < 1000 { return Err(APIError::APIMisuseError { err: "channel_value must be at least 1000 satoshis" }); } - let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration }; - let channel = Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key, channel_value_satoshis, push_msat, user_id, Arc::clone(&self.logger), config)?; + let config = + if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration }; + let channel = Channel::new_outbound( + &self.fee_estimator, + &self.keys_manager, + their_network_key, + channel_value_satoshis, + push_msat, + user_id, + Arc::clone(&self.logger), + config, + )?; let res = channel.get_open_channel(self.genesis_hash.clone(), &self.fee_estimator); let _ = self.total_consistency_lock.read().unwrap(); @@ -782,23 +785,27 @@ impl ChannelMan } else { panic!("RNG is bad???"); } - }, - hash_map::Entry::Vacant(entry) => { entry.insert(channel); } + } + hash_map::Entry::Vacant(entry) => { + entry.insert(channel); + } } - channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel { - node_id: their_network_key, - msg: res, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendOpenChannel { node_id: their_network_key, msg: res }); Ok(()) } - fn list_channels_with_filter)) -> bool>(&self, f: Fn) -> Vec { + fn list_channels_with_filter)) -> bool>( + &self, f: Fn, + ) -> Vec { let mut res = Vec::new(); { let channel_state = self.channel_state.lock().unwrap(); res.reserve(channel_state.by_id.len()); for (channel_id, channel) in channel_state.by_id.iter().filter(f) { - let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat(); + let (inbound_capacity_msat, outbound_capacity_msat) = + channel.get_inbound_outbound_available_balance_msat(); res.push(ChannelDetails { channel_id: (*channel_id).clone(), short_channel_id: channel.get_short_channel_id(), @@ -855,32 +862,41 @@ impl ChannelMan let (shutdown_msg, failed_htlcs) = chan_entry.get_mut().get_shutdown()?; channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { node_id: chan_entry.get().get_their_node_id(), - msg: shutdown_msg + msg: shutdown_msg, }); if chan_entry.get().is_shutdown() { if let Some(short_id) = chan_entry.get().get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } (failed_htlcs, Some(chan_entry.remove_entry().1)) - } else { (failed_htlcs, None) } - }, - hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable{err: "No such channel"}) + } else { + (failed_htlcs, None) + } + } + hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable { err: "No such channel" }), } }; for htlc_source in failed_htlcs.drain(..) { - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + self.fail_htlc_backwards_internal( + self.channel_state.lock().unwrap(), + htlc_source.0, + &htlc_source.1, + HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, + ); } let chan_update = if let Some(chan) = chan_option { if let Ok(update) = self.get_channel_update(&chan) { Some(update) - } else { None } - } else { None }; + } else { + None + } + } else { + None + }; if let Some(update) = chan_update { let mut channel_state = self.channel_state.lock().unwrap(); - channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { - msg: update - }); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } Ok(()) @@ -891,7 +907,12 @@ impl ChannelMan let (funding_txo_option, monitor_update, mut failed_htlcs) = shutdown_res; log_trace!(self, "Finishing force-closure of channel {} HTLCs to fail", failed_htlcs.len()); for htlc_source in failed_htlcs.drain(..) { - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + self.fail_htlc_backwards_internal( + self.channel_state.lock().unwrap(), + htlc_source.0, + &htlc_source.1, + HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, + ); } if let Some(funding_txo) = funding_txo_option { // There isn't anything we can do if we get an update failure - we're already @@ -923,9 +944,7 @@ impl ChannelMan self.finish_force_close_channel(chan.force_shutdown(true)); if let Ok(update) = self.get_channel_update(&chan) { let mut channel_state = self.channel_state.lock().unwrap(); - channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { - msg: update - }); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } } @@ -937,7 +956,10 @@ impl ChannelMan } } - fn decode_update_add_htlc_onion(&self, msg: &msgs::UpdateAddHTLC) -> (PendingHTLCStatus, MutexGuard>) { + fn decode_update_add_htlc_onion( + &self, msg: &msgs::UpdateAddHTLC, + ) -> (PendingHTLCStatus, MutexGuard>) { + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! return_malformed_err { ($msg: expr, $err_code: expr) => { { @@ -958,7 +980,9 @@ impl ChannelMan let shared_secret = { let mut arr = [0; 32]; - arr.copy_from_slice(&SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key)[..]); + arr.copy_from_slice( + &SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key)[..], + ); arr }; let (rho, mu) = onion_utils::gen_rho_mu_from_shared_secret(&shared_secret); @@ -981,6 +1005,8 @@ impl ChannelMan } let mut channel_state = None; + + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! return_err { ($msg: expr, $err_code: expr, $data: expr) => { { @@ -998,152 +1024,168 @@ impl ChannelMan } let mut chacha = ChaCha20::new(&rho, &[0u8; 8]); - let mut chacha_stream = ChaChaReader { chacha: &mut chacha, read: Cursor::new(&msg.onion_routing_packet.hop_data[..]) }; + let mut chacha_stream = + ChaChaReader { chacha: &mut chacha, read: Cursor::new(&msg.onion_routing_packet.hop_data[..]) }; let (next_hop_data, next_hop_hmac) = { match msgs::OnionHopData::read(&mut chacha_stream) { Err(err) => { let error_code = match err { msgs::DecodeError::UnknownVersion => 0x4000 | 1, // unknown realm byte - msgs::DecodeError::UnknownRequiredFeature| - msgs::DecodeError::InvalidValue| - msgs::DecodeError::ShortRead => 0x4000 | 22, // invalid_onion_payload - _ => 0x2000 | 2, // Should never happen + msgs::DecodeError::UnknownRequiredFeature + | msgs::DecodeError::InvalidValue + | msgs::DecodeError::ShortRead => 0x4000 | 22, // invalid_onion_payload + _ => 0x2000 | 2, // Should never happen }; - return_err!("Unable to decode our hop data", error_code, &[0;0]); - }, + return_err!("Unable to decode our hop data", error_code, &[0; 0]); + } Ok(msg) => { let mut hmac = [0; 32]; if let Err(_) = chacha_stream.read_exact(&mut hmac[..]) { - return_err!("Unable to decode hop data", 0x4000 | 22, &[0;0]); + return_err!("Unable to decode hop data", 0x4000 | 22, &[0; 0]); } (msg, hmac) - }, + } } }; let pending_forward_info = if next_hop_hmac == [0; 32] { - #[cfg(test)] - { - // In tests, make sure that the initial onion pcket data is, at least, non-0. - // We could do some fancy randomness test here, but, ehh, whatever. - // This checks for the issue where you can calculate the path length given the - // onion data as all the path entries that the originator sent will be here - // as-is (and were originally 0s). - // Of course reverse path calculation is still pretty easy given naive routing - // algorithms, but this fixes the most-obvious case. - let mut next_bytes = [0; 32]; - chacha_stream.read_exact(&mut next_bytes).unwrap(); - assert_ne!(next_bytes[..], [0; 32][..]); - chacha_stream.read_exact(&mut next_bytes).unwrap(); - assert_ne!(next_bytes[..], [0; 32][..]); - } - - // OUR PAYMENT! - // final_expiry_too_soon - // We have to have some headroom to broadcast on chain if we have the preimage, so make sure we have at least - // HTLC_FAIL_BACK_BUFFER blocks to go. - // Also, ensure that, in the case of an unknown payment hash, our payment logic has enough time to fail the HTLC backward - // before our onchain logic triggers a channel closure (see HTLC_FAIL_BACK_BUFFER rational). - if (msg.cltv_expiry as u64) <= self.latest_block_height.load(Ordering::Acquire) as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 { - return_err!("The final CLTV expiry is too soon to handle", 17, &[0;0]); - } - // final_incorrect_htlc_amount - if next_hop_data.amt_to_forward > msg.amount_msat { - return_err!("Upstream node sent less than we were supposed to receive in payment", 19, &byte_utils::be64_to_array(msg.amount_msat)); - } - // final_incorrect_cltv_expiry - if next_hop_data.outgoing_cltv_value != msg.cltv_expiry { - return_err!("Upstream node set CLTV to the wrong value", 18, &byte_utils::be32_to_array(msg.cltv_expiry)); - } - - let payment_data = match next_hop_data.format { - msgs::OnionHopDataFormat::Legacy { .. } => None, - msgs::OnionHopDataFormat::NonFinalNode { .. } => return_err!("Got non final data with an HMAC of 0", 0x4000 | 22, &[0;0]), - msgs::OnionHopDataFormat::FinalNode { payment_data } => payment_data, - }; + #[cfg(test)] + { + // In tests, make sure that the initial onion pcket data is, at least, non-0. + // We could do some fancy randomness test here, but, ehh, whatever. + // This checks for the issue where you can calculate the path length given the + // onion data as all the path entries that the originator sent will be here + // as-is (and were originally 0s). + // Of course reverse path calculation is still pretty easy given naive routing + // algorithms, but this fixes the most-obvious case. + let mut next_bytes = [0; 32]; + chacha_stream.read_exact(&mut next_bytes).unwrap(); + assert_ne!(next_bytes[..], [0; 32][..]); + chacha_stream.read_exact(&mut next_bytes).unwrap(); + assert_ne!(next_bytes[..], [0; 32][..]); + } - // Note that we could obviously respond immediately with an update_fulfill_htlc - // message, however that would leak that we are the recipient of this payment, so - // instead we stay symmetric with the forwarding case, only responding (after a - // delay) once they've send us a commitment_signed! + // OUR PAYMENT! + // final_expiry_too_soon + // We have to have some headroom to broadcast on chain if we have the preimage, so make sure we have at least + // HTLC_FAIL_BACK_BUFFER blocks to go. + // Also, ensure that, in the case of an unknown payment hash, our payment logic has enough time to fail the HTLC backward + // before our onchain logic triggers a channel closure (see HTLC_FAIL_BACK_BUFFER rational). + if (msg.cltv_expiry as u64) + <= self.latest_block_height.load(Ordering::Acquire) as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 + { + return_err!("The final CLTV expiry is too soon to handle", 17, &[0; 0]); + } + // final_incorrect_htlc_amount + if next_hop_data.amt_to_forward > msg.amount_msat { + return_err!( + "Upstream node sent less than we were supposed to receive in payment", + 19, + &byte_utils::be64_to_array(msg.amount_msat) + ); + } + // final_incorrect_cltv_expiry + if next_hop_data.outgoing_cltv_value != msg.cltv_expiry { + return_err!( + "Upstream node set CLTV to the wrong value", + 18, + &byte_utils::be32_to_array(msg.cltv_expiry) + ); + } - PendingHTLCStatus::Forward(PendingHTLCInfo { - routing: PendingHTLCRouting::Receive { - payment_data, - incoming_cltv_expiry: msg.cltv_expiry, - }, - payment_hash: msg.payment_hash.clone(), - incoming_shared_secret: shared_secret, - amt_to_forward: next_hop_data.amt_to_forward, - outgoing_cltv_value: next_hop_data.outgoing_cltv_value, - }) - } else { - let mut new_packet_data = [0; 20*65]; - let read_pos = chacha_stream.read(&mut new_packet_data).unwrap(); - #[cfg(debug_assertions)] - { - // Check two things: - // a) that the behavior of our stream here will return Ok(0) even if the TLV - // read above emptied out our buffer and the unwrap() wont needlessly panic - // b) that we didn't somehow magically end up with extra data. - let mut t = [0; 1]; - debug_assert!(chacha_stream.read(&mut t).unwrap() == 0); - } - // Once we've emptied the set of bytes our peer gave us, encrypt 0 bytes until we - // fill the onion hop data we'll forward to our next-hop peer. - chacha_stream.chacha.process_in_place(&mut new_packet_data[read_pos..]); - - let mut new_pubkey = msg.onion_routing_packet.public_key.unwrap(); - - let blinding_factor = { - let mut sha = Sha256::engine(); - sha.input(&new_pubkey.serialize()[..]); - sha.input(&shared_secret); - Sha256::from_engine(sha).into_inner() - }; + let payment_data = match next_hop_data.format { + msgs::OnionHopDataFormat::Legacy { .. } => None, + msgs::OnionHopDataFormat::NonFinalNode { .. } => { + return_err!("Got non final data with an HMAC of 0", 0x4000 | 22, &[0; 0]) + } + msgs::OnionHopDataFormat::FinalNode { payment_data } => payment_data, + }; - let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor[..]) { - Err(e) - } else { Ok(new_pubkey) }; + // Note that we could obviously respond immediately with an update_fulfill_htlc + // message, however that would leak that we are the recipient of this payment, so + // instead we stay symmetric with the forwarding case, only responding (after a + // delay) once they've send us a commitment_signed! + + PendingHTLCStatus::Forward(PendingHTLCInfo { + routing: PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry: msg.cltv_expiry }, + payment_hash: msg.payment_hash.clone(), + incoming_shared_secret: shared_secret, + amt_to_forward: next_hop_data.amt_to_forward, + outgoing_cltv_value: next_hop_data.outgoing_cltv_value, + }) + } else { + let mut new_packet_data = [0; 20 * 65]; + let read_pos = chacha_stream.read(&mut new_packet_data).unwrap(); + #[cfg(debug_assertions)] + { + // Check two things: + // a) that the behavior of our stream here will return Ok(0) even if the TLV + // read above emptied out our buffer and the unwrap() wont needlessly panic + // b) that we didn't somehow magically end up with extra data. + let mut t = [0; 1]; + debug_assert!(chacha_stream.read(&mut t).unwrap() == 0); + } + // Once we've emptied the set of bytes our peer gave us, encrypt 0 bytes until we + // fill the onion hop data we'll forward to our next-hop peer. + chacha_stream.chacha.process_in_place(&mut new_packet_data[read_pos..]); - let outgoing_packet = msgs::OnionPacket { - version: 0, - public_key, - hop_data: new_packet_data, - hmac: next_hop_hmac.clone(), - }; + let mut new_pubkey = msg.onion_routing_packet.public_key.unwrap(); - let short_channel_id = match next_hop_data.format { - msgs::OnionHopDataFormat::Legacy { short_channel_id } => short_channel_id, - msgs::OnionHopDataFormat::NonFinalNode { short_channel_id } => short_channel_id, - msgs::OnionHopDataFormat::FinalNode { .. } => { - return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0;0]); - }, - }; + let blinding_factor = { + let mut sha = Sha256::engine(); + sha.input(&new_pubkey.serialize()[..]); + sha.input(&shared_secret); + Sha256::from_engine(sha).into_inner() + }; - PendingHTLCStatus::Forward(PendingHTLCInfo { - routing: PendingHTLCRouting::Forward { - onion_packet: outgoing_packet, - short_channel_id: short_channel_id, - }, - payment_hash: msg.payment_hash.clone(), - incoming_shared_secret: shared_secret, - amt_to_forward: next_hop_data.amt_to_forward, - outgoing_cltv_value: next_hop_data.outgoing_cltv_value, - }) + let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor[..]) { + Err(e) + } else { + Ok(new_pubkey) + }; + + let outgoing_packet = + msgs::OnionPacket { version: 0, public_key, hop_data: new_packet_data, hmac: next_hop_hmac.clone() }; + + let short_channel_id = match next_hop_data.format { + msgs::OnionHopDataFormat::Legacy { short_channel_id } => short_channel_id, + msgs::OnionHopDataFormat::NonFinalNode { short_channel_id } => short_channel_id, + msgs::OnionHopDataFormat::FinalNode { .. } => { + return_err!( + "Final Node OnionHopData provided for us as an intermediary node", + 0x4000 | 22, + &[0; 0] + ); + } }; + PendingHTLCStatus::Forward(PendingHTLCInfo { + routing: PendingHTLCRouting::Forward { onion_packet: outgoing_packet, short_channel_id }, + payment_hash: msg.payment_hash.clone(), + incoming_shared_secret: shared_secret, + amt_to_forward: next_hop_data.amt_to_forward, + outgoing_cltv_value: next_hop_data.outgoing_cltv_value, + }) + }; + channel_state = Some(self.channel_state.lock().unwrap()); - if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref routing, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info { + if let &PendingHTLCStatus::Forward(PendingHTLCInfo { + ref routing, + ref amt_to_forward, + ref outgoing_cltv_value, + .. + }) = &pending_forward_info + { // If short_channel_id is 0 here, we'll reject the HTLC as there cannot be a channel // with a short_channel_id of 0. This is important as various things later assume // short_channel_id is non-0 in any ::Forward. if let &PendingHTLCRouting::Forward { ref short_channel_id, .. } = routing { let id_option = channel_state.as_ref().unwrap().short_to_id.get(&short_channel_id).cloned(); let forwarding_id = match id_option { - None => { // unknown_next_peer - return_err!("Don't have available channel for forwarding as requested.", 0x4000 | 10, &[0;0]); - }, + None => { + // unknown_next_peer + return_err!("Don't have available channel for forwarding as requested.", 0x4000 | 10, &[0; 0]); + } Some(id) => id.clone(), }; if let Some((err, code, chan_update)) = loop { @@ -1154,46 +1196,76 @@ impl ChannelMan // around to doing the actual forward, but better to fail early if we can and // hopefully an attacker trying to path-trace payments cannot make this occur // on a small/per-node/per-channel scale. - if !chan.is_live() { // channel_disabled - break Some(("Forwarding channel is not in a ready state.", 0x1000 | 20, Some(self.get_channel_update(chan).unwrap()))); + if !chan.is_live() { + // channel_disabled + break Some(( + "Forwarding channel is not in a ready state.", + 0x1000 | 20, + Some(self.get_channel_update(chan).unwrap()), + )); } - if *amt_to_forward < chan.get_their_htlc_minimum_msat() { // amount_below_minimum - break Some(("HTLC amount was below the htlc_minimum_msat", 0x1000 | 11, Some(self.get_channel_update(chan).unwrap()))); + if *amt_to_forward < chan.get_their_htlc_minimum_msat() { + // amount_below_minimum + break Some(( + "HTLC amount was below the htlc_minimum_msat", + 0x1000 | 11, + Some(self.get_channel_update(chan).unwrap()), + )); } - let fee = amt_to_forward.checked_mul(chan.get_fee_proportional_millionths() as u64).and_then(|prop_fee| { (prop_fee / 1000000).checked_add(chan.get_our_fee_base_msat(&self.fee_estimator) as u64) }); - if fee.is_none() || msg.amount_msat < fee.unwrap() || (msg.amount_msat - fee.unwrap()) < *amt_to_forward { // fee_insufficient - break Some(("Prior hop has deviated from specified fees parameters or origin node has obsolete ones", 0x1000 | 12, Some(self.get_channel_update(chan).unwrap()))); + let fee = amt_to_forward.checked_mul(chan.get_fee_proportional_millionths() as u64).and_then( + |prop_fee| { + (prop_fee / 1000000).checked_add(chan.get_our_fee_base_msat(&self.fee_estimator) as u64) + }, + ); + if fee.is_none() + || msg.amount_msat < fee.unwrap() + || (msg.amount_msat - fee.unwrap()) < *amt_to_forward + { + // fee_insufficient + break Some(( + "Prior hop has deviated from specified fees parameters or origin node has obsolete ones", + 0x1000 | 12, + Some(self.get_channel_update(chan).unwrap()), + )); } - if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + CLTV_EXPIRY_DELTA as u64 { // incorrect_cltv_expiry + if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + CLTV_EXPIRY_DELTA as u64 { + // incorrect_cltv_expiry break Some(("Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta", 0x1000 | 13, Some(self.get_channel_update(chan).unwrap()))); } let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1; // Theoretically, channel counterparty shouldn't send us a HTLC expiring now, but we want to be robust wrt to counterparty // packet sanitization (see HTLC_FAIL_BACK_BUFFER rational) - if msg.cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { // expiry_too_soon - break Some(("CLTV expiry is too close", 0x1000 | 14, Some(self.get_channel_update(chan).unwrap()))); + if msg.cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { + // expiry_too_soon + break Some(( + "CLTV expiry is too close", + 0x1000 | 14, + Some(self.get_channel_update(chan).unwrap()), + )); } - if msg.cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { // expiry_too_far + if msg.cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { + // expiry_too_far break Some(("CLTV expiry is too far in the future", 21, None)); } // In theory, we would be safe against unitentional channel-closure, if we only required a margin of LATENCY_GRACE_PERIOD_BLOCKS. // But, to be safe against policy reception, we use a longuer delay. if (*outgoing_cltv_value) as u64 <= (cur_height + HTLC_FAIL_BACK_BUFFER) as u64 { - break Some(("Outgoing CLTV value is too soon", 0x1000 | 14, Some(self.get_channel_update(chan).unwrap()))); + break Some(( + "Outgoing CLTV value is too soon", + 0x1000 | 14, + Some(self.get_channel_update(chan).unwrap()), + )); } break None; - } - { + } { let mut res = Vec::with_capacity(8 + 128); if let Some(chan_update) = chan_update { if code == 0x1000 | 11 || code == 0x1000 | 12 { res.extend_from_slice(&byte_utils::be64_to_array(msg.amount_msat)); - } - else if code == 0x1000 | 13 { + } else if code == 0x1000 | 13 { res.extend_from_slice(&byte_utils::be32_to_array(msg.cltv_expiry)); - } - else if code == 0x1000 | 20 { + } else if code == 0x1000 | 20 { res.extend_from_slice(&byte_utils::be16_to_array(chan_update.contents.flags)); } res.extend_from_slice(&chan_update.encode_with_len()[..]); @@ -1210,15 +1282,21 @@ impl ChannelMan /// May be called with channel_state already locked! fn get_channel_update(&self, chan: &Channel) -> Result { let short_channel_id = match chan.get_short_channel_id() { - None => return Err(LightningError{err: "Channel not yet established", action: msgs::ErrorAction::IgnoreError}), + None => { + return Err(LightningError { + err: "Channel not yet established", + action: msgs::ErrorAction::IgnoreError, + }) + } Some(id) => id, }; - let were_node_one = PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key).serialize()[..] < chan.get_their_node_id().serialize()[..]; + let were_node_one = PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key).serialize()[..] + < chan.get_their_node_id().serialize()[..]; let unsigned = msgs::UnsignedChannelUpdate { chain_hash: self.genesis_hash, - short_channel_id: short_channel_id, + short_channel_id, timestamp: chan.get_update_time_counter(), flags: (!were_node_one) as u16 | ((!chan.is_live() as u16) << 1), cltv_expiry_delta: CLTV_EXPIRY_DELTA, @@ -1231,22 +1309,27 @@ impl ChannelMan let msg_hash = Sha256dHash::hash(&unsigned.encode()[..]); let sig = self.secp_ctx.sign(&hash_to_message!(&msg_hash[..]), &self.our_network_key); - Ok(msgs::ChannelUpdate { - signature: sig, - contents: unsigned - }) + Ok(msgs::ChannelUpdate { signature: sig, contents: unsigned }) } // Only public for testing, this should otherwise never be called direcly - pub(crate) fn send_payment_along_path(&self, path: &Vec, payment_hash: &PaymentHash, payment_secret: &Option, total_value: u64, cur_height: u32) -> Result<(), APIError> { - log_trace!(self, "Attempting to send payment for path with next hop {}", path.first().unwrap().short_channel_id); + pub(crate) fn send_payment_along_path( + &self, path: &Vec, payment_hash: &PaymentHash, payment_secret: &Option, + total_value: u64, cur_height: u32, + ) -> Result<(), APIError> { + log_trace!( + self, + "Attempting to send payment for path with next hop {}", + path.first().unwrap().short_channel_id + ); let (session_priv, prng_seed) = self.keys_manager.get_onion_rand(); let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &session_priv) - .map_err(|_| APIError::RouteError{err: "Pubkey along hop was maliciously selected"})?; - let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(path, total_value, payment_secret, cur_height)?; + .map_err(|_| APIError::RouteError { err: "Pubkey along hop was maliciously selected" })?; + let (onion_payloads, htlc_msat, htlc_cltv) = + onion_utils::build_onion_payloads(path, total_value, payment_secret, cur_height)?; if onion_utils::route_size_insane(&onion_payloads) { - return Err(APIError::RouteError{err: "Route size too large considering onion data"}); + return Err(APIError::RouteError { err: "Route size too large considering onion data" }); } let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash); @@ -1255,7 +1338,7 @@ impl ChannelMan let err: Result<(), _> = loop { let mut channel_lock = self.channel_state.lock().unwrap(); let id = match channel_lock.short_to_id.get(&path.first().unwrap().short_channel_id) { - None => return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!"}), + None => return Err(APIError::ChannelUnavailable { err: "No channel available with first hop!" }), Some(id) => id.clone(), }; @@ -1263,20 +1346,43 @@ impl ChannelMan if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(id) { match { if chan.get().get_their_node_id() != path.first().unwrap().pubkey { - return Err(APIError::RouteError{err: "Node ID mismatch on first hop!"}); + return Err(APIError::RouteError { err: "Node ID mismatch on first hop!" }); } if !chan.get().is_live() { - return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected/pending monitor update!"}); + return Err(APIError::ChannelUnavailable { + err: "Peer for first hop currently disconnected/pending monitor update!", + }); } - break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute { - path: path.clone(), - session_priv: session_priv.clone(), - first_hop_htlc_msat: htlc_msat, - }, onion_packet), channel_state, chan) + break_chan_entry!( + self, + chan.get_mut().send_htlc_and_commit( + htlc_msat, + payment_hash.clone(), + htlc_cltv, + HTLCSource::OutboundRoute { + path: path.clone(), + session_priv: session_priv.clone(), + first_hop_htlc_msat: htlc_msat, + }, + onion_packet + ), + channel_state, + chan + ) } { Some((update_add, commitment_signed, monitor_update)) => { - if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) { - maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true); + if let Err(e) = + self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) + { + maybe_break_monitor_err!( + self, + e, + channel_state, + chan, + RAACommitmentOrder::CommitmentFirst, + false, + true + ); // Note that MonitorUpdateFailed here indicates (per function docs) // that we will resend the commitment update once monitor updating // is restored. Therefore, we must return an error indicating that @@ -1296,18 +1402,18 @@ impl ChannelMan commitment_signed, }, }); - }, - None => {}, + } + None => {} } - } else { unreachable!(); } + } else { + unreachable!(); + } return Ok(()); }; match handle_error!(self, err, path.first().unwrap().pubkey) { Ok(_) => unreachable!(), - Err(e) => { - Err(APIError::ChannelUnavailable { err: e.err }) - }, + Err(e) => Err(APIError::ChannelUnavailable { err: e.err }), } } @@ -1350,27 +1456,35 @@ impl ChannelMan /// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature /// bit set (either as required or as available). If multiple paths are present in the Route, /// we assume the invoice had the basic_mpp feature set. - pub fn send_payment(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option) -> Result<(), PaymentSendFailure> { + pub fn send_payment( + &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option, + ) -> Result<(), PaymentSendFailure> { if route.paths.len() < 1 { - return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "There must be at least one path to send over"})); + return Err(PaymentSendFailure::ParameterError(APIError::RouteError { + err: "There must be at least one path to send over", + })); } if route.paths.len() > 10 { // This limit is completely arbitrary - there aren't any real fundamental path-count // limits. After we support retrying individual paths we should likely bump this, but // for now more than 10 paths likely carries too much one-path failure. - return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "Sending over more than 10 paths is not currently supported"})); + return Err(PaymentSendFailure::ParameterError(APIError::RouteError { + err: "Sending over more than 10 paths is not currently supported", + })); } let mut total_value = 0; let our_node_id = self.get_our_node_id(); let mut path_errs = Vec::with_capacity(route.paths.len()); 'path_check: for path in route.paths.iter() { if path.len() < 1 || path.len() > 20 { - path_errs.push(Err(APIError::RouteError{err: "Path didn't go anywhere/had bogus size"})); + path_errs.push(Err(APIError::RouteError { err: "Path didn't go anywhere/had bogus size" })); continue 'path_check; } for (idx, hop) in path.iter().enumerate() { if idx != path.len() - 1 && hop.pubkey == our_node_id { - path_errs.push(Err(APIError::RouteError{err: "Path went through us but wasn't a simple rebalance loop to us"})); + path_errs.push(Err(APIError::RouteError { + err: "Path went through us but wasn't a simple rebalance loop to us", + })); continue 'path_check; } } @@ -1389,8 +1503,12 @@ impl ChannelMan let mut has_ok = false; let mut has_err = false; for res in results.iter() { - if res.is_ok() { has_ok = true; } - if res.is_err() { has_err = true; } + if res.is_ok() { + has_ok = true; + } + if res.is_err() { + has_err = true; + } if let &Err(APIError::MonitorUpdateFailed) = res { // MonitorUpdateFailed is inherently unsafe to retry, so we call it a // PartialFailure. @@ -1422,32 +1540,39 @@ impl ChannelMan let (chan, msg) = { let (res, chan) = match self.channel_state.lock().unwrap().by_id.remove(temporary_channel_id) { - Some(mut chan) => { - (chan.get_outbound_funding_created(funding_txo) - .map_err(|e| if let ChannelError::Close(msg) = e { - MsgHandleErrInternal::from_finish_shutdown(msg, chan.channel_id(), chan.force_shutdown(true), None) - } else { unreachable!(); }) - , chan) - }, - None => return + Some(mut chan) => ( + chan.get_outbound_funding_created(funding_txo).map_err(|e| { + if let ChannelError::Close(msg) = e { + MsgHandleErrInternal::from_finish_shutdown( + msg, + chan.channel_id(), + chan.force_shutdown(true), + None, + ) + } else { + unreachable!(); + } + }), + chan, + ), + None => return, }; match handle_error!(self, res, chan.get_their_node_id()) { - Ok(funding_msg) => { - (chan, funding_msg) - }, - Err(_) => { return; } + Ok(funding_msg) => (chan, funding_msg), + Err(_) => { + return; + } } }; let mut channel_state = self.channel_state.lock().unwrap(); - channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated { - node_id: chan.get_their_node_id(), - msg: msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendFundingCreated { node_id: chan.get_their_node_id(), msg }); match channel_state.by_id.entry(chan.channel_id()) { hash_map::Entry::Occupied(_) => { panic!("Generated duplicate funding txid?"); - }, + } hash_map::Entry::Vacant(e) => { e.insert(chan); } @@ -1456,14 +1581,19 @@ impl ChannelMan fn get_announcement_sigs(&self, chan: &Channel) -> Option { if !chan.should_announce() { - log_trace!(self, "Can't send announcement_signatures for private channel {}", log_bytes!(chan.channel_id())); - return None + log_trace!( + self, + "Can't send announcement_signatures for private channel {}", + log_bytes!(chan.channel_id()) + ); + return None; } - let (announcement, our_bitcoin_sig) = match chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone()) { - Ok(res) => res, - Err(_) => return None, // Only in case of state precondition violations eg channel is closing - }; + let (announcement, our_bitcoin_sig) = + match chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone()) { + Ok(res) => res, + Err(_) => return None, // Only in case of state precondition violations eg channel is closing + }; let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]); let our_node_sig = self.secp_ctx.sign(&msghash, &self.our_network_key); @@ -1511,7 +1641,9 @@ impl ChannelMan features: NodeFeatures::known(), timestamp: self.last_node_announcement_serial.fetch_add(1, Ordering::AcqRel) as u32, node_id: self.get_our_node_id(), - rgb, alias, addresses, + rgb, + alias, + addresses, excess_address_data: Vec::new(), excess_data: Vec::new(), }; @@ -1521,7 +1653,7 @@ impl ChannelMan channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastNodeAnnouncement { msg: msgs::NodeAnnouncement { signature: self.secp_ctx.sign(&msghash, &self.our_network_key), - contents: announcement + contents: announcement, }, }); } @@ -1554,10 +1686,12 @@ impl ChannelMan htlc_id: prev_htlc_id, incoming_packet_shared_secret: forward_info.incoming_shared_secret, }); - failed_forwards.push((htlc_source, forward_info.payment_hash, - HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() } + failed_forwards.push(( + htlc_source, + forward_info.payment_hash, + HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() }, )); - }, + } HTLCForwardInfo::FailHTLC { .. } => { // Channel went away before we could fail it. This implies // the channel is now on chain and our counterparty is @@ -1574,32 +1708,58 @@ impl ChannelMan let mut fail_htlc_msgs = Vec::new(); for forward_info in pending_forwards.drain(..) { match forward_info { - HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo { - routing: PendingHTLCRouting::Forward { - onion_packet, .. - }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value }, } => { + HTLCForwardInfo::AddHTLC { + prev_short_channel_id, + prev_htlc_id, + forward_info: + PendingHTLCInfo { + routing: PendingHTLCRouting::Forward { onion_packet, .. }, + incoming_shared_secret, + payment_hash, + amt_to_forward, + outgoing_cltv_value, + }, + } => { log_trace!(self, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(payment_hash.0), prev_short_channel_id, short_chan_id); let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: prev_short_channel_id, htlc_id: prev_htlc_id, incoming_packet_shared_secret: incoming_shared_secret, }); - match chan.get_mut().send_htlc(amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet) { + match chan.get_mut().send_htlc( + amt_to_forward, + payment_hash, + outgoing_cltv_value, + htlc_source.clone(), + onion_packet, + ) { Err(e) => { if let ChannelError::Ignore(msg) = e { - log_trace!(self, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(payment_hash.0), msg); + log_trace!( + self, + "Failed to forward HTLC with payment_hash {}: {}", + log_bytes!(payment_hash.0), + msg + ); } else { panic!("Stated return value requirements in send_htlc() were not met"); } let chan_update = self.get_channel_update(chan.get()).unwrap(); - failed_forwards.push((htlc_source, payment_hash, - HTLCFailReason::Reason { failure_code: 0x1000 | 7, data: chan_update.encode_with_len() } + failed_forwards.push(( + htlc_source, + payment_hash, + HTLCFailReason::Reason { + failure_code: 0x1000 | 7, + data: chan_update.encode_with_len(), + }, )); continue; - }, + } Ok(update_add) => { match update_add { - Some(msg) => { add_htlc_msgs.push(msg); }, + Some(msg) => { + add_htlc_msgs.push(msg); + } None => { // Nothing to do here...we're waiting on a remote // revoke_and_ack before we can add anymore HTLCs. The Channel @@ -1612,16 +1772,25 @@ impl ChannelMan } } } - }, + } HTLCForwardInfo::AddHTLC { .. } => { panic!("short_channel_id != 0 should imply any pending_forward entries are of type Forward"); - }, + } HTLCForwardInfo::FailHTLC { htlc_id, err_packet } => { - log_trace!(self, "Failing HTLC back to channel with short id {} after delay", short_chan_id); + log_trace!( + self, + "Failing HTLC back to channel with short id {} after delay", + short_chan_id + ); match chan.get_mut().get_update_fail_htlc(htlc_id, err_packet) { Err(e) => { if let ChannelError::Ignore(msg) = e { - log_trace!(self, "Failed to fail backwards to short_id {}: {}", short_chan_id, msg); + log_trace!( + self, + "Failed to fail backwards to short_id {}: {}", + short_chan_id, + msg + ); } else { panic!("Stated return value requirements in get_update_fail_htlc() were not met"); } @@ -1629,8 +1798,10 @@ impl ChannelMan // pending, and if not that's OK, if not, the channel is on // the chain and sending the HTLC-Timeout is their problem. continue; - }, - Ok(Some(msg)) => { fail_htlc_msgs.push(msg); }, + } + Ok(Some(msg)) => { + fail_htlc_msgs.push(msg); + } Ok(None) => { // Nothing to do here...we're waiting on a remote // revoke_and_ack before we can update the commitment @@ -1642,7 +1813,7 @@ impl ChannelMan // update_fail_htlc in time, it's not our problem. } } - }, + } } } @@ -1653,26 +1824,53 @@ impl ChannelMan // We surely failed send_commitment due to bad keys, in that case // close channel and then send error message to peer. let their_node_id = chan.get().get_their_node_id(); - let err: Result<(), _> = match e { + let err: Result<(), _> = match e { ChannelError::Ignore(_) => { - panic!("Stated return value requirements in send_commitment() were not met"); - }, + panic!( + "Stated return value requirements in send_commitment() were not met" + ); + } ChannelError::Close(msg) => { - log_trace!(self, "Closing channel {} due to Close-required error: {}", log_bytes!(chan.key()[..]), msg); + log_trace!( + self, + "Closing channel {} due to Close-required error: {}", + log_bytes!(chan.key()[..]), + msg + ); let (channel_id, mut channel) = chan.remove_entry(); if let Some(short_id) = channel.get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } - Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, channel.force_shutdown(true), self.get_channel_update(&channel).ok())) - }, - ChannelError::CloseDelayBroadcast { .. } => { panic!("Wait is only generated on receipt of channel_reestablish, which is handled by try_chan_entry, we don't bother to support it here"); } + Err(MsgHandleErrInternal::from_finish_shutdown( + msg, + channel_id, + channel.force_shutdown(true), + self.get_channel_update(&channel).ok(), + )) + } + ChannelError::CloseDelayBroadcast { .. } => { + panic!("Wait is only generated on receipt of channel_reestablish, which is handled by try_chan_entry, we don't bother to support it here"); + } }; handle_errors.push((their_node_id, err)); continue; } }; - if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) { - handle_errors.push((chan.get().get_their_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true))); + if let Err(e) = + self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) + { + handle_errors.push(( + chan.get().get_their_node_id(), + handle_monitor_err!( + self, + e, + channel_state, + chan, + RAACommitmentOrder::CommitmentFirst, + false, + true + ), + )); continue; } channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { @@ -1693,9 +1891,18 @@ impl ChannelMan } else { for forward_info in pending_forwards.drain(..) { match forward_info { - HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo { - routing: PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry }, - incoming_shared_secret, payment_hash, amt_to_forward, .. }, } => { + HTLCForwardInfo::AddHTLC { + prev_short_channel_id, + prev_htlc_id, + forward_info: + PendingHTLCInfo { + routing: PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry }, + incoming_shared_secret, + payment_hash, + amt_to_forward, + .. + }, + } => { let prev_hop = HTLCPreviousHopData { short_channel_id: prev_short_channel_id, htlc_id: prev_htlc_id, @@ -1703,9 +1910,14 @@ impl ChannelMan }; let mut total_value = 0; - let payment_secret_opt = - if let &Some(ref data) = &payment_data { Some(data.payment_secret.clone()) } else { None }; - let htlcs = channel_state.claimable_htlcs.entry((payment_hash, payment_secret_opt)) + let payment_secret_opt = if let &Some(ref data) = &payment_data { + Some(data.payment_secret.clone()) + } else { + None + }; + let htlcs = channel_state + .claimable_htlcs + .entry((payment_hash, payment_secret_opt)) .or_insert(Vec::new()); htlcs.push(ClaimableHTLC { prev_hop, @@ -1719,43 +1931,50 @@ impl ChannelMan if htlc.payment_data.as_ref().unwrap().total_msat != data.total_msat { total_value = msgs::MAX_VALUE_MSAT; } - if total_value >= msgs::MAX_VALUE_MSAT { break; } + if total_value >= msgs::MAX_VALUE_MSAT { + break; + } } - if total_value >= msgs::MAX_VALUE_MSAT || total_value > data.total_msat { + if total_value >= msgs::MAX_VALUE_MSAT || total_value > data.total_msat { for htlc in htlcs.iter() { - let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec(); - htlc_msat_height_data.extend_from_slice( - &byte_utils::be32_to_array( - self.latest_block_height.load(Ordering::Acquire) - as u32, - ), - ); - failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData { + let mut htlc_msat_height_data = + byte_utils::be64_to_array(htlc.value).to_vec(); + htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array( + self.latest_block_height.load(Ordering::Acquire) as u32, + )); + failed_forwards.push(( + HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: htlc.prev_hop.short_channel_id, htlc_id: htlc.prev_hop.htlc_id, - incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret, - }), payment_hash, - HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data } + incoming_packet_shared_secret: htlc + .prev_hop + .incoming_packet_shared_secret, + }), + payment_hash, + HTLCFailReason::Reason { + failure_code: 0x4000 | 15, + data: htlc_msat_height_data, + }, )); } } else if total_value == data.total_msat { new_events.push(events::Event::PaymentReceived { - payment_hash: payment_hash, + payment_hash, payment_secret: Some(data.payment_secret), amt: total_value, }); } } else { new_events.push(events::Event::PaymentReceived { - payment_hash: payment_hash, + payment_hash, payment_secret: None, amt: amt_to_forward, }); } - }, + } HTLCForwardInfo::AddHTLC { .. } => { panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive"); - }, + } HTLCForwardInfo::FailHTLC { .. } => { panic!("Got pending fail of our own HTLC"); } @@ -1766,14 +1985,21 @@ impl ChannelMan } for (htlc_source, payment_hash, failure_reason) in failed_forwards.drain(..) { - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source, &payment_hash, failure_reason); + self.fail_htlc_backwards_internal( + self.channel_state.lock().unwrap(), + htlc_source, + &payment_hash, + failure_reason, + ); } for (their_node_id, err) in handle_errors.drain(..) { let _ = handle_error!(self, err, their_node_id); } - if new_events.is_empty() { return } + if new_events.is_empty() { + return; + } let mut events = self.pending_events.lock().unwrap(); events.append(&mut new_events); } @@ -1790,9 +2016,9 @@ impl ChannelMan for (_, chan) in channel_state.by_id.iter_mut() { if chan.is_disabled_staged() && !chan.is_live() { if let Ok(update) = self.get_channel_update(&chan) { - channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { - msg: update - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } chan.to_fresh(); } else if chan.is_disabled_staged() && chan.is_live() { @@ -1815,17 +2041,24 @@ impl ChannelMan let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(*payment_hash, *payment_secret)); if let Some(mut sources) = removed_source { for htlc in sources.drain(..) { - if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); } + if channel_state.is_none() { + channel_state = Some(self.channel_state.lock().unwrap()); + } let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec(); htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array( self.latest_block_height.load(Ordering::Acquire) as u32, )); - self.fail_htlc_backwards_internal(channel_state.take().unwrap(), - HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash, - HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }); + self.fail_htlc_backwards_internal( + channel_state.take().unwrap(), + HTLCSource::PreviousHopData(htlc.prev_hop), + payment_hash, + HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }, + ); } true - } else { false } + } else { + false + } } /// Fails an HTLC backwards to the sender of it to us. @@ -1834,7 +2067,10 @@ impl ChannelMan /// to fail and take the channel_state lock for each iteration (as we take ownership and may /// drop it). In other words, no assumptions are made that entries in claimable_htlcs point to /// still-available channels. - fn fail_htlc_backwards_internal(&self, mut channel_state_lock: MutexGuard>, source: HTLCSource, payment_hash: &PaymentHash, onion_error: HTLCFailReason) { + fn fail_htlc_backwards_internal( + &self, mut channel_state_lock: MutexGuard>, source: HTLCSource, + payment_hash: &PaymentHash, onion_error: HTLCFailReason, + ) { //TODO: There is a timing attack here where if a node fails an HTLC back to us they can //identify whether we sent it or not based on the (I presume) very different runtime //between the branches here. We should make this async and move it into the forward HTLCs @@ -1845,37 +2081,38 @@ impl ChannelMan mem::drop(channel_state_lock); match &onion_error { &HTLCFailReason::LightningError { ref err } => { -#[cfg(test)] - let (channel_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); -#[cfg(not(test))] - let (channel_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); + #[cfg(test)] + let (channel_update, payment_retryable, onion_error_code, onion_error_data) = + onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); + #[cfg(not(test))] + let (channel_update, payment_retryable, _, _) = + onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone()); // TODO: If we decided to blame ourselves (or one of our channels) in // process_onion_failure we should close that channel as it implies our // next-hop is needlessly blaming us! if let Some(update) = channel_update { - self.channel_state.lock().unwrap().pending_msg_events.push( - events::MessageSendEvent::PaymentFailureNetworkUpdate { - update, - } - ); + self.channel_state + .lock() + .unwrap() + .pending_msg_events + .push(events::MessageSendEvent::PaymentFailureNetworkUpdate { update }); } - self.pending_events.lock().unwrap().push( - events::Event::PaymentFailed { - payment_hash: payment_hash.clone(), - rejected_by_dest: !payment_retryable, -#[cfg(test)] - error_code: onion_error_code, -#[cfg(test)] - error_data: onion_error_data - } - ); - }, + self.pending_events.lock().unwrap().push(events::Event::PaymentFailed { + payment_hash: payment_hash.clone(), + rejected_by_dest: !payment_retryable, + #[cfg(test)] + error_code: onion_error_code, + #[cfg(test)] + error_data: onion_error_data, + }); + } &HTLCFailReason::Reason { -#[cfg(test)] - ref failure_code, -#[cfg(test)] - ref data, - .. } => { + #[cfg(test)] + ref failure_code, + #[cfg(test)] + ref data, + .. + } => { // we get a fail_malformed_htlc from the first hop // TODO: We'd like to generate a PaymentFailureNetworkUpdate for temporary // failures here, but that would be insufficient as Router::get_route @@ -1883,28 +2120,41 @@ impl ChannelMan // ChannelDetails. // TODO: For non-temporary failures, we really should be closing the // channel here as we apparently can't relay through them anyway. - self.pending_events.lock().unwrap().push( - events::Event::PaymentFailed { - payment_hash: payment_hash.clone(), - rejected_by_dest: path.len() == 1, -#[cfg(test)] - error_code: Some(*failure_code), -#[cfg(test)] - error_data: Some(data.clone()), - } - ); + self.pending_events.lock().unwrap().push(events::Event::PaymentFailed { + payment_hash: payment_hash.clone(), + rejected_by_dest: path.len() == 1, + #[cfg(test)] + error_code: Some(*failure_code), + #[cfg(test)] + error_data: Some(data.clone()), + }); } } - }, - HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret }) => { + } + HTLCSource::PreviousHopData(HTLCPreviousHopData { + short_channel_id, + htlc_id, + incoming_packet_shared_secret, + }) => { let err_packet = match onion_error { HTLCFailReason::Reason { failure_code, data } => { - log_trace!(self, "Failing HTLC with payment_hash {} backwards from us with code {}", log_bytes!(payment_hash.0), failure_code); - let packet = onion_utils::build_failure_packet(&incoming_packet_shared_secret, failure_code, &data[..]).encode(); + log_trace!( + self, + "Failing HTLC with payment_hash {} backwards from us with code {}", + log_bytes!(payment_hash.0), + failure_code + ); + let packet = + onion_utils::build_failure_packet(&incoming_packet_shared_secret, failure_code, &data[..]) + .encode(); onion_utils::encrypt_failure_packet(&incoming_packet_shared_secret, &packet) - }, + } HTLCFailReason::LightningError { err } => { - log_trace!(self, "Failing HTLC with payment_hash {} backwards with pre-built LightningError", log_bytes!(payment_hash.0)); + log_trace!( + self, + "Failing HTLC with payment_hash {} backwards with pre-built LightningError", + log_bytes!(payment_hash.0) + ); onion_utils::encrypt_failure_packet(&incoming_packet_shared_secret, &err.data) } }; @@ -1916,19 +2166,17 @@ impl ChannelMan match channel_state_lock.forward_htlcs.entry(short_channel_id) { hash_map::Entry::Occupied(mut entry) => { entry.get_mut().push(HTLCForwardInfo::FailHTLC { htlc_id, err_packet }); - }, + } hash_map::Entry::Vacant(entry) => { - entry.insert(vec!(HTLCForwardInfo::FailHTLC { htlc_id, err_packet })); + entry.insert(vec![HTLCForwardInfo::FailHTLC { htlc_id, err_packet }]); } } mem::drop(channel_state_lock); if let Some(time) = forward_event { let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::PendingHTLCsForwardable { - time_forwardable: time - }); + pending_events.push(events::Event::PendingHTLCsForwardable { time_forwardable: time }); } - }, + } } } @@ -1947,7 +2195,9 @@ impl ChannelMan /// set. Thus, for such payments we will claim any payments which do not under-pay. /// /// May panic if called except in response to a PaymentReceived event. - pub fn claim_funds(&self, payment_preimage: PaymentPreimage, payment_secret: &Option, expected_amount: u64) -> bool { + pub fn claim_funds( + &self, payment_preimage: PaymentPreimage, payment_secret: &Option, expected_amount: u64, + ) -> bool { let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner()); let _ = self.total_consistency_lock.read().unwrap(); @@ -1978,7 +2228,9 @@ impl ChannelMan }; for htlc in sources.iter() { - if !is_mpp || !valid_mpp { break; } + if !is_mpp || !valid_mpp { + break; + } if let None = channel_state.as_ref().unwrap().short_to_id.get(&htlc.prev_hop.short_channel_id) { valid_mpp = false; } @@ -1987,29 +2239,44 @@ impl ChannelMan let mut errs = Vec::new(); let mut claimed_any_htlcs = false; for htlc in sources.drain(..) { - if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); } - if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) { + if channel_state.is_none() { + channel_state = Some(self.channel_state.lock().unwrap()); + } + if (is_mpp && !valid_mpp) + || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) + { let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec(); htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array( self.latest_block_height.load(Ordering::Acquire) as u32, )); - self.fail_htlc_backwards_internal(channel_state.take().unwrap(), - HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash, - HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data }); + self.fail_htlc_backwards_internal( + channel_state.take().unwrap(), + HTLCSource::PreviousHopData(htlc.prev_hop), + &payment_hash, + HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }, + ); } else { match self.claim_funds_from_hop(channel_state.as_mut().unwrap(), htlc.prev_hop, payment_preimage) { Err(Some(e)) => { if let msgs::ErrorAction::IgnoreError = e.1.err.action { // We got a temporary failure updating monitor, but will claim the // HTLC when the monitor updating is restored (or on chain). - log_error!(self, "Temporary failure claiming HTLC, treating as success: {}", e.1.err.err); + log_error!( + self, + "Temporary failure claiming HTLC, treating as success: {}", + e.1.err.err + ); claimed_any_htlcs = true; - } else { errs.push(e); } - }, - Err(None) if is_mpp => unreachable!("We already checked for channel existence, we can't fail here!"), + } else { + errs.push(e); + } + } + Err(None) if is_mpp => { + unreachable!("We already checked for channel existence, we can't fail here!") + } Err(None) => { log_warn!(self, "Channel we expected to claim an HTLC from was closed."); - }, + } Ok(()) => claimed_any_htlcs = true, } } @@ -2025,17 +2292,20 @@ impl ChannelMan } claimed_any_htlcs - } else { false } + } else { + false + } } - fn claim_funds_from_hop(&self, channel_state_lock: &mut MutexGuard>, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage) -> Result<(), Option<(PublicKey, MsgHandleErrInternal)>> { + fn claim_funds_from_hop( + &self, channel_state_lock: &mut MutexGuard>, prev_hop: HTLCPreviousHopData, + payment_preimage: PaymentPreimage, + ) -> Result<(), Option<(PublicKey, MsgHandleErrInternal)>> { //TODO: Delay the claimed_funds relaying just like we do outbound relay! let channel_state = &mut **channel_state_lock; let chan_id = match channel_state.short_to_id.get(&prev_hop.short_channel_id) { Some(chan_id) => chan_id.clone(), - None => { - return Err(None) - } + None => return Err(None), }; if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(chan_id) { @@ -2043,11 +2313,25 @@ impl ChannelMan match chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage) { Ok((msgs, monitor_option)) => { if let Some(monitor_update) = monitor_option { - if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) { + if let Err(e) = + self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) + { if was_frozen_for_monitor { assert!(msgs.is_none()); } else { - return Err(Some((chan.get().get_their_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, msgs.is_some()).unwrap_err()))); + return Err(Some(( + chan.get().get_their_node_id(), + handle_monitor_err!( + self, + e, + channel_state, + chan, + RAACommitmentOrder::CommitmentFirst, + false, + msgs.is_some() + ) + .unwrap_err(), + ))); } } } @@ -2061,11 +2345,11 @@ impl ChannelMan update_fail_malformed_htlcs: Vec::new(), update_fee: None, commitment_signed, - } + }, }); } - return Ok(()) - }, + return Ok(()); + } Err(e) => { // TODO: Do something with e? // This should only occur if we are claiming an HTLC at the same time as the @@ -2075,37 +2359,41 @@ impl ChannelMan // about to lose funds) and only if the lock in claim_funds was dropped as a // previous HTLC was failed (thus not for an MPP payment). debug_assert!(false, "This shouldn't be reachable except in absurdly rare cases between monitor updates and HTLC timeouts: {:?}", e); - return Err(None) - }, + return Err(None); + } } - } else { unreachable!(); } + } else { + unreachable!(); + } } - fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard>, source: HTLCSource, payment_preimage: PaymentPreimage) { + fn claim_funds_internal( + &self, mut channel_state_lock: MutexGuard>, source: HTLCSource, + payment_preimage: PaymentPreimage, + ) { match source { HTLCSource::OutboundRoute { .. } => { mem::drop(channel_state_lock); let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::PaymentSent { - payment_preimage - }); - }, + pending_events.push(events::Event::PaymentSent { payment_preimage }); + } HTLCSource::PreviousHopData(hop_data) => { - if let Err((their_node_id, err)) = match self.claim_funds_from_hop(&mut channel_state_lock, hop_data, payment_preimage) { - Ok(()) => Ok(()), - Err(None) => { - // TODO: There is probably a channel monitor somewhere that needs to - // learn the preimage as the channel already hit the chain and that's - // why it's missing. - Ok(()) - }, - Err(Some(res)) => Err(res), - } { + if let Err((their_node_id, err)) = + match self.claim_funds_from_hop(&mut channel_state_lock, hop_data, payment_preimage) { + Ok(()) => Ok(()), + Err(None) => { + // TODO: There is probably a channel monitor somewhere that needs to + // learn the preimage as the channel already hit the chain and that's + // why it's missing. + Ok(()) + } + Err(Some(res)) => Err(res), + } { mem::drop(channel_state_lock); let res: Result<(), _> = Err(err); let _ = handle_error!(self, res, their_node_id); } - }, + } } } @@ -2151,16 +2439,30 @@ impl ChannelMan Some(chan) => chan, None => return, }; - if !channel.is_awaiting_monitor_update() || channel.get_latest_monitor_update_id() != highest_applied_update_id { + if !channel.is_awaiting_monitor_update() + || channel.get_latest_monitor_update_id() != highest_applied_update_id + { return; } - let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel.monitor_updating_restored(); + let ( + raa, + commitment_update, + order, + pending_forwards, + mut pending_failures, + needs_broadcast_safe, + funding_locked, + ) = channel.monitor_updating_restored(); if !pending_forwards.is_empty() { - htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards)); + htlc_forwards.push(( + channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), + pending_forwards, + )); } htlc_failures.append(&mut pending_failures); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! handle_cs { () => { if let Some(update) = commitment_update { pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { @@ -2169,6 +2471,7 @@ impl ChannelMan }); } } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! handle_raa { () => { if let Some(revoke_and_ack) = raa { pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { @@ -2181,11 +2484,11 @@ impl ChannelMan RAACommitmentOrder::CommitmentFirst => { handle_cs!(); handle_raa!(); - }, + } RAACommitmentOrder::RevokeAndACKFirst => { handle_raa!(); handle_cs!(); - }, + } } if needs_broadcast_safe { pending_events.push(events::Event::FundingBroadcastSafe { @@ -2194,10 +2497,8 @@ impl ChannelMan }); } if let Some(msg) = funding_locked { - pending_msg_events.push(events::MessageSendEvent::SendFundingLocked { - node_id: channel.get_their_node_id(), - msg, - }); + pending_msg_events + .push(events::MessageSendEvent::SendFundingLocked { node_id: channel.get_their_node_id(), msg }); if let Some(announcement_sigs) = self.get_announcement_sigs(channel) { pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures { node_id: channel.get_their_node_id(), @@ -2220,17 +2521,36 @@ impl ChannelMan } } - fn internal_open_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> { + fn internal_open_channel( + &self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, + ) -> Result<(), MsgHandleErrInternal> { if msg.chain_hash != self.genesis_hash { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash", msg.temporary_channel_id.clone())); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Unknown genesis block hash", + msg.temporary_channel_id.clone(), + )); } - let channel = Channel::new_from_req(&self.fee_estimator, &self.keys_manager, their_node_id.clone(), their_features, msg, 0, Arc::clone(&self.logger), &self.default_configuration) - .map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id))?; + let channel = Channel::new_from_req( + &self.fee_estimator, + &self.keys_manager, + their_node_id.clone(), + their_features, + msg, + 0, + Arc::clone(&self.logger), + &self.default_configuration, + ) + .map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id))?; let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(channel.channel_id()) { - hash_map::Entry::Occupied(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision!", msg.temporary_channel_id.clone())), + hash_map::Entry::Occupied(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "temporary_channel_id collision!", + msg.temporary_channel_id.clone(), + )) + } hash_map::Entry::Vacant(entry) => { channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel { node_id: their_node_id.clone(), @@ -2242,43 +2562,72 @@ impl ChannelMan Ok(()) } - fn internal_accept_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::AcceptChannel) -> Result<(), MsgHandleErrInternal> { + fn internal_accept_channel( + &self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::AcceptChannel, + ) -> Result<(), MsgHandleErrInternal> { let (value, output_script, user_id) = { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.temporary_channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.temporary_channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.temporary_channel_id, + )); } - try_chan_entry!(self, chan.get_mut().accept_channel(&msg, &self.default_configuration, their_features), channel_state, chan); - (chan.get().get_value_satoshis(), chan.get().get_funding_redeemscript().to_v0_p2wsh(), chan.get().get_user_id()) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.temporary_channel_id)) + try_chan_entry!( + self, + chan.get_mut().accept_channel(&msg, &self.default_configuration, their_features), + channel_state, + chan + ); + ( + chan.get().get_value_satoshis(), + chan.get().get_funding_redeemscript().to_v0_p2wsh(), + chan.get().get_user_id(), + ) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.temporary_channel_id, + )) + } } }; let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(events::Event::FundingGenerationReady { temporary_channel_id: msg.temporary_channel_id, channel_value_satoshis: value, - output_script: output_script, + output_script, user_channel_id: user_id, }); Ok(()) } - fn internal_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> { + fn internal_funding_created( + &self, their_node_id: &PublicKey, msg: &msgs::FundingCreated, + ) -> Result<(), MsgHandleErrInternal> { let ((funding_msg, monitor_update), mut chan) = { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.temporary_channel_id.clone()) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.temporary_channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.temporary_channel_id, + )); } (try_chan_entry!(self, chan.get_mut().funding_created(msg), channel_state, chan), chan.remove()) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.temporary_channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.temporary_channel_id, + )) + } } }; // Because we have exclusive ownership of the channel here we can release the channel_state @@ -2290,23 +2639,31 @@ impl ChannelMan // channel, not the temporary_channel_id. This is compatible with ourselves, but the // spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for // any messages referencing a previously-closed channel anyway. - return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", funding_msg.channel_id, chan.force_shutdown(true), None)); - }, + return Err(MsgHandleErrInternal::from_finish_shutdown( + "ChannelMonitor storage failure", + funding_msg.channel_id, + chan.force_shutdown(true), + None, + )); + } ChannelMonitorUpdateErr::TemporaryFailure => { // There's no problem signing a counterparty's funding transaction if our monitor // hasn't persisted to disk yet - we can't lose money on a transaction that we haven't // accepted payment from yet. We do, however, need to wait to send our funding_locked // until we have persisted our monitor. chan.monitor_update_failed(false, false, Vec::new(), Vec::new()); - }, + } } } let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(funding_msg.channel_id) { hash_map::Entry::Occupied(_) => { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id", funding_msg.channel_id)) - }, + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Already had channel with the new channel_id", + funding_msg.channel_id, + )) + } hash_map::Entry::Vacant(e) => { channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned { node_id: their_node_id.clone(), @@ -2318,46 +2675,70 @@ impl ChannelMan Ok(()) } - fn internal_funding_signed(&self, their_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> { + fn internal_funding_signed( + &self, their_node_id: &PublicKey, msg: &msgs::FundingSigned, + ) -> Result<(), MsgHandleErrInternal> { let (funding_txo, user_id) = { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } let monitor = match chan.get_mut().funding_signed(&msg) { Ok(update) => update, Err(e) => try_chan_entry!(self, Err(e), channel_state, chan), }; if let Err(e) = self.monitor.add_monitor(chan.get().get_funding_txo().unwrap(), monitor) { - return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, false, false); + return_monitor_err!( + self, + e, + channel_state, + chan, + RAACommitmentOrder::RevokeAndACKFirst, + false, + false + ); } (chan.get().get_funding_txo().unwrap(), chan.get().get_user_id()) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } }; let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::FundingBroadcastSafe { - funding_txo: funding_txo, - user_channel_id: user_id, - }); + pending_events.push(events::Event::FundingBroadcastSafe { funding_txo, user_channel_id: user_id }); Ok(()) } - fn internal_funding_locked(&self, their_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result<(), MsgHandleErrInternal> { + fn internal_funding_locked( + &self, their_node_id: &PublicKey, msg: &msgs::FundingLocked, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } try_chan_entry!(self, chan.get_mut().funding_locked(&msg), channel_state, chan); if let Some(announcement_sigs) = self.get_announcement_sigs(chan.get()) { - log_trace!(self, "Sending announcement_signatures for {} in response to funding_locked", log_bytes!(chan.get().channel_id())); + log_trace!( + self, + "Sending announcement_signatures for {} in response to funding_locked", + log_bytes!(chan.get().channel_id()) + ); // If we see locking block before receiving remote funding_locked, we broadcast our // announcement_sigs at remote funding_locked reception. If we receive remote // funding_locked before seeing locking block, we broadcast our announcement_sigs at locking @@ -2373,8 +2754,10 @@ impl ChannelMan }); } Ok(()) - }, - hash_map::Entry::Vacant(_) => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } } } @@ -2386,60 +2769,85 @@ impl ChannelMan match channel_state.by_id.entry(msg.channel_id.clone()) { hash_map::Entry::Occupied(mut chan_entry) => { if chan_entry.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } - let (shutdown, closing_signed, dropped_htlcs) = try_chan_entry!(self, chan_entry.get_mut().shutdown(&self.fee_estimator, &msg), channel_state, chan_entry); + let (shutdown, closing_signed, dropped_htlcs) = try_chan_entry!( + self, + chan_entry.get_mut().shutdown(&self.fee_estimator, &msg), + channel_state, + chan_entry + ); if let Some(msg) = shutdown { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { - node_id: their_node_id.clone(), - msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendShutdown { node_id: their_node_id.clone(), msg }); } if let Some(msg) = closing_signed { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned { - node_id: their_node_id.clone(), - msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendClosingSigned { node_id: their_node_id.clone(), msg }); } if chan_entry.get().is_shutdown() { if let Some(short_id) = chan_entry.get().get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } (dropped_htlcs, Some(chan_entry.remove_entry().1)) - } else { (dropped_htlcs, None) } - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } else { + (dropped_htlcs, None) + } + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } }; for htlc_source in dropped_htlcs.drain(..) { - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + self.fail_htlc_backwards_internal( + self.channel_state.lock().unwrap(), + htlc_source.0, + &htlc_source.1, + HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, + ); } if let Some(chan) = chan_option { if let Ok(update) = self.get_channel_update(&chan) { let mut channel_state = self.channel_state.lock().unwrap(); - channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { - msg: update - }); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } } Ok(()) } - fn internal_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result<(), MsgHandleErrInternal> { + fn internal_closing_signed( + &self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned, + ) -> Result<(), MsgHandleErrInternal> { let (tx, chan_option) = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id.clone()) { hash_map::Entry::Occupied(mut chan_entry) => { if chan_entry.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } - let (closing_signed, tx) = try_chan_entry!(self, chan_entry.get_mut().closing_signed(&self.fee_estimator, &msg), channel_state, chan_entry); + let (closing_signed, tx) = try_chan_entry!( + self, + chan_entry.get_mut().closing_signed(&self.fee_estimator, &msg), + channel_state, + chan_entry + ); if let Some(msg) = closing_signed { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned { - node_id: their_node_id.clone(), - msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendClosingSigned { node_id: their_node_id.clone(), msg }); } if tx.is_some() { // We're done with this channel, we've got a signed closing transaction and @@ -2451,9 +2859,16 @@ impl ChannelMan channel_state.short_to_id.remove(&short_id); } (tx, Some(chan_entry.remove_entry().1)) - } else { (tx, None) } - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } else { + (tx, None) + } + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } }; if let Some(broadcast_tx) = tx { @@ -2463,15 +2878,15 @@ impl ChannelMan if let Some(chan) = chan_option { if let Ok(update) = self.get_channel_update(&chan) { let mut channel_state = self.channel_state.lock().unwrap(); - channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { - msg: update - }); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } } Ok(()) } - fn internal_update_add_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC) -> Result<(), MsgHandleErrInternal> { + fn internal_update_add_htlc( + &self, their_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC, + ) -> Result<(), MsgHandleErrInternal> { //TODO: BOLT 4 points out a specific attack where a peer may re-send an onion packet and //determine the state of the payment based on our response/if we forward anything/the time //we take to respond. We should take care to avoid allowing such an attack. @@ -2487,13 +2902,18 @@ impl ChannelMan match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } if !chan.get().is_usable() { // If the update_add is completely bogus, the call will Err and we will close, // but if we've sent a shutdown and they haven't acknowledged it yet, we just // want to reject the new HTLC and fail it backwards instead of forwarding. - if let PendingHTLCStatus::Forward(PendingHTLCInfo { incoming_shared_secret, .. }) = pending_forward_info { + if let PendingHTLCStatus::Forward(PendingHTLCInfo { incoming_shared_secret, .. }) = + pending_forward_info + { let chan_update = self.get_channel_update(chan.get()); pending_forward_info = PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { channel_id: msg.channel_id, @@ -2504,103 +2924,169 @@ impl ChannelMan // that we can't return |20 for an inbound channel being disabled. // This probably needs a spec update but should definitely be // allowed. - onion_utils::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &{ - let mut res = Vec::with_capacity(8 + 128); - res.extend_from_slice(&byte_utils::be16_to_array(update.contents.flags)); - res.extend_from_slice(&update.encode_with_len()[..]); - res - }[..]) + onion_utils::build_first_hop_failure_packet( + &incoming_shared_secret, + 0x1000 | 20, + &{ + let mut res = Vec::with_capacity(8 + 128); + res.extend_from_slice(&byte_utils::be16_to_array(update.contents.flags)); + res.extend_from_slice(&update.encode_with_len()[..]); + res + }[..], + ) } else { // This can only happen if the channel isn't in the fully-funded // state yet, implying our counterparty is trying to route payments // over the channel back to themselves (cause no one else should // know the short_id is a lightning channel yet). We should have no // problem just calling this unknown_next_peer - onion_utils::build_first_hop_failure_packet(&incoming_shared_secret, 0x4000|10, &[]) + onion_utils::build_first_hop_failure_packet(&incoming_shared_secret, 0x4000 | 10, &[]) }, })); } } try_chan_entry!(self, chan.get_mut().update_add_htlc(&msg, pending_forward_info), channel_state, chan); - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } Ok(()) } - fn internal_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) -> Result<(), MsgHandleErrInternal> { + fn internal_update_fulfill_htlc( + &self, their_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_lock = self.channel_state.lock().unwrap(); let htlc_source = { let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } try_chan_entry!(self, chan.get_mut().update_fulfill_htlc(&msg), channel_state, chan) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } }; self.claim_funds_internal(channel_lock, htlc_source, msg.payment_preimage.clone()); Ok(()) } - fn internal_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), MsgHandleErrInternal> { + fn internal_update_fail_htlc( + &self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } - try_chan_entry!(self, chan.get_mut().update_fail_htlc(&msg, HTLCFailReason::LightningError { err: msg.reason.clone() }), channel_state, chan); - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + try_chan_entry!( + self, + chan.get_mut().update_fail_htlc(&msg, HTLCFailReason::LightningError { err: msg.reason.clone() }), + channel_state, + chan + ); + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } Ok(()) } - fn internal_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), MsgHandleErrInternal> { + fn internal_update_fail_malformed_htlc( + &self, their_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } if (msg.failure_code & 0x8000) == 0 { - let chan_err: ChannelError = ChannelError::Close("Got update_fail_malformed_htlc with BADONION not set"); + let chan_err: ChannelError = + ChannelError::Close("Got update_fail_malformed_htlc with BADONION not set"); try_chan_entry!(self, Err(chan_err), channel_state, chan); } - try_chan_entry!(self, chan.get_mut().update_fail_malformed_htlc(&msg, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() }), channel_state, chan); + try_chan_entry!( + self, + chan.get_mut().update_fail_malformed_htlc( + &msg, + HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() } + ), + channel_state, + chan + ); Ok(()) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } } - fn internal_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(), MsgHandleErrInternal> { + fn internal_commitment_signed( + &self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } let (revoke_and_ack, commitment_signed, closing_signed, monitor_update) = - match chan.get_mut().commitment_signed(&msg, &self.fee_estimator) { - Err((None, e)) => try_chan_entry!(self, Err(e), channel_state, chan), - Err((Some(update), e)) => { - assert!(chan.get().is_awaiting_monitor_update()); - let _ = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), update); - try_chan_entry!(self, Err(e), channel_state, chan); - unreachable!(); - }, - Ok(res) => res - }; + match chan.get_mut().commitment_signed(&msg, &self.fee_estimator) { + Err((None, e)) => try_chan_entry!(self, Err(e), channel_state, chan), + Err((Some(update), e)) => { + assert!(chan.get().is_awaiting_monitor_update()); + let _ = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), update); + try_chan_entry!(self, Err(e), channel_state, chan); + unreachable!(); + } + Ok(res) => res, + }; if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) { - return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, true, commitment_signed.is_some()); + return_monitor_err!( + self, + e, + channel_state, + chan, + RAACommitmentOrder::RevokeAndACKFirst, + true, + commitment_signed.is_some() + ); //TODO: Rebroadcast closing_signed if present on monitor update restoration } channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { @@ -2621,14 +3107,18 @@ impl ChannelMan }); } if let Some(msg) = closing_signed { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned { - node_id: their_node_id.clone(), - msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendClosingSigned { node_id: their_node_id.clone(), msg }); } Ok(()) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } } @@ -2643,14 +3133,22 @@ impl ChannelMan } for (forward_info, prev_htlc_id) in pending_forwards.drain(..) { match channel_state.forward_htlcs.entry(match forward_info.routing { - PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id, - PendingHTLCRouting::Receive { .. } => 0, + PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id, + PendingHTLCRouting::Receive { .. } => 0, }) { hash_map::Entry::Occupied(mut entry) => { - entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info }); - }, + entry.get_mut().push(HTLCForwardInfo::AddHTLC { + prev_short_channel_id, + prev_htlc_id, + forward_info, + }); + } hash_map::Entry::Vacant(entry) => { - entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info })); + entry.insert(vec![HTLCForwardInfo::AddHTLC { + prev_short_channel_id, + prev_htlc_id, + forward_info, + }]); } } } @@ -2658,50 +3156,82 @@ impl ChannelMan match forward_event { Some(time) => { let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::PendingHTLCsForwardable { - time_forwardable: time - }); + pending_events.push(events::Event::PendingHTLCsForwardable { time_forwardable: time }); } - None => {}, + None => {} } } } - fn internal_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result<(), MsgHandleErrInternal> { + fn internal_revoke_and_ack( + &self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK, + ) -> Result<(), MsgHandleErrInternal> { let (pending_forwards, mut pending_failures, short_channel_id) = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update(); - let (commitment_update, pending_forwards, pending_failures, closing_signed, monitor_update) = - try_chan_entry!(self, chan.get_mut().revoke_and_ack(&msg, &self.fee_estimator), channel_state, chan); + let (commitment_update, pending_forwards, pending_failures, closing_signed, monitor_update) = try_chan_entry!( + self, + chan.get_mut().revoke_and_ack(&msg, &self.fee_estimator), + channel_state, + chan + ); if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) { if was_frozen_for_monitor { - assert!(commitment_update.is_none() && closing_signed.is_none() && pending_forwards.is_empty() && pending_failures.is_empty()); - return Err(MsgHandleErrInternal::ignore_no_close("Previous monitor update failure prevented responses to RAA")); + assert!( + commitment_update.is_none() + && closing_signed.is_none() && pending_forwards.is_empty() + && pending_failures.is_empty() + ); + return Err(MsgHandleErrInternal::ignore_no_close( + "Previous monitor update failure prevented responses to RAA", + )); } else { - return_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, commitment_update.is_some(), pending_forwards, pending_failures); + return_monitor_err!( + self, + e, + channel_state, + chan, + RAACommitmentOrder::CommitmentFirst, + false, + commitment_update.is_some(), + pending_forwards, + pending_failures + ); } } if let Some(updates) = commitment_update { - channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { - node_id: their_node_id.clone(), - updates, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::UpdateHTLCs { node_id: their_node_id.clone(), updates }); } if let Some(msg) = closing_signed { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned { - node_id: their_node_id.clone(), - msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendClosingSigned { node_id: their_node_id.clone(), msg }); } - (pending_forwards, pending_failures, chan.get().get_short_channel_id().expect("RAA should only work on a short-id-available channel")) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + ( + pending_forwards, + pending_failures, + chan.get() + .get_short_channel_id() + .expect("RAA should only work on a short-id-available channel"), + ) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } }; for failure in pending_failures.drain(..) { @@ -2712,42 +3242,78 @@ impl ChannelMan Ok(()) } - fn internal_update_fee(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFee) -> Result<(), MsgHandleErrInternal> { + fn internal_update_fee( + &self, their_node_id: &PublicKey, msg: &msgs::UpdateFee, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } try_chan_entry!(self, chan.get_mut().update_fee(&self.fee_estimator, &msg), channel_state, chan); - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } Ok(()) } - fn internal_announcement_signatures(&self, their_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures) -> Result<(), MsgHandleErrInternal> { + fn internal_announcement_signatures( + &self, their_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } if !chan.get().is_usable() { - return Err(MsgHandleErrInternal::from_no_close(LightningError{err: "Got an announcement_signatures before we were ready for it", action: msgs::ErrorAction::IgnoreError})); + return Err(MsgHandleErrInternal::from_no_close(LightningError { + err: "Got an announcement_signatures before we were ready for it", + action: msgs::ErrorAction::IgnoreError, + })); } let our_node_id = self.get_our_node_id(); - let (announcement, our_bitcoin_sig) = - try_chan_entry!(self, chan.get_mut().get_channel_announcement(our_node_id.clone(), self.genesis_hash.clone()), channel_state, chan); + let (announcement, our_bitcoin_sig) = try_chan_entry!( + self, + chan.get_mut().get_channel_announcement(our_node_id.clone(), self.genesis_hash.clone()), + channel_state, + chan + ); let were_node_one = announcement.node_id_1 == our_node_id; let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]); - if self.secp_ctx.verify(&msghash, &msg.node_signature, if were_node_one { &announcement.node_id_2 } else { &announcement.node_id_1 }).is_err() || - self.secp_ctx.verify(&msghash, &msg.bitcoin_signature, if were_node_one { &announcement.bitcoin_key_2 } else { &announcement.bitcoin_key_1 }).is_err() { + if self + .secp_ctx + .verify( + &msghash, + &msg.node_signature, + if were_node_one { &announcement.node_id_2 } else { &announcement.node_id_1 }, + ) + .is_err() || self + .secp_ctx + .verify( + &msghash, + &msg.bitcoin_signature, + if were_node_one { &announcement.bitcoin_key_2 } else { &announcement.bitcoin_key_1 }, + ) + .is_err() + { let chan_err: ChannelError = ChannelError::Close("Bad announcement_signatures node_signature"); try_chan_entry!(self, Err(chan_err), channel_state, chan); } @@ -2764,20 +3330,30 @@ impl ChannelMan }, update_msg: self.get_channel_update(chan.get()).unwrap(), // can only fail if we're not in a ready state }); - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } Ok(()) } - fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> { + fn internal_channel_reestablish( + &self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish, + ) -> Result<(), MsgHandleErrInternal> { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan) => { if chan.get().get_their_node_id() != *their_node_id { - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Got a message for a channel from the wrong node!", + msg.channel_id, + )); } let (funding_locked, revoke_and_ack, commitment_update, monitor_update_opt, mut order, shutdown) = try_chan_entry!(self, chan.get_mut().channel_reestablish(msg), channel_state, chan); @@ -2792,16 +3368,24 @@ impl ChannelMan if commitment_update.is_none() { order = RAACommitmentOrder::RevokeAndACKFirst; } - return_monitor_err!(self, e, channel_state, chan, order, revoke_and_ack.is_some(), commitment_update.is_some()); + return_monitor_err!( + self, + e, + channel_state, + chan, + order, + revoke_and_ack.is_some(), + commitment_update.is_some() + ); //TODO: Resend the funding_locked if needed once we get the monitor running again } } if let Some(msg) = funding_locked { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingLocked { - node_id: their_node_id.clone(), - msg - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendFundingLocked { node_id: their_node_id.clone(), msg }); } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! send_raa { () => { if let Some(msg) = revoke_and_ack { channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { @@ -2810,6 +3394,8 @@ impl ChannelMan }); } } } + + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! send_cu { () => { if let Some(updates) = commitment_update { channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { @@ -2822,21 +3408,25 @@ impl ChannelMan RAACommitmentOrder::RevokeAndACKFirst => { send_raa!(); send_cu!(); - }, + } RAACommitmentOrder::CommitmentFirst => { send_cu!(); send_raa!(); - }, + } } if let Some(msg) = shutdown { - channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { - node_id: their_node_id.clone(), - msg, - }); + channel_state + .pending_msg_events + .push(events::MessageSendEvent::SendShutdown { node_id: their_node_id.clone(), msg }); } Ok(()) - }, - hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + hash_map::Entry::Vacant(_) => { + return Err(MsgHandleErrInternal::send_err_msg_no_close( + "Failed to find corresponding channel", + msg.channel_id, + )) + } } } @@ -2845,7 +3435,7 @@ impl ChannelMan /// PeerManager::process_events afterwards. /// Note: This API is likely to change! #[doc(hidden)] - pub fn update_fee(&self, channel_id: [u8;32], feerate_per_kw: u64) -> Result<(), APIError> { + pub fn update_fee(&self, channel_id: [u8; 32], feerate_per_kw: u64) -> Result<(), APIError> { let _ = self.total_consistency_lock.read().unwrap(); let their_node_id; let err: Result<(), _> = loop { @@ -2853,22 +3443,33 @@ impl ChannelMan let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(channel_id) { - hash_map::Entry::Vacant(_) => return Err(APIError::APIMisuseError{err: "Failed to find corresponding channel"}), + hash_map::Entry::Vacant(_) => { + return Err(APIError::APIMisuseError { err: "Failed to find corresponding channel" }) + } hash_map::Entry::Occupied(mut chan) => { if !chan.get().is_outbound() { - return Err(APIError::APIMisuseError{err: "update_fee cannot be sent for an inbound channel"}); + return Err(APIError::APIMisuseError { + err: "update_fee cannot be sent for an inbound channel", + }); } if chan.get().is_awaiting_monitor_update() { return Err(APIError::MonitorUpdateFailed); } if !chan.get().is_live() { - return Err(APIError::ChannelUnavailable{err: "Channel is either not yet fully established or peer is currently disconnected"}); + return Err(APIError::ChannelUnavailable { + err: "Channel is either not yet fully established or peer is currently disconnected", + }); } their_node_id = chan.get().get_their_node_id(); - if let Some((update_fee, commitment_signed, monitor_update)) = - break_chan_entry!(self, chan.get_mut().send_update_fee_and_commit(feerate_per_kw), channel_state, chan) - { - if let Err(_e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) { + if let Some((update_fee, commitment_signed, monitor_update)) = break_chan_entry!( + self, + chan.get_mut().send_update_fee_and_commit(feerate_per_kw), + channel_state, + chan + ) { + if let Err(_e) = + self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) + { unimplemented!(); } channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { @@ -2883,23 +3484,25 @@ impl ChannelMan }, }); } - }, + } } - return Ok(()) + return Ok(()); }; match handle_error!(self, err, their_node_id) { Ok(_) => unreachable!(), - Err(e) => { Err(APIError::APIMisuseError { err: e.err })} + Err(e) => Err(APIError::APIMisuseError { err: e.err }), } } } -impl events::MessageSendEventsProvider for ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +impl events::MessageSendEventsProvider + for ChannelManager +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { fn get_and_clear_pending_msg_events(&self) -> Vec { // TODO: Event release to users and serialization is currently race-y: it's very easy for a @@ -2912,8 +3515,17 @@ impl events::Me log_trace!(self, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); } else { - log_trace!(self, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0)); - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + log_trace!( + self, + "Failing HTLC with hash {} from our monitor", + log_bytes!(htlc_update.payment_hash.0) + ); + self.fail_htlc_backwards_internal( + self.channel_state.lock().unwrap(), + htlc_update.source, + &htlc_update.payment_hash, + HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, + ); } } } @@ -2925,11 +3537,13 @@ impl events::Me } } -impl events::EventsProvider for ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +impl events::EventsProvider + for ChannelManager +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { fn get_and_clear_pending_events(&self) -> Vec { // TODO: Event release to users and serialization is currently race-y: it's very easy for a @@ -2942,8 +3556,17 @@ impl events::Ev log_trace!(self, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); } else { - log_trace!(self, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0)); - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + log_trace!( + self, + "Failing HTLC with hash {} from our monitor", + log_bytes!(htlc_update.payment_hash.0) + ); + self.fail_htlc_backwards_internal( + self.channel_state.lock().unwrap(), + htlc_update.source, + &htlc_update.payment_hash, + HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, + ); } } } @@ -2955,14 +3578,22 @@ impl events::Ev } } -impl - ChainListener for ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +impl< + ChanSigner: ChannelKeys, + M: Deref + Sync + Send, + T: Deref + Sync + Send, + K: Deref + Sync + Send, + F: Deref + Sync + Send, + > ChainListener for ChannelManager +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { - fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) { + fn block_connected( + &self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32], + ) { let header_hash = header.bitcoin_hash(); log_trace!(self, "Block {} at height {} connected with {} txn matched", header_hash, height, txn_matched.len()); let _ = self.total_consistency_lock.read().unwrap(); @@ -2978,10 +3609,14 @@ impl= htlc.cltv_expiry - HTLC_FAIL_BACK_BUFFER { let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec(); htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(height)); - timed_out_htlcs.push((HTLCSource::PreviousHopData(htlc.prev_hop.clone()), payment_hash.clone(), HTLCFailReason::Reason { - failure_code: 0x4000 | 15, - data: htlc_msat_height_data - })); + timed_out_htlcs.push(( + HTLCSource::PreviousHopData(htlc.prev_hop.clone()), + payment_hash.clone(), + HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data }, + )); false - } else { true } + } else { + true + } }); !htlcs.is_empty() // Only retain this entry if htlcs has at least one entry. }); @@ -3081,8 +3731,14 @@ impl= header.time as usize { break; } - if self.last_node_announcement_serial.compare_exchange(old_serial, header.time as usize, Ordering::AcqRel, Ordering::Relaxed).is_ok() { + if old_serial >= header.time as usize { + break; + } + if self + .last_node_announcement_serial + .compare_exchange(old_serial, header.time as usize, Ordering::AcqRel, Ordering::Relaxed) + .is_ok() + { break; } } @@ -3097,16 +3753,14 @@ impl - ChannelMessageHandler for ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +impl< + ChanSigner: ChannelKeys, + M: Deref + Sync + Send, + T: Deref + Sync + Send, + K: Deref + Sync + Send, + F: Deref + Sync + Send, + > ChannelMessageHandler for ChannelManager +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { fn handle_open_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel) { let _ = self.total_consistency_lock.read().unwrap(); let _ = handle_error!(self, self.internal_open_channel(their_node_id, their_features, msg), *their_node_id); } - fn handle_accept_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::AcceptChannel) { + fn handle_accept_channel( + &self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::AcceptChannel, + ) { let _ = self.total_consistency_lock.read().unwrap(); let _ = handle_error!(self, self.internal_accept_channel(their_node_id, their_features, msg), *their_node_id); } @@ -3220,7 +3883,11 @@ impl node_id != their_node_id, - &events::MessageSendEvent::SendOpenChannel { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendFundingCreated { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendFundingSigned { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendFundingLocked { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendAnnouncementSignatures { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::UpdateHTLCs { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendRevokeAndACK { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendClosingSigned { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendShutdown { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::SendChannelReestablish { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::BroadcastChannelAnnouncement { .. } => true, - &events::MessageSendEvent::BroadcastNodeAnnouncement { .. } => true, - &events::MessageSendEvent::BroadcastChannelUpdate { .. } => true, - &events::MessageSendEvent::HandleError { ref node_id, .. } => node_id != their_node_id, - &events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => true, - } + pending_msg_events.retain(|msg| match msg { + &events::MessageSendEvent::SendAcceptChannel { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendOpenChannel { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendFundingCreated { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendFundingSigned { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendFundingLocked { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendAnnouncementSignatures { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::UpdateHTLCs { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendRevokeAndACK { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendClosingSigned { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendShutdown { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::SendChannelReestablish { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::BroadcastChannelAnnouncement { .. } => true, + &events::MessageSendEvent::BroadcastNodeAnnouncement { .. } => true, + &events::MessageSendEvent::BroadcastChannelUpdate { .. } => true, + &events::MessageSendEvent::HandleError { ref node_id, .. } => node_id != their_node_id, + &events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => true, }); } if no_channels_remain { @@ -3289,7 +3956,12 @@ impl { - e.insert(Mutex::new(PeerState { - latest_features: init_msg.features.clone(), - })); - }, + e.insert(Mutex::new(PeerState { latest_features: init_msg.features.clone() })); + } hash_map::Entry::Occupied(e) => { e.get().lock().unwrap().latest_features = init_msg.features.clone(); - }, + } } } @@ -3331,7 +4001,9 @@ impl { 1u8.write(writer)?; payment_data.write(writer)?; incoming_cltv_expiry.write(writer)?; - }, + } } self.incoming_shared_secret.write(writer)?; self.payment_hash.write(writer)?; @@ -3404,7 +4076,7 @@ impl Writeable for HTLCFailureMsg { &HTLCFailureMsg::Relay(ref fail_msg) => { 0u8.write(writer)?; fail_msg.write(writer)?; - }, + } &HTLCFailureMsg::Malformed(ref fail_msg) => { 1u8.write(writer)?; fail_msg.write(writer)?; @@ -3430,7 +4102,7 @@ impl Writeable for PendingHTLCStatus { &PendingHTLCStatus::Forward(ref forward_info) => { 0u8.write(writer)?; forward_info.write(writer)?; - }, + } &PendingHTLCStatus::Fail(ref fail_msg) => { 1u8.write(writer)?; fail_msg.write(writer)?; @@ -3469,7 +4141,7 @@ impl Writeable for HTLCSource { &HTLCSource::PreviousHopData(ref hop_data) => { 0u8.write(writer)?; hop_data.write(writer)?; - }, + } &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat } => { 1u8.write(writer)?; path.write(writer)?; @@ -3501,7 +4173,7 @@ impl Writeable for HTLCFailReason { &HTLCFailReason::LightningError { ref err } => { 0u8.write(writer)?; err.write(writer)?; - }, + } &HTLCFailReason::Reason { ref failure_code, ref data } => { 1u8.write(writer)?; failure_code.write(writer)?; @@ -3516,10 +4188,7 @@ impl Readable for HTLCFailReason { fn read(reader: &mut R) -> Result { match ::read(reader)? { 0 => Ok(HTLCFailReason::LightningError { err: Readable::read(reader)? }), - 1 => Ok(HTLCFailReason::Reason { - failure_code: Readable::read(reader)?, - data: Readable::read(reader)?, - }), + 1 => Ok(HTLCFailReason::Reason { failure_code: Readable::read(reader)?, data: Readable::read(reader)? }), _ => Err(DecodeError::InvalidValue), } } @@ -3533,12 +4202,12 @@ impl Writeable for HTLCForwardInfo { prev_short_channel_id.write(writer)?; prev_htlc_id.write(writer)?; forward_info.write(writer)?; - }, + } &HTLCForwardInfo::FailHTLC { ref htlc_id, ref err_packet } => { 1u8.write(writer)?; htlc_id.write(writer)?; err_packet.write(writer)?; - }, + } } Ok(()) } @@ -3552,20 +4221,21 @@ impl Readable for HTLCForwardInfo { prev_htlc_id: Readable::read(reader)?, forward_info: Readable::read(reader)?, }), - 1 => Ok(HTLCForwardInfo::FailHTLC { - htlc_id: Readable::read(reader)?, - err_packet: Readable::read(reader)?, - }), + 1 => { + Ok(HTLCForwardInfo::FailHTLC { htlc_id: Readable::read(reader)?, err_packet: Readable::read(reader)? }) + } _ => Err(DecodeError::InvalidValue), } } } -impl Writeable for ChannelManager - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +impl Writeable + for ChannelManager +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { let _ = self.total_consistency_lock.write().unwrap(); @@ -3639,12 +4309,12 @@ impl - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { - /// The keys provider which will give us relevant keys. Some keys will be loaded during /// deserialization. pub keys_manager: K, @@ -3687,13 +4357,17 @@ pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T: // Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the // SipmleArcChannelManager type: impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref> - ReadableArgs> for (BlockHash, Arc>) - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, + ReadableArgs> + for (BlockHash, Arc>) +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { - fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F>) -> Result { + fn read( + reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F>, + ) -> Result { let (blockhash, chan_manager) = <(BlockHash, ChannelManager)>::read(reader, args)?; Ok((blockhash, Arc::new(chan_manager))) } @@ -3701,12 +4375,15 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref> ReadableArgs> for (BlockHash, ChannelManager) - where M::Target: ManyChannelMonitor, - T::Target: BroadcasterInterface, - K::Target: KeysInterface, - F::Target: FeeEstimator, +where + M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, { - fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F>) -> Result { + fn read( + reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F>, + ) -> Result { let _ver: u8 = Readable::read(reader)?; let min_ver: u8 = Readable::read(reader)?; if min_ver > SERIALIZATION_VERSION { @@ -3732,16 +4409,21 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?; funding_txo_set.insert(funding_txo.clone()); if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) { - if channel.get_cur_local_commitment_transaction_number() < monitor.get_cur_local_commitment_number() || - channel.get_revoked_remote_commitment_transaction_number() < monitor.get_min_seen_secret() || - channel.get_cur_remote_commitment_transaction_number() < monitor.get_cur_remote_commitment_number() || - channel.get_latest_monitor_update_id() > monitor.get_latest_update_id() { + if channel.get_cur_local_commitment_transaction_number() < monitor.get_cur_local_commitment_number() + || channel.get_revoked_remote_commitment_transaction_number() < monitor.get_min_seen_secret() + || channel.get_cur_remote_commitment_transaction_number() + < monitor.get_cur_remote_commitment_number() + || channel.get_latest_monitor_update_id() > monitor.get_latest_update_id() + { // If the channel is ahead of the monitor, return InvalidValue: return Err(DecodeError::InvalidValue); - } else if channel.get_cur_local_commitment_transaction_number() > monitor.get_cur_local_commitment_number() || - channel.get_revoked_remote_commitment_transaction_number() > monitor.get_min_seen_secret() || - channel.get_cur_remote_commitment_transaction_number() > monitor.get_cur_remote_commitment_number() || - channel.get_latest_monitor_update_id() < monitor.get_latest_update_id() { + } else if channel.get_cur_local_commitment_transaction_number() + > monitor.get_cur_local_commitment_number() + || channel.get_revoked_remote_commitment_transaction_number() > monitor.get_min_seen_secret() + || channel.get_cur_remote_commitment_transaction_number() + > monitor.get_cur_remote_commitment_number() + || channel.get_latest_monitor_update_id() < monitor.get_latest_update_id() + { // But if the channel is behind of the monitor, close the channel: let (_, _, mut new_failed_htlcs) = channel.force_shutdown(true); failed_htlcs.append(&mut new_failed_htlcs); @@ -3791,9 +4473,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De let mut per_peer_state = HashMap::with_capacity(cmp::min(peer_count as usize, 128)); for _ in 0..peer_count { let peer_pubkey = Readable::read(reader)?; - let peer_state = PeerState { - latest_features: Readable::read(reader)?, - }; + let peer_state = PeerState { latest_features: Readable::read(reader)? }; per_peer_state.insert(peer_pubkey, Mutex::new(peer_state)); } @@ -3830,7 +4510,12 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De }; for htlc_source in failed_htlcs.drain(..) { - channel_manager.fail_htlc_backwards_internal(channel_manager.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + channel_manager.fail_htlc_backwards_internal( + channel_manager.channel_state.lock().unwrap(), + htlc_source.0, + &htlc_source.1, + HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, + ); } //TODO: Broadcast channel update for closed channels, but only after we've made a diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index 71196252a3c..fe2b29cd4e4 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -12,37 +12,37 @@ //! ChannelMonitors to get out of the HSM and onto monitoring devices. use bitcoin::blockdata::block::BlockHeader; -use bitcoin::blockdata::transaction::{TxOut,Transaction}; -use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint; -use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::opcodes; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint; +use bitcoin::blockdata::transaction::{Transaction, TxOut}; use bitcoin::consensus::encode; use bitcoin::util::hash::BitcoinHash; -use bitcoin::hashes::Hash; +use bitcoin::hash_types::{BlockHash, Txid, WPubkeyHash}; use bitcoin::hashes::sha256::Hash as Sha256; -use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash}; +use bitcoin::hashes::Hash; -use bitcoin::secp256k1::{Secp256k1,Signature}; -use bitcoin::secp256k1::key::{SecretKey,PublicKey}; use bitcoin::secp256k1; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; +use bitcoin::secp256k1::{Secp256k1, Signature}; -use ln::msgs::DecodeError; +use chain::chaininterface::{BroadcasterInterface, ChainListener, ChainWatchInterface, FeeEstimator}; +use chain::keysinterface::{ChannelKeys, SpendableOutputDescriptor}; +use chain::transaction::OutPoint; use ln::chan_utils; -use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, LocalCommitmentTransaction, HTLCType}; -use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash}; +use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCType, LocalCommitmentTransaction}; +use ln::channelmanager::{HTLCSource, PaymentHash, PaymentPreimage}; +use ln::msgs::DecodeError; use ln::onchaintx::OnchainTxHandler; -use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface, FeeEstimator}; -use chain::transaction::OutPoint; -use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys}; use util::logger::Logger; -use util::ser::{ReadableArgs, Readable, MaybeReadable, Writer, Writeable, U48}; +use util::ser::{MaybeReadable, Readable, ReadableArgs, Writeable, Writer, U48}; use util::{byte_utils, events}; -use std::collections::{HashMap, hash_map}; -use std::sync::{Arc,Mutex}; -use std::{hash,cmp, mem}; +use std::collections::{hash_map, HashMap}; use std::ops::Deref; +use std::sync::{Arc, Mutex}; +use std::{cmp, hash, mem}; /// An update generated by the underlying Channel itself which contains some new information the /// ChannelMonitor should be made aware of. @@ -75,7 +75,10 @@ impl Readable for ChannelMonitorUpdate { fn read(r: &mut R) -> Result { let update_id: u64 = Readable::read(r)?; let len: u64 = Readable::read(r)?; - let mut updates = Vec::with_capacity(cmp::min(len as usize, MAX_ALLOC_SIZE / ::std::mem::size_of::())); + let mut updates = Vec::with_capacity(cmp::min( + len as usize, + MAX_ALLOC_SIZE / ::std::mem::size_of::(), + )); for _ in 0..len { updates.push(Readable::read(r)?); } @@ -145,7 +148,7 @@ pub struct MonitorUpdateError(pub &'static str); pub struct HTLCUpdate { pub(super) payment_hash: PaymentHash, pub(super) payment_preimage: Option, - pub(super) source: HTLCSource + pub(super) source: HTLCSource, } impl_writeable!(HTLCUpdate, 0, { payment_hash, payment_preimage, source }); @@ -184,7 +187,9 @@ pub trait ManyChannelMonitor: Send + Sync { /// /// Any spends of outputs which should have been registered which aren't passed to /// ChannelMonitors via block_connected may result in FUNDS LOSS. - fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor) -> Result<(), ChannelMonitorUpdateErr>; + fn add_monitor( + &self, funding_txo: OutPoint, monitor: ChannelMonitor, + ) -> Result<(), ChannelMonitorUpdateErr>; /// Updates a monitor for the given `funding_txo`. /// @@ -198,7 +203,9 @@ pub trait ManyChannelMonitor: Send + Sync { /// /// Any spends of outputs which should have been registered which aren't passed to /// ChannelMonitors via block_connected may result in FUNDS LOSS. - fn update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>; + fn update_monitor( + &self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate, + ) -> Result<(), ChannelMonitorUpdateErr>; /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated /// with success or failure. @@ -221,8 +228,9 @@ pub trait ManyChannelMonitor: Send + Sync { /// If you're using this for local monitoring of your own channels, you probably want to use /// `OutPoint` as the key, which will give you a ManyChannelMonitor implementation. pub struct SimpleManyChannelMonitor - where T::Target: BroadcasterInterface, - F::Target: FeeEstimator +where + T::Target: BroadcasterInterface, + F::Target: FeeEstimator, { #[cfg(test)] // Used in ChannelManager tests to manipulate channels directly pub monitors: Mutex>>, @@ -231,20 +239,24 @@ pub struct SimpleManyChannelMonitor, broadcaster: T, logger: Arc, - fee_estimator: F + fee_estimator: F, } -impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send> +impl<'a, Key: Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send> ChainListener for SimpleManyChannelMonitor - where T::Target: BroadcasterInterface, - F::Target: FeeEstimator +where + T::Target: BroadcasterInterface, + F::Target: FeeEstimator, { - fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], _indexes_of_txn_matched: &[u32]) { + fn block_connected( + &self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], _indexes_of_txn_matched: &[u32], + ) { let block_hash = header.bitcoin_hash(); { let mut monitors = self.monitors.lock().unwrap(); for monitor in monitors.values_mut() { - let txn_outputs = monitor.block_connected(txn_matched, height, &block_hash, &*self.broadcaster, &*self.fee_estimator); + let txn_outputs = + monitor.block_connected(txn_matched, height, &block_hash, &*self.broadcaster, &*self.fee_estimator); for (ref txid, ref outputs) in txn_outputs { for (idx, output) in outputs.iter().enumerate() { @@ -264,13 +276,17 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref + } } -impl SimpleManyChannelMonitor - where T::Target: BroadcasterInterface, - F::Target: FeeEstimator +impl + SimpleManyChannelMonitor +where + T::Target: BroadcasterInterface, + F::Target: FeeEstimator, { /// Creates a new object which can be used to monitor several channels given the chain /// interface with which to register to receive notifications. - pub fn new(chain_monitor: Arc, broadcaster: T, logger: Arc, feeest: F) -> SimpleManyChannelMonitor { + pub fn new( + chain_monitor: Arc, broadcaster: T, logger: Arc, feeest: F, + ) -> SimpleManyChannelMonitor { let res = SimpleManyChannelMonitor { monitors: Mutex::new(HashMap::new()), chain_monitor, @@ -286,12 +302,21 @@ impl) -> Result<(), MonitorUpdateError> { let mut monitors = self.monitors.lock().unwrap(); let entry = match monitors.entry(key) { - hash_map::Entry::Occupied(_) => return Err(MonitorUpdateError("Channel monitor for given key is already present")), + hash_map::Entry::Occupied(_) => { + return Err(MonitorUpdateError("Channel monitor for given key is already present")) + } hash_map::Entry::Vacant(e) => e, }; - log_trace!(self, "Got new Channel Monitor for channel {}", log_bytes!(monitor.funding_info.0.to_channel_id()[..])); + log_trace!( + self, + "Got new Channel Monitor for channel {}", + log_bytes!(monitor.funding_info.0.to_channel_id()[..]) + ); self.chain_monitor.install_watch_tx(&monitor.funding_info.0.txid, &monitor.funding_info.1); - self.chain_monitor.install_watch_outpoint((monitor.funding_info.0.txid, monitor.funding_info.0.index as u32), &monitor.funding_info.1); + self.chain_monitor.install_watch_outpoint( + (monitor.funding_info.0.txid, monitor.funding_info.0.index as u32), + &monitor.funding_info.1, + ); for (txid, outputs) in monitor.get_outputs_to_watch().iter() { for (idx, script) in outputs.iter().enumerate() { self.chain_monitor.install_watch_outpoint((*txid, idx as u32), script); @@ -308,24 +333,30 @@ impl { log_trace!(self, "Updating Channel Monitor for channel {}", log_funding_info!(orig_monitor)); orig_monitor.update_monitor(update, &self.broadcaster) - }, - None => Err(MonitorUpdateError("No such monitor registered")) + } + None => Err(MonitorUpdateError("No such monitor registered")), } } } -impl ManyChannelMonitor for SimpleManyChannelMonitor - where T::Target: BroadcasterInterface, - F::Target: FeeEstimator +impl ManyChannelMonitor + for SimpleManyChannelMonitor +where + T::Target: BroadcasterInterface, + F::Target: FeeEstimator, { - fn add_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor) -> Result<(), ChannelMonitorUpdateErr> { + fn add_monitor( + &self, funding_txo: OutPoint, monitor: ChannelMonitor, + ) -> Result<(), ChannelMonitorUpdateErr> { match self.add_monitor_by_key(funding_txo, monitor) { Ok(_) => Ok(()), Err(_) => Err(ChannelMonitorUpdateErr::PermanentFailure), } } - fn update_monitor(&self, funding_txo: OutPoint, update: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr> { + fn update_monitor( + &self, funding_txo: OutPoint, update: ChannelMonitorUpdate, + ) -> Result<(), ChannelMonitorUpdateErr> { match self.update_monitor_by_key(funding_txo, update) { Ok(_) => Ok(()), Err(_) => Err(ChannelMonitorUpdateErr::PermanentFailure), @@ -341,9 +372,11 @@ impl Ma } } -impl events::EventsProvider for SimpleManyChannelMonitor - where T::Target: BroadcasterInterface, - F::Target: FeeEstimator +impl events::EventsProvider + for SimpleManyChannelMonitor +where + T::Target: BroadcasterInterface, + F::Target: FeeEstimator, { fn get_and_clear_pending_events(&self) -> Vec { let mut pending_events = Vec::new(); @@ -423,40 +456,23 @@ struct LocalSignedTx { /// a new bumped one in case of lenghty confirmation delay #[derive(Clone, PartialEq)] pub(crate) enum InputMaterial { - Revoked { - witness_script: Script, - pubkey: Option, - key: SecretKey, - is_htlc: bool, - amount: u64, - }, - RemoteHTLC { - witness_script: Script, - key: SecretKey, - preimage: Option, - amount: u64, - locktime: u32, - }, - LocalHTLC { - preimage: Option, - amount: u64, - }, - Funding { - funding_redeemscript: Script, - } + Revoked { witness_script: Script, pubkey: Option, key: SecretKey, is_htlc: bool, amount: u64 }, + RemoteHTLC { witness_script: Script, key: SecretKey, preimage: Option, amount: u64, locktime: u32 }, + LocalHTLC { preimage: Option, amount: u64 }, + Funding { funding_redeemscript: Script }, } -impl Writeable for InputMaterial { +impl Writeable for InputMaterial { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { match self { - &InputMaterial::Revoked { ref witness_script, ref pubkey, ref key, ref is_htlc, ref amount} => { + &InputMaterial::Revoked { ref witness_script, ref pubkey, ref key, ref is_htlc, ref amount } => { writer.write_all(&[0; 1])?; witness_script.write(writer)?; pubkey.write(writer)?; writer.write_all(&key[..])?; is_htlc.write(writer)?; writer.write_all(&byte_utils::be64_to_array(*amount))?; - }, + } &InputMaterial::RemoteHTLC { ref witness_script, ref key, ref preimage, ref amount, ref locktime } => { writer.write_all(&[1; 1])?; witness_script.write(writer)?; @@ -464,12 +480,12 @@ impl Writeable for InputMaterial { preimage.write(writer)?; writer.write_all(&byte_utils::be64_to_array(*amount))?; writer.write_all(&byte_utils::be32_to_array(*locktime))?; - }, + } &InputMaterial::LocalHTLC { ref preimage, ref amount } => { writer.write_all(&[2; 1])?; preimage.write(writer)?; writer.write_all(&byte_utils::be64_to_array(*amount))?; - }, + } &InputMaterial::Funding { ref funding_redeemscript } => { writer.write_all(&[3; 1])?; funding_redeemscript.write(writer)?; @@ -488,41 +504,22 @@ impl Readable for InputMaterial { let key = Readable::read(reader)?; let is_htlc = Readable::read(reader)?; let amount = Readable::read(reader)?; - InputMaterial::Revoked { - witness_script, - pubkey, - key, - is_htlc, - amount - } - }, + InputMaterial::Revoked { witness_script, pubkey, key, is_htlc, amount } + } 1 => { let witness_script = Readable::read(reader)?; let key = Readable::read(reader)?; let preimage = Readable::read(reader)?; let amount = Readable::read(reader)?; let locktime = Readable::read(reader)?; - InputMaterial::RemoteHTLC { - witness_script, - key, - preimage, - amount, - locktime - } - }, + InputMaterial::RemoteHTLC { witness_script, key, preimage, amount, locktime } + } 2 => { let preimage = Readable::read(reader)?; let amount = Readable::read(reader)?; - InputMaterial::LocalHTLC { - preimage, - amount, - } - }, - 3 => { - InputMaterial::Funding { - funding_redeemscript: Readable::read(reader)?, - } + InputMaterial::LocalHTLC { preimage, amount } } + 3 => InputMaterial::Funding { funding_redeemscript: Readable::read(reader)? }, _ => return Err(DecodeError::InvalidValue), }; Ok(input_material) @@ -548,7 +545,7 @@ pub(crate) struct ClaimRequest { pub(crate) outpoint: BitcoinOutPoint, // Following outpoint type, set of data needed to generate transaction digest // and satisfy witness program. - pub(crate) witness_data: InputMaterial + pub(crate) witness_data: InputMaterial, } /// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it @@ -616,7 +613,12 @@ impl Writeable for ChannelMonitorUpdateStep { source.write(w)?; } } - &ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { ref unsigned_commitment_tx, ref htlc_outputs, ref commitment_number, ref their_revocation_point } => { + &ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { + ref unsigned_commitment_tx, + ref htlc_outputs, + ref commitment_number, + ref their_revocation_point, + } => { 1u8.write(w)?; unsigned_commitment_tx.write(w)?; commitment_number.write(w)?; @@ -626,24 +628,24 @@ impl Writeable for ChannelMonitorUpdateStep { output.write(w)?; source.as_ref().map(|b| b.as_ref()).write(w)?; } - }, + } &ChannelMonitorUpdateStep::PaymentPreimage { ref payment_preimage } => { 2u8.write(w)?; payment_preimage.write(w)?; - }, + } &ChannelMonitorUpdateStep::CommitmentSecret { ref idx, ref secret } => { 3u8.write(w)?; idx.write(w)?; secret.write(w)?; - }, + } &ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { ref their_current_per_commitment_point } => { 4u8.write(w)?; their_current_per_commitment_point.write(w)?; - }, + } &ChannelMonitorUpdateStep::ChannelForceClosed { ref should_broadcast } => { 5u8.write(w)?; should_broadcast.write(w)?; - }, + } } Ok(()) } @@ -651,55 +653,38 @@ impl Writeable for ChannelMonitorUpdateStep { impl Readable for ChannelMonitorUpdateStep { fn read(r: &mut R) -> Result { match Readable::read(r)? { - 0u8 => { - Ok(ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { - commitment_tx: Readable::read(r)?, - htlc_outputs: { - let len: u64 = Readable::read(r)?; - let mut res = Vec::new(); - for _ in 0..len { - res.push((Readable::read(r)?, Readable::read(r)?, Readable::read(r)?)); - } - res - }, - }) - }, - 1u8 => { - Ok(ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { - unsigned_commitment_tx: Readable::read(r)?, - commitment_number: Readable::read(r)?, - their_revocation_point: Readable::read(r)?, - htlc_outputs: { - let len: u64 = Readable::read(r)?; - let mut res = Vec::new(); - for _ in 0..len { - res.push((Readable::read(r)?, as Readable>::read(r)?.map(|o| Box::new(o)))); - } - res - }, - }) - }, - 2u8 => { - Ok(ChannelMonitorUpdateStep::PaymentPreimage { - payment_preimage: Readable::read(r)?, - }) - }, + 0u8 => Ok(ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { + commitment_tx: Readable::read(r)?, + htlc_outputs: { + let len: u64 = Readable::read(r)?; + let mut res = Vec::new(); + for _ in 0..len { + res.push((Readable::read(r)?, Readable::read(r)?, Readable::read(r)?)); + } + res + }, + }), + 1u8 => Ok(ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { + unsigned_commitment_tx: Readable::read(r)?, + commitment_number: Readable::read(r)?, + their_revocation_point: Readable::read(r)?, + htlc_outputs: { + let len: u64 = Readable::read(r)?; + let mut res = Vec::new(); + for _ in 0..len { + res.push((Readable::read(r)?, as Readable>::read(r)?.map(|o| Box::new(o)))); + } + res + }, + }), + 2u8 => Ok(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: Readable::read(r)? }), 3u8 => { - Ok(ChannelMonitorUpdateStep::CommitmentSecret { - idx: Readable::read(r)?, - secret: Readable::read(r)?, - }) - }, - 4u8 => { - Ok(ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { - their_current_per_commitment_point: Readable::read(r)?, - }) - }, - 5u8 => { - Ok(ChannelMonitorUpdateStep::ChannelForceClosed { - should_broadcast: Readable::read(r)? - }) - }, + Ok(ChannelMonitorUpdateStep::CommitmentSecret { idx: Readable::read(r)?, secret: Readable::read(r)? }) + } + 4u8 => Ok(ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { + their_current_per_commitment_point: Readable::read(r)?, + }), + 5u8 => Ok(ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast: Readable::read(r)? }), _ => Err(DecodeError::InvalidValue), } } @@ -909,15 +894,15 @@ impl ChannelMonitor { match second_option { Some(second_pubkey) => { writer.write_all(&second_pubkey.serialize())?; - }, + } None => { writer.write_all(&[0; 33])?; - }, + } } - }, + } None => { writer.write_all(&byte_utils::be48_to_array(0))?; - }, + } } writer.write_all(&byte_utils::be16_to_array(self.our_to_self_delay))?; @@ -925,6 +910,7 @@ impl ChannelMonitor { self.commitment_secrets.write(writer)?; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! serialize_htlc_in_commitment { ($htlc_output: expr) => { writer.write_all(&[$htlc_output.offered as u8; 1])?; @@ -961,6 +947,7 @@ impl ChannelMonitor { writer.write_all(&byte_utils::be48_to_array(*commitment_number))?; } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! serialize_local_tx { ($local_tx: expr) => { $local_tx.txid.write(writer)?; @@ -1024,11 +1011,11 @@ impl ChannelMonitor { 0u8.write(writer)?; htlc_update.0.write(writer)?; htlc_update.1.write(writer)?; - }, + } OnchainEvent::MaturingOutput { ref descriptor } => { 1u8.write(writer)?; descriptor.write(writer)?; - }, + } } } } @@ -1051,19 +1038,22 @@ impl ChannelMonitor { } impl ChannelMonitor { - pub(super) fn new(keys: ChanSigner, shutdown_pubkey: &PublicKey, - our_to_self_delay: u16, destination_script: &Script, funding_info: (OutPoint, Script), - their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey, - their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64, - commitment_transaction_number_obscure_factor: u64, - initial_local_commitment_tx: LocalCommitmentTransaction, - logger: Arc) -> ChannelMonitor { - + pub(super) fn new( + keys: ChanSigner, shutdown_pubkey: &PublicKey, our_to_self_delay: u16, destination_script: &Script, + funding_info: (OutPoint, Script), their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey, + their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64, + commitment_transaction_number_obscure_factor: u64, initial_local_commitment_tx: LocalCommitmentTransaction, + logger: Arc, + ) -> ChannelMonitor { assert!(commitment_transaction_number_obscure_factor <= (1 << 48)); let our_channel_close_key_hash = WPubkeyHash::hash(&shutdown_pubkey.serialize()); - let shutdown_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_close_key_hash[..]).into_script(); + let shutdown_script = Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&our_channel_close_key_hash[..]) + .into_script(); - let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), their_to_self_delay, logger.clone()); + let mut onchain_tx_handler = + OnchainTxHandler::new(destination_script.clone(), keys.clone(), their_to_self_delay, logger.clone()); let local_tx_sequence = initial_local_commitment_tx.unsigned_tx.input[0].sequence as u64; let local_tx_locktime = initial_local_commitment_tx.unsigned_tx.lock_time as u64; @@ -1101,7 +1091,7 @@ impl ChannelMonitor { their_htlc_base_key: their_htlc_base_key.clone(), their_delayed_payment_base_key: their_delayed_payment_base_key.clone(), funding_redeemscript, - channel_value_satoshis: channel_value_satoshis, + channel_value_satoshis, their_cur_revocation_points: None, our_to_self_delay, @@ -1115,7 +1105,9 @@ impl ChannelMonitor { prev_local_signed_commitment_tx: None, current_local_commitment_tx: local_commitment_tx, current_remote_commitment_number: 1 << 48, - current_local_commitment_number: 0xffff_ffff_ffff - ((((local_tx_sequence & 0xffffff) << 3*8) | (local_tx_locktime as u64 & 0xffffff)) ^ commitment_transaction_number_obscure_factor), + current_local_commitment_number: 0xffff_ffff_ffff + - ((((local_tx_sequence & 0xffffff) << 3 * 8) | (local_tx_locktime as u64 & 0xffffff)) + ^ commitment_transaction_number_obscure_factor), payment_preimages: HashMap::new(), pending_htlcs_updated: Vec::new(), @@ -1160,22 +1152,24 @@ impl ChannelMonitor { self.payment_preimages.retain(|&k, _| { for &(ref htlc, _, _) in cur_local_signed_commitment_tx.htlc_outputs.iter() { if k == htlc.payment_hash { - return true + return true; } } if let Some(prev_local_commitment_tx) = prev_local_signed_commitment_tx { for &(ref htlc, _, _) in prev_local_commitment_tx.htlc_outputs.iter() { if k == htlc.payment_hash { - return true + return true; } } } let contains = if let Some(cn) = remote_hash_commitment_number.get(&k) { if *cn < min_idx { - return true + return true; } true - } else { false }; + } else { + false + }; if contains { remote_hash_commitment_number.remove(&k); } @@ -1190,7 +1184,11 @@ impl ChannelMonitor { /// The monitor watches for it to be broadcasted and then uses the HTLC information (and /// possibly future revocation/preimage information) to claim outputs where possible. /// We cache also the mapping hash:commitment number to lighten pruning of old preimages by watchtowers. - pub(super) fn provide_latest_remote_commitment_tx_info(&mut self, unsigned_commitment_tx: &Transaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_revocation_point: PublicKey) { + pub(super) fn provide_latest_remote_commitment_tx_info( + &mut self, unsigned_commitment_tx: &Transaction, + htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, + their_revocation_point: PublicKey, + ) { // TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction // so that a remote monitor doesn't learn anything unless there is a malicious close. // (only maybe, sadly we cant do the same for local info, as we need to be aware of @@ -1200,8 +1198,18 @@ impl ChannelMonitor { } let new_txid = unsigned_commitment_tx.txid(); - log_trace!(self, "Tracking new remote commitment transaction with txid {} at commitment number {} with {} HTLC outputs", new_txid, commitment_number, htlc_outputs.len()); - log_trace!(self, "New potential remote commitment transaction: {}", encode::serialize_hex(unsigned_commitment_tx)); + log_trace!( + self, + "Tracking new remote commitment transaction with txid {} at commitment number {} with {} HTLC outputs", + new_txid, + commitment_number, + htlc_outputs.len() + ); + log_trace!( + self, + "New potential remote commitment transaction: {}", + encode::serialize_hex(unsigned_commitment_tx) + ); self.prev_remote_commitment_txid = self.current_remote_commitment_txid.take(); self.current_remote_commitment_txid = Some(new_txid); self.remote_claimable_outpoints.insert(new_txid, htlc_outputs); @@ -1213,14 +1221,15 @@ impl ChannelMonitor { self.their_cur_revocation_points = Some((old_points.0, old_points.1, Some(their_revocation_point))); } else if old_points.0 == commitment_number + 2 { if let Some(old_second_point) = old_points.2 { - self.their_cur_revocation_points = Some((old_points.0 - 1, old_second_point, Some(their_revocation_point))); + self.their_cur_revocation_points = + Some((old_points.0 - 1, old_second_point, Some(their_revocation_point))); } else { self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None)); } } else { self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None)); } - }, + } None => { self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None)); } @@ -1228,11 +1237,18 @@ impl ChannelMonitor { } pub(super) fn provide_rescue_remote_commitment_tx_info(&mut self, their_revocation_point: PublicKey) { - if let Ok(payment_key) = chan_utils::derive_public_key(&self.secp_ctx, &their_revocation_point, &self.keys.pubkeys().payment_basepoint) { - let to_remote_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0) + if let Ok(payment_key) = chan_utils::derive_public_key( + &self.secp_ctx, + &their_revocation_point, + &self.keys.pubkeys().payment_basepoint, + ) { + let to_remote_script = Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) .push_slice(&WPubkeyHash::hash(&payment_key.serialize())[..]) .into_script(); - if let Ok(to_remote_key) = chan_utils::derive_private_key(&self.secp_ctx, &their_revocation_point, &self.keys.payment_base_key()) { + if let Ok(to_remote_key) = + chan_utils::derive_private_key(&self.secp_ctx, &their_revocation_point, &self.keys.payment_base_key()) + { self.broadcasted_remote_payment_script = Some((to_remote_script, to_remote_key)); } } @@ -1243,7 +1259,10 @@ impl ChannelMonitor { /// is important that any clones of this channel monitor (including remote clones) by kept /// up-to-date as our local commitment transaction is updated. /// Panics if set_their_to_self_delay has never been called. - pub(super) fn provide_latest_local_commitment_tx_info(&mut self, commitment_tx: LocalCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>) -> Result<(), MonitorUpdateError> { + pub(super) fn provide_latest_local_commitment_tx_info( + &mut self, commitment_tx: LocalCommitmentTransaction, + htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>, + ) -> Result<(), MonitorUpdateError> { if self.local_tx_signed { return Err(MonitorUpdateError("A local commitment tx has already been signed, no new local commitment txn can be sent to our counterparty")); } @@ -1258,7 +1277,7 @@ impl ChannelMonitor { delayed_payment_key: commitment_tx.local_keys.a_delayed_payment_key, per_commitment_point: commitment_tx.local_keys.per_commitment_point, feerate_per_kw: commitment_tx.feerate_per_kw, - htlc_outputs: htlc_outputs, + htlc_outputs, }; // Returning a monitor error before updating tracking points means in case of using // a concurrent watchtower implementation for same channel, if this one doesn't @@ -1268,7 +1287,9 @@ impl ChannelMonitor { if let Err(_) = self.onchain_tx_handler.provide_latest_local_tx(commitment_tx) { return Err(MonitorUpdateError("Local commitment signed has already been signed, no further update of LOCAL commitment transaction is allowed")); } - self.current_local_commitment_number = 0xffff_ffff_ffff - ((((sequence & 0xffffff) << 3*8) | (locktime as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor); + self.current_local_commitment_number = 0xffff_ffff_ffff + - ((((sequence & 0xffffff) << 3 * 8) | (locktime as u64 & 0xffffff)) + ^ self.commitment_transaction_number_obscure_factor); mem::swap(&mut new_local_commitment_tx, &mut self.current_local_commitment_tx); self.prev_local_signed_commitment_tx = Some(new_local_commitment_tx); Ok(()) @@ -1281,7 +1302,8 @@ impl ChannelMonitor { } pub(super) fn broadcast_latest_local_commitment_txn(&mut self, broadcaster: &B) - where B::Target: BroadcasterInterface, + where + B::Target: BroadcasterInterface, { for tx in self.get_latest_local_commitment_txn().iter() { broadcaster.broadcast_transaction(tx); @@ -1293,18 +1315,31 @@ impl ChannelMonitor { for update in updates.updates.drain(..) { match update { ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, htlc_outputs } => { - if self.lockdown_from_offchain { panic!(); } + if self.lockdown_from_offchain { + panic!(); + } self.provide_latest_local_commitment_tx_info(commitment_tx, htlc_outputs)? - }, - ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => - self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point), - ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => - self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage), - ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => - self.provide_secret(idx, secret)?, - ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => - self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point), - ChannelMonitorUpdateStep::ChannelForceClosed { .. } => {}, + } + ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { + unsigned_commitment_tx, + htlc_outputs, + commitment_number, + their_revocation_point, + } => self.provide_latest_remote_commitment_tx_info( + &unsigned_commitment_tx, + htlc_outputs, + commitment_number, + their_revocation_point, + ), + ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => self.provide_payment_preimage( + &PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), + &payment_preimage, + ), + ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => self.provide_secret(idx, secret)?, + ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => { + self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point) + } + ChannelMonitorUpdateStep::ChannelForceClosed { .. } => {} } } self.latest_update_id = updates.update_id; @@ -1315,8 +1350,11 @@ impl ChannelMonitor { /// itself. /// /// panics if the given update is not the next update by update_id. - pub fn update_monitor(&mut self, mut updates: ChannelMonitorUpdate, broadcaster: &B) -> Result<(), MonitorUpdateError> - where B::Target: BroadcasterInterface, + pub fn update_monitor( + &mut self, mut updates: ChannelMonitorUpdate, broadcaster: &B, + ) -> Result<(), MonitorUpdateError> + where + B::Target: BroadcasterInterface, { if self.latest_update_id + 1 != updates.update_id { panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!"); @@ -1324,17 +1362,30 @@ impl ChannelMonitor { for update in updates.updates.drain(..) { match update { ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, htlc_outputs } => { - if self.lockdown_from_offchain { panic!(); } + if self.lockdown_from_offchain { + panic!(); + } self.provide_latest_local_commitment_tx_info(commitment_tx, htlc_outputs)? - }, - ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => - self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point), - ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => - self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage), - ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => - self.provide_secret(idx, secret)?, - ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => - self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point), + } + ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { + unsigned_commitment_tx, + htlc_outputs, + commitment_number, + their_revocation_point, + } => self.provide_latest_remote_commitment_tx_info( + &unsigned_commitment_tx, + htlc_outputs, + commitment_number, + their_revocation_point, + ), + ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => self.provide_payment_preimage( + &PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), + &payment_preimage, + ), + ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => self.provide_secret(idx, secret)?, + ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } => { + self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point) + } ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => { self.lockdown_from_offchain = true; if should_broadcast { @@ -1423,7 +1474,9 @@ impl ChannelMonitor { /// HTLC-Success/HTLC-Timeout transactions. /// Return updates for HTLC pending in the channel and failed automatically by the broadcast of /// revoked remote commitment tx - fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec, (Txid, Vec)) { + fn check_spend_remote_transaction( + &mut self, tx: &Transaction, height: u32, + ) -> (Vec, (Txid, Vec)) { // Most secp and related errors trying to create keys means we have no hope of constructing // a spend transaction...so we return no transactions to broadcast let mut claimable_outpoints = Vec::new(); @@ -1432,6 +1485,7 @@ impl ChannelMonitor { let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers! let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! ignore_error { ( $thing : expr ) => { match $thing { @@ -1441,33 +1495,78 @@ impl ChannelMonitor { }; } - let commitment_number = 0xffffffffffff - ((((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor); + let commitment_number = 0xffffffffffff + - ((((tx.input[0].sequence as u64 & 0xffffff) << 3 * 8) | (tx.lock_time as u64 & 0xffffff)) + ^ self.commitment_transaction_number_obscure_factor); if commitment_number >= self.get_min_seen_secret() { let secret = self.get_secret(commitment_number).unwrap(); let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret)); let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key); - let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint)); - let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &self.keys.revocation_base_key())); - let b_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().htlc_basepoint)); - let local_payment_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, &per_commitment_point, &self.keys.payment_base_key())); - let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.their_delayed_payment_base_key)); - let a_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.their_htlc_base_key)); - - let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key); + let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key( + &self.secp_ctx, + &per_commitment_point, + &self.keys.pubkeys().revocation_basepoint + )); + let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key( + &self.secp_ctx, + &per_commitment_key, + &self.keys.revocation_base_key() + )); + let b_htlc_key = ignore_error!(chan_utils::derive_public_key( + &self.secp_ctx, + &per_commitment_point, + &self.keys.pubkeys().htlc_basepoint + )); + let local_payment_key = ignore_error!(chan_utils::derive_private_key( + &self.secp_ctx, + &per_commitment_point, + &self.keys.payment_base_key() + )); + let delayed_key = ignore_error!(chan_utils::derive_public_key( + &self.secp_ctx, + &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), + &self.their_delayed_payment_base_key + )); + let a_htlc_key = ignore_error!(chan_utils::derive_public_key( + &self.secp_ctx, + &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), + &self.their_htlc_base_key + )); + + let revokeable_redeemscript = + chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key); let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh(); self.broadcasted_remote_payment_script = { // Note that the Network here is ignored as we immediately drop the address for the // script_pubkey version - let payment_hash160 = WPubkeyHash::hash(&PublicKey::from_secret_key(&self.secp_ctx, &local_payment_key).serialize()); - Some((Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script(), local_payment_key)) + let payment_hash160 = + WPubkeyHash::hash(&PublicKey::from_secret_key(&self.secp_ctx, &local_payment_key).serialize()); + Some(( + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&payment_hash160[..]) + .into_script(), + local_payment_key, + )) }; // First, process non-htlc outputs (to_local & to_remote) for (idx, outp) in tx.output.iter().enumerate() { if outp.script_pubkey == revokeable_p2wsh { - let witness_data = InputMaterial::Revoked { witness_script: revokeable_redeemscript.clone(), pubkey: Some(revocation_pubkey), key: revocation_key, is_htlc: false, amount: outp.value }; - claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.our_to_self_delay as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, witness_data}); + let witness_data = InputMaterial::Revoked { + witness_script: revokeable_redeemscript.clone(), + pubkey: Some(revocation_pubkey), + key: revocation_key, + is_htlc: false, + amount: outp.value, + }; + claimable_outpoints.push(ClaimRequest { + absolute_timelock: height + self.our_to_self_delay as u32, + aggregable: true, + outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, + witness_data, + }); } } @@ -1475,25 +1574,48 @@ impl ChannelMonitor { if let Some(ref per_commitment_data) = per_commitment_option { for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() { if let Some(transaction_output_index) = htlc.transaction_output_index { - let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey); - if transaction_output_index as usize >= tx.output.len() || - tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 || - tx.output[transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() { + let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys( + &htlc, + &a_htlc_key, + &b_htlc_key, + &revocation_pubkey, + ); + if transaction_output_index as usize >= tx.output.len() + || tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 + || tx.output[transaction_output_index as usize].script_pubkey + != expected_script.to_v0_p2wsh() + { return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user } - let witness_data = InputMaterial::Revoked { witness_script: expected_script, pubkey: Some(revocation_pubkey), key: revocation_key, is_htlc: true, amount: tx.output[transaction_output_index as usize].value }; - claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data }); + let witness_data = InputMaterial::Revoked { + witness_script: expected_script, + pubkey: Some(revocation_pubkey), + key: revocation_key, + is_htlc: true, + amount: tx.output[transaction_output_index as usize].value, + }; + claimable_outpoints.push(ClaimRequest { + absolute_timelock: htlc.cltv_expiry, + aggregable: true, + outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, + witness_data, + }); } } } // Last, track onchain revoked commitment transaction and fail backward outgoing HTLCs as payment path is broken - if !claimable_outpoints.is_empty() || per_commitment_option.is_some() { // ie we're confident this is actually ours + if !claimable_outpoints.is_empty() || per_commitment_option.is_some() { + // ie we're confident this is actually ours // We're definitely a remote commitment transaction! log_trace!(self, "Got broadcast of revoked remote commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len()); watch_outputs.append(&mut tx.output.clone()); - self.remote_commitment_txn_on_chain.insert(commitment_txid, (commitment_number, tx.output.iter().map(|output| { output.script_pubkey.clone() }).collect())); + self.remote_commitment_txn_on_chain.insert( + commitment_txid, + (commitment_number, tx.output.iter().map(|output| output.script_pubkey.clone()).collect()), + ); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! check_htlc_fails { ($txid: expr, $commitment_tx: expr) => { if let Some(ref outpoints) = self.remote_claimable_outpoints.get($txid) { @@ -1539,10 +1661,14 @@ impl ChannelMonitor { // not being generated by the above conditional. Thus, to be safe, we go ahead and // insert it here. watch_outputs.append(&mut tx.output.clone()); - self.remote_commitment_txn_on_chain.insert(commitment_txid, (commitment_number, tx.output.iter().map(|output| { output.script_pubkey.clone() }).collect())); + self.remote_commitment_txn_on_chain.insert( + commitment_txid, + (commitment_number, tx.output.iter().map(|output| output.script_pubkey.clone()).collect()), + ); log_trace!(self, "Got broadcast of non-revoked remote commitment transaction {}", commitment_txid); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! check_htlc_fails { ($txid: expr, $commitment_tx: expr, $id: tt) => { if let Some(ref latest_outpoints) = self.remote_claimable_outpoints.get($txid) { @@ -1593,39 +1719,99 @@ impl ChannelMonitor { } if let Some(revocation_points) = self.their_cur_revocation_points { - let revocation_point_option = - if revocation_points.0 == commitment_number { Some(&revocation_points.1) } - else if let Some(point) = revocation_points.2.as_ref() { - if revocation_points.0 == commitment_number + 1 { Some(point) } else { None } - } else { None }; + let revocation_point_option = if revocation_points.0 == commitment_number { + Some(&revocation_points.1) + } else if let Some(point) = revocation_points.2.as_ref() { + if revocation_points.0 == commitment_number + 1 { + Some(point) + } else { + None + } + } else { + None + }; if let Some(revocation_point) = revocation_point_option { - let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &self.keys.pubkeys().revocation_basepoint)); - let b_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &self.keys.pubkeys().htlc_basepoint)); - let htlc_privkey = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &self.keys.htlc_base_key())); - let a_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &self.their_htlc_base_key)); - let local_payment_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &self.keys.payment_base_key())); + let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key( + &self.secp_ctx, + revocation_point, + &self.keys.pubkeys().revocation_basepoint + )); + let b_htlc_key = ignore_error!(chan_utils::derive_public_key( + &self.secp_ctx, + revocation_point, + &self.keys.pubkeys().htlc_basepoint + )); + let htlc_privkey = ignore_error!(chan_utils::derive_private_key( + &self.secp_ctx, + revocation_point, + &self.keys.htlc_base_key() + )); + let a_htlc_key = ignore_error!(chan_utils::derive_public_key( + &self.secp_ctx, + revocation_point, + &self.their_htlc_base_key + )); + let local_payment_key = ignore_error!(chan_utils::derive_private_key( + &self.secp_ctx, + revocation_point, + &self.keys.payment_base_key() + )); self.broadcasted_remote_payment_script = { // Note that the Network here is ignored as we immediately drop the address for the // script_pubkey version - let payment_hash160 = WPubkeyHash::hash(&PublicKey::from_secret_key(&self.secp_ctx, &local_payment_key).serialize()); - Some((Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script(), local_payment_key)) + let payment_hash160 = WPubkeyHash::hash( + &PublicKey::from_secret_key(&self.secp_ctx, &local_payment_key).serialize(), + ); + Some(( + Builder::new() + .push_opcode(opcodes::all::OP_PUSHBYTES_0) + .push_slice(&payment_hash160[..]) + .into_script(), + local_payment_key, + )) }; // Then, try to find htlc outputs for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() { if let Some(transaction_output_index) = htlc.transaction_output_index { - let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey); - if transaction_output_index as usize >= tx.output.len() || - tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 || - tx.output[transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() { + let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys( + &htlc, + &a_htlc_key, + &b_htlc_key, + &revocation_pubkey, + ); + if transaction_output_index as usize >= tx.output.len() + || tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 + || tx.output[transaction_output_index as usize].script_pubkey + != expected_script.to_v0_p2wsh() + { return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user } - let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None }; + let preimage = if htlc.offered { + if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { + Some(*p) + } else { + None + } + } else { + None + }; let aggregable = if !htlc.offered { false } else { true }; if preimage.is_some() || !htlc.offered { - let witness_data = InputMaterial::RemoteHTLC { witness_script: expected_script, key: htlc_privkey, preimage, amount: htlc.amount_msat / 1000, locktime: htlc.cltv_expiry }; - claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data }); + let witness_data = InputMaterial::RemoteHTLC { + witness_script: expected_script, + key: htlc_privkey, + preimage, + amount: htlc.amount_msat / 1000, + locktime: htlc.cltv_expiry, + }; + claimable_outpoints.push(ClaimRequest { + absolute_timelock: htlc.cltv_expiry, + aggregable, + outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, + witness_data, + }); } } } @@ -1636,12 +1822,15 @@ impl ChannelMonitor { } /// Attempts to claim a remote HTLC-Success/HTLC-Timeout's outputs using the revocation key - fn check_spend_remote_htlc(&mut self, tx: &Transaction, commitment_number: u64, height: u32) -> (Vec, Option<(Txid, Vec)>) { + fn check_spend_remote_htlc( + &mut self, tx: &Transaction, commitment_number: u64, height: u32, + ) -> (Vec, Option<(Txid, Vec)>) { let htlc_txid = tx.txid(); if tx.input.len() != 1 || tx.output.len() != 1 || tx.input[0].witness.len() != 5 { - return (Vec::new(), None) + return (Vec::new(), None); } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! ignore_error { ( $thing : expr ) => { match $thing { @@ -1651,43 +1840,89 @@ impl ChannelMonitor { }; } - let secret = if let Some(secret) = self.get_secret(commitment_number) { secret } else { return (Vec::new(), None); }; + let secret = if let Some(secret) = self.get_secret(commitment_number) { + secret + } else { + return (Vec::new(), None); + }; let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret)); let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key); - let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.keys.pubkeys().revocation_basepoint)); - let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &self.keys.revocation_base_key())); - let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &self.their_delayed_payment_base_key)); - let redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key); + let revocation_pubkey = ignore_error!(chan_utils::derive_public_revocation_key( + &self.secp_ctx, + &per_commitment_point, + &self.keys.pubkeys().revocation_basepoint + )); + let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key( + &self.secp_ctx, + &per_commitment_key, + &self.keys.revocation_base_key() + )); + let delayed_key = ignore_error!(chan_utils::derive_public_key( + &self.secp_ctx, + &per_commitment_point, + &self.their_delayed_payment_base_key + )); + let redeemscript = + chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key); log_trace!(self, "Remote HTLC broadcast {}:{}", htlc_txid, 0); - let witness_data = InputMaterial::Revoked { witness_script: redeemscript, pubkey: Some(revocation_pubkey), key: revocation_key, is_htlc: false, amount: tx.output[0].value }; - let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.our_to_self_delay as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0}, witness_data }); + let witness_data = InputMaterial::Revoked { + witness_script: redeemscript, + pubkey: Some(revocation_pubkey), + key: revocation_key, + is_htlc: false, + amount: tx.output[0].value, + }; + let claimable_outpoints = vec![ClaimRequest { + absolute_timelock: height + self.our_to_self_delay as u32, + aggregable: true, + outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0 }, + witness_data, + }]; (claimable_outpoints, Some((htlc_txid, tx.output.clone()))) } - fn broadcast_by_local_state(&self, commitment_tx: &Transaction, local_tx: &LocalSignedTx) -> (Vec, Vec, Option<(Script, SecretKey, Script)>) { + fn broadcast_by_local_state( + &self, commitment_tx: &Transaction, local_tx: &LocalSignedTx, + ) -> (Vec, Vec, Option<(Script, SecretKey, Script)>) { let mut claim_requests = Vec::with_capacity(local_tx.htlc_outputs.len()); let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len()); - let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.their_to_self_delay, &local_tx.delayed_payment_key); - let broadcasted_local_revokable_script = if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, &local_tx.per_commitment_point, self.keys.delayed_payment_base_key()) { + let redeemscript = chan_utils::get_revokeable_redeemscript( + &local_tx.revocation_key, + self.their_to_self_delay, + &local_tx.delayed_payment_key, + ); + let broadcasted_local_revokable_script = if let Ok(local_delayedkey) = chan_utils::derive_private_key( + &self.secp_ctx, + &local_tx.per_commitment_point, + self.keys.delayed_payment_base_key(), + ) { Some((redeemscript.to_v0_p2wsh(), local_delayedkey, redeemscript)) - } else { None }; + } else { + None + }; for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() { if let Some(transaction_output_index) = htlc.transaction_output_index { - claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, + claim_requests.push(ClaimRequest { + absolute_timelock: ::std::u32::MAX, + aggregable: false, + outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, witness_data: InputMaterial::LocalHTLC { preimage: if !htlc.offered { - if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { - Some(preimage.clone()) - } else { - // We can't build an HTLC-Success transaction without the preimage - continue; - } - } else { None }, + if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { + Some(preimage.clone()) + } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { + None + }, amount: htlc.amount_msat, - }}); + }, + }); watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone()); } } @@ -1698,11 +1933,14 @@ impl ChannelMonitor { /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet) /// revoked using data in local_claimable_outpoints. /// Should not be used if check_spend_revoked_transaction succeeds. - fn check_spend_local_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec, (Txid, Vec)) { + fn check_spend_local_transaction( + &mut self, tx: &Transaction, height: u32, + ) -> (Vec, (Txid, Vec)) { let commitment_txid = tx.txid(); let mut claim_requests = Vec::new(); let mut watch_outputs = Vec::new(); + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! wait_threshold_conf { ($height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => { log_trace!(self, "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation (at height{})", log_bytes!($payment_hash.0), $commitment_tx, height + ANTI_REORG_DELAY - 1); @@ -1726,6 +1964,7 @@ impl ChannelMonitor { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! append_onchain_update { ($updates: expr) => { claim_requests = $updates.0; @@ -1751,6 +1990,7 @@ impl ChannelMonitor { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! fail_dust_htlcs_after_threshold_conf { ($local_tx: expr) => { for &(ref htlc, _, ref source) in &$local_tx.htlc_outputs { @@ -1791,20 +2031,25 @@ impl ChannelMonitor { for htlc in self.current_local_commitment_tx.htlc_outputs.iter() { if let Some(vout) = htlc.0.transaction_output_index { let preimage = if !htlc.0.offered { - if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else { - // We can't build an HTLC-Success transaction without the preimage - continue; - } - } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx( - &::bitcoin::OutPoint { txid, vout }, &preimage) { + if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { + Some(preimage.clone()) + } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { + None + }; + if let Some(htlc_tx) = + self.onchain_tx_handler.get_fully_signed_htlc_tx(&::bitcoin::OutPoint { txid, vout }, &preimage) + { res.push(htlc_tx); } } } // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do. // The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation. - return res + return res; } Vec::new() } @@ -1815,24 +2060,31 @@ impl ChannelMonitor { #[cfg(test)] pub fn unsafe_get_latest_local_commitment_txn(&mut self) -> Vec { log_trace!(self, "Getting signed copy of latest local commitment transaction!"); - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(&self.funding_redeemscript) { + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(&self.funding_redeemscript) + { let txid = commitment_tx.txid(); let mut res = vec![commitment_tx]; for htlc in self.current_local_commitment_tx.htlc_outputs.iter() { if let Some(vout) = htlc.0.transaction_output_index { let preimage = if !htlc.0.offered { - if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else { - // We can't build an HTLC-Success transaction without the preimage - continue; - } - } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx( - &::bitcoin::OutPoint { txid, vout }, &preimage) { + if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { + Some(preimage.clone()) + } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { + None + }; + if let Some(htlc_tx) = self + .onchain_tx_handler + .unsafe_get_fully_signed_htlc_tx(&::bitcoin::OutPoint { txid, vout }, &preimage) + { res.push(htlc_tx); } } } - return res + return res; } Vec::new() } @@ -1842,16 +2094,23 @@ impl ChannelMonitor { /// Eventually this should be pub and, roughly, implement ChainListener, however this requires /// &mut self, as well as returns new spendable outputs and outpoints to watch for spending of /// on-chain. - fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F)-> Vec<(Txid, Vec)> - where B::Target: BroadcasterInterface, - F::Target: FeeEstimator + fn block_connected( + &mut self, txn_matched: &[&Transaction], height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, + ) -> Vec<(Txid, Vec)> + where + B::Target: BroadcasterInterface, + F::Target: FeeEstimator, { for tx in txn_matched { let mut output_val = 0; for out in tx.output.iter() { - if out.value > 21_000_000_0000_0000 { panic!("Value-overflowing transaction provided to block connected"); } + if out.value > 21_000_000_0000_0000 { + panic!("Value-overflowing transaction provided to block connected"); + } output_val += out.value; - if output_val > 21_000_000_0000_0000 { panic!("Value-overflowing transaction provided to block connected"); } + if output_val > 21_000_000_0000_0000 { + panic!("Value-overflowing transaction provided to block connected"); + } } } @@ -1866,7 +2125,7 @@ impl ChannelMonitor { // filters. let prevout = &tx.input[0].previous_output; if prevout.txid == self.funding_info.0.txid && prevout.vout == self.funding_info.0.index as u32 { - if (tx.input[0].sequence >> 8*3) as u8 == 0x80 && (tx.lock_time >> 8*3) as u8 == 0x20 { + if (tx.input[0].sequence >> 8 * 3) as u8 == 0x80 && (tx.lock_time >> 8 * 3) as u8 == 0x20 { let (mut new_outpoints, new_outputs) = self.check_spend_remote_transaction(&tx, height); if !new_outputs.1.is_empty() { watch_outputs.push(new_outputs); @@ -1882,7 +2141,8 @@ impl ChannelMonitor { } } else { if let Some(&(commitment_number, _)) = self.remote_commitment_txn_on_chain.get(&prevout.txid) { - let (mut new_outpoints, new_outputs_option) = self.check_spend_remote_htlc(&tx, commitment_number, height); + let (mut new_outpoints, new_outputs_option) = + self.check_spend_remote_htlc(&tx, commitment_number, height); claimable_outpoints.append(&mut new_outpoints); if let Some(new_outputs) = new_outputs_option { watch_outputs.push(new_outputs); @@ -1899,11 +2159,20 @@ impl ChannelMonitor { } let should_broadcast = self.would_broadcast_at_height(height); if should_broadcast { - claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { funding_redeemscript: self.funding_redeemscript.clone() }}); + claimable_outpoints.push(ClaimRequest { + absolute_timelock: height, + aggregable: false, + outpoint: BitcoinOutPoint { + txid: self.funding_info.0.txid.clone(), + vout: self.funding_info.0.index as u32, + }, + witness_data: InputMaterial::Funding { funding_redeemscript: self.funding_redeemscript.clone() }, + }); } if should_broadcast { if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(&self.funding_redeemscript) { - let (mut new_outpoints, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, &self.current_local_commitment_tx); + let (mut new_outpoints, new_outputs, _) = + self.broadcast_by_local_state(&commitment_tx, &self.current_local_commitment_tx); if !new_outputs.is_empty() { watch_outputs.push((self.current_local_commitment_tx.txid.clone(), new_outputs)); } @@ -1914,35 +2183,50 @@ impl ChannelMonitor { for ev in events { match ev { OnchainEvent::HTLCUpdate { htlc_update } => { - log_trace!(self, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0)); + log_trace!( + self, + "HTLC {} failure update has got enough confirmations to be passed upstream", + log_bytes!((htlc_update.1).0) + ); self.pending_htlcs_updated.push(HTLCUpdate { payment_hash: htlc_update.1, payment_preimage: None, source: htlc_update.0, }); - }, + } OnchainEvent::MaturingOutput { descriptor } => { - log_trace!(self, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor)); - self.pending_events.push(events::Event::SpendableOutputs { - outputs: vec![descriptor] - }); + log_trace!( + self, + "Descriptor {} has got enough confirmations to be passed upstream", + log_spendable!(descriptor) + ); + self.pending_events.push(events::Event::SpendableOutputs { outputs: vec![descriptor] }); } } } } - self.onchain_tx_handler.block_connected(txn_matched, claimable_outpoints, height, &*broadcaster, &*fee_estimator); + self.onchain_tx_handler.block_connected( + txn_matched, + claimable_outpoints, + height, + &*broadcaster, + &*fee_estimator, + ); self.last_block_hash = block_hash.clone(); for &(ref txid, ref output_scripts) in watch_outputs.iter() { - self.outputs_to_watch.insert(txid.clone(), output_scripts.iter().map(|o| o.script_pubkey.clone()).collect()); + self.outputs_to_watch + .insert(txid.clone(), output_scripts.iter().map(|o| o.script_pubkey.clone()).collect()); } watch_outputs } - fn block_disconnected(&mut self, height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F) - where B::Target: BroadcasterInterface, - F::Target: FeeEstimator + fn block_disconnected( + &mut self, height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, + ) where + B::Target: BroadcasterInterface, + F::Target: FeeEstimator, { log_trace!(self, "Block {} at height {} disconnected", block_hash, height); if let Some(_) = self.onchain_events_waiting_threshold_conf.remove(&(height + ANTI_REORG_DELAY - 1)) { @@ -1967,6 +2251,7 @@ impl ChannelMonitor { // to the source, and if we don't fail the channel we will have to ensure that the next // updates that peer sends us are update_fails, failing the channel if not. It's probably // easier to just fail the channel as this case should be rare enough anyway. + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! scan_commitment { ($htlcs: expr, $local_tx: expr) => { for ref htlc in $htlcs { @@ -2024,11 +2309,18 @@ impl ChannelMonitor { fn is_resolving_htlc_output(&mut self, tx: &Transaction, height: u32) { 'outer_loop: for input in &tx.input { let mut payment_data = None; - let revocation_sig_claim = (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) && input.witness[1].len() == 33) - || (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::AcceptedHTLC) && input.witness[1].len() == 33); - let accepted_preimage_claim = input.witness.len() == 5 && HTLCType::scriptlen_to_htlctype(input.witness[4].len()) == Some(HTLCType::AcceptedHTLC); - let offered_preimage_claim = input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC); - + let revocation_sig_claim = (input.witness.len() == 3 + && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) + && input.witness[1].len() == 33) + || (input.witness.len() == 3 + && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::AcceptedHTLC) + && input.witness[1].len() == 33); + let accepted_preimage_claim = input.witness.len() == 5 + && HTLCType::scriptlen_to_htlctype(input.witness[4].len()) == Some(HTLCType::AcceptedHTLC); + let offered_preimage_claim = input.witness.len() == 3 + && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC); + + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! log_claim { ($tx_info: expr, $local_tx: expr, $htlc: expr, $source_avail: expr) => { // We found the output in question, but aren't failing it backwards @@ -2051,6 +2343,7 @@ impl ChannelMonitor { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! check_htlc_valid_remote { ($remote_txid: expr, $htlc_output: expr) => { if let Some(txid) = $remote_txid { @@ -2067,6 +2360,7 @@ impl ChannelMonitor { } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! scan_commitment { ($htlcs: expr, $tx_info: expr, $local_tx: expr) => { for (ref htlc_output, source_option) in $htlcs { @@ -2095,18 +2389,27 @@ impl ChannelMonitor { } if input.previous_output.txid == self.current_local_commitment_tx.txid { - scan_commitment!(self.current_local_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), - "our latest local commitment tx", true); + scan_commitment!( + self.current_local_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), + "our latest local commitment tx", + true + ); } if let Some(ref prev_local_signed_commitment_tx) = self.prev_local_signed_commitment_tx { if input.previous_output.txid == prev_local_signed_commitment_tx.txid { - scan_commitment!(prev_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), - "our previous local commitment tx", true); + scan_commitment!( + prev_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), + "our previous local commitment tx", + true + ); } } if let Some(ref htlc_outputs) = self.remote_claimable_outpoints.get(&input.previous_output.txid) { - scan_commitment!(htlc_outputs.iter().map(|&(ref a, ref b)| (a, (b.as_ref().clone()).map(|boxed| &**boxed))), - "remote commitment tx", false); + scan_commitment!( + htlc_outputs.iter().map(|&(ref a, ref b)| (a, (b.as_ref().clone()).map(|boxed| &**boxed))), + "remote commitment tx", + false + ); } // Check that scan_commitment, above, decided there is some source worth relaying an @@ -2119,7 +2422,7 @@ impl ChannelMonitor { self.pending_htlcs_updated.push(HTLCUpdate { source, payment_preimage: Some(payment_preimage), - payment_hash + payment_hash, }); } } else if offered_preimage_claim { @@ -2128,7 +2431,7 @@ impl ChannelMonitor { self.pending_htlcs_updated.push(HTLCUpdate { source, payment_preimage: Some(payment_preimage), - payment_hash + payment_hash, }); } } else { @@ -2136,18 +2439,14 @@ impl ChannelMonitor { match self.onchain_events_waiting_threshold_conf.entry(height + ANTI_REORG_DELAY - 1) { hash_map::Entry::Occupied(mut entry) => { let e = entry.get_mut(); - e.retain(|ref event| { - match **event { - OnchainEvent::HTLCUpdate { ref htlc_update } => { - return htlc_update.0 != source - }, - _ => true - } + e.retain(|ref event| match **event { + OnchainEvent::HTLCUpdate { ref htlc_update } => return htlc_update.0 != source, + _ => true, }); - e.push(OnchainEvent::HTLCUpdate { htlc_update: (source, payment_hash)}); + e.push(OnchainEvent::HTLCUpdate { htlc_update: (source, payment_hash) }); } hash_map::Entry::Vacant(entry) => { - entry.insert(vec![OnchainEvent::HTLCUpdate { htlc_update: (source, payment_hash)}]); + entry.insert(vec![OnchainEvent::HTLCUpdate { htlc_update: (source, payment_hash) }]); } } } @@ -2158,16 +2457,17 @@ impl ChannelMonitor { /// Check if any transaction broadcasted is paying fund back to some address we can assume to own fn is_paying_spendable_output(&mut self, tx: &Transaction, height: u32) { let mut spendable_output = None; - for (i, outp) in tx.output.iter().enumerate() { // There is max one spendable output for any channel tx, including ones generated by us + for (i, outp) in tx.output.iter().enumerate() { + // There is max one spendable output for any channel tx, including ones generated by us if outp.script_pubkey == self.destination_script { - spendable_output = Some(SpendableOutputDescriptor::StaticOutput { + spendable_output = Some(SpendableOutputDescriptor::StaticOutput { outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 }, output: outp.clone(), }); break; } else if let Some(ref broadcasted_local_revokable_script) = self.broadcasted_local_revokable_script { if broadcasted_local_revokable_script.0 == outp.script_pubkey { - spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WSH { + spendable_output = Some(SpendableOutputDescriptor::DynamicOutputP2WSH { outpoint: BitcoinOutPoint { txid: tx.txid(), vout: i as u32 }, key: broadcasted_local_revokable_script.1, witness_script: broadcasted_local_revokable_script.2.clone(), @@ -2207,10 +2507,11 @@ impl ChannelMonitor { } } -const MAX_ALLOC_SIZE: usize = 64*1024; +const MAX_ALLOC_SIZE: usize = 64 * 1024; impl ReadableArgs> for (BlockHash, ChannelMonitor) { fn read(reader: &mut R, logger: Arc) -> Result { + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! unwrap_obj { ($key: expr) => { match $key { @@ -2236,8 +2537,8 @@ impl ReadableArgs> for (BlockHas let local_delayedkey = Readable::read(reader)?; let revokable_script = Readable::read(reader)?; Some((revokable_address, local_delayedkey, revokable_script)) - }, - 1 => { None }, + } + 1 => None, _ => return Err(DecodeError::InvalidValue), }; let broadcasted_remote_payment_script = match ::read(reader)? { @@ -2245,8 +2546,8 @@ impl ReadableArgs> for (BlockHas let payment_address = Readable::read(reader)?; let payment_key = Readable::read(reader)?; Some((payment_address, payment_key)) - }, - 1 => { None }, + } + 1 => None, _ => return Err(DecodeError::InvalidValue), }; let shutdown_script = Readable::read(reader)?; @@ -2254,10 +2555,7 @@ impl ReadableArgs> for (BlockHas let keys = Readable::read(reader)?; // Technically this can fail and serialize fail a round-trip, but only for serialization of // barely-init'd ChannelMonitors that we can't do anything with. - let outpoint = OutPoint { - txid: Readable::read(reader)?, - index: Readable::read(reader)?, - }; + let outpoint = OutPoint { txid: Readable::read(reader)?, index: Readable::read(reader)? }; let funding_info = (outpoint, Readable::read(reader)?); let current_remote_commitment_txid = Readable::read(reader)?; let prev_remote_commitment_txid = Readable::read(reader)?; @@ -2287,6 +2585,7 @@ impl ReadableArgs> for (BlockHas let commitment_secrets = Readable::read(reader)?; + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! read_htlc_in_commitment { () => { { @@ -2304,13 +2603,17 @@ impl ReadableArgs> for (BlockHas } let remote_claimable_outpoints_len: u64 = Readable::read(reader)?; - let mut remote_claimable_outpoints = HashMap::with_capacity(cmp::min(remote_claimable_outpoints_len as usize, MAX_ALLOC_SIZE / 64)); + let mut remote_claimable_outpoints = + HashMap::with_capacity(cmp::min(remote_claimable_outpoints_len as usize, MAX_ALLOC_SIZE / 64)); for _ in 0..remote_claimable_outpoints_len { let txid: Txid = Readable::read(reader)?; let htlcs_count: u64 = Readable::read(reader)?; let mut htlcs = Vec::with_capacity(cmp::min(htlcs_count as usize, MAX_ALLOC_SIZE / 32)); for _ in 0..htlcs_count { - htlcs.push((read_htlc_in_commitment!(), as Readable>::read(reader)?.map(|o: HTLCSource| Box::new(o)))); + htlcs.push(( + read_htlc_in_commitment!(), + as Readable>::read(reader)?.map(|o: HTLCSource| Box::new(o)), + )); } if let Some(_) = remote_claimable_outpoints.insert(txid, htlcs) { return Err(DecodeError::InvalidValue); @@ -2318,7 +2621,8 @@ impl ReadableArgs> for (BlockHas } let remote_commitment_txn_on_chain_len: u64 = Readable::read(reader)?; - let mut remote_commitment_txn_on_chain = HashMap::with_capacity(cmp::min(remote_commitment_txn_on_chain_len as usize, MAX_ALLOC_SIZE / 32)); + let mut remote_commitment_txn_on_chain = + HashMap::with_capacity(cmp::min(remote_commitment_txn_on_chain_len as usize, MAX_ALLOC_SIZE / 32)); for _ in 0..remote_commitment_txn_on_chain_len { let txid: Txid = Readable::read(reader)?; let commitment_number = ::read(reader)?.0; @@ -2333,7 +2637,8 @@ impl ReadableArgs> for (BlockHas } let remote_hash_commitment_number_len: u64 = Readable::read(reader)?; - let mut remote_hash_commitment_number = HashMap::with_capacity(cmp::min(remote_hash_commitment_number_len as usize, MAX_ALLOC_SIZE / 32)); + let mut remote_hash_commitment_number = + HashMap::with_capacity(cmp::min(remote_hash_commitment_number_len as usize, MAX_ALLOC_SIZE / 32)); for _ in 0..remote_hash_commitment_number_len { let payment_hash: PaymentHash = Readable::read(reader)?; let commitment_number = ::read(reader)?.0; @@ -2342,6 +2647,7 @@ impl ReadableArgs> for (BlockHas } } + #[cfg_attr(rustfmt, rustfmt_skip)] macro_rules! read_local_tx { () => { { @@ -2376,9 +2682,7 @@ impl ReadableArgs> for (BlockHas let prev_local_signed_commitment_tx = match ::read(reader)? { 0 => None, - 1 => { - Some(read_local_tx!()) - }, + 1 => Some(read_local_tx!()), _ => return Err(DecodeError::InvalidValue), }; let current_local_commitment_tx = read_local_tx!(); @@ -2387,7 +2691,8 @@ impl ReadableArgs> for (BlockHas let current_local_commitment_number = ::read(reader)?.0; let payment_preimages_len: u64 = Readable::read(reader)?; - let mut payment_preimages = HashMap::with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32)); + let mut payment_preimages = + HashMap::with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32)); for _ in 0..payment_preimages_len { let preimage: PaymentPreimage = Readable::read(reader)?; let hash = PaymentHash(Sha256::hash(&preimage.0[..]).into_inner()); @@ -2397,13 +2702,15 @@ impl ReadableArgs> for (BlockHas } let pending_htlcs_updated_len: u64 = Readable::read(reader)?; - let mut pending_htlcs_updated = Vec::with_capacity(cmp::min(pending_htlcs_updated_len as usize, MAX_ALLOC_SIZE / (32 + 8*3))); + let mut pending_htlcs_updated = + Vec::with_capacity(cmp::min(pending_htlcs_updated_len as usize, MAX_ALLOC_SIZE / (32 + 8 * 3))); for _ in 0..pending_htlcs_updated_len { pending_htlcs_updated.push(Readable::read(reader)?); } let pending_events_len: u64 = Readable::read(reader)?; - let mut pending_events = Vec::with_capacity(cmp::min(pending_events_len as usize, MAX_ALLOC_SIZE / mem::size_of::())); + let mut pending_events = + Vec::with_capacity(cmp::min(pending_events_len as usize, MAX_ALLOC_SIZE / mem::size_of::())); for _ in 0..pending_events_len { if let Some(event) = MaybeReadable::read(reader)? { pending_events.push(event); @@ -2413,7 +2720,8 @@ impl ReadableArgs> for (BlockHas let last_block_hash: BlockHash = Readable::read(reader)?; let waiting_threshold_conf_len: u64 = Readable::read(reader)?; - let mut onchain_events_waiting_threshold_conf = HashMap::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128)); + let mut onchain_events_waiting_threshold_conf = + HashMap::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128)); for _ in 0..waiting_threshold_conf_len { let height_target = Readable::read(reader)?; let events_len: u64 = Readable::read(reader)?; @@ -2423,16 +2731,12 @@ impl ReadableArgs> for (BlockHas 0 => { let htlc_source = Readable::read(reader)?; let hash = Readable::read(reader)?; - OnchainEvent::HTLCUpdate { - htlc_update: (htlc_source, hash) - } - }, + OnchainEvent::HTLCUpdate { htlc_update: (htlc_source, hash) } + } 1 => { let descriptor = Readable::read(reader)?; - OnchainEvent::MaturingOutput { - descriptor - } - }, + OnchainEvent::MaturingOutput { descriptor } + } _ => return Err(DecodeError::InvalidValue), }; events.push(ev); @@ -2441,11 +2745,15 @@ impl ReadableArgs> for (BlockHas } let outputs_to_watch_len: u64 = Readable::read(reader)?; - let mut outputs_to_watch = HashMap::with_capacity(cmp::min(outputs_to_watch_len as usize, MAX_ALLOC_SIZE / (mem::size_of::() + mem::size_of::>()))); + let mut outputs_to_watch = HashMap::with_capacity(cmp::min( + outputs_to_watch_len as usize, + MAX_ALLOC_SIZE / (mem::size_of::() + mem::size_of::>()), + )); for _ in 0..outputs_to_watch_len { let txid = Readable::read(reader)?; let outputs_len: u64 = Readable::read(reader)?; - let mut outputs = Vec::with_capacity(cmp::min(outputs_len as usize, MAX_ALLOC_SIZE / mem::size_of::