Skip to content

Rework IncomingPayment model#722

Merged
pm47 merged 9 commits intomasterfrom
model-rework-incoming
Dec 19, 2024
Merged

Rework IncomingPayment model#722
pm47 merged 9 commits intomasterfrom
model-rework-incoming

Conversation

@pm47
Copy link
Copy Markdown
Member

@pm47 pm47 commented Oct 23, 2024

We move from a flat model with a single IncomingPayment class and a combination of Origin + ReceivedWith parts to a hierarchical model.

This new model:

  • makes incoming/outgoing databases symmetrical
  • removes impossible combinations allowed in the previous model (e.g. an on-chain origin with a fee-credit part)
  • removes hacks required for the handling of on-chain deposits, which were shoe-horned in what was originally a lightning-only model

Before:

Origin
   |
   `--- Invoice
   |
   `--- Offer
   |
   `--- SwapIn
   |
   `--- OnChain

ReceivedWith
      |
      `--- LightningPayment
      |
      `--- AddedToFeeCredit
      |
      `--- OnChainIncomingPayment
                    |
                    `--- NewChannel
                    |
                    `--- SpliceIn

After:

IncomingPayment
      |
      `--- LightningIncomingPayment
      |             |
      |             `--- Bolt11IncomingPayment
      |             |
      |             `--- Bolt12IncomingPayment
      |
      `--- OnChainIncomingPayment
                    |
                    `--- NewChannelIncomingPayment
                    |
                    `--- SpliceInIncomingPayment
                    |
                    `--- LegacySwapInIncomingPayment
                    |
                    `--- LegacyPayToOpenIncomingPayment

LightningIncomingPayment.Part
      |
      `--- Htlc
      |
      `--- FeeCredit

The handling of backward compatible data is tricky, especially for legacy pay-to-open/pay-to-splice, which can be a mix of lightning parts and on-chain parts, and either Bolt11 or Bolt12. Note that Legacy* classes are not used at all within lightning-kmp, they are just meant to handle pre-existing data in the database.

payment old model new model
Plain Lightning Bolt11 Origin=Invoice, ReceivedWith=LightningPayment Bolt11IncomingPayment
Plain Lightning Bolt12 Origin=Offer, ReceivedWith=LightningPayment Bolt12IncomingPayment
Pre-otf pay-to-open Bolt11 Origin=Invoice, ReceivedWith=NewChannel LegacyPayToOpenIncomingPayment
Pre-otf pay-to-splice Bolt11 Origin=Invoice, ReceivedWith=SpliceIn LegacyPayToOpenIncomingPayment
Pre-otf pay-to-open Bolt12 Origin=Offer, ReceivedWith=NewChannel LegacyPayToOpenIncomingPayment
Pre-otf pay-to-splice Bolt12 Origin=Offer, ReceivedWith=SpliceIn LegacyPayToOpenIncomingPayment
Legacy trusted swap-in Origin=SwapIn, ReceivedWith=NewChannel LegacySwapInIncomingPayment
Swap-in potentiam open Origin=OnChain, ReceivedWith=NewChannel NewChannelIncomingPayment
Swap-in potentiam splice Origin=OnChain, ReceivedWith=SpliceIn SpliceInIncomingPayment

@pm47 pm47 requested a review from t-bast October 23, 2024 10:25
Comment thread src/commonMain/kotlin/fr/acinq/lightning/io/Peer.kt
Comment thread src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt
Copy link
Copy Markdown
Member

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

Looks good to me, this is a good clean-up! It's simpler than I thought, the hard part is probably the DB part on the Phoenix side?

I don't see any issue on the lightning-kmp side, everything is much clearer now.

Comment thread src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt Outdated
Comment thread src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt Outdated
Comment thread src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt Outdated
Comment thread src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt Outdated
Comment thread src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt Outdated
Comment thread src/commonMain/kotlin/fr/acinq/lightning/io/Peer.kt Outdated
t-bast
t-bast previously approved these changes Oct 24, 2024
Copy link
Copy Markdown
Member

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

LGTM as far as backwards-compatibility doesn't create any issue for Phoenix!

t-bast
t-bast previously approved these changes Nov 20, 2024
Copy link
Copy Markdown
Member

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

LGTM 👍

pm47 added 8 commits December 17, 2024 17:42
This allows for a unified identifier for all payments that affect the
balance.

For `IncomingPayment`, the `payment_hash` is currently abusively used as
a primary key, which is hacky in the context of swap-ins. To minimize
integration effort, the payment id simply derived from that existing
key, with no other changes.
We move from a flat model with a single `IncomingPayment` class and a
combination of `Origin` + `ReceivedWith` parts to a hierarchical model.

This new model:
- makes incoming/outgoing databases symmetrical
- removes impossible combinations allowed in the previous model (e.g. an
  on-chain origin with a fee-credit part)
- removes hacks required for the handling of on-chain deposits, which
  were shoe-horned in what was originally a lightning-only model

Before:
```
Origin
   |
   `--- Invoice
   |
   `--- Offer
   |
   `--- SwapIn
   |
   `--- OnChain

