1use crate::crate_time::SystemTime;
4use crate::gen::fiber as molecule_fiber;
5use crate::invoice::HashAlgorithm;
6use crate::onion::{PaymentOnionPacket, TlcErrPacket, TlcErrPacketError};
7use crate::protocol::{ChannelAnnouncement, ChannelUpdate, EcdsaSignature};
8use crate::serde_utils::PartialSignatureAsBytes;
9use crate::serde_utils::PubNonceAsBytes;
10use crate::EntityHex;
11use crate::Hash256;
12use crate::Privkey;
13use crate::Pubkey;
14use bitflags::bitflags;
15use ckb_types::packed::Byte32 as MByte32;
16use ckb_types::packed::Script;
17use ckb_types::packed::Transaction;
18use ckb_types::prelude::{Pack, Unpack};
19use ckb_types::H256;
20use molecule::prelude::{Builder, Entity};
21use musig2::secp::{Point, Scalar};
22use musig2::BinaryEncoding;
23use musig2::PartialSignature;
24use musig2::PubNonce;
25use musig2::{SecNonce, SecNonceBuilder};
26use serde::{Deserialize, Serialize};
27use serde_with::serde_as;
28use std::collections::{HashMap, VecDeque};
29use std::fmt::{Debug, Formatter};
30
31bitflags! {
32 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
33 #[serde(transparent)]
34 pub struct ChannelFlags: u8 {
35 const PUBLIC = 1;
36 const ONE_WAY = 1 << 1;
37 const EXTERNAL_FUNDING = 1 << 2;
38 }
39
40 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
41 #[serde(transparent)]
42 pub struct ChannelUpdateChannelFlags: u32 {
43 const DISABLED = 1;
44 }
45
46 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
47 #[serde(transparent)]
48 pub struct ChannelUpdateMessageFlags: u32 {
49 const UPDATE_OF_NODE1 = 0;
50 const UPDATE_OF_NODE2 = 1;
51 }
52
53 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
54 #[serde(transparent)]
55 pub struct NegotiatingFundingFlags: u32 {
56 const OUR_INIT_SENT = 1;
57 const THEIR_INIT_SENT = 1 << 1;
58 const INIT_SENT = NegotiatingFundingFlags::OUR_INIT_SENT.bits() | NegotiatingFundingFlags::THEIR_INIT_SENT.bits();
59 const AWAITING_EXTERNAL_FUNDING = 1 << 2;
60 }
61
62 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
63 #[serde(transparent)]
64 pub struct CollaboratingFundingTxFlags: u32 {
65 const AWAITING_REMOTE_TX_COLLABORATION_MSG = 1;
66 const PREPARING_LOCAL_TX_COLLABORATION_MSG = 1 << 1;
67 const OUR_TX_COMPLETE_SENT = 1 << 2;
68 const THEIR_TX_COMPLETE_SENT = 1 << 3;
69 const COLLABORATION_COMPLETED = CollaboratingFundingTxFlags::OUR_TX_COMPLETE_SENT.bits() | CollaboratingFundingTxFlags::THEIR_TX_COMPLETE_SENT.bits();
70 }
71
72 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
73 #[serde(transparent)]
74 pub struct SigningCommitmentFlags: u32 {
75 const OUR_COMMITMENT_SIGNED_SENT = 1;
76 const THEIR_COMMITMENT_SIGNED_SENT = 1 << 1;
77 const COMMITMENT_SIGNED_SENT = SigningCommitmentFlags::OUR_COMMITMENT_SIGNED_SENT.bits() | SigningCommitmentFlags::THEIR_COMMITMENT_SIGNED_SENT.bits();
78 }
79
80 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
81 #[serde(transparent)]
82 pub struct AwaitingTxSignaturesFlags: u32 {
83 const OUR_TX_SIGNATURES_SENT = 1;
84 const THEIR_TX_SIGNATURES_SENT = 1 << 1;
85 const TX_SIGNATURES_SENT = AwaitingTxSignaturesFlags::OUR_TX_SIGNATURES_SENT.bits() | AwaitingTxSignaturesFlags::THEIR_TX_SIGNATURES_SENT.bits();
86 }
87
88 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
89 #[serde(transparent)]
90 pub struct AwaitingChannelReadyFlags: u32 {
91 const OUR_CHANNEL_READY = 1;
92 const THEIR_CHANNEL_READY = 1 << 1;
93 const CHANNEL_READY = AwaitingChannelReadyFlags::OUR_CHANNEL_READY.bits() | AwaitingChannelReadyFlags::THEIR_CHANNEL_READY.bits();
94 }
95
96 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
97 #[serde(transparent)]
98 pub struct ShuttingDownFlags: u32 {
99 const OUR_SHUTDOWN_SENT = 1;
100 const THEIR_SHUTDOWN_SENT = 1 << 1;
101 const AWAITING_PENDING_TLCS = ShuttingDownFlags::OUR_SHUTDOWN_SENT.bits() | ShuttingDownFlags::THEIR_SHUTDOWN_SENT.bits();
102 const DROPPING_PENDING = 1 << 2;
103 const WAITING_COMMITMENT_CONFIRMATION = 1 << 3;
104 }
105
106 #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
107 #[serde(transparent)]
108 pub struct CloseFlags: u32 {
109 const COOPERATIVE = 1;
110 const UNCOOPERATIVE_LOCAL = 1 << 1;
111 const ABANDONED = 1 << 2;
112 const FUNDING_ABORTED = 1 << 3;
113 const UNCOOPERATIVE_REMOTE = 1 << 4;
114 const WAITING_ONCHAIN_SETTLEMENT = 1 << 5;
115 const ONCHAIN_SETTLEMENT_CONFIRMED = 1 << 6;
117 }
118
119 #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
120 #[serde(transparent)]
121 pub struct AppliedFlags: u8 {
122 const ADD = 1;
123 const REMOVE = 1 << 1;
124 }
125}
126
127#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord, Hash)]
129pub enum TLCId {
130 Offered(u64),
132 Received(u64),
134}
135
136impl From<TLCId> for u64 {
137 fn from(id: TLCId) -> u64 {
138 match id {
139 TLCId::Offered(id) => id,
140 TLCId::Received(id) => id,
141 }
142 }
143}
144
145impl TLCId {
146 pub fn is_offered(&self) -> bool {
147 matches!(self, TLCId::Offered(_))
148 }
149
150 pub fn is_received(&self) -> bool {
151 !self.is_offered()
152 }
153
154 pub fn flip(&self) -> Self {
155 match self {
156 TLCId::Offered(id) => TLCId::Received(*id),
157 TLCId::Received(id) => TLCId::Offered(*id),
158 }
159 }
160
161 pub fn flip_mut(&mut self) {
162 *self = self.flip();
163 }
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
168pub enum OutboundTlcStatus {
169 LocalAnnounced,
171 Committed,
173 RemoteRemoved,
175 RemoveWaitPrevAck,
178 RemoveWaitAck,
180 RemoveAckConfirmed,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
186pub enum InboundTlcStatus {
187 RemoteAnnounced,
189 AnnounceWaitPrevAck,
192 AnnounceWaitAck,
194 Committed,
196 LocalRemoved,
198 RemoveAckConfirmed,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
204pub enum TlcStatus {
205 Outbound(OutboundTlcStatus),
207 Inbound(InboundTlcStatus),
209}
210
211impl TlcStatus {
212 pub fn as_outbound_status(&self) -> OutboundTlcStatus {
213 match self {
214 TlcStatus::Outbound(status) => status.clone(),
215 _ => {
216 unreachable!("unexpected status")
217 }
218 }
219 }
220
221 pub fn as_inbound_status(&self) -> InboundTlcStatus {
222 match self {
223 TlcStatus::Inbound(status) => status.clone(),
224 _ => {
225 unreachable!("unexpected status ")
226 }
227 }
228 }
229}
230
231#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
238pub enum ChannelState {
239 NegotiatingFunding(NegotiatingFundingFlags),
244 CollaboratingFundingTx(CollaboratingFundingTxFlags),
246 SigningCommitment(SigningCommitmentFlags),
248 AwaitingTxSignatures(AwaitingTxSignaturesFlags),
251 AwaitingChannelReady(AwaitingChannelReadyFlags),
254 ChannelReady,
257 ShuttingDown(ShuttingDownFlags),
259 Closed(CloseFlags),
261 Stale,
264}
265
266#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
267pub enum ChannelConnectivityState {
268 Online,
269 Offline,
270 Syncing,
271}
272
273#[serde_as]
274#[derive(Clone, Debug, Serialize, Deserialize)]
275pub struct ExternalFundingPersistState {
276 #[serde_as(as = "EntityHex")]
277 pub funding_lock_script: Script,
278 #[serde_as(as = "Vec<EntityHex>")]
279 pub funding_lock_script_cell_deps: Vec<ckb_types::packed::CellDep>,
280 #[serde_as(as = "EntityHex")]
281 pub unsigned_funding_tx: Transaction,
282 pub started_at_ms: u64,
283 pub signed_submitted: bool,
284 pub peer_commitment_signed_received: bool,
285}
286
287impl ChannelState {
288 pub fn is_awaiting_external_funding(&self) -> bool {
289 matches!(
290 self,
291 ChannelState::NegotiatingFunding(flags)
292 if flags.contains(NegotiatingFundingFlags::AWAITING_EXTERNAL_FUNDING)
293 )
294 }
295
296 pub fn is_closed(&self) -> bool {
297 matches!(
298 self,
299 ChannelState::Closed(_)
300 | ChannelState::ShuttingDown(ShuttingDownFlags::WAITING_COMMITMENT_CONFIRMATION)
301 )
302 }
303
304 pub fn can_abort_funding(&self) -> bool {
305 match self {
306 ChannelState::NegotiatingFunding(_)
307 | ChannelState::CollaboratingFundingTx(_)
308 | ChannelState::SigningCommitment(_) => true,
309 ChannelState::AwaitingTxSignatures(flags)
310 if !flags.contains(AwaitingTxSignaturesFlags::OUR_TX_SIGNATURES_SENT) =>
311 {
312 true
313 }
314 _ => false,
315 }
316 }
317}
318
319impl ShuttingDownFlags {
320 pub fn is_ok_for_commitment_operation(&self) -> bool {
321 !self.contains(ShuttingDownFlags::DROPPING_PENDING)
322 && !self.contains(ShuttingDownFlags::WAITING_COMMITMENT_CONFIRMATION)
323 }
324}
325
326pub const INITIAL_COMMITMENT_NUMBER: u64 = 0;
328
329#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
331pub struct CommitmentNumbers {
332 pub local: u64,
333 pub remote: u64,
334}
335
336impl Default for CommitmentNumbers {
337 fn default() -> Self {
338 Self::new()
339 }
340}
341
342impl CommitmentNumbers {
343 pub fn new() -> Self {
344 Self {
345 local: INITIAL_COMMITMENT_NUMBER,
346 remote: INITIAL_COMMITMENT_NUMBER,
347 }
348 }
349
350 pub fn get_local(&self) -> u64 {
351 self.local
352 }
353
354 pub fn get_remote(&self) -> u64 {
355 self.remote
356 }
357
358 pub fn increment_local(&mut self) {
359 self.local += 1;
360 }
361
362 pub fn increment_remote(&mut self) {
363 self.remote += 1;
364 }
365}
366
367#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
369pub struct ChannelConstraints {
370 pub max_tlc_value_in_flight: u128,
372 pub max_tlc_number_in_flight: u64,
374}
375
376impl ChannelConstraints {
377 pub fn new(max_tlc_value_in_flight: u128, max_tlc_number_in_flight: u64) -> Self {
378 Self {
379 max_tlc_value_in_flight,
380 max_tlc_number_in_flight,
381 }
382 }
383}
384
385#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
388pub struct ChannelTlcInfo {
389 pub timestamp: u64,
391
392 pub enabled: bool,
394
395 pub tlc_fee_proportional_millionths: u128,
401
402 pub tlc_expiry_delta: u64,
404
405 pub tlc_minimum_value: u128,
407}
408
409impl ChannelTlcInfo {
410 pub fn new(
412 tlc_minimum_value: u128,
413 tlc_expiry_delta: u64,
414 tlc_fee_proportional_millionths: u128,
415 timestamp: u64,
416 ) -> Self {
417 Self {
418 tlc_minimum_value,
419 tlc_expiry_delta,
420 tlc_fee_proportional_millionths,
421 enabled: true,
422 timestamp,
423 }
424 }
425}
426
427#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
429pub struct ChannelBasePublicKeys {
430 pub funding_pubkey: Pubkey,
433 pub tlc_base_key: Pubkey,
436}
437
438#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
441pub struct PrevTlcInfo {
442 pub prev_channel_id: Hash256,
443 pub prev_tlc_id: u64,
445 pub forwarding_fee: u128,
446 pub shared_secret: Option<[u8; 32]>,
447}
448
449impl PrevTlcInfo {
450 pub fn new_with_shared_secret(
451 prev_channel_id: Hash256,
452 prev_tlc_id: u64,
453 forwarding_fee: u128,
454 shared_secret: [u8; 32],
455 ) -> Self {
456 Self {
457 prev_channel_id,
458 prev_tlc_id,
459 forwarding_fee,
460 shared_secret: Some(shared_secret),
461 }
462 }
463}
464
465#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
466pub struct TlcInfo {
467 pub status: TlcStatus,
468 pub tlc_id: TLCId,
469 pub amount: u128,
470 pub payment_hash: Hash256,
471 pub total_amount: Option<u128>,
473 pub payment_secret: Option<Hash256>,
475 pub attempt_id: Option<u64>,
478 pub expiry: u64,
479 pub hash_algorithm: HashAlgorithm,
480 pub onion_packet: Option<PaymentOnionPacket>,
482 pub shared_secret: [u8; 32],
486 #[serde(default)]
492 pub is_trampoline_hop: bool,
493 pub created_at: CommitmentNumbers,
494 pub removed_reason: Option<RemoveTlcReason>,
495
496 pub forwarding_tlc: Option<(Hash256, u64)>,
522 pub removed_confirmed_at: Option<u64>,
523 pub applied_flags: AppliedFlags,
524}
525
526use std::fmt;
527use std::time::Duration;
528
529impl fmt::Debug for TlcInfo {
530 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
531 f.debug_struct("TlcInfo")
532 .field("status", &self.status)
533 .field("tlc_id", &self.tlc_id)
534 .field("amount", &self.amount)
535 .field("payment_hash", &self.payment_hash)
536 .field("expiry", &self.expiry)
537 .field("created_at", &self.created_at)
538 .field("removed_reason", &self.removed_reason)
539 .field("applied_flags", &self.applied_flags)
540 .finish()
541 }
542}
543
544impl TlcInfo {
545 pub fn log(&self) -> String {
546 format!(
547 "id: {:?} status: {:?} amount: {:?} removed: {:?} hash: {:?} ",
548 &self.tlc_id, self.status, self.amount, self.removed_reason, self.payment_hash,
549 )
550 }
551
552 pub fn id(&self) -> u64 {
553 self.tlc_id.into()
554 }
555
556 pub fn is_offered(&self) -> bool {
557 self.tlc_id.is_offered()
558 }
559
560 pub fn is_received(&self) -> bool {
561 !self.is_offered()
562 }
563
564 pub fn get_commitment_numbers(&self) -> CommitmentNumbers {
565 self.created_at
566 }
567
568 pub fn flip_mut(&mut self) {
569 self.tlc_id.flip_mut();
570 }
571
572 pub fn outbound_status(&self) -> OutboundTlcStatus {
573 self.status.as_outbound_status()
574 }
575
576 pub fn inbound_status(&self) -> InboundTlcStatus {
577 self.status.as_inbound_status()
578 }
579
580 pub fn is_fail_remove_confirmed(&self) -> bool {
581 matches!(self.removed_reason, Some(RemoveTlcReason::RemoveTlcFail(_)))
582 && matches!(
583 self.status,
584 TlcStatus::Outbound(OutboundTlcStatus::RemoveAckConfirmed)
585 | TlcStatus::Outbound(OutboundTlcStatus::RemoveWaitAck)
586 | TlcStatus::Inbound(InboundTlcStatus::RemoveAckConfirmed)
587 )
588 }
589
590 pub fn get_htlc_type(&self) -> u8 {
596 let offered_flag = if self.is_offered() { 0u8 } else { 1u8 };
597 ((self.hash_algorithm as u8) << 1) + offered_flag
598 }
599}
600
601#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
603pub struct PendingTlcs {
604 pub tlcs: Vec<TlcInfo>,
605 pub next_tlc_id: u64,
606}
607
608impl PendingTlcs {
609 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TlcInfo> {
610 self.tlcs.iter_mut()
611 }
612
613 pub fn get_next_id(&self) -> u64 {
614 self.next_tlc_id
615 }
616
617 pub fn increment_next_id(&mut self) {
618 self.next_tlc_id += 1;
619 }
620
621 pub fn add_tlc(&mut self, tlc: TlcInfo) {
622 self.tlcs.push(tlc);
623 }
624}
625
626#[derive(Default, Clone, Debug, Serialize, Deserialize)]
628pub struct TlcState {
629 pub offered_tlcs: PendingTlcs,
630 pub received_tlcs: PendingTlcs,
631 pub waiting_ack: bool,
632}
633
634impl TlcState {
635 pub fn info(&self) -> String {
636 format!(
637 "offer_tlcs: {:?} received_tlcs: {:?}",
638 self.offered_tlcs.tlcs.len(),
639 self.received_tlcs.tlcs.len(),
640 )
641 }
642
643 #[cfg(debug_assertions)]
644 pub fn debug(&self) {
645 let format_tlc_list = |tlcs: &[TlcInfo]| -> String {
646 if tlcs.is_empty() {
647 " <none>".to_string()
648 } else {
649 tlcs.iter()
650 .map(|tlc| format!(" {}", tlc.log()))
651 .collect::<Vec<_>>()
652 .join("\n")
653 }
654 };
655
656 let offered_str = format_tlc_list(&self.offered_tlcs.tlcs);
657 let received_str = format_tlc_list(&self.received_tlcs.tlcs);
658
659 if offered_str.contains("<none>") && received_str.contains("<none>") {
660 tracing::info!("TlcState: <none>");
661 } else {
662 tracing::info!(
663 "TlcState:\n Offered:\n{}\n Received:\n{}",
664 offered_str,
665 received_str
666 );
667 }
668 }
669
670 pub fn get_mut(&mut self, tlc_id: &TLCId) -> Option<&mut TlcInfo> {
671 self.offered_tlcs
672 .tlcs
673 .iter_mut()
674 .find(|tlc| tlc.tlc_id == *tlc_id)
675 .or_else(|| {
676 self.received_tlcs
677 .tlcs
678 .iter_mut()
679 .find(|tlc| tlc.tlc_id == *tlc_id)
680 })
681 }
682
683 pub fn get(&self, tlc_id: &TLCId) -> Option<&TlcInfo> {
684 if tlc_id.is_offered() {
685 self.offered_tlcs
686 .tlcs
687 .iter()
688 .find(|tlc| tlc.tlc_id == *tlc_id)
689 } else {
690 self.received_tlcs
691 .tlcs
692 .iter()
693 .find(|tlc| tlc.tlc_id == *tlc_id)
694 }
695 }
696
697 pub fn get_committed_received_tlcs(&self) -> impl Iterator<Item = &TlcInfo> + '_ {
698 self.received_tlcs.tlcs.iter().filter(|tlc| {
699 debug_assert!(tlc.is_received());
700 matches!(tlc.inbound_status(), InboundTlcStatus::Committed)
701 })
702 }
703
704 pub fn get_expired_offered_tlcs(
705 &self,
706 expect_expiry: u64,
707 ) -> impl Iterator<Item = &TlcInfo> + '_ {
708 self.offered_tlcs.tlcs.iter().filter(move |tlc| {
709 tlc.outbound_status() != OutboundTlcStatus::LocalAnnounced
710 && tlc.removed_confirmed_at.is_none()
711 && tlc.expiry < expect_expiry
712 })
713 }
714
715 pub fn get_next_offering(&self) -> u64 {
716 self.offered_tlcs.get_next_id()
717 }
718
719 pub fn get_next_received(&self) -> u64 {
720 self.received_tlcs.get_next_id()
721 }
722
723 pub fn increment_offering(&mut self) {
724 self.offered_tlcs.increment_next_id();
725 }
726
727 pub fn increment_received(&mut self) {
728 self.received_tlcs.increment_next_id();
729 }
730
731 pub fn set_waiting_ack(&mut self, waiting_ack: bool) {
732 self.waiting_ack = waiting_ack;
733 }
734
735 pub fn all_tlcs(&self) -> impl Iterator<Item = &TlcInfo> + '_ {
736 self.offered_tlcs
737 .tlcs
738 .iter()
739 .chain(self.received_tlcs.tlcs.iter())
740 }
741
742 pub fn apply_remove_tlc(&mut self, tlc_id: TLCId) {
743 if tlc_id.is_offered() {
744 self.offered_tlcs.tlcs.retain(|tlc| tlc.tlc_id != tlc_id);
745 } else {
746 self.received_tlcs.tlcs.retain(|tlc| tlc.tlc_id != tlc_id);
747 }
748 }
749
750 pub fn add_offered_tlc(&mut self, tlc: TlcInfo) {
751 self.offered_tlcs.add_tlc(tlc);
752 }
753
754 pub fn add_received_tlc(&mut self, tlc: TlcInfo) {
755 self.received_tlcs.add_tlc(tlc);
756 }
757
758 pub fn set_received_tlc_removed(&mut self, tlc_id: u64, reason: RemoveTlcReason) -> Hash256 {
759 let tlc = self.get_mut(&TLCId::Received(tlc_id)).expect("get tlc");
760 assert!(matches!(
761 tlc.inbound_status(),
762 InboundTlcStatus::AnnounceWaitAck | InboundTlcStatus::Committed
763 ));
764 tlc.removed_reason = Some(reason);
765 tlc.status = TlcStatus::Inbound(InboundTlcStatus::LocalRemoved);
766 tlc.payment_hash
767 }
768
769 pub fn set_offered_tlc_removed(&mut self, tlc_id: u64, reason: RemoveTlcReason) -> Hash256 {
770 let tlc = self.get_mut(&TLCId::Offered(tlc_id)).expect("get tlc");
771 assert_eq!(tlc.outbound_status(), OutboundTlcStatus::Committed);
772 tlc.removed_reason = Some(reason);
773 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoteRemoved);
774 tlc.payment_hash
775 }
776
777 pub fn commitment_signed_tlcs(&self, for_remote: bool) -> impl Iterator<Item = &TlcInfo> + '_ {
778 self.offered_tlcs
779 .tlcs
780 .iter()
781 .filter(move |tlc| match tlc.outbound_status() {
782 OutboundTlcStatus::LocalAnnounced => for_remote,
783 OutboundTlcStatus::Committed => true,
784 OutboundTlcStatus::RemoteRemoved => for_remote,
785 OutboundTlcStatus::RemoveWaitPrevAck => for_remote,
786 OutboundTlcStatus::RemoveWaitAck => false,
787 OutboundTlcStatus::RemoveAckConfirmed => false,
788 })
789 .chain(
790 self.received_tlcs
791 .tlcs
792 .iter()
793 .filter(move |tlc| match tlc.inbound_status() {
794 InboundTlcStatus::RemoteAnnounced => !for_remote,
795 InboundTlcStatus::AnnounceWaitPrevAck => !for_remote,
796 InboundTlcStatus::AnnounceWaitAck => true,
797 InboundTlcStatus::Committed => true,
798 InboundTlcStatus::LocalRemoved => !for_remote,
799 InboundTlcStatus::RemoveAckConfirmed => false,
800 }),
801 )
802 }
803
804 pub fn update_for_commitment_signed(&mut self) -> bool {
805 for tlc in self.offered_tlcs.tlcs.iter_mut() {
806 if tlc.outbound_status() == OutboundTlcStatus::RemoteRemoved {
807 let status = if self.waiting_ack {
808 OutboundTlcStatus::RemoveWaitPrevAck
809 } else {
810 OutboundTlcStatus::RemoveWaitAck
811 };
812 tlc.status = TlcStatus::Outbound(status);
813 }
814 }
815 for tlc in self.received_tlcs.tlcs.iter_mut() {
816 if tlc.inbound_status() == InboundTlcStatus::RemoteAnnounced {
817 let status = if self.waiting_ack {
818 InboundTlcStatus::AnnounceWaitPrevAck
819 } else {
820 InboundTlcStatus::AnnounceWaitAck
821 };
822 tlc.status = TlcStatus::Inbound(status)
823 }
824 }
825 self.need_another_commitment_signed()
826 }
827
828 pub fn update_for_revoke_and_ack(&mut self, commitment_number: CommitmentNumbers) {
829 for tlc in self.offered_tlcs.tlcs.iter_mut() {
830 match tlc.outbound_status() {
831 OutboundTlcStatus::LocalAnnounced => {
832 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::Committed);
833 }
834 OutboundTlcStatus::RemoveWaitPrevAck => {
835 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoveWaitAck);
836 }
837 OutboundTlcStatus::RemoveWaitAck => {
838 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoveAckConfirmed);
839 tlc.removed_confirmed_at = Some(commitment_number.get_local());
840 }
841 _ => {}
842 }
843 }
844
845 for tlc in self.received_tlcs.tlcs.iter_mut() {
846 match tlc.inbound_status() {
847 InboundTlcStatus::AnnounceWaitPrevAck => {
848 tlc.status = TlcStatus::Inbound(InboundTlcStatus::AnnounceWaitAck);
849 }
850 InboundTlcStatus::AnnounceWaitAck => {
851 tlc.status = TlcStatus::Inbound(InboundTlcStatus::Committed);
852 }
853 InboundTlcStatus::LocalRemoved => {
854 tlc.status = TlcStatus::Inbound(InboundTlcStatus::RemoveAckConfirmed);
855 tlc.removed_confirmed_at = Some(commitment_number.get_remote());
856 }
857 _ => {}
858 }
859 }
860 }
861
862 pub fn need_another_commitment_signed(&self) -> bool {
863 self.offered_tlcs.tlcs.iter().any(|tlc| {
864 let status = tlc.outbound_status();
865 matches!(
866 status,
867 OutboundTlcStatus::LocalAnnounced
868 | OutboundTlcStatus::RemoteRemoved
869 | OutboundTlcStatus::RemoveWaitPrevAck
870 | OutboundTlcStatus::RemoveWaitAck
871 )
872 }) || self.received_tlcs.tlcs.iter().any(|tlc| {
873 let status = tlc.inbound_status();
874 matches!(
875 status,
876 InboundTlcStatus::RemoteAnnounced
877 | InboundTlcStatus::AnnounceWaitPrevAck
878 | InboundTlcStatus::AnnounceWaitAck
879 )
880 })
881 }
882}
883
884#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
886pub struct AddTlcCommand {
887 pub amount: u128,
888 pub payment_hash: Hash256,
889 pub attempt_id: Option<u64>,
891 pub expiry: u64,
892 pub hash_algorithm: HashAlgorithm,
893 pub onion_packet: Option<PaymentOnionPacket>,
895 pub shared_secret: [u8; 32],
899 pub is_trampoline_hop: bool,
905 pub previous_tlc: Option<PrevTlcInfo>,
906}
907
908impl fmt::Debug for AddTlcCommand {
909 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
910 f.debug_struct("AddTlcCommand")
911 .field("amount", &self.amount)
912 .field("payment_hash", &self.payment_hash)
913 .field("attempt_id", &self.attempt_id)
914 .field("expiry", &self.expiry)
915 .field("hash_algorithm", &self.hash_algorithm)
916 .field("is_trampoline_hop", &self.is_trampoline_hop)
917 .field("previous_tlc", &self.previous_tlc)
918 .finish()
919 }
920}
921
922#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug, Hash)]
924pub enum RetryableTlcOperation {
925 RemoveTlc(TLCId, RemoveTlcReason),
926 AddTlc(AddTlcCommand),
927}
928
929#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
931pub struct AddTlc {
932 pub channel_id: Hash256,
933 pub tlc_id: u64,
934 pub amount: u128,
935 pub payment_hash: Hash256,
936 pub expiry: u64,
937 pub hash_algorithm: HashAlgorithm,
938 pub onion_packet: Option<PaymentOnionPacket>,
939}
940
941impl fmt::Debug for AddTlc {
942 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
943 f.debug_struct("AddTlc")
944 .field("channel_id", &self.channel_id)
945 .field("tlc_id", &self.tlc_id)
946 .field("amount", &self.amount)
947 .field("payment_hash", &self.payment_hash)
948 .field("expiry", &self.expiry)
949 .field("hash_algorithm", &self.hash_algorithm)
950 .finish()
951 }
952}
953
954impl From<AddTlc> for molecule_fiber::AddTlc {
955 fn from(add_tlc: AddTlc) -> Self {
956 molecule_fiber::AddTlc::new_builder()
957 .channel_id(add_tlc.channel_id.into())
958 .tlc_id(add_tlc.tlc_id.pack())
959 .amount(add_tlc.amount.pack())
960 .payment_hash(add_tlc.payment_hash.into())
961 .expiry(add_tlc.expiry.pack())
962 .hash_algorithm(molecule::prelude::Byte::new(add_tlc.hash_algorithm as u8))
963 .onion_packet(
964 add_tlc
965 .onion_packet
966 .map(|p| p.into_bytes())
967 .unwrap_or_default()
968 .pack(),
969 )
970 .build()
971 }
972}
973
974impl TryFrom<molecule_fiber::AddTlc> for AddTlc {
975 type Error = anyhow::Error;
976
977 fn try_from(add_tlc: molecule_fiber::AddTlc) -> Result<Self, Self::Error> {
978 let onion_packet_bytes: Vec<u8> = add_tlc.onion_packet().unpack();
979 let onion_packet =
980 (!onion_packet_bytes.is_empty()).then(|| PaymentOnionPacket::new(onion_packet_bytes));
981 Ok(AddTlc {
982 onion_packet,
983 channel_id: add_tlc.channel_id().into(),
984 tlc_id: add_tlc.tlc_id().unpack(),
985 amount: add_tlc.amount().unpack(),
986 payment_hash: add_tlc.payment_hash().into(),
987 expiry: add_tlc.expiry().unpack(),
988 hash_algorithm: add_tlc
989 .hash_algorithm()
990 .try_into()
991 .map_err(|e: crate::invoice::UnknownHashAlgorithmError| anyhow::anyhow!(e))?,
992 })
993 }
994}
995
996#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
998pub struct RemoveTlc {
999 pub channel_id: Hash256,
1000 pub tlc_id: u64,
1001 pub reason: RemoveTlcReason,
1002}
1003
1004impl From<RemoveTlc> for molecule_fiber::RemoveTlc {
1005 fn from(remove_tlc: RemoveTlc) -> Self {
1006 molecule_fiber::RemoveTlc::new_builder()
1007 .channel_id(remove_tlc.channel_id.into())
1008 .tlc_id(remove_tlc.tlc_id.pack())
1009 .reason(
1010 molecule_fiber::RemoveTlcReason::new_builder()
1011 .set(remove_tlc.reason)
1012 .build(),
1013 )
1014 .build()
1015 }
1016}
1017
1018impl TryFrom<molecule_fiber::RemoveTlc> for RemoveTlc {
1019 type Error = anyhow::Error;
1020
1021 fn try_from(remove_tlc: molecule_fiber::RemoveTlc) -> Result<Self, Self::Error> {
1022 Ok(RemoveTlc {
1023 channel_id: remove_tlc.channel_id().into(),
1024 tlc_id: remove_tlc.tlc_id().unpack(),
1025 reason: remove_tlc.reason().into(),
1026 })
1027 }
1028}
1029
1030#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug, Hash)]
1032pub enum TlcReplayUpdate {
1033 Add(AddTlc),
1034 Remove(RemoveTlc),
1035}
1036
1037pub const CURRENT_COMMIT_DIFF_VERSION: u8 = 2;
1039
1040fn default_commit_diff_version() -> u8 {
1041 CURRENT_COMMIT_DIFF_VERSION
1042}
1043
1044#[serde_as]
1046#[derive(Clone, Debug, Serialize, Deserialize)]
1047pub struct CommitmentSignedTemplate {
1048 #[serde_as(as = "PubNonceAsBytes")]
1049 pub next_commitment_nonce: PubNonce,
1050 #[serde(default)]
1051 #[serde_as(as = "Option<PartialSignatureAsBytes>")]
1052 pub funding_tx_partial_signature: Option<PartialSignature>,
1053}
1054
1055#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1057pub enum ReplayOrderHint {
1058 RevokeThenCommit,
1059 CommitThenRevoke,
1060}
1061
1062#[serde_as]
1064#[derive(Clone, Debug, Serialize, Deserialize)]
1065pub struct CommitDiff {
1066 #[serde(default = "default_commit_diff_version")]
1068 pub version: u8,
1069 #[serde(default)]
1071 pub channel_id: Hash256,
1072 #[serde(default)]
1074 pub local_commitment_number_at_send: u64,
1075 #[serde(default)]
1076 pub remote_commitment_number_at_send: u64,
1077 #[serde_as(as = "EntityHex")]
1079 pub commit_tx: Transaction,
1080 #[serde(default, alias = "tlc_updates")]
1082 pub replay_updates: Vec<TlcReplayUpdate>,
1083 #[serde(default)]
1085 pub commitment_signed_template: Option<CommitmentSignedTemplate>,
1086 #[serde(default)]
1088 pub replay_order_hint: Option<ReplayOrderHint>,
1089 #[serde(default, alias = "created_at")]
1091 pub created_at_ms: u64,
1092}
1093
1094#[serde_as]
1096#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
1097pub struct ShutdownInfo {
1098 #[serde_as(as = "EntityHex")]
1099 pub close_script: Script,
1100 pub fee_rate: u64,
1101 #[serde_as(as = "Option<PartialSignatureAsBytes>")]
1102 pub signature: Option<PartialSignature>,
1103}
1104
1105#[serde_as]
1107#[derive(Debug, Clone, Serialize, Deserialize)]
1108pub struct RevokeAndAck {
1109 pub channel_id: Hash256,
1110 #[serde_as(as = "PartialSignatureAsBytes")]
1111 pub revocation_partial_signature: PartialSignature,
1112 pub next_per_commitment_point: Pubkey,
1113 #[serde_as(as = "PubNonceAsBytes")]
1114 pub next_revocation_nonce: PubNonce,
1115}
1116#[serde_as]
1123#[derive(Default, Clone, Debug, Serialize, Deserialize)]
1124pub struct PublicChannelInfo {
1125 #[serde_as(as = "Option<(_, PartialSignatureAsBytes)>")]
1127 pub local_channel_announcement_signature: Option<(EcdsaSignature, PartialSignature)>,
1128 #[serde_as(as = "Option<(_, PartialSignatureAsBytes)>")]
1129 pub remote_channel_announcement_signature: Option<(EcdsaSignature, PartialSignature)>,
1130 #[serde_as(as = "Option<PubNonceAsBytes>")]
1131 pub remote_channel_announcement_nonce: Option<PubNonce>,
1132 pub channel_announcement: Option<ChannelAnnouncement>,
1133 pub channel_update: Option<ChannelUpdate>,
1134}
1135
1136impl PublicChannelInfo {
1137 pub fn new() -> Self {
1138 Default::default()
1139 }
1140}
1141
1142#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
1147pub struct InMemorySigner {
1148 pub funding_key: Privkey,
1150 pub tlc_base_key: Privkey,
1152 pub musig2_base_nonce: Privkey,
1154 pub commitment_seed: [u8; 32],
1156}
1157
1158impl fmt::Debug for InMemorySigner {
1159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1160 f.debug_struct("InMemorySigner")
1161 .field("funding_key", &"[REDACTED]")
1162 .field("tlc_base_key", &"[REDACTED]")
1163 .field("musig2_base_nonce", &"[REDACTED]")
1164 .field("commitment_seed", &"[REDACTED]")
1165 .finish()
1166 }
1167}
1168
1169pub fn blake2b_hash_with_salt(data: &[u8], salt: &[u8]) -> [u8; 32] {
1171 let mut hasher = ckb_hash::new_blake2b();
1172 hasher.update(salt);
1173 hasher.update(data);
1174 let mut result = [0u8; 32];
1175 hasher.finalize(&mut result);
1176 result
1177}
1178
1179pub fn get_tweak_by_commitment_point(commitment_point: &Pubkey) -> [u8; 32] {
1181 let mut hasher = ckb_hash::new_blake2b();
1182 hasher.update(&commitment_point.serialize());
1183 let mut result = [0u8; 32];
1184 hasher.finalize(&mut result);
1185 result
1186}
1187
1188pub fn derive_private_key(secret: &Privkey, commitment_point: &Pubkey) -> Privkey {
1190 secret.tweak(get_tweak_by_commitment_point(commitment_point))
1191}
1192
1193#[deprecated(note = "use `try_derive_public_key` instead to avoid panicking on invalid keys")]
1195pub fn derive_public_key(base_key: &Pubkey, commitment_point: &Pubkey) -> Pubkey {
1196 base_key.tweak(get_tweak_by_commitment_point(commitment_point))
1197}
1198
1199pub fn try_derive_public_key(
1201 base_key: &Pubkey,
1202 commitment_point: &Pubkey,
1203) -> Result<Pubkey, String> {
1204 base_key.try_tweak(get_tweak_by_commitment_point(commitment_point))
1205}
1206
1207#[deprecated(note = "use `try_derive_tlc_pubkey` instead to avoid panicking on invalid keys")]
1209pub fn derive_tlc_pubkey(base_key: &Pubkey, commitment_point: &Pubkey) -> Pubkey {
1210 #[allow(deprecated)]
1211 derive_public_key(base_key, commitment_point)
1212}
1213
1214pub fn try_derive_tlc_pubkey(
1216 base_key: &Pubkey,
1217 commitment_point: &Pubkey,
1218) -> Result<Pubkey, String> {
1219 try_derive_public_key(base_key, commitment_point)
1220}
1221
1222pub fn is_tlc_key_derivation_safe(base_key: &Pubkey, commitment_point: &Pubkey) -> bool {
1229 let tweak = get_tweak_by_commitment_point(commitment_point);
1230 let Ok(scalar) = Scalar::from_slice(&tweak) else {
1231 return false;
1232 };
1233 let base_point = Point::from(base_key);
1234 let result = base_point + scalar.base_point_mul();
1235 result.not_inf().is_ok()
1236}
1237
1238pub fn get_commitment_secret(commitment_seed: &[u8; 32], commitment_number: u64) -> [u8; 32] {
1242 let mut res: [u8; 32] = *commitment_seed;
1243 for i in 0..48 {
1244 let bitpos = 47 - i;
1245 if commitment_number & (1 << bitpos) == (1 << bitpos) {
1246 res[bitpos / 8] ^= 1 << (bitpos & 7);
1247 res = ckb_hash::blake2b_256(res);
1248 }
1249 }
1250 res
1251}
1252
1253pub fn get_commitment_point(commitment_seed: &[u8; 32], commitment_number: u64) -> Pubkey {
1255 Privkey::from(&get_commitment_secret(commitment_seed, commitment_number)).pubkey()
1256}
1257
1258pub enum Musig2Context {
1260 Commitment,
1262 Revoke,
1264}
1265
1266impl std::fmt::Display for Musig2Context {
1267 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1268 let context_str = match self {
1269 Musig2Context::Commitment => "COMMITMENT",
1270 Musig2Context::Revoke => "REVOKE",
1271 };
1272 write!(f, "{}", context_str)
1273 }
1274}
1275
1276impl InMemorySigner {
1277 pub fn generate_from_seed(params: &[u8]) -> InMemorySigner {
1279 let seed = ckb_hash::blake2b_256(params);
1280
1281 let commitment_seed = {
1282 let mut hasher = ckb_hash::new_blake2b();
1283 hasher.update(&seed);
1284 hasher.update(&b"commitment seed"[..]);
1285 let mut result = [0u8; 32];
1286 hasher.finalize(&mut result);
1287 result
1288 };
1289
1290 let key_derive = |seed: &[u8], info: &[u8]| {
1291 let result = blake2b_hash_with_salt(seed, info);
1292 Privkey::from_slice(&result)
1293 };
1294
1295 let funding_key = key_derive(&seed, b"funding key");
1296 let tlc_base_key = key_derive(funding_key.as_ref(), b"HTLC base key");
1297 let musig2_base_nonce = key_derive(tlc_base_key.as_ref(), b"musig nocne");
1298
1299 InMemorySigner {
1300 funding_key,
1301 tlc_base_key,
1302 musig2_base_nonce,
1303 commitment_seed,
1304 }
1305 }
1306
1307 pub fn get_base_public_keys(&self) -> ChannelBasePublicKeys {
1309 ChannelBasePublicKeys {
1310 funding_pubkey: self.funding_key.pubkey(),
1311 tlc_base_key: self.tlc_base_key.pubkey(),
1312 }
1313 }
1314
1315 pub fn get_commitment_point(&self, commitment_number: u64) -> Pubkey {
1321 get_commitment_point(&self.commitment_seed, commitment_number)
1322 }
1323
1324 pub fn get_commitment_secret(&self, commitment_number: u64) -> [u8; 32] {
1326 get_commitment_secret(&self.commitment_seed, commitment_number)
1327 }
1328
1329 pub fn derive_tlc_key(&self, new_commitment_number: u64) -> Privkey {
1331 let per_commitment_point = self.get_commitment_point(new_commitment_number);
1332 derive_private_key(&self.tlc_base_key, &per_commitment_point)
1333 }
1334
1335 pub fn derive_musig2_nonce(&self, commitment_number: u64, context: Musig2Context) -> SecNonce {
1337 let commitment_point = self.get_commitment_point(commitment_number);
1338 let seckey = derive_private_key(&self.musig2_base_nonce, &commitment_point);
1339
1340 SecNonceBuilder::new(seckey.as_ref())
1341 .with_extra_input(&context.to_string())
1342 .build()
1343 }
1344}
1345
1346#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
1348pub enum ChannelOpeningStatus {
1349 WaitingForPeer,
1352 FundingTxBuilding,
1354 FundingTxBroadcasted,
1356 ChannelReady,
1358 Failed,
1360}
1361
1362#[serde_as]
1368#[derive(Clone, Debug, Serialize, Deserialize)]
1369pub struct ChannelOpenRecord {
1370 pub channel_id: Hash256,
1375 pub pubkey: Pubkey,
1377 pub is_acceptor: bool,
1379 pub status: ChannelOpeningStatus,
1381 pub funding_amount: u128,
1385 pub failure_detail: Option<String>,
1387 pub created_at: u64,
1389 pub last_updated_at: u64,
1391}
1392
1393impl ChannelOpenRecord {
1394 pub fn new(channel_id: Hash256, pubkey: Pubkey, funding_amount: u128) -> Self {
1396 let now = crate::now_timestamp_as_millis_u64();
1397 Self {
1398 channel_id,
1399 pubkey,
1400 is_acceptor: false,
1401 status: ChannelOpeningStatus::WaitingForPeer,
1402 funding_amount,
1403 failure_detail: None,
1404 created_at: now,
1405 last_updated_at: now,
1406 }
1407 }
1408
1409 pub fn new_inbound(channel_id: Hash256, pubkey: Pubkey, remote_funding_amount: u128) -> Self {
1412 let mut record = Self::new(channel_id, pubkey, remote_funding_amount);
1413 record.is_acceptor = true;
1414 record
1415 }
1416
1417 pub fn update_status(&mut self, status: ChannelOpeningStatus) {
1419 self.status = status;
1420 self.last_updated_at = crate::now_timestamp_as_millis_u64();
1421 }
1422
1423 pub fn fail(&mut self, reason: String) {
1425 self.status = ChannelOpeningStatus::Failed;
1426 self.failure_detail = Some(reason);
1427 self.last_updated_at = crate::now_timestamp_as_millis_u64();
1428 }
1429}
1430
1431pub trait ChannelOpenRecordStore {
1433 fn get_channel_open_records(&self) -> Vec<ChannelOpenRecord>;
1435 fn get_channel_open_record(&self, channel_id: &Hash256) -> Option<ChannelOpenRecord>;
1437 fn insert_channel_open_record(&self, record: ChannelOpenRecord);
1439 fn delete_channel_open_record(&self, channel_id: &Hash256);
1441}
1442
1443#[derive(Clone, Serialize, Deserialize, Debug)]
1445pub struct PendingNotifySettleTlc {
1446 pub payment_hash: Hash256,
1447 pub tlc_id: u64,
1448 pub hold_expire_at: Option<u64>,
1450}
1451
1452impl PendingNotifySettleTlc {
1453 pub fn pending_notify_should_hold(&self) -> bool {
1455 self.hold_expire_at.is_some()
1456 }
1457
1458 pub fn pending_notify_hold_expiry_duration(
1460 &self,
1461 now_millis_since_unix_epoch: u64,
1462 ) -> Duration {
1463 Duration::from_millis(
1464 self.hold_expire_at
1465 .unwrap_or_default()
1466 .saturating_sub(now_millis_since_unix_epoch),
1467 )
1468 }
1469}
1470
1471#[serde_as]
1476#[derive(Clone, Serialize, Deserialize)]
1477pub struct ChannelActorData {
1478 pub state: ChannelState,
1479 pub public_channel_info: Option<PublicChannelInfo>,
1481
1482 pub local_tlc_info: ChannelTlcInfo,
1483 pub remote_tlc_info: Option<ChannelTlcInfo>,
1484
1485 pub local_pubkey: Pubkey,
1487 pub remote_pubkey: Pubkey,
1489
1490 pub id: Hash256,
1491 #[serde_as(as = "Option<EntityHex>")]
1492 pub funding_tx: Option<Transaction>,
1493
1494 pub funding_tx_confirmed_at: Option<(H256, u32, u64)>,
1495
1496 #[serde_as(as = "Option<EntityHex>")]
1497 pub funding_udt_type_script: Option<Script>,
1498
1499 pub is_acceptor: bool,
1502
1503 pub is_one_way: bool,
1506
1507 pub to_local_amount: u128,
1510 pub to_remote_amount: u128,
1513
1514 pub local_reserved_ckb_amount: u64,
1518 pub remote_reserved_ckb_amount: u64,
1519
1520 pub commitment_fee_rate: u64,
1523
1524 pub commitment_delay_epoch: u64,
1527
1528 pub funding_fee_rate: u64,
1531
1532 pub signer: InMemorySigner,
1534
1535 pub local_channel_public_keys: ChannelBasePublicKeys,
1537
1538 pub commitment_numbers: CommitmentNumbers,
1541
1542 pub local_constraints: ChannelConstraints,
1543 pub remote_constraints: ChannelConstraints,
1544
1545 pub tlc_state: TlcState,
1547
1548 pub retryable_tlc_operations: VecDeque<RetryableTlcOperation>,
1550 pub waiting_forward_tlc_tasks: HashMap<TLCId, [u8; 32]>,
1551
1552 #[serde_as(as = "Option<EntityHex>")]
1554 pub remote_shutdown_script: Option<Script>,
1555 #[serde_as(as = "EntityHex")]
1557 pub local_shutdown_script: Script,
1558
1559 #[serde_as(as = "Option<PubNonceAsBytes>")]
1562 pub last_committed_remote_nonce: Option<PubNonce>,
1563
1564 #[serde_as(as = "Option<PubNonceAsBytes>")]
1565 pub remote_revocation_nonce_for_verify: Option<PubNonce>,
1566 #[serde_as(as = "Option<PubNonceAsBytes>")]
1567 pub remote_revocation_nonce_for_send: Option<PubNonce>,
1568 #[serde_as(as = "Option<PubNonceAsBytes>")]
1569 pub remote_revocation_nonce_for_next: Option<PubNonce>,
1570
1571 #[serde_as(as = "Option<EntityHex>")]
1574 pub latest_commitment_transaction: Option<Transaction>,
1575
1576 pub remote_commitment_points: Vec<(u64, Pubkey)>,
1579 pub remote_channel_public_keys: Option<ChannelBasePublicKeys>,
1580
1581 pub local_shutdown_info: Option<ShutdownInfo>,
1583 pub remote_shutdown_info: Option<ShutdownInfo>,
1584
1585 pub shutdown_transaction_hash: Option<H256>,
1588
1589 pub reestablishing: bool,
1592 pub last_revoke_ack_msg: Option<RevokeAndAck>,
1593
1594 pub created_at: SystemTime,
1595
1596 #[serde(default)]
1599 pub pending_replay_updates: Vec<TlcReplayUpdate>,
1600
1601 #[serde(default)]
1603 pub last_was_revoke: bool,
1604
1605 pub connectivity_state: ChannelConnectivityState,
1607
1608 #[serde(default)]
1610 pub external_funding: Option<ExternalFundingPersistState>,
1611}
1612
1613fn partial_signature_to_molecule(partial_signature: PartialSignature) -> MByte32 {
1614 MByte32::from_slice(partial_signature.serialize().as_ref()).expect("[Byte; 32] from [u8; 32]")
1615}
1616
1617fn pub_nonce_to_molecule(pub_nonce: PubNonce) -> molecule_fiber::PubNonce {
1618 molecule_fiber::PubNonce::from_slice(pub_nonce.to_bytes().as_ref())
1619 .expect("PubNonce from 66 bytes")
1620}
1621
1622impl From<PubNonce> for molecule_fiber::PubNonce {
1623 fn from(value: PubNonce) -> Self {
1624 molecule_fiber::PubNonce::from_slice(value.to_bytes().as_ref())
1625 .expect("valid pubnonce serialized to 66 bytes")
1626 }
1627}
1628
1629impl TryFrom<molecule_fiber::PubNonce> for PubNonce {
1630 type Error = musig2::errors::DecodeError<PubNonce>;
1631
1632 fn try_from(value: molecule_fiber::PubNonce) -> Result<Self, Self::Error> {
1633 PubNonce::from_bytes(value.as_slice())
1634 }
1635}
1636
1637impl From<RevokeAndAck> for molecule_fiber::RevokeAndAck {
1638 fn from(revoke_and_ack: RevokeAndAck) -> Self {
1639 molecule_fiber::RevokeAndAck::new_builder()
1640 .channel_id(revoke_and_ack.channel_id.into())
1641 .revocation_partial_signature(partial_signature_to_molecule(
1642 revoke_and_ack.revocation_partial_signature,
1643 ))
1644 .next_per_commitment_point(revoke_and_ack.next_per_commitment_point.into())
1645 .next_revocation_nonce(pub_nonce_to_molecule(revoke_and_ack.next_revocation_nonce))
1646 .build()
1647 }
1648}
1649
1650impl TryFrom<molecule_fiber::RevokeAndAck> for RevokeAndAck {
1651 type Error = anyhow::Error;
1652
1653 fn try_from(revoke_and_ack: molecule_fiber::RevokeAndAck) -> Result<Self, Self::Error> {
1654 Ok(RevokeAndAck {
1655 channel_id: revoke_and_ack.channel_id().into(),
1656 revocation_partial_signature: PartialSignature::from_slice(
1657 revoke_and_ack.revocation_partial_signature().as_slice(),
1658 )
1659 .map_err(|e| anyhow::anyhow!(e))?,
1660 next_per_commitment_point: revoke_and_ack
1661 .next_per_commitment_point()
1662 .try_into()
1663 .map_err(|e: secp256k1::Error| anyhow::anyhow!(e))?,
1664 next_revocation_nonce: PubNonce::from_bytes(
1665 revoke_and_ack.next_revocation_nonce().as_slice(),
1666 )
1667 .map_err(|e| anyhow::anyhow!("{}", e))?,
1668 })
1669 }
1670}
1671
1672#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1674pub struct RemoveTlcFulfill {
1675 pub payment_preimage: Hash256,
1676}
1677
1678#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1680pub enum RemoveTlcReason {
1681 RemoveTlcFulfill(RemoveTlcFulfill),
1682 RemoveTlcFail(TlcErrPacket),
1683}
1684
1685impl Debug for RemoveTlcReason {
1686 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1687 match self {
1688 RemoveTlcReason::RemoveTlcFulfill(_fulfill) => {
1689 write!(f, "RemoveTlcFulfill")
1690 }
1691 RemoveTlcReason::RemoveTlcFail(_fail) => {
1692 write!(f, "RemoveTlcFail")
1693 }
1694 }
1695 }
1696}
1697
1698impl RemoveTlcReason {
1699 pub fn backward(self, shared_secret: &[u8; 32]) -> Result<Self, TlcErrPacketError> {
1702 match self {
1703 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill) => {
1704 Ok(RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill))
1705 }
1706 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail) => Ok(RemoveTlcReason::RemoveTlcFail(
1707 remove_tlc_fail.backward(shared_secret)?,
1708 )),
1709 }
1710 }
1711}
1712
1713impl From<RemoveTlcReason> for molecule_fiber::RemoveTlcReasonUnion {
1714 fn from(remove_tlc_reason: RemoveTlcReason) -> Self {
1715 match remove_tlc_reason {
1716 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill) => {
1717 molecule_fiber::RemoveTlcReasonUnion::RemoveTlcFulfill(remove_tlc_fulfill.into())
1718 }
1719 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail) => {
1720 molecule_fiber::RemoveTlcReasonUnion::TlcErrPacket(remove_tlc_fail.into())
1721 }
1722 }
1723 }
1724}
1725
1726impl From<RemoveTlcReason> for molecule_fiber::RemoveTlcReason {
1727 fn from(remove_tlc_reason: RemoveTlcReason) -> Self {
1728 molecule_fiber::RemoveTlcReason::new_builder()
1729 .set(remove_tlc_reason)
1730 .build()
1731 }
1732}
1733
1734impl From<molecule_fiber::RemoveTlcReason> for RemoveTlcReason {
1735 fn from(remove_tlc_reason: molecule_fiber::RemoveTlcReason) -> Self {
1736 match remove_tlc_reason.to_enum() {
1737 molecule_fiber::RemoveTlcReasonUnion::RemoveTlcFulfill(remove_tlc_fulfill) => {
1738 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill.into())
1739 }
1740 molecule_fiber::RemoveTlcReasonUnion::TlcErrPacket(remove_tlc_fail) => {
1741 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail.into())
1742 }
1743 }
1744 }
1745}
1746
1747impl From<RemoveTlcFulfill> for molecule_fiber::RemoveTlcFulfill {
1748 fn from(remove_tlc_fulfill: RemoveTlcFulfill) -> Self {
1749 molecule_fiber::RemoveTlcFulfill::new_builder()
1750 .payment_preimage(remove_tlc_fulfill.payment_preimage.into())
1751 .build()
1752 }
1753}
1754
1755impl From<molecule_fiber::RemoveTlcFulfill> for RemoveTlcFulfill {
1756 fn from(remove_tlc_fulfill: molecule_fiber::RemoveTlcFulfill) -> Self {
1757 RemoveTlcFulfill {
1758 payment_preimage: remove_tlc_fulfill.payment_preimage().into(),
1759 }
1760 }
1761}
1762
1763#[serde_as]
1768#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
1769pub struct ChannelUpdateInfo {
1770 #[serde_as(as = "crate::U64Hex")]
1772 pub timestamp: u64,
1773 pub enabled: bool,
1775 #[serde_as(as = "Option<crate::U128Hex>")]
1777 pub outbound_liquidity: Option<u128>,
1778 #[serde_as(as = "crate::U64Hex")]
1780 pub tlc_expiry_delta: u64,
1781 #[serde_as(as = "crate::U128Hex")]
1783 pub tlc_minimum_value: u128,
1784 #[serde_as(as = "crate::U64Hex")]
1786 pub fee_rate: u64,
1787}
1788
1789impl From<&ChannelTlcInfo> for ChannelUpdateInfo {
1790 fn from(info: &ChannelTlcInfo) -> Self {
1791 Self {
1792 timestamp: info.timestamp,
1793 enabled: info.enabled,
1794 outbound_liquidity: None,
1795 tlc_expiry_delta: info.tlc_expiry_delta,
1796 tlc_minimum_value: info.tlc_minimum_value,
1797 fee_rate: info.tlc_fee_proportional_millionths as u64,
1798 }
1799 }
1800}
1801
1802impl From<ChannelTlcInfo> for ChannelUpdateInfo {
1803 fn from(info: ChannelTlcInfo) -> Self {
1804 Self::from(&info)
1805 }
1806}
1807
1808impl From<crate::protocol::ChannelUpdate> for ChannelUpdateInfo {
1809 fn from(update: crate::protocol::ChannelUpdate) -> Self {
1810 Self::from(&update)
1811 }
1812}
1813
1814impl From<&crate::protocol::ChannelUpdate> for ChannelUpdateInfo {
1815 fn from(update: &crate::protocol::ChannelUpdate) -> Self {
1816 Self {
1817 timestamp: update.timestamp,
1818 enabled: !update.is_disabled(),
1819 outbound_liquidity: None,
1820 tlc_expiry_delta: update.tlc_expiry_delta,
1821 tlc_minimum_value: update.tlc_minimum_value,
1822 fee_rate: update.tlc_fee_proportional_millionths as u64,
1823 }
1824 }
1825}