This commit fixes a heap escape found in `GetBlock`. This happens
because the `msgBlock` is a pointer returned from `getBlockImpl`, and
the whole `getBlockImpl` escapes to the heap because it's referenced in
two places,
- in the `Cache`, it's used as a reference type to create the new block.
- this pointer is also returned and now needs to stay on the heap.
The fix is simple, we now make a copy of the block and use the copy
instead, freeing `getBlockImpl` from the heap.
This commit introduces a wrapper function fetchFundingTxWrapper
which calls fetchFundingTx in a goroutine. This is to avoid an issue
with pruned nodes where the router is attempting to stop, but the
prunedBlockDispatcher is waiting to connect to peers that can serve
the block. This can cause the shutdown process to hang until we
connect to a peer that can send us the block.
This is to avoid a potential race on WriteMessage and Flush internals.
Because there is no locking on WriteMessage and Flush, if we allow
writeMessage calls in Start after the writeHandler has started,
the writeMessage calls may call WriteMessage/Flush at the same time
that writeMessage calls from the writeHandler does. Since there is
no locking, internals like b.nextHeaderSend can race and cause
panics.
Without this the following could happen:
* InboundPeerConnected is called while we already have an inbound
connection with the peer. This calls removePeer which calls Disconnect.
* If the peer is starting up in Start, it may be sending messages
synchronously via SendMessage(true, ...). This eventually calls the
writeMessage function which will exit if disconnect is set to 1.
* Since Disconnect was called, disconnect will be 1 and writeMessage
will exit, causing writeHandler to exit.
* If there is more than 1 message being sent, later messages will
queue in queueHandler but be unable to get into sendQueue as the
writeHandler goroutine has exited.
* The synchronous sends will be waiting on the errChan indefinitely
and startReady will never get closed meaning Disconnect will never
proceed.
The end result is that the server's mutex will be held until shutdown.
Avoid this by using writeMessage to bypass the writeHandler goroutine.