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