-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync: sync all payment updates #1095
Conversation
@JssDWt this looks very smart and the main benefit I see is that we can be truly incremental by fetching only the changed data. |
Take the situation where a payment was
Note that this current PR also syncs all failed payments. Maybe it's worth adding a commit to delete failed payments from the payments database? |
|
I don't mean the same payment. If any other payment succeeds after the pending one is synced, then the
You're right. Only the |
I see. Still there is this question how do we skip that payment if we never filter out payments that were completed after the last_sync_time. Sorry for being Nitty on this, I think the incremental benefit is very valuable by itself just curious if this indeed solves the pending annoying issue. |
Right, so basically it should only be filtered out if the payment has completed successfully, and has a completed_at time that is before the highest payment_time (which is either created_at or) time of the latest sync. That seems unlikely indeed. I agree it should work for the most part, as long as the timestamps are accurate, and all created on the same machine. There's another suspect: https://github.com/breez/breez-sdk/blob/f6c7c8729c51c01ab7a62787bc94c340e590f43a/libs/sdk-core/src/greenlight/node_api.rs#L1851 |
Rather than syncing payments based on the payment time, sync based on the created and updated indices in core lightning. This ensures that all updates are retrieved, also when a payment is updated after the fact. To do this, listsendpays is called, rather than listpays. listsendpays contains a filter based on index. Starting off with the last synced index, fetch all missing newly created payments and updates. It's possible that this particular sync doesn't fetch all payment parts associated to a payment. Therefore, the sendpays are cached into a local database. When a new sync round is done, all known existing parts are fetched from the local database as well, to ensure the resulting sdk payments are 'complete', i.e. they're not missing any parts. This should fix the issue where for closed channels, payments would be marked forever pending.
3c5588a
to
0b1d841
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. It would be great if the indices query would be available also for list_pays freeing us from handling it in low level but unfortunately it is not the case.
let mut key = hex::encode(&send_pay.payment_hash); | ||
key.push('|'); | ||
key.push_str(&send_pay.groupid.to_string()); | ||
if !hash_groups.contains(&key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it makes sense to query from the db directly those that we want? (based on the payment hash and group id).
if let Some(last) = created_invoices.invoices.last() { | ||
new_sync_state.list_invoices_index.created = last.created_index() | ||
} | ||
let updated_invoices = node_client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently we are adding extra call for invoices and payments (created, updated). Did you check perhaps querying by updated is enough? I mean what is the value of updated for a newly create invoice or payment? IF it is the same as the created timestamp than we should be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newly created pays/invoices are not returned when querying the updated index. It's really only for updates to previously created pays/invoices.
@JssDWt do you think it worth that @andrei-21 will check this PR on his issue to get feedback? |
let amount_msat = match send_pay_amount_msat { | ||
Some(amount_msat) => amount_msat, | ||
None => { | ||
agg.amount = None; | ||
return; | ||
} | ||
}; | ||
|
||
if let Some(amount) = agg.amount { | ||
agg.amount = Some(amount + amount_msat); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should fix breez/c-breez#909:
if let Some(send_pay_amount_msat) = send_pay_amount_msat {
agg.amount = Some(agg.amount.unwrap_or(0) + send_pay_amount_msat);
}
Rather than syncing payments based on the payment time, sync based on the created and updated indices in core lightning. This ensures that all updates are retrieved, also when a payment is updated after the fact. To do this, listsendpays is called, rather than listpays. listsendpays contains a filter based on index. Starting off with the last synced index, fetch all missing newly created payments and updates. It's possible that this particular sync doesn't fetch all payment parts associated to a payment. Therefore, the sendpays are cached into a local database. When a new sync round is done, all known existing parts are fetched from the local database as well, to ensure the resulting sdk payments are 'complete', i.e. they're not missing any parts. This should fix the issue where for closed channels, payments would be marked forever pending.
Should fix #1094
Inspiration from https://github.com/ElementsProject/lightning/blob/136244835215ae7fcb48ffcaf3c5bb80c3173348/plugins/pay.c#L415-L533