Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fetch shutdown script based on commit_upfront_shutdown_pubkey - #1019

Merged
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey
Aug 9, 2021
Merged

Fetch shutdown script based on commit_upfront_shutdown_pubkey#1019
TheBlueMatt merged 11 commits into
lightningdevkit:mainfrom
jkczyz:2021-07-shutdown-pubkey

Conversation

@jkczyz

@jkczyzjkczyz commented Jul 28, 2021

Copy link
Copy Markdown
Contributor

Rather than fetching a channel's shutdown script from KeysInterface at creation time, do so based on ChannelConfig::commit_upfront_shutdown_pubkey (i.e., either creation or shutdown time).

Additionally, support any acceptable shutdown script pubkey as defined by BOLT 2 while maintaining backwards compatibility with the legacy KeysInterface::get_shutdown_pubkey, which is replaced by KeysInterface::get_shutdown_scriptpubkey.

This change requires storing an optional script as a TLV field for both Channel and ChannelMonitor. Additionally, since the field is now optional, a new ChannelMonitorUpdateStep is needed for when the script is generated at shutdown time.

Fixes#994.

@codecov

codecovBot commented Jul 28, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1019 (b24b4e9) into main (69ee486) will increase coverage by 0.12%.
The diff coverage is 92.15%.

❗ Current head b24b4e9 differs from pull request most recent head 1d3861e. Consider uploading reports for the commit 1d3861e to get more accurate results
Impacted file tree graph

