-
Notifications
You must be signed in to change notification settings - Fork 338
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
Minimize reads to counterparty_claimable_outpoints #3057
base: main
Are you sure you want to change the base?
Minimize reads to counterparty_claimable_outpoints #3057
Conversation
0ee0080
to
2081c15
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #3057 +/- ##
==========================================
+ Coverage 89.82% 90.77% +0.94%
==========================================
Files 116 117 +1
Lines 96466 102525 +6059
Branches 96466 102525 +6059
==========================================
+ Hits 86655 93071 +6416
+ Misses 7264 7029 -235
+ Partials 2547 2425 -122 ☔ View full report in Codecov by Sentry. |
78fd449
to
3aea5ef
Compare
Now this PR should be ready for review. |
@@ -3775,9 +3773,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||
&self.channel_id(), txid); | |||
self.funding_spend_seen = true; | |||
let mut commitment_tx_to_counterparty_output = None; | |||
if (tx.input[0].sequence.0 >> 8*3) as u8 == 0x80 && (tx.lock_time.to_consensus_u32() >> 8*3) as u8 == 0x20 { | |||
let per_commitment_option = self.counterparty_claimable_outpoints.get(&tx.txid()).map(|x| x.iter() | |||
.map(|&(ref a, ref b)| (a.clone(), b.clone())).collect::<Vec<_>>()); |
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.
Had to clone here because calling self.check_spend_counterparty_transaction needs a mut ref to self and without clone self.counterparty_claimable_outpoints.get
will need a immut ref to self.
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.
Its not really a huge deal, but maybe that's an indication we're building the wrong API here - if we're passing a copy of some internal state to a method probably we should....not be doing that :). Instead, maybe we pass an override value (ie "i have this, dont look it up" and check_spend_counterparty_transaction
can do a lookup if no override is provided.
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.
removed per_commitment_option from check_spend signature
This PR is ready for review and merging. |
($txid: expr, $commitment_tx: expr) => { | ||
if let Some(ref latest_outpoints) = $self.counterparty_claimable_outpoints.get($txid) { | ||
($txid: expr, $commitment_tx: expr, $per_commitment_outpoints: expr) => { | ||
if let Some(ref latest_outpoints) = $per_commitment_outpoints { |
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.
While you're here, mind seeing if you can make this a function instead of a macro?
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.
ok, i tried this.
Both check_htlc_fails
and fail_unbroadcast_htlcs
need mut refernce to self they push/delete from onchain_events_awaiting_threshold_conf
.
and per_commitment_option
uses a immut reference. so i don't think we can do it easily unless i use clone everywhere. (otherwise we somehow have to revamp onchain_events_awaiting_threshold_conf into return of fn or something.)
@@ -2763,15 +2763,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||
// If the channel is force closed, try to claim the output from this preimage. | |||
// First check if a counterparty commitment transaction has been broadcasted: | |||
macro_rules! claim_htlcs { | |||
($commitment_number: expr, $txid: expr) => { | |||
let (htlc_claim_reqs, _) = self.get_counterparty_output_claim_info($commitment_number, $txid, None); | |||
($commitment_number: expr, $txid: expr, $htlcs: expr) => { |
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.
Same here.
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.
same thing as above, claim_htlcs needs a mut reference to self, and per_commitment_option needs a immut reference.
@@ -3235,8 +3235,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||
/// Returns packages to claim the revoked output(s), as well as additional outputs to watch and | |||
/// general information about the output that is to the counterparty in the commitment | |||
/// transaction. | |||
fn check_spend_counterparty_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, logger: &L) | |||
-> (Vec<PackageTemplate>, TransactionOutputs, CommitmentTxCounterpartyOutputInfo) | |||
fn check_spend_counterparty_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, per_commitment_option: Option<&Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>, logger: &L) |
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.
Do you want to go ahead and define a type for this? Doesn't really matter but might leave things cleaner in this PR.
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.
i reverted this change to fn signature, since we are no longer re-using per_commitment_option b/w this and cancel_prev_claims.
We will need some more changes once we implement provide_claim_info, will see if need a new request type here then.
@@ -3775,9 +3773,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||
&self.channel_id(), txid); | |||
self.funding_spend_seen = true; | |||
let mut commitment_tx_to_counterparty_output = None; | |||
if (tx.input[0].sequence.0 >> 8*3) as u8 == 0x80 && (tx.lock_time.to_consensus_u32() >> 8*3) as u8 == 0x20 { | |||
let per_commitment_option = self.counterparty_claimable_outpoints.get(&tx.txid()).map(|x| x.iter() | |||
.map(|&(ref a, ref b)| (a.clone(), b.clone())).collect::<Vec<_>>()); |
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.
Its not really a huge deal, but maybe that's an indication we're building the wrong API here - if we're passing a copy of some internal state to a method probably we should....not be doing that :). Instead, maybe we pass an override value (ie "i have this, dont look it up" and check_spend_counterparty_transaction
can do a lookup if no override is provided.
($counterparty_txid: expr, $htlc_output: expr) => { | ||
if let Some(txid) = $counterparty_txid { | ||
for &(ref pending_htlc, ref pending_source) in self.counterparty_claimable_outpoints.get(&txid).unwrap() { | ||
($htlc_output: expr, $per_commitment_data: expr) => { |
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.
Same here, can this be an fn instead?
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.
this one should be doable,
but it is getting messy really quick, as args/vars for check_htlc_valid_counterparty/log_claim/sca_commitment are intertwined.
I can do this is separate PR.
its current signature as it is extracted to function looks like
fn check_htlc_valid_counterparty<L: Deref>(
&self, htlc_output: &HTLCOutputInCommitment, per_commitment_data: &[(HTLCOutputInCommitment, Option<Box<HTLCSource>>)],
htlc_claim: &Option<HTLCClaim>, input: &TxIn, txid: &Txid, logger: &WithChannelMonitor<L>,
) -> Option<(HTLCSource, PaymentHash, u64)> where L::Target: Logger {
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.
Part of #3076
59eb80e
to
ea5f999
Compare
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.
One question, one nit, otherwise LGTM.
Reads related to current/previous commitment_tx should be explicit and reads related to older commitment_txs should be minimized.
3435f18
to
39900bb
Compare
@@ -3230,7 +3230,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||
/// Attempts to claim a counterparty commitment transaction's outputs using the revocation key and | |||
/// data in counterparty_claimable_outpoints. Will directly claim any HTLC outputs which expire at a | |||
/// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for | |||
/// HTLC-Success/HTLC-Timeout transactions. | |||
/// HTLC-Success/HTLC-Timeout transactions. This function should only be called when claimable HTLC |
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.
I'm not really convinced pushing this on the caller makes sense either? Rather, ISTM it would make sense for this function to just be retryable - we call it whenever we think we have a transaction for it, it tries to use the transaction and if it finds it needs some per_commitment data that it doesn't have it just returns and expects to be called again later.
As part of #3049