allow configuring an array of opening params

This commit is contained in:
Jesse de Wit
2023-05-12 14:04:00 +02:00
parent acffe289ff
commit aaccc5fafb
4 changed files with 70 additions and 41 deletions

View File

@@ -66,8 +66,18 @@ type NodeConfig struct {
// The channel can be closed if not used this duration in seconds.
MaxInactiveDuration uint64 `json:"maxInactiveDuration,string"`
// The validity duration of an opening params promise.
FeeValidityDuration uint64 `json:"feeValidityDuration,string"`
FeeParams []*FeeParamsSettings `json:"feeParams"`
// Set this field to connect to an LND node.
Lnd *LndConfig `json:"lnd,omitempty"`
// Set this field to connect to a CLN node.
Cln *ClnConfig `json:"cln,omitempty"`
}
type FeeParamsSettings struct {
// The validity duration of an opening params promise in seconds.
ValidityDuration uint64 `json:"validityDuration,string"`
// Maximum number of blocks that the client is allowed to set its
// `to_self_delay` parameter.
@@ -80,13 +90,16 @@ type NodeConfig struct {
// fee rate, and take a margin of 20%, the fee multiplication factor should
// be 500 * 1.2 * 1000 = 600000. With 20 sat/vbyte, the resulting minimum fee
// would be 600000 * 20 = 12000000msat = 12000sat.
FeeMultiplicationFactor uint64 `json:"feeMultiplicationFactor,string"`
MultiplicationFactor uint64 `json:"multiplicationFactor,string"`
// Set this field to connect to an LND node.
Lnd *LndConfig `json:"lnd,omitempty"`
// The proportional fee to charge on channeel opens in ppm.
Proportional uint32 `json:"proportional,string"`
// Set this field to connect to a CLN node.
Cln *ClnConfig `json:"cln,omitempty"`
// The minimum fee to charge for a channel open.
MinimumFeeMsat uint64 `json:"minimumFeeMsat,string"`
// The maximum idle time in blocks
MaxIdleTime uint32 `json:"maxIdleTime,string"`
}
type LndConfig struct {

View File

@@ -102,7 +102,7 @@ func (i *Interceptor) Intercept(nextHop string, reqPaymentHash []byte, reqOutgoi
Proportional: uint32(i.config.ChannelFeePermyriad * 100),
ValidUntil: time.Now().UTC().Add(time.Duration(time.Hour * 24)).Format(basetypes.TIME_FORMAT),
MaxIdleTime: uint32(i.config.MaxInactiveDuration / 600),
MaxClientToSelfDelay: uint32(i.config.MaxClientToSelfDelay),
MaxClientToSelfDelay: uint32(10000),
}
}

View File

@@ -109,11 +109,18 @@ func newLspd(h *lntest.TestHarness, mem *mempoolApi, name string, nodeConfig *co
ChannelMinimumFeeMsat: 2000000,
AdditionalChannelCapacity: 100000,
MaxInactiveDuration: 3888000,
FeeValidityDuration: 60 * 60 * 24,
MaxClientToSelfDelay: 2016,
FeeMultiplicationFactor: 1000000,
Lnd: lnd,
Cln: cln,
FeeParams: []*config.FeeParamsSettings{
{
ValidityDuration: 60 * 60 * 24,
MaxClientToSelfDelay: 2016,
MultiplicationFactor: 1000000,
Proportional: 4000,
MinimumFeeMsat: 2000000,
MaxIdleTime: 6480,
},
},
Lnd: lnd,
Cln: cln,
}
if nodeConfig != nil {

View File

@@ -10,6 +10,7 @@ import (
"log"
"math"
"net"
"sort"
"strings"
"time"
@@ -67,7 +68,7 @@ func (s *server) ChannelInformation(ctx context.Context, in *lspdrpc.ChannelInfo
return nil, err
}
params, err := s.createOpeningParams(ctx, node)
params, err := s.createOpeningParamsMenu(ctx, node)
if err != nil {
return nil, err
}
@@ -86,14 +87,16 @@ func (s *server) ChannelInformation(ctx context.Context, in *lspdrpc.ChannelInfo
ChannelMinimumFeeMsat: int64(node.nodeConfig.ChannelMinimumFeeMsat),
LspPubkey: node.publicKey.SerializeCompressed(), // TODO: Is the publicKey different from the ecies public key?
MaxInactiveDuration: int64(node.nodeConfig.MaxInactiveDuration),
OpeningFeeParamsMenu: []*lspdrpc.OpeningFeeParams{params},
OpeningFeeParamsMenu: params,
}, nil
}
func (s *server) createOpeningParams(
func (s *server) createOpeningParamsMenu(
ctx context.Context,
node *node,
) (*lspdrpc.OpeningFeeParams, error) {
) ([]*lspdrpc.OpeningFeeParams, error) {
var menu []*lspdrpc.OpeningFeeParams
// Get a fee estimate.
estimate, err := s.feeEstimator.EstimateFeeRate(ctx, s.feeStrategy)
if err != nil {
@@ -101,33 +104,39 @@ func (s *server) createOpeningParams(
return nil, fmt.Errorf("failed to get fee estimate")
}
// Multiply the fee estiimate by the configured multiplication factor.
minFeeMsat := estimate.SatPerVByte *
float64(node.nodeConfig.FeeMultiplicationFactor)
for _, setting := range node.nodeConfig.FeeParams {
// Multiply the fee estiimate by the configured multiplication factor.
minFeeMsat := estimate.SatPerVByte *
float64(setting.MultiplicationFactor)
// Make sure the fee is not lower than the minimum fee.
minFeeMsat = math.Max(minFeeMsat, float64(node.nodeConfig.ChannelMinimumFeeMsat))
// Make sure the fee is not lower than the minimum fee.
minFeeMsat = math.Max(minFeeMsat, float64(setting.MinimumFeeMsat))
validUntil := time.Now().UTC().Add(
time.Second * time.Duration(node.nodeConfig.FeeValidityDuration),
)
params := &lspdrpc.OpeningFeeParams{
MinMsat: uint64(minFeeMsat),
// Proportional is ppm, so divide by 100.
Proportional: uint32(node.nodeConfig.ChannelFeePermyriad / 100),
ValidUntil: validUntil.Format(basetypes.TIME_FORMAT),
// MaxInactiveDuration is in seconds, so divide by 600 for blocks.
MaxIdleTime: uint32(node.nodeConfig.MaxInactiveDuration / 600),
MaxClientToSelfDelay: uint32(node.nodeConfig.MaxClientToSelfDelay),
validUntil := time.Now().UTC().Add(
time.Second * time.Duration(setting.ValidityDuration),
)
params := &lspdrpc.OpeningFeeParams{
MinMsat: uint64(minFeeMsat),
Proportional: setting.Proportional,
ValidUntil: validUntil.Format(basetypes.TIME_FORMAT),
MaxIdleTime: setting.MaxIdleTime,
MaxClientToSelfDelay: uint32(setting.MaxClientToSelfDelay),
}
promise, err := createPromise(node, params)
if err != nil {
log.Printf("Failed to create promise: %v", err)
return nil, err
}
params.Promise = *promise
menu = append(menu, params)
}
promise, err := createPromise(node, params)
if err != nil {
log.Printf("Failed to create promise: %v", err)
}
params.Promise = *promise
return params, nil
sort.Slice(menu, func(i, j int) bool {
return menu[i].MinMsat < menu[j].MinMsat
})
return menu, nil
}
func createPromise(node *node, params *lspdrpc.OpeningFeeParams) (*string, error) {
@@ -238,7 +247,7 @@ func (s *server) RegisterPayment(
Proportional: uint32(node.nodeConfig.ChannelFeePermyriad * 100),
ValidUntil: time.Now().UTC().Add(time.Duration(time.Hour * 24)).Format(basetypes.TIME_FORMAT),
MaxIdleTime: uint32(node.nodeConfig.MaxInactiveDuration / 600),
MaxClientToSelfDelay: uint32(node.nodeConfig.MaxClientToSelfDelay),
MaxClientToSelfDelay: uint32(10000),
}
}