Skip to content

smite: extend accept_channel oracle with key reuse checks - #259

Merged
morehouse merged 2 commits into
lnfuzz:masterfrom
NishantBansal2003:more-accept-chan-oracles
Oct 8, 2026
Merged

morehouse merged 2 commits into
lnfuzz:masterfrom
NishantBansal2003:more-accept-chan-oracles

Conversation

@NishantBansal2003

@NishantBansal2003 NishantBansal2003 commented Sep 17, 2026 •

Copy link
Copy Markdown
Member

ref: #209 (comment)

Some more oracles added in this PR:

open_channel

  • chain_hash != regtest
  • channel_reserve_satoshis >= funding_satoshis
  • dust_limit_satoshis > 10_000 sat
  • to_self_delay > 2016
  • feerate_per_kw == 0 for non 0FC channels

accept_channel

  • dust_limit_satoshis > 10_000 sat
  • htlc_minimum_msat > max_htlc_value_in_flight_msat
  • htlc_minimum_msat > open_channel.funding_satoshis
  • to_self_delay == 0
  • max_accepted_htlcs == 0
  • pubkey match any pubkeys from open_channel and accept_channel
  • per_commitment_point should not be reused

Notes

  • CLN defaults to_self_delay to 6 in accept_channel on regtest and 144 on mainnet, so I think we should only check that to_self_delay != 0
  • CLN defaults the feerate_per_kw floor to 1 on regtest and 253 on mainnet when accepting the open_channel message, so I think we should only check that feerate_per_kw != 0

Comment thread smite/src/oracles/accept_channel.rs
Comment thread smite/src/oracles/accept_channel.rs Outdated
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite/src/oracles/accept_channel.rs Outdated
Comment thread smite-scenarios/src/executor/tests.rs Outdated
Comment thread smite-scenarios/src/executor/tests/harness.rs Outdated
Comment thread smite/src/oracles/accept_channel.rs
Comment thread smite/src/oracles/accept_channel.rs Outdated
@NishantBansal2003 NishantBansal2003 changed the title smite: extend accept_channel oracle with sanity and key reuse checks smite: extend accept_channel oracle with key reuse checks Sep 30, 2026
@NishantBansal2003
NishantBansal2003 marked this pull request as ready for review September 30, 2026 06:48
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite/src/bolt/types.rs Outdated
Comment thread smite-scenarios/src/executor/tests.rs Outdated
Comment thread smite-scenarios/src/executor/tests.rs Outdated
Comment thread smite/src/oracles/accept_channel.rs Outdated
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite-scenarios/src/executor/tests/harness.rs Outdated
@NishantBansal2003
NishantBansal2003 force-pushed the more-accept-chan-oracles branch from 4b5f3b9 to 6ae5679 Compare October 1, 2026 12:29
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite-scenarios/src/executor/tests.rs Outdated
Comment thread smite-scenarios/src/executor/tests.rs
Comment thread smite/src/pending_channel.rs Outdated
Comment thread smite-scenarios/src/executor/tests/harness.rs Outdated
@morehouse

Copy link
Copy Markdown
Collaborator

It turns out LDK actually reuses payment_basepoints within a pool of 1000 points:

They do this to assist in recovery of funds after data loss. AFAICT, this is a safe legitimate thing to do since the private key for payment_basepoint is never revealed.

So we probably need to rethink our approach here. I think we should refine the oracle to flag only these two cases:

  • target uses any pubkey that we know the privkey for
  • target PCP matches any other target key (except for aliases/retransmit exceptions)

We could do this with a single map that distinguishes between the above types of pubkeys. Something like:

enum KeyOrigin {
  Ours { instruction: usize },
  TargetBasepoint { channel: ChannelId, field: &'static str },
  TargetPcp { channel: ChannelId, field: &'static str, commitment_number: u64 },
}
revealed_pubkeys: HashMap<PublicKey, KeyOrigin>

The checks we would implement:

  • RecvAcceptChannel: check all received pubkeys against the map, reporting a violation if:
    • any basepoints are present as Ours or TargetPcp
    • the first_per_commitment_point matches any entry
  • RecvChannelReady: check second_per_commitment_point against the map, reporting a violation if it matches any entry, unless the entry is TargetPcp with the exact same channel and commitment_number
  • RecvRevokeAndAck: check next_per_commitment_point against the map, reporting a violation if it matches any entry, unless the entry is TargetPcp with the exact same channel and commitment_number

@NishantBansal2003
NishantBansal2003 force-pushed the more-accept-chan-oracles branch from 7c48851 to 359bf31 Compare October 7, 2026 12:18
Comment thread smite/src/pending_channel.rs
Comment thread smite/src/pending_channel.rs Outdated
Comment thread smite-scenarios/src/executor.rs Outdated
Comment thread smite-scenarios/src/executor/tests.rs Outdated
// We will carry forward two funding flows with different temporary channel
// IDs and funding amounts and hence different funded channel IDs.
let first_negotiation = sample_funding_negotiation();
let target_pcp = sample_pubkey(1);

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.

sample_pubkey(1) is also used in the sample open_channel, which makes this test look like it's going to fail once the channel_ready oracle is added.

Suggested change
let target_pcp = sample_pubkey(1);
let target_pcp = sample_pubkey(9);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I assume this is just to clear up the confusion? since we don't execute any negotiate_channel instructions that would add open_channel keys to revealed

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.

Yeah the suggested change is just the minimal change that helps slightly with the confusion. An even better change would rewrite the test so that we're not relying on this hidden behavior (i.e. we injected the negotiation without processing the corresponding open_channel).

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.

BTW I still have some refactorings planned for the executor tests that should make it easier to use the full flow rather than injecting the negotiation as a shortcut. My eventual goal is to avoid injecting any test state into the executor unless absolutely necessary.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

An even better change would rewrite the test so that we're not relying on this hidden behavior (i.e. we injected the negotiation without processing the corresponding open_channel).

Yeah, I also want to avoid injecting negotiations, but currently sample_funding_negotiation().accept_channel reuses pubkeys whose params are used for the further funding flow recv operations. So we won't be able to reach that state without injecting, otherwise we get an oracle violation. But I think this could be simplified once we have instructions for the full flow

Comment thread smite/src/oracles/accept_channel.rs Outdated
Comment thread smite-scenarios/src/executor.rs
Comment thread smite-scenarios/src/executor/tests.rs

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

Ready for squash.

Comment thread smite-scenarios/src/executor/tests/harness.rs Outdated
This prepares for an oracle that detects pubkey reuse by the target.

Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
@NishantBansal2003
NishantBansal2003 force-pushed the more-accept-chan-oracles branch from 79a8e71 to 57f2195 Compare October 8, 2026 06:30
@morehouse
morehouse merged commit a243ab2 into lnfuzz:master Oct 8, 2026
5 checks passed
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.

2 participants