diff --git a/ci/LDKSwift/Tests/LDKSwiftTests/HumanObjectPeerTestInstance.swift b/ci/LDKSwift/Tests/LDKSwiftTests/HumanObjectPeerTestInstance.swift index 36a18e14..ede630f6 100644 --- a/ci/LDKSwift/Tests/LDKSwiftTests/HumanObjectPeerTestInstance.swift +++ b/ci/LDKSwift/Tests/LDKSwiftTests/HumanObjectPeerTestInstance.swift @@ -676,6 +676,39 @@ public class HumanObjectPeerTestInstance { let recreatedInvoice = Bolt11Invoice.fromStr(s: invoice.toStr()) XCTAssertTrue(recreatedInvoice.isOk()) + + // find route + + do { + let payerPubkey = peer1.channelManager.getOurNodeId() + let payeePubkey = peer2.channelManager.getOurNodeId() + let paymentParameters = PaymentParameters.initForKeysend(payeePubkey: payeePubkey, finalCltvExpiryDelta: 3, allowMpp: false) + + let amount = invoice.amountMilliSatoshis()! + let routeParameters = RouteParameters(paymentParamsArg: paymentParameters, finalValueMsatArg: amount) + let randomSeedBytes: [UInt8] = [UInt8](repeating: 0, count: 32) + let scoringParams = ProbabilisticScoringDecayParameters.initWithDefault() + let networkGraph = peer1.constructor!.netGraph! + let scorer = ProbabilisticScorer(decayParams: scoringParams, networkGraph: networkGraph, logger: logger) + let score = scorer.asScore() + + let scoreParams = ProbabilisticScoringFeeParameters.initWithDefault() + + let foundRoute = Bindings.findRoute( + ourNodePubkey: payerPubkey, + routeParams: routeParameters, + networkGraph: networkGraph, + firstHops: usableChannelsA, + logger: logger, + scorer: score, + scoreParams: scoreParams, + randomSeedBytes: randomSeedBytes + ) + + let route = foundRoute.getValue()! + let fees = route.getTotalFees() + print("found route fees: \(fees)") + } let channelManagerConstructor = peer1.constructor! let invoicePaymentResult = Bindings.payInvoice(invoice: invoice, retryStrategy: Bindings.Retry.initWithAttempts(a: 3), channelmanager: channelManagerConstructor.channelManager) diff --git a/out/Bindings.swift b/out/Bindings.swift index 96ad6b88..eee5b577 100644 --- a/out/Bindings.swift +++ b/out/Bindings.swift @@ -1236,7 +1236,9 @@ public class Bindings { if let firstHops = firstHops { let firstHopsVector = Vec_ChannelDetailsZ( - array: firstHops, instantiationContext: "Bindings.swift::\(#function):\(#line)") + array: firstHops, instantiationContext: "Bindings.swift::\(#function):\(#line)" + ) + .dangle() firstHopsVectorPointer = UnsafeMutablePointer.allocate(capacity: 1) firstHopsVectorPointer!.initialize(to: firstHopsVector.cType!) diff --git a/out/traits/Router.swift b/out/traits/Router.swift index 1c733cc2..85c4b358 100644 --- a/out/traits/Router.swift +++ b/out/traits/Router.swift @@ -269,7 +269,9 @@ extension Bindings { if let firstHops = firstHops { let firstHopsVector = Vec_ChannelDetailsZ( - array: firstHops, instantiationContext: "Router.swift::\(#function):\(#line)") + array: firstHops, instantiationContext: "Router.swift::\(#function):\(#line)" + ) + .dangle() firstHopsVectorPointer = UnsafeMutablePointer.allocate(capacity: 1) firstHopsVectorPointer!.initialize(to: firstHopsVector.cType!) @@ -323,7 +325,9 @@ extension Bindings { if let firstHops = firstHops { let firstHopsVector = Vec_ChannelDetailsZ( - array: firstHops, instantiationContext: "Router.swift::\(#function):\(#line)") + array: firstHops, instantiationContext: "Router.swift::\(#function):\(#line)" + ) + .dangle() firstHopsVectorPointer = UnsafeMutablePointer.allocate(capacity: 1) firstHopsVectorPointer!.initialize(to: firstHopsVector.cType!) diff --git a/src/generation/base_type_generator.mts b/src/generation/base_type_generator.mts index ff655f3e..7a0de801 100644 --- a/src/generation/base_type_generator.mts +++ b/src/generation/base_type_generator.mts @@ -735,6 +735,13 @@ export abstract class BaseTypeGenerator { // memoryManagementInfix = '' // } } + } else if (argument.isAsteriskPointer && this.isPointerArgumentNullable(argument, containerType)) { + // if we're taking a nullable argument that needs to be passed to Rust as a nullable pointer, + // the initialization of the argument will occur inside an if let block, and the value + // to which the pointer will later refer must not get immediately cleaned up. + // It is not quite clear to me how to determine when to, eventually, clear that memory, + // which is why for the time being, this actually results in some additional direct leaks. + memoryManagementInfix = '.dangle()'; } } else if (argument.type instanceof RustPrimitiveWrapper && argument.type.isDeallocatable()) { // memoryManagementInfix = '.dangle()';