diff --git a/.gitignore b/.gitignore index d66282f25..fe9c51cb2 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,9 @@ swift.swiftdoc *.a *.d +# macOS Finder metadata (icon positions, view options) +.DS_Store + # IDE and local files .idea .build diff --git a/CHANGELOG.md b/CHANGELOG.md index a618f6f1f..c8d04799a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,12 @@ ## Synonym Fork Additions +- Added configurable routing scorer parameters: + - New config structs: `ScoringFeeParameters` and `ScoringDecayParameters` + - New `Config` fields: `scoring_fee_params` and `scoring_decay_params` (optional; default to + LDK probabilistic scorer defaults when unset) + - New builder APIs: `set_scoring_fee_params(...)` and `set_scoring_decay_params(...)` + - Exposed via UniFFI/UDL for Swift/Kotlin/Python consumers - Added `connection_timeout_secs` field to `ElectrumSyncConfig` (default: 10 s). This bounds Electrum socket operations for both the BDK on-chain and LDK tx-sync clients, preventing Tokio's blocking thread pool from being exhausted by threads stuck on dead sockets under total packet diff --git a/Package.swift b/Package.swift index 9d261f9dc..aecdc3628 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let tag = "v0.7.0-rc.36" -let checksum = "de56fe19149808ccc5e517047ea7bf6b4d5d2c2e33d3ad539ef0155bf1aec8f7" +let checksum = "b7270d0e8d81de05ea70531618fe3350c3069e67ad561c87e8a234227352fe11" let url = "https://github.com/synonymdev/ldk-node/releases/download/\(tag)/LDKNodeFFI.xcframework.zip" let package = Package( diff --git a/bindings/kotlin/.editorconfig b/bindings/kotlin/.editorconfig new file mode 100644 index 000000000..a1479ffd2 --- /dev/null +++ b/bindings/kotlin/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*.kt] +indent_style = space +indent_size = 4 + +[*.kts] +indent_style = space +indent_size = 4 diff --git a/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/arm64-v8a/libldk_node.so b/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/arm64-v8a/libldk_node.so index b5cd3ffea..cd9330669 100755 Binary files a/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/arm64-v8a/libldk_node.so and b/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/arm64-v8a/libldk_node.so differ diff --git a/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/armeabi-v7a/libldk_node.so b/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/armeabi-v7a/libldk_node.so index 4562ceaa7..45e31e6ee 100755 Binary files a/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/armeabi-v7a/libldk_node.so and b/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/armeabi-v7a/libldk_node.so differ diff --git a/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/x86_64/libldk_node.so b/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/x86_64/libldk_node.so index 4c7768d1d..d24e04f99 100755 Binary files a/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/x86_64/libldk_node.so and b/bindings/kotlin/ldk-node-android/lib/src/main/jniLibs/x86_64/libldk_node.so differ diff --git a/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.android.kt b/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.android.kt index 5a12c371c..8e0ba22d6 100644 --- a/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.android.kt +++ b/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.android.kt @@ -1517,6 +1517,10 @@ internal typealias UniffiVTableCallbackInterfaceVssHeaderProviderUniffiByValue = + + + + @@ -2107,6 +2111,16 @@ internal interface UniffiLib : Library { `url`: RustBufferByValue, uniffiCallStatus: UniffiRustCallStatus, ): Unit + fun uniffi_ldk_node_fn_method_builder_set_scoring_decay_params( + `ptr`: Pointer?, + `params`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): Unit + fun uniffi_ldk_node_fn_method_builder_set_scoring_fee_params( + `ptr`: Pointer?, + `params`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): Unit fun uniffi_ldk_node_fn_method_builder_set_storage_dir_path( `ptr`: Pointer?, `storageDirPath`: RustBufferByValue, @@ -3178,6 +3192,10 @@ internal interface UniffiLib : Library { ): Short fun uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source( ): Short + fun uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params( + ): Short + fun uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params( + ): Short fun uniffi_ldk_node_checksum_method_builder_set_storage_dir_path( ): Short fun uniffi_ldk_node_checksum_method_feerate_to_sat_per_kwu( @@ -3695,6 +3713,12 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source() != 63501.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params() != 19869.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params() != 11588.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_ldk_node_checksum_method_builder_set_storage_dir_path() != 59019.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -6099,6 +6123,30 @@ open class Builder: Disposable, BuilderInterface { } } + override fun `setScoringDecayParams`(`params`: ScoringDecayParameters) { + callWithPointer { + uniffiRustCall { uniffiRustCallStatus -> + UniffiLib.INSTANCE.uniffi_ldk_node_fn_method_builder_set_scoring_decay_params( + it, + FfiConverterTypeScoringDecayParameters.lower(`params`), + uniffiRustCallStatus, + ) + } + } + } + + override fun `setScoringFeeParams`(`params`: ScoringFeeParameters) { + callWithPointer { + uniffiRustCall { uniffiRustCallStatus -> + UniffiLib.INSTANCE.uniffi_ldk_node_fn_method_builder_set_scoring_fee_params( + it, + FfiConverterTypeScoringFeeParameters.lower(`params`), + uniffiRustCallStatus, + ) + } + } + } + override fun `setStorageDirPath`(`storageDirPath`: kotlin.String) { callWithPointer { uniffiRustCall { uniffiRustCallStatus -> @@ -9417,6 +9465,8 @@ object FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterULong.read(buf), FfiConverterOptionalTypeAnchorChannelsConfig.read(buf), FfiConverterOptionalTypeRouteParametersConfig.read(buf), + FfiConverterOptionalTypeScoringFeeParameters.read(buf), + FfiConverterOptionalTypeScoringDecayParameters.read(buf), FfiConverterBoolean.read(buf), FfiConverterTypeAddressType.read(buf), FfiConverterSequenceTypeAddressType.read(buf), @@ -9433,6 +9483,8 @@ object FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterULong.allocationSize(value.`probingLiquidityLimitMultiplier`) + FfiConverterOptionalTypeAnchorChannelsConfig.allocationSize(value.`anchorChannelsConfig`) + FfiConverterOptionalTypeRouteParametersConfig.allocationSize(value.`routeParameters`) + + FfiConverterOptionalTypeScoringFeeParameters.allocationSize(value.`scoringFeeParams`) + + FfiConverterOptionalTypeScoringDecayParameters.allocationSize(value.`scoringDecayParams`) + FfiConverterBoolean.allocationSize(value.`includeUntrustedPendingInSpendable`) + FfiConverterTypeAddressType.allocationSize(value.`addressType`) + FfiConverterSequenceTypeAddressType.allocationSize(value.`addressTypesToMonitor`) @@ -9448,6 +9500,8 @@ object FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterULong.write(value.`probingLiquidityLimitMultiplier`, buf) FfiConverterOptionalTypeAnchorChannelsConfig.write(value.`anchorChannelsConfig`, buf) FfiConverterOptionalTypeRouteParametersConfig.write(value.`routeParameters`, buf) + FfiConverterOptionalTypeScoringFeeParameters.write(value.`scoringFeeParams`, buf) + FfiConverterOptionalTypeScoringDecayParameters.write(value.`scoringDecayParams`, buf) FfiConverterBoolean.write(value.`includeUntrustedPendingInSpendable`, buf) FfiConverterTypeAddressType.write(value.`addressType`, buf) FfiConverterSequenceTypeAddressType.write(value.`addressTypesToMonitor`, buf) @@ -10085,6 +10139,74 @@ object FfiConverterTypeRuntimeSyncIntervals: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringDecayParameters { + return ScoringDecayParameters( + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + ) + } + + override fun allocationSize(value: ScoringDecayParameters) = ( + FfiConverterULong.allocationSize(value.`historicalNoUpdatesHalfLifeSecs`) + + FfiConverterULong.allocationSize(value.`liquidityOffsetHalfLifeSecs`) + ) + + override fun write(value: ScoringDecayParameters, buf: ByteBuffer) { + FfiConverterULong.write(value.`historicalNoUpdatesHalfLifeSecs`, buf) + FfiConverterULong.write(value.`liquidityOffsetHalfLifeSecs`, buf) + } +} + + + + +object FfiConverterTypeScoringFeeParameters: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringFeeParameters { + return ScoringFeeParameters( + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterBoolean.read(buf), + FfiConverterULong.read(buf), + ) + } + + override fun allocationSize(value: ScoringFeeParameters) = ( + FfiConverterULong.allocationSize(value.`basePenaltyMsat`) + + FfiConverterULong.allocationSize(value.`basePenaltyAmountMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`liquidityPenaltyMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`liquidityPenaltyAmountMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`historicalLiquidityPenaltyMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`historicalLiquidityPenaltyAmountMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`antiProbingPenaltyMsat`) + + FfiConverterULong.allocationSize(value.`consideredImpossiblePenaltyMsat`) + + FfiConverterBoolean.allocationSize(value.`linearSuccessProbability`) + + FfiConverterULong.allocationSize(value.`probingDiversityPenaltyMsat`) + ) + + override fun write(value: ScoringFeeParameters, buf: ByteBuffer) { + FfiConverterULong.write(value.`basePenaltyMsat`, buf) + FfiConverterULong.write(value.`basePenaltyAmountMultiplierMsat`, buf) + FfiConverterULong.write(value.`liquidityPenaltyMultiplierMsat`, buf) + FfiConverterULong.write(value.`liquidityPenaltyAmountMultiplierMsat`, buf) + FfiConverterULong.write(value.`historicalLiquidityPenaltyMultiplierMsat`, buf) + FfiConverterULong.write(value.`historicalLiquidityPenaltyAmountMultiplierMsat`, buf) + FfiConverterULong.write(value.`antiProbingPenaltyMsat`, buf) + FfiConverterULong.write(value.`consideredImpossiblePenaltyMsat`, buf) + FfiConverterBoolean.write(value.`linearSuccessProbability`, buf) + FfiConverterULong.write(value.`probingDiversityPenaltyMsat`, buf) + } +} + + + + object FfiConverterTypeSpendableUtxo: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): SpendableUtxo { return SpendableUtxo( @@ -12929,6 +13051,64 @@ object FfiConverterOptionalTypeRouteParametersConfig: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringDecayParameters? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterTypeScoringDecayParameters.read(buf) + } + + override fun allocationSize(value: ScoringDecayParameters?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterTypeScoringDecayParameters.allocationSize(value) + } + } + + override fun write(value: ScoringDecayParameters?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterTypeScoringDecayParameters.write(value, buf) + } + } +} + + + + +object FfiConverterOptionalTypeScoringFeeParameters: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringFeeParameters? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterTypeScoringFeeParameters.read(buf) + } + + override fun allocationSize(value: ScoringFeeParameters?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterTypeScoringFeeParameters.allocationSize(value) + } + } + + override fun write(value: ScoringFeeParameters?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterTypeScoringFeeParameters.write(value, buf) + } + } +} + + + + object FfiConverterOptionalTypeTransactionDetails: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): TransactionDetails? { if (buf.get().toInt() == 0) { diff --git a/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt b/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt index e79493a9f..b3c0eebea 100644 --- a/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt +++ b/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt @@ -352,6 +352,10 @@ interface BuilderInterface { fun `setPathfindingScoresSource`(`url`: kotlin.String) + fun `setScoringDecayParams`(`params`: ScoringDecayParameters) + + fun `setScoringFeeParams`(`params`: ScoringFeeParameters) + fun `setStorageDirPath`(`storageDirPath`: kotlin.String) companion object @@ -849,6 +853,8 @@ data class Config ( val `probingLiquidityLimitMultiplier`: kotlin.ULong, val `anchorChannelsConfig`: AnchorChannelsConfig?, val `routeParameters`: RouteParametersConfig?, + val `scoringFeeParams`: ScoringFeeParameters?, + val `scoringDecayParams`: ScoringDecayParameters?, val `includeUntrustedPendingInSpendable`: kotlin.Boolean, val `addressType`: AddressType, val `addressTypesToMonitor`: List @@ -1161,6 +1167,34 @@ data class RuntimeSyncIntervals ( +@kotlinx.serialization.Serializable +data class ScoringDecayParameters ( + val `historicalNoUpdatesHalfLifeSecs`: kotlin.ULong, + val `liquidityOffsetHalfLifeSecs`: kotlin.ULong +) { + companion object +} + + + +@kotlinx.serialization.Serializable +data class ScoringFeeParameters ( + val `basePenaltyMsat`: kotlin.ULong, + val `basePenaltyAmountMultiplierMsat`: kotlin.ULong, + val `liquidityPenaltyMultiplierMsat`: kotlin.ULong, + val `liquidityPenaltyAmountMultiplierMsat`: kotlin.ULong, + val `historicalLiquidityPenaltyMultiplierMsat`: kotlin.ULong, + val `historicalLiquidityPenaltyAmountMultiplierMsat`: kotlin.ULong, + val `antiProbingPenaltyMsat`: kotlin.ULong, + val `consideredImpossiblePenaltyMsat`: kotlin.ULong, + val `linearSuccessProbability`: kotlin.Boolean, + val `probingDiversityPenaltyMsat`: kotlin.ULong +) { + companion object +} + + + @kotlinx.serialization.Serializable data class SpendableUtxo ( val `outpoint`: OutPoint, @@ -2245,6 +2279,10 @@ enum class WordCount { + + + + diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt b/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt index e79493a9f..b3c0eebea 100644 --- a/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt +++ b/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.common.kt @@ -352,6 +352,10 @@ interface BuilderInterface { fun `setPathfindingScoresSource`(`url`: kotlin.String) + fun `setScoringDecayParams`(`params`: ScoringDecayParameters) + + fun `setScoringFeeParams`(`params`: ScoringFeeParameters) + fun `setStorageDirPath`(`storageDirPath`: kotlin.String) companion object @@ -849,6 +853,8 @@ data class Config ( val `probingLiquidityLimitMultiplier`: kotlin.ULong, val `anchorChannelsConfig`: AnchorChannelsConfig?, val `routeParameters`: RouteParametersConfig?, + val `scoringFeeParams`: ScoringFeeParameters?, + val `scoringDecayParams`: ScoringDecayParameters?, val `includeUntrustedPendingInSpendable`: kotlin.Boolean, val `addressType`: AddressType, val `addressTypesToMonitor`: List @@ -1161,6 +1167,34 @@ data class RuntimeSyncIntervals ( +@kotlinx.serialization.Serializable +data class ScoringDecayParameters ( + val `historicalNoUpdatesHalfLifeSecs`: kotlin.ULong, + val `liquidityOffsetHalfLifeSecs`: kotlin.ULong +) { + companion object +} + + + +@kotlinx.serialization.Serializable +data class ScoringFeeParameters ( + val `basePenaltyMsat`: kotlin.ULong, + val `basePenaltyAmountMultiplierMsat`: kotlin.ULong, + val `liquidityPenaltyMultiplierMsat`: kotlin.ULong, + val `liquidityPenaltyAmountMultiplierMsat`: kotlin.ULong, + val `historicalLiquidityPenaltyMultiplierMsat`: kotlin.ULong, + val `historicalLiquidityPenaltyAmountMultiplierMsat`: kotlin.ULong, + val `antiProbingPenaltyMsat`: kotlin.ULong, + val `consideredImpossiblePenaltyMsat`: kotlin.ULong, + val `linearSuccessProbability`: kotlin.Boolean, + val `probingDiversityPenaltyMsat`: kotlin.ULong +) { + companion object +} + + + @kotlinx.serialization.Serializable data class SpendableUtxo ( val `outpoint`: OutPoint, @@ -2245,6 +2279,10 @@ enum class WordCount { + + + + diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.jvm.kt b/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.jvm.kt index f61b26797..583ce6d7f 100644 --- a/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.jvm.kt +++ b/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.jvm.kt @@ -1515,6 +1515,10 @@ internal typealias UniffiVTableCallbackInterfaceVssHeaderProviderUniffiByValue = + + + + @@ -2105,6 +2109,16 @@ internal interface UniffiLib : Library { `url`: RustBufferByValue, uniffiCallStatus: UniffiRustCallStatus, ): Unit + fun uniffi_ldk_node_fn_method_builder_set_scoring_decay_params( + `ptr`: Pointer?, + `params`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): Unit + fun uniffi_ldk_node_fn_method_builder_set_scoring_fee_params( + `ptr`: Pointer?, + `params`: RustBufferByValue, + uniffiCallStatus: UniffiRustCallStatus, + ): Unit fun uniffi_ldk_node_fn_method_builder_set_storage_dir_path( `ptr`: Pointer?, `storageDirPath`: RustBufferByValue, @@ -3176,6 +3190,10 @@ internal interface UniffiLib : Library { ): Short fun uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source( ): Short + fun uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params( + ): Short + fun uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params( + ): Short fun uniffi_ldk_node_checksum_method_builder_set_storage_dir_path( ): Short fun uniffi_ldk_node_checksum_method_feerate_to_sat_per_kwu( @@ -3693,6 +3711,12 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source() != 63501.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params() != 19869.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params() != 11588.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_ldk_node_checksum_method_builder_set_storage_dir_path() != 59019.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -6088,6 +6112,30 @@ open class Builder: Disposable, BuilderInterface { } } + override fun `setScoringDecayParams`(`params`: ScoringDecayParameters) { + callWithPointer { + uniffiRustCall { uniffiRustCallStatus -> + UniffiLib.INSTANCE.uniffi_ldk_node_fn_method_builder_set_scoring_decay_params( + it, + FfiConverterTypeScoringDecayParameters.lower(`params`), + uniffiRustCallStatus, + ) + } + } + } + + override fun `setScoringFeeParams`(`params`: ScoringFeeParameters) { + callWithPointer { + uniffiRustCall { uniffiRustCallStatus -> + UniffiLib.INSTANCE.uniffi_ldk_node_fn_method_builder_set_scoring_fee_params( + it, + FfiConverterTypeScoringFeeParameters.lower(`params`), + uniffiRustCallStatus, + ) + } + } + } + override fun `setStorageDirPath`(`storageDirPath`: kotlin.String) { callWithPointer { uniffiRustCall { uniffiRustCallStatus -> @@ -9406,6 +9454,8 @@ object FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterULong.read(buf), FfiConverterOptionalTypeAnchorChannelsConfig.read(buf), FfiConverterOptionalTypeRouteParametersConfig.read(buf), + FfiConverterOptionalTypeScoringFeeParameters.read(buf), + FfiConverterOptionalTypeScoringDecayParameters.read(buf), FfiConverterBoolean.read(buf), FfiConverterTypeAddressType.read(buf), FfiConverterSequenceTypeAddressType.read(buf), @@ -9422,6 +9472,8 @@ object FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterULong.allocationSize(value.`probingLiquidityLimitMultiplier`) + FfiConverterOptionalTypeAnchorChannelsConfig.allocationSize(value.`anchorChannelsConfig`) + FfiConverterOptionalTypeRouteParametersConfig.allocationSize(value.`routeParameters`) + + FfiConverterOptionalTypeScoringFeeParameters.allocationSize(value.`scoringFeeParams`) + + FfiConverterOptionalTypeScoringDecayParameters.allocationSize(value.`scoringDecayParams`) + FfiConverterBoolean.allocationSize(value.`includeUntrustedPendingInSpendable`) + FfiConverterTypeAddressType.allocationSize(value.`addressType`) + FfiConverterSequenceTypeAddressType.allocationSize(value.`addressTypesToMonitor`) @@ -9437,6 +9489,8 @@ object FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterULong.write(value.`probingLiquidityLimitMultiplier`, buf) FfiConverterOptionalTypeAnchorChannelsConfig.write(value.`anchorChannelsConfig`, buf) FfiConverterOptionalTypeRouteParametersConfig.write(value.`routeParameters`, buf) + FfiConverterOptionalTypeScoringFeeParameters.write(value.`scoringFeeParams`, buf) + FfiConverterOptionalTypeScoringDecayParameters.write(value.`scoringDecayParams`, buf) FfiConverterBoolean.write(value.`includeUntrustedPendingInSpendable`, buf) FfiConverterTypeAddressType.write(value.`addressType`, buf) FfiConverterSequenceTypeAddressType.write(value.`addressTypesToMonitor`, buf) @@ -10074,6 +10128,74 @@ object FfiConverterTypeRuntimeSyncIntervals: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringDecayParameters { + return ScoringDecayParameters( + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + ) + } + + override fun allocationSize(value: ScoringDecayParameters) = ( + FfiConverterULong.allocationSize(value.`historicalNoUpdatesHalfLifeSecs`) + + FfiConverterULong.allocationSize(value.`liquidityOffsetHalfLifeSecs`) + ) + + override fun write(value: ScoringDecayParameters, buf: ByteBuffer) { + FfiConverterULong.write(value.`historicalNoUpdatesHalfLifeSecs`, buf) + FfiConverterULong.write(value.`liquidityOffsetHalfLifeSecs`, buf) + } +} + + + + +object FfiConverterTypeScoringFeeParameters: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringFeeParameters { + return ScoringFeeParameters( + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterULong.read(buf), + FfiConverterBoolean.read(buf), + FfiConverterULong.read(buf), + ) + } + + override fun allocationSize(value: ScoringFeeParameters) = ( + FfiConverterULong.allocationSize(value.`basePenaltyMsat`) + + FfiConverterULong.allocationSize(value.`basePenaltyAmountMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`liquidityPenaltyMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`liquidityPenaltyAmountMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`historicalLiquidityPenaltyMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`historicalLiquidityPenaltyAmountMultiplierMsat`) + + FfiConverterULong.allocationSize(value.`antiProbingPenaltyMsat`) + + FfiConverterULong.allocationSize(value.`consideredImpossiblePenaltyMsat`) + + FfiConverterBoolean.allocationSize(value.`linearSuccessProbability`) + + FfiConverterULong.allocationSize(value.`probingDiversityPenaltyMsat`) + ) + + override fun write(value: ScoringFeeParameters, buf: ByteBuffer) { + FfiConverterULong.write(value.`basePenaltyMsat`, buf) + FfiConverterULong.write(value.`basePenaltyAmountMultiplierMsat`, buf) + FfiConverterULong.write(value.`liquidityPenaltyMultiplierMsat`, buf) + FfiConverterULong.write(value.`liquidityPenaltyAmountMultiplierMsat`, buf) + FfiConverterULong.write(value.`historicalLiquidityPenaltyMultiplierMsat`, buf) + FfiConverterULong.write(value.`historicalLiquidityPenaltyAmountMultiplierMsat`, buf) + FfiConverterULong.write(value.`antiProbingPenaltyMsat`, buf) + FfiConverterULong.write(value.`consideredImpossiblePenaltyMsat`, buf) + FfiConverterBoolean.write(value.`linearSuccessProbability`, buf) + FfiConverterULong.write(value.`probingDiversityPenaltyMsat`, buf) + } +} + + + + object FfiConverterTypeSpendableUtxo: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): SpendableUtxo { return SpendableUtxo( @@ -12918,6 +13040,64 @@ object FfiConverterOptionalTypeRouteParametersConfig: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringDecayParameters? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterTypeScoringDecayParameters.read(buf) + } + + override fun allocationSize(value: ScoringDecayParameters?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterTypeScoringDecayParameters.allocationSize(value) + } + } + + override fun write(value: ScoringDecayParameters?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterTypeScoringDecayParameters.write(value, buf) + } + } +} + + + + +object FfiConverterOptionalTypeScoringFeeParameters: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): ScoringFeeParameters? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterTypeScoringFeeParameters.read(buf) + } + + override fun allocationSize(value: ScoringFeeParameters?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterTypeScoringFeeParameters.allocationSize(value) + } + } + + override fun write(value: ScoringFeeParameters?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterTypeScoringFeeParameters.write(value, buf) + } + } +} + + + + object FfiConverterOptionalTypeTransactionDetails: FfiConverterRustBuffer { override fun read(buf: ByteBuffer): TransactionDetails? { if (buf.get().toInt() == 0) { diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-aarch64/libldk_node.dylib b/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-aarch64/libldk_node.dylib index e5bfee794..12fde889c 100644 Binary files a/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-aarch64/libldk_node.dylib and b/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-aarch64/libldk_node.dylib differ diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-x86-64/libldk_node.dylib b/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-x86-64/libldk_node.dylib index ad19d4d19..7407fece9 100644 Binary files a/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-x86-64/libldk_node.dylib and b/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/darwin-x86-64/libldk_node.dylib differ diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 6f2f57380..8014b2dc2 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -16,11 +16,31 @@ dictionary Config { u64 probing_liquidity_limit_multiplier; AnchorChannelsConfig? anchor_channels_config; RouteParametersConfig? route_parameters; + ScoringFeeParameters? scoring_fee_params; + ScoringDecayParameters? scoring_decay_params; boolean include_untrusted_pending_in_spendable; AddressType address_type; sequence address_types_to_monitor; }; +dictionary ScoringFeeParameters { + u64 base_penalty_msat; + u64 base_penalty_amount_multiplier_msat; + u64 liquidity_penalty_multiplier_msat; + u64 liquidity_penalty_amount_multiplier_msat; + u64 historical_liquidity_penalty_multiplier_msat; + u64 historical_liquidity_penalty_amount_multiplier_msat; + u64 anti_probing_penalty_msat; + u64 considered_impossible_penalty_msat; + boolean linear_success_probability; + u64 probing_diversity_penalty_msat; +}; + +dictionary ScoringDecayParameters { + u64 historical_no_updates_half_life_secs; + u64 liquidity_offset_half_life_secs; +}; + dictionary AnchorChannelsConfig { sequence trusted_peers_no_reserve; u64 per_channel_reserve_sats; @@ -118,6 +138,8 @@ interface Builder { void set_gossip_source_p2p(); void set_gossip_source_rgs(string rgs_server_url); void set_pathfinding_scores_source(string url); + void set_scoring_fee_params(ScoringFeeParameters params); + void set_scoring_decay_params(ScoringDecayParameters params); void set_liquidity_source_lsps1(PublicKey node_id, SocketAddress address, string? token); void set_liquidity_source_lsps2(PublicKey node_id, SocketAddress address, string? token); void set_storage_dir_path(string storage_dir_path); diff --git a/bindings/python/src/ldk_node/ldk_node.py b/bindings/python/src/ldk_node/ldk_node.py index 22fc4ff43..ea1594ee2 100644 --- a/bindings/python/src/ldk_node/ldk_node.py +++ b/bindings/python/src/ldk_node/ldk_node.py @@ -649,6 +649,10 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source() != 63501: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params() != 19869: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params() != 11588: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_ldk_node_checksum_method_builder_set_storage_dir_path() != 59019: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_ldk_node_checksum_method_feerate_to_sat_per_kwu() != 58911: @@ -1646,6 +1650,18 @@ class _UniffiVTableCallbackInterfaceVssHeaderProvider(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_ldk_node_fn_method_builder_set_pathfinding_scores_source.restype = None +_UniffiLib.uniffi_ldk_node_fn_method_builder_set_scoring_decay_params.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_ldk_node_fn_method_builder_set_scoring_decay_params.restype = None +_UniffiLib.uniffi_ldk_node_fn_method_builder_set_scoring_fee_params.argtypes = ( + ctypes.c_void_p, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_ldk_node_fn_method_builder_set_scoring_fee_params.restype = None _UniffiLib.uniffi_ldk_node_fn_method_builder_set_storage_dir_path.argtypes = ( ctypes.c_void_p, _UniffiRustBuffer, @@ -3007,6 +3023,12 @@ class _UniffiVTableCallbackInterfaceVssHeaderProvider(ctypes.Structure): _UniffiLib.uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source.argtypes = ( ) _UniffiLib.uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source.restype = ctypes.c_uint16 +_UniffiLib.uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params.argtypes = ( +) +_UniffiLib.uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params.restype = ctypes.c_uint16 +_UniffiLib.uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params.argtypes = ( +) +_UniffiLib.uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params.restype = ctypes.c_uint16 _UniffiLib.uniffi_ldk_node_checksum_method_builder_set_storage_dir_path.argtypes = ( ) _UniffiLib.uniffi_ldk_node_checksum_method_builder_set_storage_dir_path.restype = ctypes.c_uint16 @@ -4701,6 +4723,10 @@ def set_node_alias(self, node_alias: "str"): raise NotImplementedError def set_pathfinding_scores_source(self, url: "str"): raise NotImplementedError + def set_scoring_decay_params(self, params: "ScoringDecayParameters"): + raise NotImplementedError + def set_scoring_fee_params(self, params: "ScoringFeeParameters"): + raise NotImplementedError def set_storage_dir_path(self, storage_dir_path: "str"): raise NotImplementedError @@ -5119,6 +5145,28 @@ def set_pathfinding_scores_source(self, url: "str") -> None: + def set_scoring_decay_params(self, params: "ScoringDecayParameters") -> None: + _UniffiConverterTypeScoringDecayParameters.check_lower(params) + + _uniffi_rust_call(_UniffiLib.uniffi_ldk_node_fn_method_builder_set_scoring_decay_params,self._uniffi_clone_pointer(), + _UniffiConverterTypeScoringDecayParameters.lower(params)) + + + + + + + def set_scoring_fee_params(self, params: "ScoringFeeParameters") -> None: + _UniffiConverterTypeScoringFeeParameters.check_lower(params) + + _uniffi_rust_call(_UniffiLib.uniffi_ldk_node_fn_method_builder_set_scoring_fee_params,self._uniffi_clone_pointer(), + _UniffiConverterTypeScoringFeeParameters.lower(params)) + + + + + + def set_storage_dir_path(self, storage_dir_path: "str") -> None: _UniffiConverterString.check_lower(storage_dir_path) @@ -8096,10 +8144,12 @@ class Config: probing_liquidity_limit_multiplier: "int" anchor_channels_config: "typing.Optional[AnchorChannelsConfig]" route_parameters: "typing.Optional[RouteParametersConfig]" + scoring_fee_params: "typing.Optional[ScoringFeeParameters]" + scoring_decay_params: "typing.Optional[ScoringDecayParameters]" include_untrusted_pending_in_spendable: "bool" address_type: "AddressType" address_types_to_monitor: "typing.List[AddressType]" - def __init__(self, *, storage_dir_path: "str", network: "Network", listening_addresses: "typing.Optional[typing.List[SocketAddress]]", announcement_addresses: "typing.Optional[typing.List[SocketAddress]]", node_alias: "typing.Optional[NodeAlias]", trusted_peers_0conf: "typing.List[PublicKey]", probing_liquidity_limit_multiplier: "int", anchor_channels_config: "typing.Optional[AnchorChannelsConfig]", route_parameters: "typing.Optional[RouteParametersConfig]", include_untrusted_pending_in_spendable: "bool", address_type: "AddressType", address_types_to_monitor: "typing.List[AddressType]"): + def __init__(self, *, storage_dir_path: "str", network: "Network", listening_addresses: "typing.Optional[typing.List[SocketAddress]]", announcement_addresses: "typing.Optional[typing.List[SocketAddress]]", node_alias: "typing.Optional[NodeAlias]", trusted_peers_0conf: "typing.List[PublicKey]", probing_liquidity_limit_multiplier: "int", anchor_channels_config: "typing.Optional[AnchorChannelsConfig]", route_parameters: "typing.Optional[RouteParametersConfig]", scoring_fee_params: "typing.Optional[ScoringFeeParameters]", scoring_decay_params: "typing.Optional[ScoringDecayParameters]", include_untrusted_pending_in_spendable: "bool", address_type: "AddressType", address_types_to_monitor: "typing.List[AddressType]"): self.storage_dir_path = storage_dir_path self.network = network self.listening_addresses = listening_addresses @@ -8109,12 +8159,14 @@ def __init__(self, *, storage_dir_path: "str", network: "Network", listening_add self.probing_liquidity_limit_multiplier = probing_liquidity_limit_multiplier self.anchor_channels_config = anchor_channels_config self.route_parameters = route_parameters + self.scoring_fee_params = scoring_fee_params + self.scoring_decay_params = scoring_decay_params self.include_untrusted_pending_in_spendable = include_untrusted_pending_in_spendable self.address_type = address_type self.address_types_to_monitor = address_types_to_monitor def __str__(self): - return "Config(storage_dir_path={}, network={}, listening_addresses={}, announcement_addresses={}, node_alias={}, trusted_peers_0conf={}, probing_liquidity_limit_multiplier={}, anchor_channels_config={}, route_parameters={}, include_untrusted_pending_in_spendable={}, address_type={}, address_types_to_monitor={})".format(self.storage_dir_path, self.network, self.listening_addresses, self.announcement_addresses, self.node_alias, self.trusted_peers_0conf, self.probing_liquidity_limit_multiplier, self.anchor_channels_config, self.route_parameters, self.include_untrusted_pending_in_spendable, self.address_type, self.address_types_to_monitor) + return "Config(storage_dir_path={}, network={}, listening_addresses={}, announcement_addresses={}, node_alias={}, trusted_peers_0conf={}, probing_liquidity_limit_multiplier={}, anchor_channels_config={}, route_parameters={}, scoring_fee_params={}, scoring_decay_params={}, include_untrusted_pending_in_spendable={}, address_type={}, address_types_to_monitor={})".format(self.storage_dir_path, self.network, self.listening_addresses, self.announcement_addresses, self.node_alias, self.trusted_peers_0conf, self.probing_liquidity_limit_multiplier, self.anchor_channels_config, self.route_parameters, self.scoring_fee_params, self.scoring_decay_params, self.include_untrusted_pending_in_spendable, self.address_type, self.address_types_to_monitor) def __eq__(self, other): if self.storage_dir_path != other.storage_dir_path: @@ -8135,6 +8187,10 @@ def __eq__(self, other): return False if self.route_parameters != other.route_parameters: return False + if self.scoring_fee_params != other.scoring_fee_params: + return False + if self.scoring_decay_params != other.scoring_decay_params: + return False if self.include_untrusted_pending_in_spendable != other.include_untrusted_pending_in_spendable: return False if self.address_type != other.address_type: @@ -8156,6 +8212,8 @@ def read(buf): probing_liquidity_limit_multiplier=_UniffiConverterUInt64.read(buf), anchor_channels_config=_UniffiConverterOptionalTypeAnchorChannelsConfig.read(buf), route_parameters=_UniffiConverterOptionalTypeRouteParametersConfig.read(buf), + scoring_fee_params=_UniffiConverterOptionalTypeScoringFeeParameters.read(buf), + scoring_decay_params=_UniffiConverterOptionalTypeScoringDecayParameters.read(buf), include_untrusted_pending_in_spendable=_UniffiConverterBool.read(buf), address_type=_UniffiConverterTypeAddressType.read(buf), address_types_to_monitor=_UniffiConverterSequenceTypeAddressType.read(buf), @@ -8172,6 +8230,8 @@ def check_lower(value): _UniffiConverterUInt64.check_lower(value.probing_liquidity_limit_multiplier) _UniffiConverterOptionalTypeAnchorChannelsConfig.check_lower(value.anchor_channels_config) _UniffiConverterOptionalTypeRouteParametersConfig.check_lower(value.route_parameters) + _UniffiConverterOptionalTypeScoringFeeParameters.check_lower(value.scoring_fee_params) + _UniffiConverterOptionalTypeScoringDecayParameters.check_lower(value.scoring_decay_params) _UniffiConverterBool.check_lower(value.include_untrusted_pending_in_spendable) _UniffiConverterTypeAddressType.check_lower(value.address_type) _UniffiConverterSequenceTypeAddressType.check_lower(value.address_types_to_monitor) @@ -8187,6 +8247,8 @@ def write(value, buf): _UniffiConverterUInt64.write(value.probing_liquidity_limit_multiplier, buf) _UniffiConverterOptionalTypeAnchorChannelsConfig.write(value.anchor_channels_config, buf) _UniffiConverterOptionalTypeRouteParametersConfig.write(value.route_parameters, buf) + _UniffiConverterOptionalTypeScoringFeeParameters.write(value.scoring_fee_params, buf) + _UniffiConverterOptionalTypeScoringDecayParameters.write(value.scoring_decay_params, buf) _UniffiConverterBool.write(value.include_untrusted_pending_in_spendable, buf) _UniffiConverterTypeAddressType.write(value.address_type, buf) _UniffiConverterSequenceTypeAddressType.write(value.address_types_to_monitor, buf) @@ -9320,6 +9382,134 @@ def write(value, buf): _UniffiConverterUInt64.write(value.fee_rate_cache_update_interval_secs, buf) +class ScoringDecayParameters: + historical_no_updates_half_life_secs: "int" + liquidity_offset_half_life_secs: "int" + def __init__(self, *, historical_no_updates_half_life_secs: "int", liquidity_offset_half_life_secs: "int"): + self.historical_no_updates_half_life_secs = historical_no_updates_half_life_secs + self.liquidity_offset_half_life_secs = liquidity_offset_half_life_secs + + def __str__(self): + return "ScoringDecayParameters(historical_no_updates_half_life_secs={}, liquidity_offset_half_life_secs={})".format(self.historical_no_updates_half_life_secs, self.liquidity_offset_half_life_secs) + + def __eq__(self, other): + if self.historical_no_updates_half_life_secs != other.historical_no_updates_half_life_secs: + return False + if self.liquidity_offset_half_life_secs != other.liquidity_offset_half_life_secs: + return False + return True + +class _UniffiConverterTypeScoringDecayParameters(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ScoringDecayParameters( + historical_no_updates_half_life_secs=_UniffiConverterUInt64.read(buf), + liquidity_offset_half_life_secs=_UniffiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterUInt64.check_lower(value.historical_no_updates_half_life_secs) + _UniffiConverterUInt64.check_lower(value.liquidity_offset_half_life_secs) + + @staticmethod + def write(value, buf): + _UniffiConverterUInt64.write(value.historical_no_updates_half_life_secs, buf) + _UniffiConverterUInt64.write(value.liquidity_offset_half_life_secs, buf) + + +class ScoringFeeParameters: + base_penalty_msat: "int" + base_penalty_amount_multiplier_msat: "int" + liquidity_penalty_multiplier_msat: "int" + liquidity_penalty_amount_multiplier_msat: "int" + historical_liquidity_penalty_multiplier_msat: "int" + historical_liquidity_penalty_amount_multiplier_msat: "int" + anti_probing_penalty_msat: "int" + considered_impossible_penalty_msat: "int" + linear_success_probability: "bool" + probing_diversity_penalty_msat: "int" + def __init__(self, *, base_penalty_msat: "int", base_penalty_amount_multiplier_msat: "int", liquidity_penalty_multiplier_msat: "int", liquidity_penalty_amount_multiplier_msat: "int", historical_liquidity_penalty_multiplier_msat: "int", historical_liquidity_penalty_amount_multiplier_msat: "int", anti_probing_penalty_msat: "int", considered_impossible_penalty_msat: "int", linear_success_probability: "bool", probing_diversity_penalty_msat: "int"): + self.base_penalty_msat = base_penalty_msat + self.base_penalty_amount_multiplier_msat = base_penalty_amount_multiplier_msat + self.liquidity_penalty_multiplier_msat = liquidity_penalty_multiplier_msat + self.liquidity_penalty_amount_multiplier_msat = liquidity_penalty_amount_multiplier_msat + self.historical_liquidity_penalty_multiplier_msat = historical_liquidity_penalty_multiplier_msat + self.historical_liquidity_penalty_amount_multiplier_msat = historical_liquidity_penalty_amount_multiplier_msat + self.anti_probing_penalty_msat = anti_probing_penalty_msat + self.considered_impossible_penalty_msat = considered_impossible_penalty_msat + self.linear_success_probability = linear_success_probability + self.probing_diversity_penalty_msat = probing_diversity_penalty_msat + + def __str__(self): + return "ScoringFeeParameters(base_penalty_msat={}, base_penalty_amount_multiplier_msat={}, liquidity_penalty_multiplier_msat={}, liquidity_penalty_amount_multiplier_msat={}, historical_liquidity_penalty_multiplier_msat={}, historical_liquidity_penalty_amount_multiplier_msat={}, anti_probing_penalty_msat={}, considered_impossible_penalty_msat={}, linear_success_probability={}, probing_diversity_penalty_msat={})".format(self.base_penalty_msat, self.base_penalty_amount_multiplier_msat, self.liquidity_penalty_multiplier_msat, self.liquidity_penalty_amount_multiplier_msat, self.historical_liquidity_penalty_multiplier_msat, self.historical_liquidity_penalty_amount_multiplier_msat, self.anti_probing_penalty_msat, self.considered_impossible_penalty_msat, self.linear_success_probability, self.probing_diversity_penalty_msat) + + def __eq__(self, other): + if self.base_penalty_msat != other.base_penalty_msat: + return False + if self.base_penalty_amount_multiplier_msat != other.base_penalty_amount_multiplier_msat: + return False + if self.liquidity_penalty_multiplier_msat != other.liquidity_penalty_multiplier_msat: + return False + if self.liquidity_penalty_amount_multiplier_msat != other.liquidity_penalty_amount_multiplier_msat: + return False + if self.historical_liquidity_penalty_multiplier_msat != other.historical_liquidity_penalty_multiplier_msat: + return False + if self.historical_liquidity_penalty_amount_multiplier_msat != other.historical_liquidity_penalty_amount_multiplier_msat: + return False + if self.anti_probing_penalty_msat != other.anti_probing_penalty_msat: + return False + if self.considered_impossible_penalty_msat != other.considered_impossible_penalty_msat: + return False + if self.linear_success_probability != other.linear_success_probability: + return False + if self.probing_diversity_penalty_msat != other.probing_diversity_penalty_msat: + return False + return True + +class _UniffiConverterTypeScoringFeeParameters(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ScoringFeeParameters( + base_penalty_msat=_UniffiConverterUInt64.read(buf), + base_penalty_amount_multiplier_msat=_UniffiConverterUInt64.read(buf), + liquidity_penalty_multiplier_msat=_UniffiConverterUInt64.read(buf), + liquidity_penalty_amount_multiplier_msat=_UniffiConverterUInt64.read(buf), + historical_liquidity_penalty_multiplier_msat=_UniffiConverterUInt64.read(buf), + historical_liquidity_penalty_amount_multiplier_msat=_UniffiConverterUInt64.read(buf), + anti_probing_penalty_msat=_UniffiConverterUInt64.read(buf), + considered_impossible_penalty_msat=_UniffiConverterUInt64.read(buf), + linear_success_probability=_UniffiConverterBool.read(buf), + probing_diversity_penalty_msat=_UniffiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiConverterUInt64.check_lower(value.base_penalty_msat) + _UniffiConverterUInt64.check_lower(value.base_penalty_amount_multiplier_msat) + _UniffiConverterUInt64.check_lower(value.liquidity_penalty_multiplier_msat) + _UniffiConverterUInt64.check_lower(value.liquidity_penalty_amount_multiplier_msat) + _UniffiConverterUInt64.check_lower(value.historical_liquidity_penalty_multiplier_msat) + _UniffiConverterUInt64.check_lower(value.historical_liquidity_penalty_amount_multiplier_msat) + _UniffiConverterUInt64.check_lower(value.anti_probing_penalty_msat) + _UniffiConverterUInt64.check_lower(value.considered_impossible_penalty_msat) + _UniffiConverterBool.check_lower(value.linear_success_probability) + _UniffiConverterUInt64.check_lower(value.probing_diversity_penalty_msat) + + @staticmethod + def write(value, buf): + _UniffiConverterUInt64.write(value.base_penalty_msat, buf) + _UniffiConverterUInt64.write(value.base_penalty_amount_multiplier_msat, buf) + _UniffiConverterUInt64.write(value.liquidity_penalty_multiplier_msat, buf) + _UniffiConverterUInt64.write(value.liquidity_penalty_amount_multiplier_msat, buf) + _UniffiConverterUInt64.write(value.historical_liquidity_penalty_multiplier_msat, buf) + _UniffiConverterUInt64.write(value.historical_liquidity_penalty_amount_multiplier_msat, buf) + _UniffiConverterUInt64.write(value.anti_probing_penalty_msat, buf) + _UniffiConverterUInt64.write(value.considered_impossible_penalty_msat, buf) + _UniffiConverterBool.write(value.linear_success_probability, buf) + _UniffiConverterUInt64.write(value.probing_diversity_penalty_msat, buf) + + class SpendableUtxo: outpoint: "OutPoint" value_sats: "int" @@ -14847,6 +15037,60 @@ def read(cls, buf): +class _UniffiConverterOptionalTypeScoringDecayParameters(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterTypeScoringDecayParameters.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterTypeScoringDecayParameters.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterTypeScoringDecayParameters.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + +class _UniffiConverterOptionalTypeScoringFeeParameters(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiConverterTypeScoringFeeParameters.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiConverterTypeScoringFeeParameters.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiConverterTypeScoringFeeParameters.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + class _UniffiConverterOptionalTypeTransactionDetails(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -16613,6 +16857,8 @@ def generate_entropy_mnemonic(word_count: "typing.Optional[WordCount]") -> "Mnem "RouteParametersConfig", "RoutingFees", "RuntimeSyncIntervals", + "ScoringDecayParameters", + "ScoringFeeParameters", "SpendableUtxo", "TransactionDetails", "TxInput", diff --git a/bindings/swift/Sources/LDKNode/LDKNode.swift b/bindings/swift/Sources/LDKNode/LDKNode.swift index 12dc76ce2..7f25c5bd7 100644 --- a/bindings/swift/Sources/LDKNode/LDKNode.swift +++ b/bindings/swift/Sources/LDKNode/LDKNode.swift @@ -1615,6 +1615,10 @@ public protocol BuilderProtocol: AnyObject { func setPathfindingScoresSource(url: String) + func setScoringDecayParams(params: ScoringDecayParameters) + + func setScoringFeeParams(params: ScoringFeeParameters) + func setStorageDirPath(storageDirPath: String) } @@ -1903,6 +1907,20 @@ open class Builder: } } + open func setScoringDecayParams(params: ScoringDecayParameters) { + try! rustCall { + uniffi_ldk_node_fn_method_builder_set_scoring_decay_params(self.uniffiClonePointer(), + FfiConverterTypeScoringDecayParameters.lower(params), $0) + } + } + + open func setScoringFeeParams(params: ScoringFeeParameters) { + try! rustCall { + uniffi_ldk_node_fn_method_builder_set_scoring_fee_params(self.uniffiClonePointer(), + FfiConverterTypeScoringFeeParameters.lower(params), $0) + } + } + open func setStorageDirPath(storageDirPath: String) { try! rustCall { uniffi_ldk_node_fn_method_builder_set_storage_dir_path(self.uniffiClonePointer(), @@ -5107,13 +5125,15 @@ public struct Config { public var probingLiquidityLimitMultiplier: UInt64 public var anchorChannelsConfig: AnchorChannelsConfig? public var routeParameters: RouteParametersConfig? + public var scoringFeeParams: ScoringFeeParameters? + public var scoringDecayParams: ScoringDecayParameters? public var includeUntrustedPendingInSpendable: Bool public var addressType: AddressType public var addressTypesToMonitor: [AddressType] /// Default memberwise initializers are never public by default, so we /// declare one manually. - public init(storageDirPath: String, network: Network, listeningAddresses: [SocketAddress]?, announcementAddresses: [SocketAddress]?, nodeAlias: NodeAlias?, trustedPeers0conf: [PublicKey], probingLiquidityLimitMultiplier: UInt64, anchorChannelsConfig: AnchorChannelsConfig?, routeParameters: RouteParametersConfig?, includeUntrustedPendingInSpendable: Bool, addressType: AddressType, addressTypesToMonitor: [AddressType]) { + public init(storageDirPath: String, network: Network, listeningAddresses: [SocketAddress]?, announcementAddresses: [SocketAddress]?, nodeAlias: NodeAlias?, trustedPeers0conf: [PublicKey], probingLiquidityLimitMultiplier: UInt64, anchorChannelsConfig: AnchorChannelsConfig?, routeParameters: RouteParametersConfig?, scoringFeeParams: ScoringFeeParameters?, scoringDecayParams: ScoringDecayParameters?, includeUntrustedPendingInSpendable: Bool, addressType: AddressType, addressTypesToMonitor: [AddressType]) { self.storageDirPath = storageDirPath self.network = network self.listeningAddresses = listeningAddresses @@ -5123,6 +5143,8 @@ public struct Config { self.probingLiquidityLimitMultiplier = probingLiquidityLimitMultiplier self.anchorChannelsConfig = anchorChannelsConfig self.routeParameters = routeParameters + self.scoringFeeParams = scoringFeeParams + self.scoringDecayParams = scoringDecayParams self.includeUntrustedPendingInSpendable = includeUntrustedPendingInSpendable self.addressType = addressType self.addressTypesToMonitor = addressTypesToMonitor @@ -5158,6 +5180,12 @@ extension Config: Equatable, Hashable { if lhs.routeParameters != rhs.routeParameters { return false } + if lhs.scoringFeeParams != rhs.scoringFeeParams { + return false + } + if lhs.scoringDecayParams != rhs.scoringDecayParams { + return false + } if lhs.includeUntrustedPendingInSpendable != rhs.includeUntrustedPendingInSpendable { return false } @@ -5180,6 +5208,8 @@ extension Config: Equatable, Hashable { hasher.combine(probingLiquidityLimitMultiplier) hasher.combine(anchorChannelsConfig) hasher.combine(routeParameters) + hasher.combine(scoringFeeParams) + hasher.combine(scoringDecayParams) hasher.combine(includeUntrustedPendingInSpendable) hasher.combine(addressType) hasher.combine(addressTypesToMonitor) @@ -5202,6 +5232,8 @@ public struct FfiConverterTypeConfig: FfiConverterRustBuffer { probingLiquidityLimitMultiplier: FfiConverterUInt64.read(from: &buf), anchorChannelsConfig: FfiConverterOptionTypeAnchorChannelsConfig.read(from: &buf), routeParameters: FfiConverterOptionTypeRouteParametersConfig.read(from: &buf), + scoringFeeParams: FfiConverterOptionTypeScoringFeeParameters.read(from: &buf), + scoringDecayParams: FfiConverterOptionTypeScoringDecayParameters.read(from: &buf), includeUntrustedPendingInSpendable: FfiConverterBool.read(from: &buf), addressType: FfiConverterTypeAddressType.read(from: &buf), addressTypesToMonitor: FfiConverterSequenceTypeAddressType.read(from: &buf) @@ -5218,6 +5250,8 @@ public struct FfiConverterTypeConfig: FfiConverterRustBuffer { FfiConverterUInt64.write(value.probingLiquidityLimitMultiplier, into: &buf) FfiConverterOptionTypeAnchorChannelsConfig.write(value.anchorChannelsConfig, into: &buf) FfiConverterOptionTypeRouteParametersConfig.write(value.routeParameters, into: &buf) + FfiConverterOptionTypeScoringFeeParameters.write(value.scoringFeeParams, into: &buf) + FfiConverterOptionTypeScoringDecayParameters.write(value.scoringDecayParams, into: &buf) FfiConverterBool.write(value.includeUntrustedPendingInSpendable, into: &buf) FfiConverterTypeAddressType.write(value.addressType, into: &buf) FfiConverterSequenceTypeAddressType.write(value.addressTypesToMonitor, into: &buf) @@ -6852,6 +6886,192 @@ public func FfiConverterTypeRuntimeSyncIntervals_lower(_ value: RuntimeSyncInter return FfiConverterTypeRuntimeSyncIntervals.lower(value) } +public struct ScoringDecayParameters { + public var historicalNoUpdatesHalfLifeSecs: UInt64 + public var liquidityOffsetHalfLifeSecs: UInt64 + + /// Default memberwise initializers are never public by default, so we + /// declare one manually. + public init(historicalNoUpdatesHalfLifeSecs: UInt64, liquidityOffsetHalfLifeSecs: UInt64) { + self.historicalNoUpdatesHalfLifeSecs = historicalNoUpdatesHalfLifeSecs + self.liquidityOffsetHalfLifeSecs = liquidityOffsetHalfLifeSecs + } +} + +extension ScoringDecayParameters: Equatable, Hashable { + public static func == (lhs: ScoringDecayParameters, rhs: ScoringDecayParameters) -> Bool { + if lhs.historicalNoUpdatesHalfLifeSecs != rhs.historicalNoUpdatesHalfLifeSecs { + return false + } + if lhs.liquidityOffsetHalfLifeSecs != rhs.liquidityOffsetHalfLifeSecs { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(historicalNoUpdatesHalfLifeSecs) + hasher.combine(liquidityOffsetHalfLifeSecs) + } +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +public struct FfiConverterTypeScoringDecayParameters: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ScoringDecayParameters { + return + try ScoringDecayParameters( + historicalNoUpdatesHalfLifeSecs: FfiConverterUInt64.read(from: &buf), + liquidityOffsetHalfLifeSecs: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: ScoringDecayParameters, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.historicalNoUpdatesHalfLifeSecs, into: &buf) + FfiConverterUInt64.write(value.liquidityOffsetHalfLifeSecs, into: &buf) + } +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +public func FfiConverterTypeScoringDecayParameters_lift(_ buf: RustBuffer) throws -> ScoringDecayParameters { + return try FfiConverterTypeScoringDecayParameters.lift(buf) +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +public func FfiConverterTypeScoringDecayParameters_lower(_ value: ScoringDecayParameters) -> RustBuffer { + return FfiConverterTypeScoringDecayParameters.lower(value) +} + +public struct ScoringFeeParameters { + public var basePenaltyMsat: UInt64 + public var basePenaltyAmountMultiplierMsat: UInt64 + public var liquidityPenaltyMultiplierMsat: UInt64 + public var liquidityPenaltyAmountMultiplierMsat: UInt64 + public var historicalLiquidityPenaltyMultiplierMsat: UInt64 + public var historicalLiquidityPenaltyAmountMultiplierMsat: UInt64 + public var antiProbingPenaltyMsat: UInt64 + public var consideredImpossiblePenaltyMsat: UInt64 + public var linearSuccessProbability: Bool + public var probingDiversityPenaltyMsat: UInt64 + + /// Default memberwise initializers are never public by default, so we + /// declare one manually. + public init(basePenaltyMsat: UInt64, basePenaltyAmountMultiplierMsat: UInt64, liquidityPenaltyMultiplierMsat: UInt64, liquidityPenaltyAmountMultiplierMsat: UInt64, historicalLiquidityPenaltyMultiplierMsat: UInt64, historicalLiquidityPenaltyAmountMultiplierMsat: UInt64, antiProbingPenaltyMsat: UInt64, consideredImpossiblePenaltyMsat: UInt64, linearSuccessProbability: Bool, probingDiversityPenaltyMsat: UInt64) { + self.basePenaltyMsat = basePenaltyMsat + self.basePenaltyAmountMultiplierMsat = basePenaltyAmountMultiplierMsat + self.liquidityPenaltyMultiplierMsat = liquidityPenaltyMultiplierMsat + self.liquidityPenaltyAmountMultiplierMsat = liquidityPenaltyAmountMultiplierMsat + self.historicalLiquidityPenaltyMultiplierMsat = historicalLiquidityPenaltyMultiplierMsat + self.historicalLiquidityPenaltyAmountMultiplierMsat = historicalLiquidityPenaltyAmountMultiplierMsat + self.antiProbingPenaltyMsat = antiProbingPenaltyMsat + self.consideredImpossiblePenaltyMsat = consideredImpossiblePenaltyMsat + self.linearSuccessProbability = linearSuccessProbability + self.probingDiversityPenaltyMsat = probingDiversityPenaltyMsat + } +} + +extension ScoringFeeParameters: Equatable, Hashable { + public static func == (lhs: ScoringFeeParameters, rhs: ScoringFeeParameters) -> Bool { + if lhs.basePenaltyMsat != rhs.basePenaltyMsat { + return false + } + if lhs.basePenaltyAmountMultiplierMsat != rhs.basePenaltyAmountMultiplierMsat { + return false + } + if lhs.liquidityPenaltyMultiplierMsat != rhs.liquidityPenaltyMultiplierMsat { + return false + } + if lhs.liquidityPenaltyAmountMultiplierMsat != rhs.liquidityPenaltyAmountMultiplierMsat { + return false + } + if lhs.historicalLiquidityPenaltyMultiplierMsat != rhs.historicalLiquidityPenaltyMultiplierMsat { + return false + } + if lhs.historicalLiquidityPenaltyAmountMultiplierMsat != rhs.historicalLiquidityPenaltyAmountMultiplierMsat { + return false + } + if lhs.antiProbingPenaltyMsat != rhs.antiProbingPenaltyMsat { + return false + } + if lhs.consideredImpossiblePenaltyMsat != rhs.consideredImpossiblePenaltyMsat { + return false + } + if lhs.linearSuccessProbability != rhs.linearSuccessProbability { + return false + } + if lhs.probingDiversityPenaltyMsat != rhs.probingDiversityPenaltyMsat { + return false + } + return true + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(basePenaltyMsat) + hasher.combine(basePenaltyAmountMultiplierMsat) + hasher.combine(liquidityPenaltyMultiplierMsat) + hasher.combine(liquidityPenaltyAmountMultiplierMsat) + hasher.combine(historicalLiquidityPenaltyMultiplierMsat) + hasher.combine(historicalLiquidityPenaltyAmountMultiplierMsat) + hasher.combine(antiProbingPenaltyMsat) + hasher.combine(consideredImpossiblePenaltyMsat) + hasher.combine(linearSuccessProbability) + hasher.combine(probingDiversityPenaltyMsat) + } +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +public struct FfiConverterTypeScoringFeeParameters: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ScoringFeeParameters { + return + try ScoringFeeParameters( + basePenaltyMsat: FfiConverterUInt64.read(from: &buf), + basePenaltyAmountMultiplierMsat: FfiConverterUInt64.read(from: &buf), + liquidityPenaltyMultiplierMsat: FfiConverterUInt64.read(from: &buf), + liquidityPenaltyAmountMultiplierMsat: FfiConverterUInt64.read(from: &buf), + historicalLiquidityPenaltyMultiplierMsat: FfiConverterUInt64.read(from: &buf), + historicalLiquidityPenaltyAmountMultiplierMsat: FfiConverterUInt64.read(from: &buf), + antiProbingPenaltyMsat: FfiConverterUInt64.read(from: &buf), + consideredImpossiblePenaltyMsat: FfiConverterUInt64.read(from: &buf), + linearSuccessProbability: FfiConverterBool.read(from: &buf), + probingDiversityPenaltyMsat: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: ScoringFeeParameters, into buf: inout [UInt8]) { + FfiConverterUInt64.write(value.basePenaltyMsat, into: &buf) + FfiConverterUInt64.write(value.basePenaltyAmountMultiplierMsat, into: &buf) + FfiConverterUInt64.write(value.liquidityPenaltyMultiplierMsat, into: &buf) + FfiConverterUInt64.write(value.liquidityPenaltyAmountMultiplierMsat, into: &buf) + FfiConverterUInt64.write(value.historicalLiquidityPenaltyMultiplierMsat, into: &buf) + FfiConverterUInt64.write(value.historicalLiquidityPenaltyAmountMultiplierMsat, into: &buf) + FfiConverterUInt64.write(value.antiProbingPenaltyMsat, into: &buf) + FfiConverterUInt64.write(value.consideredImpossiblePenaltyMsat, into: &buf) + FfiConverterBool.write(value.linearSuccessProbability, into: &buf) + FfiConverterUInt64.write(value.probingDiversityPenaltyMsat, into: &buf) + } +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +public func FfiConverterTypeScoringFeeParameters_lift(_ buf: RustBuffer) throws -> ScoringFeeParameters { + return try FfiConverterTypeScoringFeeParameters.lift(buf) +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +public func FfiConverterTypeScoringFeeParameters_lower(_ value: ScoringFeeParameters) -> RustBuffer { + return FfiConverterTypeScoringFeeParameters.lower(value) +} + public struct SpendableUtxo { public var outpoint: OutPoint public var valueSats: UInt64 @@ -10212,6 +10432,54 @@ private struct FfiConverterOptionTypeRouteParametersConfig: FfiConverterRustBuff } } +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +private struct FfiConverterOptionTypeScoringDecayParameters: FfiConverterRustBuffer { + typealias SwiftType = ScoringDecayParameters? + + static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeScoringDecayParameters.write(value, into: &buf) + } + + static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeScoringDecayParameters.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif +private struct FfiConverterOptionTypeScoringFeeParameters: FfiConverterRustBuffer { + typealias SwiftType = ScoringFeeParameters? + + static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeScoringFeeParameters.write(value, into: &buf) + } + + static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeScoringFeeParameters.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -12452,6 +12720,12 @@ private var initializationResult: InitializationResult = { if uniffi_ldk_node_checksum_method_builder_set_pathfinding_scores_source() != 63501 { return InitializationResult.apiChecksumMismatch } + if uniffi_ldk_node_checksum_method_builder_set_scoring_decay_params() != 19869 { + return InitializationResult.apiChecksumMismatch + } + if uniffi_ldk_node_checksum_method_builder_set_scoring_fee_params() != 11588 { + return InitializationResult.apiChecksumMismatch + } if uniffi_ldk_node_checksum_method_builder_set_storage_dir_path() != 59019 { return InitializationResult.apiChecksumMismatch } diff --git a/src/builder.rs b/src/builder.rs index 00269e04b..9a517bd1e 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -51,8 +51,8 @@ use crate::chain::ChainSource; use crate::config::{ default_user_config, may_announce_channel, AddressType, AddressTypeRuntimeConfig, AnnounceError, AsyncPaymentsRole, BitcoindRestClientConfig, Config, ElectrumSyncConfig, - EsploraSyncConfig, RuntimeSyncIntervals, DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, - DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN, + EsploraSyncConfig, RuntimeSyncIntervals, ScoringDecayParameters, ScoringFeeParameters, + DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN, }; use crate::connection::ConnectionManager; use crate::event::EventQueue; @@ -496,6 +496,18 @@ impl NodeBuilder { self } + /// Sets scorer fee parameters used for pathfinding penalties. + pub fn set_scoring_fee_params(&mut self, params: ScoringFeeParameters) -> &mut Self { + self.config.scoring_fee_params = Some(params); + self + } + + /// Sets scorer decay parameters used for liquidity estimate decay. + pub fn set_scoring_decay_params(&mut self, params: ScoringDecayParameters) -> &mut Self { + self.config.scoring_decay_params = Some(params); + self + } + /// Configures the [`Node`] instance to source inbound liquidity from the given /// [bLIP-51 / LSPS1] service. /// @@ -1050,6 +1062,16 @@ impl ArcedNodeBuilder { self.inner.write().unwrap().set_pathfinding_scores_source(url); } + /// Sets scorer fee parameters used for pathfinding penalties. + pub fn set_scoring_fee_params(&self, params: ScoringFeeParameters) { + self.inner.write().unwrap().set_scoring_fee_params(params); + } + + /// Sets scorer decay parameters used for liquidity estimate decay. + pub fn set_scoring_decay_params(&self, params: ScoringDecayParameters) { + self.inner.write().unwrap().set_scoring_decay_params(params); + } + /// Configures the [`Node`] instance to source inbound liquidity from the given /// [bLIP-51 / LSPS1] service. /// @@ -1910,11 +1932,15 @@ fn build_with_store_internal( )); // Deserialize scorer + let scoring_decay_params = config + .scoring_decay_params + .clone() + .map(ProbabilisticScoringDecayParameters::from) + .unwrap_or_else(ProbabilisticScoringDecayParameters::default); let local_scorer = match scorer_data_res { Ok(data) => { - let params = ProbabilisticScoringDecayParameters::default(); let mut reader = Cursor::new(data); - let args = (params, Arc::clone(&network_graph), Arc::clone(&logger)); + let args = (scoring_decay_params, Arc::clone(&network_graph), Arc::clone(&logger)); match ProbabilisticScorer::read(&mut reader, args) { Ok(scorer) => scorer, Err(e) => { @@ -1924,8 +1950,11 @@ fn build_with_store_internal( } }, Err(e) if e.kind() == lightning::io::ErrorKind::NotFound => { - let params = ProbabilisticScoringDecayParameters::default(); - ProbabilisticScorer::new(params, Arc::clone(&network_graph), Arc::clone(&logger)) + ProbabilisticScorer::new( + scoring_decay_params, + Arc::clone(&network_graph), + Arc::clone(&logger), + ) }, Err(e) => { log_error!(logger, "Failed to read scoring data from store: {}", e); @@ -1957,7 +1986,11 @@ fn build_with_store_internal( }, } - let scoring_fee_params = ProbabilisticScoringFeeParameters::default(); + let scoring_fee_params = config + .scoring_fee_params + .clone() + .map(ProbabilisticScoringFeeParameters::from) + .unwrap_or_else(ProbabilisticScoringFeeParameters::default); let router = Arc::new(DefaultRouter::new( Arc::clone(&network_graph), Arc::clone(&logger), @@ -2521,7 +2554,8 @@ mod tests { use lightning::util::ser::Writeable; use super::{ - apply_channel_data_migration, sanitize_alias, BuildError, ChannelDataMigration, NodeAlias, + apply_channel_data_migration, sanitize_alias, BuildError, ChannelDataMigration, Config, + NodeAlias, NodeBuilder, ScoringDecayParameters, ScoringFeeParameters, }; use crate::io::test_utils::InMemoryStore; use crate::logger::Logger; @@ -2564,6 +2598,48 @@ mod tests { assert_eq!(node.err().unwrap(), BuildError::InvalidNodeAlias); } + #[test] + fn set_scoring_params_updates_builder_config() { + let mut builder = NodeBuilder::from_config(Config::default()); + let fee_params = ScoringFeeParameters { + base_penalty_msat: 2_000, + base_penalty_amount_multiplier_msat: 200_000, + liquidity_penalty_multiplier_msat: 1, + liquidity_penalty_amount_multiplier_msat: 2, + historical_liquidity_penalty_multiplier_msat: 20_000, + historical_liquidity_penalty_amount_multiplier_msat: 2_500, + anti_probing_penalty_msat: 500, + considered_impossible_penalty_msat: 999_999, + linear_success_probability: true, + probing_diversity_penalty_msat: 321, + }; + let decay_params = ScoringDecayParameters { + historical_no_updates_half_life_secs: 1_234, + liquidity_offset_half_life_secs: 567, + }; + + builder.set_scoring_fee_params(fee_params.clone()); + builder.set_scoring_decay_params(decay_params.clone()); + + assert_eq!( + builder.config.scoring_fee_params.as_ref().unwrap().base_penalty_msat, + fee_params.base_penalty_msat + ); + assert_eq!( + builder.config.scoring_fee_params.as_ref().unwrap().linear_success_probability, + fee_params.linear_success_probability + ); + assert_eq!( + builder + .config + .scoring_decay_params + .as_ref() + .unwrap() + .historical_no_updates_half_life_secs, + decay_params.historical_no_updates_half_life_secs + ); + } + /// Creates valid serialized (BlockHash, ChannelMonitor) bytes for testing. /// /// Uses LDK's functional test utilities to create a real channel between two diff --git a/src/config.rs b/src/config.rs index 0df143a40..e2fa1aa66 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,6 +14,9 @@ use bitcoin::secp256k1::PublicKey; use bitcoin::Network; use lightning::ln::msgs::SocketAddress; use lightning::routing::gossip::NodeAlias; +use lightning::routing::scoring::{ + ProbabilisticScoringDecayParameters, ProbabilisticScoringFeeParameters, +}; use lightning::routing::router::RouteParametersConfig; use lightning::util::config::{ ChannelConfig as LdkChannelConfig, MaxDustHTLCExposure as LdkMaxDustHTLCExposure, UserConfig, @@ -291,6 +294,14 @@ pub struct Config { /// **Note:** If unset, default parameters will be used, and you will be able to override the /// parameters on a per-payment basis in the corresponding method calls. pub route_parameters: Option, + /// Optional parameters for configuring routing scorer fee penalties. + /// + /// If unset, defaults from [`ProbabilisticScoringFeeParameters::default`] are used. + pub scoring_fee_params: Option, + /// Optional parameters for configuring routing scorer decay behavior. + /// + /// If unset, defaults from [`ProbabilisticScoringDecayParameters::default`] are used. + pub scoring_decay_params: Option, /// Whether to include unconfirmed funds from external sources in spendable balance. /// /// If `true`, [`BalanceDetails::spendable_onchain_balance_sats`] will include @@ -321,6 +332,8 @@ impl Default for Config { probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER, anchor_channels_config: Some(AnchorChannelsConfig::default()), route_parameters: None, + scoring_fee_params: None, + scoring_decay_params: None, node_alias: None, include_untrusted_pending_in_spendable: false, address_type: AddressType::default(), @@ -329,6 +342,113 @@ impl Default for Config { } } +/// Configuration options for [`ProbabilisticScoringFeeParameters`]. +#[derive(Debug, Clone)] +pub struct ScoringFeeParameters { + /// See [`ProbabilisticScoringFeeParameters::base_penalty_msat`]. + pub base_penalty_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::base_penalty_amount_multiplier_msat`]. + pub base_penalty_amount_multiplier_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::liquidity_penalty_multiplier_msat`]. + pub liquidity_penalty_multiplier_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::liquidity_penalty_amount_multiplier_msat`]. + pub liquidity_penalty_amount_multiplier_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::historical_liquidity_penalty_multiplier_msat`]. + pub historical_liquidity_penalty_multiplier_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::historical_liquidity_penalty_amount_multiplier_msat`]. + pub historical_liquidity_penalty_amount_multiplier_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::anti_probing_penalty_msat`]. + pub anti_probing_penalty_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::considered_impossible_penalty_msat`]. + pub considered_impossible_penalty_msat: u64, + /// See [`ProbabilisticScoringFeeParameters::linear_success_probability`]. + pub linear_success_probability: bool, + /// See [`ProbabilisticScoringFeeParameters::probing_diversity_penalty_msat`]. + pub probing_diversity_penalty_msat: u64, +} + +impl Default for ScoringFeeParameters { + fn default() -> Self { + let params = ProbabilisticScoringFeeParameters::default(); + Self::from(params) + } +} + +impl From for ScoringFeeParameters { + fn from(value: ProbabilisticScoringFeeParameters) -> Self { + Self { + base_penalty_msat: value.base_penalty_msat, + base_penalty_amount_multiplier_msat: value.base_penalty_amount_multiplier_msat, + liquidity_penalty_multiplier_msat: value.liquidity_penalty_multiplier_msat, + liquidity_penalty_amount_multiplier_msat: value.liquidity_penalty_amount_multiplier_msat, + historical_liquidity_penalty_multiplier_msat: value + .historical_liquidity_penalty_multiplier_msat, + historical_liquidity_penalty_amount_multiplier_msat: value + .historical_liquidity_penalty_amount_multiplier_msat, + anti_probing_penalty_msat: value.anti_probing_penalty_msat, + considered_impossible_penalty_msat: value.considered_impossible_penalty_msat, + linear_success_probability: value.linear_success_probability, + probing_diversity_penalty_msat: value.probing_diversity_penalty_msat, + } + } +} + +impl From for ProbabilisticScoringFeeParameters { + fn from(value: ScoringFeeParameters) -> Self { + let mut params = ProbabilisticScoringFeeParameters::default(); + params.base_penalty_msat = value.base_penalty_msat; + params.base_penalty_amount_multiplier_msat = value.base_penalty_amount_multiplier_msat; + params.liquidity_penalty_multiplier_msat = value.liquidity_penalty_multiplier_msat; + params.liquidity_penalty_amount_multiplier_msat = + value.liquidity_penalty_amount_multiplier_msat; + params.historical_liquidity_penalty_multiplier_msat = + value.historical_liquidity_penalty_multiplier_msat; + params.historical_liquidity_penalty_amount_multiplier_msat = + value.historical_liquidity_penalty_amount_multiplier_msat; + params.anti_probing_penalty_msat = value.anti_probing_penalty_msat; + params.considered_impossible_penalty_msat = value.considered_impossible_penalty_msat; + params.linear_success_probability = value.linear_success_probability; + params.probing_diversity_penalty_msat = value.probing_diversity_penalty_msat; + params + } +} + +/// Configuration options for [`ProbabilisticScoringDecayParameters`]. +#[derive(Debug, Clone)] +pub struct ScoringDecayParameters { + /// See [`ProbabilisticScoringDecayParameters::historical_no_updates_half_life`]. + pub historical_no_updates_half_life_secs: u64, + /// See [`ProbabilisticScoringDecayParameters::liquidity_offset_half_life`]. + pub liquidity_offset_half_life_secs: u64, +} + +impl Default for ScoringDecayParameters { + fn default() -> Self { + let params = ProbabilisticScoringDecayParameters::default(); + Self::from(params) + } +} + +impl From for ScoringDecayParameters { + fn from(value: ProbabilisticScoringDecayParameters) -> Self { + Self { + historical_no_updates_half_life_secs: value.historical_no_updates_half_life.as_secs(), + liquidity_offset_half_life_secs: value.liquidity_offset_half_life.as_secs(), + } + } +} + +impl From for ProbabilisticScoringDecayParameters { + fn from(value: ScoringDecayParameters) -> Self { + Self { + historical_no_updates_half_life: Duration::from_secs( + value.historical_no_updates_half_life_secs, + ), + liquidity_offset_half_life: Duration::from_secs(value.liquidity_offset_half_life_secs), + } + } +} + /// Configuration options pertaining to 'Anchor' channels, i.e., channels for which the /// `option_anchors_zero_fee_htlc_tx` channel type is negotiated. /// diff --git a/src/ffi/types.rs b/src/ffi/types.rs index 020f5bd22..2129b0594 100644 --- a/src/ffi/types.rs +++ b/src/ffi/types.rs @@ -47,7 +47,7 @@ use crate::builder::sanitize_alias; pub use crate::config::{ battery_saving_sync_intervals, default_config, AddressType, AnchorChannelsConfig, BackgroundSyncConfig, ElectrumSyncConfig, EsploraSyncConfig, MaxDustHTLCExposure, - RuntimeSyncIntervals, + RuntimeSyncIntervals, ScoringDecayParameters, ScoringFeeParameters, }; use crate::error::Error; pub use crate::graph::{ChannelInfo, ChannelUpdateInfo, NodeAnnouncementInfo, NodeInfo};