github.com/decred/dcrlnd@v0.7.6/watchtower/wtwire/wtwire.go (about) 1 package wtwire 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 8 "github.com/decred/dcrd/chaincfg/chainhash" 9 "github.com/decred/dcrd/dcrec/secp256k1/v4" 10 "github.com/decred/dcrd/wire" 11 "github.com/decred/dcrlnd/lnwallet/chainfee" 12 "github.com/decred/dcrlnd/lnwire" 13 "github.com/decred/dcrlnd/watchtower/blob" 14 ) 15 16 // WriteElement is a one-stop shop to write the big endian representation of 17 // any element which is to be serialized for the wire protocol. The passed 18 // io.Writer should be backed by an appropriately sized byte slice, or be able 19 // to dynamically expand to accommodate additional data. 20 func WriteElement(w io.Writer, element interface{}) error { 21 switch e := element.(type) { 22 case uint8: 23 var b [1]byte 24 b[0] = e 25 if _, err := w.Write(b[:]); err != nil { 26 return err 27 } 28 29 case uint16: 30 var b [2]byte 31 binary.BigEndian.PutUint16(b[:], e) 32 if _, err := w.Write(b[:]); err != nil { 33 return err 34 } 35 36 case blob.Type: 37 var b [2]byte 38 binary.BigEndian.PutUint16(b[:], uint16(e)) 39 if _, err := w.Write(b[:]); err != nil { 40 return err 41 } 42 43 case uint32: 44 var b [4]byte 45 binary.BigEndian.PutUint32(b[:], e) 46 if _, err := w.Write(b[:]); err != nil { 47 return err 48 } 49 50 case uint64: 51 var b [8]byte 52 binary.BigEndian.PutUint64(b[:], e) 53 if _, err := w.Write(b[:]); err != nil { 54 return err 55 } 56 57 case [16]byte: 58 if _, err := w.Write(e[:]); err != nil { 59 return err 60 } 61 62 case [32]byte: 63 if _, err := w.Write(e[:]); err != nil { 64 return err 65 } 66 67 case [33]byte: 68 if _, err := w.Write(e[:]); err != nil { 69 return err 70 } 71 72 case []byte: 73 if err := wire.WriteVarBytes(w, 0, e); err != nil { 74 return err 75 } 76 77 case chainfee.AtomPerKByte: 78 var b [8]byte 79 binary.BigEndian.PutUint64(b[:], uint64(e)) 80 if _, err := w.Write(b[:]); err != nil { 81 return err 82 } 83 84 case ErrorCode: 85 var b [2]byte 86 binary.BigEndian.PutUint16(b[:], uint16(e)) 87 if _, err := w.Write(b[:]); err != nil { 88 return err 89 } 90 91 case chainhash.Hash: 92 if _, err := w.Write(e[:]); err != nil { 93 return err 94 } 95 96 case *lnwire.RawFeatureVector: 97 if e == nil { 98 return fmt.Errorf("cannot write nil feature vector") 99 } 100 101 if err := e.Encode(w); err != nil { 102 return err 103 } 104 105 case *secp256k1.PublicKey: 106 if e == nil { 107 return fmt.Errorf("cannot write nil pubkey") 108 } 109 110 var b [33]byte 111 serializedPubkey := e.SerializeCompressed() 112 copy(b[:], serializedPubkey) 113 if _, err := w.Write(b[:]); err != nil { 114 return err 115 } 116 117 default: 118 return fmt.Errorf("unknown type in WriteElement: %T", e) 119 } 120 121 return nil 122 } 123 124 // WriteElements is writes each element in the elements slice to the passed 125 // io.Writer using WriteElement. 126 func WriteElements(w io.Writer, elements ...interface{}) error { 127 for _, element := range elements { 128 err := WriteElement(w, element) 129 if err != nil { 130 return err 131 } 132 } 133 return nil 134 } 135 136 // ReadElement is a one-stop utility function to deserialize any datastructure 137 // encoded using the serialization format of lnwire. 138 func ReadElement(r io.Reader, element interface{}) error { 139 switch e := element.(type) { 140 case *uint8: 141 var b [1]uint8 142 if _, err := r.Read(b[:]); err != nil { 143 return err 144 } 145 *e = b[0] 146 147 case *uint16: 148 var b [2]byte 149 if _, err := io.ReadFull(r, b[:]); err != nil { 150 return err 151 } 152 *e = binary.BigEndian.Uint16(b[:]) 153 154 case *blob.Type: 155 var b [2]byte 156 if _, err := io.ReadFull(r, b[:]); err != nil { 157 return err 158 } 159 *e = blob.Type(binary.BigEndian.Uint16(b[:])) 160 161 case *uint32: 162 var b [4]byte 163 if _, err := io.ReadFull(r, b[:]); err != nil { 164 return err 165 } 166 *e = binary.BigEndian.Uint32(b[:]) 167 168 case *uint64: 169 var b [8]byte 170 if _, err := io.ReadFull(r, b[:]); err != nil { 171 return err 172 } 173 *e = binary.BigEndian.Uint64(b[:]) 174 175 case *[16]byte: 176 if _, err := io.ReadFull(r, e[:]); err != nil { 177 return err 178 } 179 180 case *[32]byte: 181 if _, err := io.ReadFull(r, e[:]); err != nil { 182 return err 183 } 184 185 case *[33]byte: 186 if _, err := io.ReadFull(r, e[:]); err != nil { 187 return err 188 } 189 190 case *[]byte: 191 bytes, err := wire.ReadVarBytes(r, 0, 66000, "[]byte") 192 if err != nil { 193 return err 194 } 195 *e = bytes 196 197 case *chainfee.AtomPerKByte: 198 var b [8]byte 199 if _, err := io.ReadFull(r, b[:]); err != nil { 200 return err 201 } 202 *e = chainfee.AtomPerKByte(binary.BigEndian.Uint64(b[:])) 203 204 case *ErrorCode: 205 var b [2]byte 206 if _, err := io.ReadFull(r, b[:]); err != nil { 207 return err 208 } 209 *e = ErrorCode(binary.BigEndian.Uint16(b[:])) 210 211 case *chainhash.Hash: 212 if _, err := io.ReadFull(r, e[:]); err != nil { 213 return err 214 } 215 216 case **lnwire.RawFeatureVector: 217 f := lnwire.NewRawFeatureVector() 218 err := f.Decode(r) 219 if err != nil { 220 return err 221 } 222 223 *e = f 224 225 case **secp256k1.PublicKey: 226 var b [secp256k1.PubKeyBytesLenCompressed]byte 227 228 if _, err := io.ReadFull(r, b[:]); err != nil { 229 return err 230 } 231 232 pubKey, err := secp256k1.ParsePubKey(b[:]) 233 if err != nil { 234 return err 235 } 236 *e = pubKey 237 238 default: 239 return fmt.Errorf("unknown type in ReadElement: %T", e) 240 } 241 242 return nil 243 } 244 245 // ReadElements deserializes a variable number of elements into the passed 246 // io.Reader, with each element being deserialized according to the ReadElement 247 // function. 248 func ReadElements(r io.Reader, elements ...interface{}) error { 249 for _, element := range elements { 250 err := ReadElement(r, element) 251 if err != nil { 252 return err 253 } 254 } 255 return nil 256 }