mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-23 06:35:07 +01:00
lnrpc/invoicesrpc: add blinded path policy buffer
This commit adds a helper function that will be used to adjust a hops policy values by certain given increase and decrease multipliers. This will be used in blinded paths to give policy values some buffer to avoid easy probing of blinded paths.
This commit is contained in:
parent
3b2a6042ff
commit
0855e3e71a
2 changed files with 224 additions and 0 deletions
|
@ -844,6 +844,77 @@ func PopulateHopHints(cfg *SelectHopHintsCfg, amtMSat lnwire.MilliSatoshi,
|
|||
return hopHints, nil
|
||||
}
|
||||
|
||||
// blindedHopPolicy holds the set of relay policy values to use for a channel
|
||||
// in a blinded path.
|
||||
type blindedHopPolicy struct {
|
||||
cltvExpiryDelta uint16
|
||||
feeRate uint32
|
||||
baseFee lnwire.MilliSatoshi
|
||||
minHTLCMsat lnwire.MilliSatoshi
|
||||
maxHTLCMsat lnwire.MilliSatoshi
|
||||
}
|
||||
|
||||
// addPolicyBuffer constructs the bufferedChanPolicies for a path hop by taking
|
||||
// its actual policy values and multiplying them by the given multipliers.
|
||||
// The base fee, fee rate and minimum HTLC msat values are adjusted via the
|
||||
// incMultiplier while the maximum HTLC msat value is adjusted via the
|
||||
// decMultiplier. If adjustments of the HTLC values no longer make sense
|
||||
// then the original HTLC value is used.
|
||||
func addPolicyBuffer(policy *blindedHopPolicy, incMultiplier,
|
||||
decMultiplier float64) (*blindedHopPolicy, error) {
|
||||
|
||||
if incMultiplier < 1 {
|
||||
return nil, fmt.Errorf("blinded path policy increase " +
|
||||
"multiplier must be greater than or equal to 1")
|
||||
}
|
||||
|
||||
if decMultiplier < 0 || decMultiplier > 1 {
|
||||
return nil, fmt.Errorf("blinded path policy decrease " +
|
||||
"multiplier must be in the range [0;1]")
|
||||
}
|
||||
|
||||
var (
|
||||
minHTLCMsat = lnwire.MilliSatoshi(
|
||||
float64(policy.minHTLCMsat) * incMultiplier,
|
||||
)
|
||||
maxHTLCMsat = lnwire.MilliSatoshi(
|
||||
float64(policy.maxHTLCMsat) * decMultiplier,
|
||||
)
|
||||
)
|
||||
|
||||
// Make sure the new minimum is not more than the original maximum.
|
||||
// If it is, then just stick to the original minimum.
|
||||
if minHTLCMsat > policy.maxHTLCMsat {
|
||||
minHTLCMsat = policy.minHTLCMsat
|
||||
}
|
||||
|
||||
// Make sure the new maximum is not less than the original minimum.
|
||||
// If it is, then just stick to the original maximum.
|
||||
if maxHTLCMsat < policy.minHTLCMsat {
|
||||
maxHTLCMsat = policy.maxHTLCMsat
|
||||
}
|
||||
|
||||
// Also ensure that the new htlc bounds make sense. If the new minimum
|
||||
// is greater than the new maximum, then just let both to their original
|
||||
// values.
|
||||
if minHTLCMsat > maxHTLCMsat {
|
||||
minHTLCMsat = policy.minHTLCMsat
|
||||
maxHTLCMsat = policy.maxHTLCMsat
|
||||
}
|
||||
|
||||
return &blindedHopPolicy{
|
||||
cltvExpiryDelta: uint16(
|
||||
float64(policy.cltvExpiryDelta) * incMultiplier,
|
||||
),
|
||||
feeRate: uint32(float64(policy.feeRate) * incMultiplier),
|
||||
baseFee: lnwire.MilliSatoshi(
|
||||
float64(policy.baseFee) * incMultiplier,
|
||||
),
|
||||
minHTLCMsat: minHTLCMsat,
|
||||
maxHTLCMsat: maxHTLCMsat,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// calcBlindedPathPolicies computes the accumulated policy values for the path.
|
||||
// These values include the total base fee, the total proportional fee and the
|
||||
// total CLTV delta. This function assumes that all the passed relay infos have
|
||||
|
|
|
@ -902,6 +902,159 @@ func TestPopulateHopHints(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestApplyBlindedPathPolicyBuffer tests blinded policy adjustments.
|
||||
func TestApplyBlindedPathPolicyBuffer(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
policyIn *blindedHopPolicy
|
||||
expectedOut *blindedHopPolicy
|
||||
incMultiplier float64
|
||||
decMultiplier float64
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "invalid increase multiplier",
|
||||
incMultiplier: 0,
|
||||
expectedError: "blinded path policy increase " +
|
||||
"multiplier must be greater than or equal to 1",
|
||||
},
|
||||
{
|
||||
name: "decrease multiplier too small",
|
||||
incMultiplier: 1,
|
||||
decMultiplier: -1,
|
||||
expectedError: "blinded path policy decrease " +
|
||||
"multiplier must be in the range [0;1]",
|
||||
},
|
||||
{
|
||||
name: "decrease multiplier too big",
|
||||
incMultiplier: 1,
|
||||
decMultiplier: 2,
|
||||
expectedError: "blinded path policy decrease " +
|
||||
"multiplier must be in the range [0;1]",
|
||||
},
|
||||
{
|
||||
name: "no change",
|
||||
incMultiplier: 1,
|
||||
decMultiplier: 1,
|
||||
policyIn: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 1,
|
||||
minHTLCMsat: 2,
|
||||
maxHTLCMsat: 3,
|
||||
baseFee: 4,
|
||||
feeRate: 5,
|
||||
},
|
||||
expectedOut: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 1,
|
||||
minHTLCMsat: 2,
|
||||
maxHTLCMsat: 3,
|
||||
baseFee: 4,
|
||||
feeRate: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "buffer up by 100% and down by and down " +
|
||||
"by 50%",
|
||||
incMultiplier: 2,
|
||||
decMultiplier: 0.5,
|
||||
policyIn: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 10,
|
||||
minHTLCMsat: 20,
|
||||
maxHTLCMsat: 300,
|
||||
baseFee: 40,
|
||||
feeRate: 50,
|
||||
},
|
||||
expectedOut: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 20,
|
||||
minHTLCMsat: 40,
|
||||
maxHTLCMsat: 150,
|
||||
baseFee: 80,
|
||||
feeRate: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "new HTLC minimum larger than OG " +
|
||||
"maximum",
|
||||
incMultiplier: 2,
|
||||
decMultiplier: 1,
|
||||
policyIn: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 10,
|
||||
minHTLCMsat: 20,
|
||||
maxHTLCMsat: 30,
|
||||
baseFee: 40,
|
||||
feeRate: 50,
|
||||
},
|
||||
expectedOut: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 20,
|
||||
minHTLCMsat: 20,
|
||||
maxHTLCMsat: 30,
|
||||
baseFee: 80,
|
||||
feeRate: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "new HTLC maximum smaller than OG " +
|
||||
"minimum",
|
||||
incMultiplier: 1,
|
||||
decMultiplier: 0.5,
|
||||
policyIn: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 10,
|
||||
minHTLCMsat: 20,
|
||||
maxHTLCMsat: 30,
|
||||
baseFee: 40,
|
||||
feeRate: 50,
|
||||
},
|
||||
expectedOut: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 10,
|
||||
minHTLCMsat: 20,
|
||||
maxHTLCMsat: 30,
|
||||
baseFee: 40,
|
||||
feeRate: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "new HTLC minimum and maximums are not " +
|
||||
"compatible",
|
||||
incMultiplier: 2,
|
||||
decMultiplier: 0.5,
|
||||
policyIn: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 10,
|
||||
minHTLCMsat: 30,
|
||||
maxHTLCMsat: 100,
|
||||
baseFee: 40,
|
||||
feeRate: 50,
|
||||
},
|
||||
expectedOut: &blindedHopPolicy{
|
||||
cltvExpiryDelta: 20,
|
||||
minHTLCMsat: 30,
|
||||
maxHTLCMsat: 100,
|
||||
baseFee: 80,
|
||||
feeRate: 100,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
bufferedPolicy, err := addPolicyBuffer(
|
||||
test.policyIn, test.incMultiplier,
|
||||
test.decMultiplier,
|
||||
)
|
||||
if test.expectedError != "" {
|
||||
require.ErrorContains(
|
||||
t, err, test.expectedError,
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
require.Equal(t, test.expectedOut, bufferedPolicy)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestBlindedPathAccumulatedPolicyCalc tests the logic for calculating the
|
||||
// accumulated routing policies of a blinded route against an example mentioned
|
||||
// in the spec document:
|
||||
|
|
Loading…
Add table
Reference in a new issue