1use crate::crate_time::SystemTime;
4use crate::gen::fiber as molecule_fiber;
5use crate::invoice::HashAlgorithm;
6use crate::onion::PaymentOnionPacket;
7use crate::onion::TlcErrPacket;
8use crate::protocol::{ChannelAnnouncement, ChannelUpdate, EcdsaSignature};
9use crate::serde_utils::PartialSignatureAsBytes;
10use crate::serde_utils::PubNonceAsBytes;
11use crate::EntityHex;
12use crate::Hash256;
13use crate::Privkey;
14use crate::Pubkey;
15use bitflags::bitflags;
16use ckb_types::packed::Byte32 as MByte32;
17use ckb_types::packed::Script;
18use ckb_types::packed::Transaction;
19use ckb_types::prelude::{Pack, Unpack};
20use ckb_types::H256;
21use molecule::prelude::{Builder, Entity};
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 }
116
117 #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
118 #[serde(transparent)]
119 pub struct AppliedFlags: u8 {
120 const ADD = 1;
121 const REMOVE = 1 << 1;
122 }
123}
124
125#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord, Hash)]
127pub enum TLCId {
128 Offered(u64),
130 Received(u64),
132}
133
134impl From<TLCId> for u64 {
135 fn from(id: TLCId) -> u64 {
136 match id {
137 TLCId::Offered(id) => id,
138 TLCId::Received(id) => id,
139 }
140 }
141}
142
143impl TLCId {
144 pub fn is_offered(&self) -> bool {
145 matches!(self, TLCId::Offered(_))
146 }
147
148 pub fn is_received(&self) -> bool {
149 !self.is_offered()
150 }
151
152 pub fn flip(&self) -> Self {
153 match self {
154 TLCId::Offered(id) => TLCId::Received(*id),
155 TLCId::Received(id) => TLCId::Offered(*id),
156 }
157 }
158
159 pub fn flip_mut(&mut self) {
160 *self = self.flip();
161 }
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
166pub enum OutboundTlcStatus {
167 LocalAnnounced,
169 Committed,
171 RemoteRemoved,
173 RemoveWaitPrevAck,
176 RemoveWaitAck,
178 RemoveAckConfirmed,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
184pub enum InboundTlcStatus {
185 RemoteAnnounced,
187 AnnounceWaitPrevAck,
190 AnnounceWaitAck,
192 Committed,
194 LocalRemoved,
196 RemoveAckConfirmed,
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
202pub enum TlcStatus {
203 Outbound(OutboundTlcStatus),
205 Inbound(InboundTlcStatus),
207}
208
209impl TlcStatus {
210 pub fn as_outbound_status(&self) -> OutboundTlcStatus {
211 match self {
212 TlcStatus::Outbound(status) => status.clone(),
213 _ => {
214 unreachable!("unexpected status")
215 }
216 }
217 }
218
219 pub fn as_inbound_status(&self) -> InboundTlcStatus {
220 match self {
221 TlcStatus::Inbound(status) => status.clone(),
222 _ => {
223 unreachable!("unexpected status ")
224 }
225 }
226 }
227}
228
229#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
236pub enum ChannelState {
237 NegotiatingFunding(NegotiatingFundingFlags),
242 CollaboratingFundingTx(CollaboratingFundingTxFlags),
244 SigningCommitment(SigningCommitmentFlags),
246 AwaitingTxSignatures(AwaitingTxSignaturesFlags),
249 AwaitingChannelReady(AwaitingChannelReadyFlags),
252 ChannelReady,
255 ShuttingDown(ShuttingDownFlags),
257 Closed(CloseFlags),
259}
260
261#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
262pub enum ChannelConnectivityState {
263 Online,
264 Offline,
265 Syncing,
266}
267
268#[serde_as]
269#[derive(Clone, Debug, Serialize, Deserialize)]
270pub struct ExternalFundingPersistState {
271 #[serde_as(as = "EntityHex")]
272 pub funding_lock_script: Script,
273 #[serde_as(as = "Vec<EntityHex>")]
274 pub funding_lock_script_cell_deps: Vec<ckb_types::packed::CellDep>,
275 #[serde_as(as = "EntityHex")]
276 pub unsigned_funding_tx: Transaction,
277 pub started_at_ms: u64,
278 pub signed_submitted: bool,
279 pub peer_commitment_signed_received: bool,
280}
281
282impl ChannelState {
283 pub fn is_awaiting_external_funding(&self) -> bool {
284 matches!(
285 self,
286 ChannelState::NegotiatingFunding(flags)
287 if flags.contains(NegotiatingFundingFlags::AWAITING_EXTERNAL_FUNDING)
288 )
289 }
290
291 pub fn is_closed(&self) -> bool {
292 matches!(
293 self,
294 ChannelState::Closed(_)
295 | ChannelState::ShuttingDown(ShuttingDownFlags::WAITING_COMMITMENT_CONFIRMATION)
296 )
297 }
298
299 pub fn can_abort_funding(&self) -> bool {
300 match self {
301 ChannelState::NegotiatingFunding(_)
302 | ChannelState::CollaboratingFundingTx(_)
303 | ChannelState::SigningCommitment(_) => true,
304 ChannelState::AwaitingTxSignatures(flags)
305 if !flags.contains(AwaitingTxSignaturesFlags::OUR_TX_SIGNATURES_SENT) =>
306 {
307 true
308 }
309 _ => false,
310 }
311 }
312}
313
314impl ShuttingDownFlags {
315 pub fn is_ok_for_commitment_operation(&self) -> bool {
316 !self.contains(ShuttingDownFlags::DROPPING_PENDING)
317 && !self.contains(ShuttingDownFlags::WAITING_COMMITMENT_CONFIRMATION)
318 }
319}
320
321pub const INITIAL_COMMITMENT_NUMBER: u64 = 0;
323
324#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
326pub struct CommitmentNumbers {
327 pub local: u64,
328 pub remote: u64,
329}
330
331impl Default for CommitmentNumbers {
332 fn default() -> Self {
333 Self::new()
334 }
335}
336
337impl CommitmentNumbers {
338 pub fn new() -> Self {
339 Self {
340 local: INITIAL_COMMITMENT_NUMBER,
341 remote: INITIAL_COMMITMENT_NUMBER,
342 }
343 }
344
345 pub fn get_local(&self) -> u64 {
346 self.local
347 }
348
349 pub fn get_remote(&self) -> u64 {
350 self.remote
351 }
352
353 pub fn increment_local(&mut self) {
354 self.local += 1;
355 }
356
357 pub fn increment_remote(&mut self) {
358 self.remote += 1;
359 }
360}
361
362#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
364pub struct ChannelConstraints {
365 pub max_tlc_value_in_flight: u128,
367 pub max_tlc_number_in_flight: u64,
369}
370
371impl ChannelConstraints {
372 pub fn new(max_tlc_value_in_flight: u128, max_tlc_number_in_flight: u64) -> Self {
373 Self {
374 max_tlc_value_in_flight,
375 max_tlc_number_in_flight,
376 }
377 }
378}
379
380#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
383pub struct ChannelTlcInfo {
384 pub timestamp: u64,
386
387 pub enabled: bool,
389
390 pub tlc_fee_proportional_millionths: u128,
396
397 pub tlc_expiry_delta: u64,
399
400 pub tlc_minimum_value: u128,
402}
403
404impl ChannelTlcInfo {
405 pub fn new(
407 tlc_minimum_value: u128,
408 tlc_expiry_delta: u64,
409 tlc_fee_proportional_millionths: u128,
410 timestamp: u64,
411 ) -> Self {
412 Self {
413 tlc_minimum_value,
414 tlc_expiry_delta,
415 tlc_fee_proportional_millionths,
416 enabled: true,
417 timestamp,
418 }
419 }
420}
421
422#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
424pub struct ChannelBasePublicKeys {
425 pub funding_pubkey: Pubkey,
428 pub tlc_base_key: Pubkey,
431}
432
433#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
436pub struct PrevTlcInfo {
437 pub prev_channel_id: Hash256,
438 pub prev_tlc_id: u64,
440 pub forwarding_fee: u128,
441 pub shared_secret: Option<[u8; 32]>,
442}
443
444impl PrevTlcInfo {
445 pub fn new(prev_channel_id: Hash256, prev_tlc_id: u64, forwarding_fee: u128) -> Self {
446 Self {
447 prev_channel_id,
448 prev_tlc_id,
449 forwarding_fee,
450 shared_secret: None,
451 }
452 }
453
454 pub fn new_with_shared_secret(
455 prev_channel_id: Hash256,
456 prev_tlc_id: u64,
457 forwarding_fee: u128,
458 shared_secret: [u8; 32],
459 ) -> Self {
460 Self {
461 prev_channel_id,
462 prev_tlc_id,
463 forwarding_fee,
464 shared_secret: Some(shared_secret),
465 }
466 }
467}
468
469#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
470pub struct TlcInfo {
471 pub status: TlcStatus,
472 pub tlc_id: TLCId,
473 pub amount: u128,
474 pub payment_hash: Hash256,
475 pub total_amount: Option<u128>,
477 pub payment_secret: Option<Hash256>,
479 pub attempt_id: Option<u64>,
482 pub expiry: u64,
483 pub hash_algorithm: HashAlgorithm,
484 pub onion_packet: Option<PaymentOnionPacket>,
486 pub shared_secret: [u8; 32],
490 #[serde(default)]
491 pub is_trampoline_hop: bool,
492 pub created_at: CommitmentNumbers,
493 pub removed_reason: Option<RemoveTlcReason>,
494
495 pub forwarding_tlc: Option<(Hash256, u64)>,
521 pub removed_confirmed_at: Option<u64>,
522 pub applied_flags: AppliedFlags,
523}
524
525use std::fmt;
526use std::time::Duration;
527
528impl fmt::Debug for TlcInfo {
529 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
530 f.debug_struct("TlcInfo")
531 .field("status", &self.status)
532 .field("tlc_id", &self.tlc_id)
533 .field("amount", &self.amount)
534 .field("payment_hash", &self.payment_hash)
535 .field("expiry", &self.expiry)
536 .field("created_at", &self.created_at)
537 .field("removed_reason", &self.removed_reason)
538 .field("applied_flags", &self.applied_flags)
539 .finish()
540 }
541}
542
543impl TlcInfo {
544 pub fn log(&self) -> String {
545 format!(
546 "id: {:?} status: {:?} amount: {:?} removed: {:?} hash: {:?} ",
547 &self.tlc_id, self.status, self.amount, self.removed_reason, self.payment_hash,
548 )
549 }
550
551 pub fn id(&self) -> u64 {
552 self.tlc_id.into()
553 }
554
555 pub fn is_offered(&self) -> bool {
556 self.tlc_id.is_offered()
557 }
558
559 pub fn is_received(&self) -> bool {
560 !self.is_offered()
561 }
562
563 pub fn get_commitment_numbers(&self) -> CommitmentNumbers {
564 self.created_at
565 }
566
567 pub fn flip_mut(&mut self) {
568 self.tlc_id.flip_mut();
569 }
570
571 pub fn outbound_status(&self) -> OutboundTlcStatus {
572 self.status.as_outbound_status()
573 }
574
575 pub fn inbound_status(&self) -> InboundTlcStatus {
576 self.status.as_inbound_status()
577 }
578
579 pub fn is_fail_remove_confirmed(&self) -> bool {
580 matches!(self.removed_reason, Some(RemoveTlcReason::RemoveTlcFail(_)))
581 && matches!(
582 self.status,
583 TlcStatus::Outbound(OutboundTlcStatus::RemoveAckConfirmed)
584 | TlcStatus::Outbound(OutboundTlcStatus::RemoveWaitAck)
585 | TlcStatus::Inbound(InboundTlcStatus::RemoveAckConfirmed)
586 )
587 }
588
589 pub fn get_htlc_type(&self) -> u8 {
595 let offered_flag = if self.is_offered() { 0u8 } else { 1u8 };
596 ((self.hash_algorithm as u8) << 1) + offered_flag
597 }
598}
599
600#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
602pub struct PendingTlcs {
603 pub tlcs: Vec<TlcInfo>,
604 pub next_tlc_id: u64,
605}
606
607impl PendingTlcs {
608 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TlcInfo> {
609 self.tlcs.iter_mut()
610 }
611
612 pub fn get_next_id(&self) -> u64 {
613 self.next_tlc_id
614 }
615
616 pub fn increment_next_id(&mut self) {
617 self.next_tlc_id += 1;
618 }
619
620 pub fn add_tlc(&mut self, tlc: TlcInfo) {
621 self.tlcs.push(tlc);
622 }
623}
624
625#[derive(Default, Clone, Debug, Serialize, Deserialize)]
627pub struct TlcState {
628 pub offered_tlcs: PendingTlcs,
629 pub received_tlcs: PendingTlcs,
630 pub waiting_ack: bool,
631}
632
633impl TlcState {
634 pub fn info(&self) -> String {
635 format!(
636 "offer_tlcs: {:?} received_tlcs: {:?}",
637 self.offered_tlcs.tlcs.len(),
638 self.received_tlcs.tlcs.len(),
639 )
640 }
641
642 #[cfg(debug_assertions)]
643 pub fn debug(&self) {
644 let format_tlc_list = |tlcs: &[TlcInfo]| -> String {
645 if tlcs.is_empty() {
646 " <none>".to_string()
647 } else {
648 tlcs.iter()
649 .map(|tlc| format!(" {}", tlc.log()))
650 .collect::<Vec<_>>()
651 .join("\n")
652 }
653 };
654
655 let offered_str = format_tlc_list(&self.offered_tlcs.tlcs);
656 let received_str = format_tlc_list(&self.received_tlcs.tlcs);
657
658 if offered_str.contains("<none>") && received_str.contains("<none>") {
659 tracing::info!("TlcState: <none>");
660 } else {
661 tracing::info!(
662 "TlcState:\n Offered:\n{}\n Received:\n{}",
663 offered_str,
664 received_str
665 );
666 }
667 }
668
669 pub fn get_mut(&mut self, tlc_id: &TLCId) -> Option<&mut TlcInfo> {
670 self.offered_tlcs
671 .tlcs
672 .iter_mut()
673 .find(|tlc| tlc.tlc_id == *tlc_id)
674 .or_else(|| {
675 self.received_tlcs
676 .tlcs
677 .iter_mut()
678 .find(|tlc| tlc.tlc_id == *tlc_id)
679 })
680 }
681
682 pub fn get(&self, tlc_id: &TLCId) -> Option<&TlcInfo> {
683 if tlc_id.is_offered() {
684 self.offered_tlcs
685 .tlcs
686 .iter()
687 .find(|tlc| tlc.tlc_id == *tlc_id)
688 } else {
689 self.received_tlcs
690 .tlcs
691 .iter()
692 .find(|tlc| tlc.tlc_id == *tlc_id)
693 }
694 }
695
696 pub fn get_committed_received_tlcs(&self) -> impl Iterator<Item = &TlcInfo> + '_ {
697 self.received_tlcs.tlcs.iter().filter(|tlc| {
698 debug_assert!(tlc.is_received());
699 matches!(tlc.inbound_status(), InboundTlcStatus::Committed)
700 })
701 }
702
703 pub fn get_expired_offered_tlcs(
704 &self,
705 expect_expiry: u64,
706 ) -> impl Iterator<Item = &TlcInfo> + '_ {
707 self.offered_tlcs.tlcs.iter().filter(move |tlc| {
708 tlc.outbound_status() != OutboundTlcStatus::LocalAnnounced
709 && tlc.removed_confirmed_at.is_none()
710 && tlc.expiry < expect_expiry
711 })
712 }
713
714 pub fn get_next_offering(&self) -> u64 {
715 self.offered_tlcs.get_next_id()
716 }
717
718 pub fn get_next_received(&self) -> u64 {
719 self.received_tlcs.get_next_id()
720 }
721
722 pub fn increment_offering(&mut self) {
723 self.offered_tlcs.increment_next_id();
724 }
725
726 pub fn increment_received(&mut self) {
727 self.received_tlcs.increment_next_id();
728 }
729
730 pub fn set_waiting_ack(&mut self, waiting_ack: bool) {
731 self.waiting_ack = waiting_ack;
732 }
733
734 pub fn all_tlcs(&self) -> impl Iterator<Item = &TlcInfo> + '_ {
735 self.offered_tlcs
736 .tlcs
737 .iter()
738 .chain(self.received_tlcs.tlcs.iter())
739 }
740
741 pub fn apply_remove_tlc(&mut self, tlc_id: TLCId) {
742 if tlc_id.is_offered() {
743 self.offered_tlcs.tlcs.retain(|tlc| tlc.tlc_id != tlc_id);
744 } else {
745 self.received_tlcs.tlcs.retain(|tlc| tlc.tlc_id != tlc_id);
746 }
747 }
748
749 pub fn add_offered_tlc(&mut self, tlc: TlcInfo) {
750 self.offered_tlcs.add_tlc(tlc);
751 }
752
753 pub fn add_received_tlc(&mut self, tlc: TlcInfo) {
754 self.received_tlcs.add_tlc(tlc);
755 }
756
757 pub fn set_received_tlc_removed(&mut self, tlc_id: u64, reason: RemoveTlcReason) -> Hash256 {
758 let tlc = self.get_mut(&TLCId::Received(tlc_id)).expect("get tlc");
759 assert_eq!(tlc.inbound_status(), InboundTlcStatus::Committed);
760 tlc.removed_reason = Some(reason);
761 tlc.status = TlcStatus::Inbound(InboundTlcStatus::LocalRemoved);
762 tlc.payment_hash
763 }
764
765 pub fn set_offered_tlc_removed(&mut self, tlc_id: u64, reason: RemoveTlcReason) -> Hash256 {
766 let tlc = self.get_mut(&TLCId::Offered(tlc_id)).expect("get tlc");
767 assert_eq!(tlc.outbound_status(), OutboundTlcStatus::Committed);
768 tlc.removed_reason = Some(reason);
769 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoteRemoved);
770 tlc.payment_hash
771 }
772
773 pub fn commitment_signed_tlcs(&self, for_remote: bool) -> impl Iterator<Item = &TlcInfo> + '_ {
774 self.offered_tlcs
775 .tlcs
776 .iter()
777 .filter(move |tlc| match tlc.outbound_status() {
778 OutboundTlcStatus::LocalAnnounced => for_remote,
779 OutboundTlcStatus::Committed => true,
780 OutboundTlcStatus::RemoteRemoved => for_remote,
781 OutboundTlcStatus::RemoveWaitPrevAck => for_remote,
782 OutboundTlcStatus::RemoveWaitAck => false,
783 OutboundTlcStatus::RemoveAckConfirmed => false,
784 })
785 .chain(
786 self.received_tlcs
787 .tlcs
788 .iter()
789 .filter(move |tlc| match tlc.inbound_status() {
790 InboundTlcStatus::RemoteAnnounced => !for_remote,
791 InboundTlcStatus::AnnounceWaitPrevAck => !for_remote,
792 InboundTlcStatus::AnnounceWaitAck => true,
793 InboundTlcStatus::Committed => true,
794 InboundTlcStatus::LocalRemoved => !for_remote,
795 InboundTlcStatus::RemoveAckConfirmed => false,
796 }),
797 )
798 }
799
800 pub fn update_for_commitment_signed(&mut self) -> bool {
801 for tlc in self.offered_tlcs.tlcs.iter_mut() {
802 if tlc.outbound_status() == OutboundTlcStatus::RemoteRemoved {
803 let status = if self.waiting_ack {
804 OutboundTlcStatus::RemoveWaitPrevAck
805 } else {
806 OutboundTlcStatus::RemoveWaitAck
807 };
808 tlc.status = TlcStatus::Outbound(status);
809 }
810 }
811 for tlc in self.received_tlcs.tlcs.iter_mut() {
812 if tlc.inbound_status() == InboundTlcStatus::RemoteAnnounced {
813 let status = if self.waiting_ack {
814 InboundTlcStatus::AnnounceWaitPrevAck
815 } else {
816 InboundTlcStatus::AnnounceWaitAck
817 };
818 tlc.status = TlcStatus::Inbound(status)
819 }
820 }
821 self.need_another_commitment_signed()
822 }
823
824 pub fn update_for_revoke_and_ack(&mut self, commitment_number: CommitmentNumbers) {
825 for tlc in self.offered_tlcs.tlcs.iter_mut() {
826 match tlc.outbound_status() {
827 OutboundTlcStatus::LocalAnnounced => {
828 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::Committed);
829 }
830 OutboundTlcStatus::RemoveWaitPrevAck => {
831 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoveWaitAck);
832 }
833 OutboundTlcStatus::RemoveWaitAck => {
834 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoveAckConfirmed);
835 tlc.removed_confirmed_at = Some(commitment_number.get_local());
836 }
837 _ => {}
838 }
839 }
840
841 for tlc in self.received_tlcs.tlcs.iter_mut() {
842 match tlc.inbound_status() {
843 InboundTlcStatus::AnnounceWaitPrevAck => {
844 tlc.status = TlcStatus::Inbound(InboundTlcStatus::AnnounceWaitAck);
845 }
846 InboundTlcStatus::AnnounceWaitAck => {
847 tlc.status = TlcStatus::Inbound(InboundTlcStatus::Committed);
848 }
849 InboundTlcStatus::LocalRemoved => {
850 tlc.status = TlcStatus::Inbound(InboundTlcStatus::RemoveAckConfirmed);
851 tlc.removed_confirmed_at = Some(commitment_number.get_remote());
852 }
853 _ => {}
854 }
855 }
856 }
857
858 pub fn need_another_commitment_signed(&self) -> bool {
859 self.offered_tlcs.tlcs.iter().any(|tlc| {
860 let status = tlc.outbound_status();
861 matches!(
862 status,
863 OutboundTlcStatus::LocalAnnounced
864 | OutboundTlcStatus::RemoteRemoved
865 | OutboundTlcStatus::RemoveWaitPrevAck
866 | OutboundTlcStatus::RemoveWaitAck
867 )
868 }) || self.received_tlcs.tlcs.iter().any(|tlc| {
869 let status = tlc.inbound_status();
870 matches!(
871 status,
872 InboundTlcStatus::RemoteAnnounced
873 | InboundTlcStatus::AnnounceWaitPrevAck
874 | InboundTlcStatus::AnnounceWaitAck
875 )
876 })
877 }
878}
879
880#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
882pub struct AddTlcCommand {
883 pub amount: u128,
884 pub payment_hash: Hash256,
885 pub attempt_id: Option<u64>,
887 pub expiry: u64,
888 pub hash_algorithm: HashAlgorithm,
889 pub onion_packet: Option<PaymentOnionPacket>,
891 pub shared_secret: [u8; 32],
895 pub is_trampoline_hop: bool,
897 pub previous_tlc: Option<PrevTlcInfo>,
898}
899
900impl fmt::Debug for AddTlcCommand {
901 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
902 f.debug_struct("AddTlcCommand")
903 .field("amount", &self.amount)
904 .field("payment_hash", &self.payment_hash)
905 .field("attempt_id", &self.attempt_id)
906 .field("expiry", &self.expiry)
907 .field("hash_algorithm", &self.hash_algorithm)
908 .field("is_trampoline_hop", &self.is_trampoline_hop)
909 .field("previous_tlc", &self.previous_tlc)
910 .finish()
911 }
912}
913
914#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug, Hash)]
916pub enum RetryableTlcOperation {
917 RemoveTlc(TLCId, RemoveTlcReason),
918 AddTlc(AddTlcCommand),
919}
920
921#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
923pub struct AddTlc {
924 pub channel_id: Hash256,
925 pub tlc_id: u64,
926 pub amount: u128,
927 pub payment_hash: Hash256,
928 pub expiry: u64,
929 pub hash_algorithm: HashAlgorithm,
930 pub onion_packet: Option<PaymentOnionPacket>,
931}
932
933impl fmt::Debug for AddTlc {
934 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
935 f.debug_struct("AddTlc")
936 .field("channel_id", &self.channel_id)
937 .field("tlc_id", &self.tlc_id)
938 .field("amount", &self.amount)
939 .field("payment_hash", &self.payment_hash)
940 .field("expiry", &self.expiry)
941 .field("hash_algorithm", &self.hash_algorithm)
942 .finish()
943 }
944}
945
946impl From<AddTlc> for molecule_fiber::AddTlc {
947 fn from(add_tlc: AddTlc) -> Self {
948 molecule_fiber::AddTlc::new_builder()
949 .channel_id(add_tlc.channel_id.into())
950 .tlc_id(add_tlc.tlc_id.pack())
951 .amount(add_tlc.amount.pack())
952 .payment_hash(add_tlc.payment_hash.into())
953 .expiry(add_tlc.expiry.pack())
954 .hash_algorithm(molecule::prelude::Byte::new(add_tlc.hash_algorithm as u8))
955 .onion_packet(
956 add_tlc
957 .onion_packet
958 .map(|p| p.into_bytes())
959 .unwrap_or_default()
960 .pack(),
961 )
962 .build()
963 }
964}
965
966impl TryFrom<molecule_fiber::AddTlc> for AddTlc {
967 type Error = anyhow::Error;
968
969 fn try_from(add_tlc: molecule_fiber::AddTlc) -> Result<Self, Self::Error> {
970 let onion_packet_bytes: Vec<u8> = add_tlc.onion_packet().unpack();
971 let onion_packet =
972 (!onion_packet_bytes.is_empty()).then(|| PaymentOnionPacket::new(onion_packet_bytes));
973 Ok(AddTlc {
974 onion_packet,
975 channel_id: add_tlc.channel_id().into(),
976 tlc_id: add_tlc.tlc_id().unpack(),
977 amount: add_tlc.amount().unpack(),
978 payment_hash: add_tlc.payment_hash().into(),
979 expiry: add_tlc.expiry().unpack(),
980 hash_algorithm: add_tlc
981 .hash_algorithm()
982 .try_into()
983 .map_err(|e: crate::invoice::UnknownHashAlgorithmError| anyhow::anyhow!(e))?,
984 })
985 }
986}
987
988#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
990pub struct RemoveTlc {
991 pub channel_id: Hash256,
992 pub tlc_id: u64,
993 pub reason: RemoveTlcReason,
994}
995
996impl From<RemoveTlc> for molecule_fiber::RemoveTlc {
997 fn from(remove_tlc: RemoveTlc) -> Self {
998 molecule_fiber::RemoveTlc::new_builder()
999 .channel_id(remove_tlc.channel_id.into())
1000 .tlc_id(remove_tlc.tlc_id.pack())
1001 .reason(
1002 molecule_fiber::RemoveTlcReason::new_builder()
1003 .set(remove_tlc.reason)
1004 .build(),
1005 )
1006 .build()
1007 }
1008}
1009
1010impl TryFrom<molecule_fiber::RemoveTlc> for RemoveTlc {
1011 type Error = anyhow::Error;
1012
1013 fn try_from(remove_tlc: molecule_fiber::RemoveTlc) -> Result<Self, Self::Error> {
1014 Ok(RemoveTlc {
1015 channel_id: remove_tlc.channel_id().into(),
1016 tlc_id: remove_tlc.tlc_id().unpack(),
1017 reason: remove_tlc.reason().into(),
1018 })
1019 }
1020}
1021
1022#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug, Hash)]
1024pub enum TlcReplayUpdate {
1025 Add(AddTlc),
1026 Remove(RemoveTlc),
1027}
1028
1029pub const CURRENT_COMMIT_DIFF_VERSION: u8 = 2;
1031
1032fn default_commit_diff_version() -> u8 {
1033 CURRENT_COMMIT_DIFF_VERSION
1034}
1035
1036#[serde_as]
1038#[derive(Clone, Debug, Serialize, Deserialize)]
1039pub struct CommitmentSignedTemplate {
1040 #[serde_as(as = "PubNonceAsBytes")]
1041 pub next_commitment_nonce: PubNonce,
1042 #[serde(default)]
1043 #[serde_as(as = "Option<PartialSignatureAsBytes>")]
1044 pub funding_tx_partial_signature: Option<PartialSignature>,
1045}
1046
1047#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1049pub enum ReplayOrderHint {
1050 RevokeThenCommit,
1051 CommitThenRevoke,
1052}
1053
1054#[serde_as]
1056#[derive(Clone, Debug, Serialize, Deserialize)]
1057pub struct CommitDiff {
1058 #[serde(default = "default_commit_diff_version")]
1060 pub version: u8,
1061 #[serde(default)]
1063 pub channel_id: Hash256,
1064 #[serde(default)]
1066 pub local_commitment_number_at_send: u64,
1067 #[serde(default)]
1068 pub remote_commitment_number_at_send: u64,
1069 #[serde_as(as = "EntityHex")]
1071 pub commit_tx: Transaction,
1072 #[serde(default, alias = "tlc_updates")]
1074 pub replay_updates: Vec<TlcReplayUpdate>,
1075 #[serde(default)]
1077 pub commitment_signed_template: Option<CommitmentSignedTemplate>,
1078 #[serde(default)]
1080 pub replay_order_hint: Option<ReplayOrderHint>,
1081 #[serde(default, alias = "created_at")]
1083 pub created_at_ms: u64,
1084}
1085
1086#[serde_as]
1088#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
1089pub struct ShutdownInfo {
1090 #[serde_as(as = "EntityHex")]
1091 pub close_script: Script,
1092 pub fee_rate: u64,
1093 #[serde_as(as = "Option<PartialSignatureAsBytes>")]
1094 pub signature: Option<PartialSignature>,
1095}
1096
1097#[serde_as]
1099#[derive(Debug, Clone, Serialize, Deserialize)]
1100pub struct RevokeAndAck {
1101 pub channel_id: Hash256,
1102 #[serde_as(as = "PartialSignatureAsBytes")]
1103 pub revocation_partial_signature: PartialSignature,
1104 pub next_per_commitment_point: Pubkey,
1105 #[serde_as(as = "PubNonceAsBytes")]
1106 pub next_revocation_nonce: PubNonce,
1107}
1108#[serde_as]
1115#[derive(Default, Clone, Debug, Serialize, Deserialize)]
1116pub struct PublicChannelInfo {
1117 #[serde_as(as = "Option<(_, PartialSignatureAsBytes)>")]
1119 pub local_channel_announcement_signature: Option<(EcdsaSignature, PartialSignature)>,
1120 #[serde_as(as = "Option<(_, PartialSignatureAsBytes)>")]
1121 pub remote_channel_announcement_signature: Option<(EcdsaSignature, PartialSignature)>,
1122 #[serde_as(as = "Option<PubNonceAsBytes>")]
1123 pub remote_channel_announcement_nonce: Option<PubNonce>,
1124 pub channel_announcement: Option<ChannelAnnouncement>,
1125 pub channel_update: Option<ChannelUpdate>,
1126}
1127
1128impl PublicChannelInfo {
1129 pub fn new() -> Self {
1130 Default::default()
1131 }
1132}
1133
1134#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
1139pub struct InMemorySigner {
1140 pub funding_key: Privkey,
1142 pub tlc_base_key: Privkey,
1144 pub musig2_base_nonce: Privkey,
1146 pub commitment_seed: [u8; 32],
1148}
1149
1150impl fmt::Debug for InMemorySigner {
1151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1152 f.debug_struct("InMemorySigner")
1153 .field("funding_key", &"[REDACTED]")
1154 .field("tlc_base_key", &"[REDACTED]")
1155 .field("musig2_base_nonce", &"[REDACTED]")
1156 .field("commitment_seed", &"[REDACTED]")
1157 .finish()
1158 }
1159}
1160
1161pub fn blake2b_hash_with_salt(data: &[u8], salt: &[u8]) -> [u8; 32] {
1163 let mut hasher = ckb_hash::new_blake2b();
1164 hasher.update(salt);
1165 hasher.update(data);
1166 let mut result = [0u8; 32];
1167 hasher.finalize(&mut result);
1168 result
1169}
1170
1171pub fn get_tweak_by_commitment_point(commitment_point: &Pubkey) -> [u8; 32] {
1173 let mut hasher = ckb_hash::new_blake2b();
1174 hasher.update(&commitment_point.serialize());
1175 let mut result = [0u8; 32];
1176 hasher.finalize(&mut result);
1177 result
1178}
1179
1180pub fn derive_private_key(secret: &Privkey, commitment_point: &Pubkey) -> Privkey {
1182 secret.tweak(get_tweak_by_commitment_point(commitment_point))
1183}
1184
1185pub fn derive_public_key(base_key: &Pubkey, commitment_point: &Pubkey) -> Pubkey {
1187 base_key.tweak(get_tweak_by_commitment_point(commitment_point))
1188}
1189
1190pub fn derive_tlc_pubkey(base_key: &Pubkey, commitment_point: &Pubkey) -> Pubkey {
1192 derive_public_key(base_key, commitment_point)
1193}
1194
1195pub fn get_commitment_secret(commitment_seed: &[u8; 32], commitment_number: u64) -> [u8; 32] {
1199 let mut res: [u8; 32] = *commitment_seed;
1200 for i in 0..48 {
1201 let bitpos = 47 - i;
1202 if commitment_number & (1 << bitpos) == (1 << bitpos) {
1203 res[bitpos / 8] ^= 1 << (bitpos & 7);
1204 res = ckb_hash::blake2b_256(res);
1205 }
1206 }
1207 res
1208}
1209
1210pub fn get_commitment_point(commitment_seed: &[u8; 32], commitment_number: u64) -> Pubkey {
1212 Privkey::from(&get_commitment_secret(commitment_seed, commitment_number)).pubkey()
1213}
1214
1215pub enum Musig2Context {
1217 Commitment,
1219 Revoke,
1221}
1222
1223impl std::fmt::Display for Musig2Context {
1224 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1225 let context_str = match self {
1226 Musig2Context::Commitment => "COMMITMENT",
1227 Musig2Context::Revoke => "REVOKE",
1228 };
1229 write!(f, "{}", context_str)
1230 }
1231}
1232
1233impl InMemorySigner {
1234 pub fn generate_from_seed(params: &[u8]) -> InMemorySigner {
1236 let seed = ckb_hash::blake2b_256(params);
1237
1238 let commitment_seed = {
1239 let mut hasher = ckb_hash::new_blake2b();
1240 hasher.update(&seed);
1241 hasher.update(&b"commitment seed"[..]);
1242 let mut result = [0u8; 32];
1243 hasher.finalize(&mut result);
1244 result
1245 };
1246
1247 let key_derive = |seed: &[u8], info: &[u8]| {
1248 let result = blake2b_hash_with_salt(seed, info);
1249 Privkey::from_slice(&result)
1250 };
1251
1252 let funding_key = key_derive(&seed, b"funding key");
1253 let tlc_base_key = key_derive(funding_key.as_ref(), b"HTLC base key");
1254 let musig2_base_nonce = key_derive(tlc_base_key.as_ref(), b"musig nocne");
1255
1256 InMemorySigner {
1257 funding_key,
1258 tlc_base_key,
1259 musig2_base_nonce,
1260 commitment_seed,
1261 }
1262 }
1263
1264 pub fn get_base_public_keys(&self) -> ChannelBasePublicKeys {
1266 ChannelBasePublicKeys {
1267 funding_pubkey: self.funding_key.pubkey(),
1268 tlc_base_key: self.tlc_base_key.pubkey(),
1269 }
1270 }
1271
1272 pub fn get_commitment_point(&self, commitment_number: u64) -> Pubkey {
1278 get_commitment_point(&self.commitment_seed, commitment_number)
1279 }
1280
1281 pub fn get_commitment_secret(&self, commitment_number: u64) -> [u8; 32] {
1283 get_commitment_secret(&self.commitment_seed, commitment_number)
1284 }
1285
1286 pub fn derive_tlc_key(&self, new_commitment_number: u64) -> Privkey {
1288 let per_commitment_point = self.get_commitment_point(new_commitment_number);
1289 derive_private_key(&self.tlc_base_key, &per_commitment_point)
1290 }
1291
1292 pub fn derive_musig2_nonce(&self, commitment_number: u64, context: Musig2Context) -> SecNonce {
1294 let commitment_point = self.get_commitment_point(commitment_number);
1295 let seckey = derive_private_key(&self.musig2_base_nonce, &commitment_point);
1296
1297 SecNonceBuilder::new(seckey.as_ref())
1298 .with_extra_input(&context.to_string())
1299 .build()
1300 }
1301}
1302
1303#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
1305pub enum ChannelOpeningStatus {
1306 WaitingForPeer,
1309 FundingTxBuilding,
1311 FundingTxBroadcasted,
1313 ChannelReady,
1315 Failed,
1317}
1318
1319#[serde_as]
1325#[derive(Clone, Debug, Serialize, Deserialize)]
1326pub struct ChannelOpenRecord {
1327 pub channel_id: Hash256,
1332 pub pubkey: Pubkey,
1334 pub is_acceptor: bool,
1336 pub status: ChannelOpeningStatus,
1338 pub funding_amount: u128,
1342 pub failure_detail: Option<String>,
1344 pub created_at: u64,
1346 pub last_updated_at: u64,
1348}
1349
1350impl ChannelOpenRecord {
1351 pub fn new(channel_id: Hash256, pubkey: Pubkey, funding_amount: u128) -> Self {
1353 let now = crate::now_timestamp_as_millis_u64();
1354 Self {
1355 channel_id,
1356 pubkey,
1357 is_acceptor: false,
1358 status: ChannelOpeningStatus::WaitingForPeer,
1359 funding_amount,
1360 failure_detail: None,
1361 created_at: now,
1362 last_updated_at: now,
1363 }
1364 }
1365
1366 pub fn new_inbound(channel_id: Hash256, pubkey: Pubkey, remote_funding_amount: u128) -> Self {
1369 let mut record = Self::new(channel_id, pubkey, remote_funding_amount);
1370 record.is_acceptor = true;
1371 record
1372 }
1373
1374 pub fn update_status(&mut self, status: ChannelOpeningStatus) {
1376 self.status = status;
1377 self.last_updated_at = crate::now_timestamp_as_millis_u64();
1378 }
1379
1380 pub fn fail(&mut self, reason: String) {
1382 self.status = ChannelOpeningStatus::Failed;
1383 self.failure_detail = Some(reason);
1384 self.last_updated_at = crate::now_timestamp_as_millis_u64();
1385 }
1386}
1387
1388pub trait ChannelOpenRecordStore {
1390 fn get_channel_open_records(&self) -> Vec<ChannelOpenRecord>;
1392 fn get_channel_open_record(&self, channel_id: &Hash256) -> Option<ChannelOpenRecord>;
1394 fn insert_channel_open_record(&self, record: ChannelOpenRecord);
1396 fn delete_channel_open_record(&self, channel_id: &Hash256);
1398}
1399
1400#[derive(Clone, Serialize, Deserialize, Debug)]
1402pub struct PendingNotifySettleTlc {
1403 pub payment_hash: Hash256,
1404 pub tlc_id: u64,
1405 pub hold_expire_at: Option<u64>,
1407}
1408
1409impl PendingNotifySettleTlc {
1410 pub fn pending_notify_should_hold(&self) -> bool {
1412 self.hold_expire_at.is_some()
1413 }
1414
1415 pub fn pending_notify_hold_expiry_duration(
1417 &self,
1418 now_millis_since_unix_epoch: u64,
1419 ) -> Duration {
1420 Duration::from_millis(
1421 self.hold_expire_at
1422 .unwrap_or_default()
1423 .saturating_sub(now_millis_since_unix_epoch),
1424 )
1425 }
1426}
1427
1428#[serde_as]
1433#[derive(Clone, Serialize, Deserialize)]
1434pub struct ChannelActorData {
1435 pub state: ChannelState,
1436 pub public_channel_info: Option<PublicChannelInfo>,
1438
1439 pub local_tlc_info: ChannelTlcInfo,
1440 pub remote_tlc_info: Option<ChannelTlcInfo>,
1441
1442 pub local_pubkey: Pubkey,
1444 pub remote_pubkey: Pubkey,
1446
1447 pub id: Hash256,
1448 #[serde_as(as = "Option<EntityHex>")]
1449 pub funding_tx: Option<Transaction>,
1450
1451 pub funding_tx_confirmed_at: Option<(H256, u32, u64)>,
1452
1453 #[serde_as(as = "Option<EntityHex>")]
1454 pub funding_udt_type_script: Option<Script>,
1455
1456 pub is_acceptor: bool,
1459
1460 pub is_one_way: bool,
1463
1464 pub to_local_amount: u128,
1467 pub to_remote_amount: u128,
1470
1471 pub local_reserved_ckb_amount: u64,
1475 pub remote_reserved_ckb_amount: u64,
1476
1477 pub commitment_fee_rate: u64,
1480
1481 pub commitment_delay_epoch: u64,
1484
1485 pub funding_fee_rate: u64,
1488
1489 pub signer: InMemorySigner,
1491
1492 pub local_channel_public_keys: ChannelBasePublicKeys,
1494
1495 pub commitment_numbers: CommitmentNumbers,
1498
1499 pub local_constraints: ChannelConstraints,
1500 pub remote_constraints: ChannelConstraints,
1501
1502 pub tlc_state: TlcState,
1504
1505 pub retryable_tlc_operations: VecDeque<RetryableTlcOperation>,
1507 pub waiting_forward_tlc_tasks: HashMap<TLCId, [u8; 32]>,
1508
1509 #[serde_as(as = "Option<EntityHex>")]
1511 pub remote_shutdown_script: Option<Script>,
1512 #[serde_as(as = "EntityHex")]
1514 pub local_shutdown_script: Script,
1515
1516 #[serde_as(as = "Option<PubNonceAsBytes>")]
1519 pub last_committed_remote_nonce: Option<PubNonce>,
1520
1521 #[serde_as(as = "Option<PubNonceAsBytes>")]
1522 pub remote_revocation_nonce_for_verify: Option<PubNonce>,
1523 #[serde_as(as = "Option<PubNonceAsBytes>")]
1524 pub remote_revocation_nonce_for_send: Option<PubNonce>,
1525 #[serde_as(as = "Option<PubNonceAsBytes>")]
1526 pub remote_revocation_nonce_for_next: Option<PubNonce>,
1527
1528 #[serde_as(as = "Option<EntityHex>")]
1531 pub latest_commitment_transaction: Option<Transaction>,
1532
1533 pub remote_commitment_points: Vec<(u64, Pubkey)>,
1536 pub remote_channel_public_keys: Option<ChannelBasePublicKeys>,
1537
1538 pub local_shutdown_info: Option<ShutdownInfo>,
1540 pub remote_shutdown_info: Option<ShutdownInfo>,
1541
1542 pub shutdown_transaction_hash: Option<H256>,
1545
1546 pub reestablishing: bool,
1549 pub last_revoke_ack_msg: Option<RevokeAndAck>,
1550
1551 pub created_at: SystemTime,
1552
1553 #[serde(default)]
1556 pub pending_replay_updates: Vec<TlcReplayUpdate>,
1557
1558 #[serde(default)]
1560 pub last_was_revoke: bool,
1561
1562 pub connectivity_state: ChannelConnectivityState,
1564
1565 #[serde(default)]
1567 pub external_funding: Option<ExternalFundingPersistState>,
1568}
1569
1570fn partial_signature_to_molecule(partial_signature: PartialSignature) -> MByte32 {
1571 MByte32::from_slice(partial_signature.serialize().as_ref()).expect("[Byte; 32] from [u8; 32]")
1572}
1573
1574fn pub_nonce_to_molecule(pub_nonce: PubNonce) -> molecule_fiber::PubNonce {
1575 molecule_fiber::PubNonce::from_slice(pub_nonce.to_bytes().as_ref())
1576 .expect("PubNonce from 66 bytes")
1577}
1578
1579impl From<PubNonce> for molecule_fiber::PubNonce {
1580 fn from(value: PubNonce) -> Self {
1581 molecule_fiber::PubNonce::from_slice(value.to_bytes().as_ref())
1582 .expect("valid pubnonce serialized to 66 bytes")
1583 }
1584}
1585
1586impl TryFrom<molecule_fiber::PubNonce> for PubNonce {
1587 type Error = musig2::errors::DecodeError<PubNonce>;
1588
1589 fn try_from(value: molecule_fiber::PubNonce) -> Result<Self, Self::Error> {
1590 PubNonce::from_bytes(value.as_slice())
1591 }
1592}
1593
1594impl From<RevokeAndAck> for molecule_fiber::RevokeAndAck {
1595 fn from(revoke_and_ack: RevokeAndAck) -> Self {
1596 molecule_fiber::RevokeAndAck::new_builder()
1597 .channel_id(revoke_and_ack.channel_id.into())
1598 .revocation_partial_signature(partial_signature_to_molecule(
1599 revoke_and_ack.revocation_partial_signature,
1600 ))
1601 .next_per_commitment_point(revoke_and_ack.next_per_commitment_point.into())
1602 .next_revocation_nonce(pub_nonce_to_molecule(revoke_and_ack.next_revocation_nonce))
1603 .build()
1604 }
1605}
1606
1607impl TryFrom<molecule_fiber::RevokeAndAck> for RevokeAndAck {
1608 type Error = anyhow::Error;
1609
1610 fn try_from(revoke_and_ack: molecule_fiber::RevokeAndAck) -> Result<Self, Self::Error> {
1611 Ok(RevokeAndAck {
1612 channel_id: revoke_and_ack.channel_id().into(),
1613 revocation_partial_signature: PartialSignature::from_slice(
1614 revoke_and_ack.revocation_partial_signature().as_slice(),
1615 )
1616 .map_err(|e| anyhow::anyhow!(e))?,
1617 next_per_commitment_point: revoke_and_ack
1618 .next_per_commitment_point()
1619 .try_into()
1620 .map_err(|e: secp256k1::Error| anyhow::anyhow!(e))?,
1621 next_revocation_nonce: PubNonce::from_bytes(
1622 revoke_and_ack.next_revocation_nonce().as_slice(),
1623 )
1624 .map_err(|e| anyhow::anyhow!("{}", e))?,
1625 })
1626 }
1627}
1628
1629#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1631pub struct RemoveTlcFulfill {
1632 pub payment_preimage: Hash256,
1633}
1634
1635#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1637pub enum RemoveTlcReason {
1638 RemoveTlcFulfill(RemoveTlcFulfill),
1639 RemoveTlcFail(TlcErrPacket),
1640}
1641
1642impl Debug for RemoveTlcReason {
1643 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1644 match self {
1645 RemoveTlcReason::RemoveTlcFulfill(_fulfill) => {
1646 write!(f, "RemoveTlcFulfill")
1647 }
1648 RemoveTlcReason::RemoveTlcFail(_fail) => {
1649 write!(f, "RemoveTlcFail")
1650 }
1651 }
1652 }
1653}
1654
1655impl RemoveTlcReason {
1656 pub fn backward(self, shared_secret: &[u8; 32]) -> Self {
1659 match self {
1660 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill) => {
1661 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill)
1662 }
1663 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail) => {
1664 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail.backward(shared_secret))
1665 }
1666 }
1667 }
1668}
1669
1670impl From<RemoveTlcReason> for molecule_fiber::RemoveTlcReasonUnion {
1671 fn from(remove_tlc_reason: RemoveTlcReason) -> Self {
1672 match remove_tlc_reason {
1673 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill) => {
1674 molecule_fiber::RemoveTlcReasonUnion::RemoveTlcFulfill(remove_tlc_fulfill.into())
1675 }
1676 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail) => {
1677 molecule_fiber::RemoveTlcReasonUnion::TlcErrPacket(remove_tlc_fail.into())
1678 }
1679 }
1680 }
1681}
1682
1683impl From<RemoveTlcReason> for molecule_fiber::RemoveTlcReason {
1684 fn from(remove_tlc_reason: RemoveTlcReason) -> Self {
1685 molecule_fiber::RemoveTlcReason::new_builder()
1686 .set(remove_tlc_reason)
1687 .build()
1688 }
1689}
1690
1691impl From<molecule_fiber::RemoveTlcReason> for RemoveTlcReason {
1692 fn from(remove_tlc_reason: molecule_fiber::RemoveTlcReason) -> Self {
1693 match remove_tlc_reason.to_enum() {
1694 molecule_fiber::RemoveTlcReasonUnion::RemoveTlcFulfill(remove_tlc_fulfill) => {
1695 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill.into())
1696 }
1697 molecule_fiber::RemoveTlcReasonUnion::TlcErrPacket(remove_tlc_fail) => {
1698 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail.into())
1699 }
1700 }
1701 }
1702}
1703
1704impl From<RemoveTlcFulfill> for molecule_fiber::RemoveTlcFulfill {
1705 fn from(remove_tlc_fulfill: RemoveTlcFulfill) -> Self {
1706 molecule_fiber::RemoveTlcFulfill::new_builder()
1707 .payment_preimage(remove_tlc_fulfill.payment_preimage.into())
1708 .build()
1709 }
1710}
1711
1712impl From<molecule_fiber::RemoveTlcFulfill> for RemoveTlcFulfill {
1713 fn from(remove_tlc_fulfill: molecule_fiber::RemoveTlcFulfill) -> Self {
1714 RemoveTlcFulfill {
1715 payment_preimage: remove_tlc_fulfill.payment_preimage().into(),
1716 }
1717 }
1718}
1719
1720#[serde_as]
1725#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
1726pub struct ChannelUpdateInfo {
1727 #[serde_as(as = "crate::U64Hex")]
1729 pub timestamp: u64,
1730 pub enabled: bool,
1732 #[serde_as(as = "Option<crate::U128Hex>")]
1734 pub outbound_liquidity: Option<u128>,
1735 #[serde_as(as = "crate::U64Hex")]
1737 pub tlc_expiry_delta: u64,
1738 #[serde_as(as = "crate::U128Hex")]
1740 pub tlc_minimum_value: u128,
1741 #[serde_as(as = "crate::U64Hex")]
1743 pub fee_rate: u64,
1744}
1745
1746impl From<&ChannelTlcInfo> for ChannelUpdateInfo {
1747 fn from(info: &ChannelTlcInfo) -> Self {
1748 Self {
1749 timestamp: info.timestamp,
1750 enabled: info.enabled,
1751 outbound_liquidity: None,
1752 tlc_expiry_delta: info.tlc_expiry_delta,
1753 tlc_minimum_value: info.tlc_minimum_value,
1754 fee_rate: info.tlc_fee_proportional_millionths as u64,
1755 }
1756 }
1757}
1758
1759impl From<ChannelTlcInfo> for ChannelUpdateInfo {
1760 fn from(info: ChannelTlcInfo) -> Self {
1761 Self::from(&info)
1762 }
1763}
1764
1765impl From<crate::protocol::ChannelUpdate> for ChannelUpdateInfo {
1766 fn from(update: crate::protocol::ChannelUpdate) -> Self {
1767 Self::from(&update)
1768 }
1769}
1770
1771impl From<&crate::protocol::ChannelUpdate> for ChannelUpdateInfo {
1772 fn from(update: &crate::protocol::ChannelUpdate) -> Self {
1773 Self {
1774 timestamp: update.timestamp,
1775 enabled: !update.is_disabled(),
1776 outbound_liquidity: None,
1777 tlc_expiry_delta: update.tlc_expiry_delta,
1778 tlc_minimum_value: update.tlc_minimum_value,
1779 fee_rate: update.tlc_fee_proportional_millionths as u64,
1780 }
1781 }
1782}