fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@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

fuzz: add chanmon holder signer fuzz ops - #4660

Closed
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops
Closed

fuzz: add chanmon holder signer fuzz ops#4660
joostjager wants to merge 1 commit into
lightningdevkit:mainfrom
joostjager:fuzz-chanmon-holder-signer-ops

Conversation

@joostjager

Copy link
Copy Markdown
Contributor

Allow chanmon consistency inputs to block and later unblock holder-side signing operations. This lets focused force-close fuzzing reuse the signer-op machinery without carrying the larger mining and settlement model.

I split this out ahead of the broader force-close fuzzing work so we can review the signer-op modeling independently. The main question is whether these holder-side unblock actions are worth spending dedicated chanmon consistency opcodes on, or whether we should keep the opcode surface smaller and rely on final cleanup to re-enable them.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 4, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from 994d779 to ba0e4c5CompareJune 4, 2026 11:58
@joostjager
joostjager marked this pull request as ready for review June 4, 2026 14:44
@joostjagerjoostjager self-assigned this Jun 4, 2026
@ldk-claude-review-bot

ldk-claude-review-bot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Good - the fuzzer uses _test_utils, so the is_signer_available checks are active.

I've now thoroughly reviewed the entire diff. The changes are correct:

  1. SUPPORTED_SIGNER_OPS expansion: Array correctly updated from 4 to 6 with consistent size annotation.
  2. enable_holder_signer_ops(): Correctly only calls monitor.signer_unblocked() (not node.signer_unblocked()) since SignHolderCommitment and SignHolderHtlcTransaction are exclusively used in chain monitor / on-chain claim paths.
  3. settle_all(): Correctly adds monitor.signer_unblocked() alongside existing signer_unblocked() to ensure both live-channel and on-chain claim retries happen during finalization.
  4. New opcodes 0xd3-0xd5: Follow the established pattern for per-node signer op toggling.
  5. Disable/enable lifecycle: disable_supported_ops_for_all_signers iterates the same SUPPORTED_SIGNER_OPS array, so all 6 ops are consistently disabled and can be individually re-enabled.

No issues found.

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

Are there any heuristics on when to save vs spend fuzz opcodes? I'm not sure how to make that call, probably @TheBlueMatt should take a look. We can always update post-merge though, I suppose.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
Comment on lines +3406 to +3407
// Keep holder signer unblocks adjacent to the existing signer op
// bytes. The helper re-enables both holder-side operations for

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.

"Adjacent" makes me think these bytes should be 0xd3..d5, so I find that a bit confusing.

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.

Hm yes they were adjacent in an earlier version of this. Moved.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
self.node.timer_tick_occurred();
}

// Re-enables holder-side signer operations and asks the chain monitor to

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 think the commit message could be improved. It references a larger refactor, which I'm not sure is helpful as someone without much context, and I don't think it explains the "why" of the diff as it is stand-alone.

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.

Also a left-over from cherry-picking these changes, fixed.

Comment threadfuzz/src/chanmon_consistency.rs Outdated
// bytes. The helper re-enables both holder-side operations for
// every signer owned by the selected node, matching the existing
// key-manager-wide blocking model.
0xe4 => harness.nodes[0].enable_holder_signer_ops(),

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.

Other bytes of this fuzzer seem much more granular and enable/unblock on a per-op and per-channel basis. Maybe we could document why we're taking a more sweeping approach here? Also "the existing key-manager-wide blocking model" -- what does that mean?

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.

It's to save fuzz opcode byte space. Also not sure which trade-off is right here.

"the existing key-manager-wide blocking model" refers to signing being disabled for all channels at once, and enabling mirroring that. Improved comment.

@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

Allow chanmon consistency fuzz inputs to block holder-side signer
operations and later retry monitor-driven claim signing. This gives
force-close sequences a way to cover local on-chain claim
construction while reusing the harness' existing signer-op blocking
machinery.
@joostjager
joostjagerforce-pushed the fuzz-chanmon-holder-signer-ops branch from ba0e4c5 to 633aff4CompareJune 8, 2026 07:36

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

Seems fine to do this IMO but also weird to do it when we don't support FCing? Doesn't seem like a large commit to just include in an FC PR (or as a followup).

@joostjager

Copy link
Copy Markdown
ContributorAuthor

As mentioned in the PR description, I split it out to discuss and review separately. The force close PR is big already.

But agreed that this is merging code that doesn't do much at the moment. Can cherry-pick it back into the bigger PR too.

@joostjager

Copy link
Copy Markdown
ContributorAuthor

Closing because of reason mentioned above, but will carry over conclusion to the FC PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@joostjager@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@valentinewallace