ReceivedWith
      |
      `--- LightningPayment
      |
      `--- AddedToFeeCredit
      |
      `--- OnChainIncomingPayment
                    |
                    `--- NewChannel
                    |
                    `--- SpliceIn
```

After:
```
IncomingPayment
      |
      `--- LightningIncomingPayment
      |             |
      |             `--- Bolt11IncomingPayment
      |             |
      |             `--- Bolt12IncomingPayment
      |
      `--- OnChainIncomingPayment
                    |
                    `--- NewChannelIncomingPayment
                    |
                    `--- SpliceInIncomingPayment
                    |
                    `--- LegacySwapInIncomingPayment
                    |
                    `--- LegacyPayToOpenIncomingPayment

LightningIncomingPayment.Part
      |
      `--- LightningPayment
      |
      `--- AddedToFeeCredit
```

The handling of backward compatible data is tricky, especially for
legacy pay-to-open/pay-to-splice, which can be a mix of lightning parts
and on-chain parts, and either Bolt11 or Bolt12. Note that `Legacy*`
classes are not used at all within `lightning-kmp`, they are just meant
to handle pre-existing data in the database.
(Simple rename, no functional changes)

Also:
- `ReceivedWith.LightningPayment` -> `Part.Htlc`
- `ReceivedWith.AddedToFeeCredit` -> `Part.FeeCredit`
Instead, the `parts` are a direct member of `LightningIncomingPayment`.
It makes the object simpler to manipulate and update. Each of them has
a `receivedAt` timestamp, offering more precision.
@pm47 pm47 force-pushed the model-rework-incoming branch from a110612 to bad4ec3 Compare December 17, 2024 16:55
@pm47 pm47 marked this pull request as ready for review December 17, 2024 17:31
Copy link
Copy Markdown
Member

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

A few nits, otherwise LGTM 👍

Comment thread modules/core/src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt Outdated
@pm47 pm47 requested a review from t-bast December 19, 2024 14:08
@pm47 pm47 merged commit 6aab996 into master Dec 19, 2024
@pm47 pm47 deleted the model-rework-incoming branch December 19, 2024 14:55
pm47 added a commit to ACINQ/phoenixd that referenced this pull request Feb 4, 2025
This is a major rework, downstream of:
- ACINQ/lightning-kmp#722
- ACINQ/lightning-kmp#738
- ACINQ/lightning-kmp#739
- ACINQ/lightning-kmp#749

Both the database schema and the serialization method have been completely reworked:
- The database schema moves from one table per payment type to one table for all incoming payments and one table for all outgoing payments. We also move from a multi-column model with custom handling of polymorphism to a single column containing the whole serialized data.
- The serialization moves from json (with serialization classes managed in phoenixd) to a binary format (managed in lightning-kmp). This removes a lot of boiler plate code, allows for factorization between phoenix/phoenixd and makes updating the model a lot easier. Legacy serialization code has been isolated as much as possible in a `migrations` package.

The channels and payments db are now pretty similar.
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.

3 participants