mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-24 14:50:46 +01:00
add node fees to htlc amounts
This commit is contained in:
parent
3146c2d68a
commit
293f1c930a
5 changed files with 43 additions and 5 deletions
|
@ -18,6 +18,8 @@ eclair {
|
||||||
}
|
}
|
||||||
commit-fee = 50000
|
commit-fee = 50000
|
||||||
closing-fee = 10000
|
closing-fee = 10000
|
||||||
|
base-fee = 546000
|
||||||
|
proportional-fee = 10
|
||||||
payment-handler = "local"
|
payment-handler = "local"
|
||||||
}
|
}
|
||||||
akka {
|
akka {
|
||||||
|
|
|
@ -29,7 +29,8 @@ object Globals {
|
||||||
val default_mindepth = 3
|
val default_mindepth = 3
|
||||||
val commit_fee = config.getInt("eclair.commit-fee")
|
val commit_fee = config.getInt("eclair.commit-fee")
|
||||||
val closing_fee = config.getInt("eclair.closing-fee")
|
val closing_fee = config.getInt("eclair.closing-fee")
|
||||||
|
val base_fee = config.getInt("eclair.base-fee")
|
||||||
|
val proportional_fee = config.getInt("eclair.proportional-fee")
|
||||||
val default_anchor_amount = 1000000
|
val default_anchor_amount = 1000000
|
||||||
|
|
||||||
//def newChannelParameters = OurChannelParams(default_locktime, commit_priv, final_priv, default_mindepth, commit_fee, "sha-seed".getBytes(), None)
|
//def newChannelParameters = OurChannelParams(default_locktime, commit_priv, final_priv, default_mindepth, commit_fee, "sha-seed".getBytes(), None)
|
||||||
|
|
|
@ -125,4 +125,13 @@ package object eclair {
|
||||||
def computeFee(feeRate: Long, numberOfHtlcs: Int): Long = {
|
def computeFee(feeRate: Long, numberOfHtlcs: Int): Long = {
|
||||||
Math.floorDiv((338 + 32 * numberOfHtlcs) * feeRate, 2000) * 2
|
Math.floorDiv((338 + 32 * numberOfHtlcs) * feeRate, 2000) * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param base fixed fee
|
||||||
|
* @param proportional proportional fee
|
||||||
|
* @param msat amount in millisatoshi
|
||||||
|
* @return the fee (in msat) that a node should be paid to forward an HTLC of 'amount' millisatoshis
|
||||||
|
*/
|
||||||
|
def nodeFee(base: Long, proportional: Long, msat: Long): Long = base + (proportional * msat) / 1000000
|
||||||
}
|
}
|
|
@ -77,10 +77,14 @@ class IRCRouter(bitcoinClient: ExtendedBitcoinClient) extends Actor with ActorLo
|
||||||
Boot.system.actorSelection(Register.actorPathToNodeId(next))
|
Boot.system.actorSelection(Register.actorPathToNodeId(next))
|
||||||
.resolveOne(2 seconds)
|
.resolveOne(2 seconds)
|
||||||
.map { channel =>
|
.map { channel =>
|
||||||
// TODO : no fees!
|
// build a route
|
||||||
val r = lightning.route(others.map(n => route_step(c.amountMsat, next = Next.Bitcoin(n))) :+ route_step(0, next = route_step.Next.End(true)))
|
val r = buildRoute(c.amountMsat, others)
|
||||||
|
|
||||||
|
// apply fee
|
||||||
|
val amountMsat = r.steps(0).amount
|
||||||
|
val fee = nodeFee(Globals.base_fee, Globals.proportional_fee, amountMsat).toInt
|
||||||
// TODO : expiry is not correctly calculated
|
// TODO : expiry is not correctly calculated
|
||||||
channel ! CMD_ADD_HTLC(c.amountMsat, c.h, locktime(Blocks(blockCount.toInt + 100 + r.steps.size - 1)), r, commit = true)
|
channel ! CMD_ADD_HTLC(amountMsat + fee, c.h, locktime(Blocks(blockCount.toInt + 100 + r.steps.size - 1)), r, commit = true)
|
||||||
s ! channel
|
s ! channel
|
||||||
}
|
}
|
||||||
}) onFailure {
|
}) onFailure {
|
||||||
|
@ -115,11 +119,23 @@ object IRCRouter {
|
||||||
}
|
}
|
||||||
case None => throw new RuntimeException("route not found")
|
case None => throw new RuntimeException("route not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def findRoute(myNodeId: BinaryData, targetNodeId: BinaryData, channels: Map[BinaryData, ChannelDesc])(implicit ec: ExecutionContext): Future[Seq[BinaryData]] = Future {
|
def findRoute(myNodeId: BinaryData, targetNodeId: BinaryData, channels: Map[BinaryData, ChannelDesc])(implicit ec: ExecutionContext): Future[Seq[BinaryData]] = Future {
|
||||||
findRouteDijkstra(myNodeId, targetNodeId, channels)
|
findRouteDijkstra(myNodeId, targetNodeId, channels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def buildRoute(finalAmountMsat: Int, nodeIds: Seq[BinaryData]) : lightning.route = {
|
||||||
|
|
||||||
|
// FIXME: use actual fee parameters that are specific to each node
|
||||||
|
def fee(amountMsat: Int) = nodeFee(Globals.base_fee, Globals.proportional_fee, amountMsat).toInt
|
||||||
|
|
||||||
|
var amountMsat = finalAmountMsat
|
||||||
|
val steps = nodeIds.reverse.map(nodeId => {
|
||||||
|
val step = route_step(amountMsat, next = Next.Bitcoin(nodeId))
|
||||||
|
amountMsat = amountMsat + fee(amountMsat)
|
||||||
|
step
|
||||||
|
})
|
||||||
|
lightning.route(steps.reverse :+ route_step(0, next = route_step.Next.End(true)))
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ package fr.acinq.eclair
|
||||||
|
|
||||||
import fr.acinq.bitcoin.BinaryData
|
import fr.acinq.bitcoin.BinaryData
|
||||||
import fr.acinq.eclair.router.{ChannelDesc, IRCRouter}
|
import fr.acinq.eclair.router.{ChannelDesc, IRCRouter}
|
||||||
|
import lightning.route_step
|
||||||
import org.jgrapht.alg.DijkstraShortestPath
|
import org.jgrapht.alg.DijkstraShortestPath
|
||||||
import org.jgrapht.graph.{DefaultEdge, SimpleGraph}
|
import org.jgrapht.graph.{DefaultEdge, SimpleGraph}
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
@ -79,4 +80,13 @@ class RouterSpec extends FunSuite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("compute fees") {
|
||||||
|
val nodeIds = Seq(BinaryData("00"), BinaryData("01"), BinaryData("02"))
|
||||||
|
val amountMsat = 1000000
|
||||||
|
val route = IRCRouter.buildRoute(amountMsat, nodeIds)
|
||||||
|
assert(route.steps.length == 4 && route.steps.last == route_step(0, next = route_step.Next.End(true)))
|
||||||
|
assert(route.steps(2).amount == amountMsat)
|
||||||
|
assert(route.steps.dropRight(1).map(_.next.bitcoin.get.key).map(bytestring2bin) == nodeIds)
|
||||||
|
assert(route.steps(0).amount - route.steps(1).amount == nodeFee(Globals.base_fee, Globals.proportional_fee, route.steps(1).amount))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue