Skip to content

Commit a128b5e

Browse files
committed
code cleanup
1 parent 8c1882b commit a128b5e

File tree

5 files changed

+135
-99
lines changed

5 files changed

+135
-99
lines changed

crates/fiber-lib/src/fiber/channel.rs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -899,14 +899,13 @@ where
899899
) {
900900
let tlc_info = state.get_received_tlc(tlc_id).expect("expect tlc").clone();
901901

902-
let preimage = self.store.get_preimage(&tlc_info.payment_hash);
903902
let parent_payment_hash = tlc_info
904903
.parent_payment_hash
905904
.unwrap_or(tlc_info.payment_hash);
906905
let invoice = self.store.get_invoice(&parent_payment_hash);
907-
let is_basic_mpp = invoice.as_ref().is_some_and(|inv| inv.basic_mpp());
908-
let is_atomic_mpp = invoice.as_ref().is_some_and(|inv| inv.atomic_mpp());
909-
if preimage.is_none() && !is_atomic_mpp {
906+
let mpp_mode = invoice.as_ref().and_then(|inv| inv.mpp_mode());
907+
let preimage = self.store.get_preimage(&tlc_info.payment_hash);
908+
if preimage.is_none() && !mpp_mode.is_some_and(|m| m == MppMode::AtomicMpp) {
910909
return;
911910
}
912911
let mut remove_reason = preimage.map(|preimage| {
@@ -915,21 +914,20 @@ where
915914
})
916915
});
917916

