-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.go
More file actions
159 lines (131 loc) · 4.52 KB
/
types.go
File metadata and controls
159 lines (131 loc) · 4.52 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
151
152
153
154
155
156
157
158
159
package cuessz
import (
"errors"
"fmt"
)
// Sentinel errors for schema validation
var (
// ErrRecursiveType indicates a recursive type reference was detected
ErrRecursiveType = errors.New("recursive type reference detected")
)
// TypeName represents the type discriminator for SSZ types
type TypeName string
const (
TypeUint8 TypeName = "uint8"
TypeUint16 TypeName = "uint16"
TypeUint32 TypeName = "uint32"
TypeUint64 TypeName = "uint64"
TypeUint128 TypeName = "uint128"
TypeUint256 TypeName = "uint256"
TypeBoolean TypeName = "boolean"
TypeContainer TypeName = "container"
TypeProgressiveContainer TypeName = "progressive_container"
TypeVector TypeName = "vector"
TypeList TypeName = "list"
TypeBitVector TypeName = "bitvector"
TypeBitList TypeName = "bitlist"
TypeUnion TypeName = "union"
// TypeRef is a special type that references another type in the schema
TypeRef TypeName = "ref"
)
func (t TypeName) String() string {
return string(t)
}
func (t TypeName) IsSometimesVariable() bool {
switch t {
case TypeVector, TypeContainer, TypeProgressiveContainer, TypeUnion, TypeRef:
return true
default:
return false
}
}
func (t TypeName) IsAlwaysVariable() bool {
switch t {
case TypeList, TypeBitList:
return true
default:
return false
}
}
func (t TypeName) IsAlwaysFixed() bool {
switch t {
case TypeUint8, TypeUint16, TypeUint32, TypeUint64, TypeUint128, TypeUint256, TypeBoolean, TypeBitVector:
return true
default:
return false
}
}
// Def represents an SSZ type definition (matches CUE #Def)
type Def struct {
Type TypeName `json:"type" yaml:"type"`
Description *string `json:"description,omitempty" yaml:"description,omitempty"`
Size uint64 `json:"size,omitempty" yaml:"size,omitempty"`
Limit uint64 `json:"limit,omitempty" yaml:"limit,omitempty"`
Ref string `json:"ref,omitempty" yaml:"ref,omitempty"`
Children []Field `json:"children,omitempty" yaml:"children,omitempty"`
ActiveFields []int `json:"active_fields,omitempty" yaml:"active_fields,omitempty"`
}
// Field represents a named field within a container (matches CUE #Field)
type Field struct {
Name string `json:"name" yaml:"name"`
Def Def `json:"def" yaml:"def"`
Description *string `json:"description,omitempty" yaml:"description,omitempty"`
}
// IsVariable determines if a def is variable-size
func (d *Def) IsVariable(refs map[string]Def) (bool, error) {
const maxIterations = 1000 // Sanity check to prevent infinite recursion
return isVariable(d, refs, 0, maxIterations)
}
// isVariable is the internal implementation with iteration tracking
func isVariable(d *Def, refs map[string]Def, iterations, maxIterations int) (bool, error) {
if iterations >= maxIterations {
return false, fmt.Errorf("max iterations reached while checking IsVariable - possible circular reference")
}
switch d.Type {
case TypeList, TypeBitList, TypeUnion:
return true, nil
case TypeProgressiveContainer, TypeContainer, TypeVector, TypeBitVector:
// Progressive/regular containers and vectors are variable-size only if they contain variable-size children
// The active_fields bitvector in progressive containers affects merkleization, not serialization
for _, child := range d.Children {
isVar, err := isVariable(&child.Def, refs, iterations+1, maxIterations)
if err != nil {
return false, err
}
if isVar {
return true, nil
}
}
case TypeRef:
if d.Ref == "" {
return false, fmt.Errorf("def has type 'ref' but no ref specified")
}
refDef, ok := refs[d.Ref]
if !ok {
return false, fmt.Errorf("ref type '%s' not found", d.Ref)
}
return isVariable(&refDef, refs, iterations+1, maxIterations)
}
return false, nil
}
// Note: Validation is now handled by CUE schema in ssz_schema.cue
// The IsValid method has been removed to avoid redundant validation
// Schema represents a collection of named SSZ type definitions
type Schema struct {
Version string `json:"version" yaml:"version"`
Defs map[string]Def `json:"defs" yaml:"defs"`
Metadata *Metadata `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// Metadata contains optional schema metadata
type Metadata struct {
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Authors []string `json:"authors,omitempty" yaml:"authors,omitempty"`
}
// Validate validates all defs in the schema
func (s *Schema) Validate() error {
if s.Defs == nil {
return fmt.Errorf("schema defs cannot be nil")
}
return nil
}