Skip to content

Commit

Permalink
Fix htlc origin JSON serialization (#1641)
Browse files Browse the repository at this point in the history
A recent refactoring to include a `replyTo` parameter made the JSON
serialization ugly and hard to work with.

Fixes #1611
  • Loading branch information
t-bast committed Dec 16, 2020
1 parent dae5eee commit 413ee29
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

package fr.acinq.eclair.api

import java.net.InetSocketAddress
import java.util.UUID

import com.google.common.net.HostAndPort
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
Expand All @@ -39,6 +36,9 @@ import org.json4s.JsonAST._
import org.json4s.{CustomKeySerializer, CustomSerializer, DefaultFormats, Extraction, TypeHints, jackson}
import scodec.bits.ByteVector

import java.net.InetSocketAddress
import java.util.UUID

/**
* JSON Serializers.
* Note: in general, deserialization does not need to be implemented.
Expand Down Expand Up @@ -311,6 +311,22 @@ class ChannelEventSerializer extends CustomSerializer[ChannelEvent](_ => ( {
)
}))

class OriginSerializer extends CustomSerializer[Origin](_ => ( {
null
}, {
case o: Origin.Local => JObject(JField("paymentId", JString(o.id.toString)))
case o: Origin.ChannelRelayed => JObject(
JField("channelId", JString(o.originChannelId.toHex)),
JField("htlcId", JLong(o.originHtlcId)),
)
case o: Origin.TrampolineRelayed => JArray(o.htlcs.map {
case (channelId, htlcId) => JObject(
JField("channelId", JString(channelId.toHex)),
JField("htlcId", JLong(htlcId)),
)
})
}))

case class CustomTypeHints(custom: Map[Class[_], String]) extends TypeHints {
val reverse: Map[String, Class[_]] = custom.map(_.swap)

Expand Down Expand Up @@ -386,6 +402,7 @@ object JsonSupport extends Json4sSupport {
new PaymentRequestSerializer +
new JavaUUIDSerializer +
new FeaturesSerializer +
new OriginSerializer +
CustomTypeHints.incomingPaymentStatus +
CustomTypeHints.outgoingPaymentStatus +
CustomTypeHints.paymentEvent).withTypeHintFieldName("type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,19 @@

package fr.acinq.eclair.api

import java.net.InetAddress
import java.util.UUID

import fr.acinq.bitcoin.{ByteVector32, OutPoint, Transaction}
import fr.acinq.eclair._
import fr.acinq.eclair.channel.Origin
import fr.acinq.eclair.payment.{PaymentRequest, PaymentSettlingOnChain}
import fr.acinq.eclair.transactions.{IncomingHtlc, OutgoingHtlc}
import fr.acinq.eclair.wire._
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import scodec.bits._

import java.net.InetAddress
import java.util.UUID

class JsonSerializersSpec extends AnyFunSuite with Matchers {

test("deserialize Map[OutPoint, ByteVector]") {
Expand Down Expand Up @@ -82,6 +83,20 @@ class JsonSerializersSpec extends AnyFunSuite with Matchers {
JsonSupport.serialization.write(OutgoingHtlc(add))(org.json4s.DefaultFormats + new DirectedHtlcSerializer) shouldBe expectedIn.replace("IN", "OUT")
}

test("HTLC origin serialization") {
val localOrigin = Origin.LocalCold(UUID.fromString("11111111-1111-1111-1111-111111111111"))
val expectedLocalOrigin = """{"paymentId":"11111111-1111-1111-1111-111111111111"}"""
JsonSupport.serialization.write(localOrigin)(org.json4s.DefaultFormats + new OriginSerializer) shouldBe expectedLocalOrigin

val channelOrigin = Origin.ChannelRelayedCold(ByteVector32(hex"345b2b05ec046ffe0c14d3b61838c79980713ad1cf8ae7a45c172ce90c9c0b9f"), 7, 500 msat, 400 msat)
val expectedChannelOrigin = """{"channelId":"345b2b05ec046ffe0c14d3b61838c79980713ad1cf8ae7a45c172ce90c9c0b9f","htlcId":7}"""
JsonSupport.serialization.write(channelOrigin)(org.json4s.DefaultFormats + new OriginSerializer) shouldBe expectedChannelOrigin

val trampolineOrigin = Origin.TrampolineRelayedCold((ByteVector32(hex"9fcd45bbaa09c60c991ac0425704163c3f3d2d683c789fa409455b9c97792692"), 3L) :: (ByteVector32(hex"70685ca81a8e4d4d01beec5781f4cc924684072ae52c507f8ebe9daf0caaab7b"), 7L) :: Nil)
val expectedTrampolineOrigin = """[{"channelId":"9fcd45bbaa09c60c991ac0425704163c3f3d2d683c789fa409455b9c97792692","htlcId":3},{"channelId":"70685ca81a8e4d4d01beec5781f4cc924684072ae52c507f8ebe9daf0caaab7b","htlcId":7}]"""
JsonSupport.serialization.write(trampolineOrigin)(org.json4s.DefaultFormats + new OriginSerializer) shouldBe expectedTrampolineOrigin
}

test("Payment Request") {
val ref = "lnbcrt50n1p0fm9cdpp5al3wvsfkc6p7fxy89eu8gm4aww9mseu9syrcqtpa4mvx42qelkwqdq9v9ekgxqrrss9qypqsqsp5wl2t45v0hj4lgud0zjxcnjccd29ts0p2kh4vpw75vnhyyzyjtjtqarpvqg33asgh3z5ghfuvhvtf39xtnu9e7aqczpgxa9quwsxkd9rnwmx06pve9awgeewxqh90dqgrhzgsqc09ek6uejr93z8puafm6gsqgrk0hy"
val pr = PaymentRequest.read(ref)
Expand Down

0 comments on commit 413ee29

Please sign in to comment.