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

chore(backend): allow asset scale 2 to asset scale 9 payments #2748

Merged
merged 7 commits into from
May 29, 2024

Conversation

mkurapov
Copy link
Contributor

@mkurapov mkurapov commented May 27, 2024

Changes proposed in this pull request

  • Fix issue where we are unable to send payments between asset scale 2 and asset scale 9 wallet addresses because the ILP rate probe exchange rate numerators were too big to store in the DB as bigints. See details in issue.
  • Update small logic where we allow fees to make up more than 50% of receive amount: https://github.com/interledger/rafiki/pull/2748/files#r1616401580
  • Some minor error/logging additions, refactoring create quote function slightly

Context

Fixes #2747

Checklist

  • Related issues linked using fixes #number
  • Tests added/updated
  • Documentation added
  • Make sure that all checks pass
  • Bruno collection updated

@github-actions github-actions bot added type: tests Testing related pkg: backend Changes in the backend package. type: source Changes business logic labels May 27, 2024
Copy link

netlify bot commented May 27, 2024

Deploy Preview for brilliant-pasca-3e80ec canceled.

Name Link
🔨 Latest commit 5242127
🔍 Latest deploy log https://app.netlify.com/sites/brilliant-pasca-3e80ec/deploys/66570fd292791300088c1db8

Comment on lines +199 to +201
if (receipt.error) {
throw receipt.error
}
Copy link
Contributor Author

@mkurapov mkurapov May 27, 2024

Choose a reason for hiding this comment

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

move this check before the debug logger, so we don't continue to log "'ILP payment completed'" when there is an error

client: options.client,
feeId: sendingFee?.id,
estimatedExchangeRate: quote.estimatedExchangeRate,
additionalFields: quote.additionalFields
Copy link
Contributor Author

Choose a reason for hiding this comment

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

don't store additionalFields anymore

@@ -245,20 +246,6 @@ async function pay(
}
}

function fromJSONtoRatio(ratio: unknown): Pay.Ratio {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not needed anymore, we don't use additionalFields quote field to get these ratio amounts

Comment on lines -232 to -234
if (receiveAmountValue <= exchangeAdjustedFees) {
throw QuoteError.NegativeReceiveAmount
}
Copy link
Contributor Author

@mkurapov mkurapov May 27, 2024

Choose a reason for hiding this comment

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

Behaviour change:
We used to throw if the receiveAmount was less than the fees: e.g. if receiveAmountValue = 100, and exchangeAdjustedFees were 60, we would throw, even though receiveAmountValue of 40 seems like it should be possible to do. (In other words, more than 50% of the transfer in this situation goes to fees, which wouldn't be nice for the user, but not necessarily a problem/bug)

We discussed this in a slack thread.

table.string('highEstimatedExchangeRateNumerator').alter()
table.string('highEstimatedExchangeRateDenominator').alter()

table.dropColumn('additionalFields')
Copy link
Contributor Author

@mkurapov mkurapov May 27, 2024

Choose a reason for hiding this comment

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

Originally, additionalFields was a temp solution when building out support for multiple payment methods. Now I decided to get rid of this extra field, since we will not be building that out.

Comment on lines 7 to 12
table.decimal('minExchangeRateNumerator', 64, 0).alter()
table.decimal('minExchangeRateDenominator', 64, 0).alter()
table.decimal('lowEstimatedExchangeRateNumerator', 64, 0).alter()
table.decimal('lowEstimatedExchangeRateDenominator', 64, 0).alter()
table.decimal('highEstimatedExchangeRateNumerator', 64, 0).alter()
table.decimal('highEstimatedExchangeRateDenominator', 64, 0).alter()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

needed something bigger than 20, (I don't think we will ever need more than 20 ever), but just being generous so we don't run into this issue again

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems reasonable. Inspecting the db shows these are stored as numeric types (same as decimal) in postgres. Found this in the docs about how much storage this would take:

Numeric values are physically stored without any extra leading or trailing zeroes. Thus, the declared precision and scale of a column are maximums, not fixed allocations. (In this sense the numeric type is more akin to varchar(n) than to char(n).) The actual storage requirement is two bytes for each group of four decimal digits, plus three to eight bytes overhead.

https://www.postgresql.org/docs/current/datatype-numeric.html

So it varies on actual size of the data, not just this declaration. So I don't really see a downside of leaving lots of extra headroom.

Copy link
Contributor

@BlairCurrey BlairCurrey May 28, 2024

Choose a reason for hiding this comment

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

Were you able to test this migration against any existing data? Since we're going from lower to higher precision I imagine it probably works fine but figure it's worth testing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@BlairCurrey I just made some transactions on main then rebuilt the backend and continued making transactions without issue

Comment on lines -211 to -221
if (!maxReceiveAmountValue) {
// FixedDelivery
const fees = quote.fee?.calculate(debitAmountValue) ?? 0n
debitAmountValue = BigInt(debitAmountValue) + fees
if (
debitAmountValue < quote.debitAmount.value ||
debitAmountValue <= BigInt(0)
) {
throw QuoteError.InvalidAmount
}
} else {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

split these up into functions, logic remains the same other than the comment below

@@ -681,41 +697,5 @@ describe('IlpPaymentService', (): void => {
expect((error as PaymentMethodHandlerError).retryable).toBe(false)
}
})

test('throws if invalid quote data', async (): Promise<void> => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we don't use additionalFields so parsing JSON is not required, so this test is not necessary

@mkurapov mkurapov changed the title chore(backend): update how we store exchange rate numerator and denom… chore(backend): allow asset scale 2 to asset scale 9 payment May 27, 2024
@mkurapov mkurapov changed the title chore(backend): allow asset scale 2 to asset scale 9 payment chore(backend): allow asset scale 2 to asset scale 9 payments May 27, 2024
@@ -272,6 +284,7 @@ describe('IlpPaymentService', (): void => {
minDeliveryAmount: -1n
} as Pay.Quote)

expect.assertions(4)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

to make sure exceptions in catch are tracked

@mkurapov mkurapov marked this pull request as ready for review May 28, 2024 08:04
@mkurapov mkurapov merged commit ddffe93 into main May 29, 2024
42 checks passed
@mkurapov mkurapov deleted the 2747/mk/fix-quotes-table branch May 29, 2024 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: backend Changes in the backend package. type: source Changes business logic type: tests Testing related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cannot send from asset scale 2 to asset scale 9
2 participants