From 4146fd6b6718102fa82536a558f379c14e36592e Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Thu, 22 Nov 2018 21:18:16 -0500 Subject: [PATCH] Typify payment_hash and payment_preimage Fix variable name as payment_hash instead of txid for index of remote_hash_commitment_number in ChannelMonitor reader --- fuzz/fuzz_targets/full_stack_target.rs | 18 +++--- src/ln/chan_utils.rs | 6 +- src/ln/channel.rs | 90 +++++++++++++------------- src/ln/channelmanager.rs | 63 ++++++++++-------- src/ln/channelmonitor.rs | 63 +++++++++--------- src/ln/msgs.rs | 6 +- src/util/events.rs | 7 +- src/util/ser.rs | 27 ++++++++ src/util/test_utils.rs | 4 +- 9 files changed, 163 insertions(+), 121 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 354625604..9756ed316 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -17,7 +17,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,C use lightning::chain::transaction::OutPoint; use lightning::chain::keysinterface::{ChannelKeys, KeysInterface}; use lightning::ln::channelmonitor; -use lightning::ln::channelmanager::{ChannelManager, PaymentFailReason}; +use lightning::ln::channelmanager::{ChannelManager, PaymentFailReason, PaymentHash, PaymentPreimage}; use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; use lightning::ln::router::Router; use lightning::util::events::{EventsProvider,Event}; @@ -328,7 +328,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { }, our_network_key, Arc::clone(&logger))); let mut should_forward = false; - let mut payments_received: Vec<[u8; 32]> = Vec::new(); + let mut payments_received: Vec = Vec::new(); let mut payments_sent = 0; let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new(); let mut pending_funding_signatures = HashMap::new(); @@ -380,11 +380,11 @@ pub fn do_test(data: &[u8], logger: &Arc) { Ok(route) => route, Err(_) => return, }; - let mut payment_hash = [0; 32]; - payment_hash[0..8].copy_from_slice(&be64_to_array(payments_sent)); + let mut payment_hash = PaymentHash([0; 32]); + payment_hash.0[0..8].copy_from_slice(&be64_to_array(payments_sent)); let mut sha = Sha256::new(); - sha.input(&payment_hash); - sha.result(&mut payment_hash); + sha.input(&payment_hash.0[..]); + sha.result(&mut payment_hash.0[..]); payments_sent += 1; match channelmanager.send_payment(route, payment_hash) { Ok(_) => {}, @@ -418,11 +418,11 @@ pub fn do_test(data: &[u8], logger: &Arc) { // for the remaining bytes. Thus, if not all remaining bytes are 0s we cannot // fulfill this HTLC, but if they are, we can just take the first byte and // place that anywhere in our preimage. - if &payment[1..] != &[0; 31] { + if &payment.0[1..] != &[0; 31] { channelmanager.fail_htlc_backwards(&payment, PaymentFailReason::PreimageUnknown); } else { - let mut payment_preimage = [0; 32]; - payment_preimage[0] = payment[0]; + let mut payment_preimage = PaymentPreimage([0; 32]); + payment_preimage.0[0] = payment.0[0]; channelmanager.claim_funds(payment_preimage); } } diff --git a/src/ln/chan_utils.rs b/src/ln/chan_utils.rs index 7f259d981..dbd6bdccc 100644 --- a/src/ln/chan_utils.rs +++ b/src/ln/chan_utils.rs @@ -3,6 +3,8 @@ use bitcoin::blockdata::opcodes; use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction}; use bitcoin::util::hash::{Hash160,Sha256dHash}; +use ln::channelmanager::PaymentHash; + use secp256k1::key::{PublicKey,SecretKey}; use secp256k1::Secp256k1; use secp256k1; @@ -156,7 +158,7 @@ pub struct HTLCOutputInCommitment { pub offered: bool, pub amount_msat: u64, pub cltv_expiry: u32, - pub payment_hash: [u8; 32], + pub payment_hash: PaymentHash, pub transaction_output_index: u32, } @@ -164,7 +166,7 @@ pub struct HTLCOutputInCommitment { pub fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, a_htlc_key: &PublicKey, b_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script { let payment_hash160 = { let mut ripemd = Ripemd160::new(); - ripemd.input(&htlc.payment_hash); + ripemd.input(&htlc.payment_hash.0[..]); let mut res = [0; 20]; ripemd.result(&mut res); res diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 6be2bb69c..c229622c0 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -15,7 +15,7 @@ use crypto::digest::Digest; use ln::msgs; use ln::msgs::DecodeError; use ln::channelmonitor::ChannelMonitor; -use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder}; +use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash}; use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT}; use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; @@ -48,7 +48,7 @@ pub struct ChannelValueStat { enum InboundHTLCRemovalReason { FailRelay(msgs::OnionErrorPacket), FailMalformed(([u8; 32], u16)), - Fulfill([u8; 32]), + Fulfill(PaymentPreimage), } enum InboundHTLCState { @@ -84,7 +84,7 @@ struct InboundHTLCOutput { htlc_id: u64, amount_msat: u64, cltv_expiry: u32, - payment_hash: [u8; 32], + payment_hash: PaymentHash, state: InboundHTLCState, } @@ -124,7 +124,7 @@ struct OutboundHTLCOutput { htlc_id: u64, amount_msat: u64, cltv_expiry: u32, - payment_hash: [u8; 32], + payment_hash: PaymentHash, state: OutboundHTLCState, source: HTLCSource, /// If we're in a removed state, set if they failed, otherwise None @@ -149,13 +149,13 @@ enum HTLCUpdateAwaitingACK { // always outbound amount_msat: u64, cltv_expiry: u32, - payment_hash: [u8; 32], + payment_hash: PaymentHash, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, time_created: Instant, //TODO: Some kind of timeout thing-a-majig }, ClaimHTLC { - payment_preimage: [u8; 32], + payment_preimage: PaymentPreimage, htlc_id: u64, }, FailHTLC { @@ -263,7 +263,7 @@ pub(super) struct Channel { monitor_pending_commitment_signed: bool, monitor_pending_order: Option, monitor_pending_forwards: Vec<(PendingForwardHTLCInfo, u64)>, - monitor_pending_failures: Vec<(HTLCSource, [u8; 32], HTLCFailReason)>, + monitor_pending_failures: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, // pending_update_fee is filled when sending and receiving update_fee // For outbound channel, feerate_per_kw is updated with the value from @@ -1091,7 +1091,7 @@ impl Channel { /// Signs a transaction created by build_htlc_transaction. If the transaction is an /// HTLC-Success transaction (ie htlc.offered is false), preimate must be set! - fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option<[u8; 32]>, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result { + fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result { if tx.input.len() != 1 { panic!("Tried to sign HTLC transaction that had input count != 1!"); } @@ -1116,7 +1116,7 @@ impl Channel { if htlc.offered { tx.input[0].witness.push(Vec::new()); } else { - tx.input[0].witness.push(preimage.unwrap().to_vec()); + tx.input[0].witness.push(preimage.unwrap().0.to_vec()); } tx.input[0].witness.push(htlc_redeemscript.into_bytes()); @@ -1127,7 +1127,7 @@ impl Channel { /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made. /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return /// Ok(_) if debug assertions are turned on and preconditions are met. - fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: [u8; 32]) -> Result<(Option, Option), ChannelError> { + fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage) -> Result<(Option, Option), ChannelError> { // Either ChannelFunded got set (which means it wont bet unset) or there is no way any // caller thought we could have something claimed (cause we wouldn't have accepted in an // incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us, @@ -1138,9 +1138,9 @@ impl Channel { assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0); let mut sha = Sha256::new(); - sha.input(&payment_preimage_arg); - let mut payment_hash_calc = [0; 32]; - sha.result(&mut payment_hash_calc); + sha.input(&payment_preimage_arg.0[..]); + let mut payment_hash_calc = PaymentHash([0; 32]); + sha.result(&mut payment_hash_calc.0[..]); let mut pending_idx = std::usize::MAX; for (idx, htlc) in self.pending_inbound_htlcs.iter().enumerate() { @@ -1216,7 +1216,7 @@ impl Channel { }), Some(self.channel_monitor.clone()))) } - pub fn get_update_fulfill_htlc_and_commit(&mut self, htlc_id: u64, payment_preimage: [u8; 32]) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option), ChannelError> { + pub fn get_update_fulfill_htlc_and_commit(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option), ChannelError> { match self.get_update_fulfill_htlc(htlc_id, payment_preimage)? { (Some(update_fulfill_htlc), _) => { let (commitment, monitor_update) = self.send_commitment_no_status_check()?; @@ -1599,7 +1599,7 @@ impl Channel { /// Marks an outbound HTLC which we have received update_fail/fulfill/malformed #[inline] - fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>, fail_reason: Option) -> Result<&HTLCSource, ChannelError> { + fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option, fail_reason: Option) -> Result<&HTLCSource, ChannelError> { for htlc in self.pending_outbound_htlcs.iter_mut() { if htlc.htlc_id == htlc_id { match check_preimage { @@ -1634,9 +1634,9 @@ impl Channel { } let mut sha = Sha256::new(); - sha.input(&msg.payment_preimage); - let mut payment_hash = [0; 32]; - sha.result(&mut payment_hash); + sha.input(&msg.payment_preimage.0[..]); + let mut payment_hash = PaymentHash([0; 32]); + sha.result(&mut payment_hash.0[..]); self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None).map(|source| source.clone()) } @@ -1817,16 +1817,16 @@ impl Channel { self.holding_cell_htlc_updates.push(htlc_update); } else { match &htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, payment_hash, ref source, ref onion_routing_packet, ..} => { - match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) { + &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => { + match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) { Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), Err(e) => { err = Some(e); } } }, - &HTLCUpdateAwaitingACK::ClaimHTLC { payment_preimage, htlc_id, .. } => { - match self.get_update_fulfill_htlc(htlc_id, payment_preimage) { + &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => { + match self.get_update_fulfill_htlc(htlc_id, *payment_preimage) { Ok(update_fulfill_msg_option) => update_fulfill_htlcs.push(update_fulfill_msg_option.0.unwrap()), Err(e) => { if let ChannelError::Ignore(_) = e {} @@ -1894,7 +1894,7 @@ impl Channel { /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail, /// generating an appropriate error *after* the channel state has been updated based on the /// revoke_and_ack message. - pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &FeeEstimator) -> Result<(Option, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, [u8; 32], HTLCFailReason)>, Option, ChannelMonitor), ChannelError> { + pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &FeeEstimator) -> Result<(Option, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option, ChannelMonitor), ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Close("Got revoke/ACK message when channel was not in an operational state")); } @@ -2104,7 +2104,7 @@ impl Channel { /// implicitly dropping) and the payment_hashes of HTLCs we tried to add but are dropping. /// No further message handling calls may be made until a channel_reestablish dance has /// completed. - pub fn remove_uncommitted_htlcs_and_mark_paused(&mut self) -> Vec<(HTLCSource, [u8; 32])> { + pub fn remove_uncommitted_htlcs_and_mark_paused(&mut self) -> Vec<(HTLCSource, PaymentHash)> { let mut outbound_drops = Vec::new(); assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0); @@ -2193,7 +2193,7 @@ impl Channel { /// Indicates that the latest ChannelMonitor update has been committed by the client /// successfully and we should restore normal operation. Returns messages which should be sent /// to the remote side. - pub fn monitor_updating_restored(&mut self) -> (Option, Option, RAACommitmentOrder, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, [u8; 32], HTLCFailReason)>) { + pub fn monitor_updating_restored(&mut self) -> (Option, Option, RAACommitmentOrder, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>) { assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, ChannelState::MonitorUpdateFailed as u32); self.channel_state &= !(ChannelState::MonitorUpdateFailed as u32); @@ -2449,7 +2449,7 @@ impl Channel { }) } - pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, [u8; 32])>), ChannelError> { + pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, PaymentHash)>), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent shutdown when we needed a channel_reestablish")); } @@ -3093,7 +3093,7 @@ impl Channel { /// waiting on the remote peer to send us a revoke_and_ack during which time we cannot add new /// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed. /// You MUST call send_commitment prior to any other calls on this Channel - pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: [u8; 32], cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { + pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { if (self.channel_state & (ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelFunded as u32) { return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down")); } @@ -3278,7 +3278,7 @@ impl Channel { /// to send to the remote peer in one go. /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for /// more info. - pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: [u8; 32], cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { + pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result, ChannelError> { match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet)? { Some(update_add_htlc) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?; @@ -3290,7 +3290,7 @@ impl Channel { /// Begins the shutdown process, getting a message for the remote peer and returning all /// holding cell HTLCs for payment failure. - pub fn get_shutdown(&mut self) -> Result<(msgs::Shutdown, Vec<(HTLCSource, [u8; 32])>), APIError> { + pub fn get_shutdown(&mut self) -> Result<(msgs::Shutdown, Vec<(HTLCSource, PaymentHash)>), APIError> { for htlc in self.pending_outbound_htlcs.iter() { if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { return Err(APIError::APIMisuseError{err: "Cannot begin shutdown with pending HTLCs. Process pending events first"}); @@ -3344,7 +3344,7 @@ impl Channel { /// those explicitly stated to be allowed after shutdown completes, eg some simple getters). /// Also returns the list of payment_hashes for channels which we can safely fail backwards /// immediately (others we will have to allow to time out). - pub fn force_shutdown(&mut self) -> (Vec, Vec<(HTLCSource, [u8; 32])>) { + pub fn force_shutdown(&mut self) -> (Vec, Vec<(HTLCSource, PaymentHash)>) { assert!(self.channel_state != ChannelState::ShutdownComplete as u32); // We go ahead and "free" any holding cell HTLCs or HTLCs we haven't yet committed to and @@ -3873,7 +3873,7 @@ mod tests { use bitcoin::blockdata::transaction::Transaction; use bitcoin::blockdata::opcodes; use hex; - use ln::channelmanager::HTLCSource; + use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash}; use ln::channel::{Channel,ChannelKeys,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,TxCreationKeys}; use ln::channel::MAX_FUNDING_SATOSHIS; use ln::chan_utils; @@ -4006,17 +4006,17 @@ mod tests { let htlc_sighash = Message::from_slice(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]).unwrap(); secp_ctx.verify(&htlc_sighash, &remote_signature, &keys.b_htlc_key).unwrap(); - let mut preimage: Option<[u8; 32]> = None; + let mut preimage: Option = None; if !htlc.offered { for i in 0..5 { let mut sha = Sha256::new(); sha.input(&[i; 32]); - let mut out = [0; 32]; - sha.result(&mut out); + let mut out = PaymentHash([0; 32]); + sha.result(&mut out.0[..]); if out == htlc.payment_hash { - preimage = Some([i; 32]); + preimage = Some(PaymentPreimage([i; 32])); } } @@ -4043,12 +4043,12 @@ mod tests { htlc_id: 0, amount_msat: 1000000, cltv_expiry: 500, - payment_hash: [0; 32], + payment_hash: PaymentHash([0; 32]), state: InboundHTLCState::Committed, }; let mut sha = Sha256::new(); sha.input(&hex::decode("0000000000000000000000000000000000000000000000000000000000000000").unwrap()); - sha.result(&mut out.payment_hash); + sha.result(&mut out.payment_hash.0[..]); out }); chan.pending_inbound_htlcs.push({ @@ -4056,12 +4056,12 @@ mod tests { htlc_id: 1, amount_msat: 2000000, cltv_expiry: 501, - payment_hash: [0; 32], + payment_hash: PaymentHash([0; 32]), state: InboundHTLCState::Committed, }; let mut sha = Sha256::new(); sha.input(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()); - sha.result(&mut out.payment_hash); + sha.result(&mut out.payment_hash.0[..]); out }); chan.pending_outbound_htlcs.push({ @@ -4069,14 +4069,14 @@ mod tests { htlc_id: 2, amount_msat: 2000000, cltv_expiry: 502, - payment_hash: [0; 32], + payment_hash: PaymentHash([0; 32]), state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), fail_reason: None, }; let mut sha = Sha256::new(); sha.input(&hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap()); - sha.result(&mut out.payment_hash); + sha.result(&mut out.payment_hash.0[..]); out }); chan.pending_outbound_htlcs.push({ @@ -4084,14 +4084,14 @@ mod tests { htlc_id: 3, amount_msat: 3000000, cltv_expiry: 503, - payment_hash: [0; 32], + payment_hash: PaymentHash([0; 32]), state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), fail_reason: None, }; let mut sha = Sha256::new(); sha.input(&hex::decode("0303030303030303030303030303030303030303030303030303030303030303").unwrap()); - sha.result(&mut out.payment_hash); + sha.result(&mut out.payment_hash.0[..]); out }); chan.pending_inbound_htlcs.push({ @@ -4099,12 +4099,12 @@ mod tests { htlc_id: 4, amount_msat: 4000000, cltv_expiry: 504, - payment_hash: [0; 32], + payment_hash: PaymentHash([0; 32]), state: InboundHTLCState::Committed, }; let mut sha = Sha256::new(); sha.input(&hex::decode("0404040404040404040404040404040404040404040404040404040404040404").unwrap()); - sha.result(&mut out.payment_hash); + sha.result(&mut out.payment_hash.0[..]); out }); diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index bfe3c5a9a..f1cf21352 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -63,6 +63,7 @@ use std::time::{Instant,Duration}; mod channel_held_info { use ln::msgs; use ln::router::Route; + use ln::channelmanager::PaymentHash; use secp256k1::key::SecretKey; /// Stores the info we will need to send when we want to forward an HTLC onwards @@ -70,7 +71,7 @@ mod channel_held_info { pub struct PendingForwardHTLCInfo { pub(super) onion_packet: Option, pub(super) incoming_shared_secret: [u8; 32], - pub(super) payment_hash: [u8; 32], + pub(super) payment_hash: PaymentHash, pub(super) short_channel_id: u64, pub(super) amt_to_forward: u64, pub(super) outgoing_cltv_value: u32, @@ -133,13 +134,21 @@ mod channel_held_info { } pub(crate) use self::channel_held_info::*; -type ShutdownResult = (Vec, Vec<(HTLCSource, [u8; 32])>); +/// payment_hash type, use to cross-lock hop +#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] +pub struct PaymentHash(pub [u8;32]); +/// payment_preimage type, use to route payment between hop +#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] +pub struct PaymentPreimage(pub [u8;32]); + +type ShutdownResult = (Vec, Vec<(HTLCSource, PaymentHash)>); /// Error type returned across the channel_state mutex boundary. When an Err is generated for a /// Channel, we generally end up with a ChannelError::Close for which we have to close the channel /// immediately (ie with no further calls on it made). Thus, this step happens inside a /// channel_state lock. We then return the set of things that need to be done outside the lock in /// this struct and call handle_error!() on it. + struct MsgHandleErrInternal { err: msgs::HandleError, shutdown_finish: Option<(ShutdownResult, Option)>, @@ -248,7 +257,7 @@ struct ChannelHolder { /// Note that while this is held in the same mutex as the channels themselves, no consistency /// guarantees are made about the channels given here actually existing anymore by the time you /// go to read them! - claimable_htlcs: HashMap<[u8; 32], Vec>, + claimable_htlcs: HashMap>, /// Messages to send to peers - pushed to in the same lock that they are generated in (except /// for broadcast messages, where ordering isn't as strict). pending_msg_events: Vec, @@ -258,7 +267,7 @@ struct MutChannelHolder<'a> { short_to_id: &'a mut HashMap, next_forward: &'a mut Instant, forward_htlcs: &'a mut HashMap>, - claimable_htlcs: &'a mut HashMap<[u8; 32], Vec>, + claimable_htlcs: &'a mut HashMap>, pending_msg_events: &'a mut Vec, } impl ChannelHolder { @@ -831,7 +840,7 @@ impl ChannelManager { } const ZERO:[u8; 21*65] = [0; 21*65]; - fn construct_onion_packet(mut payloads: Vec, onion_keys: Vec, associated_data: &[u8; 32]) -> msgs::OnionPacket { + fn construct_onion_packet(mut payloads: Vec, onion_keys: Vec, associated_data: &PaymentHash) -> msgs::OnionPacket { let mut buf = Vec::with_capacity(21*65); buf.resize(21*65, 0); @@ -868,7 +877,7 @@ impl ChannelManager { let mut hmac = Hmac::new(Sha256::new(), &keys.mu); hmac.input(&packet_data); - hmac.input(&associated_data[..]); + hmac.input(&associated_data.0[..]); hmac.raw_result(&mut hmac_res); } @@ -990,7 +999,7 @@ impl ChannelManager { let mut hmac = Hmac::new(Sha256::new(), &mu); hmac.input(&msg.onion_routing_packet.hop_data); - hmac.input(&msg.payment_hash); + hmac.input(&msg.payment_hash.0[..]); if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) { return_err!("HMAC Check failed", 0x8000 | 0x4000 | 5, &get_onion_hash!()); } @@ -1188,7 +1197,7 @@ impl ChannelManager { /// /// Raises APIError::RoutError when invalid route or forward parameter /// (cltv_delta, fee, node public key) is specified - pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<(), APIError> { + pub fn send_payment(&self, route: Route, payment_hash: PaymentHash) -> Result<(), APIError> { if route.hops.len() < 1 || route.hops.len() > 20 { return Err(APIError::RouteError{err: "Route didn't go anywhere/had bogus size"}); } @@ -1482,7 +1491,7 @@ impl ChannelManager { } /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect after a PaymentReceived event. - pub fn fail_htlc_backwards(&self, payment_hash: &[u8; 32], reason: PaymentFailReason) -> bool { + pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, reason: PaymentFailReason) -> bool { let _ = self.total_consistency_lock.read().unwrap(); let mut channel_state = Some(self.channel_state.lock().unwrap()); @@ -1502,7 +1511,7 @@ impl ChannelManager { /// to fail and take the channel_state lock for each iteration (as we take ownership and may /// drop it). In other words, no assumptions are made that entries in claimable_htlcs point to /// still-available channels. - fn fail_htlc_backwards_internal(&self, mut channel_state_lock: MutexGuard, source: HTLCSource, payment_hash: &[u8; 32], onion_error: HTLCFailReason) { + fn fail_htlc_backwards_internal(&self, mut channel_state_lock: MutexGuard, source: HTLCSource, payment_hash: &PaymentHash, onion_error: HTLCFailReason) { match source { HTLCSource::OutboundRoute { .. } => { mem::drop(channel_state_lock); @@ -1575,11 +1584,11 @@ impl ChannelManager { /// should probably kick the net layer to go send messages if this returns true! /// /// May panic if called except in response to a PaymentReceived event. - pub fn claim_funds(&self, payment_preimage: [u8; 32]) -> bool { + pub fn claim_funds(&self, payment_preimage: PaymentPreimage) -> bool { let mut sha = Sha256::new(); - sha.input(&payment_preimage); - let mut payment_hash = [0; 32]; - sha.result(&mut payment_hash); + sha.input(&payment_preimage.0[..]); + let mut payment_hash = PaymentHash([0; 32]); + sha.result(&mut payment_hash.0[..]); let _ = self.total_consistency_lock.read().unwrap(); @@ -1593,7 +1602,7 @@ impl ChannelManager { true } else { false } } - fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard, source: HTLCSource, payment_preimage: [u8; 32]) { + fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard, source: HTLCSource, payment_preimage: PaymentPreimage) { match source { HTLCSource::OutboundRoute { .. } => { mem::drop(channel_state_lock); @@ -3280,7 +3289,7 @@ mod tests { use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor}; use chain::keysinterface; use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC}; - use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,PaymentFailReason,RAACommitmentOrder}; + use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,PaymentFailReason,RAACommitmentOrder, PaymentPreimage, PaymentHash}; use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS, ManyChannelMonitor}; use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT}; use ln::router::{Route, RouteHop, Router}; @@ -3443,7 +3452,7 @@ mod tests { }, ); - let packet = ChannelManager::construct_onion_packet(payloads, onion_keys, &[0x42; 32]); + let packet = ChannelManager::construct_onion_packet(payloads, onion_keys, &PaymentHash([0x42; 32])); // Just check the final packet encoding, as it includes all the per-hop vectors in it // anyway... assert_eq!(packet.encode(), hex::decode("0002eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619e5f14350c2a76fc232b5e46d421e9615471ab9e0bc887beff8c95fdb878f7b3a716a996c7845c93d90e4ecbb9bde4ece2f69425c99e4bc820e44485455f135edc0d10f7d61ab590531cf08000179a333a347f8b4072f216400406bdf3bf038659793d4a1fd7b246979e3150a0a4cb052c9ec69acf0f48c3d39cd55675fe717cb7d80ce721caad69320c3a469a202f1e468c67eaf7a7cd8226d0fd32f7b48084dca885d56047694762b67021713ca673929c163ec36e04e40ca8e1c6d17569419d3039d9a1ec866abe044a9ad635778b961fc0776dc832b3a451bd5d35072d2269cf9b040f6b7a7dad84fb114ed413b1426cb96ceaf83825665ed5a1d002c1687f92465b49ed4c7f0218ff8c6c7dd7221d589c65b3b9aaa71a41484b122846c7c7b57e02e679ea8469b70e14fe4f70fee4d87b910cf144be6fe48eef24da475c0b0bcc6565ae82cd3f4e3b24c76eaa5616c6111343306ab35c1fe5ca4a77c0e314ed7dba39d6f1e0de791719c241a939cc493bea2bae1c1e932679ea94d29084278513c77b899cc98059d06a27d171b0dbdf6bee13ddc4fc17a0c4d2827d488436b57baa167544138ca2e64a11b43ac8a06cd0c2fba2d4d900ed2d9205305e2d7383cc98dacb078133de5f6fb6bed2ef26ba92cea28aafc3b9948dd9ae5559e8bd6920b8cea462aa445ca6a95e0e7ba52961b181c79e73bd581821df2b10173727a810c92b83b5ba4a0403eb710d2ca10689a35bec6c3a708e9e92f7d78ff3c5d9989574b00c6736f84c199256e76e19e78f0c98a9d580b4a658c84fc8f2096c2fbea8f5f8c59d0fdacb3be2802ef802abbecb3aba4acaac69a0e965abd8981e9896b1f6ef9d60f7a164b371af869fd0e48073742825e9434fc54da837e120266d53302954843538ea7c6c3dbfb4ff3b2fdbe244437f2a153ccf7bdb4c92aa08102d4f3cff2ae5ef86fab4653595e6a5837fa2f3e29f27a9cde5966843fb847a4a61f1e76c281fe8bb2b0a181d096100db5a1a5ce7a910238251a43ca556712eaadea167fb4d7d75825e440f3ecd782036d7574df8bceacb397abefc5f5254d2722215c53ff54af8299aaaad642c6d72a14d27882d9bbd539e1cc7a527526ba89b8c037ad09120e98ab042d3e8652b31ae0e478516bfaf88efca9f3676ffe99d2819dcaeb7610a626695f53117665d267d3f7abebd6bbd6733f645c72c389f03855bdf1e4b8075b516569b118233a0f0971d24b83113c0b096f5216a207ca99a7cddc81c130923fe3d91e7508c9ac5f2e914ff5dccab9e558566fa14efb34ac98d878580814b94b73acbfde9072f30b881f7f0fff42d4045d1ace6322d86a97d164aa84d93a60498065cc7c20e636f5862dc81531a88c60305a2e59a985be327a6902e4bed986dbf4a0b50c217af0ea7fdf9ab37f9ea1a1aaa72f54cf40154ea9b269f1a7c09f9f43245109431a175d50e2db0132337baa0ef97eed0fcf20489da36b79a1172faccc2f7ded7c60e00694282d93359c4682135642bc81f433574aa8ef0c97b4ade7ca372c5ffc23c7eddd839bab4e0f14d6df15c9dbeab176bec8b5701cf054eb3072f6dadc98f88819042bf10c407516ee58bce33fbe3b3d86a54255e577db4598e30a135361528c101683a5fcde7e8ba53f3456254be8f45fe3a56120ae96ea3773631fcb3873aa3abd91bcff00bd38bd43697a2e789e00da6077482e7b1b1a677b5afae4c54e6cbdf7377b694eb7d7a5b913476a5be923322d3de06060fd5e819635232a2cf4f0731da13b8546d1d6d4f8d75b9fce6c2341a71b0ea6f780df54bfdb0dd5cd9855179f602f9172307c7268724c3618e6817abd793adc214a0dc0bc616816632f27ea336fb56dfd").unwrap()); @@ -3924,18 +3933,18 @@ mod tests { macro_rules! get_payment_preimage_hash { ($node: expr) => { { - let payment_preimage = [*$node.network_payment_count.borrow(); 32]; + let payment_preimage = PaymentPreimage([*$node.network_payment_count.borrow(); 32]); *$node.network_payment_count.borrow_mut() += 1; - let mut payment_hash = [0; 32]; + let mut payment_hash = PaymentHash([0; 32]); let mut sha = Sha256::new(); - sha.input(&payment_preimage[..]); - sha.result(&mut payment_hash); + sha.input(&payment_preimage.0[..]); + sha.result(&mut payment_hash.0[..]); (payment_preimage, payment_hash) } } } - fn send_along_route(origin_node: &Node, route: Route, expected_route: &[&Node], recv_value: u64) -> ([u8; 32], [u8; 32]) { + fn send_along_route(origin_node: &Node, route: Route, expected_route: &[&Node], recv_value: u64) -> (PaymentPreimage, PaymentHash) { let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(origin_node); let mut payment_event = { @@ -3989,7 +3998,7 @@ mod tests { (our_payment_preimage, our_payment_hash) } - fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: [u8; 32]) { + fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: PaymentPreimage) { assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage)); check_added_monitors!(expected_route.last().unwrap(), 1); @@ -4074,13 +4083,13 @@ mod tests { } } - fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: [u8; 32]) { + fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: PaymentPreimage) { claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage); } const TEST_FINAL_CLTV: u32 = 32; - fn route_payment(origin_node: &Node, expected_route: &[&Node], recv_value: u64) -> ([u8; 32], [u8; 32]) { + fn route_payment(origin_node: &Node, expected_route: &[&Node], recv_value: u64) -> (PaymentPreimage, PaymentHash) { let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), None, &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap(); assert_eq!(route.hops.len(), expected_route.len()); for (node, hop) in expected_route.iter().zip(route.hops.iter()) { @@ -4111,7 +4120,7 @@ mod tests { claim_payment(&origin, expected_route, our_payment_preimage); } - fn fail_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_hash: [u8; 32]) { + fn fail_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_hash: PaymentHash) { assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, PaymentFailReason::PreimageUnknown)); check_added_monitors!(expected_route.last().unwrap(), 1); @@ -4176,7 +4185,7 @@ mod tests { } } - fn fail_payment(origin_node: &Node, expected_route: &[&Node], our_payment_hash: [u8; 32]) { + fn fail_payment(origin_node: &Node, expected_route: &[&Node], our_payment_hash: PaymentHash) { fail_payment_along_route(origin_node, expected_route, false, our_payment_hash); } diff --git a/src/ln/channelmonitor.rs b/src/ln/channelmonitor.rs index 86b7ea17f..5c5c0c73c 100644 --- a/src/ln/channelmonitor.rs +++ b/src/ln/channelmonitor.rs @@ -29,7 +29,7 @@ use secp256k1; use ln::msgs::DecodeError; use ln::chan_utils; use ln::chan_utils::HTLCOutputInCommitment; -use ln::channelmanager::{HTLCSource, HTLCPreviousHopData}; +use ln::channelmanager::{HTLCSource, HTLCPreviousHopData, PaymentPreimage, PaymentHash}; use ln::router::{Route, RouteHop}; use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT}; use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface}; @@ -104,7 +104,7 @@ pub trait ManyChannelMonitor: Send + Sync { /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated /// with success or failure backward - fn fetch_pending_htlc_updated(&self) -> Vec<([u8; 32], Option<[u8; 32]>, Option)>; + fn fetch_pending_htlc_updated(&self) -> Vec<(PaymentHash, Option, Option)>; } /// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a @@ -126,7 +126,7 @@ pub struct SimpleManyChannelMonitor { chain_monitor: Arc, broadcaster: Arc, pending_events: Mutex>, - pending_htlc_updated: Mutex, Option)>>>, + pending_htlc_updated: Mutex, Option)>>>, logger: Arc, } @@ -286,7 +286,7 @@ impl ManyChannelMonitor for SimpleManyChannelMonitor { } } - fn fetch_pending_htlc_updated(&self) -> Vec<([u8; 32], Option<[u8; 32]>, Option)> { + fn fetch_pending_htlc_updated(&self) -> Vec<(PaymentHash, Option, Option)> { let mut updated = self.pending_htlc_updated.lock().unwrap(); let mut pending_htlcs_updated = Vec::with_capacity(updated.len()); for (k, v) in updated.drain() { @@ -386,7 +386,7 @@ pub struct ChannelMonitor { /// Maps payment_hash values to commitment numbers for remote transactions for non-revoked /// remote transactions (ie should remain pretty small). /// Serialized to disk but should generally not be sent to Watchtowers. - remote_hash_commitment_number: HashMap<[u8; 32], u64>, + remote_hash_commitment_number: HashMap, // We store two local commitment transactions to avoid any race conditions where we may update // some monitors (potentially on watchtowers) but then fail to update others, resulting in the @@ -399,7 +399,7 @@ pub struct ChannelMonitor { // deserialization current_remote_commitment_number: u64, - payment_preimages: HashMap<[u8; 32], [u8; 32]>, + payment_preimages: HashMap, destination_script: Script, @@ -639,7 +639,7 @@ impl ChannelMonitor { /// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all /// commitment_tx_infos which contain the payment hash have been revoked. - pub(super) fn provide_payment_preimage(&mut self, payment_hash: &[u8; 32], payment_preimage: &[u8; 32]) { + pub(super) fn provide_payment_preimage(&mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage) { self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone()); } @@ -936,7 +936,7 @@ impl ChannelMonitor { writer.write_all(&[$htlc_output.offered as u8; 1])?; writer.write_all(&byte_utils::be64_to_array($htlc_output.amount_msat))?; writer.write_all(&byte_utils::be32_to_array($htlc_output.cltv_expiry))?; - writer.write_all(&$htlc_output.payment_hash)?; + writer.write_all(&$htlc_output.payment_hash.0[..])?; writer.write_all(&byte_utils::be32_to_array($htlc_output.transaction_output_index))?; } } @@ -1008,7 +1008,7 @@ impl ChannelMonitor { if for_local_storage { writer.write_all(&byte_utils::be64_to_array(self.remote_hash_commitment_number.len() as u64))?; for (ref payment_hash, commitment_number) in self.remote_hash_commitment_number.iter() { - writer.write_all(*payment_hash)?; + writer.write_all(&payment_hash.0[..])?; writer.write_all(&byte_utils::be48_to_array(*commitment_number))?; } } else { @@ -1062,7 +1062,7 @@ impl ChannelMonitor { writer.write_all(&byte_utils::be64_to_array(self.payment_preimages.len() as u64))?; for payment_preimage in self.payment_preimages.values() { - writer.write_all(payment_preimage)?; + writer.write_all(&payment_preimage.0[..])?; } self.last_block_hash.write(writer)?; @@ -1441,7 +1441,7 @@ impl ChannelMonitor { }), }; let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx); - sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.to_vec()); + sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec()); spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { outpoint: BitcoinOutPoint { txid: single_htlc_tx.txid(), vout: 0 }, output: single_htlc_tx.output[0].clone(), @@ -1492,7 +1492,7 @@ impl ChannelMonitor { for input in spend_tx.input.iter_mut() { let value = values_drain.next().unwrap(); - sign_input!(sighash_parts, input, value.0, value.1.to_vec()); + sign_input!(sighash_parts, input, value.0, (value.1).0.to_vec()); } spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { @@ -1653,7 +1653,7 @@ impl ChannelMonitor { htlc_success_tx.input[0].witness.push(our_sig.serialize_der(&self.secp_ctx).to_vec()); htlc_success_tx.input[0].witness[2].push(SigHashType::All as u8); - htlc_success_tx.input[0].witness.push(payment_preimage.to_vec()); + htlc_success_tx.input[0].witness.push(payment_preimage.0.to_vec()); htlc_success_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes()); add_dynamic_output!(htlc_success_tx, 0); @@ -1744,7 +1744,7 @@ impl ChannelMonitor { } } - fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec)>, Vec, Vec<(Option, Option<[u8 ; 32]>, [u8; 32])>) { + fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec)>, Vec, Vec<(Option, Option, PaymentHash)>) { let mut watch_outputs = Vec::new(); let mut spendable_outputs = Vec::new(); let mut htlc_updated = Vec::new(); @@ -1867,7 +1867,7 @@ impl ChannelMonitor { false } - pub(crate) fn is_resolving_output(&mut self, tx: &Transaction) -> Vec<(Option, Option<[u8;32]>, [u8;32])> { + pub(crate) fn is_resolving_output(&mut self, tx: &Transaction) -> Vec<(Option, Option, PaymentHash)> { let mut htlc_updated = Vec::new(); let commitment_number = 0xffffffffffff - ((((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor); @@ -1885,7 +1885,7 @@ impl ChannelMonitor { // No need to check remote_claimabe_outpoints, symmetric HTLCSource must be present as per-htlc data on local commitment tx } else if tx.input.len() > 0{ for input in &tx.input { - let mut payment_data: (Option, Option<[u8;32]>, Option<[u8;32]>) = (None, None, None); + let mut payment_data: (Option, Option, Option) = (None, None, None); if let Some(ref current_local_signed_commitment_tx) = self.current_local_signed_commitment_tx { if input.previous_output.txid == current_local_signed_commitment_tx.txid { for htlc_output in ¤t_local_signed_commitment_tx.htlc_outputs { @@ -1914,15 +1914,15 @@ impl ChannelMonitor { // If tx isn't solving htlc output from local/remote commitment tx and htlc isn't outbound we don't need // to broadcast solving backward if payment_data.0.is_some() && payment_data.2.is_some() { - let mut payment_preimage = [0; 32]; + let mut payment_preimage = PaymentPreimage([0; 32]); let mut preimage = None; if input.witness.len() == 5 && input.witness[4].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - for (arr, vec) in payment_preimage.iter_mut().zip(tx.input[0].witness[3].iter()) { + for (arr, vec) in payment_preimage.0.iter_mut().zip(tx.input[0].witness[3].iter()) { *arr = *vec; } preimage = Some(payment_preimage); } else if input.witness.len() == 3 && input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT { - for (arr, vec) in payment_preimage.iter_mut().zip(tx.input[0].witness[1].iter()) { + for (arr, vec) in payment_preimage.0.iter_mut().zip(tx.input[0].witness[1].iter()) { *arr = *vec; } preimage = Some(payment_preimage); @@ -2035,7 +2035,7 @@ impl ReadableArgs> for (Sha256dHash, ChannelM let offered: bool = Readable::read(reader)?; let amount_msat: u64 = Readable::read(reader)?; let cltv_expiry: u32 = Readable::read(reader)?; - let payment_hash: [u8; 32] = Readable::read(reader)?; + let payment_hash: PaymentHash = Readable::read(reader)?; let transaction_output_index: u32 = Readable::read(reader)?; HTLCOutputInCommitment { @@ -2145,9 +2145,9 @@ impl ReadableArgs> for (Sha256dHash, ChannelM let remote_hash_commitment_number_len: u64 = Readable::read(reader)?; let mut remote_hash_commitment_number = HashMap::with_capacity(cmp::min(remote_hash_commitment_number_len as usize, MAX_ALLOC_SIZE / 32)); for _ in 0..remote_hash_commitment_number_len { - let txid: [u8; 32] = Readable::read(reader)?; + let payment_hash: PaymentHash = Readable::read(reader)?; let commitment_number = >::read(reader)?.0; - if let Some(_) = remote_hash_commitment_number.insert(txid, commitment_number) { + if let Some(_) = remote_hash_commitment_number.insert(payment_hash, commitment_number) { return Err(DecodeError::InvalidValue); } } @@ -2213,11 +2213,11 @@ impl ReadableArgs> for (Sha256dHash, ChannelM let mut payment_preimages = HashMap::with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32)); let mut sha = Sha256::new(); for _ in 0..payment_preimages_len { - let preimage: [u8; 32] = Readable::read(reader)?; + let preimage: PaymentPreimage = Readable::read(reader)?; sha.reset(); - sha.input(&preimage); - let mut hash = [0; 32]; - sha.result(&mut hash); + sha.input(&preimage.0[..]); + let mut hash = PaymentHash([0; 32]); + sha.result(&mut hash.0[..]); if let Some(_) = payment_preimages.insert(hash, preimage) { return Err(DecodeError::InvalidValue); } @@ -2263,6 +2263,7 @@ mod tests { use bitcoin::blockdata::transaction::Transaction; use crypto::digest::Digest; use hex; + use ln::channelmanager::{PaymentPreimage, PaymentHash}; use ln::channelmonitor::ChannelMonitor; use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys}; use ln::channelmanager::{HTLCSource, HTLCPreviousHopData}; @@ -2656,12 +2657,12 @@ mod tests { { let mut rng = thread_rng(); for _ in 0..20 { - let mut preimage = [0; 32]; - rng.fill_bytes(&mut preimage); + let mut preimage = PaymentPreimage([0; 32]); + rng.fill_bytes(&mut preimage.0[..]); let mut sha = Sha256::new(); - sha.input(&preimage); - let mut hash = [0; 32]; - sha.result(&mut hash); + sha.input(&preimage.0[..]); + let mut hash = PaymentHash([0; 32]); + sha.result(&mut hash.0[..]); preimages.push((preimage, hash)); } } diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 354376649..4cff6256f 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -29,6 +29,8 @@ use std::result::Result; use util::{byte_utils, events}; use util::ser::{Readable, Writeable, Writer}; +use ln::channelmanager::{PaymentPreimage, PaymentHash}; + /// An error in decoding a message or struct. #[derive(Debug)] pub enum DecodeError { @@ -256,7 +258,7 @@ pub struct UpdateAddHTLC { pub(crate) channel_id: [u8; 32], pub(crate) htlc_id: u64, pub(crate) amount_msat: u64, - pub(crate) payment_hash: [u8; 32], + pub(crate) payment_hash: PaymentHash, pub(crate) cltv_expiry: u32, pub(crate) onion_routing_packet: OnionPacket, } @@ -266,7 +268,7 @@ pub struct UpdateAddHTLC { pub struct UpdateFulfillHTLC { pub(crate) channel_id: [u8; 32], pub(crate) htlc_id: u64, - pub(crate) payment_preimage: [u8; 32], + pub(crate) payment_preimage: PaymentPreimage, } /// An update_fail_htlc message to be sent or received from a peer diff --git a/src/util/events.rs b/src/util/events.rs index a11321794..2d810e839 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -13,6 +13,7 @@ //TODO: We need better separation of event types ^ use ln::msgs; +use ln::channelmanager::{PaymentPreimage, PaymentHash}; use chain::transaction::OutPoint; use chain::keysinterface::SpendableOutputDescriptor; @@ -59,7 +60,7 @@ pub enum Event { /// the amount expected. PaymentReceived { /// The hash for which the preimage should be handed to the ChannelManager. - payment_hash: [u8; 32], + payment_hash: PaymentHash, /// The value, in thousandths of a satoshi, that this payment is for. amt: u64, }, @@ -71,7 +72,7 @@ pub enum Event { /// The preimage to the hash given to ChannelManager::send_payment. /// Note that this serves as a payment receipt, if you wish to have such a thing, you must /// store it somehow! - payment_preimage: [u8; 32], + payment_preimage: PaymentPreimage, }, /// Indicates an outbound payment we made failed. Probably some intermediary node dropped /// something. You may wish to retry with a different route. @@ -79,7 +80,7 @@ pub enum Event { /// deduplicate them by payment_hash (which MUST be unique)! PaymentFailed { /// The hash which was given to ChannelManager::send_payment. - payment_hash: [u8; 32], + payment_hash: PaymentHash, /// Indicates the payment was rejected for some reason by the recipient. This implies that /// the payment has failed, not just the route in question. If this is not set, you may /// retry the payment via a different route. diff --git a/src/util/ser.rs b/src/util/ser.rs index 84cfa8d16..c1d2802a7 100644 --- a/src/util/ser.rs +++ b/src/util/ser.rs @@ -12,6 +12,7 @@ use bitcoin::util::hash::Sha256dHash; use bitcoin::blockdata::script::Script; use std::marker::Sized; use ln::msgs::DecodeError; +use ln::channelmanager::{PaymentPreimage, PaymentHash}; use util::byte_utils; use util::byte_utils::{be64_to_array, be48_to_array, be32_to_array, be16_to_array, slice_to_be16, slice_to_be32, slice_to_be48, slice_to_be64}; @@ -386,3 +387,29 @@ impl Readable for Signature { } } } + +impl Writeable for PaymentPreimage { + fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + self.0.write(w) + } +} + +impl Readable for PaymentPreimage { + fn read(r: &mut R) -> Result { + let buf: [u8; 32] = Readable::read(r)?; + Ok(PaymentPreimage(buf)) + } +} + +impl Writeable for PaymentHash { + fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + self.0.write(w) + } +} + +impl Readable for PaymentHash { + fn read(r: &mut R) -> Result { + let buf: [u8; 32] = Readable::read(r)?; + Ok(PaymentHash(buf)) + } +} diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 4a5aa60d3..3c4686406 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -4,7 +4,7 @@ use chain::transaction::OutPoint; use ln::channelmonitor; use ln::msgs; use ln::msgs::{HandleError}; -use ln::channelmanager::HTLCSource; +use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash}; use util::events; use util::logger::{Logger, Level, Record}; use util::ser::{ReadableArgs, Writer}; @@ -66,7 +66,7 @@ impl channelmonitor::ManyChannelMonitor for TestChannelMonitor { self.update_ret.lock().unwrap().clone() } - fn fetch_pending_htlc_updated(&self) -> Vec<([u8; 32], Option<[u8; 32]>, Option)> { + fn fetch_pending_htlc_updated(&self) -> Vec<(PaymentHash, Option, Option)> { return self.simple_monitor.fetch_pending_htlc_updated(); } } -- 2.39.5