Skip to content

BOLT 12: clarify that offer_amount must be greater than zero#1316

Merged
t-bast merged 1 commit intolightning:masterfrom
vincenzopalazzo:clarify-offer-amount-non-zero
Mar 11, 2026
Merged

BOLT 12: clarify that offer_amount must be greater than zero#1316
t-bast merged 1 commit intolightning:masterfrom
vincenzopalazzo:clarify-offer-amount-non-zero

Conversation

@vincenzopalazzo
Copy link
Contributor

Add explicit requirements that:

  • Writers MUST set offer_amount greater than zero when present
  • Readers MUST NOT respond to offers where offer_amount is zero

This addresses ambiguity about whether offer_amount=0 is valid. Since omitting offer_amount indicates no minimum is required, a zero value when present would be semantically incorrect.

Fixes #1314

Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

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

ACK 8605772, this is obvious and I think it's a bit spammy to explicitly spell it out, but why not.

@rustyrussell WDYT?

@vincenzopalazzo
Copy link
Contributor Author

ACK 8605772, this is obvious and I think it's a bit spammy to explicitly spell it out, but why not.

I agree, but I think if we have this in the spec will be obvious what to do, for instance ldk was accepting it and causing some parsing crash with cln IIRC

Copy link
Collaborator

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

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

Ack

Test vector please!

@vincenzopalazzo
Copy link
Contributor Author

Will create a test vector for this as Rusty suggested!

vincenzopalazzo added a commit to vincenzopalazzo/rust-lightning that referenced this pull request Mar 9, 2026
Per the spec clarification in lightning/bolts#1316:
- Writers MUST set offer_amount greater than zero when present
- Readers MUST NOT respond to offers where offer_amount is zero

Reject amount_msats(0) in the builder with InvalidAmount, and reject
parsed offers with amount=0 (with or without currency) during TLV
deserialization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vincenzopalazzo
Copy link
Contributor Author

Here are two test vectors for bolt12/offers-test.json covering the offer_amount=0 rejection:

  {
    "description": "Invalid: zero offer_amount",
    "valid": false,
    "bolt12": "lno1pqqq5qqkyyp4he0fg7pqje62jmnq78cr0ashv4q06qql58tyd9rhp3t2wuyugtq",
    "field info": "offer_amount is 0",
    "fields": [
      {
        "type": 8,
        "length": 0,
        "hex": ""
      },
      {
        "type": 10,
        "length": 0,
        "hex": ""
      },
      {
        "type": 22,
        "length": 33,
        "hex": "035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42c"
      }
    ]
  },
  {
    "description": "Invalid: zero offer_amount with currency",
    "valid": false,
    "bolt12": "lno1qcp4256ypqqq5qqkyyp4he0fg7pqje62jmnq78cr0ashv4q06qql58tyd9rhp3t2wuyugtq",
    "field info": "offer_amount is 0, offer_currency is USD",
    "fields": [
      {
        "type": 6,
        "length": 3,
        "hex": "555344"
      },
      {
        "type": 8,
        "length": 0,
        "hex": ""
      },
      {
        "type": 10,
        "length": 0,
        "hex": ""
      },
      {
        "type": 22,
        "length": 33,
        "hex": "035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42c"
      }
    ]
  }

Notes:

  • offer_amount (type 8) is encoded as length 0 because HighZeroBytesDroppedBigSize drops all zero bytes, resulting in an empty TLV value (which decodes to 0)
  • offer_description (type 10) is included as an empty string so that amount=0 is the only reason for rejection (without it, the offer would also be invalid for missing description when amount is set)
  • The second vector includes offer_currency=USD (type 6) to test the currency+zero-amount combination
  • Both should be rejected by readers per this spec clarification

Generated with LDK and verified roundtrip (bech32 NoChecksum decodes back to the expected TLV bytes).

vincenzopalazzo added a commit to vincenzopalazzo/rust-lightning that referenced this pull request Mar 9, 2026
Per the spec clarification in lightning/bolts#1316:
- Writers MUST set offer_amount greater than zero when present
- Readers MUST NOT respond to offers where offer_amount is zero

Reject amount_msats(0) in the builder with InvalidAmount, and reject
parsed offers with amount=0 (with or without currency) during TLV
deserialization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
vincenzopalazzo added a commit to vincenzopalazzo/rust-lightning that referenced this pull request Mar 9, 2026
Per the spec clarification in lightning/bolts#1316:
- Writers MUST set offer_amount greater than zero when present
- Readers MUST NOT respond to offers where offer_amount is zero

Reject amount_msats(0) in the builder with InvalidAmount, and reject
parsed offers with amount=0 (with or without currency) during TLV
deserialization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add explicit requirements that:
- Writers MUST set offer_amount greater than zero when present
- Readers MUST NOT respond to offers where offer_amount is zero

This addresses ambiguity about whether offer_amount=0 is valid.
Since omitting offer_amount indicates no minimum is required,
a zero value when present would be semantically incorrect.

Fixes lightning#1314
@vincenzopalazzo vincenzopalazzo force-pushed the clarify-offer-amount-non-zero branch from 8605772 to c092554 Compare March 9, 2026 21:18
t-bast added a commit to ACINQ/eclair that referenced this pull request Mar 10, 2026
This doesn't make any sense, the field should be omitted if any amount
is acceptable: setting it to `0` is confusing.

See lightning/bolts#1316
Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

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

ACK c092554, added to eclair in ACINQ/eclair#3265.

@vincenzopalazzo
Copy link
Contributor Author

Updated also the ldk one with the test vector, so I think we are ready to go? :-)

@t-bast t-bast merged commit 3111193 into lightning:master Mar 11, 2026
@vincenzopalazzo vincenzopalazzo deleted the clarify-offer-amount-non-zero branch March 11, 2026 09:51
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.

Clarify whether offer_amount can be zero

3 participants