1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-03-27 02:37:06 +01:00

added payment-related events

This commit is contained in:
pm47 2016-08-26 17:35:59 +02:00
parent 2bbbffcd03
commit 5b258c2c6e
5 changed files with 31 additions and 21 deletions

View file

@ -7,7 +7,6 @@ import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel.Helpers._
import fr.acinq.eclair.channel.TypeDefs.Change
import fr.acinq.eclair.crypto.ShaChain
import fr.acinq.eclair.router.Router$
import lightning._
import lightning.open_channel.anchor_offer.{WILL_CREATE_ANCHOR, WONT_CREATE_ANCHOR}
import lightning.route_step.Next
@ -326,8 +325,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
case Event(fulfill@update_fulfill_htlc(id, r), d@DATA_NORMAL(commitments, _, downstreams)) =>
Try(Commitments.receiveFulfill(d.commitments, fulfill)) match {
case Success(commitments1) =>
propagateDownstream(Right(fulfill), downstreams)
case Success((commitments1, htlc)) =>
propagateDownstream(htlc, Right(fulfill), downstreams)
commitments1.ourParams.autoSignInterval.map(interval => context.system.scheduler.scheduleOnce(interval, self, CMD_SIGN))
stay using d.copy(commitments = commitments1, downstreams = downstreams - id)
case Failure(cause) => handleOurError(cause, d)
@ -343,8 +342,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
case Event(fail@update_fail_htlc(id, reason), d@DATA_NORMAL(commitments, _, downstreams)) =>
Try(Commitments.receiveFail(d.commitments, fail)) match {
case Success(commitments1) =>
propagateDownstream(Left(fail), downstreams)
case Success((commitments1, htlc)) =>
propagateDownstream(htlc, Left(fail), downstreams)
commitments1.ourParams.autoSignInterval.map(interval => context.system.scheduler.scheduleOnce(interval, self, CMD_SIGN))
stay using d.copy(commitments = commitments1, downstreams = downstreams - id)
case Failure(cause) => handleOurError(cause, d)
@ -448,8 +447,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
case Event(fulfill@update_fulfill_htlc(id, r), d: DATA_CLEARING) =>
Try(Commitments.receiveFulfill(d.commitments, fulfill)) match {
case Success(commitments1) =>
propagateDownstream(Right(fulfill), d.downstreams)
case Success((commitments1, htlc)) =>
propagateDownstream(htlc, Right(fulfill), d.downstreams)
stay using d.copy(commitments = commitments1, downstreams = d.downstreams - id)
case Failure(cause) => handleOurError(cause, d)
}
@ -462,8 +461,8 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
case Event(fail@update_fail_htlc(id, reason), d: DATA_CLEARING) =>
Try(Commitments.receiveFail(d.commitments, fail)) match {
case Success(commitments1) =>
propagateDownstream(Left(fail), d.downstreams)
case Success((commitments1, htlc)) =>
propagateDownstream(htlc, Left(fail), d.downstreams)
stay using d.copy(commitments = commitments1, downstreams = d.downstreams - id)
case Failure(cause) => handleOurError(cause, d)
}
@ -673,17 +672,18 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
}
case route_step(amount, Next.End(true)) +: rest =>
log.info(s"we are the final recipient of htlc #${add.id}")
context.system.eventStream.publish(PaymentReceived(self, add.rHash))
paymentHandler ! add
}
}
def propagateDownstream(fulfill_or_fail: Either[update_fail_htlc, update_fulfill_htlc], downstreams: Map[Long, Option[BinaryData]]) = {
val (id, short, cmd: Command) = fulfill_or_fail match {
def propagateDownstream(htlc: update_add_htlc, fail_or_fulfill: Either[update_fail_htlc, update_fulfill_htlc], downstreams: Map[Long, Option[BinaryData]]) = {
val (id, short, cmd: Command) = fail_or_fulfill match {
case Left(fail) => (fail.id, "fail", CMD_FAIL_HTLC(fail.id, fail.reason.info.toStringUtf8))
case Right(fulfill) => (fulfill.id, "fulfill", CMD_FULFILL_HTLC(fulfill.id, fulfill.r))
}
downstreams(id) match {
case Some(previousChannelId) =>
(downstreams(id), fail_or_fulfill) match {
case (Some(previousChannelId), _) =>
log.debug(s"propagating $short for htlc #$id to $previousChannelId")
import ExecutionContext.Implicits.global
context.system.actorSelection(Register.actorPathToChannelId(previousChannelId))
@ -697,8 +697,12 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
case Failure(t: Throwable) =>
log.warning(s"couldn't resolve downstream node, htlc #$id will timeout", t)
}
case None =>
case (None, Left(fail)) =>
log.info(s"we were the origin payer for htlc #$id")
context.system.eventStream.publish(PaymentFailed(self, htlc.rHash))
case (None, Right(fulfill)) =>
log.info(s"we were the origin payer for htlc #$id")
context.system.eventStream.publish(PaymentSent(self, htlc.rHash))
}
}

View file

@ -2,6 +2,7 @@ package fr.acinq.eclair.channel
import akka.actor.ActorRef
import fr.acinq.bitcoin.BinaryData
import lightning.sha256_hash
/**
* Created by PM on 17/08/2016.
@ -16,3 +17,9 @@ case class ChannelIdAssigned(channel: ActorRef, channelId: BinaryData, amount: L
case class ChannelChangedState(channel: ActorRef, theirNodeId: String, previousState: State, currentState: State, currentData: Data) extends ChannelEvent
case class ChannelSignatureReceived(channel: ActorRef, Commitments: Commitments) extends ChannelEvent
case class PaymentSent(channel: ActorRef, h: sha256_hash) extends ChannelEvent
case class PaymentFailed(channel: ActorRef, h: sha256_hash) extends ChannelEvent
case class PaymentReceived(channel: ActorRef, h: sha256_hash) extends ChannelEvent

View file

@ -119,9 +119,9 @@ object Commitments {
}
}
def receiveFulfill(commitments: Commitments, fulfill: update_fulfill_htlc): Commitments = {
def receiveFulfill(commitments: Commitments, fulfill: update_fulfill_htlc): (Commitments, update_add_htlc) = {
commitments.theirCommit.spec.htlcs.collectFirst { case u: Htlc if u.add.id == fulfill.id => u.add } match {
case Some(htlc) if htlc.rHash == bin2sha256(Crypto.sha256(fulfill.r)) => addTheirProposal(commitments, fulfill)
case Some(htlc) if htlc.rHash == bin2sha256(Crypto.sha256(fulfill.r)) => (addTheirProposal(commitments, fulfill), htlc)
case Some(htlc) => throw new RuntimeException(s"invalid htlc preimage for htlc id=${fulfill.id}")
case None => throw new RuntimeException(s"unknown htlc id=${fulfill.id}") // TODO : we should fail the channel
}
@ -137,9 +137,9 @@ object Commitments {
}
}
def receiveFail(commitments: Commitments, fail: update_fail_htlc): Commitments = {
commitments.theirCommit.spec.htlcs.collectFirst { case u: Htlc if u.add.id == fail.id => u } match {
case Some(htlc) => addTheirProposal(commitments, fail)
def receiveFail(commitments: Commitments, fail: update_fail_htlc): (Commitments, update_add_htlc) = {
commitments.theirCommit.spec.htlcs.collectFirst { case u: Htlc if u.add.id == fail.id => u.add } match {
case Some(htlc) => (addTheirProposal(commitments, fail), htlc)
case None => throw new RuntimeException(s"unknown htlc id=${fail.id}") // TODO : we should fail the channel
}
}

View file

@ -49,7 +49,6 @@ class Router(initialBlockCount: Long) extends Actor with ActorLogging {
.map { channel =>
// build a route
val r = buildRoute(c.amountMsat, next +: others)
// apply fee
val amountMsat = r.steps(0).amount
channel ! CMD_ADD_HTLC(amountMsat, c.h, locktime(Blocks(currentBlockCount.toInt + 100 + r.steps.size - 2)), r.copy(steps = r.steps.tail), commit = true)

View file

@ -25,7 +25,7 @@ class StealRevokedCommitmentSpec extends FunSuite {
def fulfillHtlc(sender: Commitments, receiver: Commitments, id: Long, paymentPreimage: BinaryData): (Commitments, Commitments) = {
val (sender1, fulfill) = Commitments.sendFulfill(sender, CMD_FULFILL_HTLC(id, paymentPreimage))
val receiver1 = Commitments.receiveFulfill(receiver, fulfill)
val (receiver1, _) = Commitments.receiveFulfill(receiver, fulfill)
(sender1, receiver1)
}