mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-03 20:56:42 +00:00

* [NOD-1500] Added Domain type and Constructor * [NOD-1500] Replaced dag+txpool with domain in flowContext * [NOD-1500] Replaced dag+txpool with domain in flowContext * [NOD-1500] Converters: domain objects from/to appmessage * [NOD-1500] Convert hashes to DomainHashes in appmessages * [NOD-1500] Remove references to daghash in dagconfig * [NOD-1500] Fixed all appmessage usages of hashes * [NOD-1500] Update all RPC to use domain * [NOD-1500] Big chunk of protocol flows re-wired to domain * [NOD-1500] Finished re-wiring all protocol flows to new Domain * [NOD-1500] Fix some mempool and kaspaminer compilation errors * [NOD-1500] Deleted util/{block,tx,daghash} and dbaccess * [NOD-1500] util.CoinbaseTransactionIndex -> transactionhelper.CoinbaseTransactionIndex * [NOD-1500] Fix txsigner * [NOD-1500] Removed all references to util/subnetworkid * [NOD-1500] Update RpcGetBlock related messages * [NOD-1500] Many more compilation fixes * [NOD-1500] Return full list of missing blocks for orphan resolution * [NOD-1500] Fixed handshake * [NOD-1500] Fixed flowcontext compilation * [NOD-1500] Update users of StartIBDIfRequired to handle error * [NOD-1500] Removed some more fields from RPC * [NOD-1500] Fix the getBlockTemplate flow * [NOD-1500] Fix HandleGetCurrentNetwork * [NOD-1500] Remove redundant code * [NOD-1500] Remove obsolete notifications * [NOD-1500] Split MiningManager and Consensus to separate fields in Domain * [NOD-1500] Update two wrong references to location of txscript * [NOD-1500] Added comments * [NOD-1500] Fix some tests * [NOD-1500] Removed serialization logic from appmessage * [NOD-1500] Rename database/serialization/messages.proto to dbobjects.proto * [NOD-1500] Delete integration tests * [NOD-1500] Remove txsort * [NOD-1500] Fix tiny bug * [NOD-1500] Remove rogue dependancy on bchd * [NOD-1500] Some stylistic fixes
204 lines
4.3 KiB
Go
204 lines
4.3 KiB
Go
package consensusserialization
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/util/binaryserializer"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var (
|
|
// littleEndian is a convenience variable since binary.LittleEndian is
|
|
// quite long.
|
|
littleEndian = binary.LittleEndian
|
|
|
|
// bigEndian is a convenience variable since binary.BigEndian is quite
|
|
// long.
|
|
bigEndian = binary.BigEndian
|
|
)
|
|
|
|
// errNoEncodingForType signifies that there's no encoding for the given type.
|
|
var errNoEncodingForType = errors.New("there's no encoding for this type")
|
|
|
|
var errMalformed = errors.New("errMalformed")
|
|
|
|
// WriteElement writes the little endian representation of element to w.
|
|
func WriteElement(w io.Writer, element interface{}) error {
|
|
// Attempt to write the element based on the concrete type via fast
|
|
// type assertions first.
|
|
switch e := element.(type) {
|
|
case int32:
|
|
err := binaryserializer.PutUint32(w, littleEndian, uint32(e))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case uint32:
|
|
err := binaryserializer.PutUint32(w, littleEndian, e)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case int64:
|
|
err := binaryserializer.PutUint64(w, littleEndian, uint64(e))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case uint64:
|
|
err := binaryserializer.PutUint64(w, littleEndian, e)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case uint8:
|
|
err := binaryserializer.PutUint8(w, e)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case bool:
|
|
var err error
|
|
if e {
|
|
err = binaryserializer.PutUint8(w, 0x01)
|
|
} else {
|
|
err = binaryserializer.PutUint8(w, 0x00)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case externalapi.DomainHash:
|
|
_, err := w.Write(e[:])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case *externalapi.DomainHash:
|
|
_, err := w.Write(e[:])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case externalapi.DomainSubnetworkID:
|
|
_, err := w.Write(e[:])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
case *externalapi.DomainSubnetworkID:
|
|
_, err := w.Write(e[:])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
return errors.Wrapf(errNoEncodingForType, "couldn't find a way to write type %T", element)
|
|
}
|
|
|
|
// writeElements writes multiple items to w. It is equivalent to multiple
|
|
// calls to writeElement.
|
|
func writeElements(w io.Writer, elements ...interface{}) error {
|
|
for _, element := range elements {
|
|
err := WriteElement(w, element)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// readElement reads the next sequence of bytes from r using little endian
|
|
// depending on the concrete type of element pointed to.
|
|
func readElement(r io.Reader, element interface{}) error {
|
|
// Attempt to read the element based on the concrete type via fast
|
|
// type assertions first.
|
|
switch e := element.(type) {
|
|
case *int32:
|
|
rv, err := binaryserializer.Uint32(r, littleEndian)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*e = int32(rv)
|
|
return nil
|
|
|
|
case *uint32:
|
|
rv, err := binaryserializer.Uint32(r, littleEndian)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*e = rv
|
|
return nil
|
|
|
|
case *int64:
|
|
rv, err := binaryserializer.Uint64(r, littleEndian)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*e = int64(rv)
|
|
return nil
|
|
|
|
case *uint64:
|
|
rv, err := binaryserializer.Uint64(r, littleEndian)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*e = rv
|
|
return nil
|
|
|
|
case *uint8:
|
|
rv, err := binaryserializer.Uint8(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*e = rv
|
|
return nil
|
|
|
|
case *bool:
|
|
rv, err := binaryserializer.Uint8(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if rv == 0x00 {
|
|
*e = false
|
|
} else if rv == 0x01 {
|
|
*e = true
|
|
} else {
|
|
return errors.Wrapf(errMalformed, "in order to keep serialization canonical, true has to"+
|
|
" always be 0x01")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
return errors.Wrapf(errNoEncodingForType, "couldn't find a way to read type %T", element)
|
|
}
|
|
|
|
// readElements reads multiple items from r. It is equivalent to multiple
|
|
// calls to readElement.
|
|
func readElements(r io.Reader, elements ...interface{}) error {
|
|
for _, element := range elements {
|
|
err := readElement(r, element)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IsMalformedError returns whether the error indicates a malformed data source
|
|
func IsMalformedError(err error) bool {
|
|
return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, errMalformed)
|
|
}
|