918-
let tlc = tlc_info.clone();
919917
if let Some(invoice) = invoice {
920918
let status = self.get_invoice_status(&invoice);
921919

922920
match status {
923921
CkbInvoiceStatus::Expired => {
924922
remove_reason = Some(RemoveTlcReason::RemoveTlcFail(TlcErrPacket::new(
925923
TlcErr::new(TlcErrorCode::InvoiceExpired),
926-
&tlc.shared_secret,
924+
&tlc_info.shared_secret,
927925
)));
928926
}
929927
CkbInvoiceStatus::Cancelled => {
930928
remove_reason = Some(RemoveTlcReason::RemoveTlcFail(TlcErrPacket::new(
931929
TlcErr::new(TlcErrorCode::InvoiceCancelled),
932-
&tlc.shared_secret,
930+
&tlc_info.shared_secret,
933931
)));
934932
}
935933
CkbInvoiceStatus::Paid => {
@@ -938,36 +936,30 @@ where
938936
error!("invoice already paid, ignore");
939937
return;
940938
}
941-
_ if is_basic_mpp || is_atomic_mpp => {
939+
_ if mpp_mode.is_some() => {
942940
// add to pending settlement tlc set
943941
// the tlc set will be settled by network actor
944-
state.pending_notify_mpp_tcls.push((
945-
parent_payment_hash,
946-
tlc.id(),
947-
if is_basic_mpp {
948-
MppMode::BasicMpp
949-
} else {
950-
MppMode::AtomicMpp
951-
},
952-
));
942+
state
943+
.pending_notify_mpp_tcls
944+
.push((parent_payment_hash, tlc_info.id()));
953945

954946
// just return, the tlc set will be settled by network actor
955947
return;
956948
}
957949
_ => {
958950
// single path payment
959-
if !is_invoice_fulfilled(&invoice, std::slice::from_ref(&tlc)) {
951+
if !is_invoice_fulfilled(&invoice, std::slice::from_ref(&tlc_info)) {
960952
remove_reason = Some(RemoveTlcReason::RemoveTlcFail(TlcErrPacket::new(
961953
TlcErr::new(TlcErrorCode::IncorrectOrUnknownPaymentDetails),
962-
&tlc.shared_secret,
954+
&tlc_info.shared_secret,
963955
)));
964956
}
965957
}
966958
}
967959
}
968960
// remove tlc
969961
if let Some(remove_reason) = remove_reason {
970-
self.register_retryable_tlc_remove(myself, state, tlc.tlc_id, remove_reason)
962+
self.register_retryable_tlc_remove(myself, state, tlc_info.tlc_id, remove_reason)
971963
.await;
972964
}
973965
}
@@ -1107,7 +1099,7 @@ where
11071099
tlc.payment_secret = Some(record.payment_secret);
11081100
tlc.total_amount = Some(record.total_amount);
11091101
}
1110-
(Some(invoice), None, Some(record)) => {
1102+
(Some(invoice), None, Some(record)) if invoice.atomic_mpp() => {
11111103
tlc.total_amount = Some(invoice.amount.unwrap_or_default());
11121104
tlc.parent_payment_hash = Some(parent_payment_hash);
11131105
let mut amp_record = record.clone();
@@ -2744,7 +2736,7 @@ where
27442736
self.store.insert_channel_actor_state(state.clone());
27452737

27462738
// try to settle down tlc set
2747-
for (payment_hash, tlc_id, mpp_mode) in pending_notify_mpp_tcls {
2739+
for (payment_hash, tlc_id) in pending_notify_mpp_tcls {
27482740
let channel_id = state.get_id();
27492741
// hold the tlc
27502742
self.store.insert_payment_hold_tlc(
@@ -2753,7 +2745,6 @@ where
27532745
channel_id,
27542746
tlc_id,
27552747
hold_expire_at: now_timestamp_as_millis_u64() + DEFAULT_HOLD_TLC_TIMEOUT,
2756-
mpp_mode,
27572748
},
27582749
);
27592750

@@ -3741,7 +3732,7 @@ pub struct ChannelActorState {
37413732

37423733
// The TLC set ready to be settled
37433734
#[serde(skip)]
3744-
pub pending_notify_mpp_tcls: Vec<(Hash256, u64, MppMode)>,
3735+
pub pending_notify_mpp_tcls: Vec<(Hash256, u64)>,
37453736

37463737
#[serde(skip)]
37473738
pub ephemeral_config: ChannelEphemeralConfig,

crates/fiber-lib/src/fiber/network.rs

Lines changed: 94 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,21 +1663,6 @@ where
16631663
}
16641664
NetworkActorCommand::SettleMPPTlcSet(payment_hash) => {
16651665
let hold_tlcs = self.store.get_payment_hold_tlcs(payment_hash);
1666-
// check all hold tlcs mpp_mode is same
1667-
let mpp_modes: HashSet<_> =
1668-
hold_tlcs.iter().map(|hold_tlc| hold_tlc.mpp_mode).collect();
1669-
if mpp_modes.len() > 1 {
1670-
error!(
1671-
"payment_hash {:?} have different mpp_mode, cannot settle",
1672-
payment_hash
1673-
);
1674-
return Ok(());
1675-
}
1676-
let Some(mpp_mode) = mpp_modes.iter().next().cloned() else {
1677-
error!("payment_hash {:?} have not hold tlcs", payment_hash);
1678-
return Ok(());
1679-
};
1680-
16811666
// load hold tlcs
16821667
let tlcs: Vec<_> = hold_tlcs
16831668
.iter()
@@ -1690,86 +1675,132 @@ where
16901675

16911676
let mut tlc_fail = None;
16921677
let mut hash_algorithm = HashAlgorithm::default();
1678+
let mut tlc_preimage_map = HashMap::new();
1679+
1680+
// we generally set all validation error as IncorrectOrUnknownPaymentDetails, this failure
1681+
// is expected to be the scenarios malicious sender have sent a inconsistent data with MPP
1682+
'validation: {
1683+
// check if all tlcs have the same total amount
1684+
if tlcs.len() > 1
1685+
&& !tlcs
1686+
.windows(2)
1687+
.all(|w| w[0].total_amount == w[1].total_amount)
1688+
{
1689+
error!("TLCs have inconsistent total_amount: {:?}", tlcs);
1690+
tlc_fail =
1691+
Some(TlcErr::new(TlcErrorCode::IncorrectOrUnknownPaymentDetails));
1692+
break 'validation;
1693+
}
16931694

1694-
// check if all tlcs have the same total amount
1695-
if tlcs.len() > 1
1696-
&& !tlcs
1697-
.windows(2)
1698-
.all(|w| w[0].total_amount == w[1].total_amount)
1699-
{
1700-
error!("TLCs have inconsistent total_amount: {:?}", tlcs);
1701-
tlc_fail = Some(TlcErr::new(TlcErrorCode::IncorrectOrUnknownPaymentDetails));
1702-
} else {
17031695
// check if tlc set are fulfilled
1704-
let Some(invoice) = self.store.get_invoice(&payment_hash) else {
1696+
let invoice = self.store.get_invoice(&payment_hash);
1697+
let Some(invoice) = invoice else {
17051698
error!(
17061699
"Try to settle mpp tlc set, but invoice not found for payment hash {:?}",
17071700
payment_hash
17081701
);
1709-
return Ok(());
1702+
tlc_fail =
1703+
Some(TlcErr::new(TlcErrorCode::IncorrectOrUnknownPaymentDetails));
1704+
break 'validation;
1705+
};
1706+
1707+
let Some(mpp_mode) = invoice.mpp_mode() else {
1708+
error!("try to settle down mpp payment_hash: {:?} while the invoice does no support MPP", payment_hash);
1709+
tlc_fail =
1710+
Some(TlcErr::new(TlcErrorCode::IncorrectOrUnknownPaymentDetails));
1711+
break 'validation;
17101712
};
1711-
// just return if invoice is not fulfilled
1713+
17121714
if !is_invoice_fulfilled(&invoice, &tlcs) {
17131715
return Ok(());
17141716
}
1717+
17151718
hash_algorithm = invoice.hash_algorithm().cloned().unwrap_or(hash_algorithm);
1716-
}
1717-
let mut tlc_preimages = HashMap::new();
1718-
match mpp_mode {
1719-
MppMode::BasicMpp => {
1720-
let Some(preimage) = self.store.get_preimage(&payment_hash) else {
1721-
error!(
1722-
"basic MPP can not get preimage for payment: {:?}",
1723-
payment_hash
1724-
);
1725-
return Ok(());
1726-
};
1727-
for tlc in tlcs.iter() {
1728-
tlc_preimages.insert((tlc.channel_id, tlc.id()), preimage);
1729-
}
1730-
}
1731-
MppMode::AtomicMpp => {
1732-
let mut atomic_mpp_data =
1733-
self.store.get_atomic_mpp_payment_data(&payment_hash);
1734-
if atomic_mpp_data.len() != tlcs.len() {
1735-
error!(
1736-
"atomic mpp don't have enough mpp data for payment_hash: {:?}",
1737-
payment_hash
1738-
);
1719+
// Generate preimages based on MPP mode
1720+
match mpp_mode {
1721+
MppMode::BasicMpp => {
1722+
let Some(preimage) = self.store.get_preimage(&payment_hash) else {
1723+
error!(
1724+
"basic MPP can not get preimage for payment: {:?}",
1725+
payment_hash
1726+
);
1727+
tlc_fail = Some(TlcErr::new(
1728+
TlcErrorCode::IncorrectOrUnknownPaymentDetails,
1729+
));
1730+
break 'validation;
1731+
};
1732+
1733+
for tlc in tlcs.iter() {
1734+
tlc_preimage_map.insert((tlc.channel_id, tlc.id()), preimage);
1735+
}
17391736
}
1740-
atomic_mpp_data.sort_by(|a, b| a.1.index.cmp(&b.1.index));
1741-
let child_descs: Vec<ChildDesc> = atomic_mpp_data
1742-
.iter()
1743-
.map(|(_, data)| ChildDesc::new(data.secret, data.index))
1744-
.collect();
1745-
let children = reconstruct_children(&child_descs, hash_algorithm);
1746-
debug_assert_eq!(child_descs.len(), children.len());
1747-
for (((channel_id, tlc_id), _), child) in
1748-
atomic_mpp_data.iter().zip(children.iter())
1749-
{
1750-
tlc_preimages.insert((*channel_id, *tlc_id), child.preimage);
1737+
MppMode::AtomicMpp => {
1738+
let mut atomic_mpp_data =
1739+
self.store.get_atomic_mpp_payment_data(&payment_hash);
1740+
1741+
if atomic_mpp_data.len() != tlcs.len() {
1742+
error!(
1743+
"atomic mpp don't have enough mpp data for payment_hash: {:?}",
1744+
payment_hash
1745+
);
1746+
tlc_fail = Some(TlcErr::new(
1747+
TlcErrorCode::IncorrectOrUnknownPaymentDetails,
1748+
));
1749+
break 'validation;
1750+
}
1751+
1752+
atomic_mpp_data.sort_by(|a, b| a.1.index.cmp(&b.1.index));
1753+
let index: Vec<u16> =
1754+
atomic_mpp_data.iter().map(|a| a.1.index).collect();
1755+
let expected_index: Vec<u16> = (0..tlcs.len() as u16).collect();
1756+
1757+
if index != expected_index {
1758+
error!(
1759+
"atomic mpp index are not expected for payment_hash: {:?}",
1760+
payment_hash
1761+
);
1762+
tlc_fail = Some(TlcErr::new(
1763+
TlcErrorCode::IncorrectOrUnknownPaymentDetails,
1764+
));
1765+
break 'validation;
1766+
}
1767+
1768+
let child_descs: Vec<ChildDesc> = atomic_mpp_data
1769+
.iter()
1770+
.map(|(_, data)| ChildDesc::new(data.secret, data.index))
1771+
.collect();
1772+
let children = reconstruct_children(&child_descs, hash_algorithm);
1773+
debug_assert_eq!(child_descs.len(), children.len());
1774+
1775+
for (((channel_id, tlc_id), _), child) in
1776+
atomic_mpp_data.iter().zip(children.iter())
1777+
{
1778+
tlc_preimage_map.insert((*channel_id, *tlc_id), child.preimage);
1779+
}
17511780
}
17521781
}
1753-
}
1782+
} // end of 'validation block
17541783

17551784
// remove tlcs
17561785
for tlc in tlcs {
17571786
let (send, _recv) = oneshot::channel();
17581787
let rpc_reply = RpcReplyPort::from(send);
1788+
17591789
let remove_reason = match tlc_fail.clone() {
17601790
Some(tlc_fail) => RemoveTlcReason::RemoveTlcFail(TlcErrPacket::new(
17611791
tlc_fail,
17621792
&tlc.shared_secret,
17631793
)),
17641794
None => {
1765-
let preimage = *tlc_preimages
1795+
let preimage = *tlc_preimage_map
17661796
.get(&(tlc.channel_id, tlc.id()))
17671797
.expect("must got preimage");
17681798
RemoveTlcReason::RemoveTlcFulfill(RemoveTlcFulfill {
17691799
payment_preimage: preimage,
17701800
})
17711801
}
17721802
};
1803+
17731804
match state
17741805
.send_command_to_channel(
17751806
tlc.channel_id,

crates/fiber-lib/src/fiber/types.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use crate::ckb::config::{UdtArgInfo, UdtCellDep, UdtCfgInfos, UdtDep, UdtScript}
1414
use crate::ckb::contracts::get_udt_whitelist;
1515
use crate::fiber::amp::Share;
1616
use crate::fiber::network::USER_CUSTOM_RECORDS_MAX_INDEX;
17-
use crate::fiber::payment::MppMode;
1817
use ckb_jsonrpc_types::CellOutput;
1918
use ckb_types::H256;
2019
use num_enum::IntoPrimitive;
@@ -4253,5 +4252,4 @@ pub struct HoldTlc {
42534252
pub channel_id: Hash256,
42544253
pub tlc_id: u64,
42554254
pub hold_expire_at: u64,
4256-
pub mpp_mode: MppMode,
42574255
}

crates/fiber-lib/src/invoice/invoice_impl.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::utils::*;
33
use crate::fiber::features::FeatureVector;
44
use crate::fiber::gen::invoice::{self as gen_invoice, *};
55
use crate::fiber::hash_algorithm::HashAlgorithm;
6+
use crate::fiber::payment::MppMode;
67
use crate::fiber::serde_utils::{duration_hex, EntityHex, U128Hex, U64Hex};
78
use crate::fiber::types::Hash256;
89
use crate::invoice::InvoiceError;
@@ -365,6 +366,16 @@ impl CkbInvoice {
365366
pub fn atomic_mpp(&self) -> bool {
366367
self.has_feature(|feature| feature.supports_atomic_mpp())
367368
}
369+
370+
pub fn mpp_mode(&self) -> Option<MppMode> {
371+
if self.basic_mpp() {
372+
Some(MppMode::BasicMpp)
373+
} else if self.atomic_mpp() {
374+
Some(MppMode::AtomicMpp)
375+
} else {
376+
None
377+
}
378+
}
368379
}
369380

370381
/// Recoverable signature

0 commit comments

Comments
 (0)