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 }