commonMain.fr.acinq.lightning.payment.RouteCalculation.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lightning-kmp Show documentation
Show all versions of lightning-kmp Show documentation
A Kotlin Multiplatform implementation of the Lightning Network
package fr.acinq.lightning.payment
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.bitcoin.Satoshi
import fr.acinq.lightning.MilliSatoshi
import fr.acinq.lightning.channel.states.ChannelState
import fr.acinq.lightning.channel.states.Normal
import fr.acinq.lightning.utils.Either
import fr.acinq.lightning.utils.MDCLogger
import fr.acinq.lightning.utils.UUID
import fr.acinq.lightning.utils.msat
import org.kodein.log.LoggerFactory
import org.kodein.log.newLogger
class RouteCalculation(loggerFactory: LoggerFactory) {
private val logger = loggerFactory.newLogger(this::class)
data class Route(val amount: MilliSatoshi, val channel: Normal)
fun findRoutes(paymentId: UUID, amount: MilliSatoshi, channels: Map): Either> {
val logger = MDCLogger(logger, staticMdc = mapOf("paymentId" to paymentId, "amount" to amount))
data class ChannelBalance(val c: Normal) {
val balance: MilliSatoshi = c.commitments.availableBalanceForSend()
val capacity: Satoshi = c.commitments.latest.fundingAmount
}
val sortedChannels = channels.values.filterIsInstance().map { ChannelBalance(it) }.sortedBy { it.balance }.reversed()
if (sortedChannels.isEmpty()) {
logger.warning { "no available channels" }
return Either.Left(FinalFailure.NoAvailableChannels)
}
val filteredChannels = sortedChannels.filter { it.balance >= it.c.channelUpdate.htlcMinimumMsat }
var remaining = amount
val routes = mutableListOf()
for (channel in filteredChannels) {
val toSend = channel.balance.min(remaining)
routes.add(Route(toSend, channel.c))
remaining -= toSend
if (remaining == 0.msat) {
break
}
}
return if (remaining > 0.msat) {
logger.info { "insufficient balance: ${sortedChannels.joinToString { "${it.c.shortChannelId}->${it.balance}/${it.capacity}" }}" }
Either.Left(FinalFailure.InsufficientBalance)
} else {
logger.info { "routes found: ${routes.map { "${it.channel.shortChannelId}->${it.amount}" }}" }
Either.Right(routes)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy