Skip to content

Commit

Permalink
more on tlc errors
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Oct 1, 2024
1 parent a9f752b commit f144887
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 32 deletions.
30 changes: 19 additions & 11 deletions src/fiber/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ where
//FIXME: we should define the error code carefully according
//refer to https://github.com/lightning/bolts/blob/master/04-onion-routing.md#failure-messages
error_code: 1,
packet_data: vec![],
},
),
}),
Expand All @@ -503,13 +504,17 @@ where
state.check_for_tlc_update(None)?;
let channel_id = state.get_id();

let tlc_details = state
.remove_tlc_with_reason(TLCId::Offered(remove_tlc.tlc_id), remove_tlc.reason)?;
let tlc_details = state.remove_tlc_with_reason(
TLCId::Offered(remove_tlc.tlc_id),
remove_tlc.reason.clone(),
)?;
if let (
Some(ref udt_type_script),
RemoveTlcReason::RemoveTlcFulfill(RemoveTlcFulfill { payment_preimage }),
) = (state.funding_udt_type_script.clone(), remove_tlc.reason)
{
) = (
state.funding_udt_type_script.clone(),
remove_tlc.reason.clone(),
) {
let mut tlc = tlc_details.tlc.clone();
tlc.payment_preimage = Some(payment_preimage);
self.subscribers
Expand All @@ -535,7 +540,7 @@ where
command: ChannelCommand::RemoveTlc(
RemoveTlcCommand {
id: previous_tlc.into(),
reason: remove_tlc.reason,
reason: remove_tlc.reason.clone(),
},
port,
),
Expand All @@ -546,6 +551,7 @@ where
info!("remove tlc from previous channel: {:?}", &res);
}

