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  }