From a2461ccdce800ec0b0bcfda4400b4227da845da6 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 27 Dec 2024 23:50:45 +0800 Subject: [PATCH] use molecule for serialize and deserialize hopdata and tlcerr --- Cargo.lock | 22 + Cargo.toml | 1 + src/fiber/gen/fiber.rs | 2661 +++++++++++++++++++++++++++++++++++ src/fiber/gen/gossip.rs | 2056 +-------------------------- src/fiber/schema/fiber.mol | 50 + src/fiber/schema/gossip.mol | 39 - src/fiber/tests/channel.rs | 5 +- src/fiber/tests/types.rs | 13 + src/fiber/types.rs | 244 +++- 9 files changed, 2963 insertions(+), 2128 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4049c90f9..ea31525f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1621,6 +1621,7 @@ dependencies = [ "molecule", "musig2", "nom", + "num_enum", "once_cell", "ractor", "rand 0.8.5", @@ -2809,6 +2810,27 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "number_prefix" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 4b6d37c80..962d1fd71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ tokio = { version = "1", features = [ indicatif = "0.16" console = "0.15.8" bincode = "1.3.3" +num_enum = "0.7.3" [features] default = [] diff --git a/src/fiber/gen/fiber.rs b/src/fiber/gen/fiber.rs index a553f2eed..16edafea5 100644 --- a/src/fiber/gen/fiber.rs +++ b/src/fiber/gen/fiber.rs @@ -3,6 +3,231 @@ use super::blockchain::*; use molecule::prelude::*; #[derive(Clone)] +pub struct Uint16(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for Uint16 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for Uint16 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for Uint16 { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl ::core::default::Default for Uint16 { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + Uint16::new_unchecked(v) + } +} +impl Uint16 { + const DEFAULT_VALUE: [u8; 2] = [0, 0]; + pub const TOTAL_SIZE: usize = 2; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 2; + pub fn nth0(&self) -> Byte { + Byte::new_unchecked(self.0.slice(0..1)) + } + pub fn nth1(&self) -> Byte { + Byte::new_unchecked(self.0.slice(1..2)) + } + pub fn raw_data(&self) -> molecule::bytes::Bytes { + self.as_bytes() + } + pub fn as_reader<'r>(&'r self) -> Uint16Reader<'r> { + Uint16Reader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for Uint16 { + type Builder = Uint16Builder; + const NAME: &'static str = "Uint16"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + Uint16(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + Uint16Reader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + Uint16Reader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set([self.nth0(), self.nth1()]) + } +} +#[derive(Clone, Copy)] +pub struct Uint16Reader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for Uint16Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for Uint16Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for Uint16Reader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + let raw_data = hex_string(&self.raw_data()); + write!(f, "{}(0x{})", Self::NAME, raw_data) + } +} +impl<'r> Uint16Reader<'r> { + pub const TOTAL_SIZE: usize = 2; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 2; + pub fn nth0(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[0..1]) + } + pub fn nth1(&self) -> ByteReader<'r> { + ByteReader::new_unchecked(&self.as_slice()[1..2]) + } + pub fn raw_data(&self) -> &'r [u8] { + self.as_slice() + } +} +impl<'r> molecule::prelude::Reader<'r> for Uint16Reader<'r> { + type Entity = Uint16; + const NAME: &'static str = "Uint16Reader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + Uint16Reader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +#[derive(Clone)] +pub struct Uint16Builder(pub(crate) [Byte; 2]); +impl ::core::fmt::Debug for Uint16Builder { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:?})", Self::NAME, &self.0[..]) + } +} +impl ::core::default::Default for Uint16Builder { + fn default() -> Self { + Uint16Builder([Byte::default(), Byte::default()]) + } +} +impl Uint16Builder { + pub const TOTAL_SIZE: usize = 2; + pub const ITEM_SIZE: usize = 1; + pub const ITEM_COUNT: usize = 2; + pub fn set(mut self, v: [Byte; 2]) -> Self { + self.0 = v; + self + } + pub fn nth0(mut self, v: Byte) -> Self { + self.0[0] = v; + self + } + pub fn nth1(mut self, v: Byte) -> Self { + self.0[1] = v; + self + } +} +impl molecule::prelude::Builder for Uint16Builder { + type Entity = Uint16; + const NAME: &'static str = "Uint16Builder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.0[0].as_slice())?; + writer.write_all(self.0[1].as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + Uint16::new_unchecked(inner.into()) + } +} +impl From<[Byte; 2usize]> for Uint16 { + fn from(value: [Byte; 2usize]) -> Self { + Self::new_builder().set(value).build() + } +} +impl ::core::convert::TryFrom<&[Byte]> for Uint16 { + type Error = ::core::array::TryFromSliceError; + fn try_from(value: &[Byte]) -> Result { + Ok(Self::new_builder() + .set(<&[Byte; 2usize]>::try_from(value)?.clone()) + .build()) + } +} +impl From for [Byte; 2usize] { + #[track_caller] + fn from(value: Uint16) -> Self { + [value.nth0(), value.nth1()] + } +} +impl From<[u8; 2usize]> for Uint16 { + fn from(value: [u8; 2usize]) -> Self { + Uint16Reader::new_unchecked(&value).to_entity() + } +} +impl ::core::convert::TryFrom<&[u8]> for Uint16 { + type Error = ::core::array::TryFromSliceError; + fn try_from(value: &[u8]) -> Result { + Ok(<[u8; 2usize]>::try_from(value)?.into()) + } +} +impl From for [u8; 2usize] { + #[track_caller] + fn from(value: Uint16) -> Self { + ::core::convert::TryFrom::try_from(value.as_slice()).unwrap() + } +} +impl<'a> From> for &'a [u8; 2usize] { + #[track_caller] + fn from(value: Uint16Reader<'a>) -> Self { + ::core::convert::TryFrom::try_from(value.as_slice()).unwrap() + } +} +impl<'a> From<&'a Uint16Reader<'a>> for &'a [u8; 2usize] { + #[track_caller] + fn from(value: &'a Uint16Reader<'a>) -> Self { + ::core::convert::TryFrom::try_from(value.as_slice()).unwrap() + } +} +#[derive(Clone)] pub struct EcdsaSignature(molecule::bytes::Bytes); impl ::core::fmt::LowerHex for EcdsaSignature { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { @@ -11764,3 +11989,2439 @@ impl From for FiberMessage { Self::new_builder().set(value).build() } } +#[derive(Clone)] +pub struct PaymentPreimageOpt(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for PaymentPreimageOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for PaymentPreimageOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for PaymentPreimageOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl ::core::default::Default for PaymentPreimageOpt { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + PaymentPreimageOpt::new_unchecked(v) + } +} +impl PaymentPreimageOpt { + const DEFAULT_VALUE: [u8; 0] = []; + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option { + if self.is_none() { + None + } else { + Some(Byte32::new_unchecked(self.0.clone())) + } + } + pub fn as_reader<'r>(&'r self) -> PaymentPreimageOptReader<'r> { + PaymentPreimageOptReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for PaymentPreimageOpt { + type Builder = PaymentPreimageOptBuilder; + const NAME: &'static str = "PaymentPreimageOpt"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + PaymentPreimageOpt(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + PaymentPreimageOptReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + PaymentPreimageOptReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_opt()) + } +} +#[derive(Clone, Copy)] +pub struct PaymentPreimageOptReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for PaymentPreimageOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for PaymentPreimageOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for PaymentPreimageOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl<'r> PaymentPreimageOptReader<'r> { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option> { + if self.is_none() { + None + } else { + Some(Byte32Reader::new_unchecked(self.as_slice())) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for PaymentPreimageOptReader<'r> { + type Entity = PaymentPreimageOpt; + const NAME: &'static str = "PaymentPreimageOptReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + PaymentPreimageOptReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + if !slice.is_empty() { + Byte32Reader::verify(&slice[..], compatible)?; + } + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct PaymentPreimageOptBuilder(pub(crate) Option); +impl PaymentPreimageOptBuilder { + pub fn set(mut self, v: Option) -> Self { + self.0 = v; + self + } +} +impl molecule::prelude::Builder for PaymentPreimageOptBuilder { + type Entity = PaymentPreimageOpt; + const NAME: &'static str = "PaymentPreimageOptBuilder"; + fn expected_length(&self) -> usize { + self.0 + .as_ref() + .map(|ref inner| inner.as_slice().len()) + .unwrap_or(0) + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + self.0 + .as_ref() + .map(|ref inner| writer.write_all(inner.as_slice())) + .unwrap_or(Ok(())) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + PaymentPreimageOpt::new_unchecked(inner.into()) + } +} +impl From for PaymentPreimageOpt { + fn from(value: Byte32) -> Self { + Self::new_builder().set(Some(value)).build() + } +} +#[derive(Clone)] +pub struct PubkeyOpt(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for PubkeyOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for PubkeyOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for PubkeyOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl ::core::default::Default for PubkeyOpt { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + PubkeyOpt::new_unchecked(v) + } +} +impl PubkeyOpt { + const DEFAULT_VALUE: [u8; 0] = []; + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option { + if self.is_none() { + None + } else { + Some(Pubkey::new_unchecked(self.0.clone())) + } + } + pub fn as_reader<'r>(&'r self) -> PubkeyOptReader<'r> { + PubkeyOptReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for PubkeyOpt { + type Builder = PubkeyOptBuilder; + const NAME: &'static str = "PubkeyOpt"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + PubkeyOpt(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + PubkeyOptReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + PubkeyOptReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_opt()) + } +} +#[derive(Clone, Copy)] +pub struct PubkeyOptReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for PubkeyOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for PubkeyOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for PubkeyOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl<'r> PubkeyOptReader<'r> { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option> { + if self.is_none() { + None + } else { + Some(PubkeyReader::new_unchecked(self.as_slice())) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for PubkeyOptReader<'r> { + type Entity = PubkeyOpt; + const NAME: &'static str = "PubkeyOptReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + PubkeyOptReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + if !slice.is_empty() { + PubkeyReader::verify(&slice[..], compatible)?; + } + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct PubkeyOptBuilder(pub(crate) Option); +impl PubkeyOptBuilder { + pub fn set(mut self, v: Option) -> Self { + self.0 = v; + self + } +} +impl molecule::prelude::Builder for PubkeyOptBuilder { + type Entity = PubkeyOpt; + const NAME: &'static str = "PubkeyOptBuilder"; + fn expected_length(&self) -> usize { + self.0 + .as_ref() + .map(|ref inner| inner.as_slice().len()) + .unwrap_or(0) + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + self.0 + .as_ref() + .map(|ref inner| writer.write_all(inner.as_slice())) + .unwrap_or(Ok(())) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + PubkeyOpt::new_unchecked(inner.into()) + } +} +impl From for PubkeyOpt { + fn from(value: Pubkey) -> Self { + Self::new_builder().set(Some(value)).build() + } +} +#[derive(Clone)] +pub struct PaymentHopData(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for PaymentHopData { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for PaymentHopData { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for PaymentHopData { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "amount", self.amount())?; + write!(f, ", {}: {}", "expiry", self.expiry())?; + write!(f, ", {}: {}", "payment_preimage", self.payment_preimage())?; + write!(f, ", {}: {}", "hash_algorithm", self.hash_algorithm())?; + write!(f, ", {}: {}", "funding_tx_hash", self.funding_tx_hash())?; + write!(f, ", {}: {}", "next_hop", self.next_hop())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for PaymentHopData { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + PaymentHopData::new_unchecked(v) + } +} +impl PaymentHopData { + const DEFAULT_VALUE: [u8; 85] = [ + 85, 0, 0, 0, 28, 0, 0, 0, 44, 0, 0, 0, 52, 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const FIELD_COUNT: usize = 6; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn amount(&self) -> Uint128 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Uint128::new_unchecked(self.0.slice(start..end)) + } + pub fn expiry(&self) -> Uint64 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Uint64::new_unchecked(self.0.slice(start..end)) + } + pub fn payment_preimage(&self) -> PaymentPreimageOpt { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + PaymentPreimageOpt::new_unchecked(self.0.slice(start..end)) + } + pub fn hash_algorithm(&self) -> Byte { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + Byte::new_unchecked(self.0.slice(start..end)) + } + pub fn funding_tx_hash(&self) -> Byte32 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Byte32::new_unchecked(self.0.slice(start..end)) + } + pub fn next_hop(&self) -> PubkeyOpt { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[28..]) as usize; + PubkeyOpt::new_unchecked(self.0.slice(start..end)) + } else { + PubkeyOpt::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> PaymentHopDataReader<'r> { + PaymentHopDataReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for PaymentHopData { + type Builder = PaymentHopDataBuilder; + const NAME: &'static str = "PaymentHopData"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + PaymentHopData(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + PaymentHopDataReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + PaymentHopDataReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .amount(self.amount()) + .expiry(self.expiry()) + .payment_preimage(self.payment_preimage()) + .hash_algorithm(self.hash_algorithm()) + .funding_tx_hash(self.funding_tx_hash()) + .next_hop(self.next_hop()) + } +} +#[derive(Clone, Copy)] +pub struct PaymentHopDataReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for PaymentHopDataReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for PaymentHopDataReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for PaymentHopDataReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "amount", self.amount())?; + write!(f, ", {}: {}", "expiry", self.expiry())?; + write!(f, ", {}: {}", "payment_preimage", self.payment_preimage())?; + write!(f, ", {}: {}", "hash_algorithm", self.hash_algorithm())?; + write!(f, ", {}: {}", "funding_tx_hash", self.funding_tx_hash())?; + write!(f, ", {}: {}", "next_hop", self.next_hop())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> PaymentHopDataReader<'r> { + pub const FIELD_COUNT: usize = 6; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn amount(&self) -> Uint128Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Uint128Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn expiry(&self) -> Uint64Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + Uint64Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn payment_preimage(&self) -> PaymentPreimageOptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + let end = molecule::unpack_number(&slice[16..]) as usize; + PaymentPreimageOptReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn hash_algorithm(&self) -> ByteReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[16..]) as usize; + let end = molecule::unpack_number(&slice[20..]) as usize; + ByteReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn funding_tx_hash(&self) -> Byte32Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[20..]) as usize; + let end = molecule::unpack_number(&slice[24..]) as usize; + Byte32Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn next_hop(&self) -> PubkeyOptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[24..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[28..]) as usize; + PubkeyOptReader::new_unchecked(&self.as_slice()[start..end]) + } else { + PubkeyOptReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for PaymentHopDataReader<'r> { + type Entity = PaymentHopData; + const NAME: &'static str = "PaymentHopDataReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + PaymentHopDataReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + Uint128Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + Uint64Reader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + PaymentPreimageOptReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + ByteReader::verify(&slice[offsets[3]..offsets[4]], compatible)?; + Byte32Reader::verify(&slice[offsets[4]..offsets[5]], compatible)?; + PubkeyOptReader::verify(&slice[offsets[5]..offsets[6]], compatible)?; + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct PaymentHopDataBuilder { + pub(crate) amount: Uint128, + pub(crate) expiry: Uint64, + pub(crate) payment_preimage: PaymentPreimageOpt, + pub(crate) hash_algorithm: Byte, + pub(crate) funding_tx_hash: Byte32, + pub(crate) next_hop: PubkeyOpt, +} +impl PaymentHopDataBuilder { + pub const FIELD_COUNT: usize = 6; + pub fn amount(mut self, v: Uint128) -> Self { + self.amount = v; + self + } + pub fn expiry(mut self, v: Uint64) -> Self { + self.expiry = v; + self + } + pub fn payment_preimage(mut self, v: PaymentPreimageOpt) -> Self { + self.payment_preimage = v; + self + } + pub fn hash_algorithm(mut self, v: Byte) -> Self { + self.hash_algorithm = v; + self + } + pub fn funding_tx_hash(mut self, v: Byte32) -> Self { + self.funding_tx_hash = v; + self + } + pub fn next_hop(mut self, v: PubkeyOpt) -> Self { + self.next_hop = v; + self + } +} +impl molecule::prelude::Builder for PaymentHopDataBuilder { + type Entity = PaymentHopData; + const NAME: &'static str = "PaymentHopDataBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.amount.as_slice().len() + + self.expiry.as_slice().len() + + self.payment_preimage.as_slice().len() + + self.hash_algorithm.as_slice().len() + + self.funding_tx_hash.as_slice().len() + + self.next_hop.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.amount.as_slice().len(); + offsets.push(total_size); + total_size += self.expiry.as_slice().len(); + offsets.push(total_size); + total_size += self.payment_preimage.as_slice().len(); + offsets.push(total_size); + total_size += self.hash_algorithm.as_slice().len(); + offsets.push(total_size); + total_size += self.funding_tx_hash.as_slice().len(); + offsets.push(total_size); + total_size += self.next_hop.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.amount.as_slice())?; + writer.write_all(self.expiry.as_slice())?; + writer.write_all(self.payment_preimage.as_slice())?; + writer.write_all(self.hash_algorithm.as_slice())?; + writer.write_all(self.funding_tx_hash.as_slice())?; + writer.write_all(self.next_hop.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + PaymentHopData::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelUpdate(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelUpdate { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelUpdate { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelUpdate { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "signature", self.signature())?; + write!(f, ", {}: {}", "chain_hash", self.chain_hash())?; + write!(f, ", {}: {}", "channel_outpoint", self.channel_outpoint())?; + write!(f, ", {}: {}", "timestamp", self.timestamp())?; + write!(f, ", {}: {}", "message_flags", self.message_flags())?; + write!(f, ", {}: {}", "channel_flags", self.channel_flags())?; + write!(f, ", {}: {}", "tlc_expiry_delta", self.tlc_expiry_delta())?; + write!(f, ", {}: {}", "tlc_minimum_value", self.tlc_minimum_value())?; + write!(f, ", {}: {}", "tlc_maximum_value", self.tlc_maximum_value())?; + write!( + f, + ", {}: {}", + "tlc_fee_proportional_millionths", + self.tlc_fee_proportional_millionths() + )?; + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelUpdate { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + ChannelUpdate::new_unchecked(v) + } +} +impl ChannelUpdate { + const DEFAULT_VALUE: [u8; 204] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const TOTAL_SIZE: usize = 204; + pub const FIELD_SIZES: [usize; 10] = [64, 32, 36, 8, 4, 4, 8, 16, 16, 16]; + pub const FIELD_COUNT: usize = 10; + pub fn signature(&self) -> EcdsaSignature { + EcdsaSignature::new_unchecked(self.0.slice(0..64)) + } + pub fn chain_hash(&self) -> Byte32 { + Byte32::new_unchecked(self.0.slice(64..96)) + } + pub fn channel_outpoint(&self) -> OutPoint { + OutPoint::new_unchecked(self.0.slice(96..132)) + } + pub fn timestamp(&self) -> Uint64 { + Uint64::new_unchecked(self.0.slice(132..140)) + } + pub fn message_flags(&self) -> Uint32 { + Uint32::new_unchecked(self.0.slice(140..144)) + } + pub fn channel_flags(&self) -> Uint32 { + Uint32::new_unchecked(self.0.slice(144..148)) + } + pub fn tlc_expiry_delta(&self) -> Uint64 { + Uint64::new_unchecked(self.0.slice(148..156)) + } + pub fn tlc_minimum_value(&self) -> Uint128 { + Uint128::new_unchecked(self.0.slice(156..172)) + } + pub fn tlc_maximum_value(&self) -> Uint128 { + Uint128::new_unchecked(self.0.slice(172..188)) + } + pub fn tlc_fee_proportional_millionths(&self) -> Uint128 { + Uint128::new_unchecked(self.0.slice(188..204)) + } + pub fn as_reader<'r>(&'r self) -> ChannelUpdateReader<'r> { + ChannelUpdateReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelUpdate { + type Builder = ChannelUpdateBuilder; + const NAME: &'static str = "ChannelUpdate"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelUpdate(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelUpdateReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelUpdateReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .signature(self.signature()) + .chain_hash(self.chain_hash()) + .channel_outpoint(self.channel_outpoint()) + .timestamp(self.timestamp()) + .message_flags(self.message_flags()) + .channel_flags(self.channel_flags()) + .tlc_expiry_delta(self.tlc_expiry_delta()) + .tlc_minimum_value(self.tlc_minimum_value()) + .tlc_maximum_value(self.tlc_maximum_value()) + .tlc_fee_proportional_millionths(self.tlc_fee_proportional_millionths()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelUpdateReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelUpdateReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelUpdateReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelUpdateReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "signature", self.signature())?; + write!(f, ", {}: {}", "chain_hash", self.chain_hash())?; + write!(f, ", {}: {}", "channel_outpoint", self.channel_outpoint())?; + write!(f, ", {}: {}", "timestamp", self.timestamp())?; + write!(f, ", {}: {}", "message_flags", self.message_flags())?; + write!(f, ", {}: {}", "channel_flags", self.channel_flags())?; + write!(f, ", {}: {}", "tlc_expiry_delta", self.tlc_expiry_delta())?; + write!(f, ", {}: {}", "tlc_minimum_value", self.tlc_minimum_value())?; + write!(f, ", {}: {}", "tlc_maximum_value", self.tlc_maximum_value())?; + write!( + f, + ", {}: {}", + "tlc_fee_proportional_millionths", + self.tlc_fee_proportional_millionths() + )?; + write!(f, " }}") + } +} +impl<'r> ChannelUpdateReader<'r> { + pub const TOTAL_SIZE: usize = 204; + pub const FIELD_SIZES: [usize; 10] = [64, 32, 36, 8, 4, 4, 8, 16, 16, 16]; + pub const FIELD_COUNT: usize = 10; + pub fn signature(&self) -> EcdsaSignatureReader<'r> { + EcdsaSignatureReader::new_unchecked(&self.as_slice()[0..64]) + } + pub fn chain_hash(&self) -> Byte32Reader<'r> { + Byte32Reader::new_unchecked(&self.as_slice()[64..96]) + } + pub fn channel_outpoint(&self) -> OutPointReader<'r> { + OutPointReader::new_unchecked(&self.as_slice()[96..132]) + } + pub fn timestamp(&self) -> Uint64Reader<'r> { + Uint64Reader::new_unchecked(&self.as_slice()[132..140]) + } + pub fn message_flags(&self) -> Uint32Reader<'r> { + Uint32Reader::new_unchecked(&self.as_slice()[140..144]) + } + pub fn channel_flags(&self) -> Uint32Reader<'r> { + Uint32Reader::new_unchecked(&self.as_slice()[144..148]) + } + pub fn tlc_expiry_delta(&self) -> Uint64Reader<'r> { + Uint64Reader::new_unchecked(&self.as_slice()[148..156]) + } + pub fn tlc_minimum_value(&self) -> Uint128Reader<'r> { + Uint128Reader::new_unchecked(&self.as_slice()[156..172]) + } + pub fn tlc_maximum_value(&self) -> Uint128Reader<'r> { + Uint128Reader::new_unchecked(&self.as_slice()[172..188]) + } + pub fn tlc_fee_proportional_millionths(&self) -> Uint128Reader<'r> { + Uint128Reader::new_unchecked(&self.as_slice()[188..204]) + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelUpdateReader<'r> { + type Entity = ChannelUpdate; + const NAME: &'static str = "ChannelUpdateReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelUpdateReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len != Self::TOTAL_SIZE { + return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); + } + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct ChannelUpdateBuilder { + pub(crate) signature: EcdsaSignature, + pub(crate) chain_hash: Byte32, + pub(crate) channel_outpoint: OutPoint, + pub(crate) timestamp: Uint64, + pub(crate) message_flags: Uint32, + pub(crate) channel_flags: Uint32, + pub(crate) tlc_expiry_delta: Uint64, + pub(crate) tlc_minimum_value: Uint128, + pub(crate) tlc_maximum_value: Uint128, + pub(crate) tlc_fee_proportional_millionths: Uint128, +} +impl ChannelUpdateBuilder { + pub const TOTAL_SIZE: usize = 204; + pub const FIELD_SIZES: [usize; 10] = [64, 32, 36, 8, 4, 4, 8, 16, 16, 16]; + pub const FIELD_COUNT: usize = 10; + pub fn signature(mut self, v: EcdsaSignature) -> Self { + self.signature = v; + self + } + pub fn chain_hash(mut self, v: Byte32) -> Self { + self.chain_hash = v; + self + } + pub fn channel_outpoint(mut self, v: OutPoint) -> Self { + self.channel_outpoint = v; + self + } + pub fn timestamp(mut self, v: Uint64) -> Self { + self.timestamp = v; + self + } + pub fn message_flags(mut self, v: Uint32) -> Self { + self.message_flags = v; + self + } + pub fn channel_flags(mut self, v: Uint32) -> Self { + self.channel_flags = v; + self + } + pub fn tlc_expiry_delta(mut self, v: Uint64) -> Self { + self.tlc_expiry_delta = v; + self + } + pub fn tlc_minimum_value(mut self, v: Uint128) -> Self { + self.tlc_minimum_value = v; + self + } + pub fn tlc_maximum_value(mut self, v: Uint128) -> Self { + self.tlc_maximum_value = v; + self + } + pub fn tlc_fee_proportional_millionths(mut self, v: Uint128) -> Self { + self.tlc_fee_proportional_millionths = v; + self + } +} +impl molecule::prelude::Builder for ChannelUpdateBuilder { + type Entity = ChannelUpdate; + const NAME: &'static str = "ChannelUpdateBuilder"; + fn expected_length(&self) -> usize { + Self::TOTAL_SIZE + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(self.signature.as_slice())?; + writer.write_all(self.chain_hash.as_slice())?; + writer.write_all(self.channel_outpoint.as_slice())?; + writer.write_all(self.timestamp.as_slice())?; + writer.write_all(self.message_flags.as_slice())?; + writer.write_all(self.channel_flags.as_slice())?; + writer.write_all(self.tlc_expiry_delta.as_slice())?; + writer.write_all(self.tlc_minimum_value.as_slice())?; + writer.write_all(self.tlc_maximum_value.as_slice())?; + writer.write_all(self.tlc_fee_proportional_millionths.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelUpdate::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct ChannelUpdateOpt(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelUpdateOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelUpdateOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelUpdateOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl ::core::default::Default for ChannelUpdateOpt { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + ChannelUpdateOpt::new_unchecked(v) + } +} +impl ChannelUpdateOpt { + const DEFAULT_VALUE: [u8; 0] = []; + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option { + if self.is_none() { + None + } else { + Some(ChannelUpdate::new_unchecked(self.0.clone())) + } + } + pub fn as_reader<'r>(&'r self) -> ChannelUpdateOptReader<'r> { + ChannelUpdateOptReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelUpdateOpt { + type Builder = ChannelUpdateOptBuilder; + const NAME: &'static str = "ChannelUpdateOpt"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelUpdateOpt(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelUpdateOptReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelUpdateOptReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_opt()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelUpdateOptReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelUpdateOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelUpdateOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelUpdateOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl<'r> ChannelUpdateOptReader<'r> { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option> { + if self.is_none() { + None + } else { + Some(ChannelUpdateReader::new_unchecked(self.as_slice())) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelUpdateOptReader<'r> { + type Entity = ChannelUpdateOpt; + const NAME: &'static str = "ChannelUpdateOptReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelUpdateOptReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + if !slice.is_empty() { + ChannelUpdateReader::verify(&slice[..], compatible)?; + } + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct ChannelUpdateOptBuilder(pub(crate) Option); +impl ChannelUpdateOptBuilder { + pub fn set(mut self, v: Option) -> Self { + self.0 = v; + self + } +} +impl molecule::prelude::Builder for ChannelUpdateOptBuilder { + type Entity = ChannelUpdateOpt; + const NAME: &'static str = "ChannelUpdateOptBuilder"; + fn expected_length(&self) -> usize { + self.0 + .as_ref() + .map(|ref inner| inner.as_slice().len()) + .unwrap_or(0) + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + self.0 + .as_ref() + .map(|ref inner| writer.write_all(inner.as_slice())) + .unwrap_or(Ok(())) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelUpdateOpt::new_unchecked(inner.into()) + } +} +impl From for ChannelUpdateOpt { + fn from(value: ChannelUpdate) -> Self { + Self::new_builder().set(Some(value)).build() + } +} +#[derive(Clone)] +pub struct ChannelFailed(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for ChannelFailed { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for ChannelFailed { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for ChannelFailed { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "channel_outpoint", self.channel_outpoint())?; + write!(f, ", {}: {}", "channel_update", self.channel_update())?; + write!(f, ", {}: {}", "node_id", self.node_id())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for ChannelFailed { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + ChannelFailed::new_unchecked(v) + } +} +impl ChannelFailed { + const DEFAULT_VALUE: [u8; 85] = [ + 85, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const FIELD_COUNT: usize = 3; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn channel_outpoint(&self) -> OutPoint { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + OutPoint::new_unchecked(self.0.slice(start..end)) + } + pub fn channel_update(&self) -> ChannelUpdateOpt { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ChannelUpdateOpt::new_unchecked(self.0.slice(start..end)) + } + pub fn node_id(&self) -> Pubkey { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + Pubkey::new_unchecked(self.0.slice(start..end)) + } else { + Pubkey::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> ChannelFailedReader<'r> { + ChannelFailedReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for ChannelFailed { + type Builder = ChannelFailedBuilder; + const NAME: &'static str = "ChannelFailed"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + ChannelFailed(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelFailedReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + ChannelFailedReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .channel_outpoint(self.channel_outpoint()) + .channel_update(self.channel_update()) + .node_id(self.node_id()) + } +} +#[derive(Clone, Copy)] +pub struct ChannelFailedReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for ChannelFailedReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for ChannelFailedReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for ChannelFailedReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "channel_outpoint", self.channel_outpoint())?; + write!(f, ", {}: {}", "channel_update", self.channel_update())?; + write!(f, ", {}: {}", "node_id", self.node_id())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> ChannelFailedReader<'r> { + pub const FIELD_COUNT: usize = 3; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn channel_outpoint(&self) -> OutPointReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + OutPointReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn channel_update(&self) -> ChannelUpdateOptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + let end = molecule::unpack_number(&slice[12..]) as usize; + ChannelUpdateOptReader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn node_id(&self) -> PubkeyReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[12..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[16..]) as usize; + PubkeyReader::new_unchecked(&self.as_slice()[start..end]) + } else { + PubkeyReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for ChannelFailedReader<'r> { + type Entity = ChannelFailed; + const NAME: &'static str = "ChannelFailedReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + ChannelFailedReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + OutPointReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + ChannelUpdateOptReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + PubkeyReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct ChannelFailedBuilder { + pub(crate) channel_outpoint: OutPoint, + pub(crate) channel_update: ChannelUpdateOpt, + pub(crate) node_id: Pubkey, +} +impl ChannelFailedBuilder { + pub const FIELD_COUNT: usize = 3; + pub fn channel_outpoint(mut self, v: OutPoint) -> Self { + self.channel_outpoint = v; + self + } + pub fn channel_update(mut self, v: ChannelUpdateOpt) -> Self { + self.channel_update = v; + self + } + pub fn node_id(mut self, v: Pubkey) -> Self { + self.node_id = v; + self + } +} +impl molecule::prelude::Builder for ChannelFailedBuilder { + type Entity = ChannelFailed; + const NAME: &'static str = "ChannelFailedBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.channel_outpoint.as_slice().len() + + self.channel_update.as_slice().len() + + self.node_id.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.channel_outpoint.as_slice().len(); + offsets.push(total_size); + total_size += self.channel_update.as_slice().len(); + offsets.push(total_size); + total_size += self.node_id.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.channel_outpoint.as_slice())?; + writer.write_all(self.channel_update.as_slice())?; + writer.write_all(self.node_id.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + ChannelFailed::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct NodeFailed(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for NodeFailed { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for NodeFailed { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for NodeFailed { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "node_id", self.node_id())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for NodeFailed { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + NodeFailed::new_unchecked(v) + } +} +impl NodeFailed { + const DEFAULT_VALUE: [u8; 41] = [ + 41, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const FIELD_COUNT: usize = 1; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn node_id(&self) -> Pubkey { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[8..]) as usize; + Pubkey::new_unchecked(self.0.slice(start..end)) + } else { + Pubkey::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> NodeFailedReader<'r> { + NodeFailedReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for NodeFailed { + type Builder = NodeFailedBuilder; + const NAME: &'static str = "NodeFailed"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + NodeFailed(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + NodeFailedReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + NodeFailedReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().node_id(self.node_id()) + } +} +#[derive(Clone, Copy)] +pub struct NodeFailedReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for NodeFailedReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for NodeFailedReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for NodeFailedReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "node_id", self.node_id())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> NodeFailedReader<'r> { + pub const FIELD_COUNT: usize = 1; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn node_id(&self) -> PubkeyReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[8..]) as usize; + PubkeyReader::new_unchecked(&self.as_slice()[start..end]) + } else { + PubkeyReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for NodeFailedReader<'r> { + type Entity = NodeFailed; + const NAME: &'static str = "NodeFailedReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + NodeFailedReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + PubkeyReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct NodeFailedBuilder { + pub(crate) node_id: Pubkey, +} +impl NodeFailedBuilder { + pub const FIELD_COUNT: usize = 1; + pub fn node_id(mut self, v: Pubkey) -> Self { + self.node_id = v; + self + } +} +impl molecule::prelude::Builder for NodeFailedBuilder { + type Entity = NodeFailed; + const NAME: &'static str = "NodeFailedBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + self.node_id.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.node_id.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.node_id.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + NodeFailed::new_unchecked(inner.into()) + } +} +#[derive(Clone)] +pub struct TlcErrData(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for TlcErrData { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for TlcErrData { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for TlcErrData { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl ::core::default::Default for TlcErrData { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + TlcErrData::new_unchecked(v) + } +} +impl TlcErrData { + const DEFAULT_VALUE: [u8; 89] = [ + 0, 0, 0, 0, 85, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + pub const ITEMS_COUNT: usize = 2; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> TlcErrDataUnion { + let inner = self.0.slice(molecule::NUMBER_SIZE..); + match self.item_id() { + 0 => ChannelFailed::new_unchecked(inner).into(), + 1 => NodeFailed::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } + pub fn as_reader<'r>(&'r self) -> TlcErrDataReader<'r> { + TlcErrDataReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for TlcErrData { + type Builder = TlcErrDataBuilder; + const NAME: &'static str = "TlcErrData"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + TlcErrData(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TlcErrDataReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TlcErrDataReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_enum()) + } +} +#[derive(Clone, Copy)] +pub struct TlcErrDataReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TlcErrDataReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for TlcErrDataReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TlcErrDataReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") + } +} +impl<'r> TlcErrDataReader<'r> { + pub const ITEMS_COUNT: usize = 2; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) + } + pub fn to_enum(&self) -> TlcErrDataUnionReader<'r> { + let inner = &self.as_slice()[molecule::NUMBER_SIZE..]; + match self.item_id() { + 0 => ChannelFailedReader::new_unchecked(inner).into(), + 1 => NodeFailedReader::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } + } +} +impl<'r> molecule::prelude::Reader<'r> for TlcErrDataReader<'r> { + type Entity = TlcErrData; + const NAME: &'static str = "TlcErrDataReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + TlcErrDataReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let item_id = molecule::unpack_number(slice); + let inner_slice = &slice[molecule::NUMBER_SIZE..]; + match item_id { + 0 => ChannelFailedReader::verify(inner_slice, compatible), + 1 => NodeFailedReader::verify(inner_slice, compatible), + _ => ve!(Self, UnknownItem, Self::ITEMS_COUNT, item_id), + }?; + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct TlcErrDataBuilder(pub(crate) TlcErrDataUnion); +impl TlcErrDataBuilder { + pub const ITEMS_COUNT: usize = 2; + pub fn set(mut self, v: I) -> Self + where + I: ::core::convert::Into, + { + self.0 = v.into(); + self + } +} +impl molecule::prelude::Builder for TlcErrDataBuilder { + type Entity = TlcErrData; + const NAME: &'static str = "TlcErrDataBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE + self.0.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + writer.write_all(&molecule::pack_number(self.0.item_id()))?; + writer.write_all(self.0.as_slice()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + TlcErrData::new_unchecked(inner.into()) + } +} +#[derive(Debug, Clone)] +pub enum TlcErrDataUnion { + ChannelFailed(ChannelFailed), + NodeFailed(NodeFailed), +} +#[derive(Debug, Clone, Copy)] +pub enum TlcErrDataUnionReader<'r> { + ChannelFailed(ChannelFailedReader<'r>), + NodeFailed(NodeFailedReader<'r>), +} +impl ::core::default::Default for TlcErrDataUnion { + fn default() -> Self { + TlcErrDataUnion::ChannelFailed(::core::default::Default::default()) + } +} +impl ::core::fmt::Display for TlcErrDataUnion { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TlcErrDataUnion::ChannelFailed(ref item) => { + write!(f, "{}::{}({})", Self::NAME, ChannelFailed::NAME, item) + } + TlcErrDataUnion::NodeFailed(ref item) => { + write!(f, "{}::{}({})", Self::NAME, NodeFailed::NAME, item) + } + } + } +} +impl<'r> ::core::fmt::Display for TlcErrDataUnionReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TlcErrDataUnionReader::ChannelFailed(ref item) => { + write!(f, "{}::{}({})", Self::NAME, ChannelFailed::NAME, item) + } + TlcErrDataUnionReader::NodeFailed(ref item) => { + write!(f, "{}::{}({})", Self::NAME, NodeFailed::NAME, item) + } + } + } +} +impl TlcErrDataUnion { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TlcErrDataUnion::ChannelFailed(ref item) => write!(f, "{}", item), + TlcErrDataUnion::NodeFailed(ref item) => write!(f, "{}", item), + } + } +} +impl<'r> TlcErrDataUnionReader<'r> { + pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TlcErrDataUnionReader::ChannelFailed(ref item) => write!(f, "{}", item), + TlcErrDataUnionReader::NodeFailed(ref item) => write!(f, "{}", item), + } + } +} +impl ::core::convert::From for TlcErrDataUnion { + fn from(item: ChannelFailed) -> Self { + TlcErrDataUnion::ChannelFailed(item) + } +} +impl ::core::convert::From for TlcErrDataUnion { + fn from(item: NodeFailed) -> Self { + TlcErrDataUnion::NodeFailed(item) + } +} +impl<'r> ::core::convert::From> for TlcErrDataUnionReader<'r> { + fn from(item: ChannelFailedReader<'r>) -> Self { + TlcErrDataUnionReader::ChannelFailed(item) + } +} +impl<'r> ::core::convert::From> for TlcErrDataUnionReader<'r> { + fn from(item: NodeFailedReader<'r>) -> Self { + TlcErrDataUnionReader::NodeFailed(item) + } +} +impl TlcErrDataUnion { + pub const NAME: &'static str = "TlcErrDataUnion"; + pub fn as_bytes(&self) -> molecule::bytes::Bytes { + match self { + TlcErrDataUnion::ChannelFailed(item) => item.as_bytes(), + TlcErrDataUnion::NodeFailed(item) => item.as_bytes(), + } + } + pub fn as_slice(&self) -> &[u8] { + match self { + TlcErrDataUnion::ChannelFailed(item) => item.as_slice(), + TlcErrDataUnion::NodeFailed(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + TlcErrDataUnion::ChannelFailed(_) => 0, + TlcErrDataUnion::NodeFailed(_) => 1, + } + } + pub fn item_name(&self) -> &str { + match self { + TlcErrDataUnion::ChannelFailed(_) => "ChannelFailed", + TlcErrDataUnion::NodeFailed(_) => "NodeFailed", + } + } + pub fn as_reader<'r>(&'r self) -> TlcErrDataUnionReader<'r> { + match self { + TlcErrDataUnion::ChannelFailed(item) => item.as_reader().into(), + TlcErrDataUnion::NodeFailed(item) => item.as_reader().into(), + } + } +} +impl<'r> TlcErrDataUnionReader<'r> { + pub const NAME: &'r str = "TlcErrDataUnionReader"; + pub fn as_slice(&self) -> &'r [u8] { + match self { + TlcErrDataUnionReader::ChannelFailed(item) => item.as_slice(), + TlcErrDataUnionReader::NodeFailed(item) => item.as_slice(), + } + } + pub fn item_id(&self) -> molecule::Number { + match self { + TlcErrDataUnionReader::ChannelFailed(_) => 0, + TlcErrDataUnionReader::NodeFailed(_) => 1, + } + } + pub fn item_name(&self) -> &str { + match self { + TlcErrDataUnionReader::ChannelFailed(_) => "ChannelFailed", + TlcErrDataUnionReader::NodeFailed(_) => "NodeFailed", + } + } +} +impl From for TlcErrData { + fn from(value: ChannelFailed) -> Self { + Self::new_builder().set(value).build() + } +} +impl From for TlcErrData { + fn from(value: NodeFailed) -> Self { + Self::new_builder().set(value).build() + } +} +#[derive(Clone)] +pub struct TlcErrDataOpt(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for TlcErrDataOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for TlcErrDataOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for TlcErrDataOpt { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl ::core::default::Default for TlcErrDataOpt { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + TlcErrDataOpt::new_unchecked(v) + } +} +impl TlcErrDataOpt { + const DEFAULT_VALUE: [u8; 0] = []; + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option { + if self.is_none() { + None + } else { + Some(TlcErrData::new_unchecked(self.0.clone())) + } + } + pub fn as_reader<'r>(&'r self) -> TlcErrDataOptReader<'r> { + TlcErrDataOptReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for TlcErrDataOpt { + type Builder = TlcErrDataOptBuilder; + const NAME: &'static str = "TlcErrDataOpt"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + TlcErrDataOpt(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TlcErrDataOptReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TlcErrDataOptReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder().set(self.to_opt()) + } +} +#[derive(Clone, Copy)] +pub struct TlcErrDataOptReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TlcErrDataOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for TlcErrDataOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TlcErrDataOptReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + if let Some(v) = self.to_opt() { + write!(f, "{}(Some({}))", Self::NAME, v) + } else { + write!(f, "{}(None)", Self::NAME) + } + } +} +impl<'r> TlcErrDataOptReader<'r> { + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + pub fn is_some(&self) -> bool { + !self.0.is_empty() + } + pub fn to_opt(&self) -> Option> { + if self.is_none() { + None + } else { + Some(TlcErrDataReader::new_unchecked(self.as_slice())) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for TlcErrDataOptReader<'r> { + type Entity = TlcErrDataOpt; + const NAME: &'static str = "TlcErrDataOptReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + TlcErrDataOptReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + if !slice.is_empty() { + TlcErrDataReader::verify(&slice[..], compatible)?; + } + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct TlcErrDataOptBuilder(pub(crate) Option); +impl TlcErrDataOptBuilder { + pub fn set(mut self, v: Option) -> Self { + self.0 = v; + self + } +} +impl molecule::prelude::Builder for TlcErrDataOptBuilder { + type Entity = TlcErrDataOpt; + const NAME: &'static str = "TlcErrDataOptBuilder"; + fn expected_length(&self) -> usize { + self.0 + .as_ref() + .map(|ref inner| inner.as_slice().len()) + .unwrap_or(0) + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + self.0 + .as_ref() + .map(|ref inner| writer.write_all(inner.as_slice())) + .unwrap_or(Ok(())) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + TlcErrDataOpt::new_unchecked(inner.into()) + } +} +impl From for TlcErrDataOpt { + fn from(value: TlcErrData) -> Self { + Self::new_builder().set(Some(value)).build() + } +} +#[derive(Clone)] +pub struct TlcErr(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for TlcErr { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl ::core::fmt::Debug for TlcErr { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl ::core::fmt::Display for TlcErr { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "error_code", self.error_code())?; + write!(f, ", {}: {}", "extra_data", self.extra_data())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl ::core::default::Default for TlcErr { + fn default() -> Self { + let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); + TlcErr::new_unchecked(v) + } +} +impl TlcErr { + const DEFAULT_VALUE: [u8; 14] = [14, 0, 0, 0, 12, 0, 0, 0, 14, 0, 0, 0, 0, 0]; + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn error_code(&self) -> Uint16 { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Uint16::new_unchecked(self.0.slice(start..end)) + } + pub fn extra_data(&self) -> TlcErrDataOpt { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + TlcErrDataOpt::new_unchecked(self.0.slice(start..end)) + } else { + TlcErrDataOpt::new_unchecked(self.0.slice(start..)) + } + } + pub fn as_reader<'r>(&'r self) -> TlcErrReader<'r> { + TlcErrReader::new_unchecked(self.as_slice()) + } +} +impl molecule::prelude::Entity for TlcErr { + type Builder = TlcErrBuilder; + const NAME: &'static str = "TlcErr"; + fn new_unchecked(data: molecule::bytes::Bytes) -> Self { + TlcErr(data) + } + fn as_bytes(&self) -> molecule::bytes::Bytes { + self.0.clone() + } + fn as_slice(&self) -> &[u8] { + &self.0[..] + } + fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TlcErrReader::from_slice(slice).map(|reader| reader.to_entity()) + } + fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { + TlcErrReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + } + fn new_builder() -> Self::Builder { + ::core::default::Default::default() + } + fn as_builder(self) -> Self::Builder { + Self::new_builder() + .error_code(self.error_code()) + .extra_data(self.extra_data()) + } +} +#[derive(Clone, Copy)] +pub struct TlcErrReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for TlcErrReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use molecule::hex_string; + if f.alternate() { + write!(f, "0x")?; + } + write!(f, "{}", hex_string(self.as_slice())) + } +} +impl<'r> ::core::fmt::Debug for TlcErrReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{}({:#x})", Self::NAME, self) + } +} +impl<'r> ::core::fmt::Display for TlcErrReader<'r> { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "{} {{ ", Self::NAME)?; + write!(f, "{}: {}", "error_code", self.error_code())?; + write!(f, ", {}: {}", "extra_data", self.extra_data())?; + let extra_count = self.count_extra_fields(); + if extra_count != 0 { + write!(f, ", .. ({} fields)", extra_count)?; + } + write!(f, " }}") + } +} +impl<'r> TlcErrReader<'r> { + pub const FIELD_COUNT: usize = 2; + pub fn total_size(&self) -> usize { + molecule::unpack_number(self.as_slice()) as usize + } + pub fn field_count(&self) -> usize { + if self.total_size() == molecule::NUMBER_SIZE { + 0 + } else { + (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 + } + } + pub fn count_extra_fields(&self) -> usize { + self.field_count() - Self::FIELD_COUNT + } + pub fn has_extra_fields(&self) -> bool { + Self::FIELD_COUNT != self.field_count() + } + pub fn error_code(&self) -> Uint16Reader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[4..]) as usize; + let end = molecule::unpack_number(&slice[8..]) as usize; + Uint16Reader::new_unchecked(&self.as_slice()[start..end]) + } + pub fn extra_data(&self) -> TlcErrDataOptReader<'r> { + let slice = self.as_slice(); + let start = molecule::unpack_number(&slice[8..]) as usize; + if self.has_extra_fields() { + let end = molecule::unpack_number(&slice[12..]) as usize; + TlcErrDataOptReader::new_unchecked(&self.as_slice()[start..end]) + } else { + TlcErrDataOptReader::new_unchecked(&self.as_slice()[start..]) + } + } +} +impl<'r> molecule::prelude::Reader<'r> for TlcErrReader<'r> { + type Entity = TlcErr; + const NAME: &'static str = "TlcErrReader"; + fn to_entity(&self) -> Self::Entity { + Self::Entity::new_unchecked(self.as_slice().to_owned().into()) + } + fn new_unchecked(slice: &'r [u8]) -> Self { + TlcErrReader(slice) + } + fn as_slice(&self) -> &'r [u8] { + self.0 + } + fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { + use molecule::verification_error as ve; + let slice_len = slice.len(); + if slice_len < molecule::NUMBER_SIZE { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); + } + let total_size = molecule::unpack_number(slice) as usize; + if slice_len != total_size { + return ve!(Self, TotalSizeNotMatch, total_size, slice_len); + } + if slice_len < molecule::NUMBER_SIZE * 2 { + return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); + } + let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; + if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { + return ve!(Self, OffsetsNotMatch); + } + if slice_len < offset_first { + return ve!(Self, HeaderIsBroken, offset_first, slice_len); + } + let field_count = offset_first / molecule::NUMBER_SIZE - 1; + if field_count < Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + } else if !compatible && field_count > Self::FIELD_COUNT { + return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); + }; + let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] + .chunks_exact(molecule::NUMBER_SIZE) + .map(|x| molecule::unpack_number(x) as usize) + .collect(); + offsets.push(total_size); + if offsets.windows(2).any(|i| i[0] > i[1]) { + return ve!(Self, OffsetsNotMatch); + } + Uint16Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; + TlcErrDataOptReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; + Ok(()) + } +} +#[derive(Clone, Debug, Default)] +pub struct TlcErrBuilder { + pub(crate) error_code: Uint16, + pub(crate) extra_data: TlcErrDataOpt, +} +impl TlcErrBuilder { + pub const FIELD_COUNT: usize = 2; + pub fn error_code(mut self, v: Uint16) -> Self { + self.error_code = v; + self + } + pub fn extra_data(mut self, v: TlcErrDataOpt) -> Self { + self.extra_data = v; + self + } +} +impl molecule::prelude::Builder for TlcErrBuilder { + type Entity = TlcErr; + const NAME: &'static str = "TlcErrBuilder"; + fn expected_length(&self) -> usize { + molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + + self.error_code.as_slice().len() + + self.extra_data.as_slice().len() + } + fn write(&self, writer: &mut W) -> molecule::io::Result<()> { + let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); + let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); + offsets.push(total_size); + total_size += self.error_code.as_slice().len(); + offsets.push(total_size); + total_size += self.extra_data.as_slice().len(); + writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; + for offset in offsets.into_iter() { + writer.write_all(&molecule::pack_number(offset as molecule::Number))?; + } + writer.write_all(self.error_code.as_slice())?; + writer.write_all(self.extra_data.as_slice())?; + Ok(()) + } + fn build(&self) -> Self::Entity { + let mut inner = Vec::with_capacity(self.expected_length()); + self.write(&mut inner) + .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); + TlcErr::new_unchecked(inner.into()) + } +} diff --git a/src/fiber/gen/gossip.rs b/src/fiber/gen/gossip.rs index b4d849c66..110edf87d 100644 --- a/src/fiber/gen/gossip.rs +++ b/src/fiber/gen/gossip.rs @@ -4,231 +4,6 @@ use super::blockchain::*; use super::fiber::*; use molecule::prelude::*; #[derive(Clone)] -pub struct Uint16(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for Uint16 { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for Uint16 { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for Uint16 { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - let raw_data = hex_string(&self.raw_data()); - write!(f, "{}(0x{})", Self::NAME, raw_data) - } -} -impl ::core::default::Default for Uint16 { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - Uint16::new_unchecked(v) - } -} -impl Uint16 { - const DEFAULT_VALUE: [u8; 2] = [0, 0]; - pub const TOTAL_SIZE: usize = 2; - pub const ITEM_SIZE: usize = 1; - pub const ITEM_COUNT: usize = 2; - pub fn nth0(&self) -> Byte { - Byte::new_unchecked(self.0.slice(0..1)) - } - pub fn nth1(&self) -> Byte { - Byte::new_unchecked(self.0.slice(1..2)) - } - pub fn raw_data(&self) -> molecule::bytes::Bytes { - self.as_bytes() - } - pub fn as_reader<'r>(&'r self) -> Uint16Reader<'r> { - Uint16Reader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for Uint16 { - type Builder = Uint16Builder; - const NAME: &'static str = "Uint16"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - Uint16(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - Uint16Reader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - Uint16Reader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder().set([self.nth0(), self.nth1()]) - } -} -#[derive(Clone, Copy)] -pub struct Uint16Reader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for Uint16Reader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for Uint16Reader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for Uint16Reader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - let raw_data = hex_string(&self.raw_data()); - write!(f, "{}(0x{})", Self::NAME, raw_data) - } -} -impl<'r> Uint16Reader<'r> { - pub const TOTAL_SIZE: usize = 2; - pub const ITEM_SIZE: usize = 1; - pub const ITEM_COUNT: usize = 2; - pub fn nth0(&self) -> ByteReader<'r> { - ByteReader::new_unchecked(&self.as_slice()[0..1]) - } - pub fn nth1(&self) -> ByteReader<'r> { - ByteReader::new_unchecked(&self.as_slice()[1..2]) - } - pub fn raw_data(&self) -> &'r [u8] { - self.as_slice() - } -} -impl<'r> molecule::prelude::Reader<'r> for Uint16Reader<'r> { - type Entity = Uint16; - const NAME: &'static str = "Uint16Reader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - Uint16Reader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { - use molecule::verification_error as ve; - let slice_len = slice.len(); - if slice_len != Self::TOTAL_SIZE { - return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); - } - Ok(()) - } -} -#[derive(Clone)] -pub struct Uint16Builder(pub(crate) [Byte; 2]); -impl ::core::fmt::Debug for Uint16Builder { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:?})", Self::NAME, &self.0[..]) - } -} -impl ::core::default::Default for Uint16Builder { - fn default() -> Self { - Uint16Builder([Byte::default(), Byte::default()]) - } -} -impl Uint16Builder { - pub const TOTAL_SIZE: usize = 2; - pub const ITEM_SIZE: usize = 1; - pub const ITEM_COUNT: usize = 2; - pub fn set(mut self, v: [Byte; 2]) -> Self { - self.0 = v; - self - } - pub fn nth0(mut self, v: Byte) -> Self { - self.0[0] = v; - self - } - pub fn nth1(mut self, v: Byte) -> Self { - self.0[1] = v; - self - } -} -impl molecule::prelude::Builder for Uint16Builder { - type Entity = Uint16; - const NAME: &'static str = "Uint16Builder"; - fn expected_length(&self) -> usize { - Self::TOTAL_SIZE - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - writer.write_all(self.0[0].as_slice())?; - writer.write_all(self.0[1].as_slice())?; - Ok(()) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - Uint16::new_unchecked(inner.into()) - } -} -impl From<[Byte; 2usize]> for Uint16 { - fn from(value: [Byte; 2usize]) -> Self { - Self::new_builder().set(value).build() - } -} -impl ::core::convert::TryFrom<&[Byte]> for Uint16 { - type Error = ::core::array::TryFromSliceError; - fn try_from(value: &[Byte]) -> Result { - Ok(Self::new_builder() - .set(<&[Byte; 2usize]>::try_from(value)?.clone()) - .build()) - } -} -impl From for [Byte; 2usize] { - #[track_caller] - fn from(value: Uint16) -> Self { - [value.nth0(), value.nth1()] - } -} -impl From<[u8; 2usize]> for Uint16 { - fn from(value: [u8; 2usize]) -> Self { - Uint16Reader::new_unchecked(&value).to_entity() - } -} -impl ::core::convert::TryFrom<&[u8]> for Uint16 { - type Error = ::core::array::TryFromSliceError; - fn try_from(value: &[u8]) -> Result { - Ok(<[u8; 2usize]>::try_from(value)?.into()) - } -} -impl From for [u8; 2usize] { - #[track_caller] - fn from(value: Uint16) -> Self { - ::core::convert::TryFrom::try_from(value.as_slice()).unwrap() - } -} -impl<'a> From> for &'a [u8; 2usize] { - #[track_caller] - fn from(value: Uint16Reader<'a>) -> Self { - ::core::convert::TryFrom::try_from(value.as_slice()).unwrap() - } -} -impl<'a> From<&'a Uint16Reader<'a>> for &'a [u8; 2usize] { - #[track_caller] - fn from(value: &'a Uint16Reader<'a>) -> Self { - ::core::convert::TryFrom::try_from(value.as_slice()).unwrap() - } -} -#[derive(Clone)] pub struct SchnorrSignature(molecule::bytes::Bytes); impl ::core::fmt::LowerHex for SchnorrSignature { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { @@ -4241,8 +4016,8 @@ impl molecule::prelude::Builder for ChannelAnnouncementBuilder { } } #[derive(Clone)] -pub struct ChannelUpdate(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for ChannelUpdate { +pub struct BroadcastMessage(molecule::bytes::Bytes); +impl ::core::fmt::LowerHex for BroadcastMessage { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { use molecule::hex_string; if f.alternate() { @@ -4251,90 +4026,58 @@ impl ::core::fmt::LowerHex for ChannelUpdate { write!(f, "{}", hex_string(self.as_slice())) } } -impl ::core::fmt::Debug for ChannelUpdate { +impl ::core::fmt::Debug for BroadcastMessage { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "{}({:#x})", Self::NAME, self) } } -impl ::core::fmt::Display for ChannelUpdate { +impl ::core::fmt::Display for BroadcastMessage { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "signature", self.signature())?; - write!(f, ", {}: {}", "chain_hash", self.chain_hash())?; - write!(f, ", {}: {}", "channel_outpoint", self.channel_outpoint())?; - write!(f, ", {}: {}", "timestamp", self.timestamp())?; - write!(f, ", {}: {}", "message_flags", self.message_flags())?; - write!(f, ", {}: {}", "channel_flags", self.channel_flags())?; - write!(f, ", {}: {}", "tlc_expiry_delta", self.tlc_expiry_delta())?; - write!(f, ", {}: {}", "tlc_minimum_value", self.tlc_minimum_value())?; - write!(f, ", {}: {}", "tlc_maximum_value", self.tlc_maximum_value())?; - write!( - f, - ", {}: {}", - "tlc_fee_proportional_millionths", - self.tlc_fee_proportional_millionths() - )?; - write!(f, " }}") + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") } } -impl ::core::default::Default for ChannelUpdate { +impl ::core::default::Default for BroadcastMessage { fn default() -> Self { let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - ChannelUpdate::new_unchecked(v) + BroadcastMessage::new_unchecked(v) } } -impl ChannelUpdate { - const DEFAULT_VALUE: [u8; 204] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +impl BroadcastMessage { + const DEFAULT_VALUE: [u8; 237] = [ + 0, 0, 0, 0, 233, 0, 0, 0, 40, 0, 0, 0, 104, 0, 0, 0, 112, 0, 0, 0, 120, 0, 0, 0, 153, 0, 0, + 0, 185, 0, 0, 0, 189, 0, 0, 0, 221, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, ]; - pub const TOTAL_SIZE: usize = 204; - pub const FIELD_SIZES: [usize; 10] = [64, 32, 36, 8, 4, 4, 8, 16, 16, 16]; - pub const FIELD_COUNT: usize = 10; - pub fn signature(&self) -> EcdsaSignature { - EcdsaSignature::new_unchecked(self.0.slice(0..64)) - } - pub fn chain_hash(&self) -> Byte32 { - Byte32::new_unchecked(self.0.slice(64..96)) - } - pub fn channel_outpoint(&self) -> OutPoint { - OutPoint::new_unchecked(self.0.slice(96..132)) - } - pub fn timestamp(&self) -> Uint64 { - Uint64::new_unchecked(self.0.slice(132..140)) - } - pub fn message_flags(&self) -> Uint32 { - Uint32::new_unchecked(self.0.slice(140..144)) - } - pub fn channel_flags(&self) -> Uint32 { - Uint32::new_unchecked(self.0.slice(144..148)) - } - pub fn tlc_expiry_delta(&self) -> Uint64 { - Uint64::new_unchecked(self.0.slice(148..156)) - } - pub fn tlc_minimum_value(&self) -> Uint128 { - Uint128::new_unchecked(self.0.slice(156..172)) - } - pub fn tlc_maximum_value(&self) -> Uint128 { - Uint128::new_unchecked(self.0.slice(172..188)) + pub const ITEMS_COUNT: usize = 3; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) } - pub fn tlc_fee_proportional_millionths(&self) -> Uint128 { - Uint128::new_unchecked(self.0.slice(188..204)) + pub fn to_enum(&self) -> BroadcastMessageUnion { + let inner = self.0.slice(molecule::NUMBER_SIZE..); + match self.item_id() { + 0 => NodeAnnouncement::new_unchecked(inner).into(), + 1 => ChannelAnnouncement::new_unchecked(inner).into(), + 2 => ChannelUpdate::new_unchecked(inner).into(), + _ => panic!("{}: invalid data", Self::NAME), + } } - pub fn as_reader<'r>(&'r self) -> ChannelUpdateReader<'r> { - ChannelUpdateReader::new_unchecked(self.as_slice()) + pub fn as_reader<'r>(&'r self) -> BroadcastMessageReader<'r> { + BroadcastMessageReader::new_unchecked(self.as_slice()) } } -impl molecule::prelude::Entity for ChannelUpdate { - type Builder = ChannelUpdateBuilder; - const NAME: &'static str = "ChannelUpdate"; +impl molecule::prelude::Entity for BroadcastMessage { + type Builder = BroadcastMessageBuilder; + const NAME: &'static str = "BroadcastMessage"; fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - ChannelUpdate(data) + BroadcastMessage(data) } fn as_bytes(&self) -> molecule::bytes::Bytes { self.0.clone() @@ -4343,31 +4086,21 @@ impl molecule::prelude::Entity for ChannelUpdate { &self.0[..] } fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - ChannelUpdateReader::from_slice(slice).map(|reader| reader.to_entity()) + BroadcastMessageReader::from_slice(slice).map(|reader| reader.to_entity()) } fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - ChannelUpdateReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) + BroadcastMessageReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) } fn new_builder() -> Self::Builder { ::core::default::Default::default() } fn as_builder(self) -> Self::Builder { - Self::new_builder() - .signature(self.signature()) - .chain_hash(self.chain_hash()) - .channel_outpoint(self.channel_outpoint()) - .timestamp(self.timestamp()) - .message_flags(self.message_flags()) - .channel_flags(self.channel_flags()) - .tlc_expiry_delta(self.tlc_expiry_delta()) - .tlc_minimum_value(self.tlc_minimum_value()) - .tlc_maximum_value(self.tlc_maximum_value()) - .tlc_fee_proportional_millionths(self.tlc_fee_proportional_millionths()) + Self::new_builder().set(self.to_enum()) } } #[derive(Clone, Copy)] -pub struct ChannelUpdateReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for ChannelUpdateReader<'r> { +pub struct BroadcastMessageReader<'r>(&'r [u8]); +impl<'r> ::core::fmt::LowerHex for BroadcastMessageReader<'r> { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { use molecule::hex_string; if f.alternate() { @@ -4376,282 +4109,22 @@ impl<'r> ::core::fmt::LowerHex for ChannelUpdateReader<'r> { write!(f, "{}", hex_string(self.as_slice())) } } -impl<'r> ::core::fmt::Debug for ChannelUpdateReader<'r> { +impl<'r> ::core::fmt::Debug for BroadcastMessageReader<'r> { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "{}({:#x})", Self::NAME, self) } } -impl<'r> ::core::fmt::Display for ChannelUpdateReader<'r> { +impl<'r> ::core::fmt::Display for BroadcastMessageReader<'r> { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "signature", self.signature())?; - write!(f, ", {}: {}", "chain_hash", self.chain_hash())?; - write!(f, ", {}: {}", "channel_outpoint", self.channel_outpoint())?; - write!(f, ", {}: {}", "timestamp", self.timestamp())?; - write!(f, ", {}: {}", "message_flags", self.message_flags())?; - write!(f, ", {}: {}", "channel_flags", self.channel_flags())?; - write!(f, ", {}: {}", "tlc_expiry_delta", self.tlc_expiry_delta())?; - write!(f, ", {}: {}", "tlc_minimum_value", self.tlc_minimum_value())?; - write!(f, ", {}: {}", "tlc_maximum_value", self.tlc_maximum_value())?; - write!( - f, - ", {}: {}", - "tlc_fee_proportional_millionths", - self.tlc_fee_proportional_millionths() - )?; - write!(f, " }}") + write!(f, "{}(", Self::NAME)?; + self.to_enum().display_inner(f)?; + write!(f, ")") } } -impl<'r> ChannelUpdateReader<'r> { - pub const TOTAL_SIZE: usize = 204; - pub const FIELD_SIZES: [usize; 10] = [64, 32, 36, 8, 4, 4, 8, 16, 16, 16]; - pub const FIELD_COUNT: usize = 10; - pub fn signature(&self) -> EcdsaSignatureReader<'r> { - EcdsaSignatureReader::new_unchecked(&self.as_slice()[0..64]) - } - pub fn chain_hash(&self) -> Byte32Reader<'r> { - Byte32Reader::new_unchecked(&self.as_slice()[64..96]) - } - pub fn channel_outpoint(&self) -> OutPointReader<'r> { - OutPointReader::new_unchecked(&self.as_slice()[96..132]) - } - pub fn timestamp(&self) -> Uint64Reader<'r> { - Uint64Reader::new_unchecked(&self.as_slice()[132..140]) - } - pub fn message_flags(&self) -> Uint32Reader<'r> { - Uint32Reader::new_unchecked(&self.as_slice()[140..144]) - } - pub fn channel_flags(&self) -> Uint32Reader<'r> { - Uint32Reader::new_unchecked(&self.as_slice()[144..148]) - } - pub fn tlc_expiry_delta(&self) -> Uint64Reader<'r> { - Uint64Reader::new_unchecked(&self.as_slice()[148..156]) - } - pub fn tlc_minimum_value(&self) -> Uint128Reader<'r> { - Uint128Reader::new_unchecked(&self.as_slice()[156..172]) - } - pub fn tlc_maximum_value(&self) -> Uint128Reader<'r> { - Uint128Reader::new_unchecked(&self.as_slice()[172..188]) - } - pub fn tlc_fee_proportional_millionths(&self) -> Uint128Reader<'r> { - Uint128Reader::new_unchecked(&self.as_slice()[188..204]) - } -} -impl<'r> molecule::prelude::Reader<'r> for ChannelUpdateReader<'r> { - type Entity = ChannelUpdate; - const NAME: &'static str = "ChannelUpdateReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - ChannelUpdateReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> { - use molecule::verification_error as ve; - let slice_len = slice.len(); - if slice_len != Self::TOTAL_SIZE { - return ve!(Self, TotalSizeNotMatch, Self::TOTAL_SIZE, slice_len); - } - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct ChannelUpdateBuilder { - pub(crate) signature: EcdsaSignature, - pub(crate) chain_hash: Byte32, - pub(crate) channel_outpoint: OutPoint, - pub(crate) timestamp: Uint64, - pub(crate) message_flags: Uint32, - pub(crate) channel_flags: Uint32, - pub(crate) tlc_expiry_delta: Uint64, - pub(crate) tlc_minimum_value: Uint128, - pub(crate) tlc_maximum_value: Uint128, - pub(crate) tlc_fee_proportional_millionths: Uint128, -} -impl ChannelUpdateBuilder { - pub const TOTAL_SIZE: usize = 204; - pub const FIELD_SIZES: [usize; 10] = [64, 32, 36, 8, 4, 4, 8, 16, 16, 16]; - pub const FIELD_COUNT: usize = 10; - pub fn signature(mut self, v: EcdsaSignature) -> Self { - self.signature = v; - self - } - pub fn chain_hash(mut self, v: Byte32) -> Self { - self.chain_hash = v; - self - } - pub fn channel_outpoint(mut self, v: OutPoint) -> Self { - self.channel_outpoint = v; - self - } - pub fn timestamp(mut self, v: Uint64) -> Self { - self.timestamp = v; - self - } - pub fn message_flags(mut self, v: Uint32) -> Self { - self.message_flags = v; - self - } - pub fn channel_flags(mut self, v: Uint32) -> Self { - self.channel_flags = v; - self - } - pub fn tlc_expiry_delta(mut self, v: Uint64) -> Self { - self.tlc_expiry_delta = v; - self - } - pub fn tlc_minimum_value(mut self, v: Uint128) -> Self { - self.tlc_minimum_value = v; - self - } - pub fn tlc_maximum_value(mut self, v: Uint128) -> Self { - self.tlc_maximum_value = v; - self - } - pub fn tlc_fee_proportional_millionths(mut self, v: Uint128) -> Self { - self.tlc_fee_proportional_millionths = v; - self - } -} -impl molecule::prelude::Builder for ChannelUpdateBuilder { - type Entity = ChannelUpdate; - const NAME: &'static str = "ChannelUpdateBuilder"; - fn expected_length(&self) -> usize { - Self::TOTAL_SIZE - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - writer.write_all(self.signature.as_slice())?; - writer.write_all(self.chain_hash.as_slice())?; - writer.write_all(self.channel_outpoint.as_slice())?; - writer.write_all(self.timestamp.as_slice())?; - writer.write_all(self.message_flags.as_slice())?; - writer.write_all(self.channel_flags.as_slice())?; - writer.write_all(self.tlc_expiry_delta.as_slice())?; - writer.write_all(self.tlc_minimum_value.as_slice())?; - writer.write_all(self.tlc_maximum_value.as_slice())?; - writer.write_all(self.tlc_fee_proportional_millionths.as_slice())?; - Ok(()) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - ChannelUpdate::new_unchecked(inner.into()) - } -} -#[derive(Clone)] -pub struct BroadcastMessage(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for BroadcastMessage { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for BroadcastMessage { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for BroadcastMessage { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}(", Self::NAME)?; - self.to_enum().display_inner(f)?; - write!(f, ")") - } -} -impl ::core::default::Default for BroadcastMessage { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - BroadcastMessage::new_unchecked(v) - } -} -impl BroadcastMessage { - const DEFAULT_VALUE: [u8; 237] = [ - 0, 0, 0, 0, 233, 0, 0, 0, 40, 0, 0, 0, 104, 0, 0, 0, 112, 0, 0, 0, 120, 0, 0, 0, 153, 0, 0, - 0, 185, 0, 0, 0, 189, 0, 0, 0, 221, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, - 0, 0, - ]; - pub const ITEMS_COUNT: usize = 3; - pub fn item_id(&self) -> molecule::Number { - molecule::unpack_number(self.as_slice()) - } - pub fn to_enum(&self) -> BroadcastMessageUnion { - let inner = self.0.slice(molecule::NUMBER_SIZE..); - match self.item_id() { - 0 => NodeAnnouncement::new_unchecked(inner).into(), - 1 => ChannelAnnouncement::new_unchecked(inner).into(), - 2 => ChannelUpdate::new_unchecked(inner).into(), - _ => panic!("{}: invalid data", Self::NAME), - } - } - pub fn as_reader<'r>(&'r self) -> BroadcastMessageReader<'r> { - BroadcastMessageReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for BroadcastMessage { - type Builder = BroadcastMessageBuilder; - const NAME: &'static str = "BroadcastMessage"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - BroadcastMessage(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - BroadcastMessageReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - BroadcastMessageReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder().set(self.to_enum()) - } -} -#[derive(Clone, Copy)] -pub struct BroadcastMessageReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for BroadcastMessageReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for BroadcastMessageReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for BroadcastMessageReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}(", Self::NAME)?; - self.to_enum().display_inner(f)?; - write!(f, ")") - } -} -impl<'r> BroadcastMessageReader<'r> { - pub const ITEMS_COUNT: usize = 3; - pub fn item_id(&self) -> molecule::Number { - molecule::unpack_number(self.as_slice()) +impl<'r> BroadcastMessageReader<'r> { + pub const ITEMS_COUNT: usize = 3; + pub fn item_id(&self) -> molecule::Number { + molecule::unpack_number(self.as_slice()) } pub fn to_enum(&self) -> BroadcastMessageUnionReader<'r> { let inner = &self.as_slice()[molecule::NUMBER_SIZE..]; @@ -7500,1438 +6973,3 @@ impl From for GossipMessage { Self::new_builder().set(value).build() } } -#[derive(Clone)] -pub struct ChannelUpdateOpt(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for ChannelUpdateOpt { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for ChannelUpdateOpt { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for ChannelUpdateOpt { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - if let Some(v) = self.to_opt() { - write!(f, "{}(Some({}))", Self::NAME, v) - } else { - write!(f, "{}(None)", Self::NAME) - } - } -} -impl ::core::default::Default for ChannelUpdateOpt { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - ChannelUpdateOpt::new_unchecked(v) - } -} -impl ChannelUpdateOpt { - const DEFAULT_VALUE: [u8; 0] = []; - pub fn is_none(&self) -> bool { - self.0.is_empty() - } - pub fn is_some(&self) -> bool { - !self.0.is_empty() - } - pub fn to_opt(&self) -> Option { - if self.is_none() { - None - } else { - Some(ChannelUpdate::new_unchecked(self.0.clone())) - } - } - pub fn as_reader<'r>(&'r self) -> ChannelUpdateOptReader<'r> { - ChannelUpdateOptReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for ChannelUpdateOpt { - type Builder = ChannelUpdateOptBuilder; - const NAME: &'static str = "ChannelUpdateOpt"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - ChannelUpdateOpt(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - ChannelUpdateOptReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - ChannelUpdateOptReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder().set(self.to_opt()) - } -} -#[derive(Clone, Copy)] -pub struct ChannelUpdateOptReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for ChannelUpdateOptReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for ChannelUpdateOptReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for ChannelUpdateOptReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - if let Some(v) = self.to_opt() { - write!(f, "{}(Some({}))", Self::NAME, v) - } else { - write!(f, "{}(None)", Self::NAME) - } - } -} -impl<'r> ChannelUpdateOptReader<'r> { - pub fn is_none(&self) -> bool { - self.0.is_empty() - } - pub fn is_some(&self) -> bool { - !self.0.is_empty() - } - pub fn to_opt(&self) -> Option> { - if self.is_none() { - None - } else { - Some(ChannelUpdateReader::new_unchecked(self.as_slice())) - } - } -} -impl<'r> molecule::prelude::Reader<'r> for ChannelUpdateOptReader<'r> { - type Entity = ChannelUpdateOpt; - const NAME: &'static str = "ChannelUpdateOptReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - ChannelUpdateOptReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { - if !slice.is_empty() { - ChannelUpdateReader::verify(&slice[..], compatible)?; - } - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct ChannelUpdateOptBuilder(pub(crate) Option); -impl ChannelUpdateOptBuilder { - pub fn set(mut self, v: Option) -> Self { - self.0 = v; - self - } -} -impl molecule::prelude::Builder for ChannelUpdateOptBuilder { - type Entity = ChannelUpdateOpt; - const NAME: &'static str = "ChannelUpdateOptBuilder"; - fn expected_length(&self) -> usize { - self.0 - .as_ref() - .map(|ref inner| inner.as_slice().len()) - .unwrap_or(0) - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - self.0 - .as_ref() - .map(|ref inner| writer.write_all(inner.as_slice())) - .unwrap_or(Ok(())) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - ChannelUpdateOpt::new_unchecked(inner.into()) - } -} -impl From for ChannelUpdateOpt { - fn from(value: ChannelUpdate) -> Self { - Self::new_builder().set(Some(value)).build() - } -} -#[derive(Clone)] -pub struct ChannelFailed(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for ChannelFailed { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for ChannelFailed { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for ChannelFailed { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "channel_outpoint", self.channel_outpoint())?; - write!(f, ", {}: {}", "channel_update", self.channel_update())?; - write!(f, ", {}: {}", "node_id", self.node_id())?; - let extra_count = self.count_extra_fields(); - if extra_count != 0 { - write!(f, ", .. ({} fields)", extra_count)?; - } - write!(f, " }}") - } -} -impl ::core::default::Default for ChannelFailed { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - ChannelFailed::new_unchecked(v) - } -} -impl ChannelFailed { - const DEFAULT_VALUE: [u8; 85] = [ - 85, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - pub const FIELD_COUNT: usize = 3; - pub fn total_size(&self) -> usize { - molecule::unpack_number(self.as_slice()) as usize - } - pub fn field_count(&self) -> usize { - if self.total_size() == molecule::NUMBER_SIZE { - 0 - } else { - (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 - } - } - pub fn count_extra_fields(&self) -> usize { - self.field_count() - Self::FIELD_COUNT - } - pub fn has_extra_fields(&self) -> bool { - Self::FIELD_COUNT != self.field_count() - } - pub fn channel_outpoint(&self) -> OutPoint { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[4..]) as usize; - let end = molecule::unpack_number(&slice[8..]) as usize; - OutPoint::new_unchecked(self.0.slice(start..end)) - } - pub fn channel_update(&self) -> ChannelUpdateOpt { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[8..]) as usize; - let end = molecule::unpack_number(&slice[12..]) as usize; - ChannelUpdateOpt::new_unchecked(self.0.slice(start..end)) - } - pub fn node_id(&self) -> Pubkey { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[12..]) as usize; - if self.has_extra_fields() { - let end = molecule::unpack_number(&slice[16..]) as usize; - Pubkey::new_unchecked(self.0.slice(start..end)) - } else { - Pubkey::new_unchecked(self.0.slice(start..)) - } - } - pub fn as_reader<'r>(&'r self) -> ChannelFailedReader<'r> { - ChannelFailedReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for ChannelFailed { - type Builder = ChannelFailedBuilder; - const NAME: &'static str = "ChannelFailed"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - ChannelFailed(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - ChannelFailedReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - ChannelFailedReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder() - .channel_outpoint(self.channel_outpoint()) - .channel_update(self.channel_update()) - .node_id(self.node_id()) - } -} -#[derive(Clone, Copy)] -pub struct ChannelFailedReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for ChannelFailedReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for ChannelFailedReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for ChannelFailedReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "channel_outpoint", self.channel_outpoint())?; - write!(f, ", {}: {}", "channel_update", self.channel_update())?; - write!(f, ", {}: {}", "node_id", self.node_id())?; - let extra_count = self.count_extra_fields(); - if extra_count != 0 { - write!(f, ", .. ({} fields)", extra_count)?; - } - write!(f, " }}") - } -} -impl<'r> ChannelFailedReader<'r> { - pub const FIELD_COUNT: usize = 3; - pub fn total_size(&self) -> usize { - molecule::unpack_number(self.as_slice()) as usize - } - pub fn field_count(&self) -> usize { - if self.total_size() == molecule::NUMBER_SIZE { - 0 - } else { - (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 - } - } - pub fn count_extra_fields(&self) -> usize { - self.field_count() - Self::FIELD_COUNT - } - pub fn has_extra_fields(&self) -> bool { - Self::FIELD_COUNT != self.field_count() - } - pub fn channel_outpoint(&self) -> OutPointReader<'r> { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[4..]) as usize; - let end = molecule::unpack_number(&slice[8..]) as usize; - OutPointReader::new_unchecked(&self.as_slice()[start..end]) - } - pub fn channel_update(&self) -> ChannelUpdateOptReader<'r> { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[8..]) as usize; - let end = molecule::unpack_number(&slice[12..]) as usize; - ChannelUpdateOptReader::new_unchecked(&self.as_slice()[start..end]) - } - pub fn node_id(&self) -> PubkeyReader<'r> { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[12..]) as usize; - if self.has_extra_fields() { - let end = molecule::unpack_number(&slice[16..]) as usize; - PubkeyReader::new_unchecked(&self.as_slice()[start..end]) - } else { - PubkeyReader::new_unchecked(&self.as_slice()[start..]) - } - } -} -impl<'r> molecule::prelude::Reader<'r> for ChannelFailedReader<'r> { - type Entity = ChannelFailed; - const NAME: &'static str = "ChannelFailedReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - ChannelFailedReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { - use molecule::verification_error as ve; - let slice_len = slice.len(); - if slice_len < molecule::NUMBER_SIZE { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); - } - let total_size = molecule::unpack_number(slice) as usize; - if slice_len != total_size { - return ve!(Self, TotalSizeNotMatch, total_size, slice_len); - } - if slice_len < molecule::NUMBER_SIZE * 2 { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); - } - let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; - if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { - return ve!(Self, OffsetsNotMatch); - } - if slice_len < offset_first { - return ve!(Self, HeaderIsBroken, offset_first, slice_len); - } - let field_count = offset_first / molecule::NUMBER_SIZE - 1; - if field_count < Self::FIELD_COUNT { - return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); - } else if !compatible && field_count > Self::FIELD_COUNT { - return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); - }; - let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] - .chunks_exact(molecule::NUMBER_SIZE) - .map(|x| molecule::unpack_number(x) as usize) - .collect(); - offsets.push(total_size); - if offsets.windows(2).any(|i| i[0] > i[1]) { - return ve!(Self, OffsetsNotMatch); - } - OutPointReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; - ChannelUpdateOptReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; - PubkeyReader::verify(&slice[offsets[2]..offsets[3]], compatible)?; - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct ChannelFailedBuilder { - pub(crate) channel_outpoint: OutPoint, - pub(crate) channel_update: ChannelUpdateOpt, - pub(crate) node_id: Pubkey, -} -impl ChannelFailedBuilder { - pub const FIELD_COUNT: usize = 3; - pub fn channel_outpoint(mut self, v: OutPoint) -> Self { - self.channel_outpoint = v; - self - } - pub fn channel_update(mut self, v: ChannelUpdateOpt) -> Self { - self.channel_update = v; - self - } - pub fn node_id(mut self, v: Pubkey) -> Self { - self.node_id = v; - self - } -} -impl molecule::prelude::Builder for ChannelFailedBuilder { - type Entity = ChannelFailed; - const NAME: &'static str = "ChannelFailedBuilder"; - fn expected_length(&self) -> usize { - molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) - + self.channel_outpoint.as_slice().len() - + self.channel_update.as_slice().len() - + self.node_id.as_slice().len() - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); - let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); - offsets.push(total_size); - total_size += self.channel_outpoint.as_slice().len(); - offsets.push(total_size); - total_size += self.channel_update.as_slice().len(); - offsets.push(total_size); - total_size += self.node_id.as_slice().len(); - writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; - for offset in offsets.into_iter() { - writer.write_all(&molecule::pack_number(offset as molecule::Number))?; - } - writer.write_all(self.channel_outpoint.as_slice())?; - writer.write_all(self.channel_update.as_slice())?; - writer.write_all(self.node_id.as_slice())?; - Ok(()) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - ChannelFailed::new_unchecked(inner.into()) - } -} -#[derive(Clone)] -pub struct NodeFailed(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for NodeFailed { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for NodeFailed { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for NodeFailed { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "node_id", self.node_id())?; - let extra_count = self.count_extra_fields(); - if extra_count != 0 { - write!(f, ", .. ({} fields)", extra_count)?; - } - write!(f, " }}") - } -} -impl ::core::default::Default for NodeFailed { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - NodeFailed::new_unchecked(v) - } -} -impl NodeFailed { - const DEFAULT_VALUE: [u8; 41] = [ - 41, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - pub const FIELD_COUNT: usize = 1; - pub fn total_size(&self) -> usize { - molecule::unpack_number(self.as_slice()) as usize - } - pub fn field_count(&self) -> usize { - if self.total_size() == molecule::NUMBER_SIZE { - 0 - } else { - (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 - } - } - pub fn count_extra_fields(&self) -> usize { - self.field_count() - Self::FIELD_COUNT - } - pub fn has_extra_fields(&self) -> bool { - Self::FIELD_COUNT != self.field_count() - } - pub fn node_id(&self) -> Pubkey { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[4..]) as usize; - if self.has_extra_fields() { - let end = molecule::unpack_number(&slice[8..]) as usize; - Pubkey::new_unchecked(self.0.slice(start..end)) - } else { - Pubkey::new_unchecked(self.0.slice(start..)) - } - } - pub fn as_reader<'r>(&'r self) -> NodeFailedReader<'r> { - NodeFailedReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for NodeFailed { - type Builder = NodeFailedBuilder; - const NAME: &'static str = "NodeFailed"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - NodeFailed(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - NodeFailedReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - NodeFailedReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder().node_id(self.node_id()) - } -} -#[derive(Clone, Copy)] -pub struct NodeFailedReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for NodeFailedReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for NodeFailedReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for NodeFailedReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "node_id", self.node_id())?; - let extra_count = self.count_extra_fields(); - if extra_count != 0 { - write!(f, ", .. ({} fields)", extra_count)?; - } - write!(f, " }}") - } -} -impl<'r> NodeFailedReader<'r> { - pub const FIELD_COUNT: usize = 1; - pub fn total_size(&self) -> usize { - molecule::unpack_number(self.as_slice()) as usize - } - pub fn field_count(&self) -> usize { - if self.total_size() == molecule::NUMBER_SIZE { - 0 - } else { - (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 - } - } - pub fn count_extra_fields(&self) -> usize { - self.field_count() - Self::FIELD_COUNT - } - pub fn has_extra_fields(&self) -> bool { - Self::FIELD_COUNT != self.field_count() - } - pub fn node_id(&self) -> PubkeyReader<'r> { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[4..]) as usize; - if self.has_extra_fields() { - let end = molecule::unpack_number(&slice[8..]) as usize; - PubkeyReader::new_unchecked(&self.as_slice()[start..end]) - } else { - PubkeyReader::new_unchecked(&self.as_slice()[start..]) - } - } -} -impl<'r> molecule::prelude::Reader<'r> for NodeFailedReader<'r> { - type Entity = NodeFailed; - const NAME: &'static str = "NodeFailedReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - NodeFailedReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { - use molecule::verification_error as ve; - let slice_len = slice.len(); - if slice_len < molecule::NUMBER_SIZE { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); - } - let total_size = molecule::unpack_number(slice) as usize; - if slice_len != total_size { - return ve!(Self, TotalSizeNotMatch, total_size, slice_len); - } - if slice_len < molecule::NUMBER_SIZE * 2 { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); - } - let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; - if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { - return ve!(Self, OffsetsNotMatch); - } - if slice_len < offset_first { - return ve!(Self, HeaderIsBroken, offset_first, slice_len); - } - let field_count = offset_first / molecule::NUMBER_SIZE - 1; - if field_count < Self::FIELD_COUNT { - return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); - } else if !compatible && field_count > Self::FIELD_COUNT { - return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); - }; - let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] - .chunks_exact(molecule::NUMBER_SIZE) - .map(|x| molecule::unpack_number(x) as usize) - .collect(); - offsets.push(total_size); - if offsets.windows(2).any(|i| i[0] > i[1]) { - return ve!(Self, OffsetsNotMatch); - } - PubkeyReader::verify(&slice[offsets[0]..offsets[1]], compatible)?; - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct NodeFailedBuilder { - pub(crate) node_id: Pubkey, -} -impl NodeFailedBuilder { - pub const FIELD_COUNT: usize = 1; - pub fn node_id(mut self, v: Pubkey) -> Self { - self.node_id = v; - self - } -} -impl molecule::prelude::Builder for NodeFailedBuilder { - type Entity = NodeFailed; - const NAME: &'static str = "NodeFailedBuilder"; - fn expected_length(&self) -> usize { - molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) + self.node_id.as_slice().len() - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); - let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); - offsets.push(total_size); - total_size += self.node_id.as_slice().len(); - writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; - for offset in offsets.into_iter() { - writer.write_all(&molecule::pack_number(offset as molecule::Number))?; - } - writer.write_all(self.node_id.as_slice())?; - Ok(()) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - NodeFailed::new_unchecked(inner.into()) - } -} -#[derive(Clone)] -pub struct TlcErrData(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for TlcErrData { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for TlcErrData { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for TlcErrData { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}(", Self::NAME)?; - self.to_enum().display_inner(f)?; - write!(f, ")") - } -} -impl ::core::default::Default for TlcErrData { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - TlcErrData::new_unchecked(v) - } -} -impl TlcErrData { - const DEFAULT_VALUE: [u8; 89] = [ - 0, 0, 0, 0, 85, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - pub const ITEMS_COUNT: usize = 2; - pub fn item_id(&self) -> molecule::Number { - molecule::unpack_number(self.as_slice()) - } - pub fn to_enum(&self) -> TlcErrDataUnion { - let inner = self.0.slice(molecule::NUMBER_SIZE..); - match self.item_id() { - 0 => ChannelFailed::new_unchecked(inner).into(), - 1 => NodeFailed::new_unchecked(inner).into(), - _ => panic!("{}: invalid data", Self::NAME), - } - } - pub fn as_reader<'r>(&'r self) -> TlcErrDataReader<'r> { - TlcErrDataReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for TlcErrData { - type Builder = TlcErrDataBuilder; - const NAME: &'static str = "TlcErrData"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - TlcErrData(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - TlcErrDataReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - TlcErrDataReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder().set(self.to_enum()) - } -} -#[derive(Clone, Copy)] -pub struct TlcErrDataReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for TlcErrDataReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for TlcErrDataReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for TlcErrDataReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}(", Self::NAME)?; - self.to_enum().display_inner(f)?; - write!(f, ")") - } -} -impl<'r> TlcErrDataReader<'r> { - pub const ITEMS_COUNT: usize = 2; - pub fn item_id(&self) -> molecule::Number { - molecule::unpack_number(self.as_slice()) - } - pub fn to_enum(&self) -> TlcErrDataUnionReader<'r> { - let inner = &self.as_slice()[molecule::NUMBER_SIZE..]; - match self.item_id() { - 0 => ChannelFailedReader::new_unchecked(inner).into(), - 1 => NodeFailedReader::new_unchecked(inner).into(), - _ => panic!("{}: invalid data", Self::NAME), - } - } -} -impl<'r> molecule::prelude::Reader<'r> for TlcErrDataReader<'r> { - type Entity = TlcErrData; - const NAME: &'static str = "TlcErrDataReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - TlcErrDataReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { - use molecule::verification_error as ve; - let slice_len = slice.len(); - if slice_len < molecule::NUMBER_SIZE { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); - } - let item_id = molecule::unpack_number(slice); - let inner_slice = &slice[molecule::NUMBER_SIZE..]; - match item_id { - 0 => ChannelFailedReader::verify(inner_slice, compatible), - 1 => NodeFailedReader::verify(inner_slice, compatible), - _ => ve!(Self, UnknownItem, Self::ITEMS_COUNT, item_id), - }?; - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct TlcErrDataBuilder(pub(crate) TlcErrDataUnion); -impl TlcErrDataBuilder { - pub const ITEMS_COUNT: usize = 2; - pub fn set(mut self, v: I) -> Self - where - I: ::core::convert::Into, - { - self.0 = v.into(); - self - } -} -impl molecule::prelude::Builder for TlcErrDataBuilder { - type Entity = TlcErrData; - const NAME: &'static str = "TlcErrDataBuilder"; - fn expected_length(&self) -> usize { - molecule::NUMBER_SIZE + self.0.as_slice().len() - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - writer.write_all(&molecule::pack_number(self.0.item_id()))?; - writer.write_all(self.0.as_slice()) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - TlcErrData::new_unchecked(inner.into()) - } -} -#[derive(Debug, Clone)] -pub enum TlcErrDataUnion { - ChannelFailed(ChannelFailed), - NodeFailed(NodeFailed), -} -#[derive(Debug, Clone, Copy)] -pub enum TlcErrDataUnionReader<'r> { - ChannelFailed(ChannelFailedReader<'r>), - NodeFailed(NodeFailedReader<'r>), -} -impl ::core::default::Default for TlcErrDataUnion { - fn default() -> Self { - TlcErrDataUnion::ChannelFailed(::core::default::Default::default()) - } -} -impl ::core::fmt::Display for TlcErrDataUnion { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TlcErrDataUnion::ChannelFailed(ref item) => { - write!(f, "{}::{}({})", Self::NAME, ChannelFailed::NAME, item) - } - TlcErrDataUnion::NodeFailed(ref item) => { - write!(f, "{}::{}({})", Self::NAME, NodeFailed::NAME, item) - } - } - } -} -impl<'r> ::core::fmt::Display for TlcErrDataUnionReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TlcErrDataUnionReader::ChannelFailed(ref item) => { - write!(f, "{}::{}({})", Self::NAME, ChannelFailed::NAME, item) - } - TlcErrDataUnionReader::NodeFailed(ref item) => { - write!(f, "{}::{}({})", Self::NAME, NodeFailed::NAME, item) - } - } - } -} -impl TlcErrDataUnion { - pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TlcErrDataUnion::ChannelFailed(ref item) => write!(f, "{}", item), - TlcErrDataUnion::NodeFailed(ref item) => write!(f, "{}", item), - } - } -} -impl<'r> TlcErrDataUnionReader<'r> { - pub(crate) fn display_inner(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TlcErrDataUnionReader::ChannelFailed(ref item) => write!(f, "{}", item), - TlcErrDataUnionReader::NodeFailed(ref item) => write!(f, "{}", item), - } - } -} -impl ::core::convert::From for TlcErrDataUnion { - fn from(item: ChannelFailed) -> Self { - TlcErrDataUnion::ChannelFailed(item) - } -} -impl ::core::convert::From for TlcErrDataUnion { - fn from(item: NodeFailed) -> Self { - TlcErrDataUnion::NodeFailed(item) - } -} -impl<'r> ::core::convert::From> for TlcErrDataUnionReader<'r> { - fn from(item: ChannelFailedReader<'r>) -> Self { - TlcErrDataUnionReader::ChannelFailed(item) - } -} -impl<'r> ::core::convert::From> for TlcErrDataUnionReader<'r> { - fn from(item: NodeFailedReader<'r>) -> Self { - TlcErrDataUnionReader::NodeFailed(item) - } -} -impl TlcErrDataUnion { - pub const NAME: &'static str = "TlcErrDataUnion"; - pub fn as_bytes(&self) -> molecule::bytes::Bytes { - match self { - TlcErrDataUnion::ChannelFailed(item) => item.as_bytes(), - TlcErrDataUnion::NodeFailed(item) => item.as_bytes(), - } - } - pub fn as_slice(&self) -> &[u8] { - match self { - TlcErrDataUnion::ChannelFailed(item) => item.as_slice(), - TlcErrDataUnion::NodeFailed(item) => item.as_slice(), - } - } - pub fn item_id(&self) -> molecule::Number { - match self { - TlcErrDataUnion::ChannelFailed(_) => 0, - TlcErrDataUnion::NodeFailed(_) => 1, - } - } - pub fn item_name(&self) -> &str { - match self { - TlcErrDataUnion::ChannelFailed(_) => "ChannelFailed", - TlcErrDataUnion::NodeFailed(_) => "NodeFailed", - } - } - pub fn as_reader<'r>(&'r self) -> TlcErrDataUnionReader<'r> { - match self { - TlcErrDataUnion::ChannelFailed(item) => item.as_reader().into(), - TlcErrDataUnion::NodeFailed(item) => item.as_reader().into(), - } - } -} -impl<'r> TlcErrDataUnionReader<'r> { - pub const NAME: &'r str = "TlcErrDataUnionReader"; - pub fn as_slice(&self) -> &'r [u8] { - match self { - TlcErrDataUnionReader::ChannelFailed(item) => item.as_slice(), - TlcErrDataUnionReader::NodeFailed(item) => item.as_slice(), - } - } - pub fn item_id(&self) -> molecule::Number { - match self { - TlcErrDataUnionReader::ChannelFailed(_) => 0, - TlcErrDataUnionReader::NodeFailed(_) => 1, - } - } - pub fn item_name(&self) -> &str { - match self { - TlcErrDataUnionReader::ChannelFailed(_) => "ChannelFailed", - TlcErrDataUnionReader::NodeFailed(_) => "NodeFailed", - } - } -} -impl From for TlcErrData { - fn from(value: ChannelFailed) -> Self { - Self::new_builder().set(value).build() - } -} -impl From for TlcErrData { - fn from(value: NodeFailed) -> Self { - Self::new_builder().set(value).build() - } -} -#[derive(Clone)] -pub struct TlcErrDataOpt(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for TlcErrDataOpt { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for TlcErrDataOpt { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for TlcErrDataOpt { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - if let Some(v) = self.to_opt() { - write!(f, "{}(Some({}))", Self::NAME, v) - } else { - write!(f, "{}(None)", Self::NAME) - } - } -} -impl ::core::default::Default for TlcErrDataOpt { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - TlcErrDataOpt::new_unchecked(v) - } -} -impl TlcErrDataOpt { - const DEFAULT_VALUE: [u8; 0] = []; - pub fn is_none(&self) -> bool { - self.0.is_empty() - } - pub fn is_some(&self) -> bool { - !self.0.is_empty() - } - pub fn to_opt(&self) -> Option { - if self.is_none() { - None - } else { - Some(TlcErrData::new_unchecked(self.0.clone())) - } - } - pub fn as_reader<'r>(&'r self) -> TlcErrDataOptReader<'r> { - TlcErrDataOptReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for TlcErrDataOpt { - type Builder = TlcErrDataOptBuilder; - const NAME: &'static str = "TlcErrDataOpt"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - TlcErrDataOpt(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - TlcErrDataOptReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - TlcErrDataOptReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder().set(self.to_opt()) - } -} -#[derive(Clone, Copy)] -pub struct TlcErrDataOptReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for TlcErrDataOptReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for TlcErrDataOptReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for TlcErrDataOptReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - if let Some(v) = self.to_opt() { - write!(f, "{}(Some({}))", Self::NAME, v) - } else { - write!(f, "{}(None)", Self::NAME) - } - } -} -impl<'r> TlcErrDataOptReader<'r> { - pub fn is_none(&self) -> bool { - self.0.is_empty() - } - pub fn is_some(&self) -> bool { - !self.0.is_empty() - } - pub fn to_opt(&self) -> Option> { - if self.is_none() { - None - } else { - Some(TlcErrDataReader::new_unchecked(self.as_slice())) - } - } -} -impl<'r> molecule::prelude::Reader<'r> for TlcErrDataOptReader<'r> { - type Entity = TlcErrDataOpt; - const NAME: &'static str = "TlcErrDataOptReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - TlcErrDataOptReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { - if !slice.is_empty() { - TlcErrDataReader::verify(&slice[..], compatible)?; - } - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct TlcErrDataOptBuilder(pub(crate) Option); -impl TlcErrDataOptBuilder { - pub fn set(mut self, v: Option) -> Self { - self.0 = v; - self - } -} -impl molecule::prelude::Builder for TlcErrDataOptBuilder { - type Entity = TlcErrDataOpt; - const NAME: &'static str = "TlcErrDataOptBuilder"; - fn expected_length(&self) -> usize { - self.0 - .as_ref() - .map(|ref inner| inner.as_slice().len()) - .unwrap_or(0) - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - self.0 - .as_ref() - .map(|ref inner| writer.write_all(inner.as_slice())) - .unwrap_or(Ok(())) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - TlcErrDataOpt::new_unchecked(inner.into()) - } -} -impl From for TlcErrDataOpt { - fn from(value: TlcErrData) -> Self { - Self::new_builder().set(Some(value)).build() - } -} -#[derive(Clone)] -pub struct TlcErr(molecule::bytes::Bytes); -impl ::core::fmt::LowerHex for TlcErr { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl ::core::fmt::Debug for TlcErr { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl ::core::fmt::Display for TlcErr { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "error_code", self.error_code())?; - write!(f, ", {}: {}", "extra_data", self.extra_data())?; - let extra_count = self.count_extra_fields(); - if extra_count != 0 { - write!(f, ", .. ({} fields)", extra_count)?; - } - write!(f, " }}") - } -} -impl ::core::default::Default for TlcErr { - fn default() -> Self { - let v = molecule::bytes::Bytes::from_static(&Self::DEFAULT_VALUE); - TlcErr::new_unchecked(v) - } -} -impl TlcErr { - const DEFAULT_VALUE: [u8; 44] = [ - 44, 0, 0, 0, 12, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - pub const FIELD_COUNT: usize = 2; - pub fn total_size(&self) -> usize { - molecule::unpack_number(self.as_slice()) as usize - } - pub fn field_count(&self) -> usize { - if self.total_size() == molecule::NUMBER_SIZE { - 0 - } else { - (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 - } - } - pub fn count_extra_fields(&self) -> usize { - self.field_count() - Self::FIELD_COUNT - } - pub fn has_extra_fields(&self) -> bool { - Self::FIELD_COUNT != self.field_count() - } - pub fn error_code(&self) -> Byte32 { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[4..]) as usize; - let end = molecule::unpack_number(&slice[8..]) as usize; - Byte32::new_unchecked(self.0.slice(start..end)) - } - pub fn extra_data(&self) -> TlcErrDataOpt { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[8..]) as usize; - if self.has_extra_fields() { - let end = molecule::unpack_number(&slice[12..]) as usize; - TlcErrDataOpt::new_unchecked(self.0.slice(start..end)) - } else { - TlcErrDataOpt::new_unchecked(self.0.slice(start..)) - } - } - pub fn as_reader<'r>(&'r self) -> TlcErrReader<'r> { - TlcErrReader::new_unchecked(self.as_slice()) - } -} -impl molecule::prelude::Entity for TlcErr { - type Builder = TlcErrBuilder; - const NAME: &'static str = "TlcErr"; - fn new_unchecked(data: molecule::bytes::Bytes) -> Self { - TlcErr(data) - } - fn as_bytes(&self) -> molecule::bytes::Bytes { - self.0.clone() - } - fn as_slice(&self) -> &[u8] { - &self.0[..] - } - fn from_slice(slice: &[u8]) -> molecule::error::VerificationResult { - TlcErrReader::from_slice(slice).map(|reader| reader.to_entity()) - } - fn from_compatible_slice(slice: &[u8]) -> molecule::error::VerificationResult { - TlcErrReader::from_compatible_slice(slice).map(|reader| reader.to_entity()) - } - fn new_builder() -> Self::Builder { - ::core::default::Default::default() - } - fn as_builder(self) -> Self::Builder { - Self::new_builder() - .error_code(self.error_code()) - .extra_data(self.extra_data()) - } -} -#[derive(Clone, Copy)] -pub struct TlcErrReader<'r>(&'r [u8]); -impl<'r> ::core::fmt::LowerHex for TlcErrReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use molecule::hex_string; - if f.alternate() { - write!(f, "0x")?; - } - write!(f, "{}", hex_string(self.as_slice())) - } -} -impl<'r> ::core::fmt::Debug for TlcErrReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{}({:#x})", Self::NAME, self) - } -} -impl<'r> ::core::fmt::Display for TlcErrReader<'r> { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "{} {{ ", Self::NAME)?; - write!(f, "{}: {}", "error_code", self.error_code())?; - write!(f, ", {}: {}", "extra_data", self.extra_data())?; - let extra_count = self.count_extra_fields(); - if extra_count != 0 { - write!(f, ", .. ({} fields)", extra_count)?; - } - write!(f, " }}") - } -} -impl<'r> TlcErrReader<'r> { - pub const FIELD_COUNT: usize = 2; - pub fn total_size(&self) -> usize { - molecule::unpack_number(self.as_slice()) as usize - } - pub fn field_count(&self) -> usize { - if self.total_size() == molecule::NUMBER_SIZE { - 0 - } else { - (molecule::unpack_number(&self.as_slice()[molecule::NUMBER_SIZE..]) as usize / 4) - 1 - } - } - pub fn count_extra_fields(&self) -> usize { - self.field_count() - Self::FIELD_COUNT - } - pub fn has_extra_fields(&self) -> bool { - Self::FIELD_COUNT != self.field_count() - } - pub fn error_code(&self) -> Byte32Reader<'r> { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[4..]) as usize; - let end = molecule::unpack_number(&slice[8..]) as usize; - Byte32Reader::new_unchecked(&self.as_slice()[start..end]) - } - pub fn extra_data(&self) -> TlcErrDataOptReader<'r> { - let slice = self.as_slice(); - let start = molecule::unpack_number(&slice[8..]) as usize; - if self.has_extra_fields() { - let end = molecule::unpack_number(&slice[12..]) as usize; - TlcErrDataOptReader::new_unchecked(&self.as_slice()[start..end]) - } else { - TlcErrDataOptReader::new_unchecked(&self.as_slice()[start..]) - } - } -} -impl<'r> molecule::prelude::Reader<'r> for TlcErrReader<'r> { - type Entity = TlcErr; - const NAME: &'static str = "TlcErrReader"; - fn to_entity(&self) -> Self::Entity { - Self::Entity::new_unchecked(self.as_slice().to_owned().into()) - } - fn new_unchecked(slice: &'r [u8]) -> Self { - TlcErrReader(slice) - } - fn as_slice(&self) -> &'r [u8] { - self.0 - } - fn verify(slice: &[u8], compatible: bool) -> molecule::error::VerificationResult<()> { - use molecule::verification_error as ve; - let slice_len = slice.len(); - if slice_len < molecule::NUMBER_SIZE { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE, slice_len); - } - let total_size = molecule::unpack_number(slice) as usize; - if slice_len != total_size { - return ve!(Self, TotalSizeNotMatch, total_size, slice_len); - } - if slice_len < molecule::NUMBER_SIZE * 2 { - return ve!(Self, HeaderIsBroken, molecule::NUMBER_SIZE * 2, slice_len); - } - let offset_first = molecule::unpack_number(&slice[molecule::NUMBER_SIZE..]) as usize; - if offset_first % molecule::NUMBER_SIZE != 0 || offset_first < molecule::NUMBER_SIZE * 2 { - return ve!(Self, OffsetsNotMatch); - } - if slice_len < offset_first { - return ve!(Self, HeaderIsBroken, offset_first, slice_len); - } - let field_count = offset_first / molecule::NUMBER_SIZE - 1; - if field_count < Self::FIELD_COUNT { - return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); - } else if !compatible && field_count > Self::FIELD_COUNT { - return ve!(Self, FieldCountNotMatch, Self::FIELD_COUNT, field_count); - }; - let mut offsets: Vec = slice[molecule::NUMBER_SIZE..offset_first] - .chunks_exact(molecule::NUMBER_SIZE) - .map(|x| molecule::unpack_number(x) as usize) - .collect(); - offsets.push(total_size); - if offsets.windows(2).any(|i| i[0] > i[1]) { - return ve!(Self, OffsetsNotMatch); - } - Byte32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?; - TlcErrDataOptReader::verify(&slice[offsets[1]..offsets[2]], compatible)?; - Ok(()) - } -} -#[derive(Clone, Debug, Default)] -pub struct TlcErrBuilder { - pub(crate) error_code: Byte32, - pub(crate) extra_data: TlcErrDataOpt, -} -impl TlcErrBuilder { - pub const FIELD_COUNT: usize = 2; - pub fn error_code(mut self, v: Byte32) -> Self { - self.error_code = v; - self - } - pub fn extra_data(mut self, v: TlcErrDataOpt) -> Self { - self.extra_data = v; - self - } -} -impl molecule::prelude::Builder for TlcErrBuilder { - type Entity = TlcErr; - const NAME: &'static str = "TlcErrBuilder"; - fn expected_length(&self) -> usize { - molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1) - + self.error_code.as_slice().len() - + self.extra_data.as_slice().len() - } - fn write(&self, writer: &mut W) -> molecule::io::Result<()> { - let mut total_size = molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1); - let mut offsets = Vec::with_capacity(Self::FIELD_COUNT); - offsets.push(total_size); - total_size += self.error_code.as_slice().len(); - offsets.push(total_size); - total_size += self.extra_data.as_slice().len(); - writer.write_all(&molecule::pack_number(total_size as molecule::Number))?; - for offset in offsets.into_iter() { - writer.write_all(&molecule::pack_number(offset as molecule::Number))?; - } - writer.write_all(self.error_code.as_slice())?; - writer.write_all(self.extra_data.as_slice())?; - Ok(()) - } - fn build(&self) -> Self::Entity { - let mut inner = Vec::with_capacity(self.expected_length()); - self.write(&mut inner) - .unwrap_or_else(|_| panic!("{} build should be ok", Self::NAME)); - TlcErr::new_unchecked(inner.into()) - } -} diff --git a/src/fiber/schema/fiber.mol b/src/fiber/schema/fiber.mol index 19f0691e9..e454c1c3c 100644 --- a/src/fiber/schema/fiber.mol +++ b/src/fiber/schema/fiber.mol @@ -1,5 +1,6 @@ import blockchain; +array Uint16 [byte; 2]; array EcdsaSignature [byte; 64]; array PubNonce [byte; 66]; // PubNonce used by musig2 crate. option PubNonceOpt (PubNonce); @@ -187,3 +188,52 @@ union FiberMessage { ReestablishChannel, AnnouncementSignatures, } + +option PaymentPreimageOpt (Byte32); +option PubkeyOpt (Pubkey); +table PaymentHopData { + amount: Uint128, + expiry: Uint64, + payment_preimage: PaymentPreimageOpt, + hash_algorithm: byte, + funding_tx_hash: Byte32, + next_hop: PubkeyOpt, +} + +// A ChannelUpdate is a update to the public channel. Newer channel information may be updated with +// a ChannelUpdate with a larger timestamp. +struct ChannelUpdate { + // Signature of the node that wants to update the channel information. + signature: EcdsaSignature, + chain_hash: Byte32, + channel_outpoint: OutPoint, + timestamp: Uint64, + message_flags: Uint32, + channel_flags: Uint32, + tlc_expiry_delta: Uint64, + tlc_minimum_value: Uint128, + tlc_maximum_value: Uint128, + tlc_fee_proportional_millionths: Uint128, +} + +option ChannelUpdateOpt (ChannelUpdate); +table ChannelFailed { + channel_outpoint: OutPoint, + channel_update: ChannelUpdateOpt, + node_id: Pubkey, +} + +table NodeFailed { + node_id: Pubkey, +} + +union TlcErrData { + ChannelFailed, + NodeFailed, +} + +option TlcErrDataOpt (TlcErrData); +table TlcErr { + error_code: Uint16, + extra_data: TlcErrDataOpt, +} \ No newline at end of file diff --git a/src/fiber/schema/gossip.mol b/src/fiber/schema/gossip.mol index 7f1ea634c..61ebdb6d8 100644 --- a/src/fiber/schema/gossip.mol +++ b/src/fiber/schema/gossip.mol @@ -1,7 +1,6 @@ import blockchain; import fiber; -array Uint16 [byte; 2]; array SchnorrSignature [byte; 64]; array SchnorrXOnlyPubkey [byte; 32]; @@ -78,22 +77,6 @@ table ChannelAnnouncement { udt_type_script: ScriptOpt, } -// A ChannelUpdate is a update to the public channel. Newer channel information may be updated with -// a ChannelUpdate with a larger timestamp. -struct ChannelUpdate { - // Signature of the node that wants to update the channel information. - signature: EcdsaSignature, - chain_hash: Byte32, - channel_outpoint: OutPoint, - timestamp: Uint64, - message_flags: Uint32, - channel_flags: Uint32, - tlc_expiry_delta: Uint64, - tlc_minimum_value: Uint128, - tlc_maximum_value: Uint128, - tlc_fee_proportional_millionths: Uint128, -} - // All the broadcast messages. union BroadcastMessage { NodeAnnouncement, @@ -166,25 +149,3 @@ union GossipMessage { QueryBroadcastMessages, QueryBroadcastMessagesResult, } - -option ChannelUpdateOpt (ChannelUpdate); -table ChannelFailed { - channel_outpoint: OutPoint, - channel_update: ChannelUpdateOpt, - node_id: Pubkey, -} - -table NodeFailed { - node_id: Pubkey, -} - -union TlcErrData { - ChannelFailed, - NodeFailed, -} - -option TlcErrDataOpt (TlcErrData); -table TlcErr { - error_code: Byte32, - extra_data: TlcErrDataOpt, -} \ No newline at end of file diff --git a/src/fiber/tests/channel.rs b/src/fiber/tests/channel.rs index 2ec3cc2a1..95d0f459c 100644 --- a/src/fiber/tests/channel.rs +++ b/src/fiber/tests/channel.rs @@ -1452,8 +1452,9 @@ async fn test_send_payment_with_max_nodes() { let res = res.unwrap(); assert_eq!(res.status, PaymentSessionStatus::Inflight); assert!(res.fee > 0); - // sleep for 2 seconds to make sure the payment is sent - tokio::time::sleep(tokio::time::Duration::from_millis(3000)).await; + + // sleep for 5 seconds to make sure the payment is sent + tokio::time::sleep(tokio::time::Duration::from_millis(5000)).await; let message = |rpc_reply| -> NetworkActorMessage { NetworkActorMessage::Command(NetworkActorCommand::GetPayment(res.payment_hash, rpc_reply)) }; diff --git a/src/fiber/tests/types.rs b/src/fiber/tests/types.rs index 9ee86d259..c92c7eeb6 100644 --- a/src/fiber/tests/types.rs +++ b/src/fiber/tests/types.rs @@ -234,3 +234,16 @@ fn test_tlc_err_packet_encryption() { assert_eq!(decrypted_tlc_fail_detail, tlc_fail_detail); } } + +#[test] +fn test_tlc_error_code() { + let code = TlcErrorCode::PermanentNodeFailure; + let str = code.as_ref().to_string(); + let code2 = TlcErrorCode::from_str(&str).expect("parse"); + assert_eq!(code, code2); + + let code = TlcErrorCode::IncorrectOrUnknownPaymentDetails; + let code_int: u16 = code.into(); + let code = TlcErrorCode::try_from(code_int).expect("invalid code"); + assert_eq!(code, TlcErrorCode::IncorrectOrUnknownPaymentDetails); +} diff --git a/src/fiber/types.rs b/src/fiber/types.rs index 6e69de18a..3a76adfe1 100644 --- a/src/fiber/types.rs +++ b/src/fiber/types.rs @@ -1,6 +1,9 @@ use super::channel::{ChannelFlags, CHANNEL_DISABLED_FLAG, MESSAGE_OF_NODE2_FLAG}; use super::config::AnnouncedNodeName; -use super::gen::fiber::{self as molecule_fiber, PubNonce as Byte66, UdtCellDeps, Uint128Opt}; +use super::gen::fiber::{ + self as molecule_fiber, ChannelUpdateOpt, PaymentPreimageOpt, PubNonce as Byte66, PubkeyOpt, + TlcErrDataOpt, UdtCellDeps, Uint128Opt, +}; use super::gen::gossip::{self as molecule_gossip}; use super::hash_algorithm::{HashAlgorithm, UnknownHashAlgorithmError}; use super::network::get_chain_hash; @@ -8,6 +11,9 @@ use super::r#gen::fiber::PubNonceOpt; use super::serde_utils::{EntityHex, SliceHex}; use crate::ckb::config::{UdtArgInfo, UdtCellDep, UdtCfgInfos, UdtScript}; use crate::ckb::contracts::get_udt_whitelist; +use num_enum::IntoPrimitive; +use num_enum::TryFromPrimitive; +use std::convert::TryFrom; use anyhow::anyhow; use ckb_types::{ @@ -1107,70 +1113,6 @@ impl TryFrom for RemoveTlcFulfill { } } -// impl From for molecule_gossip::TlcErr { -// fn from(tlc_err: TlcErr) -> Self { -// molecule_gossip::TlcErr::new_builder() -// .error_code(ckb_types::packed::Byte32::new(tlc_err.error_code as u32)) -// .extra_data( -// tlc_err -// .extra_data -// .map(|data| match data { -// TlcErrData::ChannelFailed { -// channel_outpoint, -// channel_update, -// node_id, -// } => molecule_gossip::TlcErrDataBuilder::set( -// molecule_gossip::ChannelFailed::new_builder() -// .channel_outpoint(channel_outpoint.into()) -// .channel_update(channel_update.into()) -// .node_id(node_id.into()) -// .build(), -// ) -// .build() -// .to_opt(), -// TlcErrData::NodeFailed { node_id } => { -// molecule_gossip::TlcErrDataBuilder::set( -// molecule_gossip::NodeFailed::new_builder() -// .node_id(node_id.into()) -// .build(), -// ) -// .build() -// .to_opt() -// } -// }) -// .pack(), -// ) -// .build() -// } -// } - -// impl TryFrom for TlcErr { -// type Error = Error; - -// fn try_from(tlc_err: molecule_gossip::TlcErr) -> Result { -// Ok(TlcErr { -// error_code: tlc_err.error_code().into(), -// extra_data: tlc_err -// .extra_data() -// .to_opt() -// .map(|data| match data.unpack() { -// TlcErrData::ChannelFailed { -// channel_outpoint, -// channel_update, -// node_id, -// } => TlcErrData::ChannelFailed { -// channel_outpoint: channel_outpoint.into(), -// channel_update: channel_update.to_opt(), -// node_id: node_id.into(), -// }, -// TlcErrData::NodeFailed { node_id } => TlcErrData::NodeFailed { -// node_id: node_id.into(), -// }, -// }), -// }) -// } -// } - #[serde_as] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum TlcErrData { @@ -1255,16 +1197,103 @@ impl TlcErr { error_code.as_ref().to_string() } + pub fn error_code_as_u16(&self) -> u16 { + self.error_code.into() + } + pub fn set_extra_data(&mut self, extra_data: TlcErrData) { self.extra_data = Some(extra_data); } fn serialize(&self) -> Vec { - bincode::serialize(self).expect("serialize hop data") + molecule_fiber::TlcErr::from(self.clone()) + .as_slice() + .to_vec() } fn deserialize(data: &[u8]) -> Option { - bincode::deserialize(data).ok() + molecule_fiber::TlcErr::from_slice(data) + .map(TlcErr::from) + .ok() + } +} + +impl TryFrom for molecule_fiber::TlcErrData { + type Error = Error; + + fn try_from(tlc_err_data: TlcErrData) -> Result { + match tlc_err_data { + TlcErrData::ChannelFailed { + channel_outpoint, + channel_update, + node_id, + } => Ok(molecule_fiber::ChannelFailed::new_builder() + .channel_outpoint(channel_outpoint.into()) + .channel_update( + ChannelUpdateOpt::new_builder() + .set(channel_update.map(|x| x.into())) + .build(), + ) + .node_id(node_id.into()) + .build() + .into()), + TlcErrData::NodeFailed { node_id } => Ok(molecule_fiber::NodeFailed::new_builder() + .node_id(node_id.into()) + .build() + .into()), + } + } +} + +impl TryFrom for TlcErrData { + type Error = Error; + + fn try_from(tlc_err_data: molecule_fiber::TlcErrData) -> Result { + match tlc_err_data.to_enum() { + molecule_fiber::TlcErrDataUnion::ChannelFailed(channel_failed) => { + Ok(TlcErrData::ChannelFailed { + channel_outpoint: channel_failed.channel_outpoint().into(), + channel_update: channel_failed + .channel_update() + .to_opt() + .map(|x| x.try_into().unwrap()), + node_id: channel_failed.node_id().try_into()?, + }) + } + molecule_fiber::TlcErrDataUnion::NodeFailed(node_failed) => { + Ok(TlcErrData::NodeFailed { + node_id: node_failed.node_id().try_into()?, + }) + } + } + } +} + +impl From for molecule_fiber::TlcErr { + fn from(tlc_err: TlcErr) -> Self { + molecule_fiber::TlcErr::new_builder() + .error_code(tlc_err.error_code_as_u16().into()) + .extra_data( + TlcErrDataOpt::new_builder() + .set(tlc_err.extra_data.map(|data| data.try_into().unwrap())) + .build(), + ) + .build() + } +} + +impl From for TlcErr { + fn from(tlc_err: molecule_fiber::TlcErr) -> Self { + TlcErr { + error_code: { + let code: u16 = tlc_err.error_code().into(); + TlcErrorCode::try_from(code).expect("parse error code failed") + }, + extra_data: tlc_err + .extra_data() + .to_opt() + .map(|data| data.try_into().unwrap()), + } } } @@ -1378,7 +1407,19 @@ const NODE: u16 = 0x2000; const UPDATE: u16 = 0x1000; #[repr(u16)] -#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, AsRefStr, EnumString)] +#[derive( + Debug, + Copy, + Clone, + Serialize, + Deserialize, + PartialEq, + Eq, + AsRefStr, + EnumString, + TryFromPrimitive, + IntoPrimitive, +)] pub enum TlcErrorCode { TemporaryNodeFailure = NODE | 2, PermanentNodeFailure = PERM | NODE | 2, @@ -2061,7 +2102,7 @@ impl ChannelUpdate { tlc_minimum_value: self.tlc_minimum_value, tlc_fee_proportional_millionths: self.tlc_fee_proportional_millionths, }; - deterministically_hash(&molecule_gossip::ChannelUpdate::from(unsigned_update)) + deterministically_hash(&molecule_fiber::ChannelUpdate::from(unsigned_update)) } pub fn is_update_of_node_1(&self) -> bool { @@ -2084,9 +2125,9 @@ impl ChannelUpdate { } } -impl From for molecule_gossip::ChannelUpdate { +impl From for molecule_fiber::ChannelUpdate { fn from(channel_update: ChannelUpdate) -> Self { - let builder = molecule_gossip::ChannelUpdate::new_builder() + let builder = molecule_fiber::ChannelUpdate::new_builder() .chain_hash(channel_update.chain_hash.into()) .channel_outpoint(channel_update.channel_outpoint) .timestamp(channel_update.timestamp.pack()) @@ -2106,10 +2147,10 @@ impl From for molecule_gossip::ChannelUpdate { } } -impl TryFrom for ChannelUpdate { +impl TryFrom for ChannelUpdate { type Error = Error; - fn try_from(channel_update: molecule_gossip::ChannelUpdate) -> Result { + fn try_from(channel_update: molecule_fiber::ChannelUpdate) -> Result { Ok(ChannelUpdate { signature: Some(channel_update.signature().try_into()?), chain_hash: channel_update.chain_hash().into(), @@ -2883,7 +2924,7 @@ impl TryFrom for Cursor { } } -impl From for molecule_gossip::Uint16 { +impl From for molecule_fiber::Uint16 { fn from(count: u16) -> Self { let le_bytes = count.to_le_bytes(); Self::new_builder() @@ -2899,8 +2940,8 @@ impl From for molecule_gossip::Uint16 { } } -impl From for u16 { - fn from(count: molecule_gossip::Uint16) -> Self { +impl From for u16 { + fn from(count: molecule_fiber::Uint16) -> Self { let le_bytes = count.as_slice().try_into().expect("Uint16 to u16"); u16::from_le_bytes(le_bytes) } @@ -3384,11 +3425,58 @@ impl HopData for PaymentHopData { } fn serialize(&self) -> Vec { - bincode::serialize(self).expect("serialize hop data") + molecule_fiber::PaymentHopData::from(self.clone()) + .as_bytes() + .to_vec() } fn deserialize(data: &[u8]) -> Option { - bincode::deserialize(data).ok() + molecule_fiber::PaymentHopData::from_slice(data) + .ok() + .map(|x| x.into()) + } +} + +impl From for molecule_fiber::PaymentHopData { + fn from(payment_hop_data: PaymentHopData) -> Self { + molecule_fiber::PaymentHopData::new_builder() + .amount(payment_hop_data.amount.pack()) + .expiry(payment_hop_data.expiry.pack()) + .payment_preimage( + PaymentPreimageOpt::new_builder() + .set(payment_hop_data.payment_preimage.map(|x| x.into())) + .build(), + ) + .hash_algorithm(Byte::new(payment_hop_data.hash_algorithm as u8)) + .funding_tx_hash(payment_hop_data.funding_tx_hash.into()) + .next_hop( + PubkeyOpt::new_builder() + .set(payment_hop_data.next_hop.map(|x| x.into())) + .build(), + ) + .build() + } +} + +impl From for PaymentHopData { + fn from(payment_hop_data: molecule_fiber::PaymentHopData) -> Self { + PaymentHopData { + amount: payment_hop_data.amount().unpack(), + expiry: payment_hop_data.expiry().unpack(), + payment_preimage: payment_hop_data + .payment_preimage() + .to_opt() + .map(|x| x.into()), + hash_algorithm: payment_hop_data + .hash_algorithm() + .try_into() + .expect("valid hash algorithm"), + funding_tx_hash: payment_hop_data.funding_tx_hash().into(), + next_hop: payment_hop_data + .next_hop() + .to_opt() + .map(|x| x.try_into().expect("invalid pubkey")), + } } }