payment_hash: PaymentHash,
state: OutboundHTLCState,
source: HTLCSource,
+ blinding_point: Option<PublicKey>,
skimmed_fee_msat: Option<u64>,
}
onion_routing_packet: msgs::OnionPacket,
// The extra fee we're skimming off the top of this HTLC.
skimmed_fee_msat: Option<u64>,
+ blinding_point: Option<PublicKey>,
},
ClaimHTLC {
payment_preimage: PaymentPreimage,
source,
onion_routing_packet,
skimmed_fee_msat,
+ blinding_point: None,
});
return Ok(None);
}
cltv_expiry,
state: OutboundHTLCState::LocalAnnounced(Box::new(onion_routing_packet.clone())),
source,
+ blinding_point: None,
skimmed_fee_msat,
});
let mut preimages: Vec<&Option<PaymentPreimage>> = vec![];
let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
+ let mut pending_outbound_blinding_points: Vec<Option<PublicKey>> = Vec::new();
(self.context.pending_outbound_htlcs.len() as u64).write(writer)?;
for (idx, htlc) in self.context.pending_outbound_htlcs.iter().enumerate() {
} else if !pending_outbound_skimmed_fees.is_empty() {
pending_outbound_skimmed_fees.push(None);
}
+ pending_outbound_blinding_points.push(htlc.blinding_point);
}
let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
+ let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
(self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
for (idx, update) in self.context.holding_cell_htlc_updates.iter().enumerate() {
match update {
&HTLCUpdateAwaitingACK::AddHTLC {
ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet,
- skimmed_fee_msat,
+ blinding_point, skimmed_fee_msat,
} => {
0u8.write(writer)?;
amount_msat.write(writer)?;
}
holding_cell_skimmed_fees.push(Some(skimmed_fee));
} else if !holding_cell_skimmed_fees.is_empty() { holding_cell_skimmed_fees.push(None); }
+
+ holding_cell_blinding_points.push(blinding_point);
},
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, ref htlc_id } => {
1u8.write(writer)?;
(35, pending_outbound_skimmed_fees, optional_vec),
(37, holding_cell_skimmed_fees, optional_vec),
(38, self.context.is_batch_funding, option),
+ (39, pending_outbound_blinding_points, optional_vec),
+ (41, holding_cell_blinding_points, optional_vec),
});
Ok(())
_ => return Err(DecodeError::InvalidValue),
},
skimmed_fee_msat: None,
+ blinding_point: None,
});
}
source: Readable::read(reader)?,
onion_routing_packet: Readable::read(reader)?,
skimmed_fee_msat: None,
+ blinding_point: None,
},
1 => HTLCUpdateAwaitingACK::ClaimHTLC {
payment_preimage: Readable::read(reader)?,
let mut is_batch_funding: Option<()> = None;
+ let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
+ let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
+
read_tlv_fields!(reader, {
(0, announcement_sigs, option),
(1, minimum_depth, option),
(35, pending_outbound_skimmed_fees_opt, optional_vec),
(37, holding_cell_skimmed_fees_opt, optional_vec),
(38, is_batch_funding, option),
+ (39, pending_outbound_blinding_points_opt, optional_vec),
+ (41, holding_cell_blinding_points_opt, optional_vec),
});
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
// We expect all skimmed fees to be consumed above
if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
}
+ if let Some(blinding_pts) = pending_outbound_blinding_points_opt {
+ let mut iter = blinding_pts.into_iter();
+ for htlc in pending_outbound_htlcs.iter_mut() {
+ htlc.blinding_point = iter.next().ok_or(DecodeError::InvalidValue)?;
+ }
+ // We expect all blinding points to be consumed above
+ if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
+ }
+ if let Some(blinding_pts) = holding_cell_blinding_points_opt {
+ let mut iter = blinding_pts.into_iter();
+ for htlc in holding_cell_htlc_updates.iter_mut() {
+ if let HTLCUpdateAwaitingACK::AddHTLC { ref mut blinding_point, .. } = htlc {
+ *blinding_point = iter.next().ok_or(DecodeError::InvalidValue)?;
+ }
+ }
+ // We expect all blinding points to be consumed above
+ if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
+ }
Ok(Channel {
context: ChannelContext {
payment_id: PaymentId([42; 32]),
},
skimmed_fee_msat: None,
+ blinding_point: None,
});
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
state: OutboundHTLCState::Committed,
source: HTLCSource::dummy(),
skimmed_fee_msat: None,
+ blinding_point: None,
};
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).to_byte_array();
out
state: OutboundHTLCState::Committed,
source: HTLCSource::dummy(),
skimmed_fee_msat: None,
+ blinding_point: None,
};
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).to_byte_array();
out
state: OutboundHTLCState::Committed,
source: HTLCSource::dummy(),
skimmed_fee_msat: None,
+ blinding_point: None,
};
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
out
state: OutboundHTLCState::Committed,
source: HTLCSource::dummy(),
skimmed_fee_msat: None,
+ blinding_point: None,
};
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
out