// TODO: only the original sender of the TLC should send `TlcRemoveReceived` event
self.network
.send_message(NetworkActorMessage::new_event(
NetworkActorEvent::TlcRemoveReceived(
Expand Down Expand Up @@ -790,6 +796,7 @@ where
//FIXME: we should define the error code carefully according
//refer to https://github.com/lightning/bolts/blob/master/04-onion-routing.md#failure-messages
error_code: 1,
packet_data: vec![],
}),
},
port,
Expand Down Expand Up @@ -966,7 +973,8 @@ where
command: RemoveTlcCommand,
) -> ProcessingChannelResult {
state.check_for_tlc_update(None)?;
let tlc = state.remove_tlc_with_reason(TLCId::Received(command.id), command.reason)?;
let tlc =
state.remove_tlc_with_reason(TLCId::Received(command.id), command.reason.clone())?;
let msg = FiberMessageWithPeerId::new(
state.get_remote_peer_id(),
FiberMessage::remove_tlc(RemoveTlc {
Expand Down Expand Up @@ -3046,7 +3054,7 @@ impl ChannelActorState {
);
tlc.creation_confirmed_at = Some(commitment_numbers);
}
match (tlc.removed_at, tlc.removal_confirmed_at) {
match (tlc.removed_at.clone(), tlc.removal_confirmed_at) {
(Some((_removed_at, reason)), None) => {
tlc.removal_confirmed_at = Some(commitment_numbers);
match reason {
Expand Down Expand Up @@ -3304,7 +3312,7 @@ impl ChannelActorState {
)))
}
Some(current) => {
match current.removed_at {
match current.removed_at.clone() {
Some((current_removed_at, current_remove_reason))
if current_remove_reason == reason && removed_at == current_removed_at =>
{
Expand Down Expand Up @@ -4561,7 +4569,7 @@ impl ChannelActorState {

need_resend_commitment_signed = true;
}
} else if let Some((commitment_number, remove_reason)) = info.removed_at {
} else if let Some((commitment_number, remove_reason)) = &info.removed_at {
if commitment_number.get_local() >= acutal_local_commitment_number {
// resend RemoveTlc message
network
Expand All @@ -4572,7 +4580,7 @@ impl ChannelActorState {
FiberMessage::remove_tlc(RemoveTlc {
channel_id: self.get_id(),
tlc_id: info.tlc.get_id(),
reason: remove_reason,
reason: remove_reason.clone(),
}),
),
),
Expand Down Expand Up @@ -5539,7 +5547,7 @@ impl DetailedTLCInfo {
}

fn is_fullfill_removed(&self) -> bool {
if let Some((_, removed_reason)) = self.removed_at {
if let Some((_, removed_reason)) = &self.removed_at {
matches!(removed_reason, RemoveTlcReason::RemoveTlcFulfill(_))
} else {
false
Expand Down
148 changes: 131 additions & 17 deletions src/fiber/gen/fiber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9366,6 +9366,11 @@ impl ::core::fmt::Display for RemoveTlcFail {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "{} {{ ", Self::NAME)?;
write!(f, "{}: {}", "error_code", self.error_code())?;
write!(f, ", {}: {}", "packet_data", self.packet_data())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
Expand All @@ -9376,12 +9381,41 @@ impl ::core::default::Default for RemoveTlcFail {
}
}
impl RemoveTlcFail {
const DEFAULT_VALUE: [u8; 4] = [0, 0, 0, 0];
pub const TOTAL_SIZE: usize = 4;
pub const FIELD_SIZES: [usize; 1] = [4];
pub const FIELD_COUNT: usize = 1;
const DEFAULT_VALUE: [u8; 20] = [
20, 0, 0, 0, 12, 0, 0, 0, 16, 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) -> Uint32 {
Uint32::new_unchecked(self.0.slice(0..4))
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
Uint32::new_unchecked(self.0.slice(start..end))
}
pub fn packet_data(&self) -> Bytes {
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;
Bytes::new_unchecked(self.0.slice(start..end))
} else {
Bytes::new_unchecked(self.0.slice(start..))
}
}
pub fn as_reader<'r>(&'r self) -> RemoveTlcFailReader<'r> {
RemoveTlcFailReader::new_unchecked(self.as_slice())
Expand Down Expand Up @@ -9409,7 +9443,9 @@ impl molecule::prelude::Entity for RemoveTlcFail {
::core::default::Default::default()
}
fn as_builder(self) -> Self::Builder {
Self::new_builder().error_code(self.error_code())
Self::new_builder()
.error_code(self.error_code())
.packet_data(self.packet_data())
}
}
#[derive(Clone, Copy)]
Expand All @@ -9432,15 +9468,47 @@ impl<'r> ::core::fmt::Display for RemoveTlcFailReader<'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, ", {}: {}", "packet_data", self.packet_data())?;
let extra_count = self.count_extra_fields();
if extra_count != 0 {
write!(f, ", .. ({} fields)", extra_count)?;
}
write!(f, " }}")
}
}
impl<'r> RemoveTlcFailReader<'r> {
pub const TOTAL_SIZE: usize = 4;
pub const FIELD_SIZES: [usize; 1] = [4];
pub const FIELD_COUNT: usize = 1;
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) -> Uint32Reader<'r> {
Uint32Reader::new_unchecked(&self.as_slice()[0..4])
let slice = self.as_slice();
let start = molecule::unpack_number(&slice[4..]) as usize;
let end = molecule::unpack_number(&slice[8..]) as usize;
Uint32Reader::new_unchecked(&self.as_slice()[start..end])
}
pub fn packet_data(&self) -> BytesReader<'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;
BytesReader::new_unchecked(&self.as_slice()[start..end])
} else {
BytesReader::new_unchecked(&self.as_slice()[start..])
}
}
}
impl<'r> molecule::prelude::Reader<'r> for RemoveTlcFailReader<'r> {
Expand All @@ -9455,36 +9523,82 @@ impl<'r> molecule::prelude::Reader<'r> for RemoveTlcFailReader<'r> {
fn as_slice(&self) -> &'r [u8] {
self.0
}
fn verify(slice: &[u8], _compatible: bool) -> molecule::error::VerificationResult<()> {
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);
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<usize> = 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);
}
Uint32Reader::verify(&slice[offsets[0]..offsets[1]], compatible)?;
BytesReader::verify(&slice[offsets[1]..offsets[2]], compatible)?;
Ok(())
}
}
#[derive(Clone, Debug, Default)]
pub struct RemoveTlcFailBuilder {
pub(crate) error_code: Uint32,
pub(crate) packet_data: Bytes,
}
impl RemoveTlcFailBuilder {
pub const TOTAL_SIZE: usize = 4;
pub const FIELD_SIZES: [usize; 1] = [4];
pub const FIELD_COUNT: usize = 1;
pub const FIELD_COUNT: usize = 2;
pub fn error_code(mut self, v: Uint32) -> Self {
self.error_code = v;
self
}
pub fn packet_data(mut self, v: Bytes) -> Self {
self.packet_data = v;
self
}
}
impl molecule::prelude::Builder for RemoveTlcFailBuilder {
type Entity = RemoveTlcFail;
const NAME: &'static str = "RemoveTlcFailBuilder";
fn expected_length(&self) -> usize {
Self::TOTAL_SIZE
molecule::NUMBER_SIZE * (Self::FIELD_COUNT + 1)
+ self.error_code.as_slice().len()
+ self.packet_data.as_slice().len()
}
fn write<W: molecule::io::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.packet_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.packet_data.as_slice())?;
Ok(())
}
fn build(&self) -> Self::Entity {
Expand Down
3 changes: 2 additions & 1 deletion src/fiber/schema/fiber.mol
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ struct RemoveTlcFulfill {
payment_preimage: Byte32,
}

struct RemoveTlcFail {
table RemoveTlcFail {
error_code: Uint32,
packet_data: Bytes,
}

union RemoveTlcReason {
Expand Down
6 changes: 4 additions & 2 deletions src/fiber/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1221,9 +1221,10 @@ impl TryFrom<molecule_fiber::RemoveTlcFulfill> for RemoveTlcFulfill {
}
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RemoveTlcFail {
pub error_code: u32,
pub packet_data: Vec<u8>,
}

impl From<RemoveTlcFail> for molecule_fiber::RemoveTlcFail {
Expand All @@ -1240,11 +1241,12 @@ impl TryFrom<molecule_fiber::RemoveTlcFail> for RemoveTlcFail {
fn try_from(remove_tlc_fail: molecule_fiber::RemoveTlcFail) -> Result<Self, Self::Error> {
Ok(RemoveTlcFail {
error_code: remove_tlc_fail.error_code().unpack(),
packet_data: remove_tlc_fail.packet_data().unpack(),
})
}
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum RemoveTlcReason {
RemoveTlcFulfill(RemoveTlcFulfill),
RemoveTlcFail(RemoveTlcFail),
Expand Down
5 changes: 4 additions & 1 deletion src/rpc/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,10 @@ where
}
RemoveTlcReason::RemoveTlcFail { error_code } => {
crate::fiber::types::RemoveTlcReason::RemoveTlcFail(
RemoveTlcFail { error_code },
RemoveTlcFail {
error_code,
packet_data: vec![],
},
)
}
},
Expand Down

0 comments on commit f144887

Please sign in to comment.