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 }