Skip to content

Commit 9d0fc80

Browse files
committed
fix spectests
1 parent 2aad4de commit 9d0fc80

9 files changed

Lines changed: 290 additions & 269 deletions

File tree

spectests/init.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,10 @@ func initializeDynSszInstances() {
5050
panic("Failed to load minimal preset: " + err.Error())
5151
}
5252

53-
dynSszOnlyMainnet = ssz.NewDynSsz(mainnetSpecs)
54-
dynSszOnlyMainnet.NoFastSsz = true
55-
56-
dynsszHybridMainnet = ssz.NewDynSsz(mainnetSpecs)
57-
dynsszHybridMainnet.NoFastSsz = false
58-
59-
dynSszOnlyMinimal = ssz.NewDynSsz(minimalSpecs)
60-
dynSszOnlyMinimal.NoFastSsz = true
61-
62-
dynsszHybridMinimal = ssz.NewDynSsz(minimalSpecs)
63-
dynsszHybridMinimal.NoFastSsz = false
53+
dynSszOnlyMainnet = ssz.NewDynSsz(mainnetSpecs, ssz.WithNoFastSsz())
54+
dynsszHybridMainnet = ssz.NewDynSsz(mainnetSpecs, ssz.WithNoFastSsz())
55+
dynSszOnlyMinimal = ssz.NewDynSsz(minimalSpecs, ssz.WithNoFastSsz())
56+
dynsszHybridMinimal = ssz.NewDynSsz(minimalSpecs, ssz.WithNoFastSsz())
6457
}
6558

6659
func init() {

spectests/spectests_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,9 @@ func testForkConsensusSpec(t *testing.T, fork string, preset string, tests []Spe
8282
require.NoError(t, err)
8383
generatedRoot := fmt.Sprintf("root: '%#x'\n", string(generatedRootBytes[:]))
8484
if string(specYAMLRoot) != generatedRoot {
85-
dynssz.Verbose = true
8685
fmt.Printf("\n\ngeneratedRoot: %v", generatedRoot)
8786
fmt.Printf("specYAMLRoot: %v\n", string(specYAMLRoot))
88-
generatedRootBytes, err = dynssz.HashTreeRoot(s2)
8987
require.NoError(t, err)
90-
91-
dynssz.Verbose = false
9288
}
9389
require.YAMLEq(t, string(specYAMLRoot), generatedRoot)
9490
})

