github.com/decred/dcrlnd@v0.7.6/channeldb/migration21/current/current_codec.go (about) 1 package current 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "io" 8 9 "github.com/decred/dcrd/chaincfg/chainhash" 10 "github.com/decred/dcrd/dcrec/secp256k1/v4" 11 "github.com/decred/dcrd/dcrutil/v4" 12 "github.com/decred/dcrd/wire" 13 lnwire "github.com/decred/dcrlnd/channeldb/migration/lnwire21" 14 "github.com/decred/dcrlnd/channeldb/migration21/common" 15 "github.com/decred/dcrlnd/keychain" 16 "github.com/decred/dcrlnd/shachain" 17 ) 18 19 var ( 20 // Big endian is the preferred byte order, due to cursor scans over 21 // integer keys iterating in order. 22 byteOrder = binary.BigEndian 23 ) 24 25 // writeOutpoint writes an outpoint to the passed writer using the minimal 26 // amount of bytes possible. 27 func writeOutpoint(w io.Writer, o *wire.OutPoint) error { 28 if _, err := w.Write(o.Hash[:]); err != nil { 29 return err 30 } 31 if err := binary.Write(w, byteOrder, o.Index); err != nil { 32 return err 33 } 34 35 // Note: this is decred-only. 36 if err := binary.Write(w, byteOrder, o.Tree); err != nil { 37 return err 38 } 39 40 return nil 41 } 42 43 // readOutpoint reads an outpoint from the passed reader that was previously 44 // written using the writeOutpoint struct. 45 func readOutpoint(r io.Reader, o *wire.OutPoint) error { 46 if _, err := io.ReadFull(r, o.Hash[:]); err != nil { 47 return err 48 } 49 if err := binary.Read(r, byteOrder, &o.Index); err != nil { 50 return err 51 } 52 53 // Note: this is decred-only. 54 if err := binary.Read(r, byteOrder, &o.Tree); err != nil { 55 return err 56 } 57 58 return nil 59 } 60 61 // UnknownElementType is an error returned when the codec is unable to encode or 62 // decode a particular type. 63 type UnknownElementType struct { 64 method string 65 element interface{} 66 } 67 68 // NewUnknownElementType creates a new UnknownElementType error from the passed 69 // method name and element. 70 func NewUnknownElementType(method string, el interface{}) UnknownElementType { 71 return UnknownElementType{method: method, element: el} 72 } 73 74 // Error returns the name of the method that encountered the error, as well as 75 // the type that was unsupported. 76 func (e UnknownElementType) Error() string { 77 return fmt.Sprintf("Unknown type in %s: %T", e.method, e.element) 78 } 79 80 // WriteElement is a one-stop shop to write the big endian representation of 81 // any element which is to be serialized for storage on disk. The passed 82 // io.Writer should be backed by an appropriately sized byte slice, or be able 83 // to dynamically expand to accommodate additional data. 84 func WriteElement(w io.Writer, element interface{}) error { 85 switch e := element.(type) { 86 case keychain.KeyDescriptor: 87 if err := binary.Write(w, byteOrder, e.Family); err != nil { 88 return err 89 } 90 if err := binary.Write(w, byteOrder, e.Index); err != nil { 91 return err 92 } 93 94 if e.PubKey != nil { 95 if err := binary.Write(w, byteOrder, true); err != nil { 96 return fmt.Errorf("error writing serialized element: %s", err) 97 } 98 99 return WriteElement(w, e.PubKey) 100 } 101 102 return binary.Write(w, byteOrder, false) 103 104 case chainhash.Hash: 105 if _, err := w.Write(e[:]); err != nil { 106 return err 107 } 108 109 case wire.OutPoint: 110 return writeOutpoint(w, &e) 111 112 case lnwire.ShortChannelID: 113 if err := binary.Write(w, byteOrder, e.ToUint64()); err != nil { 114 return err 115 } 116 117 case lnwire.ChannelID: 118 if _, err := w.Write(e[:]); err != nil { 119 return err 120 } 121 122 case int64, uint64: 123 if err := binary.Write(w, byteOrder, e); err != nil { 124 return err 125 } 126 127 case uint32: 128 if err := binary.Write(w, byteOrder, e); err != nil { 129 return err 130 } 131 132 case int32: 133 if err := binary.Write(w, byteOrder, e); err != nil { 134 return err 135 } 136 137 case uint16: 138 if err := binary.Write(w, byteOrder, e); err != nil { 139 return err 140 } 141 142 case uint8: 143 if err := binary.Write(w, byteOrder, e); err != nil { 144 return err 145 } 146 147 case bool: 148 if err := binary.Write(w, byteOrder, e); err != nil { 149 return err 150 } 151 152 case dcrutil.Amount: 153 if err := binary.Write(w, byteOrder, uint64(e)); err != nil { 154 return err 155 } 156 157 case lnwire.MilliAtom: 158 if err := binary.Write(w, byteOrder, uint64(e)); err != nil { 159 return err 160 } 161 162 case *secp256k1.PrivateKey: 163 b := e.Serialize() 164 if _, err := w.Write(b); err != nil { 165 return err 166 } 167 168 case *secp256k1.PublicKey: 169 b := e.SerializeCompressed() 170 if _, err := w.Write(b); err != nil { 171 return err 172 } 173 174 case shachain.Producer: 175 return e.Encode(w) 176 177 case shachain.Store: 178 return e.Encode(w) 179 180 case *wire.MsgTx: 181 return e.Serialize(w) 182 183 case [32]byte: 184 if _, err := w.Write(e[:]); err != nil { 185 return err 186 } 187 188 case []byte: 189 if err := wire.WriteVarBytes(w, 0, e); err != nil { 190 return err 191 } 192 193 case lnwire.Message: 194 var msgBuf bytes.Buffer 195 if _, err := lnwire.WriteMessage(&msgBuf, e, 0); err != nil { 196 return err 197 } 198 199 msgLen := uint16(len(msgBuf.Bytes())) 200 if err := WriteElements(w, msgLen); err != nil { 201 return err 202 } 203 204 if _, err := w.Write(msgBuf.Bytes()); err != nil { 205 return err 206 } 207 208 case common.ClosureType: 209 if err := binary.Write(w, byteOrder, e); err != nil { 210 return err 211 } 212 213 case lnwire.FundingFlag: 214 if err := binary.Write(w, byteOrder, e); err != nil { 215 return err 216 } 217 218 default: 219 return UnknownElementType{"WriteElement", e} 220 } 221 222 return nil 223 } 224 225 // WriteElements is writes each element in the elements slice to the passed 226 // io.Writer using WriteElement. 227 func WriteElements(w io.Writer, elements ...interface{}) error { 228 for _, element := range elements { 229 err := WriteElement(w, element) 230 if err != nil { 231 return err 232 } 233 } 234 return nil 235 } 236 237 // ReadElement is a one-stop utility function to deserialize any datastructure 238 // encoded using the serialization format of the database. 239 func ReadElement(r io.Reader, element interface{}) error { 240 switch e := element.(type) { 241 case *keychain.KeyDescriptor: 242 if err := binary.Read(r, byteOrder, &e.Family); err != nil { 243 return err 244 } 245 if err := binary.Read(r, byteOrder, &e.Index); err != nil { 246 return err 247 } 248 249 var hasPubKey bool 250 if err := binary.Read(r, byteOrder, &hasPubKey); err != nil { 251 return err 252 } 253 254 if hasPubKey { 255 return ReadElement(r, &e.PubKey) 256 } 257 258 case *chainhash.Hash: 259 if _, err := io.ReadFull(r, e[:]); err != nil { 260 return err 261 } 262 263 case *wire.OutPoint: 264 return readOutpoint(r, e) 265 266 case *lnwire.ShortChannelID: 267 var a uint64 268 if err := binary.Read(r, byteOrder, &a); err != nil { 269 return err 270 } 271 *e = lnwire.NewShortChanIDFromInt(a) 272 273 case *lnwire.ChannelID: 274 if _, err := io.ReadFull(r, e[:]); err != nil { 275 return err 276 } 277 278 case *int64, *uint64: 279 if err := binary.Read(r, byteOrder, e); err != nil { 280 return err 281 } 282 283 case *uint32: 284 if err := binary.Read(r, byteOrder, e); err != nil { 285 return err 286 } 287 288 case *int32: 289 if err := binary.Read(r, byteOrder, e); err != nil { 290 return err 291 } 292 293 case *uint16: 294 if err := binary.Read(r, byteOrder, e); err != nil { 295 return err 296 } 297 298 case *uint8: 299 if err := binary.Read(r, byteOrder, e); err != nil { 300 return err 301 } 302 303 case *bool: 304 if err := binary.Read(r, byteOrder, e); err != nil { 305 return err 306 } 307 308 case *dcrutil.Amount: 309 var a uint64 310 if err := binary.Read(r, byteOrder, &a); err != nil { 311 return err 312 } 313 314 *e = dcrutil.Amount(a) 315 316 case *lnwire.MilliAtom: 317 var a uint64 318 if err := binary.Read(r, byteOrder, &a); err != nil { 319 return err 320 } 321 322 *e = lnwire.MilliAtom(a) 323 324 case **secp256k1.PrivateKey: 325 var b [secp256k1.PrivKeyBytesLen]byte 326 if _, err := io.ReadFull(r, b[:]); err != nil { 327 return err 328 } 329 330 priv := secp256k1.PrivKeyFromBytes(b[:]) 331 *e = priv 332 333 case **secp256k1.PublicKey: 334 var b [secp256k1.PubKeyBytesLenCompressed]byte 335 if _, err := io.ReadFull(r, b[:]); err != nil { 336 return err 337 } 338 339 pubKey, err := secp256k1.ParsePubKey(b[:]) 340 if err != nil { 341 return err 342 } 343 *e = pubKey 344 345 case *shachain.Producer: 346 var root [32]byte 347 if _, err := io.ReadFull(r, root[:]); err != nil { 348 return err 349 } 350 351 // TODO(roasbeef): remove 352 producer, err := shachain.NewRevocationProducerFromBytes(root[:]) 353 if err != nil { 354 return err 355 } 356 357 *e = producer 358 359 case *shachain.Store: 360 store, err := shachain.NewRevocationStoreFromBytes(r) 361 if err != nil { 362 return err 363 } 364 365 *e = store 366 367 case **wire.MsgTx: 368 tx := wire.NewMsgTx() 369 if err := tx.Deserialize(r); err != nil { 370 return err 371 } 372 373 *e = tx 374 375 case *[32]byte: 376 if _, err := io.ReadFull(r, e[:]); err != nil { 377 return err 378 } 379 380 case *[]byte: 381 bytes, err := wire.ReadVarBytes(r, 0, 66000, "[]byte") 382 if err != nil { 383 return err 384 } 385 386 *e = bytes 387 388 case *lnwire.Message: 389 var msgLen uint16 390 if err := ReadElement(r, &msgLen); err != nil { 391 return err 392 } 393 394 msgReader := io.LimitReader(r, int64(msgLen)) 395 msg, err := lnwire.ReadMessage(msgReader, 0) 396 if err != nil { 397 return err 398 } 399 400 *e = msg 401 402 case *common.ClosureType: 403 if err := binary.Read(r, byteOrder, e); err != nil { 404 return err 405 } 406 407 case *lnwire.FundingFlag: 408 if err := binary.Read(r, byteOrder, e); err != nil { 409 return err 410 } 411 412 default: 413 return UnknownElementType{"ReadElement", e} 414 } 415 416 return nil 417 } 418 419 // ReadElements deserializes a variable number of elements into the passed 420 // io.Reader, with each element being deserialized according to the ReadElement 421 // function. 422 func ReadElements(r io.Reader, elements ...interface{}) error { 423 for _, element := range elements { 424 err := ReadElement(r, element) 425 if err != nil { 426 return err 427 } 428 } 429 return nil 430 }