@@ -19,7 +19,7 @@ func TestUnitConversionTolerance(t *testing.T) {
19
19
)
20
20
var (
21
21
rate = rfqmath.BigIntFixedPoint {
22
- Coefficient : rfqmath .NewBigIntFromUint64 (9852216748 ),
22
+ Coefficient : rfqmath .NewBigIntFromUint64 (9_852_216_748 ),
23
23
Scale : 0 ,
24
24
}
25
25
)
@@ -61,8 +61,12 @@ func TestUnitConversionTolerance(t *testing.T) {
61
61
newMarginAssetUnits , rate ,
62
62
)
63
63
64
+ proposedMargin := rfqmath .UnitsToMilliSatoshi (marginAssetUnits , rate ) +
65
+ lnwire .MilliSatoshi (numHTLCs )
66
+
64
67
t .Logf ("Old tolerance allowed in msat: %d" , allowedMarginMSat )
65
68
t .Logf ("New tolerance allowed in msat: %d" , newAllowedMarginMSat )
69
+ t .Logf ("Proposed tolerance allowed in msat: %d" , proposedMargin )
66
70
}
67
71
68
72
// TestUnitConversionToleranceRapid uses rapid to randomly draw invoice amounts,
@@ -74,7 +78,7 @@ func TestUnitConversionToleranceRapid(t *testing.T) {
74
78
Draw (t , "invoiceAmtUnits" )
75
79
numHTLCs := rapid .Uint64Range (1 , 16 ).
76
80
Draw (t , "numHTLCs" )
77
- coefficient := rapid .Uint64Range (1 , 20_000_000_000 ).
81
+ coefficient := rapid .Uint64Range (1 , 300_000_000_000 ).
78
82
Draw (t , "coefficient" )
79
83
80
84
rate := rfqmath.BigIntFixedPoint {
@@ -89,26 +93,46 @@ func TestUnitConversionToleranceRapid(t *testing.T) {
89
93
90
94
shardSizeMSat := invoiceAmtMsat / lnwire .MilliSatoshi (numHTLCs )
91
95
shardSizeFP := rfqmath .MilliSatoshiToUnits (shardSizeMSat , rate )
92
- shardSizeUnit := shardSizeFP .ScaleTo (0 ).ToUint64 ()
93
96
94
- shardSumFP := rfqmath .NewBigIntFixedPoint (
95
- shardSizeUnit * numHTLCs , 0 ,
96
- )
97
- inboundAmountMSat := rfqmath .UnitsToMilliSatoshi (
98
- shardSumFP , rate ,
99
- )
97
+ // In order to account for the full invoice amt we need to also
98
+ // somehow carry the remainder of invoiceAmt/numHTLCs. We do so
99
+ // by appending it to the last shard.
100
+ invoiceMod := invoiceAmtMsat % lnwire .MilliSatoshi (numHTLCs )
101
+ lastShardMsat := shardSizeMSat + invoiceMod
102
+ lastShardFP := rfqmath .MilliSatoshiToUnits (lastShardMsat , rate )
103
+
104
+ var inboundAmountMSat lnwire.MilliSatoshi
105
+
106
+ // Each shard calls individually into the rfqmath library. This
107
+ // allows for a total error that scales with the number of
108
+ // shards. We go up to numHTLCS-1 because we want to add any
109
+ // leftovers to the last shard.
110
+ for range numHTLCs - 1 {
111
+ shardPartialSum := rfqmath .UnitsToMilliSatoshi (
112
+ shardSizeFP , rate ,
113
+ )
114
+
115
+ inboundAmountMSat += shardPartialSum
116
+ }
117
+
118
+ // Make a single pass over the last shard, which may also carry
119
+ // the remainder of the payment amt.
120
+ lastShardMsat = rfqmath .UnitsToMilliSatoshi (lastShardFP , rate )
121
+ inboundAmountMSat += lastShardMsat
100
122
101
- newMarginAssetUnits := rfqmath .NewBigIntFixedPoint (
102
- numHTLCs + 1 , 0 ,
123
+ allowedMarginUnits := rfqmath .NewBigIntFixedPoint (
124
+ numHTLCs , 0 ,
103
125
)
104
- newAllowedMarginMSat := rfqmath .UnitsToMilliSatoshi (
105
- newMarginAssetUnits , rate ,
126
+ marginAmt := rfqmath .UnitsToMilliSatoshi (
127
+ allowedMarginUnits , rate ,
106
128
)
107
129
130
+ marginAmt += lnwire .MilliSatoshi (numHTLCs )
131
+
108
132
// The difference should be within the newly allowed margin.
109
133
require .LessOrEqual (
110
134
t ,
111
- invoiceAmtMsat - inboundAmountMSat , newAllowedMarginMSat ,
135
+ invoiceAmtMsat - inboundAmountMSat , marginAmt ,
112
136
)
113
137
})
114
138
}
0 commit comments