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.
This commit is contained in:
Olaoluwa Osuntokun committed 2017-11-10 19:51:02 -08:00
1 parent 70ed50738a
commit de3af9b0c0
3 files changed
+29 -48

No files matched your search

+16
View File
@@ -3,6 +3,8 @@ package htlcswitch
import (
"sync"
"sync/atomic"
"github.com/lightningnetwork/lnd/lnwire"
)
// packetQueue is an goroutine-safe queue of htlc packets which over flow the
@@ -23,6 +25,11 @@ type packetQueue struct {
// with the lock held.
queueLen int32
// totalHtlcAmt is the sum of the value of all pending HTLC's currently
// residing within the overflow queue. This value should only read or
// modified *atomically*.
totalHtlcAmt int64
queueCond *sync.Cond
queueMtx sync.Mutex
queue []*htlcPacket
@@ -125,6 +132,7 @@ func (p *packetQueue) packetCoordinator() {
p.queue[0] = nil
p.queue = p.queue[1:]
atomic.AddInt32(&p.queueLen, -1)
atomic.AddInt64(&p.totalHtlcAmt, int64(-nextPkt.amount))
p.queueCond.L.Unlock()
case <-p.quit:
return
@@ -147,6 +155,7 @@ func (p *packetQueue) AddPkt(pkt *htlcPacket) {
p.queueCond.L.Lock()
p.queue = append(p.queue, pkt)
atomic.AddInt32(&p.queueLen, 1)
atomic.AddInt64(&p.totalHtlcAmt, int64(pkt.amount))
p.queueCond.L.Unlock()
// With the message added, we signal to the msgConsumer that there are
@@ -180,3 +189,10 @@ func (p *packetQueue) SignalFreeSlot() {
func (p *packetQueue) Length() int32 {
return atomic.LoadInt32(&p.queueLen)
}
// TotalHtlcAmount is the total amount (in mSAT) of all HTLC's currently
// residing within the overflow queue.
func (p *packetQueue) TotalHtlcAmount() lnwire.MilliSatoshi {
// TODO(roasbeef): also factor in fee rate?
return lnwire.MilliSatoshi(atomic.LoadInt64(&p.totalHtlcAmt))
}