Skip to content

Use the TxOutRef type for the ChannelMonitor's funding_txo field. #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions fuzz/fuzz_targets/channel_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use lightning::ln::channelmanager::{HTLCFailReason, PendingForwardHTLCInfo};
use lightning::ln::msgs;
use lightning::ln::msgs::MsgDecodable;
use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget};
use lightning::chain::transaction::OutPoint;
use lightning::util::reset_rng_state;

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

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

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

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

let mut funding_created = decode_msg!(msgs::FundingCreated, 32+32+2+64);
funding_created.funding_txid = funding_output.0.clone();
funding_created.funding_output_index = funding_output.1;
funding_created.funding_txid = funding_output.txid.clone();
funding_created.funding_output_index = funding_output.index;
return_err!(chan.funding_created(&funding_created));
chan
};
Expand Down
5 changes: 3 additions & 2 deletions fuzz/fuzz_targets/full_stack_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crypto::sha2::Sha256;
use crypto::digest::Digest;

use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
use lightning::chain::transaction::OutPoint;
use lightning::ln::channelmonitor;
use lightning::ln::channelmanager::ChannelManager;
use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
Expand Down Expand Up @@ -93,7 +94,7 @@ impl FeeEstimator for FuzzEstimator {

struct TestChannelMonitor {}
impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
fn add_update_monitor(&self, _funding_txo: (Sha256dHash, u16), _monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
fn add_update_monitor(&self, _funding_txo: OutPoint, _monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
//TODO!
Ok(())
}
Expand Down Expand Up @@ -280,7 +281,7 @@ pub fn do_test(data: &[u8]) {
let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut {
value: funding_generation.1, script_pubkey: funding_generation.2,
}] };
let funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
let funding_output = OutPoint::new(Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
pending_funding_signatures.insert(funding_output, tx);
}
Expand Down
1 change: 1 addition & 0 deletions src/chain/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod chaininterface;
pub mod transaction;
24 changes: 24 additions & 0 deletions src/chain/transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use bitcoin::util::hash::Sha256dHash;
use bitcoin::util::uint::Uint256;

/// A reference to a transaction output.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct OutPoint {
/// The referenced transaction's txid.
pub txid: Sha256dHash,
/// The index of the referenced output in its transaction's vout.
pub index: u16,
}

impl OutPoint {
/// Creates a new `OutPoint` from the txid an the index.
pub fn new(txid: Sha256dHash, index: u16) -> OutPoint {
OutPoint { txid, index }
}

/// Convert an `OutPoint` to a lightning channel id.
pub fn to_channel_id(&self) -> Uint256 {
// TODO: or le?
self.txid.into_be() ^ Uint256::from_u64(self.index as u64).unwrap()
}
}
62 changes: 33 additions & 29 deletions src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason};
use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
use util::{transaction_utils,rng};
use util::sha2::Sha256;

Expand Down Expand Up @@ -482,9 +483,9 @@ impl Channel {
let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
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();
let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key,
&PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key).unwrap(),
&chan_keys.htlc_base_key,
BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
&PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key).unwrap(),
&chan_keys.htlc_base_key,
BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
channel_monitor.set_their_htlc_base_key(&msg.htlc_basepoint);
channel_monitor.set_their_to_self_delay(msg.to_self_delay);

