Avoid calling libsecp serialization fns when calculating length
authorMatt Corallo <git@bluematt.me>
Sat, 29 May 2021 18:24:16 +0000 (18:24 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 1 Jun 2021 15:47:01 +0000 (15:47 +0000)
commitc632fffc3ddb98da0ba918a77317fdda504116f3
tree1ab7ea3a1af9568681e6b1bbcdb104de4027123c
parent615419d5255157bf394a4f281279711133e17552
Avoid calling libsecp serialization fns when calculating length

When writing out libsecp256k1 objects during serialization in a
TLV, we potentially calculate the TLV length twice before
performing the actual serialization (once when calculating the
total TLV-stream length and once when calculating the length of the
secp256k1-object-containing TLV). Because the lengths of secp256k1
objects is a constant, we'd ideally like LLVM to entirely optimize
out those calls and simply know the expected length. However,
without cross-language LTO, there is no way for LLVM to verify that
there are no side-effects of the calls to libsecp256k1, leaving
LLVM with no way to optimize them out.

This commit adds a new method to `Writeable` which returns the
length of an object once serialized. It is implemented by default
using `LengthCalculatingWriter` (which LLVM generally optimizes out
for Rust objects) and overrides it for libsecp256k1 objects.

As of this commit, on an Intel 2687W v3, the serialization
benchmarks take:

test routing::network_graph::benches::read_network_graph  ... bench: 2,035,402,164 ns/iter (+/- 1,855,357)
test routing::network_graph::benches::write_network_graph ... bench: 308,235,267 ns/iter (+/- 140,202)
lightning/src/util/ser.rs
lightning/src/util/ser_macros.rs