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

rfq: fix precision issue in HTLC compliance check #1194

Merged
merged 1 commit into from
Nov 18, 2024
Merged

Conversation

guggero
Copy link
Member

@guggero guggero commented Nov 15, 2024

Due to the integer nature of asset units, when converting to milli-satoshi and back, we might be off by a fraction of an asset unit when comparing to the milli-satoshi amount of an HTLC. We'll add a single asset unit to the reported inbound amount when checking in-out amount compliance to allow for those asset rounding imprecisions. In a real-world scenario where an asset has a decimal display value of 6, this would result in an imprecision of fractions of cents and be earned back by the spread on the actual conversion itself.

@coveralls
Copy link

coveralls commented Nov 15, 2024

Pull Request Test Coverage Report for Build 11888540506

Details

  • 0 of 3 (0.0%) changed or added relevant lines in 1 file are covered.
  • 28 unchanged lines in 6 files lost coverage.
  • Overall coverage decreased (-0.008%) to 40.996%

Changes Missing Coverage Covered Lines Changed/Added Lines %
rfq/order.go 0 3 0.0%
Files with Coverage Reduction New Missed Lines %
rfq/order.go 2 0.0%
tappsbt/create.go 2 53.22%
tapgarden/planter.go 2 74.87%
tapchannel/aux_leaf_signer.go 3 36.33%
asset/asset.go 4 80.96%
universe/interface.go 15 47.09%
Totals Coverage Status
Change from base Build 11847785762: -0.008%
Covered Lines: 25149
Relevant Lines: 61345

💛 - Coveralls

Copy link
Member

@GeorgeTsagk GeorgeTsagk left a comment

Choose a reason for hiding this comment

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

Thanks for the fix!

// value of the asset. So we increase it by exactly one asset unit to
// ensure that the fee logic in lnd does not reject the HTLC.
roundingCorrection := rfqmath.NewBigIntFromUint64(1)
assetAmt = assetAmt.Add(roundingCorrection)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would adding an entire asset unit be acceptable in the scenario where where one asset unit is a considerable amount / value to the user? e.g. the amount represented an 1e8 sats. Or are the rounding errors only expected when the values are de minis?

What other methods might be available to address the source of the rounding errors?

Copy link
Member Author

Choose a reason for hiding this comment

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

just to clarify: this PR doesn't "fix" any rounding related code. It just adjusts a check to allow an HTLC to be forwarded that is affected by the rounding down. The rounding down will always happen, due to the integer nature of taproot assets (see RFQ/decimal display doc for more info).
The decision we can make is: do we force the sender to over pay by one unit so that the ultimate receiver always sees the expected (or even one unit more) balance? Or do we allow under payment of one unit, leading to the scenario where the ultimate receiver sees a final balance lower than expected.

But since this only fixes a check, I don't think we should block this PR and look at the decision holistically.

Copy link
Contributor

@gijswijs gijswijs left a comment

Choose a reason for hiding this comment

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

LGTM 🎉

rfq/order.go Outdated
@@ -297,6 +297,12 @@ func (c *AssetPurchasePolicy) CheckHtlcCompliance(
return fmt.Errorf("error summing asset balance: %w", err)
}

// Due to rounding errors, we may slightly underreport the incoming
// value of the asset. So we increase it by exactly one asset unit to
// ensure that the fee logic in lnd does not reject the HTLC.
Copy link
Contributor

Choose a reason for hiding this comment

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

fee logic in lnd

This is a somewhat confusing comment to me. Lnd fee logic doesn't come into play in this compliance check, does it? We check the inboundAmount against the outbound amount a few lines down and proceed accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right, this was Copilot suggesting a comment based on other instances in this file 😅 In some places we report the converted value back to lnd and then the fee logic there decides if an HTLC pays enough fees. But not in this case. Updated the comment.

// Due to rounding errors, we may slightly underreport the incoming
// value of the asset. So we increase it by exactly one asset unit to
// ensure that the fee logic in lnd does not reject the HTLC.
roundingCorrection := rfqmath.NewBigIntFromUint64(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we always assume the rounding error is less then 1 asset unit?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the imprecision of an integer representation of a division can at most be 0.99999......, since we're strictly cutting off any fractional part after the division.

Due to the integer nature of asset units, when converting to
milli-satoshi and back, we might be off by a fraction of an asset unit
when comparing to the milli-satoshi amount of an HTLC.
We'll add a single asset unit to the reported inbound amount when
checking in-out amount compliance to allow for those asset rounding
imprecisions. In a real-world scenario where an asset has a decimal
display value of 6, this would result in an imprecision of fractions of
cents and be earned back by the spread on the actual conversion itself.
@guggero guggero merged commit 4f645ce into main Nov 18, 2024
18 checks passed
@guggero guggero deleted the rfq-rounding branch November 18, 2024 09:04
gijswijs pushed a commit that referenced this pull request Nov 20, 2024
rfq: fix precision issue in HTLC compliance check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

5 participants