Skip to content

smite-ir: implement AnnouncementSignaturesGenerator - #250

Open
devvaansh wants to merge 3 commits into
lnfuzz:masterfrom
devvaansh:announcement-signatures-generator
Open

devvaansh wants to merge 3 commits into
lnfuzz:masterfrom
devvaansh:announcement-signatures-generator

Conversation

@devvaansh

@devvaansh devvaansh commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Generates programs that open, fund, and confirm an announced channel, then sign and send announcement_signatures for it.

BuildAnnouncementSignatures has had no producer since #124, so no generated program could reach it. The message only means anything on a channel the target has already opened with us, so the generator emits the funding flow itself rather than relying on a preceding one: the channel id, the funding keys, and the short_channel_id all have to come from the same channel, and pick_variable cannot promise that.

The signatures cover the channel_announcement body the target rebuilds for itself, so every field has to match what it already knows. That is why the features are empty and the scid is looked up from the confirmed funding output rather than loaded. It is also why the node secret now comes from the context: the Noise static key is our node id on the wire and is what targets verify node_signature against, but it was private to smite-scenarios and absent from ProgramContext, so a LoadPrivateKey literal could never produce a valid signature. LoadLocalNodeSecretFromContext is not param-mutable, since OperationParamMutator can already invalidate a signature through the message body.

announcement_signatures is only legal on an announced channel, so append_open_channel takes an announce flag. Announcing also restricts the channel type, since LDK and LND reject an announced channel that negotiates option_scid_alias or option_zeroconf; a test pins the excluded list to that property so a new variant fails rather than silently changing what announced channels negotiate. Both existing call sites pass false, so the flows they generate are unchanged.

Tested with unit tests covering the ordering of the flow, that the channel is announced with an announceable type and enough confirmations, and that each signed field is tied to the channel being announced: the scid to the funding output, bitcoin_key_1 to the key that signed funding_created, bitcoin_key_2 to the funding pubkey from accept_channel, and the node signature to the context key. Not yet fuzzed against the targets; I'll follow up with coverage once I've run a campaign.

Ref: #71

Loads our node's secret key from the program context, so that programs
can sign gossip as the identity the target knows us by.

The Noise static key is our node id on the wire, and it is what targets
verify our gossip signatures against. Signing with a LoadPrivateKey
literal instead can never produce a valid signature, so
announcement_signatures has no way to get past signature verification
today.

The key is not exposed as a mutable parameter. OperationParamMutator can
already invalidate a signature by mutating the message body, and letting
it corrupt our identity as well would just collapse every mutation of
the instruction onto the same path.

The executor test fixture holds a different key than the scenarios use,
so a passing test proves the executor read the context.
announcement_signatures is only legal on an announced channel, so
append_open_channel takes an announce flag that sets channel_flags bit 0.

Announcing also restricts the channel type: LDK and LND reject an
announced channel that negotiates option_scid_alias or option_zeroconf,
neither of which has an announceable short_channel_id. A test pins the
list to that property so a new variant fails rather than silently
changing what announced channels negotiate.

Both existing call sites pass false, so the flows they generate are
unchanged.
Generates programs that open, fund, and confirm an announced channel,
then sign and send announcement_signatures for it.

BuildAnnouncementSignatures has had no producer since it landed, so no
generated program could reach it. The message only means anything on a
channel the target has already opened with us, so the generator emits the
funding flow itself rather than relying on a preceding one: the channel
id, the funding keys, and the short_channel_id all have to come from the
same channel, and pick_variable cannot promise that.

The signatures cover the channel_announcement body the target rebuilds
for itself, so every field has to match what it already knows. That is
why the features are empty, the scid is looked up from the confirmed
funding output rather than loaded, and the node secret comes from the
context.
@devvaansh

devvaansh commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

@morehouse Flagging a tradeoff before review. The generator emits its own funding flow rather than composing with FundingFlowGenerator, since channel_id, the funding keys, and the short_channel_id all have to describe the same channel and pick_variable can't promise that. The cost is duplication: ~42 of its 63 code lines are a near-verbatim copy of FundingFlowGenerator, differing only in the announce flag, the MineBlocks
count, and include_alias.

I'd rather check what the codebase want than guess: on #193 it was decided to merge the funded variant into the existing generator since it was less code overall, and on #228 an append_open_channel helper rather than duplicating the construction logic. Should I extract an append_funding_flow(builder, rng, announce) -> FundingFlowVars that FundingFlowGenerator delegates to and this generator extends (~138 lines down to ~55), or fold announcement_signatures into FundingFlowGenerator behind a flag and drop the separate generator entirely?

The only reason I kept it separate is the AnyGenerator entry, which lets GeneratorInsertionMutator splice an announcement flow on its own.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant