In this commit, we might a very small change to the way writing messages
works in the peer, which should have large implications w.r.t reducing
memory usage amongst chatty nodes.
When profiling the heap on one of my nodes earlier, I noticed this
fragment:
```
Showing top 20 nodes out of 68
flat flat% sum% cum cum%
0 0% 0% 75.53MB 54.61% main.(*peer).writeHandler
75.53MB 54.61% 54.61% 75.53MB 54.61% main.(*peer).writeMessage
```
Which points to an inefficiency with the way we handle allocations when
writing new messages, drilling down further we see:
```
(pprof) list writeMessage
Total: 138.31MB
ROUTINE ======================== main.(*peer).writeMessage in /root/go/src/github.com/lightningnetwork/lnd/peer.go
75.53MB 75.53MB (flat, cum) 54.61% of Total
. . 1104: p.logWireMessage(msg, false)
. . 1105:
. . 1106: // As the Lightning wire protocol is fully message oriented, we only
. . 1107: // allows one wire message per outer encapsulated crypto message. So
. . 1108: // we'll create a temporary buffer to write the message directly to.
75.53MB 75.53MB 1109: var msgPayload [lnwire.MaxMessagePayload]byte
. . 1110: b := bytes.NewBuffer(msgPayload[0:0:len(msgPayload)])
. . 1111:
. . 1112: // With the temp buffer created and sliced properly (length zero, full
. . 1113: // capacity), we'll now encode the message directly into this buffer.
. . 1114: n, err := lnwire.WriteMessage(b, msg, 0)
(pprof) list writeHandler
Total: 138.31MB
ROUTINE ======================== main.(*peer).writeHandler in /root/go/src/github.com/lightningnetwork/lnd/peer.go
0 75.53MB (flat, cum) 54.61% of Total
. . 1148:
. . 1149: // Write out the message to the socket, closing the
. . 1150: // 'sentChan' if it's non-nil, The 'sentChan' allows
. . 1151: // callers to optionally synchronize sends with the
. . 1152: // writeHandler.
. 75.53MB 1153: err := p.writeMessage(outMsg.msg)
. . 1154: if outMsg.errChan != nil {
. . 1155: outMsg.errChan <- err
. . 1156: }
. . 1157:
. . 1158: if err != nil {
```
Ah hah! We create a _new_ buffer each time we want to write a message
out. This is unnecessary and _very_ wasteful (as seen by the profile).
The fix is simple: re-use a buffer unique to each peer when writing out
messages. Since we know what the max message size is, we just allocate
one of these 65KB buffers for each peer, and keep it around until the
peer is removed.
This commit fixes a bug within the funding manager, where we would use
the wrong min_htlc_value parameter. Instead of attributing the custom
passed value for MinHtlc to the remote's constraints, we would add it to
our own constraints.
This commit adds TestFundingManagerCustomChannelParameters, which checks
that custom channel parameters specified at channel creation is
preserved and recorded correctly on both sides of the channel.
This commit fixes a bug that would cause the local and remote commitment
to be incompatible when using custom remote CSV delay when opening a
channel. This would happen because we wouldn't store the CSV value
before we received the FundingAccept message, and here we would use the
default value.
This commit fixes this by making the csv value part of the
reservationWithCtx struct, such that it can be recorded for use when the
FundingAccept msg comes back.
It is better to replace bash shell with potentially long-running
last script command. This way the running command will receive all
potential unix process signals directly.
A concrete example which motivated this change:
Exec of btcd is needed for graceful shutdown of btcd during
`docker-compose down`. Docker Compose properly sends this signal to our
start-btcd.sh bash shell but it is not further signalled to the running
btcd process. Docker Compose then kills whole container forcefully after
some timeout.
An alternative solution would be to trap SIGTERM in our bash script and
forward it to running btcd. Which would be IMO ugly and error prone.
In this commit, we fix an existing bug in the NewBreachRetribution
method. Rather than creating the slice to the proper length, we instead
now create it to the proper _capacity_. As we'll now properly filter out
any dust HTLCs, before this commit, even if no HTLCs were added, then
the slice would still have a full length, meaning callers could actually
interact with _blank_ HtlcRetribution structs.
The fix is simple: create the slice with the proper capacity, and append
to the end of it.
In this commit, we fix an existing within lnd. Before this commit,
within NewBreachRetribution the order of the keys when generating the
sender HTLC script was incorrect. As in this case, the remote party is
the sender, their key should be first. However, the order was swapped,
meaning that at breach time, our transaction would be rejected as it had
the incorrect witness script.
The fix is simple: swap the ordering of the keys. After this commit, the
test extension added in the prior commit now passes.
In this commit, we extend the testRevokedCloseRetributionRemoteHodl so
that the final broadcast revoked transaction has incoming *and* outgoing
HTLC's. As is, this test fails as there's a lingering bug in the way we
generate htlc resolutions. A follow up commit will remedy this issue.
In this commit we add a new error: InvalidHtlcSigError. This error will
be returned when we're unable to validate an HTLC signature sent by the
remote party. This will allow other nodes to more easily debug _why_ the
signature was rejected.
In this commit, we fix a slight bug in lnd. Before this commit, we would
send the error to the remote peer, but in an async manner. As a result,
it was possible for the connections to be closed _before_ the error
actually reached the remote party. The fix is simple: wait for the error
to be returned when sending the message. This ensures that the error
reaches the remote party before we kill the connection.
In this commit, add a new argument to the SendMessage method to allow
callers to request that the method block until the message has been sent
on the socket to the remote peer.
This commit changes the chainntnfs tests to adhere to the new
RegisterSpendNtfn signature. It also makes sure that for the test
testSpendNotification, we are only getting notified when a spend is
mined, as previously btcd would notify on mempool inclusion, while
neutrino and bitcoind would notify only on confirmation, and the test
wouldn't catch this.
This commit adds a boolean to RegisterSpendNtfn, giving the caller the
option to only register for notifications on confirmed spends. This is
implemented for the btcd backend using logic similar to what is in used
for Neutrino, paving the way for later unifying them.
In this commit, we fix an issue where users would be displayed negative
amounts of satoshis either as sent or received. This can happen if the
total amount of channel updates decreases due to channels being closed.
To fix this, we properly handle a negative difference of channel
updates by updating the stats logged to only include active
channels/links to the switch.
In this commit, we modify the docs in order to clarify that both btcd
and bitcoind are supported as chain backends. Many users expressed
confusion as the old set of docs stated that we "require" my btcd fork,
rather than clarifying that *if* you want to use btcd, then you must use
my fork.
In this commit we add a new command line option (and a sane default) to
allow users to specify the *smallest* inbound channel that they'll
accept. Having a higher-ish limit lets users limit their channels, and
also avoid a series of very low value "spam" channels.
The new option is --minchansize, and expressed in satoshis. If we
receive an inbound channel request for a value smaller than this, then
we'll immediately reject it.