@@ Coverage Diff @@## main #1019 +/- ##
==========================================
+ Coverage 90.79% 90.92% +0.12% 
==========================================
Files 61 62 +1 Lines 31578 32253 +675 ==========================================
+ Hits 28672 29326 +654 - Misses 2906 2927 +21 
Impacted FilesCoverage Δ
lightning/src/ln/mod.rs90.00% <ø> (ø)
lightning/src/util/errors.rs67.30% <0.00%> (-4.13%)⬇️
lightning/src/util/test_utils.rs82.29% <76.00%> (-0.26%)⬇️
lightning/src/chain/channelmonitor.rs90.43% <83.33%> (-0.15%)⬇️
lightning/src/ln/channelmanager.rs86.82% <85.45%> (+1.12%)⬆️
lightning/src/ln/functional_test_utils.rs95.11% <91.66%> (-0.07%)⬇️
lightning/src/ln/script.rs93.75% <93.75%> (ø)
lightning/src/ln/functional_tests.rs97.23% <93.87%> (-0.05%)⬇️
lightning/src/ln/channel.rs89.34% <95.20%> (+0.11%)⬆️
lightning-background-processor/src/lib.rs95.48% <100.00%> (-0.10%)⬇️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69ee486...1d3861e. Read the comment docs.

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from e75d748 to c0bf4fdCompareJuly 28, 2021 23:19
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 05d73ed to 83f3245CompareJuly 30, 2021 04:23
Comment threadlightning/src/chain/channelmonitor.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Oops, this needs a similar test fix in the background-processor as well - https://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commit;h=9218054becc3dcf690bdd8fcf819952ee783365a

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from ade99f8 to 260f269CompareJuly 31, 2021 15:41
Comment threadlightning/src/ln/script.rs Outdated
/// # Panics
///
/// This function may panic if given a segwit program with an invalid length.
pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Self {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we should return an Result here - version needs to be <= 16 so users can totally make it fail, we shouldn't panic in that case, no? Also, why do the conversion to u5 and then call new_witness_program? That seems like a very roundabout way to get there, just push the version followed by the program as done at https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#280-290 (but do the push using push_int which does the right thing here, don't have to resort to manual opcode calculation https://docs.rs/bitcoin/0.27.0/src/bitcoin/blockdata/script.rs.html#706-720 )

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also this will change soon upstream, not sure how that would impact this. rust-bitcoin/rust-bitcoin#617

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, must cleaner like that. Will need to swap NonZeroU8 for WitnessVersion when it is available upstream.

Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/script.rs
Comment threadlightning/src/chain/channelmonitor.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 260f269 to c8ffc05CompareJuly 31, 2021 18:31
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
});
if let Some(monitor_update) = monitor_update {
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
// TODO: How should this be handled?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be handled like any other error - call handle_monitor_err to convert the error into a MsgHandleErrInternal, then store it in a variable outside the lock (like failed_htlcs and chan_option) and handle_error the error outside of the lock.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... in the case of an error should we still send the shutdown message above? Similarly, should an error short-circuit any remaining code (e.g., failing back HTLCs, broadcasting channel update)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in the case of an error should we still send the shutdown message above?

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message, for temporary, we should still send the shutdown.

failing back HTLCs,

We must never, ever forget to fail back htlcs we were told to fail back.

broadcasting channel update

This is only if we force-closed the channel due to an error, I think, so we shouldn't get to this point today if there's a monitor update, but a monitor update could cause us to get there now (if its a permanent one).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ok, this turned out to be a bit more tricky than I imagined. Confirming my understanding below.

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

There are two errors - permanent ones and temporary ones. In the case of permenent, yes, we should force-close instead and send an error message,

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

for temporary, we should still send the shutdown.

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Rebased and added for internal_shutdown, too: a024930

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Change is in 49614d8. Let me know if that is what you had in mind and if there's a simpler way of going about this. Need to do the same for internal_shutdown.

Nope, that's about right. These things are tricky to handle. I left a few specific comments on that commit.

These are handled by handle_monitor_err and handle_error, respectively, IIUC.

That's the MsgHandleErrInternal vs monitor-error distinction, not the permanent-vs-temporary distinction, both of which are handled by handle_monitor_err (and friends)

What I don't quite understand is why we would send shutdown if we aren't certain that our ChannelMonitor has been updated with the shutdown script yet. Is it because if TemporaryError ever becomes a PermanentError, we wouldn't care about the shutdown script since we are force closing in that case?

The Temporary->Permanent thing isn't a big deal, as you note. The real question is what happens if someone gives a Temporary update, and then takes longer to update their ChannelMonitor than we do doing the full closing_signed negotiation (because only afterclosing_signed negotiation could a transaction ever appear on chain with the script contained in the monitor update). Unlike most other monitor updates (at least RevokeAndACK), sending a Shutdown message isn't an immediate lock-in to a new states and the monitor doesn't need to know about it immediately, only before the closing transaction appears on chain.

If we wait for the update to complete here, then we have to add Shutdown resending, which I really don't want to do. An alternative, which is much easier, is to just wait for the monitor update to complete before ever sending a closing_signed, something I can shove in #985

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 10 times, most recently from 9924683 to 621e31eCompareAugust 4, 2021 19:20
Comment threadlightning/src/ln/script.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 621e31e to d808581CompareAugust 4, 2021 20:44

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The ChannelMonitorUpdate changes look good to me, will re-review the rest a bit later but the rest was already basically good IMO.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch 2 times, most recently from 46075b3 to 79eb7daCompareAugust 4, 2021 23:30

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Basically LGTM

Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/util/errors.rs

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some of the new logic in ChannelManager is still sinking in for me, but overall this is looking good! Finished a first complete pass

Comment threadlightning/src/ln/functional_tests.rs

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for all the good feedback! Will see what I can do about the missing test coverage. It's a matter how easy it is to induce some error conditions (e.g., monitor update failing, keys provider giving an incompatible script).

Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/functional_tests.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from 3f87283 to d6aec00CompareAugust 6, 2021 04:18
msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

@valentinewallacevalentinewallaceAug 6, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the intended behavior to only broadcast a channel update if the channel was < ChannelState::FundingSent? Because I think this line will only return true if that's the situation 🤔 .

I think coverage is missing here too. I get that we're in "crunch time" though, so I'm pretty fine on punting tests if it comes to it

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I believe it may also occur if we already handled a shutdown from the counterparty but didn't yet send our own shutdown.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Ah, actually now that I think of it, you're right. Since we lock channel_state, the situation that I mentioned can't occur.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe this code block is actually now unreachable. We return an Err in case we're ready to shut down here instead of getting into this block.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Removed code block from internal_shutdown rather than here as discussed on Slack.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't really find anything to comment on, this is shaping up from my PoV!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prob not worth checking to see if they set a script here (which would make them a buggy peer), right?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

Comment threadlightning/src/ln/channel.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from d6aec00 to fbf624eCompareAugust 9, 2021 05:04

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added the requested tests. For testing IncompatibleShutdownScript errors, I needed to add InitFeatures to NodeCfg and pass it when connecting peers (see separate commit 2e03385) since ChannelManager::close_channel pulls the features from per_peer_state. We could probably use this in some of the test utilities instead of passing &InitFeatures::known() everywhere, but that's a more involved follow-up.

It looks like this was rebased without any conflict, was there a reason for the rebase I missed?

I was probably proactively rebasing just in case. 🙂

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront, if I understand BOLT 2 correctly.

Comment threadlightning/src/ln/channel.rs
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from fbf624e to 76307ceCompareAugust 9, 2021 12:58
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I was probably proactively rebasing just in case. slightly_smiling_face

Oops, in general is it possible to avoid this? It makes it hard to diff-tree between revisions to see what changed.

@valentinewallacevalentinewallace left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK mod one last clarification. Thanks for the additional test coverage added!

@@ -843,6 +854,16 @@ impl<Signer: Sign> Channel<Signer> {
}
} else { None };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