ssztypes/descriptor.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2025 pk910
2+
// SPDX-License-Identifier: Apache-2.0
3+
// This file is part of the dynamic-ssz library.
4+
5+
package ssztypes
6+
7+
import (
8+
"reflect"
9+
)
10+
11+
// SszTypeFlag is a flag indicating whether a type has a specific SSZ type feature
12+
type SszTypeFlag uint8
13+
14+
const (
15+
SszTypeFlagIsDynamic SszTypeFlag = 1 << iota // Whether the type is a dynamic type (or has nested dynamic types)
16+
SszTypeFlagHasLimit // Whether the type has a max size tag
17+
SszTypeFlagHasDynamicSize // Whether this type or any of its nested types uses dynamic spec size value that differs from the default
18+
SszTypeFlagHasDynamicMax // Whether this type or any of its nested types uses dynamic spec max value that differs from the default
19+
SszTypeFlagHasSizeExpr // Whether this type or any of its nested types uses a dynamic expression to calculate the size or max size
20+
SszTypeFlagHasMaxExpr // Whether this type or any of its nested types uses a dynamic expression to calculate the max size
21+
SszTypeFlagHasBitSize // Whether the type has a bit size tag
22+
)
23+
24+
// SszCompatFlag is a flag indicating whether a type implements a specific SSZ compatibility interface
25+
type SszCompatFlag uint16
26+
27+
const (
28+
SszCompatFlagFastSSZMarshaler SszCompatFlag = 1 << iota // Whether the type implements fastssz.Marshaler
29+
SszCompatFlagFastSSZHasher // Whether the type implements fastssz.HashRoot
30+
SszCompatFlagHashTreeRootWith // Whether the type implements HashTreeRootWith
31+
SszCompatFlagDynamicMarshaler // Whether the type implements DynamicMarshaler
32+
SszCompatFlagDynamicUnmarshaler // Whether the type implements DynamicUnmarshaler
33+
SszCompatFlagDynamicSizer // Whether the type implements DynamicSizer
34+
SszCompatFlagDynamicHashRoot // Whether the type implements DynamicHashRoot
35+
SszCompatFlagDynamicEncoder // Whether the type implements DynamicEncoder
36+
SszCompatFlagDynamicDecoder // Whether the type implements DynamicDecoder
37+
)
38+
39+
type GoTypeFlag uint8
40+
41+
const (
42+
GoTypeFlagIsPointer GoTypeFlag = 1 << iota // Whether the type is a pointer type
43+
GoTypeFlagIsByteArray // Whether the type is a byte array
44+
GoTypeFlagIsString // Whether the type is a string type
45+
GoTypeFlagIsTime // Whether the type is a time.Time type
46+
)
47+
48+
// TypeDescriptor represents a cached, optimized descriptor for a type's SSZ encoding/decoding
49+
type TypeDescriptor struct {
50+
Type reflect.Type `json:"-"` // Reflect type
51+
CodegenInfo *any `json:"-"` // Codegen information
52+
Kind reflect.Kind `json:"kind"` // Reflect kind of the type
53+
Size uint32 `json:"size"` // SSZ size (-1 if dynamic)
54+
Len uint32 `json:"len"` // Length of array/slice / static size of container
55+
Limit uint64 `json:"limit"` // Limit of array/slice (ssz-max tag)
56+
ContainerDesc *ContainerDescriptor `json:"container,omitempty"` // For structs
57+
UnionVariants map[uint8]*TypeDescriptor `json:"union,omitempty"` // Union variant types by index (for CompatibleUnion)
58+
ElemDesc *TypeDescriptor `json:"field,omitempty"` // For slices/arrays
59+
HashTreeRootWithMethod *reflect.Method `json:"-"` // Cached HashTreeRootWith method for performance
60+
SizeExpression *string `json:"size_expr,omitempty"` // The dynamic expression used to calculate the size of the type
61+
MaxExpression *string `json:"max_expr,omitempty"` // The dynamic expression used to calculate the max size of the type
62+
BitSize uint32 `json:"bit_size,omitempty"` // Bit size for bit vector types (ssz-bitsize tag)
63+
SszType SszType `json:"type"` // SSZ type of the type
64+
SszTypeFlags SszTypeFlag `json:"flags"` // SSZ type flags
65+
SszCompatFlags SszCompatFlag `json:"compat"` // SSZ compatibility flags
66+
GoTypeFlags GoTypeFlag `json:"go_flags"` // Additional go type flags
67+
}
68+
69+
// FieldDescriptor represents a cached descriptor for a struct field
70+
type ContainerDescriptor struct {
71+
Fields []FieldDescriptor `json:"fields"` // For structs
72+
DynFields []DynFieldDescriptor `json:"dyn_fields"` // Dynamic struct fields
73+
}
74+
75+
// FieldDescriptor represents a cached descriptor for a struct field
76+
type FieldDescriptor struct {
77+
Name string `json:"name"` // Name of the field
78+
Type *TypeDescriptor `json:"type"` // Type descriptor
79+
SszIndex uint16 `json:"index,omitempty"` // SSZ index for progressive containers
80+
}
81+
82+
// DynFieldDescriptor represents a dynamic field descriptor for a struct
83+
type DynFieldDescriptor struct {
84+
Field *FieldDescriptor `json:"field"`
85+
HeaderOffset uint32 `json:"offset"`
86+
Index int16 `json:"index"` // Index of the field in the struct
87+
}

ssztypes/typecache.go

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -23,84 +23,6 @@ type TypeCache struct {
2323
CompatFlags map[string]SszCompatFlag
2424
}
2525

