-
Notifications
You must be signed in to change notification settings - Fork 412
Provide additional parameters to sign_remote_commitment #442
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
Changes from all commits
bee53fa
164af7f
ffba0d3
78c17d5
0a99bd9
81afee9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -800,7 +800,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
/// Note that below-dust HTLCs are included in the third return value, but not the second, and | ||
/// sources are provided only for outbound HTLCs in the third return value. | ||
#[inline] | ||
fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, usize, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>) { | ||
fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, usize, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, Vec<Script>) { | ||
let obscured_commitment_transaction_number = self.get_commitment_transaction_number_obscure_factor() ^ (INITIAL_COMMITMENT_NUMBER - commitment_number); | ||
|
||
let txins = { | ||
|
@@ -814,7 +814,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
ins | ||
}; | ||
|
||
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 txouts: Vec<(TxOut, (Option<(HTLCOutputInCommitment, Option<&HTLCSource>)>, Script))> = | ||
Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2); | ||
let mut included_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)> = Vec::new(); | ||
|
||
let dust_limit_satoshis = if local { self.our_dust_limit_satoshis } else { self.their_dust_limit_satoshis }; | ||
|
@@ -842,10 +843,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
let htlc_in_tx = get_htlc_in_commitment!($htlc, true); | ||
if $htlc.amount_msat / 1000 >= dust_limit_satoshis + (feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000) { | ||
log_trace!(self, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, log_bytes!($htlc.payment_hash.0), $htlc.amount_msat); | ||
let script = chan_utils::get_htlc_redeemscript(&htlc_in_tx, &keys); | ||
txouts.push((TxOut { | ||
script_pubkey: chan_utils::get_htlc_redeemscript(&htlc_in_tx, &keys).to_v0_p2wsh(), | ||
script_pubkey: script.to_v0_p2wsh(), | ||
value: $htlc.amount_msat / 1000 | ||
}, Some((htlc_in_tx, $source)))); | ||
}, (Some((htlc_in_tx, $source)), script))); | ||
} else { | ||
log_trace!(self, " ...including {} {} dust HTLC {} (hash {}) with value {} due to dust limit", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, log_bytes!($htlc.payment_hash.0), $htlc.amount_msat); | ||
included_dust_htlcs.push((htlc_in_tx, $source)); | ||
|
@@ -854,10 +856,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
let htlc_in_tx = get_htlc_in_commitment!($htlc, false); | ||
if $htlc.amount_msat / 1000 >= dust_limit_satoshis + (feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000) { | ||
log_trace!(self, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, log_bytes!($htlc.payment_hash.0), $htlc.amount_msat); | ||
let script = chan_utils::get_htlc_redeemscript(&htlc_in_tx, &keys); | ||
txouts.push((TxOut { // "received HTLC output" | ||
script_pubkey: chan_utils::get_htlc_redeemscript(&htlc_in_tx, &keys).to_v0_p2wsh(), | ||
script_pubkey: script.to_v0_p2wsh(), | ||
value: $htlc.amount_msat / 1000 | ||
}, Some((htlc_in_tx, $source)))); | ||
}, (Some((htlc_in_tx, $source)), script))); | ||
} else { | ||
log_trace!(self, " ...including {} {} dust HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, log_bytes!($htlc.payment_hash.0), $htlc.amount_msat); | ||
included_dust_htlcs.push((htlc_in_tx, $source)); | ||
|
@@ -925,7 +928,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
assert!(value_to_self_msat >= 0); | ||
// Note that in case they have several just-awaiting-last-RAA fulfills in-progress (ie | ||
// AwaitingRemoteRevokeToRemove or AwaitingRemovedRemoteRevoke) we may have allowed them to | ||
// "violate" their reserve value by couting those against it. Thus, we have to convert | ||
// "violate" their reserve value by counting those against it. Thus, we have to convert | ||
// everything to i64 before subtracting as otherwise we can overflow. | ||
let value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 - (self.value_to_self_msat as i64) - (remote_htlc_total_msat as i64) - value_to_self_msat_offset; | ||
assert!(value_to_remote_msat >= 0); | ||
|
@@ -957,25 +960,29 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
|
||
if value_to_a >= (dust_limit_satoshis as i64) { | ||
log_trace!(self, " ...including {} output with value {}", if local { "to_local" } else { "to_remote" }, value_to_a); | ||
let script = chan_utils::get_revokeable_redeemscript(&keys.revocation_key, | ||
if local { self.their_to_self_delay } else { self.our_to_self_delay }, | ||
&keys.a_delayed_payment_key); | ||
txouts.push((TxOut { | ||
script_pubkey: chan_utils::get_revokeable_redeemscript(&keys.revocation_key, | ||
if local { self.their_to_self_delay } else { self.our_to_self_delay }, | ||
&keys.a_delayed_payment_key).to_v0_p2wsh(), | ||
script_pubkey: script.to_v0_p2wsh(), | ||
value: value_to_a as u64 | ||
}, None)); | ||
}, (None, script))); | ||
} | ||
|
||
if value_to_b >= (dust_limit_satoshis as i64) { | ||
log_trace!(self, " ...including {} output with value {}", if local { "to_remote" } else { "to_local" }, value_to_b); | ||
let script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Looks like moving script to here is used, so needless hunk. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps I'm missing something because Rust is new to me. I pulled the argument out into a variable for readability. Are you saying that it's more efficient to have the expression inline in the next line? I did an experiment as follows, and got identical compiler output with
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, sorry, not commenting about effeciency at all here, just noting that the hunk isn't doing anything. I usually point out such things as its otherwise awkward in the same commit and I didn't automatically assume it was for readability. Doesn't matter too much either way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, so readability improvements in separate commits, so the intention is more transparent? or attach a PR note to the hunk? |
||
.push_slice(&Hash160::hash(&keys.b_payment_key.serialize())[..]) | ||
.into_script(); | ||
// p2wpkh doesn't need a redeem script. Provide a placeholder. | ||
let redeem_script = Builder::new().into_script(); | ||
txouts.push((TxOut { | ||
script_pubkey: Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0) | ||
.push_slice(&Hash160::hash(&keys.b_payment_key.serialize())[..]) | ||
.into_script(), | ||
script_pubkey: script, | ||
value: value_to_b as u64 | ||
}, None)); | ||
}, (None, redeem_script))); | ||
} | ||
|
||
transaction_utils::sort_outputs(&mut txouts, |a, b| { | ||
transaction_utils::sort_outputs(&mut txouts, |(a, _), (b, _)| { | ||
if let &Some(ref a_htlc) = a { | ||
if let &Some(ref b_htlc) = b { | ||
a_htlc.0.cltv_expiry.cmp(&b_htlc.0.cltv_expiry) | ||
|
@@ -990,10 +997,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
}); | ||
|
||
let mut outputs: Vec<TxOut> = Vec::with_capacity(txouts.len()); | ||
let mut scripts: Vec<Script> = Vec::with_capacity(txouts.len()); | ||
let mut htlcs_included: Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)> = Vec::with_capacity(txouts.len() + included_dust_htlcs.len()); | ||
for (idx, mut out) in txouts.drain(..).enumerate() { | ||
outputs.push(out.0); | ||
if let Some((mut htlc, source_option)) = out.1.take() { | ||
for (idx, (out, (mut htlc_data, script))) in txouts.drain(..).enumerate() { | ||
outputs.push(out); | ||
scripts.push(script); | ||
if let Some((mut htlc, source_option)) = htlc_data.take() { | ||
htlc.transaction_output_index = Some(idx as u32); | ||
htlcs_included.push((htlc, source_option)); | ||
} | ||
|
@@ -1006,7 +1015,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
lock_time: ((0x20 as u32) << 8*3) | ((obscured_commitment_transaction_number & 0xffffffu64) as u32), | ||
input: txins, | ||
output: outputs, | ||
}, non_dust_htlc_count, htlcs_included) | ||
}, non_dust_htlc_count, htlcs_included, scripts) | ||
devrandom marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
#[inline] | ||
|
@@ -1423,8 +1432,10 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
let localtx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, sig, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey.as_ref().unwrap()); | ||
|
||
let remote_keys = self.build_remote_transaction_keys()?; | ||
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0; | ||
let remote_signature = self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) | ||
let commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw); | ||
let remote_initial_commitment_tx = commitment_tx.0; | ||
let scripts = commitment_tx.3; | ||
let remote_signature = self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx, &scripts, &self.their_cur_commitment_point.unwrap()) | ||
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0; | ||
|
||
// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish. | ||
|
@@ -1743,7 +1754,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
let mut local_commitment_tx = { | ||
let mut commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, feerate_per_kw); | ||
let htlcs_cloned: Vec<_> = commitment_tx.2.drain(..).map(|htlc| (htlc.0, htlc.1.map(|h| h.clone()))).collect(); | ||
(commitment_tx.0, commitment_tx.1, htlcs_cloned) | ||
(commitment_tx.0, commitment_tx.1, htlcs_cloned, commitment_tx.3) | ||
}; | ||
let local_commitment_txid = local_commitment_tx.0.txid(); | ||
let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all(&local_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]); | ||
|
@@ -3149,8 +3160,10 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
/// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) | ||
fn get_outbound_funding_created_signature(&mut self) -> Result<(Signature, Transaction), ChannelError> { | ||
let remote_keys = self.build_remote_transaction_keys()?; | ||
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0; | ||
Ok((self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) | ||
let commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw); | ||
let remote_initial_commitment_tx = commitment_tx.0; | ||
let scripts = commitment_tx.3; | ||
Ok((self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx, &scripts, &self.their_cur_commitment_point.unwrap()) | ||
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0, remote_initial_commitment_tx)) | ||
} | ||
|
||
|
@@ -3458,7 +3471,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> { | |
htlcs.push(htlc); | ||
} | ||
|
||
let res = self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, self.our_to_self_delay, &self.secp_ctx) | ||
let res = self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, self.our_to_self_delay, &self.secp_ctx, &remote_commitment_tx.3, &self.their_cur_commitment_point.unwrap()) | ||
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?; | ||
signature = res.0; | ||
htlc_signatures = res.1; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it should probably be a vec containing pairs, not two vecs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The outputs vec is buried inside the
Transaction
object, so I assume this has to wait until we move to tx construction in the signer.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you're thinking of moving the redeem script vec into
Transaction
?