They are allowed to support the feature but not necessarily set the shutdown script upfront,

IIUC, this is allowed unless both peers advertise support for the feature, in which case setting a script is required: from BOLT 2

I was concerned about the case where a peer didn't advertise the feature but still set a shutdown script up front, but checked the spec and that seems to be allowed 🤷

msg: shutdown_msg
});

if chan_entry.get().is_shutdown() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I guess I just wanna get clear that this code block (and similar) are necessary, and what situation they would run in? Double checked and couldn't find any test coverage by adding prints

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ACK post-squash.

jkczyz added 11 commits August 9, 2021 15:55
BOLT 2 enumerates the script formats that may be used for a shutdown
script. KeysInterface::get_shutdown_pubkey returns a PublicKey used to
form one of the acceptable formats (P2WPKH). Add a ShutdownScript
abstraction to encapsulate all accept formats and be backwards
compatible with P2WPKH scripts serialized as the corresponding
PublicKey.
KeysInterface::get_shutdown_pubkey is used to form P2WPKH shutdown
scripts. However, BOLT 2 allows for a wider variety of scripts. Refactor
KeysInterface to allow any supported script while still maintaining
serialization backwards compatibility with P2WPKH script pubkeys stored
simply as the PublicKey.
Add an optional TLV field to Channel and ChannelMonitor to support the
new format, but continue to serialize the legacy PublicKey format.
Similar to 2745bd5, this ensures that
ChannelManager knows about the features its peers.
When a shutdown script is omitted from open_channel or accept_channel,
it must be provided when sending shutdown. Generate the shutdown script
at channel closing time in this case rather at channel opening.
This requires producing a ChannelMonitorUpdate with the shutdown script
since it is no longer known at ChannelMonitor creation.
When handling shutdown messages, Channel cannot move to
ChannelState::ShutdownComplete. Remove the code in ChannelManager that
adds a MessageSendEvent::BroadcastChannelUpdate in this case since it is
unreachable.
@jkczyz
jkczyzforce-pushed the 2021-07-shutdown-pubkey branch from b24b4e9 to 1d3861eCompareAugust 9, 2021 21:00
@TheBlueMatt
TheBlueMatt merged commit 767f120 into lightningdevkit:mainAug 9, 2021
Sign up for freeto 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.

Fetch KeysInterface's get_shutdown_pubkey at close-time with !commit_upfront_shutdown_pubkey

3 participants

@jkczyz@TheBlueMatt@valentinewallace