mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-29 11:11:53 +01:00
rpcserver+lnrpc: allow users to update max HTLC channel policies
In this commit, we enable callers of UpdateChannelPolicy to specify their desired max HTLC forwarding policy for one or multiple channels.
This commit is contained in:
parent
9a52cb6dab
commit
4b9da07e78
1039
lnrpc/rpc.pb.go
1039
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load Diff
@ -2395,6 +2395,9 @@ message PolicyUpdateRequest {
|
||||
|
||||
/// The required timelock delta for HTLCs forwarded over the channel.
|
||||
uint32 time_lock_delta = 5 [json_name = "time_lock_delta"];
|
||||
|
||||
/// If set, the maximum HTLC size in milli-satoshis. If unset, the maximum HTLC will be unchanged.
|
||||
uint64 max_htlc_msat = 6 [json_name = "max_htlc_msat"];
|
||||
}
|
||||
message PolicyUpdateResponse {
|
||||
}
|
||||
|
@ -3150,6 +3150,11 @@
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "/ The required timelock delta for HTLCs forwarded over the channel."
|
||||
},
|
||||
"max_htlc_msat": {
|
||||
"type": "string",
|
||||
"format": "uint64",
|
||||
"description": "/ If set, the maximum HTLC size in milli-satoshis. If unset, the maximum HTLC will be unchanged."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1122,6 +1122,15 @@ type expectedChanUpdate struct {
|
||||
chanPoint *lnrpc.ChannelPoint
|
||||
}
|
||||
|
||||
// calculateMaxHtlc re-implements the RequiredRemoteChannelReserve of the
|
||||
// funding manager's config, which corresponds to the maximum MaxHTLC value we
|
||||
// allow users to set when updating a channel policy.
|
||||
func calculateMaxHtlc(chanCap btcutil.Amount) uint64 {
|
||||
reserve := lnwire.NewMSatFromSatoshis(chanCap / 100)
|
||||
max := lnwire.NewMSatFromSatoshis(chanCap) - reserve
|
||||
return uint64(max)
|
||||
}
|
||||
|
||||
// waitForChannelUpdate waits for a node to receive the expected channel
|
||||
// updates.
|
||||
func waitForChannelUpdate(t *harnessTest, subscription graphSubscription,
|
||||
@ -1292,6 +1301,10 @@ func checkChannelPolicy(policy, expectedPolicy *lnrpc.RoutingPolicy) error {
|
||||
return fmt.Errorf("expected min htlc %v, got %v",
|
||||
expectedPolicy.MinHtlc, policy.MinHtlc)
|
||||
}
|
||||
if policy.MaxHtlcMsat != expectedPolicy.MaxHtlcMsat {
|
||||
return fmt.Errorf("expected max htlc %v, got %v",
|
||||
expectedPolicy.MaxHtlcMsat, policy.MaxHtlcMsat)
|
||||
}
|
||||
if policy.Disabled != expectedPolicy.Disabled {
|
||||
return errors.New("edge should be disabled but isn't")
|
||||
}
|
||||
@ -1310,6 +1323,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
defaultTimeLockDelta = lnd.DefaultBitcoinTimeLockDelta
|
||||
defaultMinHtlc = 1000
|
||||
)
|
||||
defaultMaxHtlc := calculateMaxHtlc(lnd.MaxBtcFundingAmount)
|
||||
|
||||
// Launch notification clients for all nodes, such that we can
|
||||
// get notified when they discover new channels and updates in the
|
||||
@ -1344,6 +1358,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
FeeRateMilliMsat: defaultFeeRate,
|
||||
TimeLockDelta: defaultTimeLockDelta,
|
||||
MinHtlc: defaultMinHtlc,
|
||||
MaxHtlcMsat: defaultMaxHtlc,
|
||||
}
|
||||
|
||||
for _, graphSub := range graphSubs {
|
||||
@ -1422,6 +1437,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
FeeRateMilliMsat: defaultFeeRate,
|
||||
TimeLockDelta: defaultTimeLockDelta,
|
||||
MinHtlc: customMinHtlc,
|
||||
MaxHtlcMsat: defaultMaxHtlc,
|
||||
}
|
||||
|
||||
expectedPolicyCarol := &lnrpc.RoutingPolicy{
|
||||
@ -1429,6 +1445,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
FeeRateMilliMsat: defaultFeeRate,
|
||||
TimeLockDelta: defaultTimeLockDelta,
|
||||
MinHtlc: defaultMinHtlc,
|
||||
MaxHtlcMsat: defaultMaxHtlc,
|
||||
}
|
||||
|
||||
for _, graphSub := range graphSubs {
|
||||
@ -1589,24 +1606,27 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
sendResp.PaymentError)
|
||||
}
|
||||
|
||||
// With our little cluster set up, we'll update the fees for the
|
||||
// channel Bob side of the Alice->Bob channel, and make sure all nodes
|
||||
// learn about it.
|
||||
// With our little cluster set up, we'll update the fees and the max htlc
|
||||
// size for the Bob side of the Alice->Bob channel, and make sure
|
||||
// all nodes learn about it.
|
||||
baseFee := int64(1500)
|
||||
feeRate := int64(12)
|
||||
timeLockDelta := uint32(66)
|
||||
maxHtlc := uint64(500000)
|
||||
|
||||
expectedPolicy = &lnrpc.RoutingPolicy{
|
||||
FeeBaseMsat: baseFee,
|
||||
FeeRateMilliMsat: testFeeBase * feeRate,
|
||||
TimeLockDelta: timeLockDelta,
|
||||
MinHtlc: defaultMinHtlc,
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
}
|
||||
|
||||
req := &lnrpc.PolicyUpdateRequest{
|
||||
BaseFeeMsat: baseFee,
|
||||
FeeRate: float64(feeRate),
|
||||
TimeLockDelta: timeLockDelta,
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
|
||||
ChanPoint: chanPoint,
|
||||
},
|
||||
@ -1689,22 +1709,25 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
baseFee = int64(800)
|
||||
feeRate = int64(123)
|
||||
timeLockDelta = uint32(22)
|
||||
maxHtlc = maxHtlc * 2
|
||||
|
||||
expectedPolicy.FeeBaseMsat = baseFee
|
||||
expectedPolicy.FeeRateMilliMsat = testFeeBase * feeRate
|
||||
expectedPolicy.TimeLockDelta = timeLockDelta
|
||||
expectedPolicy.MaxHtlcMsat = maxHtlc
|
||||
|
||||
req = &lnrpc.PolicyUpdateRequest{
|
||||
BaseFeeMsat: baseFee,
|
||||
FeeRate: float64(feeRate),
|
||||
TimeLockDelta: timeLockDelta,
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
}
|
||||
req.Scope = &lnrpc.PolicyUpdateRequest_Global{}
|
||||
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
_, err = net.Alice.UpdateChannelPolicy(ctxt, req)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get alice's balance: %v", err)
|
||||
t.Fatalf("unable to update alice's channel policy: %v", err)
|
||||
}
|
||||
|
||||
// Wait for all nodes to have seen the policy updates for both of
|
||||
@ -3950,7 +3973,8 @@ func assertAmountPaid(t *harnessTest, channelName string,
|
||||
// listenerNode has received the policy update.
|
||||
func updateChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
|
||||
chanPoint *lnrpc.ChannelPoint, baseFee int64, feeRate int64,
|
||||
timeLockDelta uint32, listenerNode *lntest.HarnessNode) {
|
||||
timeLockDelta uint32, maxHtlc uint64, listenerNode *lntest.HarnessNode) {
|
||||
|
||||
ctxb := context.Background()
|
||||
|
||||
expectedPolicy := &lnrpc.RoutingPolicy{
|
||||
@ -3958,6 +3982,7 @@ func updateChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
|
||||
FeeRateMilliMsat: feeRate,
|
||||
TimeLockDelta: timeLockDelta,
|
||||
MinHtlc: 1000, // default value
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
}
|
||||
|
||||
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
||||
@ -3967,6 +3992,7 @@ func updateChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
|
||||
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
|
||||
ChanPoint: chanPoint,
|
||||
},
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
}
|
||||
|
||||
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
|
||||
@ -4143,14 +4169,15 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
// Set the fee policies of the Alice -> Bob and the Dave -> Alice
|
||||
// channel edges to relatively large non default values. This makes it
|
||||
// possible to pick up more subtle fee calculation errors.
|
||||
maxHtlc := uint64(calculateMaxHtlc(chanAmt))
|
||||
updateChannelPolicy(
|
||||
t, net.Alice, chanPointAlice, 1000, 100000,
|
||||
lnd.DefaultBitcoinTimeLockDelta, carol,
|
||||
lnd.DefaultBitcoinTimeLockDelta, maxHtlc, carol,
|
||||
)
|
||||
|
||||
updateChannelPolicy(
|
||||
t, dave, chanPointDave, 5000, 150000,
|
||||
lnd.DefaultBitcoinTimeLockDelta, carol,
|
||||
lnd.DefaultBitcoinTimeLockDelta, maxHtlc, carol,
|
||||
)
|
||||
|
||||
// Using Carol as the source, pay to the 5 invoices from Bob created
|
||||
@ -12372,18 +12399,21 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
baseFee := int64(10000)
|
||||
feeRate := int64(5)
|
||||
timeLockDelta := uint32(lnd.DefaultBitcoinTimeLockDelta)
|
||||
maxHtlc := calculateMaxHtlc(chanAmt)
|
||||
|
||||
expectedPolicy := &lnrpc.RoutingPolicy{
|
||||
FeeBaseMsat: baseFee,
|
||||
FeeRateMilliMsat: testFeeBase * feeRate,
|
||||
TimeLockDelta: timeLockDelta,
|
||||
MinHtlc: 1000, // default value
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
}
|
||||
|
||||
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
||||
BaseFeeMsat: baseFee,
|
||||
FeeRate: float64(feeRate),
|
||||
TimeLockDelta: timeLockDelta,
|
||||
MaxHtlcMsat: maxHtlc,
|
||||
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
|
||||
ChanPoint: chanPointCarolDave,
|
||||
},
|
||||
@ -12634,6 +12664,7 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
FeeRateMilliMsat: int64(lnd.DefaultBitcoinFeeRate),
|
||||
TimeLockDelta: lnd.DefaultBitcoinTimeLockDelta,
|
||||
MinHtlc: 1000, // default value
|
||||
MaxHtlcMsat: calculateMaxHtlc(chanAmt),
|
||||
Disabled: true,
|
||||
}
|
||||
|
||||
|
@ -4602,6 +4602,7 @@ func (r *rpcServer) UpdateChannelPolicy(ctx context.Context,
|
||||
chanPolicy := routing.ChannelPolicy{
|
||||
FeeSchema: feeSchema,
|
||||
TimeLockDelta: req.TimeLockDelta,
|
||||
MaxHTLC: lnwire.MilliSatoshi(req.MaxHtlcMsat),
|
||||
}
|
||||
|
||||
rpcsLog.Debugf("[updatechanpolicy] updating channel policy base_fee=%v, "+
|
||||
|
Loading…
x
Reference in New Issue
Block a user