In this commit, we eliminate the final allocation that takes place when
we write out messages. Once again this was escaping to the heap, so we
make it an attribute on the Machine struct, which allows pure static
allocation.
```
goos: darwin
goarch: arm64
pkg: github.com/lightningnetwork/lnd/brontide
cpu: Apple M4 Max
BenchmarkWriteMessage-16 25840 46376 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25646 46672 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25874 46391 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25512 46427 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25760 46309 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25789 46520 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25602 46619 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25766 46464 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25820 46487 ns/op 2 B/op 0 allocs/op
BenchmarkWriteMessage-16 25634 46553 ns/op 2 B/op 0 allocs/op
PASS
ok github.com/lightningnetwork/lnd/brontide 16.907s
```
Here we introduce the access manager which has caches that will
determine the access control status of our peers. Peers that have
had their funding transaction confirm with us are protected. Peers
that only have pending-open channels with us are temporary access
and can have their access revoked. The rest of the peers are granted
restricted access.
It is best to have deterministic fuzz targets, so that if a failure
occurs, it can be easily reproduced.
This commit swaps the cryptographically secure RNG for a deterministic
one seeded from fuzzer input.
Move the functionality directly into completeHandshake instead. If a
failure does happen at any point during the handshake, it is beneficial
to know which line it happens on for debugging. The helper function was
hiding this information.
This commit was previously split into the following parts to ease
review:
- 2d746f68: replace imports
- 4008f0fd: use ecdsa.Signature
- 849e33d1: remove btcec.S256()
- b8f6ebbd: use v2 library correctly
- fa80bca9: bump go modules
In this commit, we implement a simple optimization that dramatically
reduces the number of allocations we need to make when we decrypt a new
message. Before this commit, we would pass in a `nil` value to the
`Decrypt` method which meant that it would always allocate a new
buffers.
Rather than force this behavior, in this commit, we pass in the
ciphertext buffer (with a length of zero), such that the decryption
operation will simply copy the plaintext bytes over the cipher text in
place. This works as the cipher text is always larger than the
plaintext, since the plaintext doesn't have a MAC attached.
The amount the perf increase, amount of allocations, and amount of bytes
allocated are pretty nice:
```
benchmark old ns/op new ns/op delta
BenchmarkReadHeaderAndBody-8 88652 75896 -14.39%
benchmark old allocs new allocs delta
BenchmarkReadHeaderAndBody-8 6 4 -33.33%
benchmark old bytes new bytes delta
BenchmarkReadHeaderAndBody-8 65664 128 -99.81%
```
Here old is without this change, and new with it.
This commit exposes the WriteMessage and Flush interfaces of the
underlying brontide.Machine, such that callers can have greater
flexibility in when blocking network operations take place.
This commit modifies WriteMessage to only perform encryption on the
passed plaintext, and buffer the ciphertext within the connection
object. We then modify internal uses of WriteMessage to follow with a
call to Flush, which actually writes the message to the wire.
Additionally, since WriteMessage does not actually perform the write
itself, the io.Writer argument is removed from the function signature
and all call sites.
This commit adds a Flush method to the brontide.Machine, which can write
out a buffered message to an io.Writer. This is a preliminary change
which will allow the encryption of the plaintext to be done in a
distinct method from actually writing the bytes to the wire.