github.com/decred/dcrlnd@v0.7.6/channeldb/channel_reestablish.go (about)

     1  package channeldb
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/btcsuite/btcwallet/walletdb"
     7  	"github.com/decred/dcrlnd/kvdb"
     8  	"github.com/decred/dcrlnd/lnwire"
     9  )
    10  
    11  var (
    12  	// chanReestablishWaitTimeBucket is a bucket that stores the total
    13  	// elapsed time that has been spent waiting for a channel reestablish
    14  	// message while a peer has been online.
    15  	//
    16  	// Keys are ShortChannelID, values are time.Duration.
    17  	chanReestablishWaitTimeBucket = []byte("chan-reestablish-wait-time")
    18  )
    19  
    20  // shortChanIDToBytes encodes a short channel id as a byte slice.
    21  func shortChanIDToBytes(s lnwire.ShortChannelID) []byte {
    22  	var b [8]byte
    23  	byteOrder.PutUint64(b[:], s.ToUint64())
    24  	return b[:]
    25  }
    26  
    27  // readChanReestablishWaitTime decodes a value from the
    28  // chanReestablishWaitTimeBucket bucket.
    29  func readChanReestablishWaitTime(v []byte) time.Duration {
    30  	if len(v) < 8 {
    31  		return 0
    32  	}
    33  	return time.Duration(byteOrder.Uint64(v))
    34  }
    35  
    36  // putChanReestablishWaitTime stores a value in the chanReestablishWaitTimeBucket.
    37  func putChanReestablishWaitTime(bucket walletdb.ReadWriteBucket, key []byte, v time.Duration) error {
    38  	var b [8]byte
    39  	byteOrder.PutUint64(b[:], uint64(v))
    40  	return bucket.Put(key, b[:])
    41  }
    42  
    43  // AddToChanReestablishWaitTime adds the passed waitTime interval to the
    44  // total time that a peer has been online without reestablishing the passed
    45  // channel.
    46  func (d *ChannelStateDB) AddToChanReestablishWaitTime(chanID lnwire.ShortChannelID, waitTime time.Duration) error {
    47  	return kvdb.Update(d.backend, func(tx kvdb.RwTx) error {
    48  		bucket := tx.ReadWriteBucket(chanReestablishWaitTimeBucket)
    49  		if bucket == nil {
    50  			var err error
    51  			bucket, err = tx.CreateTopLevelBucket(chanReestablishWaitTimeBucket)
    52  			if err != nil {
    53  				return err
    54  			}
    55  		}
    56  
    57  		// Read the existing wait time from the DB.
    58  		key := shortChanIDToBytes(chanID)
    59  
    60  		// Store current+additional wait time.
    61  		current := readChanReestablishWaitTime(bucket.Get(key))
    62  		newWaitTime := current + waitTime
    63  		return putChanReestablishWaitTime(bucket, key, newWaitTime)
    64  	}, func() {})
    65  }
    66  
    67  // ResetChanReestablishWaitTime zeros the time that a peer has spent online
    68  // while not reestablishing a channel.  This is called when a channel has been
    69  // successfully reestablished.
    70  func (d *ChannelStateDB) ResetChanReestablishWaitTime(chanID lnwire.ShortChannelID) error {
    71  	return kvdb.Update(d.backend, func(tx kvdb.RwTx) error {
    72  		var err error
    73  		bucket := tx.ReadWriteBucket(chanReestablishWaitTimeBucket)
    74  		if bucket == nil {
    75  			bucket, err = tx.CreateTopLevelBucket(chanReestablishWaitTimeBucket)
    76  			if err != nil {
    77  				return err
    78  			}
    79  		}
    80  
    81  		key := shortChanIDToBytes(chanID)
    82  		return putChanReestablishWaitTime(bucket, key, 0)
    83  	}, func() {})
    84  }
    85  
    86  // GetChanReestablishWaitTime returns the total time (across all connections)
    87  // that a peer has been online while NOT reestablishing a channel.
    88  func (d *ChannelStateDB) GetChanReestablishWaitTime(chanID lnwire.ShortChannelID) (waitTime time.Duration, err error) {
    89  	err = kvdb.View(d.backend, func(tx kvdb.RTx) error {
    90  		bucket := tx.ReadBucket(chanReestablishWaitTimeBucket)
    91  		if bucket == nil {
    92  			return nil
    93  		}
    94  
    95  		key := shortChanIDToBytes(chanID)
    96  		waitTime = readChanReestablishWaitTime(bucket.Get(key))
    97  		return nil
    98  	}, func() {})
    99  	return
   100  }