Commit Graph

10 Commits

Author SHA1 Message Date
Olaoluwa Osuntokun
151a4325b1
htlcswitch: fix alignment of the packetQueue's fields for 32-bit systems (#507)
In this commit, we fix an existing issue that would cause lnd to panic
on 32-bit systems. Within the packetQueue we utilize atomics heavily.
However, it's the caller's job to ensure 64-bit alignment of 64-bit words
accessed atomically. This is documented within the sync/atomic package
as a set of known bugs.

The old alignment of this struct was:

⛰  structlayout github.com/lightningnetwork/lnd/htlcswitch packetQueue
packetQueue.queueLen int32: 0-4 (size 4, align 4)
padding: 4-8 (size 4, align 0)
packetQueue.totalHtlcAmt int64: 8-16 (size 8, align 8)
packetQueue.queueCond *sync.Cond: 16-24 (size 8, align 8)
packetQueue.queueMtx.state int32: 24-28 (size 4, align 4)
packetQueue.queueMtx.sema uint32: 28-32 (size 4, align 4)
packetQueue.queue []*github.com/lightningnetwork/lnd/htlcswitch.htlcPacket: 32-56 (size 24, align 8)
packetQueue.outgoingPkts chan *github.com/lightningnetwork/lnd/htlcswitch.htlcPacket: 56-64 (size 8, align 8)
packetQueue.freeSlots chan struct{}: 64-72 (size 8, align 8)
packetQueue.wg.noCopy sync.noCopy: 72-72 (size 0, align 1)
packetQueue.wg.state1 [12]byte: 72-84 (size 12, align 1)
packetQueue.wg.sema uint32: 84-88 (size 4, align 4)
packetQueue.quit chan struct{}: 88-96 (size 8, align 8)

After this commit, the new alignment of this sturct is:

⛰  structlayout  -json github.com/lightningnetwork/lnd/htlcswitch packetQueue | structlayout-optimize
packetQueue.queue []*github.com/lightningnetwork/lnd/htlcswitch.htlcPacket: 0-24 (size 24, align 8)
packetQueue.wg struct: 24-40 (size 16, align 8)
packetQueue.freeSlots chan struct{}: 40-48 (size 8, align 8)
packetQueue.queueCond *sync.Cond: 48-56 (size 8, align 8)
packetQueue.queueMtx struct: 56-64 (size 8, align 8)
packetQueue.outgoingPkts chan *github.com/lightningnetwork/lnd/htlcswitch.htlcPacket: 64-72 (size 8, align 8)
packetQueue.totalHtlcAmt int64: 72-80 (size 8, align 8)
packetQueue.quit chan struct{}: 80-88 (size 8, align 8)
packetQueue.queueLen int32: 88-92 (size 4, align 8)
padding: 92-96 (size 4, align 0)

Fixes #505, and #463.
2017-12-22 16:32:11 +01:00
Olaoluwa Osuntokun
de3af9b0c0
htlcswitch: modify Bandwidth() method on links to use more accurate accoutning
In this commit, we modify the existing implementation of the
Bandwidth() method on the default ChannelLink implementation to use
much tighter accounting. Before this commit, there was a bug wherein if
the link restarted with pending un-settled HTLC’s, and one of them was
settled, then the bandwidth wouldn’t properly be updated to reflect
this fact.

To fix this, we’ve done away with the manual accounting and instead
grab the current balances from two sources: the set of active HTLC’s
within the overflow queue, and the report from the link itself which
includes the pending HTLC’s and factors in the amount we’d need to (or
not need to) pay in fees for each HTLC.
2017-11-10 19:51:02 -08:00
Olaoluwa Osuntokun
5ec3ee2ece
htlcswitch: expand TestWaitingQueueThreadSafety to assert proper queue length 2017-09-25 16:55:18 -07:00
Olaoluwa Osuntokun
97e730cf51
htlcswitch: fix possible deadlock bug in packetQueue
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.
2017-09-25 15:59:31 -07:00
Olaoluwa Osuntokun
be5b2d46a5
htlcswitch: ensure the packetQueue can handle total+partial commitment overflows
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.
2017-09-25 12:47:34 -07:00
Olaoluwa Osuntokun
210fc6e714
htlcswitch: eliminate internal queryHandler within packetQueue
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.
2017-09-25 12:34:56 -07:00
Olaoluwa Osuntokun
6f5ef249e4
htlcswitch: re-write link's packet overflow queue for readability+extensibility
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.
2017-09-22 15:54:16 -07:00
Olaoluwa Osuntokun
8a51b1a0c6
Htlcswitch: switch all accounting and forwarding decisions to use mSAT's 2017-08-22 00:53:04 -07:00
Olaoluwa Osuntokun
1f5a4fcb8e
htlcswitch: change over all internal indexes to use short channel ID's 2017-06-16 23:49:46 +02:00
Andrey Samokhvalov
22d90d6b35 htlcswitch: add packet queue
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.
2017-05-31 11:06:08 -07:00