Impl `serialized_length()` without `LengthCalculatingWriter`
authorMatt Corallo <git@bluematt.me>
Sat, 29 May 2021 18:32:53 +0000 (18:32 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 1 Jun 2021 15:47:01 +0000 (15:47 +0000)
commit583e6ac6f0bf1fd311621ea7584d160bd6d7c192
tree86622f30e4f4ec835d43531f975ac717a7da6ece
parentc632fffc3ddb98da0ba918a77317fdda504116f3
Impl `serialized_length()` without `LengthCalculatingWriter`

With the new `serialized_length()` method potentially being
significantly more efficient than `LengthCalculatingWriter`, this
commit ensures we call `serialized_length()` when calculating
length of a larger struct.

Specifically, prior to this commit a call to
`serialized_length()` on a large object serialized with
`impl_writeable`, `impl_writeable_len_match`, or
`encode_varint_length_prefixed_tlv` (and
`impl_writeable_tlv_based`) would always serialize all inner fields
of that object using `LengthCalculatingWriter`. This would ignore
any `serialized_length()` overrides by inner fields. Instead, we
override `serialized_length()` on all of the above by calculating
the serialized size using calls to `serialized_length()` on inner
fields.

Further, writes to `LengthCalculatingWriter` should never fail as
its `write` method never returns an error. Thus, any write failures
indicate a bug in an object's write method or in our
object-creation sanity checking. We `.expect()` such write calls
here.

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

test routing::network_graph::benches::read_network_graph  ... bench: 2,039,451,296 ns/iter (+/- 4,329,821)
test routing::network_graph::benches::write_network_graph ... bench: 166,685,412 ns/iter (+/- 352,537)
lightning/src/util/ser_macros.rs