-
Notifications
You must be signed in to change notification settings - Fork 8
/
sizer.go
91 lines (79 loc) · 2.71 KB
/
sizer.go
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
// ssz: Go Simple Serialize (SSZ) codec library
// Copyright 2024 ssz Authors
// SPDX-License-Identifier: BSD-3-Clause
package ssz
import (
"github.com/prysmaticlabs/go-bitfield"
)
// Sizer is an SSZ static and dynamic size computer.
type Sizer struct {
codec *Codec // Self-referencing to have access to fork contexts
}
// Fork retrieves the current fork (if any) that the sizer is operating in.
func (siz *Sizer) Fork() Fork {
return siz.codec.fork
}
// SizeDynamicBytes returns the serialized size of the dynamic part of a dynamic
// blob.
func SizeDynamicBytes(siz *Sizer, blobs []byte) uint32 {
return uint32(len(blobs))
}
// SizeSliceOfBits returns the serialized size of the dynamic part of a slice of
// bits.
//
// Note, a nil slice of bits is sized as an empty bit list.
func SizeSliceOfBits(siz *Sizer, bits bitfield.Bitlist) uint32 {
if bits != nil {
return uint32(len(bits))
}
return uint32(len(bitlistZero))
}
// SizeSliceOfUint64s returns the serialized size of the dynamic part of a dynamic
// list of uint64s.
func SizeSliceOfUint64s[T ~uint64](siz *Sizer, ns []T) uint32 {
return uint32(len(ns)) * 8
}
// SizeDynamicObject returns the serialized size of the dynamic part of a dynamic
// object.
func SizeDynamicObject[T newableDynamicObject[U], U any](siz *Sizer, obj T) uint32 {
if obj == nil {
// If the object is nil, pull up it's zero value. This will be very slow,
// but it should not happen in production, only during tests mostly.
obj = zeroValueDynamic[T, U]()
}
return obj.SizeSSZ(siz, false)
}
// SizeSliceOfStaticBytes returns the serialized size of the dynamic part of a dynamic
// list of static blobs.
func SizeSliceOfStaticBytes[T commonBytesLengths](siz *Sizer, blobs []T) uint32 {
if len(blobs) == 0 {
return 0
}
return uint32(len(blobs) * len(blobs[0]))
}
// SizeSliceOfDynamicBytes returns the serialized size of the dynamic part of a dynamic
// list of dynamic blobs.
func SizeSliceOfDynamicBytes(siz *Sizer, blobs [][]byte) uint32 {
var size uint32
for _, blob := range blobs {
size += uint32(4 + len(blob)) // 4-byte offset + dynamic data later
}
return size
}
// SizeSliceOfStaticObjects returns the serialized size of the dynamic part of a dynamic
// list of static objects.
func SizeSliceOfStaticObjects[T StaticObject](siz *Sizer, objects []T) uint32 {
if len(objects) == 0 {
return 0
}
return uint32(len(objects)) * objects[0].SizeSSZ(siz)
}
// SizeSliceOfDynamicObjects returns the serialized size of the dynamic part of
// a dynamic list of dynamic objects.
func SizeSliceOfDynamicObjects[T DynamicObject](siz *Sizer, objects []T) uint32 {
var size uint32
for _, obj := range objects {
size += 4 + obj.SizeSSZ(siz, false) // 4-byte offset + dynamic data later
}
return size
}