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 }
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_with_shared_secret(
446 prev_channel_id: Hash256,
447 prev_tlc_id: u64,
448 forwarding_fee: u128,
449 shared_secret: [u8; 32],
450 ) -> Self {
451 Self {
452 prev_channel_id,
453 prev_tlc_id,
454 forwarding_fee,
455 shared_secret: Some(shared_secret),
456 }
457 }
458}
459
460#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
461pub struct TlcInfo {
462 pub status: TlcStatus,
463 pub tlc_id: TLCId,
464 pub amount: u128,
465 pub payment_hash: Hash256,
466 pub total_amount: Option<u128>,
468 pub payment_secret: Option<Hash256>,
470 pub attempt_id: Option<u64>,
473 pub expiry: u64,
474 pub hash_algorithm: HashAlgorithm,
475 pub onion_packet: Option<PaymentOnionPacket>,
477 pub shared_secret: [u8; 32],
481 #[serde(default)]
487 pub is_trampoline_hop: bool,
488 pub created_at: CommitmentNumbers,
489 pub removed_reason: Option<RemoveTlcReason>,
490
491 pub forwarding_tlc: Option<(Hash256, u64)>,
517 pub removed_confirmed_at: Option<u64>,
518 pub applied_flags: AppliedFlags,
519}
520
521use std::fmt;
522use std::time::Duration;
523
524impl fmt::Debug for TlcInfo {
525 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
526 f.debug_struct("TlcInfo")
527 .field("status", &self.status)
528 .field("tlc_id", &self.tlc_id)
529 .field("amount", &self.amount)
530 .field("payment_hash", &self.payment_hash)
531 .field("expiry", &self.expiry)
532 .field("created_at", &self.created_at)
533 .field("removed_reason", &self.removed_reason)
534 .field("applied_flags", &self.applied_flags)
535 .finish()
536 }
537}
538
539impl TlcInfo {
540 pub fn log(&self) -> String {
541 format!(
542 "id: {:?} status: {:?} amount: {:?} removed: {:?} hash: {:?} ",
543 &self.tlc_id, self.status, self.amount, self.removed_reason, self.payment_hash,
544 )
545 }
546
547 pub fn id(&self) -> u64 {
548 self.tlc_id.into()
549 }
550
551 pub fn is_offered(&self) -> bool {
552 self.tlc_id.is_offered()
553 }
554
555 pub fn is_received(&self) -> bool {
556 !self.is_offered()
557 }
558
559 pub fn get_commitment_numbers(&self) -> CommitmentNumbers {
560 self.created_at
561 }
562
563 pub fn flip_mut(&mut self) {
564 self.tlc_id.flip_mut();
565 }
566
567 pub fn outbound_status(&self) -> OutboundTlcStatus {
568 self.status.as_outbound_status()
569 }
570
571 pub fn inbound_status(&self) -> InboundTlcStatus {
572 self.status.as_inbound_status()
573 }
574
575 pub fn is_fail_remove_confirmed(&self) -> bool {
576 matches!(self.removed_reason, Some(RemoveTlcReason::RemoveTlcFail(_)))
577 && matches!(
578 self.status,
579 TlcStatus::Outbound(OutboundTlcStatus::RemoveAckConfirmed)
580 | TlcStatus::Outbound(OutboundTlcStatus::RemoveWaitAck)
581 | TlcStatus::Inbound(InboundTlcStatus::RemoveAckConfirmed)
582 )
583 }
584
585 pub fn get_htlc_type(&self) -> u8 {
591 let offered_flag = if self.is_offered() { 0u8 } else { 1u8 };
592 ((self.hash_algorithm as u8) << 1) + offered_flag
593 }
594}
595
596#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
598pub struct PendingTlcs {
599 pub tlcs: Vec<TlcInfo>,
600 pub next_tlc_id: u64,
601}
602
603impl PendingTlcs {
604 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TlcInfo> {
605 self.tlcs.iter_mut()
606 }
607
608 pub fn get_next_id(&self) -> u64 {
609 self.next_tlc_id
610 }
611
612 pub fn increment_next_id(&mut self) {
613 self.next_tlc_id += 1;
614 }
615
616 pub fn add_tlc(&mut self, tlc: TlcInfo) {
617 self.tlcs.push(tlc);
618 }
619}
620
621#[derive(Default, Clone, Debug, Serialize, Deserialize)]
623pub struct TlcState {
624 pub offered_tlcs: PendingTlcs,
625 pub received_tlcs: PendingTlcs,
626 pub waiting_ack: bool,
627}
628
629impl TlcState {
630 pub fn info(&self) -> String {
631 format!(
632 "offer_tlcs: {:?} received_tlcs: {:?}",
633 self.offered_tlcs.tlcs.len(),
634 self.received_tlcs.tlcs.len(),
635 )
636 }
637
638 #[cfg(debug_assertions)]
639 pub fn debug(&self) {
640 let format_tlc_list = |tlcs: &[TlcInfo]| -> String {
641 if tlcs.is_empty() {
642 " <none>".to_string()
643 } else {
644 tlcs.iter()
645 .map(|tlc| format!(" {}", tlc.log()))
646 .collect::<Vec<_>>()
647 .join("\n")
648 }
649 };
650
651 let offered_str = format_tlc_list(&self.offered_tlcs.tlcs);
652 let received_str = format_tlc_list(&self.received_tlcs.tlcs);
653
654 if offered_str.contains("<none>") && received_str.contains("<none>") {
655 tracing::info!("TlcState: <none>");
656 } else {
657 tracing::info!(
658 "TlcState:\n Offered:\n{}\n Received:\n{}",
659 offered_str,
660 received_str
661 );
662 }
663 }
664
665 pub fn get_mut(&mut self, tlc_id: &TLCId) -> Option<&mut TlcInfo> {
666 self.offered_tlcs
667 .tlcs
668 .iter_mut()
669 .find(|tlc| tlc.tlc_id == *tlc_id)
670 .or_else(|| {
671 self.received_tlcs
672 .tlcs
673 .iter_mut()
674 .find(|tlc| tlc.tlc_id == *tlc_id)
675 })
676 }
677
678 pub fn get(&self, tlc_id: &TLCId) -> Option<&TlcInfo> {
679 if tlc_id.is_offered() {
680 self.offered_tlcs
681 .tlcs
682 .iter()
683 .find(|tlc| tlc.tlc_id == *tlc_id)
684 } else {
685 self.received_tlcs
686 .tlcs
687 .iter()
688 .find(|tlc| tlc.tlc_id == *tlc_id)
689 }
690 }
691
692 pub fn get_committed_received_tlcs(&self) -> impl Iterator<Item = &TlcInfo> + '_ {
693 self.received_tlcs.tlcs.iter().filter(|tlc| {
694 debug_assert!(tlc.is_received());
695 matches!(tlc.inbound_status(), InboundTlcStatus::Committed)
696 })
697 }
698
699 pub fn get_expired_offered_tlcs(
700 &self,
701 expect_expiry: u64,
702 ) -> impl Iterator<Item = &TlcInfo> + '_ {
703 self.offered_tlcs.tlcs.iter().filter(move |tlc| {
704 tlc.outbound_status() != OutboundTlcStatus::LocalAnnounced
705 && tlc.removed_confirmed_at.is_none()
706 && tlc.expiry < expect_expiry
707 })
708 }
709
710 pub fn get_next_offering(&self) -> u64 {
711 self.offered_tlcs.get_next_id()
712 }
713
714 pub fn get_next_received(&self) -> u64 {
715 self.received_tlcs.get_next_id()
716 }
717
718 pub fn increment_offering(&mut self) {
719 self.offered_tlcs.increment_next_id();
720 }
721
722 pub fn increment_received(&mut self) {
723 self.received_tlcs.increment_next_id();
724 }
725
726 pub fn set_waiting_ack(&mut self, waiting_ack: bool) {
727 self.waiting_ack = waiting_ack;
728 }
729
730 pub fn all_tlcs(&self) -> impl Iterator<Item = &TlcInfo> + '_ {
731 self.offered_tlcs
732 .tlcs
733 .iter()
734 .chain(self.received_tlcs.tlcs.iter())
735 }
736
737 pub fn apply_remove_tlc(&mut self, tlc_id: TLCId) {
738 if tlc_id.is_offered() {
739 self.offered_tlcs.tlcs.retain(|tlc| tlc.tlc_id != tlc_id);
740 } else {
741 self.received_tlcs.tlcs.retain(|tlc| tlc.tlc_id != tlc_id);
742 }
743 }
744
745 pub fn add_offered_tlc(&mut self, tlc: TlcInfo) {
746 self.offered_tlcs.add_tlc(tlc);
747 }
748
749 pub fn add_received_tlc(&mut self, tlc: TlcInfo) {
750 self.received_tlcs.add_tlc(tlc);
751 }
752
753 pub fn set_received_tlc_removed(&mut self, tlc_id: u64, reason: RemoveTlcReason) -> Hash256 {
754 let tlc = self.get_mut(&TLCId::Received(tlc_id)).expect("get tlc");
755 assert_eq!(tlc.inbound_status(), InboundTlcStatus::Committed);
756 tlc.removed_reason = Some(reason);
757 tlc.status = TlcStatus::Inbound(InboundTlcStatus::LocalRemoved);
758 tlc.payment_hash
759 }
760
761 pub fn set_offered_tlc_removed(&mut self, tlc_id: u64, reason: RemoveTlcReason) -> Hash256 {
762 let tlc = self.get_mut(&TLCId::Offered(tlc_id)).expect("get tlc");
763 assert_eq!(tlc.outbound_status(), OutboundTlcStatus::Committed);
764 tlc.removed_reason = Some(reason);
765 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoteRemoved);
766 tlc.payment_hash
767 }
768
769 pub fn commitment_signed_tlcs(&self, for_remote: bool) -> impl Iterator<Item = &TlcInfo> + '_ {
770 self.offered_tlcs
771 .tlcs
772 .iter()
773 .filter(move |tlc| match tlc.outbound_status() {
774 OutboundTlcStatus::LocalAnnounced => for_remote,
775 OutboundTlcStatus::Committed => true,
776 OutboundTlcStatus::RemoteRemoved => for_remote,
777 OutboundTlcStatus::RemoveWaitPrevAck => for_remote,
778 OutboundTlcStatus::RemoveWaitAck => false,
779 OutboundTlcStatus::RemoveAckConfirmed => false,
780 })
781 .chain(
782 self.received_tlcs
783 .tlcs
784 .iter()
785 .filter(move |tlc| match tlc.inbound_status() {
786 InboundTlcStatus::RemoteAnnounced => !for_remote,
787 InboundTlcStatus::AnnounceWaitPrevAck => !for_remote,
788 InboundTlcStatus::AnnounceWaitAck => true,
789 InboundTlcStatus::Committed => true,
790 InboundTlcStatus::LocalRemoved => !for_remote,
791 InboundTlcStatus::RemoveAckConfirmed => false,
792 }),
793 )
794 }
795
796 pub fn update_for_commitment_signed(&mut self) -> bool {
797 for tlc in self.offered_tlcs.tlcs.iter_mut() {
798 if tlc.outbound_status() == OutboundTlcStatus::RemoteRemoved {
799 let status = if self.waiting_ack {
800 OutboundTlcStatus::RemoveWaitPrevAck
801 } else {
802 OutboundTlcStatus::RemoveWaitAck
803 };
804 tlc.status = TlcStatus::Outbound(status);
805 }
806 }
807 for tlc in self.received_tlcs.tlcs.iter_mut() {
808 if tlc.inbound_status() == InboundTlcStatus::RemoteAnnounced {
809 let status = if self.waiting_ack {
810 InboundTlcStatus::AnnounceWaitPrevAck
811 } else {
812 InboundTlcStatus::AnnounceWaitAck
813 };
814 tlc.status = TlcStatus::Inbound(status)
815 }
816 }
817 self.need_another_commitment_signed()
818 }
819
820 pub fn update_for_revoke_and_ack(&mut self, commitment_number: CommitmentNumbers) {
821 for tlc in self.offered_tlcs.tlcs.iter_mut() {
822 match tlc.outbound_status() {
823 OutboundTlcStatus::LocalAnnounced => {
824 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::Committed);
825 }
826 OutboundTlcStatus::RemoveWaitPrevAck => {
827 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoveWaitAck);
828 }
829 OutboundTlcStatus::RemoveWaitAck => {
830 tlc.status = TlcStatus::Outbound(OutboundTlcStatus::RemoveAckConfirmed);
831 tlc.removed_confirmed_at = Some(commitment_number.get_local());
832 }
833 _ => {}
834 }
835 }
836
837 for tlc in self.received_tlcs.tlcs.iter_mut() {
838 match tlc.inbound_status() {
839 InboundTlcStatus::AnnounceWaitPrevAck => {
840 tlc.status = TlcStatus::Inbound(InboundTlcStatus::AnnounceWaitAck);
841 }
842 InboundTlcStatus::AnnounceWaitAck => {
843 tlc.status = TlcStatus::Inbound(InboundTlcStatus::Committed);
844 }
845 InboundTlcStatus::LocalRemoved => {
846 tlc.status = TlcStatus::Inbound(InboundTlcStatus::RemoveAckConfirmed);
847 tlc.removed_confirmed_at = Some(commitment_number.get_remote());
848 }
849 _ => {}
850 }
851 }
852 }
853
854 pub fn need_another_commitment_signed(&self) -> bool {
855 self.offered_tlcs.tlcs.iter().any(|tlc| {
856 let status = tlc.outbound_status();
857 matches!(
858 status,
859 OutboundTlcStatus::LocalAnnounced
860 | OutboundTlcStatus::RemoteRemoved
861 | OutboundTlcStatus::RemoveWaitPrevAck
862 | OutboundTlcStatus::RemoveWaitAck
863 )
864 }) || self.received_tlcs.tlcs.iter().any(|tlc| {
865 let status = tlc.inbound_status();
866 matches!(
867 status,
868 InboundTlcStatus::RemoteAnnounced
869 | InboundTlcStatus::AnnounceWaitPrevAck
870 | InboundTlcStatus::AnnounceWaitAck
871 )
872 })
873 }
874}
875
876#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
878pub struct AddTlcCommand {
879 pub amount: u128,
880 pub payment_hash: Hash256,
881 pub attempt_id: Option<u64>,
883 pub expiry: u64,
884 pub hash_algorithm: HashAlgorithm,
885 pub onion_packet: Option<PaymentOnionPacket>,
887 pub shared_secret: [u8; 32],
891 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 is_tlc_key_derivation_safe(base_key: &Pubkey, commitment_point: &Pubkey) -> bool {
1202 let tweak = get_tweak_by_commitment_point(commitment_point);
1203 let Ok(scalar) = Scalar::from_slice(&tweak) else {
1204 return false;
1205 };
1206 let base_point = Point::from(base_key);
1207 let result = base_point + scalar.base_point_mul();
1208 result.not_inf().is_ok()
1209}
1210
1211pub fn get_commitment_secret(commitment_seed: &[u8; 32], commitment_number: u64) -> [u8; 32] {
1215 let mut res: [u8; 32] = *commitment_seed;
1216 for i in 0..48 {
1217 let bitpos = 47 - i;
1218 if commitment_number & (1 << bitpos) == (1 << bitpos) {
1219 res[bitpos / 8] ^= 1 << (bitpos & 7);
1220 res = ckb_hash::blake2b_256(res);
1221 }
1222 }
1223 res
1224}
1225
1226pub fn get_commitment_point(commitment_seed: &[u8; 32], commitment_number: u64) -> Pubkey {
1228 Privkey::from(&get_commitment_secret(commitment_seed, commitment_number)).pubkey()
1229}
1230
1231pub enum Musig2Context {
1233 Commitment,
1235 Revoke,
1237}
1238
1239impl std::fmt::Display for Musig2Context {
1240 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1241 let context_str = match self {
1242 Musig2Context::Commitment => "COMMITMENT",
1243 Musig2Context::Revoke => "REVOKE",
1244 };
1245 write!(f, "{}", context_str)
1246 }
1247}
1248
1249impl InMemorySigner {
1250 pub fn generate_from_seed(params: &[u8]) -> InMemorySigner {
1252 let seed = ckb_hash::blake2b_256(params);
1253
1254 let commitment_seed = {
1255 let mut hasher = ckb_hash::new_blake2b();
1256 hasher.update(&seed);
1257 hasher.update(&b"commitment seed"[..]);
1258 let mut result = [0u8; 32];
1259 hasher.finalize(&mut result);
1260 result
1261 };
1262
1263 let key_derive = |seed: &[u8], info: &[u8]| {
1264 let result = blake2b_hash_with_salt(seed, info);
1265 Privkey::from_slice(&result)
1266 };
1267
1268 let funding_key = key_derive(&seed, b"funding key");
1269 let tlc_base_key = key_derive(funding_key.as_ref(), b"HTLC base key");
1270 let musig2_base_nonce = key_derive(tlc_base_key.as_ref(), b"musig nocne");
1271
1272 InMemorySigner {
1273 funding_key,
1274 tlc_base_key,
1275 musig2_base_nonce,
1276 commitment_seed,
1277 }
1278 }
1279
1280 pub fn get_base_public_keys(&self) -> ChannelBasePublicKeys {
1282 ChannelBasePublicKeys {
1283 funding_pubkey: self.funding_key.pubkey(),
1284 tlc_base_key: self.tlc_base_key.pubkey(),
1285 }
1286 }
1287
1288 pub fn get_commitment_point(&self, commitment_number: u64) -> Pubkey {
1294 get_commitment_point(&self.commitment_seed, commitment_number)
1295 }
1296
1297 pub fn get_commitment_secret(&self, commitment_number: u64) -> [u8; 32] {
1299 get_commitment_secret(&self.commitment_seed, commitment_number)
1300 }
1301
1302 pub fn derive_tlc_key(&self, new_commitment_number: u64) -> Privkey {
1304 let per_commitment_point = self.get_commitment_point(new_commitment_number);
1305 derive_private_key(&self.tlc_base_key, &per_commitment_point)
1306 }
1307
1308 pub fn derive_musig2_nonce(&self, commitment_number: u64, context: Musig2Context) -> SecNonce {
1310 let commitment_point = self.get_commitment_point(commitment_number);
1311 let seckey = derive_private_key(&self.musig2_base_nonce, &commitment_point);
1312
1313 SecNonceBuilder::new(seckey.as_ref())
1314 .with_extra_input(&context.to_string())
1315 .build()
1316 }
1317}
1318
1319#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
1321pub enum ChannelOpeningStatus {
1322 WaitingForPeer,
1325 FundingTxBuilding,
1327 FundingTxBroadcasted,
1329 ChannelReady,
1331 Failed,
1333}
1334
1335#[serde_as]
1341#[derive(Clone, Debug, Serialize, Deserialize)]
1342pub struct ChannelOpenRecord {
1343 pub channel_id: Hash256,
1348 pub pubkey: Pubkey,
1350 pub is_acceptor: bool,
1352 pub status: ChannelOpeningStatus,
1354 pub funding_amount: u128,
1358 pub failure_detail: Option<String>,
1360 pub created_at: u64,
1362 pub last_updated_at: u64,
1364}
1365
1366impl ChannelOpenRecord {
1367 pub fn new(channel_id: Hash256, pubkey: Pubkey, funding_amount: u128) -> Self {
1369 let now = crate::now_timestamp_as_millis_u64();
1370 Self {
1371 channel_id,
1372 pubkey,
1373 is_acceptor: false,
1374 status: ChannelOpeningStatus::WaitingForPeer,
1375 funding_amount,
1376 failure_detail: None,
1377 created_at: now,
1378 last_updated_at: now,
1379 }
1380 }
1381
1382 pub fn new_inbound(channel_id: Hash256, pubkey: Pubkey, remote_funding_amount: u128) -> Self {
1385 let mut record = Self::new(channel_id, pubkey, remote_funding_amount);
1386 record.is_acceptor = true;
1387 record
1388 }
1389
1390 pub fn update_status(&mut self, status: ChannelOpeningStatus) {
1392 self.status = status;
1393 self.last_updated_at = crate::now_timestamp_as_millis_u64();
1394 }
1395
1396 pub fn fail(&mut self, reason: String) {
1398 self.status = ChannelOpeningStatus::Failed;
1399 self.failure_detail = Some(reason);
1400 self.last_updated_at = crate::now_timestamp_as_millis_u64();
1401 }
1402}
1403
1404pub trait ChannelOpenRecordStore {
1406 fn get_channel_open_records(&self) -> Vec<ChannelOpenRecord>;
1408 fn get_channel_open_record(&self, channel_id: &Hash256) -> Option<ChannelOpenRecord>;
1410 fn insert_channel_open_record(&self, record: ChannelOpenRecord);
1412 fn delete_channel_open_record(&self, channel_id: &Hash256);
1414}
1415
1416#[derive(Clone, Serialize, Deserialize, Debug)]
1418pub struct PendingNotifySettleTlc {
1419 pub payment_hash: Hash256,
1420 pub tlc_id: u64,
1421 pub hold_expire_at: Option<u64>,
1423}
1424
1425impl PendingNotifySettleTlc {
1426 pub fn pending_notify_should_hold(&self) -> bool {
1428 self.hold_expire_at.is_some()
1429 }
1430
1431 pub fn pending_notify_hold_expiry_duration(
1433 &self,
1434 now_millis_since_unix_epoch: u64,
1435 ) -> Duration {
1436 Duration::from_millis(
1437 self.hold_expire_at
1438 .unwrap_or_default()
1439 .saturating_sub(now_millis_since_unix_epoch),
1440 )
1441 }
1442}
1443
1444#[serde_as]
1449#[derive(Clone, Serialize, Deserialize)]
1450pub struct ChannelActorData {
1451 pub state: ChannelState,
1452 pub public_channel_info: Option<PublicChannelInfo>,
1454
1455 pub local_tlc_info: ChannelTlcInfo,
1456 pub remote_tlc_info: Option<ChannelTlcInfo>,
1457
1458 pub local_pubkey: Pubkey,
1460 pub remote_pubkey: Pubkey,
1462
1463 pub id: Hash256,
1464 #[serde_as(as = "Option<EntityHex>")]
1465 pub funding_tx: Option<Transaction>,
1466
1467 pub funding_tx_confirmed_at: Option<(H256, u32, u64)>,
1468
1469 #[serde_as(as = "Option<EntityHex>")]
1470 pub funding_udt_type_script: Option<Script>,
1471
1472 pub is_acceptor: bool,
1475
1476 pub is_one_way: bool,
1479
1480 pub to_local_amount: u128,
1483 pub to_remote_amount: u128,
1486
1487 pub local_reserved_ckb_amount: u64,
1491 pub remote_reserved_ckb_amount: u64,
1492
1493 pub commitment_fee_rate: u64,
1496
1497 pub commitment_delay_epoch: u64,
1500
1501 pub funding_fee_rate: u64,
1504
1505 pub signer: InMemorySigner,
1507
1508 pub local_channel_public_keys: ChannelBasePublicKeys,
1510
1511 pub commitment_numbers: CommitmentNumbers,
1514
1515 pub local_constraints: ChannelConstraints,
1516 pub remote_constraints: ChannelConstraints,
1517
1518 pub tlc_state: TlcState,
1520
1521 pub retryable_tlc_operations: VecDeque<RetryableTlcOperation>,
1523 pub waiting_forward_tlc_tasks: HashMap<TLCId, [u8; 32]>,
1524
1525 #[serde_as(as = "Option<EntityHex>")]
1527 pub remote_shutdown_script: Option<Script>,
1528 #[serde_as(as = "EntityHex")]
1530 pub local_shutdown_script: Script,
1531
1532 #[serde_as(as = "Option<PubNonceAsBytes>")]
1535 pub last_committed_remote_nonce: Option<PubNonce>,
1536
1537 #[serde_as(as = "Option<PubNonceAsBytes>")]
1538 pub remote_revocation_nonce_for_verify: Option<PubNonce>,
1539 #[serde_as(as = "Option<PubNonceAsBytes>")]
1540 pub remote_revocation_nonce_for_send: Option<PubNonce>,
1541 #[serde_as(as = "Option<PubNonceAsBytes>")]
1542 pub remote_revocation_nonce_for_next: Option<PubNonce>,
1543
1544 #[serde_as(as = "Option<EntityHex>")]
1547 pub latest_commitment_transaction: Option<Transaction>,
1548
1549 pub remote_commitment_points: Vec<(u64, Pubkey)>,
1552 pub remote_channel_public_keys: Option<ChannelBasePublicKeys>,
1553
1554 pub local_shutdown_info: Option<ShutdownInfo>,
1556 pub remote_shutdown_info: Option<ShutdownInfo>,
1557
1558 pub shutdown_transaction_hash: Option<H256>,
1561
1562 pub reestablishing: bool,
1565 pub last_revoke_ack_msg: Option<RevokeAndAck>,
1566
1567 pub created_at: SystemTime,
1568
1569 #[serde(default)]
1572 pub pending_replay_updates: Vec<TlcReplayUpdate>,
1573
1574 #[serde(default)]
1576 pub last_was_revoke: bool,
1577
1578 pub connectivity_state: ChannelConnectivityState,
1580
1581 #[serde(default)]
1583 pub external_funding: Option<ExternalFundingPersistState>,
1584}
1585
1586fn partial_signature_to_molecule(partial_signature: PartialSignature) -> MByte32 {
1587 MByte32::from_slice(partial_signature.serialize().as_ref()).expect("[Byte; 32] from [u8; 32]")
1588}
1589
1590fn pub_nonce_to_molecule(pub_nonce: PubNonce) -> molecule_fiber::PubNonce {
1591 molecule_fiber::PubNonce::from_slice(pub_nonce.to_bytes().as_ref())
1592 .expect("PubNonce from 66 bytes")
1593}
1594
1595impl From<PubNonce> for molecule_fiber::PubNonce {
1596 fn from(value: PubNonce) -> Self {
1597 molecule_fiber::PubNonce::from_slice(value.to_bytes().as_ref())
1598 .expect("valid pubnonce serialized to 66 bytes")
1599 }
1600}
1601
1602impl TryFrom<molecule_fiber::PubNonce> for PubNonce {
1603 type Error = musig2::errors::DecodeError<PubNonce>;
1604
1605 fn try_from(value: molecule_fiber::PubNonce) -> Result<Self, Self::Error> {
1606 PubNonce::from_bytes(value.as_slice())
1607 }
1608}
1609
1610impl From<RevokeAndAck> for molecule_fiber::RevokeAndAck {
1611 fn from(revoke_and_ack: RevokeAndAck) -> Self {
1612 molecule_fiber::RevokeAndAck::new_builder()
1613 .channel_id(revoke_and_ack.channel_id.into())
1614 .revocation_partial_signature(partial_signature_to_molecule(
1615 revoke_and_ack.revocation_partial_signature,
1616 ))
1617 .next_per_commitment_point(revoke_and_ack.next_per_commitment_point.into())
1618 .next_revocation_nonce(pub_nonce_to_molecule(revoke_and_ack.next_revocation_nonce))
1619 .build()
1620 }
1621}
1622
1623impl TryFrom<molecule_fiber::RevokeAndAck> for RevokeAndAck {
1624 type Error = anyhow::Error;
1625
1626 fn try_from(revoke_and_ack: molecule_fiber::RevokeAndAck) -> Result<Self, Self::Error> {
1627 Ok(RevokeAndAck {
1628 channel_id: revoke_and_ack.channel_id().into(),
1629 revocation_partial_signature: PartialSignature::from_slice(
1630 revoke_and_ack.revocation_partial_signature().as_slice(),
1631 )
1632 .map_err(|e| anyhow::anyhow!(e))?,
1633 next_per_commitment_point: revoke_and_ack
1634 .next_per_commitment_point()
1635 .try_into()
1636 .map_err(|e: secp256k1::Error| anyhow::anyhow!(e))?,
1637 next_revocation_nonce: PubNonce::from_bytes(
1638 revoke_and_ack.next_revocation_nonce().as_slice(),
1639 )
1640 .map_err(|e| anyhow::anyhow!("{}", e))?,
1641 })
1642 }
1643}
1644
1645#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1647pub struct RemoveTlcFulfill {
1648 pub payment_preimage: Hash256,
1649}
1650
1651#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1653pub enum RemoveTlcReason {
1654 RemoveTlcFulfill(RemoveTlcFulfill),
1655 RemoveTlcFail(TlcErrPacket),
1656}
1657
1658impl Debug for RemoveTlcReason {
1659 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1660 match self {
1661 RemoveTlcReason::RemoveTlcFulfill(_fulfill) => {
1662 write!(f, "RemoveTlcFulfill")
1663 }
1664 RemoveTlcReason::RemoveTlcFail(_fail) => {
1665 write!(f, "RemoveTlcFail")
1666 }
1667 }
1668 }
1669}
1670
1671impl RemoveTlcReason {
1672 pub fn backward(self, shared_secret: &[u8; 32]) -> Result<Self, TlcErrPacketError> {
1675 match self {
1676 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill) => {
1677 Ok(RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill))
1678 }
1679 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail) => Ok(RemoveTlcReason::RemoveTlcFail(
1680 remove_tlc_fail.backward(shared_secret)?,
1681 )),
1682 }
1683 }
1684}
1685
1686impl From<RemoveTlcReason> for molecule_fiber::RemoveTlcReasonUnion {
1687 fn from(remove_tlc_reason: RemoveTlcReason) -> Self {
1688 match remove_tlc_reason {
1689 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill) => {
1690 molecule_fiber::RemoveTlcReasonUnion::RemoveTlcFulfill(remove_tlc_fulfill.into())
1691 }
1692 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail) => {
1693 molecule_fiber::RemoveTlcReasonUnion::TlcErrPacket(remove_tlc_fail.into())
1694 }
1695 }
1696 }
1697}
1698
1699impl From<RemoveTlcReason> for molecule_fiber::RemoveTlcReason {
1700 fn from(remove_tlc_reason: RemoveTlcReason) -> Self {
1701 molecule_fiber::RemoveTlcReason::new_builder()
1702 .set(remove_tlc_reason)
1703 .build()
1704 }
1705}
1706
1707impl From<molecule_fiber::RemoveTlcReason> for RemoveTlcReason {
1708 fn from(remove_tlc_reason: molecule_fiber::RemoveTlcReason) -> Self {
1709 match remove_tlc_reason.to_enum() {
1710 molecule_fiber::RemoveTlcReasonUnion::RemoveTlcFulfill(remove_tlc_fulfill) => {
1711 RemoveTlcReason::RemoveTlcFulfill(remove_tlc_fulfill.into())
1712 }
1713 molecule_fiber::RemoveTlcReasonUnion::TlcErrPacket(remove_tlc_fail) => {
1714 RemoveTlcReason::RemoveTlcFail(remove_tlc_fail.into())
1715 }
1716 }
1717 }
1718}
1719
1720impl From<RemoveTlcFulfill> for molecule_fiber::RemoveTlcFulfill {
1721 fn from(remove_tlc_fulfill: RemoveTlcFulfill) -> Self {
1722 molecule_fiber::RemoveTlcFulfill::new_builder()
1723 .payment_preimage(remove_tlc_fulfill.payment_preimage.into())
1724 .build()
1725 }
1726}
1727
1728impl From<molecule_fiber::RemoveTlcFulfill> for RemoveTlcFulfill {
1729 fn from(remove_tlc_fulfill: molecule_fiber::RemoveTlcFulfill) -> Self {
1730 RemoveTlcFulfill {
1731 payment_preimage: remove_tlc_fulfill.payment_preimage().into(),
1732 }
1733 }
1734}
1735
1736#[serde_as]
1741#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
1742pub struct ChannelUpdateInfo {
1743 #[serde_as(as = "crate::U64Hex")]
1745 pub timestamp: u64,
1746 pub enabled: bool,
1748 #[serde_as(as = "Option<crate::U128Hex>")]
1750 pub outbound_liquidity: Option<u128>,
1751 #[serde_as(as = "crate::U64Hex")]
1753 pub tlc_expiry_delta: u64,
1754 #[serde_as(as = "crate::U128Hex")]
1756 pub tlc_minimum_value: u128,
1757 #[serde_as(as = "crate::U64Hex")]
1759 pub fee_rate: u64,
1760}
1761
1762impl From<&ChannelTlcInfo> for ChannelUpdateInfo {
1763 fn from(info: &ChannelTlcInfo) -> Self {
1764 Self {
1765 timestamp: info.timestamp,
1766 enabled: info.enabled,
1767 outbound_liquidity: None,
1768 tlc_expiry_delta: info.tlc_expiry_delta,
1769 tlc_minimum_value: info.tlc_minimum_value,
1770 fee_rate: info.tlc_fee_proportional_millionths as u64,
1771 }
1772 }
1773}
1774
1775impl From<ChannelTlcInfo> for ChannelUpdateInfo {
1776 fn from(info: ChannelTlcInfo) -> Self {
1777 Self::from(&info)
1778 }
1779}
1780
1781impl From<crate::protocol::ChannelUpdate> for ChannelUpdateInfo {
1782 fn from(update: crate::protocol::ChannelUpdate) -> Self {
1783 Self::from(&update)
1784 }
1785}
1786
1787impl From<&crate::protocol::ChannelUpdate> for ChannelUpdateInfo {
1788 fn from(update: &crate::protocol::ChannelUpdate) -> Self {
1789 Self {
1790 timestamp: update.timestamp,
1791 enabled: !update.is_disabled(),
1792 outbound_liquidity: None,
1793 tlc_expiry_delta: update.tlc_expiry_delta,
1794 tlc_minimum_value: update.tlc_minimum_value,
1795 fee_rate: update.tlc_fee_proportional_millionths as u64,
1796 }
1797 }
1798}