26-
// SszTypeFlag is a flag indicating whether a type has a specific SSZ type feature
27-
type SszTypeFlag uint8
28-
29-
const (
30-
SszTypeFlagIsDynamic SszTypeFlag = 1 << iota // Whether the type is a dynamic type (or has nested dynamic types)
31-
SszTypeFlagHasLimit // Whether the type has a max size tag
32-
SszTypeFlagHasDynamicSize // Whether this type or any of its nested types uses dynamic spec size value that differs from the default
33-
SszTypeFlagHasDynamicMax // Whether this type or any of its nested types uses dynamic spec max value that differs from the default
34-
SszTypeFlagHasSizeExpr // Whether this type or any of its nested types uses a dynamic expression to calculate the size or max size
35-
SszTypeFlagHasMaxExpr // Whether this type or any of its nested types uses a dynamic expression to calculate the max size
36-
SszTypeFlagHasBitSize // Whether the type has a bit size tag
37-
)
38-
39-
// SszCompatFlag is a flag indicating whether a type implements a specific SSZ compatibility interface
40-
type SszCompatFlag uint16
41-
42-
const (
43-
SszCompatFlagFastSSZMarshaler SszCompatFlag = 1 << iota // Whether the type implements fastssz.Marshaler
44-
SszCompatFlagFastSSZHasher // Whether the type implements fastssz.HashRoot
45-
SszCompatFlagHashTreeRootWith // Whether the type implements HashTreeRootWith
46-
SszCompatFlagDynamicMarshaler // Whether the type implements DynamicMarshaler
47-
SszCompatFlagDynamicUnmarshaler // Whether the type implements DynamicUnmarshaler
48-
SszCompatFlagDynamicSizer // Whether the type implements DynamicSizer
49-
SszCompatFlagDynamicHashRoot // Whether the type implements DynamicHashRoot
50-
SszCompatFlagDynamicEncoder // Whether the type implements DynamicEncoder
51-
SszCompatFlagDynamicDecoder // Whether the type implements DynamicDecoder
52-
)
53-
54-
type GoTypeFlag uint8
55-
56-
const (
57-
GoTypeFlagIsPointer GoTypeFlag = 1 << iota // Whether the type is a pointer type
58-
GoTypeFlagIsByteArray // Whether the type is a byte array
59-
GoTypeFlagIsString // Whether the type is a string type
60-
GoTypeFlagIsTime // Whether the type is a time.Time type
61-
)
62-
63-
// TypeDescriptor represents a cached, optimized descriptor for a type's SSZ encoding/decoding
64-
type TypeDescriptor struct {
65-
Type reflect.Type `json:"-"` // Reflect type
66-
CodegenInfo *any `json:"-"` // Codegen information
67-
Kind reflect.Kind `json:"kind"` // Reflect kind of the type
68-
Size uint32 `json:"size"` // SSZ size (-1 if dynamic)
69-
Len uint32 `json:"len"` // Length of array/slice / static size of container
70-
Limit uint64 `json:"limit"` // Limit of array/slice (ssz-max tag)
71-
ContainerDesc *ContainerDescriptor `json:"container,omitempty"` // For structs
72-
UnionVariants map[uint8]*TypeDescriptor `json:"union,omitempty"` // Union variant types by index (for CompatibleUnion)
73-
ElemDesc *TypeDescriptor `json:"field,omitempty"` // For slices/arrays
74-
HashTreeRootWithMethod *reflect.Method `json:"-"` // Cached HashTreeRootWith method for performance
75-
SizeExpression *string `json:"size_expr,omitempty"` // The dynamic expression used to calculate the size of the type
76-
MaxExpression *string `json:"max_expr,omitempty"` // The dynamic expression used to calculate the max size of the type
77-
BitSize uint32 `json:"bit_size,omitempty"` // Bit size for bit vector types (ssz-bitsize tag)
78-
SszType SszType `json:"type"` // SSZ type of the type
79-
SszTypeFlags SszTypeFlag `json:"flags"` // SSZ type flags
80-
SszCompatFlags SszCompatFlag `json:"compat"` // SSZ compatibility flags
81-
GoTypeFlags GoTypeFlag `json:"go_flags"` // Additional go type flags
82-
}
83-
84-
// FieldDescriptor represents a cached descriptor for a struct field
85-
type ContainerDescriptor struct {
86-
Fields []FieldDescriptor `json:"fields"` // For structs
87-
DynFields []DynFieldDescriptor `json:"dyn_fields"` // Dynamic struct fields
88-
}
89-
90-
// FieldDescriptor represents a cached descriptor for a struct field
91-
type FieldDescriptor struct {
92-
Name string `json:"name"` // Name of the field
93-
Type *TypeDescriptor `json:"type"` // Type descriptor
94-
SszIndex uint16 `json:"index,omitempty"` // SSZ index for progressive containers
95-
}
96-
97-
// DynFieldDescriptor represents a dynamic field descriptor for a struct
98-
type DynFieldDescriptor struct {
99-
Field *FieldDescriptor `json:"field"`
100-
HeaderOffset uint32 `json:"offset"`
101-
Index int16 `json:"index"` // Index of the field in the struct
102-
}
103-
10426
// NewTypeCache creates a new type cache
10527
func NewTypeCache(specs sszutils.DynamicSpecs) *TypeCache {
10628
return &TypeCache{

ssztypes/typecache_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ import (
1212
"unsafe"
1313
)
1414

15+
type dummyDynamicSpecs struct {
16+
specValues map[string]uint64
17+
}
18+
19+
func (d *dummyDynamicSpecs) ResolveSpecValue(name string) (bool, uint64, error) {
20+
value, ok := d.specValues[name]
21+
return ok, value, nil
22+
}
23+
1524
// Test error cases in TypeCache.GetTypeDescriptor
1625
func TestTypeCache_ErrorCases(t *testing.T) {
1726
ds := &dummyDynamicSpecs{}

ssztypes/typewrapper.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2025 pk910
2+
// SPDX-License-Identifier: Apache-2.0
3+
// This file is part of the dynamic-ssz library.
4+
5+
package ssztypes
6+
7+
import (
8+
"fmt"
9+
"reflect"
10+
11+
"github.com/pk910/dynamic-ssz/sszutils"
12+
)
13+
14+
// wrapperDescriptorInfo contains type and annotation information for a wrapper
15+
type wrapperDescriptorInfo struct {
16+
Type reflect.Type
17+
SizeHints []SszSizeHint
18+
MaxSizeHints []SszMaxSizeHint
19+
TypeHints []SszTypeHint
20+
}
21+
22+
// ExtractWrapperDescriptorInfo extracts wrapper information from a wrapper descriptor type.
23+
// This function validates that the descriptor has exactly one field and extracts its annotations.
24+
func extractWrapperDescriptorInfo(descriptorType reflect.Type, ds sszutils.DynamicSpecs) (*wrapperDescriptorInfo, error) {
25+
if descriptorType.Kind() != reflect.Struct {
26+
return nil, fmt.Errorf("wrapper descriptor must be a struct, got %v", descriptorType.Kind())
27+
}
28+
29+
if descriptorType.NumField() != 1 {
30+
return nil, fmt.Errorf("wrapper descriptor must have exactly 1 field, got %d", descriptorType.NumField())
31+
}
32+
33+
field := descriptorType.Field(0)
34+
35+
// Extract SSZ annotations using existing DynSsz methods
36+
sizeHints, err := getSszSizeTag(ds, &field)
37+
if err != nil {
38+
return nil, fmt.Errorf("failed to parse ssz-size tag for field %s: %w", field.Name, err)
39+
}
40+
41+
maxSizeHints, err := getSszMaxSizeTag(ds, &field)
42+
if err != nil {
43+
return nil, fmt.Errorf("failed to parse ssz-max tag for field %s: %w", field.Name, err)
44+
}
45+
46+
typeHints, err := getSszTypeTag(&field)
47+
if err != nil {
48+
return nil, fmt.Errorf("failed to parse ssz-type tag for field %s: %w", field.Name, err)
49+
}
50+
51+
return &wrapperDescriptorInfo{
52+
Type: field.Type,
53+
SizeHints: sizeHints,
54+
MaxSizeHints: maxSizeHints,
55+
TypeHints: typeHints,
56+
}, nil
57+
}

0 commit comments

Comments
 (0)