mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-24 06:47:44 +01:00
In preparation for the commit which will add the main logic for migration 32 (which will migrate the MC store to use a more minimal encoding), this commit just adds some of the code that the migration will need to the package.
146 lines
3.2 KiB
Go
146 lines
3.2 KiB
Go
package migration32
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
lnwire "github.com/lightningnetwork/lnd/channeldb/migration/lnwire21"
|
|
)
|
|
|
|
var (
|
|
// Big endian is the preferred byte order, due to cursor scans over
|
|
// integer keys iterating in order.
|
|
byteOrder = binary.BigEndian
|
|
)
|
|
|
|
// ReadElement is a one-stop utility function to deserialize any datastructure
|
|
// encoded using the serialization format of the database.
|
|
func ReadElement(r io.Reader, element interface{}) error {
|
|
switch e := element.(type) {
|
|
case *uint32:
|
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case *lnwire.MilliSatoshi:
|
|
var a uint64
|
|
if err := binary.Read(r, byteOrder, &a); err != nil {
|
|
return err
|
|
}
|
|
|
|
*e = lnwire.MilliSatoshi(a)
|
|
|
|
case *[]byte:
|
|
bytes, err := wire.ReadVarBytes(r, 0, 66000, "[]byte")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*e = bytes
|
|
|
|
case *int64, *uint64:
|
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case *bool:
|
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case *int32:
|
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
default:
|
|
return UnknownElementType{"ReadElement", e}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ReadElements deserializes a variable number of elements into the passed
|
|
// io.Reader, with each element being deserialized according to the ReadElement
|
|
// function.
|
|
func ReadElements(r io.Reader, elements ...interface{}) error {
|
|
for _, element := range elements {
|
|
err := ReadElement(r, element)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// UnknownElementType is an error returned when the codec is unable to encode or
|
|
// decode a particular type.
|
|
type UnknownElementType struct {
|
|
method string
|
|
element interface{}
|
|
}
|
|
|
|
// Error returns the name of the method that encountered the error, as well as
|
|
// the type that was unsupported.
|
|
func (e UnknownElementType) Error() string {
|
|
return fmt.Sprintf("Unknown type in %s: %T", e.method, e.element)
|
|
}
|
|
|
|
// WriteElement is a one-stop shop to write the big endian representation of
|
|
// any element which is to be serialized for storage on disk. The passed
|
|
// io.Writer should be backed by an appropriately sized byte slice, or be able
|
|
// to dynamically expand to accommodate additional data.
|
|
func WriteElement(w io.Writer, element interface{}) error {
|
|
switch e := element.(type) {
|
|
case int64, uint64:
|
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case uint32:
|
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case int32:
|
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case bool:
|
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
case lnwire.MilliSatoshi:
|
|
if err := binary.Write(w, byteOrder, uint64(e)); err != nil {
|
|
return err
|
|
}
|
|
|
|
case []byte:
|
|
if err := wire.WriteVarBytes(w, 0, e); err != nil {
|
|
return err
|
|
}
|
|
|
|
default:
|
|
return UnknownElementType{"WriteElement", e}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// WriteElements is writes each element in the elements slice to the passed
|
|
// io.Writer using WriteElement.
|
|
func WriteElements(w io.Writer, elements ...interface{}) error {
|
|
for _, element := range elements {
|
|
err := WriteElement(w, element)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|