Skip to content
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

fix(api): idempotency bug in registerBroadcastHandler #3558

Merged
merged 5 commits into from
Nov 16, 2023

Conversation

vindard
Copy link
Contributor

@vindard vindard commented Nov 15, 2023

Description

In PR #3550, by fixing the idempotency issue where an InvalidLedgerTransactionStateError is thrown if the handler is re-run and records a reconciliation transaction (see traces), we introduced a new bug where multiple reconciliation transaction are created on re-run.

This PR cleans up the fix from #3550 by introducing an explicit isOnChainFeeReconciliationTxn check and it fixes the new multiple-reconciliation-txns bug.

@github-actions github-actions bot added the core label Nov 15, 2023
@vindard vindard requested review from dolcalmi and jireva November 15, 2023 21:58
@vindard vindard force-pushed the onchain-fee-reconciliation branch from d2cdb7b to 28279fe Compare November 16, 2023 01:06
export const isOnChainFeeReconciliationTxn = (
txn: LedgerTransaction<WalletCurrency>,
): boolean =>
txn.type === LedgerTransactionType.OnchainPayment && txn.address === undefined
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure when we began to use non undefinied/null/empty validation (should be !txn.address we already had an issue in prod with this) also.. should not include bankowner wallet id validation?

Copy link
Contributor Author

@vindard vindard Nov 16, 2023

Choose a reason for hiding this comment

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

In this case I was thinking it should specifically check for the absence of the address property (since the OnChainAddress can technically also be falsy/empty even though it should never be). Or, what sort of issue has this thrown in prod?

should not include bankowner wallet id validation

Maybe not necessary since the reconciliation transaction only ever involves Liabilities:bankOwner account and Asset:OnChain accounts and I believe we only bring in Liabilities accounts in our ledger get methods. address absence should be enough for this check?

Sidenotes:
For this check, ideally it should be a different tx type value instead of also being an onchain_payment so we don't even need the check, but that might be a tricky migration to do. And I also considered maybe setting a custom description for these types of transactions but then there was no way to guarantee that someone couldn't set the same description on normal onchain-payment transactions which would break the heuristic. I switched from checking for satsFee presence to address presence since this is more isolated and might less likely eventually be populated on the reconciliation-type transactions that get constructed inside FeeOnlyEntryBuilder.

Copy link
Collaborator

Choose a reason for hiding this comment

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

at least with validations in data from external services we must be more "defensive", we cant guarantee the undefined so it is safer just to use !txn.address

FYI: the error was a validation using undefined and a service returning null value (typescript in theory was ok but you know we cant trust TS )

Copy link
Contributor Author

@vindard vindard Nov 16, 2023

Choose a reason for hiding this comment

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

Oh yea ok that makes sense.

For here though, address is set explicitly in our translateToLedgerTx function, so there's also less risk of it being something unexpected? We handle the uncertain-falsy-check-from-external-service in the line tx.payee_addresses && tx.payee_addresses.length > 0 inside translateToLedgerTx

@@ -168,7 +169,7 @@ export const setOnChainTxIdByPayoutId = async ({

const bankOwnerWalletId = await getBankOwnerWalletId()
const bankOwnerTxns = txns.filter(
(txn) => txn.satsFee && txn.walletId === bankOwnerWalletId,
(txn) => !isOnChainFeeReconciliationTxn(txn) && txn.walletId === bankOwnerWalletId,
Copy link
Collaborator

Choose a reason for hiding this comment

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

can reconciliation be applied to other wallets (different from bankowner)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mm, it shouldn't be since reconciliations only involve Liabilities:bankOwner and Assets:OnChain. Why do you ask?

Copy link
Collaborator

Choose a reason for hiding this comment

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

if that is the case then walletId validation should be in isOnChainFeeReconciliationTxn

Copy link
Contributor Author

@vindard vindard Nov 16, 2023

Choose a reason for hiding this comment

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

Not sure if that would be helpful here though, because we'd still need to do the txn.walletId === bankOwnerWalletId check since normal non-reconciliation onchain_payment txns can also be from user wallet ids

I switched the check order around to this to try to make this check more intuitive:

(txn) => txn.walletId  === bankOwnerWalletId && !isOnChainFeeReconciliationTxn(txn),

@vindard vindard force-pushed the onchain-fee-reconciliation branch from 28279fe to 810778c Compare November 16, 2023 13:04
@vindard vindard force-pushed the onchain-fee-reconciliation branch from 810778c to df0a32a Compare November 16, 2023 13:31
@vindard vindard requested a review from dolcalmi November 16, 2023 15:27
@vindard vindard merged commit 9b57c22 into main Nov 16, 2023
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants