github.com/decred/dcrlnd@v0.7.6/watchtower/wtdb/codec.go (about)

     1  package wtdb
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/decred/dcrlnd/channeldb"
     7  	"github.com/decred/dcrlnd/lnwallet/chainfee"
     8  	"github.com/decred/dcrlnd/watchtower/blob"
     9  	"github.com/decred/dcrlnd/watchtower/wtpolicy"
    10  )
    11  
    12  // UnknownElementType is an alias for channeldb.UnknownElementType.
    13  type UnknownElementType = channeldb.UnknownElementType
    14  
    15  // ReadElement deserializes a single element from the provided io.Reader.
    16  func ReadElement(r io.Reader, element interface{}) error {
    17  	err := channeldb.ReadElement(r, element)
    18  	switch {
    19  
    20  	// Known to channeldb codec.
    21  	case err == nil:
    22  		return nil
    23  
    24  	// Fail if error is not UnknownElementType.
    25  	default:
    26  		if _, ok := err.(UnknownElementType); !ok {
    27  			return err
    28  		}
    29  	}
    30  
    31  	// Process any wtdb-specific extensions to the codec.
    32  	switch e := element.(type) {
    33  
    34  	case *SessionID:
    35  		if _, err := io.ReadFull(r, e[:]); err != nil {
    36  			return err
    37  		}
    38  
    39  	case *blob.BreachHint:
    40  		if _, err := io.ReadFull(r, e[:]); err != nil {
    41  			return err
    42  		}
    43  
    44  	case *wtpolicy.Policy:
    45  		var (
    46  			blobType     uint16
    47  			sweepFeeRate uint64
    48  		)
    49  		err := channeldb.ReadElements(r,
    50  			&blobType,
    51  			&e.MaxUpdates,
    52  			&e.RewardBase,
    53  			&e.RewardRate,
    54  			&sweepFeeRate,
    55  		)
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		e.BlobType = blob.Type(blobType)
    61  		e.SweepFeeRate = chainfee.AtomPerKByte(sweepFeeRate)
    62  
    63  	// Type is still unknown to wtdb extensions, fail.
    64  	default:
    65  		return channeldb.NewUnknownElementType(
    66  			"ReadElement", element,
    67  		)
    68  	}
    69  
    70  	return nil
    71  }
    72  
    73  // WriteElement serializes a single element into the provided io.Writer.
    74  func WriteElement(w io.Writer, element interface{}) error {
    75  	err := channeldb.WriteElement(w, element)
    76  	switch {
    77  
    78  	// Known to channeldb codec.
    79  	case err == nil:
    80  		return nil
    81  
    82  	// Fail if error is not UnknownElementType.
    83  	default:
    84  		if _, ok := err.(UnknownElementType); !ok {
    85  			return err
    86  		}
    87  	}
    88  
    89  	// Process any wtdb-specific extensions to the codec.
    90  	switch e := element.(type) {
    91  
    92  	case SessionID:
    93  		if _, err := w.Write(e[:]); err != nil {
    94  			return err
    95  		}
    96  
    97  	case blob.BreachHint:
    98  		if _, err := w.Write(e[:]); err != nil {
    99  			return err
   100  		}
   101  
   102  	case wtpolicy.Policy:
   103  		return channeldb.WriteElements(w,
   104  			uint16(e.BlobType),
   105  			e.MaxUpdates,
   106  			e.RewardBase,
   107  			e.RewardRate,
   108  			uint64(e.SweepFeeRate),
   109  		)
   110  
   111  	// Type is still unknown to wtdb extensions, fail.
   112  	default:
   113  		return channeldb.NewUnknownElementType(
   114  			"WriteElement", element,
   115  		)
   116  	}
   117  
   118  	return nil
   119  }
   120  
   121  // WriteElements serializes a variadic list of elements into the given
   122  // io.Writer.
   123  func WriteElements(w io.Writer, elements ...interface{}) error {
   124  	for _, element := range elements {
   125  		if err := WriteElement(w, element); err != nil {
   126  			return err
   127  		}
   128  	}
   129  
   130  	return nil
   131  }
   132  
   133  // ReadElements deserializes the provided io.Reader into a variadic list of
   134  // target elements.
   135  func ReadElements(r io.Reader, elements ...interface{}) error {
   136  	for _, element := range elements {
   137  		if err := ReadElement(r, element); err != nil {
   138  			return err
   139  		}
   140  	}
   141  
   142  	return nil
   143  }