MFEE4 hardcoded balances are imprecise
andrevmatos opened this issue · comments
Problem Definition
While implementing raiden-network/light-client#2785 and testing with values generated from a recent develop
python client, I could not match the exact values returned for the piecewise imbalance penalty function generated from the client in JS. After some debugging, it became clear the culprit was calculate_imbalance_fees. It relies heavily in python's big binary number calculation, which can't be easily reproduced in other platforms. More specifically, the o ** b
operation is the more problematic, since often o
is the 1e+18
magnitude, and b
may be fractional (e.g 2.5
), giving a result in the order of 1e+45
, which gave me a parameter a
of 4.0000000000000003e-29
, clearly indicating a binary rounding error.
Besides this, in several places, plain round
calls are made which hide the fact that python rounds using the ROUND_HALF_EVEN
heuristic (half decimals are rounded in even's direction).
It's not good that the reference implementation depends on such platform-specific details, so my suggestion is that these calculations are done using Decimal
or other arbitrary generic number format. Hopefully, this should be enough to fix these precision issues. Also, moving to only integer arithmetic operations on producing these numbers would completely remove the source of differences between platforms (big floating point numbers handling).
As a quick workaround before that, we'd appreciate that the values asserted in MFEE4 scenario are relaxed a bit. In our tests, allow_balance_error: 10
is double what we need, should give a good margin, which is still 5e-16
times smaller than the transfer amount itself, so pretty negligible considering the default added fee margins.
For reference, below is the diff of the python's imbalance penalty curve (what's sent in PFSFeeUpdate
message) for MFEE4's 2e+18
total capacity, where -
are python's y values, and +
is LC's decimal.js
output with 40
significant digits precision and explicit ROUND_HALF_EVEN
behavior (as PC's):
@@ -6,27 +6,27 @@
"0",
"40000000000000000",
],
Array [
"100000000000000000",
- "30737338856836652",
+ "30737338856836647",
],
Array [
"200000000000000000",
- "22897336089597848",
+ "22897336089597846",
],
Array [
"300000000000000000",
- "16398536520067884",
+ "16398536520067881",
],
Array [
"400000000000000000",
- "11154192037077362",
+ "11154192037077361",
],
Array [
"500000000000000000",
- "7071067811865476",
+ "7071067811865475",
],
Array [
"600000000000000000",
"4047715405015526",
],
@@ -62,27 +62,27 @@
"1400000000000000000",
"4047715405015526",
],
Array [
"1500000000000000000",
- "7071067811865476",
+ "7071067811865475",
],
Array [
"1600000000000000000",
- "11154192037077362",
+ "11154192037077361",
],
Array [
"1700000000000000000",
- "16398536520067884",
+ "16398536520067881",
],
Array [
"1800000000000000000",
- "22897336089597848",
+ "22897336089597846",
],
Array [
"1900000000000000000",
- "30737338856836652",
+ "30737338856836647",
],
Array [
"2000000000000000000",
"40000000000000000",
],