Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions Bitkit/Services/LightningService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ class LightningService {

static var shared = LightningService()

private static let scoringBasePenaltyMsat: UInt64 = 50000
private static let scoringLiquidityPenaltyMultiplierMsat: UInt64 = 10000
private static let scoringLiquidityPenaltyAmountMultiplierMsat: UInt64 = 10000
private static let scoringHistoricalLiquidityPenaltyAmountMultiplierMsat: UInt64 = 20000
private static let scoringConsideredImpossiblePenaltyMsat: UInt64 = 1_000_000_000_000
private static let scoringProbingDiversityPenaltyMsat: UInt64 = 60000

private static let defaultScoringFeeParameters = ScoringFeeParameters(
basePenaltyMsat: 1024,
basePenaltyAmountMultiplierMsat: 131_072,
liquidityPenaltyMultiplierMsat: 0,
liquidityPenaltyAmountMultiplierMsat: 0,
historicalLiquidityPenaltyMultiplierMsat: 10000,
historicalLiquidityPenaltyAmountMultiplierMsat: 1250,
antiProbingPenaltyMsat: 250,
consideredImpossiblePenaltyMsat: 100_000_000_000,
linearSuccessProbability: false,
probingDiversityPenaltyMsat: 0
)

private init() {}

/// Flag and lock to prevent concurrent setup calls
Expand Down Expand Up @@ -107,6 +127,8 @@ class LightningService {
builder.setPathfindingScoresSource(url: scorerUrl)
}

builder.setScoringFeeParams(params: Self.scoringFeeParameters(config: config))

// Configure gossip source from current settings
configureGossipSource(builder: builder, rgsServerUrl: rgsServerUrl)

Expand Down Expand Up @@ -1575,6 +1597,23 @@ extension LightningService {

// MARK: - Probing

private static func scoringFeeParameters(config: Config) -> ScoringFeeParameters {
let defaultParameters = config.scoringFeeParams ?? defaultScoringFeeParameters

return ScoringFeeParameters(
basePenaltyMsat: scoringBasePenaltyMsat,
basePenaltyAmountMultiplierMsat: defaultParameters.basePenaltyAmountMultiplierMsat,
liquidityPenaltyMultiplierMsat: scoringLiquidityPenaltyMultiplierMsat,
liquidityPenaltyAmountMultiplierMsat: scoringLiquidityPenaltyAmountMultiplierMsat,
historicalLiquidityPenaltyMultiplierMsat: defaultParameters.historicalLiquidityPenaltyMultiplierMsat,
historicalLiquidityPenaltyAmountMultiplierMsat: scoringHistoricalLiquidityPenaltyAmountMultiplierMsat,
antiProbingPenaltyMsat: defaultParameters.antiProbingPenaltyMsat,
consideredImpossiblePenaltyMsat: scoringConsideredImpossiblePenaltyMsat,
linearSuccessProbability: defaultParameters.linearSuccessProbability,
probingDiversityPenaltyMsat: scoringProbingDiversityPenaltyMsat
)
}

/// Sends a probe to test if a payment route exists for the given invoice.
/// - Parameters:
/// - bolt11: The Lightning invoice string (BOLT 11)
Expand Down
8 changes: 4 additions & 4 deletions Bitkit/ViewModels/WalletViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class WalletViewModel: ObservableObject {
success: false,
paymentId: paymentId,
paymentHash: paymentHash,
shortChannelId: shortChannelId,
shortChannelId: shortChannelId.map(String.init),
routeFeeMsat: routeFeeMsat
)
case let .paymentReceived(_, paymentHash, _, _):
Expand Down Expand Up @@ -681,7 +681,7 @@ class WalletViewModel: ObservableObject {
let success: Bool
let paymentId: PaymentId
let paymentHash: PaymentHash
let shortChannelId: UInt64?
let shortChannelId: String?
let routeFeeMsat: UInt64?
}

Expand Down Expand Up @@ -724,7 +724,7 @@ class WalletViewModel: ObservableObject {
success: false,
paymentId: paymentId,
paymentHash: paymentHash,
shortChannelId: shortChannelId,
shortChannelId: shortChannelId.map(String.init),
routeFeeMsat: routeFeeMsat
)
if pendingPaymentIds.isEmpty, let lastFailure {
Expand All @@ -739,7 +739,7 @@ class WalletViewModel: ObservableObject {
}
}

private func cacheProbeOutcome(success: Bool, paymentId: PaymentId, paymentHash: PaymentHash, shortChannelId: UInt64?, routeFeeMsat: UInt64?) {
private func cacheProbeOutcome(success: Bool, paymentId: PaymentId, paymentHash: PaymentHash, shortChannelId: String?, routeFeeMsat: UInt64?) {
probeOutcomes[paymentId] = ProbeOutcome(
success: success,
paymentId: paymentId,
Expand Down
2 changes: 1 addition & 1 deletion Bitkit/Views/Settings/ProbingTool/ProbingToolScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ struct ProbingToolScreen: View {
}
app.toast(type: .success, title: "Probe Successful", description: "Route verified in \(durationMs) ms")
} else {
let scidText = resolved.shortChannelId.map(String.init) ?? "unknown"
let scidText = resolved.shortChannelId ?? "unknown"
let message = "Hash: \(resolved.paymentHash), SCID: \(scidText)"
await MainActor.run {
probeResult = ProbeResult(
Expand Down
1 change: 1 addition & 0 deletions changelog.d/next/623.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved Lightning payment route selection reliability.
Loading