1use crate::channel::{ChannelUpdateChannelFlags, ChannelUpdateMessageFlags};
8use crate::gen::fiber as molecule_fiber;
9use crate::gen::gossip as molecule_gossip;
10use crate::primitives::u8_32_as_byte_32;
11use crate::serde_utils::EntityHex;
12use crate::UdtCfgInfos;
13use crate::{Hash256, Privkey, Pubkey};
14use ckb_types::packed::{BytesVec, OutPoint, Script};
15use ckb_types::prelude::Pack;
16use molecule::prelude::{Builder, Byte, Entity};
17use musig2::LiftedSignature;
18use serde::{Deserialize, Deserializer, Serialize, Serializer};
19use serde_with::serde_as;
20use std::cmp::Ordering;
21use std::time::Duration;
22
23pub const CURSOR_SIZE: usize = 45;
25pub use feature_bits::*;
26
27type Secp256k1Signature = secp256k1::ecdsa::Signature;
28
29#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
31pub struct EcdsaSignature(pub Secp256k1Signature);
32
33impl EcdsaSignature {
34 pub fn verify(&self, pubkey: &Pubkey, message: &[u8; 32]) -> bool {
35 let message = secp256k1::Message::from_digest(*message);
36 let pk = secp256k1::PublicKey::from_slice(&pubkey.0)
37 .expect("Pubkey should always contain valid serialized public key");
38 secp256k1::SECP256K1
39 .verify_ecdsa(&message, &self.0, &pk)
40 .is_ok()
41 }
42}
43
44impl From<EcdsaSignature> for Secp256k1Signature {
45 fn from(sig: EcdsaSignature) -> Self {
46 sig.0
47 }
48}
49
50impl From<Secp256k1Signature> for EcdsaSignature {
51 fn from(sig: Secp256k1Signature) -> Self {
52 Self(sig)
53 }
54}
55
56impl From<EcdsaSignature> for molecule_fiber::EcdsaSignature {
59 fn from(signature: EcdsaSignature) -> molecule_fiber::EcdsaSignature {
60 molecule_fiber::EcdsaSignature::new_builder()
61 .set(
62 signature
63 .0
64 .serialize_compact()
65 .into_iter()
66 .map(Into::into)
67 .collect::<Vec<Byte>>()
68 .try_into()
69 .expect("Signature serialized to correct length"),
70 )
71 .build()
72 }
73}
74
75impl TryFrom<molecule_fiber::EcdsaSignature> for EcdsaSignature {
76 type Error = secp256k1::Error;
77
78 fn try_from(signature: molecule_fiber::EcdsaSignature) -> Result<Self, Self::Error> {
79 let signature = signature.raw_data();
80 Secp256k1Signature::from_compact(&signature).map(Into::into)
81 }
82}
83
84#[derive(Eq, PartialEq, Copy, Clone, Default, Hash)]
88pub struct AnnouncedNodeName(pub [u8; 32]);
89
90impl AnnouncedNodeName {
91 pub fn as_bytes(&self) -> &[u8; 32] {
92 &self.0
93 }
94
95 pub fn from_slice(slice: &[u8]) -> Result<Self, String> {
96 if slice.len() > 32 {
97 return Err("Node Alias can not be longer than 32 bytes".to_string());
98 }
99 let mut bytes = [0; 32];
100 bytes[..slice.len()].copy_from_slice(slice);
101 Ok(Self(bytes))
102 }
103
104 pub fn from_string(value: &str) -> Result<Self, String> {
105 let str_bytes = value.as_bytes();
106 Self::from_slice(str_bytes)
107 }
108
109 pub fn as_str(&self) -> &str {
110 let end = self.0.iter().position(|&b| b == 0).unwrap_or(self.0.len());
111 if end == 0 {
112 return "";
113 }
114 std::str::from_utf8(&self.0[..end]).expect("valid utf8 string")
115 }
116}
117
118impl std::fmt::Display for AnnouncedNodeName {
119 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
120 write!(f, "{}", self.as_str())
121 }
122}
123
124impl std::fmt::Debug for AnnouncedNodeName {
125 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
126 write!(f, "AnnouncedNodeName({})", self)
127 }
128}
129
130impl<'s> From<&'s str> for AnnouncedNodeName {
131 fn from(value: &'s str) -> Self {
132 Self::from_string(value).expect("Valid announced node name")
133 }
134}
135
136impl Serialize for AnnouncedNodeName {
137 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
138 where
139 S: Serializer,
140 {
141 serializer.serialize_str(std::str::from_utf8(&self.0).expect("valid utf8 string"))
142 }
143}
144
145impl<'de> Deserialize<'de> for AnnouncedNodeName {
146 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
147 where
148 D: Deserializer<'de>,
149 {
150 let s = String::deserialize(deserializer)?;
151 Self::from_string(&s).map_err(serde::de::Error::custom)
152 }
153}
154
155pub type FeatureBit = u16;
157
158#[macro_export]
166macro_rules! declare_feature_bits_and_methods {
167 (
168 $( $name:ident, $odd:expr; )*
169 ) => {
170 paste::paste! {
171 $(
172 pub const [<$name _REQUIRED>]: u16 = $odd - 1;
174 pub const [<$name _OPTIONAL>]: u16 = $odd;
176 )*
177
178 pub const MAX_FEATURE_BIT: u16 = {
179 let mut max = 0;
180 $(
181 if $odd % 2 == 0 || $odd <= max {
182 panic!("feature base bit must be defined as increasing odd numbers");
183 }
184 max = $odd;
185 )*
186 max
187 };
188
189 pub fn feature_bit_name(bit: FeatureBit) -> &'static str {
190 match bit {
191 $(
192 [<$name _REQUIRED>] => stringify!([<$name _REQUIRED>]),
193 [<$name _OPTIONAL>] => stringify!([<$name _OPTIONAL>]),
194 )*
195 _ => "Unknown Feature",
196 }
197 }
198
199 impl FeatureVector {
200 $(
201 pub fn [<set_ $name:lower _required>](&mut self) {
202 self.set([<$name _REQUIRED>], true);
203 }
204 pub fn [<set_ $name:lower _optional>](&mut self) {
205 self.set([<$name _OPTIONAL>], true);
206 }
207 pub fn [<unset_ $name:lower _required>](&mut self) {
208 self.set([<$name _REQUIRED>], false);
209 }
210 pub fn [<unset_ $name:lower _optional>](&mut self) {
211 self.set([<$name _OPTIONAL>], false);
212 }
213 pub fn [<requires_ $name:lower>](&self) -> bool {
214 self.requires_feature([<$name _REQUIRED>])
215 }
216 pub fn [<supports_ $name:lower>](&self) -> bool {
217 self.supports_feature([<$name _OPTIONAL>])
218 }
219 )*
220 }
221 }
222 };
223}
224
225pub mod feature_bits {
231 use super::*;
232 declare_feature_bits_and_methods! {
233 GOSSIP_QUERIES, 1;
234 BASIC_MPP, 3;
235 TRAMPOLINE_ROUTING, 5;
236 }
238}
239
240#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
242pub struct FeatureVector {
243 inner: Vec<u8>,
244}
245
246impl Default for FeatureVector {
247 fn default() -> Self {
248 let mut feature = Self::new();
249 feature.set_gossip_queries_required();
250 feature.set_basic_mpp_required();
251 feature.set_trampoline_routing_required();
252
253 feature
257 }
258}
259
260impl FeatureVector {
261 pub fn new() -> Self {
262 let len = (feature_bits::MAX_FEATURE_BIT / 8) as usize + 1;
263 Self {
264 inner: vec![0; len],
265 }
266 }
267
268 pub fn from(bytes: Vec<u8>) -> Self {
269 Self { inner: bytes }
270 }
271
272 pub fn bytes(&self) -> Vec<u8> {
273 self.inner.clone()
274 }
275
276 fn is_set(&self, bit: FeatureBit) -> bool {
277 let idx = (bit / 8) as usize;
278 if idx >= self.inner.len() {
279 return false;
280 }
281 self.inner
282 .get(idx)
283 .map(|&byte| (byte >> (bit % 8)) & 1 == 1)
284 .unwrap_or(false)
285 }
286
287 fn set(&mut self, bit: FeatureBit, set: bool) {
288 let idx = (bit / 8) as usize;
289 if self.inner.len() <= idx {
290 self.inner.resize(idx + 1, 0);
291 }
292 let mask = 1 << (bit % 8);
293 if set {
294 self.inner[idx] |= mask;
295 } else {
296 self.inner[idx] &= !mask;
297 }
298 }
299
300 pub fn enabled_features(&self) -> Vec<FeatureBit> {
301 (0..(self.inner.len() * 8) as FeatureBit)
302 .filter(|&bit| self.is_set(bit))
303 .collect()
304 }
305
306 pub fn enabled_features_names(&self) -> Vec<String> {
307 self.enabled_features()
308 .into_iter()
309 .map(feature_bits::feature_bit_name)
310 .map(|name| name.to_string())
311 .collect()
312 }
313
314 pub fn is_empty(&self) -> bool {
315 self.inner.iter().all(|&b| b == 0)
316 }
317
318 pub fn set_feature(&mut self, bit: FeatureBit) {
319 self.set(bit, true);
320 }
321
322 pub fn unset_feature(&mut self, bit: FeatureBit) {
323 self.set(bit, false);
324 }
325
326 pub fn requires_feature(&self, bit: FeatureBit) -> bool {
327 self.is_set(bit) && bit.is_multiple_of(2)
328 }
329
330 pub fn supports_feature(&self, bit: FeatureBit) -> bool {
331 self.is_set(bit) || self.is_set(bit ^ 1)
332 }
333
334 pub fn compatible_with(&self, other: &Self) -> bool {
335 if self
336 .enabled_features()
337 .iter()
338 .any(|&bit| self.requires_feature(bit) && !other.supports_feature(bit))
339 {
340 return false;
341 }
342 true
343 }
344}
345
346impl std::fmt::Debug for FeatureVector {
347 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
348 f.debug_struct("FeatureVector")
349 .field("features", &self.enabled_features_names())
350 .finish()
351 }
352}
353
354#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
356pub struct SchnorrSignature(pub secp256k1::schnorr::Signature);
357
358impl SchnorrSignature {
359 pub fn inner(&self) -> &secp256k1::schnorr::Signature {
361 &self.0
362 }
363
364 pub fn to_byte_array(&self) -> [u8; 64] {
366 self.0.to_byte_array()
367 }
368
369 pub fn from_slice(data: &[u8]) -> Result<Self, secp256k1::Error> {
371 secp256k1::schnorr::Signature::from_slice(data).map(SchnorrSignature)
372 }
373}
374
375impl std::ops::Deref for SchnorrSignature {
376 type Target = secp256k1::schnorr::Signature;
377
378 fn deref(&self) -> &Self::Target {
379 &self.0
380 }
381}
382
383impl From<SchnorrSignature> for secp256k1::schnorr::Signature {
384 fn from(sig: SchnorrSignature) -> Self {
385 sig.0
386 }
387}
388
389impl From<secp256k1::schnorr::Signature> for SchnorrSignature {
390 fn from(sig: secp256k1::schnorr::Signature) -> Self {
391 Self(sig)
392 }
393}
394
395impl From<LiftedSignature> for SchnorrSignature {
396 fn from(sig: LiftedSignature) -> Self {
397 Self(secp256k1::schnorr::Signature::from(sig))
398 }
399}
400
401impl From<SchnorrSignature> for molecule_gossip::SchnorrSignature {
404 fn from(signature: SchnorrSignature) -> molecule_gossip::SchnorrSignature {
405 molecule_gossip::SchnorrSignature::new_builder()
406 .set(
407 signature
408 .0
409 .to_byte_array()
410 .into_iter()
411 .map(Into::into)
412 .collect::<Vec<Byte>>()
413 .try_into()
414 .expect("Signature serialized to correct length"),
415 )
416 .build()
417 }
418}
419
420impl TryFrom<molecule_gossip::SchnorrSignature> for SchnorrSignature {
421 type Error = secp256k1::Error;
422
423 fn try_from(signature: molecule_gossip::SchnorrSignature) -> Result<Self, Self::Error> {
424 secp256k1::schnorr::Signature::from_slice(signature.as_slice()).map(Into::into)
425 }
426}
427
428#[serde_as]
433#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Hash)]
434pub struct ChannelAnnouncement {
435 pub node1_signature: Option<EcdsaSignature>,
437 pub node2_signature: Option<EcdsaSignature>,
439 pub ckb_signature: Option<SchnorrSignature>,
441 pub features: u64,
443 pub chain_hash: Hash256,
445 #[serde_as(as = "EntityHex")]
447 pub channel_outpoint: OutPoint,
448 pub node1_id: Pubkey,
450 pub node2_id: Pubkey,
452 pub ckb_key: secp256k1::XOnlyPublicKey,
454 pub capacity: u128,
456 #[serde_as(as = "Option<EntityHex>")]
458 pub udt_type_script: Option<Script>,
459}
460
461impl ChannelAnnouncement {
462 pub fn is_signed(&self) -> bool {
464 self.node1_signature.is_some()
465 && self.node2_signature.is_some()
466 && self.ckb_signature.is_some()
467 }
468
469 pub fn out_point(&self) -> &OutPoint {
471 &self.channel_outpoint
472 }
473
474 pub fn new_unsigned(
476 node1_pubkey: &Pubkey,
477 node2_pubkey: &Pubkey,
478 channel_outpoint: OutPoint,
479 chain_hash: Hash256,
480 ckb_pubkey: &secp256k1::XOnlyPublicKey,
481 capacity: u128,
482 udt_type_script: Option<Script>,
483 ) -> Self {
484 Self {
485 node1_signature: None,
486 node2_signature: None,
487 ckb_signature: None,
488 features: Default::default(),
489 chain_hash,
490 channel_outpoint,
491 node1_id: *node1_pubkey,
492 node2_id: *node2_pubkey,
493 ckb_key: *ckb_pubkey,
494 capacity,
495 udt_type_script,
496 }
497 }
498}
499
500#[serde_as]
505#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Hash)]
506pub struct ChannelUpdate {
507 pub signature: Option<EcdsaSignature>,
509 pub chain_hash: Hash256,
511 #[serde_as(as = "EntityHex")]
513 pub channel_outpoint: OutPoint,
514 pub timestamp: u64,
516 pub message_flags: ChannelUpdateMessageFlags,
518 pub channel_flags: ChannelUpdateChannelFlags,
520 pub tlc_expiry_delta: u64,
522 pub tlc_minimum_value: u128,
524 pub tlc_fee_proportional_millionths: u128,
526}
527
528impl ChannelUpdate {
529 pub fn is_update_of_node_1(&self) -> bool {
531 !self.is_update_of_node_2()
532 }
533
534 pub fn is_update_of_node_2(&self) -> bool {
536 self.message_flags
537 .contains(ChannelUpdateMessageFlags::UPDATE_OF_NODE2)
538 }
539
540 pub fn is_disabled(&self) -> bool {
542 self.channel_flags
543 .contains(ChannelUpdateChannelFlags::DISABLED)
544 }
545
546 pub fn message_to_sign(&self) -> [u8; 32] {
548 let unsigned_update = ChannelUpdate {
549 signature: None,
550 chain_hash: self.chain_hash,
551 channel_outpoint: self.channel_outpoint.clone(),
552 timestamp: self.timestamp,
553 message_flags: self.message_flags,
554 channel_flags: self.channel_flags,
555 tlc_expiry_delta: self.tlc_expiry_delta,
556 tlc_minimum_value: self.tlc_minimum_value,
557 tlc_fee_proportional_millionths: self.tlc_fee_proportional_millionths,
558 };
559 deterministically_hash(&molecule_fiber::ChannelUpdate::from(unsigned_update))
560 }
561
562 pub fn cursor(&self) -> Cursor {
564 Cursor::new(
565 self.timestamp,
566 BroadcastMessageID::ChannelUpdate(self.channel_outpoint.clone()),
567 )
568 }
569}
570
571impl ChannelAnnouncement {
572 pub fn message_to_sign(&self) -> [u8; 32] {
574 let unsigned_announcement = Self {
575 node1_signature: None,
576 node2_signature: None,
577 ckb_signature: None,
578 features: self.features,
579 chain_hash: self.chain_hash,
580 channel_outpoint: self.channel_outpoint.clone(),
581 node1_id: self.node1_id,
582 node2_id: self.node2_id,
583 ckb_key: self.ckb_key,
584 capacity: self.capacity,
585 udt_type_script: self.udt_type_script.clone(),
586 };
587 deterministically_hash(&molecule_gossip::ChannelAnnouncement::from(
588 unsigned_announcement,
589 ))
590 }
591}
592
593impl NodeAnnouncement {
594 #[allow(clippy::too_many_arguments)]
599 pub fn new_unsigned(
600 node_name: AnnouncedNodeName,
601 features: FeatureVector,
602 addresses: Vec<tentacle_multiaddr::Multiaddr>,
603 node_id: Pubkey,
604 chain_hash: Hash256,
605 timestamp: u64,
606 auto_accept_min_ckb_funding_amount: u64,
607 udt_cfg_infos: UdtCfgInfos,
608 version: String,
609 ) -> Self {
610 Self {
611 signature: None,
612 features,
613 timestamp,
614 node_id,
615 version,
616 node_name,
617 chain_hash,
618 addresses,
619 auto_accept_min_ckb_funding_amount,
620 udt_cfg_infos,
621 }
622 }
623
624 #[allow(clippy::too_many_arguments)]
629 pub fn new_signed(
630 node_name: AnnouncedNodeName,
631 features: FeatureVector,
632 addresses: Vec<tentacle_multiaddr::Multiaddr>,
633 private_key: &Privkey,
634 chain_hash: Hash256,
635 timestamp: u64,
636 auto_accept_min_ckb_funding_amount: u64,
637 udt_cfg_infos: UdtCfgInfos,
638 version: String,
639 ) -> Self {
640 let mut unsigned = Self::new_unsigned(
641 node_name,
642 features,
643 addresses,
644 private_key.pubkey(),
645 chain_hash,
646 timestamp,
647 auto_accept_min_ckb_funding_amount,
648 udt_cfg_infos,
649 version,
650 );
651 unsigned.signature = Some(private_key.sign(unsigned.message_to_sign()));
652 unsigned
653 }
654
655 pub fn message_to_sign(&self) -> [u8; 32] {
657 let unsigned_announcement = NodeAnnouncement {
658 signature: None,
659 features: self.features.clone(),
660 timestamp: self.timestamp,
661 node_id: self.node_id,
662 version: self.version.clone(),
663 node_name: self.node_name,
664 chain_hash: self.chain_hash,
665 addresses: self.addresses.clone(),
666 auto_accept_min_ckb_funding_amount: self.auto_accept_min_ckb_funding_amount,
667 udt_cfg_infos: self.udt_cfg_infos.clone(),
668 };
669 deterministically_hash(&molecule_gossip::NodeAnnouncement::from(
670 unsigned_announcement,
671 ))
672 }
673
674 pub fn cursor(&self) -> Cursor {
676 Cursor::new(
677 self.timestamp,
678 BroadcastMessageID::NodeAnnouncement(self.node_id),
679 )
680 }
681
682 pub fn verify(&self) -> bool {
684 let message = self.message_to_sign();
685 match self.signature {
686 Some(ref signature) => signature.verify(&self.node_id, &message),
687 _ => false,
688 }
689 }
690}
691
692pub(crate) fn deterministically_hash<T: Entity>(v: &T) -> [u8; 32] {
694 ckb_hash::blake2b_256(v.as_slice())
695}
696
697#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
702pub enum BroadcastMessage {
703 NodeAnnouncement(NodeAnnouncement),
705 ChannelAnnouncement(ChannelAnnouncement),
707 ChannelUpdate(ChannelUpdate),
709}
710
711impl BroadcastMessage {
712 pub fn cursor(&self) -> Option<Cursor> {
714 match self {
715 BroadcastMessage::ChannelAnnouncement(_) => None,
716 BroadcastMessage::ChannelUpdate(channel_update) => Some(channel_update.cursor()),
717 BroadcastMessage::NodeAnnouncement(node_announcement) => {
718 Some(node_announcement.cursor())
719 }
720 }
721 }
722
723 pub fn message_id(&self) -> BroadcastMessageID {
725 match self {
726 BroadcastMessage::NodeAnnouncement(node_announcement) => {
727 BroadcastMessageID::NodeAnnouncement(node_announcement.node_id)
728 }
729 BroadcastMessage::ChannelAnnouncement(channel_announcement) => {
730 BroadcastMessageID::ChannelAnnouncement(
731 channel_announcement.channel_outpoint.clone(),
732 )
733 }
734 BroadcastMessage::ChannelUpdate(channel_update) => {
735 BroadcastMessageID::ChannelUpdate(channel_update.channel_outpoint.clone())
736 }
737 }
738 }
739
740 pub fn timestamp(&self) -> Option<u64> {
742 match self {
743 BroadcastMessage::NodeAnnouncement(node_announcement) => {
744 Some(node_announcement.timestamp)
745 }
746 BroadcastMessage::ChannelAnnouncement(_) => None,
747 BroadcastMessage::ChannelUpdate(channel_update) => Some(channel_update.timestamp),
748 }
749 }
750}
751
752#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
757pub struct NodeAnnouncement {
758 pub signature: Option<EcdsaSignature>,
760 pub features: FeatureVector,
762 pub timestamp: u64,
764 pub node_id: Pubkey,
766 pub version: String,
768 pub node_name: AnnouncedNodeName,
770 pub addresses: Vec<tentacle_multiaddr::Multiaddr>,
772 pub chain_hash: Hash256,
774 pub auto_accept_min_ckb_funding_amount: u64,
776 pub udt_cfg_infos: UdtCfgInfos,
778}
779
780#[derive(Debug, Clone, Eq, PartialEq, Hash)]
782pub enum BroadcastMessageID {
783 ChannelAnnouncement(OutPoint),
784 ChannelUpdate(OutPoint),
785 NodeAnnouncement(Pubkey),
786}
787
788impl Default for BroadcastMessageID {
789 fn default() -> Self {
790 BroadcastMessageID::ChannelAnnouncement(OutPoint::default())
791 }
792}
793
794impl Ord for BroadcastMessageID {
800 fn cmp(&self, other: &Self) -> Ordering {
801 match (self, other) {
802 (
803 BroadcastMessageID::ChannelAnnouncement(outpoint1),
804 BroadcastMessageID::ChannelAnnouncement(outpoint2),
805 ) => outpoint1.cmp(outpoint2),
806 (
807 BroadcastMessageID::ChannelUpdate(outpoint1),
808 BroadcastMessageID::ChannelUpdate(outpoint2),
809 ) => outpoint1.cmp(outpoint2),
810 (
811 BroadcastMessageID::NodeAnnouncement(node1),
812 BroadcastMessageID::NodeAnnouncement(node2),
813 ) => node1.cmp(node2),
814 (BroadcastMessageID::NodeAnnouncement(_), _) => Ordering::Less,
815 (BroadcastMessageID::ChannelUpdate(_), _) => Ordering::Greater,
816 (
817 BroadcastMessageID::ChannelAnnouncement(_),
818 BroadcastMessageID::NodeAnnouncement(_),
819 ) => Ordering::Greater,
820 (BroadcastMessageID::ChannelAnnouncement(_), BroadcastMessageID::ChannelUpdate(_)) => {
821 Ordering::Less
822 }
823 }
824 }
825}
826
827impl PartialOrd for BroadcastMessageID {
828 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
829 Some(self.cmp(other))
830 }
831}
832
833const MESSAGE_ID_SIZE: usize = 1 + 36;
835
836impl BroadcastMessageID {
837 pub fn to_bytes(&self) -> [u8; MESSAGE_ID_SIZE] {
838 let mut result = [0u8; MESSAGE_ID_SIZE];
839 match self {
840 BroadcastMessageID::ChannelAnnouncement(channel_outpoint) => {
841 result[0] = 0;
842 result[1..].copy_from_slice(&channel_outpoint.as_bytes());
843 }
844 BroadcastMessageID::ChannelUpdate(channel_outpoint) => {
845 result[0] = 1;
846 result[1..].copy_from_slice(&channel_outpoint.as_bytes());
847 }
848 BroadcastMessageID::NodeAnnouncement(node_id) => {
849 result[0] = 2;
850 let node_id = node_id.serialize();
851 result[1..1 + node_id.len()].copy_from_slice(&node_id);
852 }
853 };
854 result
855 }
856
857 pub fn from_bytes(bytes: &[u8]) -> Result<Self, anyhow::Error> {
858 use molecule::prelude::Entity;
859 if bytes.len() != MESSAGE_ID_SIZE {
860 anyhow::bail!("Invalid message id size: {}", bytes.len());
861 }
862 match bytes[0] {
863 0 => Ok(BroadcastMessageID::ChannelAnnouncement(
864 OutPoint::from_slice(&bytes[1..])?,
865 )),
866 1 => Ok(BroadcastMessageID::ChannelUpdate(OutPoint::from_slice(
867 &bytes[1..],
868 )?)),
869 2 => Ok(BroadcastMessageID::NodeAnnouncement(Pubkey::from_slice(
870 &bytes[1..1 + Pubkey::serialization_len()],
871 )?)),
872 _ => anyhow::bail!("Invalid message id type: {}", bytes[0]),
873 }
874 }
875}
876
877#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
879pub struct Cursor {
880 pub timestamp: u64,
881 pub message_id: BroadcastMessageID,
882}
883
884impl Cursor {
885 pub fn new(timestamp: u64, message_id: BroadcastMessageID) -> Self {
886 Self {
887 timestamp,
888 message_id,
889 }
890 }
891
892 pub fn go_back_for_some_time(&self, duration: Duration) -> Self {
895 let current_timestamp = self.timestamp;
896 let duration_millis = duration.as_millis() as u64;
897 if current_timestamp > duration_millis {
898 Self {
899 timestamp: current_timestamp - duration_millis,
900 message_id: self.message_id.clone(),
901 }
902 } else {
903 Default::default()
904 }
905 }
906
907 pub fn to_bytes(&self) -> [u8; 45] {
908 self.timestamp
909 .to_be_bytes()
910 .into_iter()
911 .chain(self.message_id.to_bytes())
912 .collect::<Vec<_>>()
913 .try_into()
914 .expect("Must serialize cursor to 45 bytes")
915 }
916
917 pub fn from_bytes(bytes: &[u8]) -> Result<Self, anyhow::Error> {
918 if bytes.len() != CURSOR_SIZE {
919 anyhow::bail!("Invalid cursor size: {}, want {}", bytes.len(), CURSOR_SIZE);
920 }
921 let timestamp = u64::from_be_bytes(bytes[..8].try_into().expect("Cursor timestamp to u64"));
922 let message_id = BroadcastMessageID::from_bytes(&bytes[8..])?;
923 Ok(Cursor {
924 timestamp,
925 message_id,
926 })
927 }
928
929 pub fn max() -> Self {
932 Self {
933 timestamp: u64::MAX,
934 message_id: BroadcastMessageID::ChannelAnnouncement(OutPoint::default()),
935 }
936 }
937
938 pub fn is_max(&self) -> bool {
939 self.timestamp == u64::MAX
940 }
941}
942
943impl From<NodeAnnouncement> for molecule_gossip::NodeAnnouncement {
946 fn from(node_announcement: NodeAnnouncement) -> Self {
947 let builder = molecule_gossip::NodeAnnouncement::new_builder()
948 .features(node_announcement.features.bytes().pack())
949 .timestamp(node_announcement.timestamp.pack())
950 .node_id(node_announcement.node_id.into())
951 .version(node_announcement.version.pack())
952 .node_name(u8_32_as_byte_32(&node_announcement.node_name.0))
953 .chain_hash(node_announcement.chain_hash.into())
954 .auto_accept_min_ckb_funding_amount(
955 node_announcement.auto_accept_min_ckb_funding_amount.pack(),
956 )
957 .udt_cfg_infos(node_announcement.udt_cfg_infos.into())
958 .address(
959 BytesVec::new_builder()
960 .set(
961 node_announcement
962 .addresses
963 .into_iter()
964 .map(|address| address.to_vec().pack())
965 .collect(),
966 )
967 .build(),
968 );
969
970 let builder = if let Some(signature) = node_announcement.signature {
971 builder.signature(signature.into())
972 } else {
973 builder
974 };
975
976 builder.build()
977 }
978}
979
980impl TryFrom<molecule_gossip::NodeAnnouncement> for NodeAnnouncement {
981 type Error = anyhow::Error;
982
983 fn try_from(node_announcement: molecule_gossip::NodeAnnouncement) -> Result<Self, Self::Error> {
984 use ckb_types::prelude::Unpack;
985 Ok(NodeAnnouncement {
986 signature: Some(
987 node_announcement
988 .signature()
989 .try_into()
990 .map_err(|e: secp256k1::Error| anyhow::anyhow!(e))?,
991 ),
992 features: FeatureVector::from(node_announcement.features().unpack()),
993 timestamp: node_announcement.timestamp().unpack(),
994 node_id: node_announcement
995 .node_id()
996 .try_into()
997 .map_err(|e: secp256k1::Error| anyhow::anyhow!(e))?,
998 version: String::from_utf8(node_announcement.version().unpack()).unwrap_or_default(),
999 chain_hash: node_announcement.chain_hash().into(),
1000 auto_accept_min_ckb_funding_amount: node_announcement
1001 .auto_accept_min_ckb_funding_amount()
1002 .unpack(),
1003 node_name: AnnouncedNodeName::from_slice(node_announcement.node_name().as_slice())
1004 .map_err(|e| anyhow::anyhow!("Invalid node_name: {}", e))?,
1005 udt_cfg_infos: node_announcement.udt_cfg_infos().try_into()?,
1006 addresses: node_announcement
1007 .address()
1008 .into_iter()
1009 .map(|bytes| {
1010 tentacle_multiaddr::Multiaddr::try_from(bytes.raw_data().to_vec())
1011 .map_err(Into::into)
1012 })
1013 .collect::<Result<Vec<_>, anyhow::Error>>()?,
1014 })
1015 }
1016}
1017
1018impl From<ChannelAnnouncement> for molecule_gossip::ChannelAnnouncement {
1019 fn from(channel_announcement: ChannelAnnouncement) -> Self {
1020 let builder = molecule_gossip::ChannelAnnouncement::new_builder()
1021 .features(channel_announcement.features.pack())
1022 .chain_hash(channel_announcement.chain_hash.into())
1023 .channel_outpoint(channel_announcement.channel_outpoint)
1024 .node1_id(channel_announcement.node1_id.into())
1025 .node2_id(channel_announcement.node2_id.into())
1026 .capacity(channel_announcement.capacity.pack())
1027 .udt_type_script(channel_announcement.udt_type_script.pack())
1028 .ckb_key(channel_announcement.ckb_key.into());
1029
1030 let builder = if let Some(signature) = channel_announcement.node1_signature {
1031 builder.node1_signature(signature.into())
1032 } else {
1033 builder
1034 };
1035
1036 let builder = if let Some(signature) = channel_announcement.node2_signature {
1037 builder.node2_signature(signature.into())
1038 } else {
1039 builder
1040 };
1041
1042 let builder = if let Some(signature) = channel_announcement.ckb_signature {
1043 builder.ckb_signature(signature.into())
1044 } else {
1045 builder
1046 };
1047
1048 builder.build()
1049 }
1050}
1051
1052impl TryFrom<molecule_gossip::ChannelAnnouncement> for ChannelAnnouncement {
1053 type Error = anyhow::Error;
1054
1055 fn try_from(
1056 channel_announcement: molecule_gossip::ChannelAnnouncement,
1057 ) -> Result<Self, Self::Error> {
1058 use ckb_types::prelude::Unpack;
1059 Ok(ChannelAnnouncement {
1060 node1_signature: Some(channel_announcement.node1_signature().try_into()?),
1061 node2_signature: Some(channel_announcement.node2_signature().try_into()?),
1062 ckb_signature: Some(channel_announcement.ckb_signature().try_into()?),
1063 features: channel_announcement.features().unpack(),
1064 capacity: channel_announcement.capacity().unpack(),
1065 chain_hash: channel_announcement.chain_hash().into(),
1066 channel_outpoint: channel_announcement.channel_outpoint(),
1067 udt_type_script: channel_announcement.udt_type_script().to_opt(),
1068 node1_id: channel_announcement.node1_id().try_into()?,
1069 node2_id: channel_announcement.node2_id().try_into()?,
1070 ckb_key: channel_announcement.ckb_key().try_into()?,
1071 })
1072 }
1073}
1074
1075impl From<ChannelUpdate> for molecule_fiber::ChannelUpdate {
1076 fn from(channel_update: ChannelUpdate) -> Self {
1077 let builder = molecule_fiber::ChannelUpdate::new_builder()
1078 .chain_hash(channel_update.chain_hash.into())
1079 .channel_outpoint(channel_update.channel_outpoint)
1080 .timestamp(channel_update.timestamp.pack())
1081 .message_flags(channel_update.message_flags.bits().pack())
1082 .channel_flags(channel_update.channel_flags.bits().pack())
1083 .tlc_expiry_delta(channel_update.tlc_expiry_delta.pack())
1084 .tlc_minimum_value(channel_update.tlc_minimum_value.pack())
1085 .tlc_fee_proportional_millionths(channel_update.tlc_fee_proportional_millionths.pack());
1086
1087 let builder = if let Some(signature) = channel_update.signature {
1088 builder.signature(signature.into())
1089 } else {
1090 builder
1091 };
1092
1093 builder.build()
1094 }
1095}
1096
1097impl TryFrom<molecule_fiber::ChannelUpdate> for ChannelUpdate {
1098 type Error = anyhow::Error;
1099
1100 fn try_from(channel_update: molecule_fiber::ChannelUpdate) -> Result<Self, Self::Error> {
1101 use ckb_types::prelude::Unpack;
1102 Ok(ChannelUpdate {
1103 signature: Some(channel_update.signature().try_into()?),
1104 chain_hash: channel_update.chain_hash().into(),
1105 channel_outpoint: channel_update.channel_outpoint(),
1106 timestamp: channel_update.timestamp().unpack(),
1107 message_flags: ChannelUpdateMessageFlags::from_bits_truncate(
1108 channel_update.message_flags().unpack(),
1109 ),
1110 channel_flags: ChannelUpdateChannelFlags::from_bits_truncate(
1111 channel_update.channel_flags().unpack(),
1112 ),
1113 tlc_expiry_delta: channel_update.tlc_expiry_delta().unpack(),
1114 tlc_minimum_value: channel_update.tlc_minimum_value().unpack(),
1115 tlc_fee_proportional_millionths: channel_update
1116 .tlc_fee_proportional_millionths()
1117 .unpack(),
1118 })
1119 }
1120}
1121
1122impl Ord for BroadcastMessage {
1123 fn cmp(&self, other: &Self) -> Ordering {
1124 self.message_id()
1125 .cmp(&other.message_id())
1126 .then(self.timestamp().cmp(&other.timestamp()))
1127 }
1128}
1129
1130impl PartialOrd for BroadcastMessage {
1131 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1132 Some(self.cmp(other))
1133 }
1134}
1135
1136impl From<BroadcastMessage> for molecule_gossip::BroadcastMessageUnion {
1137 fn from(fiber_broadcast_message: BroadcastMessage) -> Self {
1138 match fiber_broadcast_message {
1139 BroadcastMessage::NodeAnnouncement(node_announcement) => {
1140 molecule_gossip::BroadcastMessageUnion::NodeAnnouncement(node_announcement.into())
1141 }
1142 BroadcastMessage::ChannelAnnouncement(channel_announcement) => {
1143 molecule_gossip::BroadcastMessageUnion::ChannelAnnouncement(
1144 channel_announcement.into(),
1145 )
1146 }
1147 BroadcastMessage::ChannelUpdate(channel_update) => {
1148 molecule_gossip::BroadcastMessageUnion::ChannelUpdate(channel_update.into())
1149 }
1150 }
1151 }
1152}
1153
1154impl TryFrom<molecule_gossip::BroadcastMessageUnion> for BroadcastMessage {
1155 type Error = anyhow::Error;
1156
1157 fn try_from(
1158 fiber_broadcast_message: molecule_gossip::BroadcastMessageUnion,
1159 ) -> Result<Self, Self::Error> {
1160 match fiber_broadcast_message {
1161 molecule_gossip::BroadcastMessageUnion::NodeAnnouncement(node_announcement) => Ok(
1162 BroadcastMessage::NodeAnnouncement(node_announcement.try_into()?),
1163 ),
1164 molecule_gossip::BroadcastMessageUnion::ChannelAnnouncement(channel_announcement) => {
1165 Ok(BroadcastMessage::ChannelAnnouncement(
1166 channel_announcement.try_into()?,
1167 ))
1168 }
1169 molecule_gossip::BroadcastMessageUnion::ChannelUpdate(channel_update) => {
1170 Ok(BroadcastMessage::ChannelUpdate(channel_update.try_into()?))
1171 }
1172 }
1173 }
1174}
1175
1176impl From<BroadcastMessage> for molecule_gossip::BroadcastMessage {
1177 fn from(fiber_broadcast_message: BroadcastMessage) -> Self {
1178 molecule_gossip::BroadcastMessage::new_builder()
1179 .set(fiber_broadcast_message)
1180 .build()
1181 }
1182}
1183
1184impl TryFrom<molecule_gossip::BroadcastMessage> for BroadcastMessage {
1185 type Error = anyhow::Error;
1186
1187 fn try_from(
1188 fiber_broadcast_message: molecule_gossip::BroadcastMessage,
1189 ) -> Result<Self, Self::Error> {
1190 fiber_broadcast_message.to_enum().try_into()
1191 }
1192}
1193
1194impl Ord for Cursor {
1195 fn cmp(&self, other: &Self) -> Ordering {
1196 self.to_bytes().cmp(&other.to_bytes())
1197 }
1198}
1199
1200impl PartialOrd for Cursor {
1201 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1202 Some(self.cmp(other))
1203 }
1204}
1205
1206impl From<Cursor> for molecule_gossip::Cursor {
1207 fn from(cursor: Cursor) -> Self {
1208 use molecule::prelude::{Builder, Byte};
1209 let serialized = cursor
1210 .timestamp
1211 .to_be_bytes()
1212 .into_iter()
1213 .chain(cursor.message_id.to_bytes())
1214 .map(Byte::new)
1215 .collect::<Vec<_>>()
1216 .try_into()
1217 .expect("Must serialize cursor to 45 bytes");
1218
1219 molecule_gossip::Cursor::new_builder()
1220 .set(serialized)
1221 .build()
1222 }
1223}
1224
1225impl TryFrom<molecule_gossip::Cursor> for Cursor {
1226 type Error = anyhow::Error;
1227
1228 fn try_from(cursor: molecule_gossip::Cursor) -> Result<Self, Self::Error> {
1229 use molecule::prelude::Entity;
1230 let slice = cursor.as_slice();
1231 if slice.len() != CURSOR_SIZE {
1232 anyhow::bail!("Invalid cursor size: {}, want {}", slice.len(), CURSOR_SIZE);
1233 }
1234 let timestamp = u64::from_be_bytes(slice[..8].try_into().expect("Cursor timestamp to u64"));
1235 let message_id = BroadcastMessageID::from_bytes(&slice[8..])?;
1236 Ok(Cursor {
1237 timestamp,
1238 message_id,
1239 })
1240 }
1241}