Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard
, '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

Track the full list of outpoints a chanmon wants monitoring for - #455

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch
Feb 19, 2020
Merged

Track the full list of outpoints a chanmon wants monitoring for#455
TheBlueMatt merged 3 commits into
lightningdevkit:masterfrom
TheBlueMatt:2020-01-monitor-reload-watch

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 955bed5 to 3125760CompareJanuary 21, 2020 04:25
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3125760 to 5e11836CompareFebruary 5, 2020 20:07
Comment threadlightning/src/ln/channelmonitor.rs Outdated
// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
watch_outputs: HashMap<Sha256dHash, Vec<Script>>,

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.

nit: watch_outputs sounds more like a boolean. watched_ or monitored_ might be more explicit

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hmm, I dont want to imply that they are watched, only that they must be watched. Went with outputs_to_watch.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

(self.watch_outputs.len() as u64).write(writer)?;

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.

this is quite the write function. It might be prudent to break it out into subroutines so it's easier to navigate.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Agreed. We should probably implement serialize on subtypes so that we can just call the write derive macro, but its not particularly worse here, just still-bad.

}
}
self.last_block_hash = block_hash.clone();
for &(ref txid, ref output_scripts) in watch_outputs.iter() {

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.

block_connected could definitely use some comments. Is this a function that's supposed to be called on block connection?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Its called by ManyChannelMonitor::block_connected, which is a https://docs.rs/lightning/0.0.10/lightning/chain/chaininterface/trait.ChainListener.html#tymethod.block_connected . Ideally ChannelMonitor would implement ChainListener too, but we're a ways away from that - #474 implements one step, though it still returns two other values (unlike ChainListener). I'll add a commit that comments this state.

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hmmm I dunno about adding yet-another field for data we already track elsewhere. On the other side it makes testing really easy because if we reuse existent fields we may have ambiguity on which outputs have been effectively confirmed onchain (like it can be either prev local or last local but not both).

Okay for now, but we'll have to refactor and make sense of all this fields at some point..

///
/// Further, the implementer must also ensure that each output returned in
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
/// any spends of any of the outputs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"This set of outputs correspond to in-channel outputs, i.e any output for which LN-specific state is needed to solve them and faithfully execute the protocol. Any miss in registering them may entrain a fund loss"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I'm not sure it matters what the outputs are...maybe in the future we'll register revokeable outputs (which we don't currently do and just send a SpendableOutput event to the user) so that we can identify if we went backwards. I added a note that you may lose funds if you fail just emphasize that it matters, though.

}
}
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
for (idx, script) in outputs.iter().enumerate() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note: enumerate work right now to get outpoint index because we clone the whole output of tx at parsing but if we start to be more picky (like not-watching output in final state like to_remote) it may break

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Right, it would need to change the same as the walk of the return value of block_connected would.

// interface knows about the TXOs that we want to be notified of spends of. We could probably
// be smart and derive them from the above storage fields, but its much simpler and more
// Obviously Correct (tm) if we just keep track of them explicitly.
outputs_to_watch: HashMap<Sha256dHash, Vec<Script>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Have you try to implement this with just returning back Script from remote_commitment_txn_on_chain+prev_local_commitment_tx+current_local_signed_commitment_tx? I think it covers all scripts we care about (well there is also outputs on revoked HTLC-txb but that's a bug we don't track them yet)

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

I have not. I was aiming for "quick and easy" given we have a ton of ongoing larger patches and refactors in that area coming up, so landing something complicated would be a waste of time, and a bunch of time. Up to you if you want me to try another way, though.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
}
}

/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Should be called by ManyChannelMonitor implementation"

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sadly, it can't be - its not pub (I have a patch for this, but too many in-flight PRs right now). Its only called by SimpleManyChannelMonitor (which is a typo here, now fixed).

@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from 3c10c69 to af4c5a2CompareFebruary 17, 2020 22:41
@TheBlueMattTheBlueMatt added this to the 0.0.10 milestone Feb 17, 2020

@ariardariard left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jkczyzjkczyz 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.

Deferring to @ariard on the approach given he's refactoring the code. Left some minor comments.

Comment threadlightning/src/ln/channelmonitor.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Comment threadlightning/src/ln/functional_test_utils.rs Outdated
Upon deserialization/reload we need to be able to register each
outpoint which spends the commitment txo which a channelmonitor
believes to be on chain. While our other internal tracking is
likely sufficient to regenerate these, its much easier to simply
track all outpouts we've ever generated, so we do that here.
This tests, after each functional test, that if we serialize and
reload all of our ChannelMonitors we end up tracking the same set
of outputs as before.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-01-monitor-reload-watch branch from af4c5a2 to 5fceb0fCompareFebruary 18, 2020 23:23
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Address Jeff's comments. Will merge after Travis passes.

@TheBlueMatt
TheBlueMatt merged commit 29d14dd into lightningdevkit:masterFeb 19, 2020
@TheBlueMattTheBlueMatt modified the milestones: 0.0.10, 0.0.11Feb 26, 2020
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.

4 participants

@TheBlueMatt@arik-so@jkczyz@ariard