- name: For each commit, run cargo check (including in fuzz)
run: ci/check-each-commit.sh upstream/main
+ check_release:
+ runs-on: ubuntu-latest
+ env:
+ TOOLCHAIN: stable
+ steps:
+ - name: Checkout source code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Install Rust ${{ env.TOOLCHAIN }} toolchain
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ env.TOOLCHAIN }}
+ override: true
+ profile: minimal
+ - name: Run cargo check for release build.
+ run: |
+ cargo check --release
+ cargo check --no-default-features --features=no-std --release
+ cargo doc --release
+
fuzz:
runs-on: ubuntu-latest
env:
+# 0.0.108 - 2022-06-10
+
+## Bug Fixes
+ * Fixed `lightning-background-processor` build in release mode.
+
+In total, this release features 9 files changed, 120 insertions, 74
+deletions in 5 commits from 4 authors, in alphabetical order:
+ * Elias Rohrer
+ * Matt Corallo
+ * Max Fang
+ * Viktor Tigerström
+
+# 0.0.107 - 2022-06-08
+
+## API Updates
+ * Channels larger than 16777215 sats (Wumbo!) are now supported and can be
+ enabled for inbound channels using
+ `ChannelHandshakeLimits::max_funding_satoshis` (#1425).
+ * Support for feature `option_zeroconf`, allowing immediate forwarding of
+ payments after channel opening. This is configured for outbound channels
+ using `ChannelHandshakeLimits::trust_own_funding_0conf` whereas
+ `ChannelManager::accept_inbound_channel_from_trusted_peer_0conf` has to be
+ used for accepting inbound channels (#1401, #1505).
+ * `ChannelManager::claim_funds` no longer returns a `bool` to indicate success.
+ Instead, an `Event::PaymentClaimed` is generated if the claim was successful.
+ Likewise, `ChannelManager::fail_htlc_backwards` no longer has a return value
+ (#1434).
+ * `lightning-rapid-gossip-sync` is a new crate for syncing gossip data from a
+ server, primarily aimed at mobile devices (#1155).
+ * `RapidGossipSync` can be passed to `BackgroundProcessor` in order to persist
+ the `NetworkGraph` and handle `NetworkUpdate`s during event handling (#1433,
+ #1517).
+ * `NetGraphMsgHandler` has been renamed to `P2PGossipSync`, the `network_graph`
+ module has been renamed to `gossip`, and `NetworkUpdate::ChannelClosed` has
+ been renamed `NetworkUpdate::ChannelFailure` (#1159).
+ * Added a `filtered_block_connected` method to `chain::Listen` and a default
+ implementation of `block_connected` for those fetching filtered instead of
+ full blocks (#1453).
+ * The `lightning-block-sync` crate's `BlockSource` trait methods now take
+ `&self` instead of `&mut self` (#1307).
+ * `inbound_payment` module is now public to allow for creating invoices without
+ a `ChannelManager` (#1384).
+ * `lightning-block-sync`'s `init` and `poll` modules support `&dyn BlockSource`
+ which can be determined at runtime (#1423).
+ * `lightning-invoice` crate's `utils` now accept an expiration time (#1422,
+ #1474).
+ * `Event::PaymentForwarded` includes `prev_channel_id` and `next_channel_id`
+ (#1419, #1475).
+ * `chain::Watch::release_pending_monitor_events`' return type now associates
+ `MonitorEvent`s with funding `OutPoints` (#1475).
+ * `lightning-background-processor` crate's `Persister` trait has been moved to
+ `lightning` crate's `util::persist` module, which now has a general
+ `KVStorePersister` trait. Blanket implementations of `Persister` and
+ `chainmonitor::Persist` are given for types implementing `KVStorePersister`.
+ ` lightning-persister`'s `FilesystemPersister` implements `KVStorePersister`
+ (#1417).
+ * `ChannelDetails` and `ChannelCounterparty` include fields for HTLC minimum
+ and maximum values (#1378).
+ * Added a `max_inbound_htlc_value_in_flight_percent_of_channel` field to
+ `ChannelHandshakeConfig`, capping the total value of outstanding inbound
+ HTLCs for a channel (#1444).
+ * `ProbabilisticScorer` is parameterized by a `Logger`, which it uses to log
+ channel liquidity updates or lack thereof (#1405).
+ * `ChannelDetails` has an `outbound_htlc_limit_msat` field, which should be
+ used in routing instead of `outbound_capacity_msat` (#1435).
+ * `ProbabilisticScorer`'s channel liquidities can be logged via
+ `debug_log_liquidity_stats` (#1460).
+ * `BackgroundProcessor` now takes an optional `WriteableScore` which it will
+ persist using the `Persister` trait's new `persist_scorer` method (#1416).
+ * Upgraded to `bitcoin` crate version 0.28.1 (#1389).
+ * `ShutdownScript::new_witness_program` now takes a `WitnessVersion` instead of
+ a `NonZeroU8` (#1389).
+ * Channels will no longer be automatically force closed when the counterparty
+ is disconnected due to incompatibility (#1429).
+ * `ChannelManager` methods for funding, accepting, and closing channels now
+ take a `counterparty_node_id` parameter, which has also been added as a field
+ to `Event::FundingGenerationReady` (#1479, #1485).
+ * `InvoicePayer::new` now takes a `Retry` enum (replacing the `RetryAttempts`
+ struct), which supports both attempt- and timeout-based retrying (#1418).
+ * `Score::channel_penalty_msat` takes a `ChannelUsage` struct, which contains
+ the capacity as an `EffectiveCapacity` enum and any potential in-flight HTLC
+ value, rather than a single `u64`. Used by `ProbabilisticScorer` for more
+ accurate penalties (#1456).
+ * `build_route_from_hops` is a new function useful for constructing a `Route`
+ given a specific list of public keys (#1491).
+ * `FundingLocked` message has been renamed `ChannelReady`, and related
+ identifiers have been renamed accordingly (#1506).
+ * `core2::io` or `std::io` (depending on feature flags `no-std` or `std`) is
+ exported as a `lightning::io` module (#1504).
+ * The deprecated `Scorer` has been removed in favor or `ProbabilisticScorer`
+ (#1512).
+
+## Performance Improvements
+ * `lightning-persister` crate's `FilesystemPersister` is faster by 15x (#1404).
+ * Log gossip query messages at `GOSSIP` instead of `TRACE` to avoid
+ overwhelming default logging (#1421).
+ * `PeerManager` supports processing messages from different peers in parallel,
+ and this is taken advantage of in gossip processing (#1023).
+ * Greatly reduced per-channel and per-node memory usage due to upgrade of
+ `secp256k1` crate to 0.22.1 and `bitcoin` crate to 0.28.1
+ * Reduced per-peer memory usage in `PeerManager` (#1472).
+
+## Spec Compliance
+ * `find_route` now assumes variable-length onions by default for nodes where
+ support for the feature is unknown (#1414).
+ * A `warn` message is now sent when receiving a `channel_reestablish` with an
+ old commitment transaction number rather than immediately force-closing the
+ channel (#1430).
+ * When a `channel_update` message is included in an onion error's `failuremsg`,
+ its message type is now encoded. Reading such messages is also supported
+ (#1465).
+
+## Bug Fixes
+ * Fixed a bug where crashing while persisting a `ChannelMonitorUpdate` for a
+ part of a multi-path payment could cause loss of funds due to a partial
+ payment claim on restart (#1434).
+ * `BackgroundProcessor` has been fixed to improve serialization reliability on
+ slow systems which can avoid force-closes (#1436).
+ * `gossip_timestamp_filter` filters are now honored when sending gossip to
+ peers (#1452).
+ * During a reorg, only force-close a channel if its funding transaction is
+ unconfirmed rather than as it loses confirmations (#1461).
+ * Fixed a rare panic in `lightning-net-tokio` when fetching a peer's socket
+ address after the connection has been closed caused by a race condition
+ (#1449).
+ * `find_route` will no longer return routes that would cause onion construction
+ to fail in some cases (#1476).
+ * `ProbabilisticScorer` uses more precision when approximating `log10` (#1406).
+
+## Serialization Compatibility
+ * All above new events/fields are ignored by prior clients. All above new
+ events/fields are not present when reading objects serialized by prior
+ versions of the library.
+ * `ChannelManager` serialization is no longer compatible with versions prior to
+ 0.0.99 (#1401).
+ * Channels with `option_zeroconf` feature enabled (not required for 0-conf
+ channel use) will be unreadable by versions prior to 0.0.107 (#1401, #1505).
+
+In total, this release features 96 files changed, 9304 insertions, 4503
+deletions in 153 commits from 18 authors, in alphabetical order:
+ * Arik Sosman
+ * Devrandom
+ * Duncan Dean
+ * Elias Rohrer
+ * Jeffrey Czyz
+ * John Cantrell
+ * John Corser
+ * Jurvis Tan
+ * Justin Moon
+ * KaFai Choi
+ * Mateusz Faltyn
+ * Matt Corallo
+ * Valentine Wallace
+ * Viktor Tigerström
+ * Vincenzo Palazzo
+ * atalw
+ * dependabot[bot]
+ * shamardy
+
+
# 0.0.106 - 2022-04-03
## API Updates
this is a simple alternative to implementing the required network stack, especially for those already using Tokio.
6. [lightning-persister](./lightning-persister)
Utilities to manage Rust-Lightning channel data persistence and retrieval.
+7. [lightning-rapid-gossip-sync](./lightning-rapid-gossip-sync)
+ Client for rapid gossip graph syncing, aimed primarily at mobile clients.
About
-----------
[package]
name = "lightning-background-processor"
-version = "0.0.106"
+version = "0.0.108"
authors = ["Valentine Wallace <vwallace@protonmail.com>"]
license = "MIT OR Apache-2.0"
repository = "http://github.com/lightningdevkit/rust-lightning"
[dependencies]
bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning", features = ["std"] }
-lightning-rapid-gossip-sync = { version = "0.0.106", path = "../lightning-rapid-gossip-sync" }
+lightning = { version = "0.0.108", path = "../lightning", features = ["std"] }
+lightning-rapid-gossip-sync = { version = "0.0.108", path = "../lightning-rapid-gossip-sync" }
[dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", features = ["_test_utils"] }
-lightning-invoice = { version = "0.14.0", path = "../lightning-invoice" }
-lightning-persister = { version = "0.0.106", path = "../lightning-persister" }
+lightning = { version = "0.0.108", path = "../lightning", features = ["_test_utils"] }
+lightning-invoice = { version = "0.16.0", path = "../lightning-invoice" }
+lightning-persister = { version = "0.0.108", path = "../lightning-persister" }
/// Prune the network graph of stale entries hourly.
const NETWORK_PRUNE_TIMER: u64 = 60 * 60;
-#[cfg(all(not(test), debug_assertions))]
+#[cfg(not(test))]
const SCORER_PERSIST_TIMER: u64 = 30;
#[cfg(test)]
const SCORER_PERSIST_TIMER: u64 = 1;
[package]
name = "lightning-block-sync"
-version = "0.0.106"
+version = "0.0.108"
authors = ["Jeffrey Czyz", "Matt Corallo"]
license = "MIT OR Apache-2.0"
repository = "http://github.com/lightningdevkit/rust-lightning"
[dependencies]
bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
futures = { version = "0.3" }
tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
[package]
name = "lightning-invoice"
description = "Data structures to parse and serialize BOLT11 lightning invoices"
-version = "0.14.0"
+version = "0.16.0"
authors = ["Sebastian Geisler <sgeisler@wh2.tu-dresden.de>"]
documentation = "https://docs.rs/lightning-invoice/"
license = "MIT OR Apache-2.0"
[dependencies]
bech32 = { version = "0.8", default-features = false }
-lightning = { version = "0.0.106", path = "../lightning", default-features = false }
+lightning = { version = "0.0.108", path = "../lightning", default-features = false }
secp256k1 = { version = "0.22", default-features = false, features = ["recovery", "alloc"] }
num-traits = { version = "0.2.8", default-features = false }
bitcoin_hashes = { version = "0.10", default-features = false }
core2 = { version = "0.3.0", default-features = false, optional = true }
[dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", default-features = false, features = ["_test_utils"] }
+lightning = { version = "0.0.108", path = "../lightning", default-features = false, features = ["_test_utils"] }
hex = "0.4"
[package]
name = "lightning-net-tokio"
-version = "0.0.106"
+version = "0.0.108"
authors = ["Matt Corallo"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/lightningdevkit/rust-lightning/"
[dependencies]
bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }
[dev-dependencies]
[package]
name = "lightning-persister"
-version = "0.0.106"
+version = "0.0.108"
authors = ["Valentine Wallace", "Matt Corallo"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/lightningdevkit/rust-lightning/"
[dependencies]
bitcoin = "0.28.1"
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
libc = "0.2"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winbase"] }
[dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", features = ["_test_utils"] }
+lightning = { version = "0.0.108", path = "../lightning", features = ["_test_utils"] }
[package]
name = "lightning-rapid-gossip-sync"
-version = "0.0.106"
+version = "0.0.108"
authors = ["Arik Sosman <git@arik.io>"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/lightningdevkit/rust-lightning"
_bench_unstable = []
[dependencies]
-lightning = { version = "0.0.106", path = "../lightning" }
+lightning = { version = "0.0.108", path = "../lightning" }
bitcoin = { version = "0.28.1", default-features = false }
[dev-dependencies]
-lightning = { version = "0.0.106", path = "../lightning", features = ["_test_utils"] }
+lightning = { version = "0.0.108", path = "../lightning", features = ["_test_utils"] }
[package]
name = "lightning"
-version = "0.0.106"
+version = "0.0.108"
authors = ["Matt Corallo"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/lightningdevkit/rust-lightning/"
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurChannelReady as u32) {
// We got a reorg but not enough to trigger a force close, just ignore.
false
- } else if self.channel_state < ChannelState::ChannelFunded as u32 {
- panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
} else {
+ if self.channel_state < ChannelState::ChannelFunded as u32 {
+ // We should never see a funding transaction on-chain until we've received
+ // funding_signed (if we're an outbound channel), or seen funding_generated (if we're
+ // an inbound channel - before that we have no known funding TXID). The fuzzer,
+ // however, may do this and we shouldn't treat it as a bug.
+ #[cfg(not(fuzzing))]
+ panic!("Started confirming a channel in a state pre-FundingSent: {}.\n\
+ Do NOT broadcast a funding transaction manually - let LDK do it for you!",
+ self.channel_state);
+ }
// We got a reorg but not enough to trigger a force close, just ignore.
false
};
// Fail a list of HTLCs that were just freed from the holding cell. The HTLCs need to be
// failed backwards or, if they were one of our outgoing HTLCs, then their failure needs to
// be surfaced to the user.
- fn fail_holding_cell_htlcs(&self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32]) {
+ fn fail_holding_cell_htlcs(
+ &self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32],
+ _counterparty_node_id: &PublicKey
+ ) {
for (htlc_src, payment_hash) in htlcs_to_fail.drain(..) {
match htlc_src {
HTLCSource::PreviousHopData(HTLCPreviousHopData { .. }) => {
hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
}
};
- self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id);
+ self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id);
match res {
Ok((pending_forwards, mut pending_failures, finalized_claim_htlcs,
short_channel_id, channel_outpoint)) =>
}
};
post_handle_chan_restoration!(self, chan_restoration_res);
- self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id);
+ self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id, counterparty_node_id);
if let Some(channel_ready_msg) = need_lnd_workaround {
self.internal_channel_ready(counterparty_node_id, &channel_ready_msg)?;
match chan.maybe_free_holding_cell_htlcs(&self.logger) {
Ok((commitment_opt, holding_cell_failed_htlcs)) => {
if !holding_cell_failed_htlcs.is_empty() {
- failed_htlcs.push((holding_cell_failed_htlcs, *channel_id));
+ failed_htlcs.push((
+ holding_cell_failed_htlcs,
+ *channel_id,
+ chan.get_counterparty_node_id()
+ ));
}
if let Some((commitment_update, monitor_update)) = commitment_opt {
if let Err(e) = self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) {
}
let has_update = has_monitor_update || !failed_htlcs.is_empty() || !handle_errors.is_empty();
- for (failures, channel_id) in failed_htlcs.drain(..) {
- self.fail_holding_cell_htlcs(failures, channel_id);
+ for (failures, channel_id, counterparty_node_id) in failed_htlcs.drain(..) {
+ self.fail_holding_cell_htlcs(failures, channel_id, &counterparty_node_id);
}
for (counterparty_node_id, err) in handle_errors.drain(..) {
use chain::transaction::OutPoint;
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
-use routing::gossip::{P2PGossipSync, NetworkGraph};
+use routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
use routing::router::{PaymentParameters, Route, get_route};
use ln::features::{InitFeatures, InvoiceFeatures};
use ln::msgs;
#[cfg(test)]
macro_rules! expect_payment_failed_with_update {
($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr, $scid: expr, $chan_closed: expr) => {
- expect_payment_failed_conditions!($node, $expected_payment_hash, $rejected_by_dest,
- $crate::ln::functional_test_utils::PaymentFailedConditions::new().blamed_scid($scid).blamed_chan_closed($chan_closed));
+ $crate::ln::functional_test_utils::expect_payment_failed_conditions(
+ &$node, $expected_payment_hash, $rejected_by_dest,
+ $crate::ln::functional_test_utils::PaymentFailedConditions::new()
+ .blamed_scid($scid).blamed_chan_closed($chan_closed));
}
}
$(
conditions = conditions.expected_htlc_error_data($expected_error_code, &$expected_error_data);
)*
- expect_payment_failed_conditions!($node, $expected_payment_hash, $rejected_by_dest, conditions);
+ $crate::ln::functional_test_utils::expect_payment_failed_conditions(&$node, $expected_payment_hash, $rejected_by_dest, conditions);
};
}
-#[cfg(test)]
-macro_rules! expect_payment_failed_conditions {
- ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr, $conditions: expr) => {
- let events = $node.node.get_and_clear_pending_events();
- assert_eq!(events.len(), 1);
- let expected_payment_id = match events[0] {
- Event::PaymentPathFailed { ref payment_hash, rejected_by_dest, ref error_code, ref error_data, ref path, ref retry, ref payment_id, ref network_update, .. } => {
- assert_eq!(*payment_hash, $expected_payment_hash, "unexpected payment_hash");
- assert_eq!(rejected_by_dest, $rejected_by_dest, "unexpected rejected_by_dest value");
- assert!(retry.is_some(), "expected retry.is_some()");
- assert_eq!(retry.as_ref().unwrap().final_value_msat, path.last().unwrap().fee_msat, "Retry amount should match last hop in path");
- assert_eq!(retry.as_ref().unwrap().payment_params.payee_pubkey, path.last().unwrap().pubkey, "Retry payee node_id should match last hop in path");
-
+pub fn expect_payment_failed_conditions<'a, 'b, 'c, 'd, 'e>(
+ node: &'a Node<'b, 'c, 'd>, expected_payment_hash: PaymentHash, expected_rejected_by_dest: bool,
+ conditions: PaymentFailedConditions<'e>
+) {
+ let mut events = node.node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ let expected_payment_id = match events.pop().unwrap() {
+ Event::PaymentPathFailed { payment_hash, rejected_by_dest, path, retry, payment_id, network_update,
+ #[cfg(test)]
+ error_code,
+ #[cfg(test)]
+ error_data, .. } => {
+ assert_eq!(payment_hash, expected_payment_hash, "unexpected payment_hash");
+ assert_eq!(rejected_by_dest, expected_rejected_by_dest, "unexpected rejected_by_dest value");
+ assert!(retry.is_some(), "expected retry.is_some()");
+ assert_eq!(retry.as_ref().unwrap().final_value_msat, path.last().unwrap().fee_msat, "Retry amount should match last hop in path");
+ assert_eq!(retry.as_ref().unwrap().payment_params.payee_pubkey, path.last().unwrap().pubkey, "Retry payee node_id should match last hop in path");
+
+ #[cfg(test)]
+ {
assert!(error_code.is_some(), "expected error_code.is_some() = true");
assert!(error_data.is_some(), "expected error_data.is_some() = true");
- if let Some((code, data)) = $conditions.expected_htlc_error_data {
+ if let Some((code, data)) = conditions.expected_htlc_error_data {
assert_eq!(error_code.unwrap(), code, "unexpected error code");
assert_eq!(&error_data.as_ref().unwrap()[..], data, "unexpected error data");
}
+ }
- if let Some(chan_closed) = $conditions.expected_blamed_chan_closed {
- match network_update {
- &Some($crate::routing::gossip::NetworkUpdate::ChannelUpdateMessage { ref msg }) if !chan_closed => {
- if let Some(scid) = $conditions.expected_blamed_scid {
- assert_eq!(msg.contents.short_channel_id, scid);
- }
- assert_eq!(msg.contents.flags & 2, 0);
- },
- &Some($crate::routing::gossip::NetworkUpdate::ChannelFailure { short_channel_id, is_permanent }) if chan_closed => {
- if let Some(scid) = $conditions.expected_blamed_scid {
- assert_eq!(short_channel_id, scid);
- }
- assert!(is_permanent);
- },
- Some(_) => panic!("Unexpected update type"),
- None => panic!("Expected update"),
- }
+ if let Some(chan_closed) = conditions.expected_blamed_chan_closed {
+ match network_update {
+ Some(NetworkUpdate::ChannelUpdateMessage { ref msg }) if !chan_closed => {
+ if let Some(scid) = conditions.expected_blamed_scid {
+ assert_eq!(msg.contents.short_channel_id, scid);
+ }
+ const CHAN_DISABLED_FLAG: u8 = 2;
+ assert_eq!(msg.contents.flags & CHAN_DISABLED_FLAG, 0);
+ },
+ Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent }) if chan_closed => {
+ if let Some(scid) = conditions.expected_blamed_scid {
+ assert_eq!(short_channel_id, scid);
+ }
+ assert!(is_permanent);
+ },
+ Some(_) => panic!("Unexpected update type"),
+ None => panic!("Expected update"),
}
+ }
- payment_id.unwrap()
- },
- _ => panic!("Unexpected event"),
- };
- if !$conditions.expected_mpp_parts_remain {
- $node.node.abandon_payment(expected_payment_id);
- let events = $node.node.get_and_clear_pending_events();
- assert_eq!(events.len(), 1);
- match events[0] {
- Event::PaymentFailed { ref payment_hash, ref payment_id } => {
- assert_eq!(*payment_hash, $expected_payment_hash, "unexpected second payment_hash");
- assert_eq!(*payment_id, expected_payment_id);
- }
- _ => panic!("Unexpected second event"),
+ payment_id.unwrap()
+ },
+ _ => panic!("Unexpected event"),
+ };
+ if !conditions.expected_mpp_parts_remain {
+ node.node.abandon_payment(expected_payment_id);
+ let events = node.node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ Event::PaymentFailed { ref payment_hash, ref payment_id } => {
+ assert_eq!(*payment_hash, expected_payment_hash, "unexpected second payment_hash");
+ assert_eq!(*payment_id, expected_payment_id);
}
+ _ => panic!("Unexpected second event"),
}
}
}
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates_1.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], fail_updates_1.commitment_signed, false);
- expect_payment_failed_conditions!(nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
+ expect_payment_failed_conditions(&nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
}
nodes[0].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &fail_updates_2.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[2], fail_updates_2.commitment_signed, false);
- expect_payment_failed_conditions!(nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
+ expect_payment_failed_conditions(&nodes[0], our_payment_hash, true, PaymentFailedConditions::new().mpp_parts_remain());
nodes[0].node.send_payment_along_path(&route.paths[1], &payment_params_opt, &our_payment_hash, &Some(our_payment_secret), 15_000_000, cur_height, payment_id, &None).unwrap();
check_added_monitors!(nodes[0], 1);
.blamed_scid(phantom_scid)
.blamed_chan_closed(true)
.expected_htlc_error_data(0x8000 | 0x4000 | 5, &sha256_of_onion);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}
#[test]
.blamed_scid(phantom_scid)
.blamed_chan_closed(true)
.expected_htlc_error_data(0x4000 | 22, &error_data);
- expect_payment_failed_conditions!(nodes[0], payment_hash, true, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
}
#[test]
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(18, &error_data);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}
#[test]
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(17, &error_data);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}
#[test]
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x4000 | 15, &error_data);
- expect_payment_failed_conditions!(nodes[0], payment_hash, true, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
}
#[test]
.blamed_scid(channel.0.contents.short_channel_id)
.blamed_chan_closed(false)
.expected_htlc_error_data(0x1000 | 7, &err_data);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
}
#[test]
let mut fail_conditions = PaymentFailedConditions::new()
.blamed_scid(phantom_scid)
.expected_htlc_error_data(0x4000 | 15, &error_data);
- expect_payment_failed_conditions!(nodes[0], payment_hash, true, fail_conditions);
+ expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
}
check_added_monitors!(nodes[1], 1);
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], htlc_updates.commitment_signed, false);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
// Rebalance the channel so the retry succeeds.
send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
check_added_monitors!(nodes[2], 1);
nodes[0].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[2], htlc_updates.commitment_signed, false);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
// Rebalance the channel so the second half of the payment can succeed.
send_payment(&nodes[3], &vec!(&nodes[2])[..], 1_500_000);
check_added_monitors!(nodes[1], 1);
commitment_signed_dance!(nodes[0], nodes[1], htlc_fail_updates_1_0.commitment_signed, false);
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..]));
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..]));
} else {
// Pass half of the payment along the second path.
pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash, Some(payment_secret), events.remove(0), true, None);
confirm_transaction(&nodes[0], &first_htlc_timeout_tx);
}
nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
- expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain());
// Finally, retry the payment (which was reloaded from the ChannelMonitor when nodes[0] was
// reloaded) via a route over the new channel, which work without issue and eventually be
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], updates.commitment_signed, false);
- expect_payment_failed_conditions!(nodes[0], payment_hash_2, false,
+ expect_payment_failed_conditions(&nodes[0], payment_hash_2, false,
PaymentFailedConditions::new().blamed_scid(last_hop[0].short_channel_id.unwrap())
.blamed_chan_closed(true).expected_htlc_error_data(0x4000|10, &[0; 0]));
}
err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
err_data.extend_from_slice(&msg.encode());
- expect_payment_failed_conditions!(nodes[0], payment_hash, false,
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false,
PaymentFailedConditions::new().blamed_scid(last_hop[0].inbound_scid_alias.unwrap())
.blamed_chan_closed(false).expected_htlc_error_data(0x1000|7, &err_data));
err_data.extend_from_slice(&(msg.serialized_length() as u16 + 2).to_be_bytes());
err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
err_data.extend_from_slice(&msg.encode());
- expect_payment_failed_conditions!(nodes[0], payment_hash, false,
+ expect_payment_failed_conditions(&nodes[0], payment_hash, false,
PaymentFailedConditions::new().blamed_scid(last_hop[0].inbound_scid_alias.unwrap())
.blamed_chan_closed(false).expected_htlc_error_data(0x1000|12, &err_data));
}