mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-24 06:47: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
|
||||
closing-fee = 10000
|
||||
base-fee = 546000
|
||||
proportional-fee = 10
|
||||
payment-handler = "local"
|
||||
}
|
||||
akka {
|
||||
|
|
|
@ -29,7 +29,8 @@ object Globals {
|
|||
val default_mindepth = 3
|
||||
val commit_fee = config.getInt("eclair.commit-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
|
||||
|
||||
//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 = {
|
||||
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))
|
||||
.resolveOne(2 seconds)
|
||||
.map { channel =>
|
||||
// TODO : no fees!
|
||||
val r = lightning.route(others.map(n => route_step(c.amountMsat, next = Next.Bitcoin(n))) :+ route_step(0, next = route_step.Next.End(true)))
|
||||
// build a route
|
||||
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
|
||||
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
|
||||
}
|
||||
}) onFailure {
|
||||
|
@ -115,11 +119,23 @@ object IRCRouter {
|
|||
}
|
||||
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 {
|
||||
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.eclair.router.{ChannelDesc, IRCRouter}
|
||||
import lightning.route_step
|
||||
import org.jgrapht.alg.DijkstraShortestPath
|
||||
import org.jgrapht.graph.{DefaultEdge, SimpleGraph}
|
||||
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