mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
routing+lnrpc: add inbound fee policy update
This commit is contained in:
parent
e8c97deaef
commit
763787e08c
@ -2166,6 +2166,31 @@ var updateChannelPolicyCommand = cli.Command{
|
||||
"0.000001 (millionths). Can not be set at " +
|
||||
"the same time as fee_rate",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "inbound_base_fee_msat",
|
||||
Usage: "the base inbound fee in milli-satoshis that " +
|
||||
"will be charged for each forwarded HTLC, " +
|
||||
"regardless of payment size. Its value must " +
|
||||
"be zero or negative - it is a discount " +
|
||||
"for using a particular incoming channel. " +
|
||||
"Note that forwards will be rejected if the " +
|
||||
"discount exceeds the outbound fee " +
|
||||
"(forward at a loss), and lead to " +
|
||||
"penalization by the sender",
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "inbound_fee_rate_ppm",
|
||||
Usage: "the inbound fee rate that will be charged " +
|
||||
"proportionally based on the value of each " +
|
||||
"forwarded HTLC and the outbound fee. Fee " +
|
||||
"rate is expressed in parts per million and " +
|
||||
"must be zero or negative - it is a discount " +
|
||||
"for using a particular incoming channel." +
|
||||
"Note that forwards will be rejected if the " +
|
||||
"discount exceeds the outbound fee " +
|
||||
"(forward at a loss), and lead to " +
|
||||
"penalization by the sender",
|
||||
},
|
||||
cli.Uint64Flag{
|
||||
Name: "time_lock_delta",
|
||||
Usage: "the CLTV delta that will be applied to all " +
|
||||
@ -2318,10 +2343,26 @@ func updateChannelPolicy(ctx *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
inboundBaseFeeMsat := ctx.Int64("inbound_base_fee_msat")
|
||||
if inboundBaseFeeMsat < math.MinInt32 ||
|
||||
inboundBaseFeeMsat > 0 {
|
||||
|
||||
return errors.New("inbound_base_fee_msat out of range")
|
||||
}
|
||||
|
||||
inboundFeeRatePpm := ctx.Int64("inbound_fee_rate_ppm")
|
||||
if inboundFeeRatePpm < math.MinInt32 ||
|
||||
inboundFeeRatePpm > 0 {
|
||||
|
||||
return errors.New("inbound_fee_rate_ppm out of range")
|
||||
}
|
||||
|
||||
req := &lnrpc.PolicyUpdateRequest{
|
||||
BaseFeeMsat: baseFee,
|
||||
TimeLockDelta: uint32(timeLockDelta),
|
||||
MaxHtlcMsat: ctx.Uint64("max_htlc_msat"),
|
||||
BaseFeeMsat: baseFee,
|
||||
TimeLockDelta: uint32(timeLockDelta),
|
||||
MaxHtlcMsat: ctx.Uint64("max_htlc_msat"),
|
||||
InboundBaseFeeMsat: int32(inboundBaseFeeMsat),
|
||||
InboundFeeRatePpm: int32(inboundFeeRatePpm),
|
||||
}
|
||||
|
||||
if ctx.IsSet("min_htlc_msat") {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4312,7 +4312,15 @@ message ChannelFeeReport {
|
||||
// The effective fee rate in milli-satoshis. Computed by dividing the
|
||||
// fee_per_mil value by 1 million.
|
||||
double fee_rate = 4;
|
||||
|
||||
// The base fee charged regardless of the number of milli-satoshis sent.
|
||||
int32 inbound_base_fee_msat = 6;
|
||||
|
||||
// The amount charged per milli-satoshis transferred expressed in
|
||||
// millionths of a satoshi.
|
||||
int32 inbound_fee_per_mil = 7;
|
||||
}
|
||||
|
||||
message FeeReportResponse {
|
||||
// An array of channel fee reports which describes the current fee schedule
|
||||
// for each channel.
|
||||
@ -4363,7 +4371,11 @@ message PolicyUpdateRequest {
|
||||
|
||||
// If true, min_htlc_msat is applied.
|
||||
bool min_htlc_msat_specified = 8;
|
||||
|
||||
int32 inbound_base_fee_msat = 10;
|
||||
int32 inbound_fee_rate_ppm = 11;
|
||||
}
|
||||
|
||||
enum UpdateFailure {
|
||||
UPDATE_FAILURE_UNKNOWN = 0;
|
||||
UPDATE_FAILURE_PENDING = 1;
|
||||
|
@ -4238,6 +4238,16 @@
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "The effective fee rate in milli-satoshis. Computed by dividing the\nfee_per_mil value by 1 million."
|
||||
},
|
||||
"inbound_base_fee_msat": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "The base fee charged regardless of the number of milli-satoshis sent."
|
||||
},
|
||||
"inbound_fee_per_mil": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "The amount charged per milli-satoshis transferred expressed in\nmillionths of a satoshi."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6536,6 +6546,14 @@
|
||||
"min_htlc_msat_specified": {
|
||||
"type": "boolean",
|
||||
"description": "If true, min_htlc_msat is applied."
|
||||
},
|
||||
"inbound_base_fee_msat": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"inbound_fee_rate_ppm": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -112,6 +112,7 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
|
||||
TimeLockDelta: uint32(edge.TimeLockDelta),
|
||||
MinHTLCOut: edge.MinHTLC,
|
||||
MaxHTLC: edge.MaxHTLC,
|
||||
InboundFee: newSchema.InboundFee,
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -180,6 +181,12 @@ func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint,
|
||||
edge.FeeProportionalMillionths = lnwire.MilliSatoshi(
|
||||
newSchema.FeeRate,
|
||||
)
|
||||
|
||||
inboundFee := newSchema.InboundFee.ToWire()
|
||||
if err := edge.ExtraOpaqueData.PackRecords(&inboundFee); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
edge.TimeLockDelta = uint16(newSchema.TimeLockDelta)
|
||||
|
||||
// Retrieve negotiated channel htlc amt limits.
|
||||
|
@ -287,6 +287,10 @@ type FeeSchema struct {
|
||||
// the effective fee rate charged per mSAT will be: (amount *
|
||||
// FeeRate/1,000,000).
|
||||
FeeRate uint32
|
||||
|
||||
// InboundFee is the inbound fee schedule that applies to forwards
|
||||
// coming in through a channel to which this FeeSchema pertains.
|
||||
InboundFee models.InboundFee
|
||||
}
|
||||
|
||||
// ChannelPolicy holds the parameters that determine the policy we enforce
|
||||
|
16
rpcserver.go
16
rpcserver.go
@ -6877,6 +6877,15 @@ func (r *rpcServer) FeeReport(ctx context.Context,
|
||||
edgePolicy.FeeProportionalMillionths
|
||||
feeRate := float64(feeRateFixedPoint) / feeBase
|
||||
|
||||
// Decode inbound fee from extra data.
|
||||
var inboundFee lnwire.Fee
|
||||
_, err := edgePolicy.ExtraOpaqueData.ExtractRecords(
|
||||
&inboundFee,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO(roasbeef): also add stats for revenue for each
|
||||
// channel
|
||||
feeReports = append(feeReports, &lnrpc.ChannelFeeReport{
|
||||
@ -6885,6 +6894,9 @@ func (r *rpcServer) FeeReport(ctx context.Context,
|
||||
BaseFeeMsat: int64(edgePolicy.FeeBaseMSat),
|
||||
FeePerMil: int64(feeRateFixedPoint),
|
||||
FeeRate: feeRate,
|
||||
|
||||
InboundBaseFeeMsat: inboundFee.BaseFee,
|
||||
InboundFeePerMil: inboundFee.FeeRate,
|
||||
})
|
||||
|
||||
return nil
|
||||
@ -7071,6 +7083,10 @@ func (r *rpcServer) UpdateChannelPolicy(ctx context.Context,
|
||||
feeSchema := routing.FeeSchema{
|
||||
BaseFee: baseFeeMsat,
|
||||
FeeRate: feeRateFixed,
|
||||
InboundFee: models.InboundFee{
|
||||
Base: req.InboundBaseFeeMsat,
|
||||
Rate: req.InboundFeeRatePpm,
|
||||
},
|
||||
}
|
||||
|
||||
maxHtlc := lnwire.MilliSatoshi(req.MaxHtlcMsat)
|
||||
|
Loading…
Reference in New Issue
Block a user