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};
}, 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<PaymentHash> = 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();
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(_) => {},
// 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);
}
}
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;
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,
}
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
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};
enum InboundHTLCRemovalReason {
FailRelay(msgs::OnionErrorPacket),
FailMalformed(([u8; 32], u16)),
- Fulfill([u8; 32]),
+ Fulfill(PaymentPreimage),
}
enum InboundHTLCState {
htlc_id: u64,
amount_msat: u64,
cltv_expiry: u32,
- payment_hash: [u8; 32],
+ payment_hash: PaymentHash,
state: InboundHTLCState,
}
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
// 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 {
monitor_pending_commitment_signed: bool,
monitor_pending_order: Option<RAACommitmentOrder>,
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
/// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
/// which peer generated this transaction and "to whom" this transaction flows.
#[inline]
- fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, Vec<HTLCOutputInCommitment>, Vec<([u8; 32], &HTLCSource, Option<u32>)>) {
+ fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, Vec<HTLCOutputInCommitment>, Vec<(PaymentHash, &HTLCSource, Option<u32>)>) {
let obscured_commitment_transaction_number = self.get_commitment_transaction_number_obscure_factor() ^ (INITIAL_COMMITMENT_NUMBER - commitment_number);
let txins = {
};
let mut txouts: Vec<(TxOut, Option<(HTLCOutputInCommitment, Option<&HTLCSource>)>)> = Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2);
- let mut unincluded_htlc_sources: Vec<([u8; 32], &HTLCSource, Option<u32>)> = Vec::new();
+ let mut unincluded_htlc_sources: Vec<(PaymentHash, &HTLCSource, Option<u32>)> = Vec::new();
let dust_limit_satoshis = if local { self.our_dust_limit_satoshis } else { self.their_dust_limit_satoshis };
let mut remote_htlc_total_msat = 0;
let mut outputs: Vec<TxOut> = Vec::with_capacity(txouts.len());
let mut htlcs_included: Vec<HTLCOutputInCommitment> = Vec::with_capacity(txouts.len());
- let mut htlc_sources: Vec<([u8; 32], &HTLCSource, Option<u32>)> = Vec::with_capacity(txouts.len() + unincluded_htlc_sources.len());
+ let mut htlc_sources: Vec<(PaymentHash, &HTLCSource, Option<u32>)> = Vec::with_capacity(txouts.len() + unincluded_htlc_sources.len());
for (idx, out) in txouts.drain(..).enumerate() {
outputs.push(out.0);
if let Some((mut htlc, source_option)) = out.1 {
/// 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<Signature, ChannelError> {
+ fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option<PaymentPreimage>, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<Signature, ChannelError> {
if tx.input.len() != 1 {
panic!("Tried to sign HTLC transaction that had input count != 1!");
}
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());
/// 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<msgs::UpdateFulfillHTLC>, Option<ChannelMonitor>), ChannelError> {
+ fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage) -> Result<(Option<msgs::UpdateFulfillHTLC>, Option<ChannelMonitor>), 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,
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[..]);
// ChannelManager may generate duplicate claims/fails due to HTLC update events from
// on-chain ChannelsMonitors during block rescan. Ideally we'd figure out a way to drop
InboundHTLCState::LocalRemoved(ref reason) => {
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
} else {
- log_warn!(self, "Have preimage and want to fulfill HTLC with payment hash {} we already failed against channel {}", log_bytes!(htlc.payment_hash), log_bytes!(self.channel_id()));
+ log_warn!(self, "Have preimage and want to fulfill HTLC with payment hash {} we already failed against channel {}", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id()));
}
return Ok((None, None));
},
}), 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<ChannelMonitor>), ChannelError> {
+ pub fn get_update_fulfill_htlc_and_commit(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option<ChannelMonitor>), 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()?;
/// 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<HTLCFailReason>) -> Result<&HTLCSource, ChannelError> {
+ fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentHash>, fail_reason: Option<HTLCFailReason>) -> Result<&HTLCSource, ChannelError> {
for htlc in self.pending_outbound_htlcs.iter_mut() {
if htlc.htlc_id == htlc_id {
match check_preimage {
}
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())
}
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 {}
/// 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<msgs::CommitmentUpdate>, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, [u8; 32], HTLCFailReason)>, Option<msgs::ClosingSigned>, ChannelMonitor), ChannelError> {
+ pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &FeeEstimator) -> Result<(Option<msgs::CommitmentUpdate>, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option<msgs::ClosingSigned>, 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"));
}
/// 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);
/// commitment update or a revoke_and_ack generation). The messages which were generated from
/// that original call must *not* have been sent to the remote end, and must instead have been
/// dropped. They will be regenerated when monitor_updating_restored is called.
- pub fn monitor_update_failed(&mut self, order: RAACommitmentOrder, mut pending_forwards: Vec<(PendingForwardHTLCInfo, u64)>, mut pending_fails: Vec<(HTLCSource, [u8; 32], HTLCFailReason)>, raa_first_dropped_cs: bool) {
+ pub fn monitor_update_failed(&mut self, order: RAACommitmentOrder, mut pending_forwards: Vec<(PendingForwardHTLCInfo, u64)>, mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, raa_first_dropped_cs: bool) {
assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0);
match order {
RAACommitmentOrder::CommitmentFirst => {
/// 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<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, [u8; 32], HTLCFailReason)>) {
+ pub fn monitor_updating_restored(&mut self) -> (Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, 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);
})
}
- pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, [u8; 32])>), ChannelError> {
+ pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, 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"));
}
/// 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<Option<msgs::UpdateAddHTLC>, ChannelError> {
+ pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket) -> Result<Option<msgs::UpdateAddHTLC>, 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"));
}
/// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation
/// when we shouldn't change HTLC/channel state.
- fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<HTLCOutputInCommitment>, Vec<([u8; 32], &HTLCSource, Option<u32>)>)), ChannelError> {
+ fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<HTLCOutputInCommitment>, Vec<(PaymentHash, &HTLCSource, Option<u32>)>)), ChannelError> {
let funding_script = self.get_funding_redeemscript();
let mut feerate_per_kw = self.feerate_per_kw;
/// 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<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned, ChannelMonitor)>, 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<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned, ChannelMonitor)>, 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()?;
/// 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"});
/// 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<Transaction>, Vec<(HTLCSource, [u8; 32])>) {
+ pub fn force_shutdown(&mut self) -> (Vec<Transaction>, 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
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;
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<PaymentPreimage> = 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]));
}
}
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({
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({
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({
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({
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
});
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
pub struct PendingForwardHTLCInfo {
pub(super) onion_packet: Option<msgs::OnionPacket>,
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,
}
pub(super) use self::channel_held_info::*;
-type ShutdownResult = (Vec<Transaction>, 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<Transaction>, 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<msgs::ChannelUpdate>)>,
/// 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<HTLCPreviousHopData>>,
+ claimable_htlcs: HashMap<PaymentHash, Vec<HTLCPreviousHopData>>,
/// 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<events::MessageSendEvent>,
short_to_id: &'a mut HashMap<u64, [u8; 32]>,
next_forward: &'a mut Instant,
forward_htlcs: &'a mut HashMap<u64, Vec<HTLCForwardInfo>>,
- claimable_htlcs: &'a mut HashMap<[u8; 32], Vec<HTLCPreviousHopData>>,
+ claimable_htlcs: &'a mut HashMap<PaymentHash, Vec<HTLCPreviousHopData>>,
pending_msg_events: &'a mut Vec<events::MessageSendEvent>,
}
impl ChannelHolder {
}
const ZERO:[u8; 21*65] = [0; 21*65];
- fn construct_onion_packet(mut payloads: Vec<msgs::OnionHopData>, onion_keys: Vec<OnionKeys>, associated_data: &[u8; 32]) -> msgs::OnionPacket {
+ fn construct_onion_packet(mut payloads: Vec<msgs::OnionHopData>, onion_keys: Vec<OnionKeys>, associated_data: &PaymentHash) -> msgs::OnionPacket {
let mut buf = Vec::with_capacity(21*65);
buf.resize(21*65, 0);
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);
}
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!());
}
/// In case of APIError::MonitorUpdateFailed, the commitment update has been irrevocably
/// committed on our end and we're just waiting for a monitor update to send it. Do NOT retry
/// the payment via a different route unless you intend to pay twice!
- 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"});
}
}
/// 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());
/// 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<ChannelHolder>, source: HTLCSource, payment_hash: &[u8; 32], onion_error: HTLCFailReason) {
+ fn fail_htlc_backwards_internal(&self, mut channel_state_lock: MutexGuard<ChannelHolder>, source: HTLCSource, payment_hash: &PaymentHash, onion_error: HTLCFailReason) {
match source {
HTLCSource::OutboundRoute { .. } => {
mem::drop(channel_state_lock);
/// 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();
true
} else { false }
}
- fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard<ChannelHolder>, source: HTLCSource, payment_preimage: [u8; 32]) {
+ fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard<ChannelHolder>, source: HTLCSource, payment_preimage: PaymentPreimage) {
match source {
HTLCSource::OutboundRoute { .. } => {
mem::drop(channel_state_lock);
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};
},
);
- 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());
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 = {
(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);
}
}
- 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()) {
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);
}
}
- 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);
}
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentFailed { ref payment_hash, .. } => {
- assert!(failed_htlcs.insert(*payment_hash));
+ assert!(failed_htlcs.insert(payment_hash.0));
},
_ => panic!("Unexpected event"),
}
assert_eq!(events.len(), 2);
match events[0] {
Event::PaymentFailed { ref payment_hash, .. } => {
- assert!(failed_htlcs.insert(*payment_hash));
+ assert!(failed_htlcs.insert(payment_hash.0));
},
_ => panic!("Unexpected event"),
}
match events[1] {
Event::PaymentFailed { ref payment_hash, .. } => {
- assert!(failed_htlcs.insert(*payment_hash));
+ assert!(failed_htlcs.insert(payment_hash.0));
},
_ => panic!("Unexpected event"),
}
- assert!(failed_htlcs.contains(&first_payment_hash));
- assert!(failed_htlcs.contains(&second_payment_hash));
- assert!(failed_htlcs.contains(&third_payment_hash));
+ assert!(failed_htlcs.contains(&first_payment_hash.0));
+ assert!(failed_htlcs.contains(&second_payment_hash.0));
+ assert!(failed_htlcs.contains(&third_payment_hash.0));
}
#[test]
use ln::msgs::DecodeError;
use ln::chan_utils;
use ln::chan_utils::HTLCOutputInCommitment;
-use ln::channelmanager::HTLCSource;
+use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT};
use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface};
use chain::transaction::OutPoint;
/// Simple structure send back by ManyChannelMonitor in case of HTLC detected onchain from a
/// forward channel and from which info are needed to update HTLC in a backward channel.
pub struct HTLCUpdate {
- pub(super) payment_hash: [u8; 32],
- pub(super) payment_preimage: Option<[u8; 32]>,
+ pub(super) payment_hash: PaymentHash,
+ pub(super) payment_preimage: Option<PaymentPreimage>,
pub(super) source: HTLCSource
}
chain_monitor: Arc<ChainWatchInterface>,
broadcaster: Arc<BroadcasterInterface>,
pending_events: Mutex<Vec<events::Event>>,
- pending_htlc_updated: Mutex<HashMap<[u8; 32], Vec<(HTLCSource, Option<[u8; 32]>)>>>,
+ pending_htlc_updated: Mutex<HashMap<PaymentHash, Vec<(HTLCSource, Option<PaymentPreimage>)>>>,
logger: Arc<Logger>,
}
delayed_payment_key: PublicKey,
feerate_per_kw: u64,
htlc_outputs: Vec<(HTLCOutputInCommitment, Signature, Signature)>,
- htlc_sources: Vec<([u8; 32], HTLCSource, Option<u32>)>,
+ htlc_sources: Vec<(PaymentHash, HTLCSource, Option<u32>)>,
}
const SERIALIZATION_VERSION: u8 = 1;
their_to_self_delay: Option<u16>,
old_secrets: [([u8; 32], u64); 49],
- remote_claimable_outpoints: HashMap<Sha256dHash, (Vec<HTLCOutputInCommitment>, Vec<([u8; 32], HTLCSource, Option<u32>)>)>,
+ remote_claimable_outpoints: HashMap<Sha256dHash, (Vec<HTLCOutputInCommitment>, Vec<(PaymentHash, HTLCSource, Option<u32>)>)>,
/// We cannot identify HTLC-Success or HTLC-Timeout transactions by themselves on the chain.
/// Nor can we figure out their commitment numbers without the commitment transaction they are
/// spending. Thus, in order to claim them via revocation key, we track all the remote
/// 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<PaymentHash, u64>,
// 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
// deserialization
current_remote_commitment_number: u64,
- payment_preimages: HashMap<[u8; 32], [u8; 32]>,
+ payment_preimages: HashMap<PaymentHash, PaymentPreimage>,
destination_script: Script,
/// The monitor watches for it to be broadcasted and then uses the HTLC information (and
/// possibly future revocation/preimage information) to claim outputs where possible.
/// We cache also the mapping hash:commitment number to lighten pruning of old preimages by watchtowers.
- pub(super) fn provide_latest_remote_commitment_tx_info(&mut self, unsigned_commitment_tx: &Transaction, htlc_outputs: Vec<HTLCOutputInCommitment>, htlc_sources: Vec<([u8; 32], HTLCSource, Option<u32>)>, commitment_number: u64, their_revocation_point: PublicKey) {
+ pub(super) fn provide_latest_remote_commitment_tx_info(&mut self, unsigned_commitment_tx: &Transaction, htlc_outputs: Vec<HTLCOutputInCommitment>, htlc_sources: Vec<(PaymentHash, HTLCSource, Option<u32>)>, commitment_number: u64, their_revocation_point: PublicKey) {
// TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction
// so that a remote monitor doesn't learn anything unless there is a malicious close.
// (only maybe, sadly we cant do the same for local info, as we need to be aware of
/// Panics if set_their_to_self_delay has never been called.
/// Also update Storage with latest local per_commitment_point to derive local_delayedkey in
/// case of onchain HTLC tx
- pub(super) fn provide_latest_local_commitment_tx_info(&mut self, signed_commitment_tx: Transaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Signature, Signature)>, htlc_sources: Vec<([u8; 32], HTLCSource, Option<u32>)>) {
+ pub(super) fn provide_latest_local_commitment_tx_info(&mut self, signed_commitment_tx: Transaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Signature, Signature)>, htlc_sources: Vec<(PaymentHash, HTLCSource, Option<u32>)>) {
assert!(self.their_to_self_delay.is_some());
self.prev_local_signed_commitment_tx = self.current_local_signed_commitment_tx.take();
self.current_local_signed_commitment_tx = Some(LocalSignedTx {
/// 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());
}
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))?;
}
}
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 {
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)?;
/// HTLC-Success/HTLC-Timeout transactions.
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
/// revoked remote commitment tx
- fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec<Transaction>, (Sha256dHash, Vec<TxOut>), Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<[u8;32]>, [u8;32])>) {
+ fn check_spend_remote_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec<Transaction>, (Sha256dHash, Vec<TxOut>), Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)>) {
// Most secp and related errors trying to create keys means we have no hope of constructing
// a spend transaction...so we return no transactions to broadcast
let mut txn_to_broadcast = Vec::new();
if let &Some(ref txid) = current_remote_commitment_txid {
if let Some(&(_, ref latest_outpoints)) = self.remote_claimable_outpoints.get(&txid) {
for &(ref payment_hash, ref source, _) in latest_outpoints.iter() {
- htlc_updated.push(((*source).clone(), None, *payment_hash));
+ htlc_updated.push(((*source).clone(), None, payment_hash.clone()));
}
}
}
if let &Some(ref txid) = prev_remote_commitment_txid {
if let Some(&(_, ref prev_outpoint)) = self.remote_claimable_outpoints.get(&txid) {
for &(ref payment_hash, ref source, _) in prev_outpoint.iter() {
- htlc_updated.push(((*source).clone(), None, *payment_hash));
+ htlc_updated.push(((*source).clone(), None, payment_hash.clone()));
}
}
}
}),
};
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(),
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 {
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);
}
}
- fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec<TxOut>)>, Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<[u8 ; 32]>, [u8; 32])>) {
+ fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec<TxOut>)>, Vec<SpendableOutputDescriptor>, Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)>) {
let mut watch_outputs = Vec::new();
let mut spendable_outputs = Vec::new();
let mut htlc_updated = Vec::new();
/// Check if any transaction broadcasted is resolving HTLC output by a success or timeout on a local
/// or remote commitment tx, if so send back the source, preimage if found and payment_hash of resolved HTLC
- fn is_resolving_htlc_output(&mut self, tx: &Transaction) -> Vec<(HTLCSource, Option<[u8;32]>, [u8;32])> {
+ fn is_resolving_htlc_output(&mut self, tx: &Transaction) -> Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)> {
let mut htlc_updated = Vec::new();
'outer_loop: for input in &tx.input {
// 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 let Some((source, payment_hash)) = payment_data {
- let mut payment_preimage = [0; 32];
+ let mut payment_preimage = PaymentPreimage([0; 32]);
if input.witness.len() == 5 && input.witness[4].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT {
- payment_preimage.copy_from_slice(&tx.input[0].witness[3]);
+ payment_preimage.0.copy_from_slice(&tx.input[0].witness[3]);
htlc_updated.push((source, Some(payment_preimage), payment_hash));
} else if input.witness.len() == 3 && input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT {
- payment_preimage.copy_from_slice(&tx.input[0].witness[1]);
+ payment_preimage.0.copy_from_slice(&tx.input[0].witness[1]);
htlc_updated.push((source, Some(payment_preimage), payment_hash));
} else {
htlc_updated.push((source, None, payment_hash));
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 {
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 = <U48 as Readable<R>>::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);
}
}
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);
}
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 util::sha2::Sha256;
{
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));
}
}
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 {
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,
}
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
//TODO: We need better separation of event types ^
use ln::msgs;
+use ln::channelmanager::{PaymentPreimage, PaymentHash};
use chain::transaction::OutPoint;
use chain::keysinterface::SpendableOutputDescriptor;
/// 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,
},
/// 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.
/// 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.
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};
}
}
}
+
+impl Writeable for PaymentPreimage {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+ self.0.write(w)
+ }
+}
+
+impl<R: Read> Readable<R> for PaymentPreimage {
+ fn read(r: &mut R) -> Result<Self, DecodeError> {
+ let buf: [u8; 32] = Readable::read(r)?;
+ Ok(PaymentPreimage(buf))
+ }
+}
+
+impl Writeable for PaymentHash {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+ self.0.write(w)
+ }
+}
+
+impl<R: Read> Readable<R> for PaymentHash {
+ fn read(r: &mut R) -> Result<Self, DecodeError> {
+ let buf: [u8; 32] = Readable::read(r)?;
+ Ok(PaymentHash(buf))
+ }
+}