github.com/amazechain/amc@v0.1.3/internal/p2p/types/types.go (about)

     1  // Package types contains all the respective p2p types that are required for sync
     2  // but cannot be represented as a protobuf schema. This package also contains those
     3  // types associated fast ssz methods.
     4  package p2ptypes
     5  
     6  import (
     7  	"github.com/pkg/errors"
     8  	ssz "github.com/prysmaticlabs/fastssz"
     9  )
    10  
    11  const rootLength = 32
    12  
    13  const maxErrorLength = 256
    14  
    15  // todo
    16  const maxRequestBlocks = 1024
    17  
    18  // SSZBytes is a bytes slice that satisfies the fast-ssz interface.
    19  type SSZBytes []byte
    20  
    21  // HashTreeRoot hashes the uint64 object following the SSZ standard.
    22  func (b *SSZBytes) HashTreeRoot() ([32]byte, error) {
    23  	return ssz.HashWithDefaultHasher(b)
    24  }
    25  
    26  // HashTreeRootWith hashes the uint64 object with the given hasher.
    27  func (b *SSZBytes) HashTreeRootWith(hh *ssz.Hasher) error {
    28  	indx := hh.Index()
    29  	hh.PutBytes(*b)
    30  	hh.Merkleize(indx)
    31  	return nil
    32  }
    33  
    34  // BlockByRootsReq specifies the block by roots request type.
    35  type BlockByRootsReq [][rootLength]byte
    36  
    37  // MarshalSSZTo marshals the block by roots request with the provided byte slice.
    38  func (r *BlockByRootsReq) MarshalSSZTo(dst []byte) ([]byte, error) {
    39  	marshalledObj, err := r.MarshalSSZ()
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	return append(dst, marshalledObj...), nil
    44  }
    45  
    46  // MarshalSSZ Marshals the block by roots request type into the serialized object.
    47  func (r *BlockByRootsReq) MarshalSSZ() ([]byte, error) {
    48  	if len(*r) > maxRequestBlocks {
    49  		return nil, errors.Errorf("block by roots request exceeds max size: %d > %d", len(*r), maxRequestBlocks)
    50  	}
    51  	buf := make([]byte, 0, r.SizeSSZ())
    52  	for _, r := range *r {
    53  		buf = append(buf, r[:]...)
    54  	}
    55  	return buf, nil
    56  }
    57  
    58  // SizeSSZ returns the size of the serialized representation.
    59  func (r *BlockByRootsReq) SizeSSZ() int {
    60  	return len(*r) * rootLength
    61  }
    62  
    63  // UnmarshalSSZ unmarshals the provided bytes buffer into the
    64  // block by roots request object.
    65  func (r *BlockByRootsReq) UnmarshalSSZ(buf []byte) error {
    66  	bufLen := len(buf)
    67  	maxLength := maxRequestBlocks * rootLength
    68  	if bufLen > maxLength {
    69  		return errors.Errorf("expected buffer with length of upto %d but received length %d", maxLength, bufLen)
    70  	}
    71  	if bufLen%rootLength != 0 {
    72  		return ssz.ErrIncorrectByteSize
    73  	}
    74  	numOfRoots := bufLen / rootLength
    75  	roots := make([][rootLength]byte, 0, numOfRoots)
    76  	for i := 0; i < numOfRoots; i++ {
    77  		var rt [rootLength]byte
    78  		copy(rt[:], buf[i*rootLength:(i+1)*rootLength])
    79  		roots = append(roots, rt)
    80  	}
    81  	*r = roots
    82  	return nil
    83  }
    84  
    85  // ErrorMessage describes the error message type.
    86  type ErrorMessage []byte
    87  
    88  // MarshalSSZTo marshals the error message with the provided byte slice.
    89  func (m *ErrorMessage) MarshalSSZTo(dst []byte) ([]byte, error) {
    90  	marshalledObj, err := m.MarshalSSZ()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	return append(dst, marshalledObj...), nil
    95  }
    96  
    97  // MarshalSSZ Marshals the error message into the serialized object.
    98  func (m *ErrorMessage) MarshalSSZ() ([]byte, error) {
    99  	if len(*m) > maxErrorLength {
   100  		return nil, errors.Errorf("error message exceeds max size: %d > %d", len(*m), maxErrorLength)
   101  	}
   102  	buf := make([]byte, m.SizeSSZ())
   103  	copy(buf, *m)
   104  	return buf, nil
   105  }
   106  
   107  // SizeSSZ returns the size of the serialized representation.
   108  func (m *ErrorMessage) SizeSSZ() int {
   109  	return len(*m)
   110  }
   111  
   112  // UnmarshalSSZ unmarshals the provided bytes buffer into the
   113  // error message object.
   114  func (m *ErrorMessage) UnmarshalSSZ(buf []byte) error {
   115  	bufLen := len(buf)
   116  	maxLength := maxErrorLength
   117  	if bufLen > maxLength {
   118  		return errors.Errorf("expected buffer with length of upto %d but received length %d", maxLength, bufLen)
   119  	}
   120  	errMsg := make([]byte, bufLen)
   121  	copy(errMsg, buf)
   122  	*m = errMsg
   123  	return nil
   124  }