Skip to content

Commit

Permalink
Removed cached codec (#1036)
Browse files Browse the repository at this point in the history
It turns out that performance gains of the cached codec are not that
great, and they come at a cost of significant pressure on the GC. In
other words: premature optimization.

When removed, the heap usage becomes very stable, which is much better
than hypothetical performance gains.

Fixes #1031.
  • Loading branch information
pm47 authored Jun 14, 2019
1 parent b4adff2 commit a3563e3
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ class Authenticator(nodeParams: NodeParams) extends Actor with DiagnosticActorLo
KeyPair(nodeParams.nodeId.value, nodeParams.privateKey.value),
remoteNodeId_opt.map(_.value),
connection = connection,
codec = LightningMessageCodecs.cachedLightningMessageCodec))
codec = LightningMessageCodecs.lightningMessageCodec))
context watch transport
context become (ready(switchboard, authenticating + (transport -> pending)))
context become ready(switchboard, authenticating + (transport -> pending))

case HandshakeCompleted(connection, transport, remoteNodeId) if authenticating.contains(transport) =>
val pendingAuth = authenticating(transport)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,31 +321,6 @@ object LightningMessageCodecs {
.typecase(264, replyChannelRangeCodec)
.typecase(265, gossipTimestampFilterCodec)


/**
* A codec that caches serialized routing messages
*/
val cachedLightningMessageCodec = new Codec[LightningMessage] {

override def sizeBound: SizeBound = lightningMessageCodec.sizeBound

val cache = CacheBuilder
.newBuilder
.weakKeys() // will cleanup values when keys are garbage collected
.build(new CacheLoader[LightningMessage, Attempt[BitVector]] {
override def load(key: LightningMessage): Attempt[BitVector] = lightningMessageCodec.encode(key)
})

override def encode(value: LightningMessage): Attempt[BitVector] = value match {
case _: ChannelAnnouncement => cache.get(value) // we only cache serialized routing messages
case _: NodeAnnouncement => cache.get(value) // we only cache serialized routing messages
case _: ChannelUpdate => cache.get(value) // we only cache serialized routing messages
case _ => lightningMessageCodec.encode(value)
}

override def decode(bits: BitVector): Attempt[DecodeResult[LightningMessage]] = lightningMessageCodec.decode(bits)
}

val perHopPayloadCodec: Codec[PerHopPayload] = (
("realm" | constant(ByteVector.fromByte(0))) ::
("short_channel_id" | shortchannelid) ::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,38 +245,6 @@ class LightningMessageCodecsSpec extends FunSuite {
}
}

test("encode/decode using cached codec") {
val codec = cachedLightningMessageCodec

val commit_sig = CommitSig(randomBytes32, randomBytes64, randomBytes64 :: randomBytes64 :: randomBytes64 :: Nil)
val revoke_and_ack = RevokeAndAck(randomBytes32, scalar(0), point(1))
val channel_announcement = ChannelAnnouncement(randomBytes64, randomBytes64, randomBytes64, randomBytes64, bin(7, 9), Block.RegtestGenesisBlock.hash, ShortChannelId(1), randomKey.publicKey, randomKey.publicKey, randomKey.publicKey, randomKey.publicKey)
val node_announcement = NodeAnnouncement(randomBytes64, bin(0, 0), 1, randomKey.publicKey, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", IPv4(InetAddress.getByAddress(Array[Byte](192.toByte, 168.toByte, 1.toByte, 42.toByte)).asInstanceOf[Inet4Address], 42000) :: Nil)
val channel_update1 = ChannelUpdate(randomBytes64, Block.RegtestGenesisBlock.hash, ShortChannelId(1), 2, 1, 0, 3, 4, 5, 6, Some(50000000L))
val channel_update2 = ChannelUpdate(randomBytes64, Block.RegtestGenesisBlock.hash, ShortChannelId(1), 2, 0, 0, 3, 4, 5, 6, None)
val announcement_signatures = AnnouncementSignatures(randomBytes32, ShortChannelId(42), randomBytes64, randomBytes64)
val ping = Ping(100, bin(10, 1))
val pong = Pong(bin(10, 1))

val cached = channel_announcement :: node_announcement :: channel_update1 :: channel_update2 :: Nil
val nonCached = commit_sig :: revoke_and_ack :: announcement_signatures :: ping :: pong :: Nil
val msgs: List[LightningMessage] = cached ::: nonCached

msgs.foreach {
case msg => {
val encoded = codec.encode(msg).require
val decoded = codec.decode(encoded).require
assert(msg === decoded.value)
}
}

import scala.language.reflectiveCalls
val cachedKeys = codec.cache.asMap().keySet()
assert(cached.forall(msg => cachedKeys.contains(msg)))
assert(nonCached.forall(msg => !cachedKeys.contains(msg)))

}

test("decode channel_update with htlc_maximum_msat") {
// this was generated by c-lightning
val bin = hex"010258fff7d0e987e2cdd560e3bb5a046b4efe7b26c969c2f51da1dceec7bcb8ae1b634790503d5290c1a6c51d681cf8f4211d27ed33a257dcc1102862571bf1792306226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0005a100000200005bc75919010100060000000000000001000000010000000a000000003a699d00"
Expand Down

0 comments on commit a3563e3

Please sign in to comment.