Repository navigation
Expand file tree
/
Copy pathinterface.go
More file actions
150 lines (133 loc) · 3.51 KB
/
Copy pathinterface.go
File metadata and controls
150 lines (133 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package ssz
// Marshaler is the interface implemented by types that can marshal themselves into valid SZZ.
type Marshaler interface {
MarshalSSZTo(dst []byte) ([]byte, error)
MarshalSSZ() ([]byte, error)
SizeSSZ() int
}
type SSZSizer interface {
SizeSSZ() int
}
// Unmarshaler is the interface implemented by types that can unmarshal a SSZ description of themselves
type Unmarshaler interface {
UnmarshalSSZ(buf []byte) error
UnmarshalSSZTail(buf []byte) ([]byte, error)
}
type HashRoot interface {
GetTree() (*Node, error)
HashTreeRoot() ([32]byte, error)
HashTreeRootWith(hh HashWalker) error
}
type HashRootProof interface {
HashTreeRootWith(hh HashWalker) error
}
type HashWalker interface {
// Intended for testing purposes to know the latest hash generated during merkleize
Hash() []byte
AppendUint8(i uint8)
AppendUint16(i uint16)
AppendUint32(i uint32)
AppendUint64(i uint64)
AppendBytes32(b []byte)
PutUint64Array(b []uint64, maxCapacity ...uint64)
PutUint64(i uint64)
PutUint32(i uint32)
PutUint16(i uint16)
PutUint8(i uint8)
FillUpTo32()
Append(i []byte)
PutBitlist(bb []byte, maxSize uint64)
PutBool(b bool)
PutBytes(b []byte)
Index() int
Merkleize(indx int)
MerkleizeWithMixin(indx int, num, limit uint64)
}
type PtrConstraint[T any] interface {
*T
Unmarshaler
SSZSizer
}
func UnmarshalFieldTail[T any, PT PtrConstraint[T]](field *PT, buf []byte) ([]byte, error) {
if *field == nil {
*field = PT(new(T))
}
return (*field).UnmarshalSSZTail(buf)
}
func UnmarshalField[T any, PT PtrConstraint[T]](field *PT, buf []byte) error {
if *field == nil {
*field = PT(new(T))
}
return (*field).UnmarshalSSZ(buf)
}
// UnmarshalSliceWithIndexCallback handles slices with index-aware unmarshal logic
func UnmarshalSliceWithIndexCallback[T any](
slice *[]T,
buf []byte,
itemSize uint64,
maxItems uint64,
unmarshalCallback func(uint64, []byte) error,
) error {
num, err := DivideInt2(uint64(len(buf)), itemSize, maxItems)
if err != nil {
return err
}
*slice = Extend(*slice, num)
for ii := uint64(0); ii < num; ii++ {
start := ii * itemSize
end := (ii + 1) * itemSize
if err := unmarshalCallback(ii, buf[start:end]); err != nil {
return err
}
}
return nil
}
// UnmarshalDynamicSliceWithCallback handles dynamic slices with custom unmarshal logic
func UnmarshalDynamicSliceWithCallback[T any](
slice *[]T,
buf []byte,
maxElements uint64,
unmarshalCallback func(uint64, []byte) error,
) error {
num, err := DecodeDynamicLength(buf, maxElements)
if err != nil {
return err
}
*slice = Extend(*slice, num)
return UnmarshalDynamic(buf, num, unmarshalCallback)
}
func UnmarshalSliceSSZ[T any, PT PtrConstraint[T]](
slice *[]PT,
buf []byte,
maxItems uint64,
) error {
// Create a zero value to get the size
var zero T
var zeroPtr PT = PT(&zero)
itemSize := uint64(zeroPtr.SizeSSZ())
return UnmarshalSliceWithIndexCallback(slice, buf, itemSize, maxItems,
func(ii uint64, itemBuf []byte) error {
return UnmarshalField[T, PT](&(*slice)[ii], itemBuf)
})
}
// UnmarshalDynamicSliceSSZ handles dynamic slices of SSZ types
func UnmarshalDynamicSliceSSZ[T any, PT PtrConstraint[T]](
slice *[]PT,
buf []byte,
maxElements uint64,
) error {
return UnmarshalDynamicSliceWithCallback(slice, buf, maxElements,
func(indx uint64, itemBuf []byte) error {
return UnmarshalField[T, PT](&(*slice)[indx], itemBuf)
})
}
func UnmarshalSSZ(v Unmarshaler, buf []byte) error {
tail, err := v.UnmarshalSSZTail(buf)
if err != nil {
return err
}
if len(tail) != 0 {
return ErrTailNotEmpty
}
return err
}