Skip to content
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

Implement claiming of revoked HTLC transactions by ChannelMonitor #163

Merged
merged 3 commits into from
Sep 13, 2018

Conversation

ariard
Copy link

@ariard ariard commented Sep 8, 2018

Still working on others parts of #137. Implement claiming of revoked HTLC-Success/HTLC-timeout transactions in check_spend_remote_transaction that as I understand the TODO was all about ?
Will add/finish test in ChannelManager with others commits tomorrow.

total_value += tx.output[0].value;
}

key_materials.push((redeemscript, per_commitment_key));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buffering key materials to create only one transaction even if inputs are from unrelated commitment_tx

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is necessary - there cant be two inputs pointing to two different remote_commitment_txn_on_chain as the commitment txn would be double-spends.

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first glance looks good, maybe replace the TODO comment with a comment describing what we're doing here, but definitely needs tests (All the claim stuff needs more tests, but at least adding new cases should get tested).



if tx.output[0].script_pubkey == revokeable_p2wsh { //HTLC transactions have one txin, one txout
inputs.push(TxIn {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should try to honor the CLTV_SHARED_CLAIM_BUFFER here - splitting out inputs into separate transactions if they expire too soon.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm in case of HTLC-Success/Timeout transactions aren't we more affected by CSV delay ? If so I think we want to follow the same delay buffer as for a CLTV but we maybe need to update comment of CLTV_SHARED_CLAIM_BUFFER. And here, if it's HTLC-Success/Timemout transactions, I think we can only have one input so no case of multi-inputs to separate ?

total_value += tx.output[0].value;
}

key_materials.push((redeemscript, per_commitment_key));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is necessary - there cant be two inputs pointing to two different remote_commitment_txn_on_chain as the commitment txn would be double-spends.

@ariard ariard force-pushed the claim_revoked_htlc_tx branch 3 times, most recently from 7d07498 to f52f666 Compare September 11, 2018 01:58
let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
assert!(node_txn.len() >= if has_htlc_tx == HTLCType::NONE { 0 } else { 1 } + if has_penalty_tx == PenaltyType::NONE { 0 } else { 1 });
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the commitment_tx ternary has it's wasn't making sense on revoked_tx case, but tell me on this and other changes of test_txn_broadcast, maybe more assert! needed

}

(txn_to_broadcast, (commitment_txid, watch_outputs))
}

/// Attempst to claim a remote HTLC-Success/HTLC-Timeout s outputs using the revocation key
fn check_spend_remote_htlc(&self, tx: &Transaction, commitment_number: u64) -> Vec<Transaction> {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was refactored mainly to avoid double-locking of remote_commitment_tx_on_chain as block_connected has only them to match HTLC transactions, so a part of old commit was moved there.

@ariard
Copy link
Author

ariard commented Sep 11, 2018

With set_their_delayed_payment_base_key as I think Channel passing it to monitor at channel opening is the only way to get it ?
ChannelMonitor still needs more tests, for example the ones on remote ouputs from revoked commit tx I believe, will open a checked box on #137 to map all cases.

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Nice work!

@@ -563,6 +563,7 @@ impl Channel {
&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_delayed_payment_base_key(&msg.delayed_payment_basepoint);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just merge this with set_their_htlc_base_key? They're always called together anyway...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, done


let mut txn_to_broadcast = Vec::new();

let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not a commitment tx :p

}

(txn_to_broadcast, (commitment_txid, watch_outputs))
}

/// Attempst to claim a remote HTLC-Success/HTLC-Timeout s outputs using the revocation key
fn check_spend_remote_htlc(&self, tx: &Transaction, commitment_number: u64) -> Vec<Transaction> {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why the space here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a mine dumb copy-paste!

broadcaster.broadcast_transaction(tx);
} else {
let remote_commitment_txn_on_chain = self.remote_commitment_txn_on_chain.lock().unwrap();
for (txid, commitment_number) in remote_commitment_txn_on_chain.iter() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remote_commitment_txn_on_chain is a HashMap, so you should be able to do a get instead of an iter() over the whole thing.

for tx in txn_matched {
for txin in tx.input.iter() {
if self.funding_txo.is_none() || (txin.previous_output.txid == self.funding_txo.as_ref().unwrap().0.txid && txin.previous_output.vout == self.funding_txo.as_ref().unwrap().0.index as u32) {
let (mut txn, new_outputs) = self.check_spend_remote_transaction(tx, height);
let (mut remote_txn, new_outputs) = self.check_spend_remote_transaction(tx, height);
txn.append(&mut remote_txn);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why append instead of just txn = remote_txn? Are you accidentally calling broadcast_transaction for txn from multiple ChannelMonitors multiple times? Maybe move txn into the per-tx loop?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified, but you mean broadcasting in per-tx loop ? Does it change something for broadcaster?

@@ -3108,9 +3108,11 @@ mod tests {

#[derive(PartialEq)]
enum HTLCType { NONE, TIMEOUT, SUCCESS }
fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
#[derive(PartialEq)]
enum PenaltyType { NONE, COMMIT, HTLC }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is COMMIT PenaltyType unused? Looks like its somewhat duplicative with the revoked_tx option?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop it for now but I think I'm gonna use in a next commit to test spending of remote outputs on revoked commitment tx

@@ -3126,7 +3128,9 @@ mod tests {
}
}
}
assert_eq!(res.len(), 1);
if revoked_tx.is_none() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just check against revoked is_none() and PenaltyType is HTLC so you check the call is doing something (and doesn't change existing logic).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified, but you mean against revoked_is_some() right?

@@ -3145,6 +3149,21 @@ mod tests {
}
assert_eq!(res.len(), 2);
}

if has_penalty_tx == PenaltyType::HTLC {
if let Some(revoked_tx) = revoked_tx {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just unwrap() to make sure the caller is sane? This is a test.....

Antoine Riard added 3 commits September 12, 2018 23:17
Needed to build redeemscript on HTLC-Success/HTLC-Timeout tx from
remote revoked commitment tx
Refactor check_spend_remote_transaction in part to check_spend_remote_htlc to
avoid lock mess in block_connected. We need
remote_commitment_txn_on_chain to match remote HTLC tx
@TheBlueMatt TheBlueMatt merged commit 01c8e4f into lightningdevkit:master Sep 13, 2018
TheBlueMatt added a commit that referenced this pull request Sep 14, 2018
Optimize some ChannelMonitor stuff after #163
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants