mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-23 14:40:34 +01:00
Use the correct extra edges to put in metrics (#2350)
We were using hints from `SendPaymentConfig.invoice` to populate `PathFindingExperimentMetrics`, but the invoice is optional and not populated for trampoline relay.
This commit is contained in:
parent
c20b3c9e8b
commit
214873e4a7
7 changed files with 16 additions and 57 deletions
|
@ -328,7 +328,7 @@ class PgAuditDb(implicit ds: DataSource) extends AuditDb with Logging {
|
|||
statement.setString(7, m.experimentName)
|
||||
statement.setString(8, m.recipientNodeId.value.toHex)
|
||||
statement.setString(9, m.paymentHash.toHex)
|
||||
statement.setString(10, m.routingHints_opt.map(serialization.write(_)).orNull)
|
||||
statement.setString(10, serialization.write(m.extraEdges))
|
||||
statement.executeUpdate()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,4 +261,4 @@ case class PathFindingExperimentMetrics(paymentHash: ByteVector32,
|
|||
isMultiPart: Boolean,
|
||||
experimentName: String,
|
||||
recipientNodeId: PublicKey,
|
||||
routingHints_opt: Option[Seq[Seq[Bolt11Invoice.ExtraHop]]])
|
||||
extraEdges: Seq[ExtraEdge])
|
||||
|
|
|
@ -264,11 +264,7 @@ class MultiPartPaymentLifecycle(nodeParams: NodeParams, cfg: SendPaymentConfig,
|
|||
}
|
||||
paymentSent.feesPaid + localFees
|
||||
}
|
||||
val hints_opt = cfg.invoice.flatMap {
|
||||
case invoice: Bolt11Invoice if invoice.routingInfo.nonEmpty => Some(invoice.routingInfo)
|
||||
case _ => None
|
||||
}
|
||||
context.system.eventStream.publish(PathFindingExperimentMetrics(cfg.paymentHash, cfg.recipientAmount, fees, status, duration, now, isMultiPart = true, request.routeParams.experimentName, cfg.recipientNodeId, hints_opt))
|
||||
context.system.eventStream.publish(PathFindingExperimentMetrics(cfg.paymentHash, cfg.recipientAmount, fees, status, duration, now, isMultiPart = true, request.routeParams.experimentName, cfg.recipientNodeId, request.extraEdges))
|
||||
}
|
||||
Metrics.SentPaymentDuration
|
||||
.withTag(Tags.MultiPart, Tags.MultiPartType.Parent)
|
||||
|
|
|
@ -349,13 +349,9 @@ class PaymentLifecycle(nodeParams: NodeParams, cfg: SendPaymentConfig, router: A
|
|||
fees
|
||||
}
|
||||
request match {
|
||||
case SendPaymentToNode(_, _, _, _, _, routeParams) =>
|
||||
val hints_opt = cfg.invoice.flatMap {
|
||||
case invoice: Bolt11Invoice if invoice.routingInfo.nonEmpty => Some(invoice.routingInfo)
|
||||
case _ => None
|
||||
}
|
||||
context.system.eventStream.publish(PathFindingExperimentMetrics(cfg.paymentHash, request.finalPayload.amount, fees, status, duration, now, isMultiPart = false, routeParams.experimentName, cfg.recipientNodeId, hints_opt))
|
||||
case SendPaymentToRoute(_, _, _, _) => ()
|
||||
case request: SendPaymentToNode =>
|
||||
context.system.eventStream.publish(PathFindingExperimentMetrics(cfg.paymentHash, request.finalPayload.amount, fees, status, duration, now, isMultiPart = false, request.routeParams.experimentName, cfg.recipientNodeId, request.extraEdges))
|
||||
case _: SendPaymentToRoute => ()
|
||||
}
|
||||
}
|
||||
Metrics.SentPaymentDuration
|
||||
|
|
|
@ -31,8 +31,6 @@ import fr.acinq.eclair.channel._
|
|||
import fr.acinq.eclair.db._
|
||||
import fr.acinq.eclair.io.Peer
|
||||
import fr.acinq.eclair.io.Peer.OpenChannel
|
||||
import fr.acinq.eclair.payment.Bolt11Invoice.ExtraHop
|
||||
import fr.acinq.eclair.payment.Invoice.BasicEdge
|
||||
import fr.acinq.eclair.payment.receive.MultiPartHandler.ReceivePayment
|
||||
import fr.acinq.eclair.payment.receive.PaymentHandler
|
||||
import fr.acinq.eclair.payment.relay.Relayer.{GetOutgoingChannels, RelayFees}
|
||||
|
@ -122,26 +120,6 @@ class EclairImplSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with I
|
|||
assert(send.recipientAmount == 123.msat)
|
||||
assert(send.paymentHash == ByteVector32.Zeroes)
|
||||
assert(send.invoice == invoice0)
|
||||
assert(send.invoice.extraEdges == Seq.empty)
|
||||
|
||||
// with assisted routes
|
||||
val externalId1 = "030bb6a5e0c6b203c7e2180fb78c7ba4bdce46126761d8201b91ddac089cdecc87"
|
||||
val hints = List(ExtraHop(Bob.nodeParams.nodeId, ShortChannelId.fromCoordinates("569178x2331x1").success.value, feeBase = 10 msat, feeProportionalMillionths = 1, cltvExpiryDelta = CltvExpiryDelta(12)))
|
||||
val invoice1 = Bolt11Invoice(Block.RegtestGenesisBlock.hash, Some(123 msat), ByteVector32.Zeroes, nodePrivKey, Left("description"), CltvExpiryDelta(18), None, None, List(hints))
|
||||
eclair.send(Some(externalId1), 123 msat, invoice1)
|
||||
val send1 = paymentInitiator.expectMsgType[SendPaymentToNode]
|
||||
assert(send1.externalId.contains(externalId1))
|
||||
assert(send1.recipientNodeId == nodePrivKey.publicKey)
|
||||
assert(send1.recipientAmount == 123.msat)
|
||||
assert(send1.paymentHash == ByteVector32.Zeroes)
|
||||
assert(send1.invoice == invoice1)
|
||||
assert(send1.invoice.extraEdges.length == 1)
|
||||
assert(send1.invoice.extraEdges.head.asInstanceOf[BasicEdge].shortChannelId == ShortChannelId.fromCoordinates("569178x2331x1").success.value)
|
||||
assert(send1.invoice.extraEdges.head.asInstanceOf[BasicEdge].sourceNodeId == Bob.nodeParams.nodeId)
|
||||
assert(send1.invoice.extraEdges.head.asInstanceOf[BasicEdge].targetNodeId == nodePrivKey.publicKey)
|
||||
assert(send1.invoice.extraEdges.head.asInstanceOf[BasicEdge].feeBase == 10.msat)
|
||||
assert(send1.invoice.extraEdges.head.asInstanceOf[BasicEdge].feeProportionalMillionths == 1)
|
||||
assert(send1.invoice.extraEdges.head.asInstanceOf[BasicEdge].cltvExpiryDelta == CltvExpiryDelta(12))
|
||||
|
||||
// with finalCltvExpiry
|
||||
val externalId2 = "487da196-a4dc-4b1e-92b4-3e5e905e9f3f"
|
||||
|
|
|
@ -852,7 +852,8 @@ class AuditDbSpec extends AnyFunSuite {
|
|||
test("add experiment metrics") {
|
||||
forAllDbs { dbs =>
|
||||
val isPg = dbs.isInstanceOf[TestPgDatabases]
|
||||
val hints = Some(Seq(Seq(ExtraHop(
|
||||
val recipientNodeId = PublicKey(hex"03f5b1f2768140178e1daac0fec11fce2eec6beec3ed64862bfb1114f7bc535b48")
|
||||
val hints = Seq(Seq(ExtraHop(
|
||||
PublicKey(hex"033f2d90d6ba1f771e4b3586b35cc9f825cfcb7cdd7edaa2bfd63f0cb81b17580e"),
|
||||
ShortChannelId(1),
|
||||
1000 msat,
|
||||
|
@ -870,12 +871,13 @@ class AuditDbSpec extends AnyFunSuite {
|
|||
800 msat,
|
||||
300,
|
||||
CltvExpiryDelta(78)
|
||||
))))
|
||||
dbs.audit.addPathFindingExperimentMetrics(PathFindingExperimentMetrics(randomBytes32(), 100000000 msat, 3000 msat, status = "SUCCESS", 37 millis, TimestampMilli.now(), isMultiPart = false, "my-test-experiment", randomKey().publicKey, hints))
|
||||
)))
|
||||
val extraEdges = hints.flatMap(Bolt11Invoice.toExtraEdges(_, recipientNodeId))
|
||||
dbs.audit.addPathFindingExperimentMetrics(PathFindingExperimentMetrics(randomBytes32(), 100000000 msat, 3000 msat, status = "SUCCESS", 37 millis, TimestampMilli.now(), isMultiPart = false, "my-test-experiment", recipientNodeId, extraEdges))
|
||||
|
||||
val table = if (isPg) "audit.path_finding_metrics" else "path_finding_metrics"
|
||||
val hint_column = if (isPg) ", routing_hints" else ""
|
||||
using(dbs.connection.prepareStatement(s"SELECT amount_msat, status, fees_msat, duration_ms, experiment_name $hint_column FROM $table")) { statement =>
|
||||
using(dbs.connection.prepareStatement(s"SELECT amount_msat, status, fees_msat, duration_ms, experiment_name, recipient_node_id $hint_column FROM $table")) { statement =>
|
||||
val result = statement.executeQuery()
|
||||
assert(result.next())
|
||||
assert(result.getLong(1) == 100000000)
|
||||
|
@ -884,7 +886,8 @@ class AuditDbSpec extends AnyFunSuite {
|
|||
assert(result.getLong(4) == 37)
|
||||
assert(result.getString(5) == "my-test-experiment")
|
||||
if (isPg) {
|
||||
assert(result.getString(6) == "[[{\"nodeId\": \"033f2d90d6ba1f771e4b3586b35cc9f825cfcb7cdd7edaa2bfd63f0cb81b17580e\", \"feeBase\": 1000, \"shortChannelId\": \"0x0x1\", \"cltvExpiryDelta\": 144, \"feeProportionalMillionths\": 100}, {\"nodeId\": \"02c15a88ff263cec5bf79c315b17b7f2e083f71d62a880e30281faaac0898cb2b7\", \"feeBase\": 900, \"shortChannelId\": \"0x0x2\", \"cltvExpiryDelta\": 12, \"feeProportionalMillionths\": 200}], [{\"nodeId\": \"026ec3e3438308519a75ca4496822a6c1e229174fbcaadeeb174704c377112c331\", \"feeBase\": 800, \"shortChannelId\": \"0x0x3\", \"cltvExpiryDelta\": 78, \"feeProportionalMillionths\": 300}]]")
|
||||
assert(result.getString(6) == recipientNodeId.toHex)
|
||||
assert(result.getString(7) == "[{\"feeBase\": 1000, \"sourceNodeId\": \"033f2d90d6ba1f771e4b3586b35cc9f825cfcb7cdd7edaa2bfd63f0cb81b17580e\", \"targetNodeId\": \"02c15a88ff263cec5bf79c315b17b7f2e083f71d62a880e30281faaac0898cb2b7\", \"shortChannelId\": \"0x0x1\", \"cltvExpiryDelta\": 144, \"feeProportionalMillionths\": 100}, {\"feeBase\": 900, \"sourceNodeId\": \"02c15a88ff263cec5bf79c315b17b7f2e083f71d62a880e30281faaac0898cb2b7\", \"targetNodeId\": \"03f5b1f2768140178e1daac0fec11fce2eec6beec3ed64862bfb1114f7bc535b48\", \"shortChannelId\": \"0x0x2\", \"cltvExpiryDelta\": 12, \"feeProportionalMillionths\": 200}, {\"feeBase\": 800, \"sourceNodeId\": \"026ec3e3438308519a75ca4496822a6c1e229174fbcaadeeb174704c377112c331\", \"targetNodeId\": \"03f5b1f2768140178e1daac0fec11fce2eec6beec3ed64862bfb1114f7bc535b48\", \"shortChannelId\": \"0x0x3\", \"cltvExpiryDelta\": 78, \"feeProportionalMillionths\": 300}]")
|
||||
}
|
||||
assert(!result.next())
|
||||
}
|
||||
|
|
|
@ -280,25 +280,11 @@ object MinimalNodeFixture extends Assertions with EitherValues {
|
|||
|
||||
def sendPayment(node1: MinimalNodeFixture, node2: MinimalNodeFixture, amount: MilliSatoshi, hints: Seq[Seq[ExtraHop]] = Seq.empty)(implicit system: ActorSystem): Either[PaymentFailed, PaymentSent] = {
|
||||
val sender = TestProbe("sender")
|
||||
sender.send(node2.paymentHandler, MultiPartHandler.ReceivePayment(Some(amount), Left("test payment")))
|
||||
sender.send(node2.paymentHandler, MultiPartHandler.ReceivePayment(Some(amount), Left("test payment"), extraHops = hints.map(_.toList).toList))
|
||||
val invoice = sender.expectMsgType[Bolt11Invoice]
|
||||
val invoiceWithHints = Bolt11Invoice(
|
||||
chainHash = node2.nodeParams.chainHash,
|
||||
amount = invoice.amount_opt,
|
||||
paymentHash = invoice.paymentHash,
|
||||
privateKey = node2.nodeParams.privateKey,
|
||||
description = invoice.description,
|
||||
minFinalCltvExpiryDelta = invoice.minFinalCltvExpiryDelta,
|
||||
fallbackAddress = invoice.fallbackAddress(),
|
||||
expirySeconds = invoice.tags.collectFirst { case expiry: Bolt11Invoice.Expiry => expiry.toLong },
|
||||
extraHops = hints.map(_.toList).toList,
|
||||
timestamp = invoice.createdAt,
|
||||
paymentSecret = invoice.paymentSecret.get,
|
||||
paymentMetadata = invoice.paymentMetadata,
|
||||
features = invoice.features)
|
||||
|
||||
val routeParams = node1.nodeParams.routerConf.pathFindingExperimentConf.experiments.values.head.getDefaultRouteParams
|
||||
sender.send(node1.paymentInitiator, PaymentInitiator.SendPaymentToNode(amount, invoiceWithHints, maxAttempts = 1, routeParams = routeParams, blockUntilComplete = true))
|
||||
sender.send(node1.paymentInitiator, PaymentInitiator.SendPaymentToNode(amount, invoice, maxAttempts = 1, routeParams = routeParams, blockUntilComplete = true))
|
||||
sender.expectMsgType[PaymentEvent] match {
|
||||
case e: PaymentSent => Right(e)
|
||||
case e: PaymentFailed => Left(e)
|
||||
|
|
Loading…
Add table
Reference in a new issue