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  }