Skip to content

Commit d0e9137

Browse files
committed
Add the OutPoint type for the ChannelMonitor's funding_txo field.
This structure replaces the (Sha256dHash, u16) tuple that was being used for the funding output. Signed-off-by: Jean Pierre Dudey <[email protected]>
1 parent d8474c9 commit d0e9137

File tree

9 files changed

+94
-60
lines changed

9 files changed

+94
-60
lines changed

fuzz/fuzz_targets/channel_target.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use lightning::ln::channelmanager::{HTLCFailReason, PendingForwardHTLCInfo};
1212
use lightning::ln::msgs;
1313
use lightning::ln::msgs::MsgDecodable;
1414
use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget};
15+
use lightning::chain::transaction::OutPoint;
1516
use lightning::util::reset_rng_state;
1617

1718
use secp256k1::key::{PublicKey, SecretKey};
@@ -196,9 +197,9 @@ pub fn do_test(data: &[u8]) {
196197
return_err!(chan.accept_channel(&accept_chan));
197198

198199
tx.output.push(TxOut{ value: chan_value, script_pubkey: chan.get_funding_redeemscript().to_v0_p2wsh() });
199-
let funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
200+
let funding_output = OutPoint::new(Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
200201

201-
chan.get_outbound_funding_created(funding_output.0.clone(), funding_output.1).unwrap();
202+
chan.get_outbound_funding_created(funding_output).unwrap();
202203
let funding_signed = decode_msg!(msgs::FundingSigned, 32+64);
203204
return_err!(chan.funding_signed(&funding_signed));
204205
chan
@@ -215,11 +216,11 @@ pub fn do_test(data: &[u8]) {
215216
chan.get_accept_channel().unwrap();
216217

217218
tx.output.push(TxOut{ value: open_chan.funding_satoshis, script_pubkey: chan.get_funding_redeemscript().to_v0_p2wsh() });
218-
let funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
219+
let funding_output = OutPoint::new(Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
219220

220221
let mut funding_created = decode_msg!(msgs::FundingCreated, 32+32+2+64);
221-
funding_created.funding_txid = funding_output.0.clone();
222-
funding_created.funding_output_index = funding_output.1;
222+
funding_created.funding_txid = funding_output.txid.clone();
223+
funding_created.funding_output_index = funding_output.index;
223224
return_err!(chan.funding_created(&funding_created));
224225
chan
225226
};

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crypto::sha2::Sha256;
1515
use crypto::digest::Digest;
1616

1717
use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
18+
use lightning::chain::transaction::OutPoint;
1819
use lightning::ln::channelmonitor;
1920
use lightning::ln::channelmanager::ChannelManager;
2021
use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
@@ -93,7 +94,7 @@ impl FeeEstimator for FuzzEstimator {
9394

9495
struct TestChannelMonitor {}
9596
impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
96-
fn add_update_monitor(&self, _funding_txo: (Sha256dHash, u16), _monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
97+
fn add_update_monitor(&self, _funding_txo: OutPoint, _monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
9798
//TODO!
9899
Ok(())
99100
}
@@ -280,7 +281,7 @@ pub fn do_test(data: &[u8]) {
280281
let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut {
281282
value: funding_generation.1, script_pubkey: funding_generation.2,
282283
}] };
283-
let funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
284+
let funding_output = OutPoint::new(Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
284285
channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
285286
pending_funding_signatures.insert(funding_output, tx);
286287
}

src/chain/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pub mod chaininterface;
2+
pub mod transaction;

src/chain/transaction.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use bitcoin::util::hash::Sha256dHash;
2+
use bitcoin::util::uint::Uint256;
3+
4+
/// A reference to a transaction output.
5+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
6+
pub struct OutPoint {
7+
/// The referenced transaction's txid.
8+
pub txid: Sha256dHash,
9+
/// The index of the referenced output in its transaction's vout.
10+
pub index: u16,
11+
}
12+
13+
impl OutPoint {
14+
/// Creates a new `OutPoint` from the txid an the index.
15+
pub fn new(txid: Sha256dHash, index: u16) -> OutPoint {
16+
OutPoint { txid, index }
17+
}
18+
19+
/// Convert an `OutPoint` to a lightning channel id.
20+
pub fn to_channel_id(&self) -> Uint256 {
21+
// TODO: or le?
22+
self.txid.into_be() ^ Uint256::from_u64(self.index as u64).unwrap()
23+
}
24+
}

src/ln/channel.rs

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason};
2121
use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
2222
use ln::chan_utils;
2323
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
24+
use chain::transaction::OutPoint;
2425
use util::{transaction_utils,rng};
2526
use util::sha2::Sha256;
2627

@@ -482,9 +483,9 @@ impl Channel {
482483
let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
483484
let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script();
484485
let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key,
485-
&PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key).unwrap(),
486-
&chan_keys.htlc_base_key,
487-
BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
486+
&PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key).unwrap(),
487+
&chan_keys.htlc_base_key,
488+
BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
488489
channel_monitor.set_their_htlc_base_key(&msg.htlc_basepoint);
489490
channel_monitor.set_their_to_self_delay(msg.to_self_delay);
490491

@@ -599,8 +600,8 @@ impl Channel {
599600
let txins = {
600601
let mut ins: Vec<TxIn> = Vec::new();
601602
ins.push(TxIn {
602-
prev_hash: self.channel_monitor.get_funding_txo().unwrap().0,
603-
prev_index: self.channel_monitor.get_funding_txo().unwrap().1 as u32,
603+
prev_hash: self.channel_monitor.get_funding_txo().unwrap().txid,
604+
prev_index: self.channel_monitor.get_funding_txo().unwrap().index as u32,
604605
script_sig: Script::new(),
605606
sequence: ((0x80 as u32) << 8*3) | ((obscured_commitment_transaction_number >> 3*8) as u32),
606607
witness: Vec::new(),
@@ -733,8 +734,8 @@ impl Channel {
733734
let txins = {
734735
let mut ins: Vec<TxIn> = Vec::new();
735736
ins.push(TxIn {
736-
prev_hash: self.channel_monitor.get_funding_txo().unwrap().0,
737-
prev_index: self.channel_monitor.get_funding_txo().unwrap().1 as u32,
737+
prev_hash: self.channel_monitor.get_funding_txo().unwrap().txid,
738+
prev_index: self.channel_monitor.get_funding_txo().unwrap().index as u32,
738739
script_sig: Script::new(),
739740
sequence: 0xffffffff,
740741
witness: Vec::new(),
@@ -1150,7 +1151,8 @@ impl Channel {
11501151
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
11511152
}
11521153

1153-
self.channel_monitor.set_funding_info(msg.funding_txid, msg.funding_output_index);
1154+
let funding_info = OutPoint::new(msg.funding_txid, msg.funding_output_index);
1155+
self.channel_monitor.set_funding_info(funding_info);
11541156

11551157
let (remote_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature) {
11561158
Ok(res) => res,
@@ -1165,7 +1167,7 @@ impl Channel {
11651167
self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new());
11661168
self.channel_state = ChannelState::FundingSent as u32;
11671169
let funding_txo = self.channel_monitor.get_funding_txo().unwrap();
1168-
self.channel_id = funding_txo.0.into_be() ^ Uint256::from_u64(funding_txo.1 as u64).unwrap(); //TODO: or le?
1170+
self.channel_id = funding_txo.to_channel_id();
11691171
self.cur_remote_commitment_transaction_number -= 1;
11701172
self.cur_local_commitment_transaction_number -= 1;
11711173

@@ -1240,11 +1242,11 @@ impl Channel {
12401242
HTLCState::AwaitingAnnouncedRemoteRevoke => {},
12411243
HTLCState::LocalAnnounced => { if for_remote_update_check { continue; } },
12421244
HTLCState::Committed => {},
1243-
HTLCState::RemoteRemoved => { if for_remote_update_check { continue; } },
1244-
HTLCState::AwaitingRemoteRevokeToRemove => { if for_remote_update_check { continue; } },
1245-
HTLCState::AwaitingRemovedRemoteRevoke => { if for_remote_update_check { continue; } },
1246-
HTLCState::LocalRemoved => {},
1247-
HTLCState::LocalRemovedAwaitingCommitment => { if for_remote_update_check { continue; } },
1245+
HTLCState::RemoteRemoved => { if for_remote_update_check { continue; } },
1246+
HTLCState::AwaitingRemoteRevokeToRemove => { if for_remote_update_check { continue; } },
1247+
HTLCState::AwaitingRemovedRemoteRevoke => { if for_remote_update_check { continue; } },
1248+
HTLCState::LocalRemoved => {},
1249+
HTLCState::LocalRemovedAwaitingCommitment => { if for_remote_update_check { continue; } },
12481250
}
12491251
if !htlc.outbound {
12501252
inbound_htlc_count += 1;
@@ -1823,7 +1825,7 @@ impl Channel {
18231825

18241826
/// Returns the funding_txo we either got from our peer, or were given by
18251827
/// get_outbound_funding_created.
1826-
pub fn get_funding_txo(&self) -> Option<(Sha256dHash, u16)> {
1828+
pub fn get_funding_txo(&self) -> Option<OutPoint> {
18271829
self.channel_monitor.get_funding_txo()
18281830
}
18291831

@@ -1920,17 +1922,17 @@ impl Channel {
19201922
}
19211923
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
19221924
for (ref tx, index_in_block) in txn_matched.iter().zip(indexes_of_txn_matched) {
1923-
if tx.txid() == self.channel_monitor.get_funding_txo().unwrap().0 {
1924-
let txo_idx = self.channel_monitor.get_funding_txo().unwrap().1 as usize;
1925+
if tx.txid() == self.channel_monitor.get_funding_txo().unwrap().txid {
1926+
let txo_idx = self.channel_monitor.get_funding_txo().unwrap().index as usize;
19251927
if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() ||
19261928
tx.output[txo_idx].value != self.channel_value_satoshis {
19271929
self.channel_state = ChannelState::ShutdownComplete as u32;
19281930
self.channel_update_count += 1;
19291931
} else {
19301932
self.funding_tx_confirmations = 1;
1931-
self.short_channel_id = Some(((height as u64) << (5*8)) |
1933+
self.short_channel_id = Some(((height as u64) << (5*8)) |
19321934
((*index_in_block as u64) << (2*8)) |
1933-
((self.channel_monitor.get_funding_txo().unwrap().1 as u64) << (2*8)));
1935+
((self.channel_monitor.get_funding_txo().unwrap().index as u64) << (2*8)));
19341936
}
19351937
}
19361938
}
@@ -2043,7 +2045,7 @@ impl Channel {
20432045
/// or if called on an inbound channel.
20442046
/// Note that channel_id changes during this call!
20452047
/// Do NOT broadcast the funding transaction until after a successful funding_signed call!
2046-
pub fn get_outbound_funding_created(&mut self, funding_txid: Sha256dHash, funding_output_index: u16) -> Result<(msgs::FundingCreated, ChannelMonitor), HandleError> {
2048+
pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result<(msgs::FundingCreated, ChannelMonitor), HandleError> {
20472049
if !self.channel_outbound {
20482050
panic!("Tried to create outbound funding_created message on an inbound channel!");
20492051
}
@@ -2054,7 +2056,7 @@ impl Channel {
20542056
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
20552057
}
20562058

2057-
self.channel_monitor.set_funding_info(funding_txid, funding_output_index);
2059+
self.channel_monitor.set_funding_info(funding_txo);
20582060

20592061
let (our_signature, commitment_tx) = match self.get_outbound_funding_created_signature() {
20602062
Ok(res) => res,
@@ -2070,13 +2072,13 @@ impl Channel {
20702072
self.channel_monitor.provide_latest_remote_commitment_tx_info(&commitment_tx, Vec::new());
20712073
self.channel_state = ChannelState::FundingCreated as u32;
20722074
let funding_txo = self.channel_monitor.get_funding_txo().unwrap();
2073-
self.channel_id = funding_txo.0.into_be() ^ Uint256::from_u64(funding_txo.1 as u64).unwrap(); //TODO: or le?
2075+
self.channel_id = funding_txo.to_channel_id();
20742076
self.cur_remote_commitment_transaction_number -= 1;
20752077

20762078
Ok((msgs::FundingCreated {
20772079
temporary_channel_id: temporary_channel_id,
2078-
funding_txid: funding_txid,
2079-
funding_output_index: funding_output_index,
2080+
funding_txid: funding_txo.txid,
2081+
funding_output_index: funding_txo.index,
20802082
signature: our_signature
20812083
}, self.channel_monitor.clone()))
20822084
}
@@ -2330,6 +2332,7 @@ mod tests {
23302332
use ln::channel::{Channel,ChannelKeys,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
23312333
use ln::chan_utils;
23322334
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
2335+
use chain::transaction::OutPoint;
23332336
use secp256k1::{Secp256k1,Message,Signature};
23342337
use secp256k1::key::{SecretKey,PublicKey};
23352338
use crypto::sha2::Sha256;
@@ -2369,7 +2372,8 @@ mod tests {
23692372
chan.their_to_self_delay = 144;
23702373
chan.our_dust_limit_satoshis = 546;
23712374

2372-
chan.channel_monitor.set_funding_info(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
2375+
let funding_info = OutPoint::new(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
2376+
chan.channel_monitor.set_funding_info(funding_info);
23732377

23742378
chan.their_payment_basepoint = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("4444444444444444444444444444444444444444444444444444444444444444").unwrap()[..]).unwrap()).unwrap();
23752379
assert_eq!(chan.their_payment_basepoint.serialize()[..],
@@ -2868,17 +2872,17 @@ mod tests {
28682872

28692873
seed[0..32].clone_from_slice(&hex_bytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap());
28702874
assert_eq!(chan_utils::build_commitment_secret(seed, 281474976710655),
2871-
hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..]);
2875+
hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..]);
28722876

28732877
assert_eq!(chan_utils::build_commitment_secret(seed, 0xaaaaaaaaaaa),
2874-
hex_bytes("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..]);
2878+
hex_bytes("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..]);
28752879

28762880
assert_eq!(chan_utils::build_commitment_secret(seed, 0x555555555555),
2877-
hex_bytes("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..]);
2881+
hex_bytes("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..]);
28782882

28792883
seed[0..32].clone_from_slice(&hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap());
28802884
assert_eq!(chan_utils::build_commitment_secret(seed, 1),
2881-
hex_bytes("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..]);
2885+
hex_bytes("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..]);
28822886
}
28832887

28842888
#[test]

src/ln/channelmanager.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bitcoin::blockdata::block::BlockHeader;
1+
use bitcoin::blockdata::block::BlockHeader;
22
use bitcoin::blockdata::transaction::Transaction;
33
use bitcoin::blockdata::constants::genesis_block;
44
use bitcoin::network::constants::Network;
@@ -12,6 +12,7 @@ use secp256k1::ecdh::SharedSecret;
1212
use secp256k1;
1313

1414
use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator};
15+
use chain::transaction::OutPoint;
1516
use ln::channel::{Channel, ChannelKeys};
1617
use ln::channelmonitor::ManyChannelMonitor;
1718
use ln::router::{Route,RouteHop};
@@ -661,12 +662,12 @@ impl ChannelManager {
661662

662663
/// Call this upon creation of a funding transaction for the given channel.
663664
/// Panics if a funding transaction has already been provided for this channel.
664-
pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: (Sha256dHash, u16)) {
665+
pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: OutPoint) {
665666
let (chan, msg, chan_monitor) = {
666667
let mut channel_state = self.channel_state.lock().unwrap();
667668
match channel_state.by_id.remove(&temporary_channel_id) {
668669
Some(mut chan) => {
669-
match chan.get_outbound_funding_created(funding_txo.0, funding_txo.1) {
670+
match chan.get_outbound_funding_created(funding_txo) {
670671
Ok(funding_msg) => {
671672
(chan, funding_msg.0, funding_msg.1)
672673
},
@@ -1029,7 +1030,7 @@ impl ChainListener for ChannelManager {
10291030
if let Some(funding_txo) = channel.get_funding_txo() {
10301031
for tx in txn_matched {
10311032
for inp in tx.input.iter() {
1032-
if inp.prev_hash == funding_txo.0 && inp.prev_index == funding_txo.1 as u32 {
1033+
if inp.prev_hash == funding_txo.txid && inp.prev_index == funding_txo.index as u32 {
10331034
if let Some(short_id) = channel.get_short_channel_id() {
10341035
short_to_ids_to_remove.push(short_id);
10351036
}
@@ -1578,7 +1579,7 @@ impl ChannelMessageHandler for ChannelManager {
15781579

15791580
let mut hmac = Hmac::new(Sha256::new(), &um);
15801581
hmac.input(&err_packet.encode()[32..]);
1581-
let mut calc_tag = [0u8; 32];
1582+
let mut calc_tag = [0u8; 32];
15821583
hmac.raw_result(&mut calc_tag);
15831584
if crypto::util::fixed_time_eq(&calc_tag, &err_packet.hmac) {
15841585
const UNKNOWN_CHAN: u16 = 0x4000|10;
@@ -1801,6 +1802,7 @@ impl ChannelMessageHandler for ChannelManager {
18011802
#[cfg(test)]
18021803
mod tests {
18031804
use chain::chaininterface;
1805+
use chain::transaction::OutPoint;
18041806
use ln::channelmanager::{ChannelManager,OnionKeys};
18051807
use ln::router::{Route, RouteHop, Router};
18061808
use ln::msgs;
@@ -2020,9 +2022,9 @@ mod tests {
20202022
tx = Transaction { version: chan_id as u32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
20212023
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
20222024
}]};
2023-
funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
2025+
funding_output = OutPoint::new(Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
20242026

2025-
node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output.clone());
2027+
node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output);
20262028
let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap();
20272029
assert_eq!(added_monitors.len(), 1);
20282030
assert_eq!(added_monitors[0].0, funding_output);

0 commit comments

Comments
 (0)