Skip to content

Commit

Permalink
fix(api): withdrawal volumes handling for failed payments (#3555)
Browse files Browse the repository at this point in the history
* refactor: nest existing facade tests

* test: add passing volume tests

* test: add failed-payment volume tests

* fix: incorporate failed payment in withdrawal volume calc

* test: add reimbursed-fee-payment volume tests

* fix: incorporate fee reimbursements in withdrawal volume

* test: add delayed-failed-payment volume tests

* fix: add 'original_journal' timestamp check for failed payments
  • Loading branch information
vindard authored Nov 16, 2023
1 parent 4bf8493 commit b87bfcd
Show file tree
Hide file tree
Showing 4 changed files with 614 additions and 344 deletions.
27 changes: 23 additions & 4 deletions core/api/src/domain/accounts/limits-volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,21 @@ const WalletVolumesAggregator = ({
return volumeInUsdAmount
}

return { outgoingUsdAmount }
const incomingUsdAmount = (): UsdPaymentAmount => {
let volumeInUsdAmount = ZERO_CENTS
for (const walletVolume of walletVolumes) {
const incomingUsdAmount =
walletVolume.incomingBaseAmount.currency === WalletCurrency.Btc
? priceRatio.convertFromBtc(walletVolume.incomingBaseAmount as BtcPaymentAmount)
: (walletVolume.incomingBaseAmount as UsdPaymentAmount)

volumeInUsdAmount = calc.add(volumeInUsdAmount, incomingUsdAmount)
}

return volumeInUsdAmount
}

return { outgoingUsdAmount, incomingUsdAmount }
}

export const AccountTxVolumeRemaining = (
Expand Down Expand Up @@ -73,10 +87,13 @@ export const AccountTxVolumeRemaining = (
priceRatio: WalletPriceRatio
walletVolumes: TxBaseVolumeAmount<WalletCurrency>[]
}): Promise<UsdPaymentAmount | ValidationError> => {
const outgoingUsdVolumeAmount = WalletVolumesAggregator({
const aggregator = WalletVolumesAggregator({
walletVolumes,
priceRatio,
}).outgoingUsdAmount()
})

const outgoingUsdVolumeAmount = aggregator.outgoingUsdAmount()
const incomingUsdVolumeAmount = aggregator.incomingUsdAmount()

const { withdrawalLimit: limit } = accountLimits
const limitAmount = paymentAmountFromNumber({
Expand All @@ -87,11 +104,13 @@ export const AccountTxVolumeRemaining = (

addAttributesToCurrentSpan({
"txVolume.outgoingInBase": `${outgoingUsdVolumeAmount.amount}`,
"txVolume.incomingInBase": `${incomingUsdVolumeAmount.amount}`,
"txVolume.threshold": `${limitAmount.amount}`,
"txVolume.limitCheck": AccountLimitsType.Withdrawal,
})

return calc.sub(limitAmount, outgoingUsdVolumeAmount)
const netVolumeAmount = calc.sub(outgoingUsdVolumeAmount, incomingUsdVolumeAmount)
return calc.sub(limitAmount, netVolumeAmount)
}

const tradeIntraAccount = async ({
Expand Down
30 changes: 30 additions & 0 deletions core/api/src/services/ledger/facade/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { timestampDaysAgo } from "@/utils"

import { paymentAmountFromNumber } from "@/domain/shared"
import { addAttributesToCurrentSpan } from "@/services/tracing"
import { MS_PER_DAY } from "@/config"

export const TxnGroups = {
allPaymentVolumeSince: [
Expand All @@ -21,6 +22,7 @@ export const TxnGroups = {
],
externalPaymentVolumeSince: [
LedgerTransactionType.Payment,
LedgerTransactionType.LnFeeReimbursement,
LedgerTransactionType.OnchainPayment,
],
intraledgerTxBaseVolumeSince: [
Expand Down Expand Up @@ -71,6 +73,34 @@ const TxVolumeAmountSinceFactory = () => {
$and: [{ timestamp: { $gte: timestamp } }],
},
},
{
$lookup: {
from: "medici_transactions",
localField: "_original_journal",
foreignField: "_journal",
as: "original_transactions",
},
},
{
$addFields: {
is_transaction_valid: {
$or: [
{ $eq: [{ $size: "$original_transactions" }, 0] },
{
$gte: [
{ $arrayElemAt: ["$original_transactions.datetime", 0] },
new Date(Date.now() - MS_PER_DAY),
],
},
],
},
},
},
{
$match: {
is_transaction_valid: true,
},
},
{
$group: {
_id: null,
Expand Down
11 changes: 9 additions & 2 deletions core/api/test/helpers/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,10 @@ export const recordSendLnPayment = async <S extends WalletCurrency>({
bankFee,
displayAmounts,
}: RecordExternalTxTestArgs<S>) => {
const paymentHash = crypto.randomUUID() as PaymentHash
const { metadata, debitAccountAdditionalMetadata, internalAccountsAdditionalMetadata } =
LedgerFacade.LnSendLedgerMetadata({
paymentHash: crypto.randomUUID() as PaymentHash,
paymentHash,
pubkey: crypto.randomUUID() as Pubkey,
feeKnownInAdvance: true,
paymentAmounts: {
Expand All @@ -186,7 +187,7 @@ export const recordSendLnPayment = async <S extends WalletCurrency>({
...displayAmounts,
})

return LedgerFacade.recordSendOffChain({
const recorded = await LedgerFacade.recordSendOffChain({
description: "sends bitcoin via ln",
amountToDebitSender: paymentAmount,
senderWalletDescriptor: walletDescriptor,
Expand All @@ -195,6 +196,12 @@ export const recordSendLnPayment = async <S extends WalletCurrency>({
additionalDebitMetadata: debitAccountAdditionalMetadata,
additionalInternalMetadata: internalAccountsAdditionalMetadata,
})
if (recorded instanceof Error) throw recorded

return {
...recorded,
paymentHash,
}
}

export const recordSendOnChainPayment = async <S extends WalletCurrency>({
Expand Down
Loading

0 comments on commit b87bfcd

Please sign in to comment.