This commit adds an additional return value to
Stream.DecodeWithParsedTypes, which returns the set of types that were
encountered during decoding. The set will contain all known types that
were decoded, as well as unknown odd types that were ignored.
The rationale for the return value (rather than an internal member) is
so that the stream remains stateless.
This return value can be used by callers during decoding to make
assertions as to whether specific types were included in the stream.
This is need, for example, when parsing onion payloads where certain
fields must be included/omitted depending on the hop type.
The original Decode method would incur the additional performance hit of
needing to track the parsed types, so we can selectively enable this
functionality when a decoder requires it by using a helper which
conditionally tracks the parsed types.
In this commit, we extend the Hop struct to carry an arbitrary set of
TLV values, and add a new field that allows us to distinguish between
the modern and legacy TLV payload.
We add a new `PackPayload` method that will be used to encode the
combined required routing TLV fields along any set of TLV fields that
were specified as part of path finding.
Finally, the `ToSphinxPath` has been extended to be able to recognize if
a hop needs the modern, or legacy payload.
In this commit, we add two new method so the `Record` struct: Type() and
Encode(). These are useful when a caller is handling a record and may
not know its underlying type and may need to encode a record in
isolation.
This commit fixes a bug in DTUint16 and DTUint32, which would cause them
to read too many bytes from the reader. This is due to the fact that
ReadFull was being called on a slice that could be greater than the
underlying type. This is not an issue for DTUint64, since the 8-byte
buffer corresponds to the maximum possible size of a uint64. The
solution is to clamp the buffer to 2 and 4 bytes respectively.
A series of tests are also added to exercise these cases.
This commit adds the truncated integer encodings used in the
variable-size onion payloads. The amount and cltv delta both use the
truncated encoding to shave bytes in the overall size, and will likely
be used in the future for additional extensions where size is a
constraint.
This commit adds concrete encoding methods for primitive integral types.
When external libs need to create custom encoders, this allows them to
do so without incurring an extra allocation on the heap. Previously, the
need to pass a pointer to the integer using an interface{} would cause
the argument to escape, which we avoid by having them copied directly.
This varint has the same serialization as the varint in btcd and
bitcoind, but has different behavior wrt returned errors. In order to
ensure the inner loop properly detects cleanly written records,
ReadVarInt will not only return EOF if it can't read the first byte, as
that means the reader has zero bytes left.
It also modifies the API to allow the caller to provided a static byte
array, which can be reused across all encoding and decoding and
increases performance.