Expand Down Expand Up @@ -599,8 +600,8 @@ impl Channel {
let txins = {
let mut ins: Vec<TxIn> = Vec::new();
ins.push(TxIn {
prev_hash: self.channel_monitor.get_funding_txo().unwrap().0,
prev_index: self.channel_monitor.get_funding_txo().unwrap().1 as u32,
prev_hash: self.channel_monitor.get_funding_txo().unwrap().txid,
prev_index: self.channel_monitor.get_funding_txo().unwrap().index as u32,
script_sig: Script::new(),
sequence: ((0x80 as u32) << 8*3) | ((obscured_commitment_transaction_number >> 3*8) as u32),
witness: Vec::new(),
Expand Down Expand Up @@ -733,8 +734,8 @@ impl Channel {
let txins = {
let mut ins: Vec<TxIn> = Vec::new();
ins.push(TxIn {
prev_hash: self.channel_monitor.get_funding_txo().unwrap().0,
prev_index: self.channel_monitor.get_funding_txo().unwrap().1 as u32,
prev_hash: self.channel_monitor.get_funding_txo().unwrap().txid,
prev_index: self.channel_monitor.get_funding_txo().unwrap().index as u32,
script_sig: Script::new(),
sequence: 0xffffffff,
witness: Vec::new(),
Expand Down Expand Up @@ -1150,7 +1151,8 @@ impl Channel {
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
}

self.channel_monitor.set_funding_info(msg.funding_txid, msg.funding_output_index);
let funding_info = OutPoint::new(msg.funding_txid, msg.funding_output_index);
self.channel_monitor.set_funding_info(funding_info);

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

Expand Down Expand Up @@ -1240,11 +1242,11 @@ impl Channel {
HTLCState::AwaitingAnnouncedRemoteRevoke => {},
HTLCState::LocalAnnounced => { if for_remote_update_check { continue; } },
HTLCState::Committed => {},
HTLCState::RemoteRemoved => { if for_remote_update_check { continue; } },
HTLCState::AwaitingRemoteRevokeToRemove => { if for_remote_update_check { continue; } },
HTLCState::AwaitingRemovedRemoteRevoke => { if for_remote_update_check { continue; } },
HTLCState::LocalRemoved => {},
HTLCState::LocalRemovedAwaitingCommitment => { if for_remote_update_check { continue; } },
HTLCState::RemoteRemoved => { if for_remote_update_check { continue; } },
HTLCState::AwaitingRemoteRevokeToRemove => { if for_remote_update_check { continue; } },
HTLCState::AwaitingRemovedRemoteRevoke => { if for_remote_update_check { continue; } },
HTLCState::LocalRemoved => {},
HTLCState::LocalRemovedAwaitingCommitment => { if for_remote_update_check { continue; } },
}
if !htlc.outbound {
inbound_htlc_count += 1;
Expand Down Expand Up @@ -1823,7 +1825,7 @@ impl Channel {

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

Expand Down Expand Up @@ -1920,17 +1922,17 @@ impl Channel {
}
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
for (ref tx, index_in_block) in txn_matched.iter().zip(indexes_of_txn_matched) {
if tx.txid() == self.channel_monitor.get_funding_txo().unwrap().0 {
let txo_idx = self.channel_monitor.get_funding_txo().unwrap().1 as usize;
if tx.txid() == self.channel_monitor.get_funding_txo().unwrap().txid {
let txo_idx = self.channel_monitor.get_funding_txo().unwrap().index as usize;
if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() ||
tx.output[txo_idx].value != self.channel_value_satoshis {
self.channel_state = ChannelState::ShutdownComplete as u32;
self.channel_update_count += 1;
} else {
self.funding_tx_confirmations = 1;
self.short_channel_id = Some(((height as u64) << (5*8)) |
self.short_channel_id = Some(((height as u64) << (5*8)) |
((*index_in_block as u64) << (2*8)) |
((self.channel_monitor.get_funding_txo().unwrap().1 as u64) << (2*8)));
((self.channel_monitor.get_funding_txo().unwrap().index as u64) << (2*8)));
}
}
}
Expand Down Expand Up @@ -2043,7 +2045,7 @@ impl Channel {
/// or if called on an inbound channel.
/// Note that channel_id changes during this call!
/// Do NOT broadcast the funding transaction until after a successful funding_signed call!
pub fn get_outbound_funding_created(&mut self, funding_txid: Sha256dHash, funding_output_index: u16) -> Result<(msgs::FundingCreated, ChannelMonitor), HandleError> {
pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result<(msgs::FundingCreated, ChannelMonitor), HandleError> {
if !self.channel_outbound {
panic!("Tried to create outbound funding_created message on an inbound channel!");
}
Expand All @@ -2054,7 +2056,7 @@ impl Channel {
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
}

self.channel_monitor.set_funding_info(funding_txid, funding_output_index);
self.channel_monitor.set_funding_info(funding_txo);

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

Ok((msgs::FundingCreated {
temporary_channel_id: temporary_channel_id,
funding_txid: funding_txid,
funding_output_index: funding_output_index,
funding_txid: funding_txo.txid,
funding_output_index: funding_txo.index,
signature: our_signature
}, self.channel_monitor.clone()))
}
Expand Down Expand Up @@ -2330,6 +2332,7 @@ mod tests {
use ln::channel::{Channel,ChannelKeys,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
use secp256k1::{Secp256k1,Message,Signature};
use secp256k1::key::{SecretKey,PublicKey};
use crypto::sha2::Sha256;
Expand Down Expand Up @@ -2369,7 +2372,8 @@ mod tests {
chan.their_to_self_delay = 144;
chan.our_dust_limit_satoshis = 546;

chan.channel_monitor.set_funding_info(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
let funding_info = OutPoint::new(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
chan.channel_monitor.set_funding_info(funding_info);

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

seed[0..32].clone_from_slice(&hex_bytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap());
assert_eq!(chan_utils::build_commitment_secret(seed, 281474976710655),
hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..]);
hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..]);

assert_eq!(chan_utils::build_commitment_secret(seed, 0xaaaaaaaaaaa),
hex_bytes("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..]);
hex_bytes("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..]);

assert_eq!(chan_utils::build_commitment_secret(seed, 0x555555555555),
hex_bytes("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..]);
hex_bytes("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..]);

seed[0..32].clone_from_slice(&hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap());
assert_eq!(chan_utils::build_commitment_secret(seed, 1),
hex_bytes("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..]);
hex_bytes("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..]);
}

#[test]
Expand Down
16 changes: 9 additions & 7 deletions src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::blockdata::constants::genesis_block;
use bitcoin::network::constants::Network;
Expand All @@ -12,6 +12,7 @@ use secp256k1::ecdh::SharedSecret;
use secp256k1;

use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator};
use chain::transaction::OutPoint;
use ln::channel::{Channel, ChannelKeys};
use ln::channelmonitor::ManyChannelMonitor;
use ln::router::{Route,RouteHop};
Expand Down Expand Up @@ -661,12 +662,12 @@ impl ChannelManager {

/// Call this upon creation of a funding transaction for the given channel.
/// Panics if a funding transaction has already been provided for this channel.
pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: (Sha256dHash, u16)) {
pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: OutPoint) {
let (chan, msg, chan_monitor) = {
let mut channel_state = self.channel_state.lock().unwrap();
match channel_state.by_id.remove(&temporary_channel_id) {
Some(mut chan) => {
match chan.get_outbound_funding_created(funding_txo.0, funding_txo.1) {
match chan.get_outbound_funding_created(funding_txo) {
Ok(funding_msg) => {
(chan, funding_msg.0, funding_msg.1)
},
Expand Down Expand Up @@ -1029,7 +1030,7 @@ impl ChainListener for ChannelManager {
if let Some(funding_txo) = channel.get_funding_txo() {
for tx in txn_matched {
for inp in tx.input.iter() {
if inp.prev_hash == funding_txo.0 && inp.prev_index == funding_txo.1 as u32 {
if inp.prev_hash == funding_txo.txid && inp.prev_index == funding_txo.index as u32 {
if let Some(short_id) = channel.get_short_channel_id() {
short_to_ids_to_remove.push(short_id);
}
Expand Down Expand Up @@ -1578,7 +1579,7 @@ impl ChannelMessageHandler for ChannelManager {

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

node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output.clone());
node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output);
let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap();
assert_eq!(added_monitors.len(), 1);
assert_eq!(added_monitors[0].0, funding_output);
Expand Down
Loading