github.com/decred/dcrlnd@v0.7.6/channeldb/migration_01_to_11/codec.go (about)

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