htlcswitch: fix issues with forwarding stats logger display

This commit fixes some issues in the display of the stats logger which
resulted in: stats being printed even though no forwarding activity
took place, and underflow of integers resulting in weird outputs when
forwarding.

This commit also adds some additional comments and renames the main
forwarding goroutine to its former name.
This commit is contained in:
Olaoluwa Osuntokun 2017-05-31 16:16:52 -07:00
parent 1aaf37974a
commit 048e4c0a39
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

@ -83,11 +83,14 @@ type Config struct {
LocalChannelClose func(pubKey []byte, request *ChanClose)
}
// Switch is a central messaging bus for all incoming/outgoing htlc's.
// The goal of the switch is forward the incoming/outgoing htlc messages from
// one channel to another, and also propagate the settle/fail htlc messages
// back to original requester by using payment circuits. Also switch is
// responsible for notifying the user about result of payment request.
// htlcSwitch is a central messaging bus for all incoming/outgoing HTLCs.
// Connected peers with active channels are treated as named interfaces which
// refer to active channels as links. A link is the switch's message
// communication point with the goroutine that manages an active channel. New
// links are registered each time a channel is created, and unregistered once
// the channel is closed. The switch manages the hand-off process for multi-hop
// HTLCs, forwarding HTLCs initiated from within the daemon, and finally
// notifies users local-systems concerning their outstanding payment requests.
type Switch struct {
started int32
shutdown int32
@ -491,13 +494,20 @@ func (s *Switch) handleChanelClose(req *ChanClose) {
return
}
// startHandling start handling inner command requests and print the
// htlc switch statistics.
// NOTE: Should be run as goroutine.
func (s *Switch) startHandling() {
// htlcForwarder is responsible for optimally forwarding (and possibly
// fragmenting) incoming/outgoing HTLCs amongst all active interfaces and their
// links. The duties of the forwarder are similar to that of a network switch,
// in that it facilitates multi-hop payments by acting as a central messaging
// bus. The switch communicates will active links to create, manage, and tear
// down active onion routed payments. Each active channel is modeled as
// networked device with metadata such as the available payment bandwidth, and
// total link capacity.
//
// NOTE: This MUST be run as a goroutine.
func (s *Switch) htlcForwarder() {
defer s.wg.Done()
// Remove all links on stop.
// Remove all links once we've been signalled for shutdown.
defer func() {
for _, link := range s.links {
if err := s.removeLink(link.ChanID()); err != nil {
@ -508,9 +518,13 @@ func (s *Switch) startHandling() {
}()
// TODO(roasbeef): cleared vs settled distinction
var prevNumUpdates uint64
var prevSatSent btcutil.Amount
var prevSatRecv btcutil.Amount
var (
totalNumUpdates uint64
totalSatSent btcutil.Amount
totalSatRecv btcutil.Amount
)
logTicker := time.NewTicker(10 * time.Second)
defer logTicker.Stop()
for {
select {
@ -540,33 +554,68 @@ func (s *Switch) startHandling() {
cmd.err <- s.handleLocalDispatch(payment, cmd.pkt)
}
case <-time.Tick(10 * time.Second):
var overallNumUpdates uint64
var overallSatSent btcutil.Amount
var overallSatRecv btcutil.Amount
// The log ticker has fired, so we'll calculate some forwarding
// stats for the last 10 seconds to display within the logs to
// users.
case <-logTicker.C:
// First, we'll collate the current running tally of
// our forwarding stats.
prevSatSent := totalSatSent
prevSatRecv := totalSatRecv
prevNumUpdates := totalNumUpdates
var (
newNumUpdates uint64
newSatSent btcutil.Amount
newSatRecv btcutil.Amount
)
// Next, we'll run through all the registered links and
// compute their up-to-date forwarding stats.
for _, link := range s.links {
// TODO(roasbeef): when links first registered
// stats printed.
updates, sent, recv := link.Stats()
overallNumUpdates += updates
overallSatSent += sent
overallSatRecv += recv
newNumUpdates += updates
newSatSent += sent
newSatRecv += recv
}
diffNumUpdates := overallNumUpdates - prevNumUpdates
diffSatSent := overallSatSent - prevSatSent
diffSatRecv := overallSatRecv - prevSatRecv
var (
diffNumUpdates uint64
diffSatSent btcutil.Amount
diffSatRecv btcutil.Amount
)
// If this is the first time we're computing these
// stats, then the diff is just the new value. We do
// this in order to avoid integer underflow issues.
if prevNumUpdates == 0 {
diffNumUpdates = newNumUpdates
diffSatSent = newSatSent
diffSatRecv = newSatRecv
} else {
diffNumUpdates = newNumUpdates - prevNumUpdates
diffSatSent = newSatSent - prevSatSent
diffSatRecv = newSatRecv - prevSatRecv
}
// If the diff of num updates is zero, then we haven't
// forwarded anything in the last 10 seconds, so we can
// skip this update.
if diffNumUpdates == 0 {
continue
}
log.Infof("sent %v satoshis received %v satoshi "+
// Otherwise, we'll log this diff, then accumulate the
// new stats into the running total.
log.Infof("Sent %v satoshis received %v satoshi "+
" in the last 10 seconds (%v tx/sec)",
diffSatSent, diffSatRecv, float64(diffNumUpdates)/10)
prevNumUpdates = overallNumUpdates
prevSatSent = overallSatSent
prevSatRecv = overallSatRecv
totalNumUpdates += diffNumUpdates
totalSatSent += diffSatSent
totalSatRecv += diffSatRecv
case cmd := <-s.linkControl:
switch cmd := cmd.(type) {
@ -597,10 +646,10 @@ func (s *Switch) Start() error {
return nil
}
log.Infof("Htlc Switch starting")
log.Infof("Starting HTLC Switch")
s.wg.Add(1)
go s.startHandling()
go s.htlcForwarder()
return nil
}
@ -613,7 +662,7 @@ func (s *Switch) Stop() error {
return nil
}
log.Infof("Htlc Switch shutting down")
log.Infof("HLTC Switch shutting down")
close(s.quit)
s.wg.Wait()