@@ -19,7 +19,7 @@ func TestUnitConversionTolerance(t *testing.T) {
1919 )
2020 var (
2121 rate = rfqmath.BigIntFixedPoint {
22- Coefficient : rfqmath .NewBigIntFromUint64 (9852216748 ),
22+ Coefficient : rfqmath .NewBigIntFromUint64 (9_852_216_748 ),
2323 Scale : 0 ,
2424 }
2525 )
@@ -61,8 +61,12 @@ func TestUnitConversionTolerance(t *testing.T) {
6161 newMarginAssetUnits , rate ,
6262 )
6363
64+ proposedMargin := rfqmath .UnitsToMilliSatoshi (marginAssetUnits , rate ) +
65+ lnwire .MilliSatoshi (numHTLCs )
66+
6467 t .Logf ("Old tolerance allowed in msat: %d" , allowedMarginMSat )
6568 t .Logf ("New tolerance allowed in msat: %d" , newAllowedMarginMSat )
69+ t .Logf ("Proposed tolerance allowed in msat: %d" , proposedMargin )
6670}
6771
6872// TestUnitConversionToleranceRapid uses rapid to randomly draw invoice amounts,
@@ -74,7 +78,7 @@ func TestUnitConversionToleranceRapid(t *testing.T) {
7478 Draw (t , "invoiceAmtUnits" )
7579 numHTLCs := rapid .Uint64Range (1 , 16 ).
7680 Draw (t , "numHTLCs" )
77- coefficient := rapid .Uint64Range (1 , 20_000_000_000 ).
81+ coefficient := rapid .Uint64Range (1 , 300_000_000_000 ).
7882 Draw (t , "coefficient" )
7983
8084 rate := rfqmath.BigIntFixedPoint {
@@ -89,26 +93,46 @@ func TestUnitConversionToleranceRapid(t *testing.T) {
8993
9094 shardSizeMSat := invoiceAmtMsat / lnwire .MilliSatoshi (numHTLCs )
9195 shardSizeFP := rfqmath .MilliSatoshiToUnits (shardSizeMSat , rate )
92- shardSizeUnit := shardSizeFP .ScaleTo (0 ).ToUint64 ()
9396
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
100122
101- newMarginAssetUnits := rfqmath .NewBigIntFixedPoint (
102- numHTLCs + 1 , 0 ,
123+ allowedMarginUnits := rfqmath .NewBigIntFixedPoint (
124+ numHTLCs , 0 ,
103125 )
104- newAllowedMarginMSat := rfqmath .UnitsToMilliSatoshi (
105- newMarginAssetUnits , rate ,
126+ marginAmt := rfqmath .UnitsToMilliSatoshi (
127+ allowedMarginUnits , rate ,
106128 )
107129
130+ marginAmt += lnwire .MilliSatoshi (numHTLCs )
131+
108132 // The difference should be within the newly allowed margin.
109133 require .LessOrEqual (
110134 t ,
111- invoiceAmtMsat - inboundAmountMSat , newAllowedMarginMSat ,
135+ invoiceAmtMsat - inboundAmountMSat , marginAmt ,
112136 )
113137 })
114138}
0 commit comments