This commit fixes a possible deadlock within the packetQueue that could
be caused by the following circular waiting dependency:
packetCoordinator woken up, grabs lock, queue isn’t empty, attempts to
send packet to link (lock still held) -> channelLink has commitment
overflow, attempts to add new item to packet queue, in AddPkt grabs
Lock -> circular wait.
We avoid this scenario by *not* holding the lock within the
packetCoordinator when we attempt to send a new packet to the switch.
Instead, we release the lock before the second select statement in the
main processing loop.
In this commit, we’ve moved away from the internal queryHandler within
the packetQueue entirely. We now use an internal queueLen variable
internally to allow callers to sample the queue’s size, and also for
synchronization purposes internally.
This commit also introduces a chan struct{} (freeSlots) that is used
internally as a semaphore. The current value of freeSlots reflects the
number of available slots within the commitment transaction. Within the
link, after an HTLC has been removed/modified, then a “slot” is freed
up. The main packetConsumer then interprets these messages as a signal
to attempt to free up a new slot within the queue itself by dumping off
to the commitment transaction.
This commit removes the internal queryHandler within the packetQueue
itself in order to make way for an upcoming commit which uses atomic
variables to report the length of the queue to outside callers.
Additionally, due to the recent change within the channeling, we no
longer need to report the total value of all pending HTLC’s to the
outside world.
This commit completes a full re-write of the link’s packet overflow
queue with the goals of the making the code itself more understandable
and also allowing it to be more extensible in the future with various
algorithms for handling HTLC congestion avoidance and persistent queue
back pressure.
The new design is simpler and consumes much less coroutines (no longer
a new goroutine for each active HLTC). We now implement a simple
synchronized queue using a standard condition variable.
In this commit pending packet queue have been added. This queue
consumes the htlc packet, store it inside the golang list and send it
to the pending channel upon release notification.