dynssz

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2025 License: Apache-2.0 Imports: 12 Imported by: 16

README

Dynamic SSZ (dynssz)

Dynamic SSZ (dynssz) is a Go library designed to provide flexible and dynamic SSZ encoding/decoding for any Go data structures. It stands out by using runtime reflection to handle serialization and deserialization of types with variable field sizes, enabling it to support dynamic specifications and configurations. While commonly used with Ethereum data structures and presets (mainnet, minimal, custom), it works with any SSZ-compatible types. dynssz integrates with fastssz to leverage static type information for encoding/decoding when possible, but its primary advantage lies in its ability to adapt to dynamic field sizes that are not well-suited to static code generation methods.

dynssz is designed to bridge the gap between the efficiency of static SSZ encoding/decoding and the flexibility required for handling dynamic data structures. It achieves this through a hybrid approach that combines the best of both worlds: leveraging fastssz for static types and dynamically processing types with variable sizes.

Benefits

  • Flexibility: Supports any SSZ-compatible data structures with custom and dynamic specifications, not limited to Ethereum types.
  • Hybrid Efficiency: Balances the efficiency of static processing with the flexibility of dynamic handling, optimizing performance where possible.
  • Developer-Friendly: Simplifies the handling of SSZ data for developers by abstracting the complexity of dynamic data processing.
  • General Purpose: Works with any Go types that follow SSZ serialization rules, making it suitable for various applications beyond blockchain.

Installation

To install dynssz, use the go get command:

go get github.com/pk910/dynamic-ssz

This will download and install the dynssz package into your Go workspace.

Usage

Struct Tag Annotations for Dynamic Encoding/Decoding

dynssz utilizes struct tag annotations to indicate how fields should be encoded/decoded, supporting both static and dynamic field sizes:

  • ssz-size: Defines static default field sizes. This tag follows the same format supported by fastssz, allowing seamless integration.

  • dynssz-size: Specifies dynamic sizes based on specification properties, extending the flexibility of dynssz to adapt to various Ethereum presets. Unlike the straightforward ssz-size, dynssz-size supports not only direct references to specification values but also simple mathematical expressions. This feature allows for dynamic calculation of field sizes based on spec values, enhancing the dynamic capabilities of dynssz.

    The dynssz-size tag can interpret and evaluate expressions involving one or multiple spec values, offering a versatile approach to defining dynamic sizes. For example:

    • A direct reference to a single spec value might look like dynssz-size:"SPEC_VALUE".
    • A simple mathematical expression based on a spec value could be dynssz-size:"(SPEC_VALUE*2)-5", enabling the size to be dynamically adjusted according to the spec value.
    • For more complex scenarios involving multiple spec values, the tag can handle expressions like dynssz-size:"(SPEC_VALUE1*SPEC_VALUE2)+SPEC_VALUE3", providing a powerful tool for defining sizes that depend on multiple dynamic specifications.

    When processing a field with a dynssz-size tag, dynssz evaluates the expression to determine the actual size. If the resolved size deviates from the default established by ssz-size, the library switches to dynamic handling for that field. This mechanism ensures that dynssz can accurately and efficiently encode or decode data structures, taking into account the intricate sizing requirements dictated by dynamic Ethereum presets.

Fields with static sizes do not need the dynssz-size tag. Here's an example of a structure using both tags:

type BeaconState struct {
    GenesisTime                  uint64
    GenesisValidatorsRoot        phase0.Root `ssz-size:"32"`
    Slot                         phase0.Slot
    Fork                         *phase0.Fork
    LatestBlockHeader            *phase0.BeaconBlockHeader
    BlockRoots                   []phase0.Root `ssz-size:"8192,32" dynssz-size:"SLOTS_PER_HISTORICAL_ROOT,32"`
    StateRoots                   []phase0.Root `ssz-size:"8192,32" dynssz-size:"SLOTS_PER_HISTORICAL_ROOT,32"`
    ...
}
Creating a New DynSsz Instance
import "github.com/pk910/dynamic-ssz"

// Define your dynamic specifications
// For Ethereum use case:
ethSpecs := map[string]any{
    "SYNC_COMMITTEE_SIZE": uint64(32),
    "SLOTS_PER_HISTORICAL_ROOT": uint64(8192),
    // ...
}

// For custom application use case:
customSpecs := map[string]any{
    "MAX_ITEMS": uint64(1000),
    "BUFFER_SIZE": uint64(4096),
    // ...
}

ds := dynssz.NewDynSsz(ethSpecs)
// or
ds := dynssz.NewDynSsz(customSpecs)
Marshaling an Object
data, err := ds.MarshalSSZ(myObject)
if err != nil {
    log.Fatalf("Failed to marshal SSZ: %v", err)
}
Unmarshaling an Object
err := ds.UnmarshalSSZ(&myObject, data)
if err != nil {
    log.Fatalf("Failed to unmarshal SSZ: %v", err)
}

Performance

The performance of dynssz has been benchmarked against fastssz using BeaconBlocks and BeaconStates from small kurtosis testnets, providing a consistent and comparable set of data. These benchmarks compare three scenarios: exclusively using fastssz, exclusively using dynssz, and a combined approach where dynssz defaults to fastssz for static types that do not require dynamic processing. The results highlight the balance between flexibility and speed:

Legend:

  • First number: Unmarshalling time in milliseconds.
  • Second number: Marshalling time in milliseconds.
  • Third number: Hash tree root time in milliseconds.
Mainnet Preset
BeaconBlock Decode + Encode + Hash (10,000 times)
  • fastssz only: [8 ms / 3 ms / 88 ms] success
  • dynssz only: [27 ms / 12 ms / 63 ms] success
  • dynssz + fastssz: [8 ms / 3 ms / 64 ms] success
BeaconState Decode + Encode + Hash (10,000 times)
  • fastssz only: [5849 ms / 4960 ms / 73087 ms] success
  • dynssz only: [22544 ms / 12256 ms / 40181 ms] success
  • dynssz + fastssz: [5728 ms / 4857 ms / 37191 ms] success
Minimal Preset
BeaconBlock Decode + Encode + Hash (10,000 times)
  • fastssz only: [0 ms / 0 ms / 0 ms] failed (unmarshal error)
  • dynssz only: [44 ms / 29 ms / 90 ms] success
  • dynssz + fastssz: [22 ms / 13 ms / 151 ms] success
BeaconState Decode + Encode + Hash (10,000 times)
  • fastssz only: [0 ms / 0 ms / 0 ms] failed (unmarshal error)
  • dynssz only: [796 ms / 407 ms / 1816 ms] success
  • dynssz + fastssz: [459 ms / 244 ms / 4712 ms] success

These results showcase the dynamic processing capabilities of dynssz, particularly its ability to handle data structures that fastssz cannot process due to its static nature. While dynssz introduces additional processing time, its flexibility allows it to successfully manage both mainnet and minimal presets. The combined dynssz and fastssz approach significantly improves performance while maintaining this flexibility, making it a viable solution for applications requiring dynamic SSZ processing.

Testing

The library includes comprehensive testing infrastructure:

  • Unit Tests: Fast, isolated tests for core functionality
  • Spec Tests: Ethereum consensus specification compliance tests
  • Examples: Working examples that are automatically tested
  • Performance Tests: Benchmarking and regression testing
Running Spec Tests
cd spectests
./run_tests.sh mainnet  # Run mainnet preset tests
./run_tests.sh minimal  # Run minimal preset tests

The spec tests automatically download the latest consensus spec test data and validate the library against the official Ethereum test vectors.

Internal Technical Overview

Key Components
  • Type and Value Size Calculation: The library distinguishes between type sizes (static sizes of types or -1 for dynamic types) and value sizes (the absolute size of an instance in SSZ representation), utilizing recursive functions to accurately determine these sizes based on reflection and tag annotations (ssz-size, dynssz-size).

  • Encoding/Decoding Dispatch: Central to the library's architecture are the marshalType and unmarshalType functions. These serve as entry points to the encoding and decoding processes, respectively, dynamically dispatching tasks to specialized functions based on the nature of the data (e.g., marshalStruct, unmarshalArray).

  • Dynamic Handling with Static Efficiency: For types that do not necessitate dynamic processing (neither the type nor its nested types have dynamic specifications), dynssz optimizes performance by invoking corresponding fastssz functions. This ensures minimal overhead for types compatible with static processing.

  • Size Hints and Spec Values: dynssz intelligently handles sizes through sszSizeHint structures, derived from field tag annotations. These hints inform the library whether to process data statically or dynamically, allowing for precise and efficient data serialization.

Architecture Flow
  1. Size Calculation: Upon receiving a data structure for encoding or decoding, dynssz first calculates its size. For encoding, it determines whether the structure can be processed statically or requires dynamic handling. For decoding, it assesses the expected size of the incoming SSZ data.

  2. Dynamic vs. Static Path Selection: Based on the size calculation and the presence of dynamic specifications, the library selects the appropriate processing path. Static paths leverage fastssz for efficiency, while dynamic paths use runtime reflection.

  3. Recursive Encoding/Decoding: The library recursively processes each field or element of the data structure. It dynamically navigates through nested structures, applying the correct encoding or decoding method based on the data type and size characteristics.

  4. Specialized Function Dispatch: For complex types (e.g., slices, arrays, structs), dynssz dispatches tasks to specialized functions tailored to handle specific encoding or decoding needs, ensuring accurate and efficient processing.

Contributing

We welcome contributions from the community! Please check out the CONTRIBUTING.md file for guidelines on how to contribute to dynssz.

License

dynssz is licensed under the Apache-2.0 License. See the LICENSE file for more details.

Acknowledgements

Thanks to all the contributors and the Ethereum community for providing the inspiration and foundation for this project.

Documentation

Overview

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

Package dynssz provides dynamic SSZ (Simple Serialize) encoding and decoding for Ethereum data structures. Unlike static code generation approaches, dynssz uses runtime reflection to handle dynamic field sizes, making it suitable for various Ethereum presets beyond the mainnet. It seamlessly integrates with fastssz for optimal performance when static definitions are applicable.

Copyright (c) 2024 by pk910. See LICENSE file for details.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file implements cached type descriptors with unsafe pointer optimization. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

dynssz: Dynamic SSZ encoding/decoding for Ethereum with fastssz efficiency. This file is part of the dynssz package. Copyright (c) 2024 by pk910. Refer to LICENSE for more information.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrIncorrectByteSize means that the byte size is incorrect
	ErrIncorrectByteSize = fmt.Errorf("incorrect byte size")

	// ErrIncorrectListSize means that the size of the list is incorrect
	ErrIncorrectListSize = fmt.Errorf("incorrect list size")
)
View Source
var (
	ErrOffset                = fmt.Errorf("incorrect offset")
	ErrSize                  = fmt.Errorf("incorrect size")
	ErrBytesLength           = fmt.Errorf("bytes array does not have the correct length")
	ErrVectorLength          = fmt.Errorf("vector does not have the correct length")
	ErrListTooBig            = fmt.Errorf("list length is higher than max value")
	ErrEmptyBitlist          = fmt.Errorf("bitlist is empty")
	ErrInvalidVariableOffset = fmt.Errorf("invalid ssz encoding. first variable element offset indexes into fixed value data")
)

Functions

func CalculateLimit added in v0.0.6

func CalculateLimit(maxCapacity, numItems, size uint64) uint64

Types

type DynFieldDescriptor added in v1.0.0

type DynFieldDescriptor struct {
	Field  *FieldDescriptor
	Offset uint32
}

DynFieldDescriptor represents a dynamic field descriptor for a struct

type DynSsz

type DynSsz struct {

	// NoFastSsz disables the use of fastssz for static types.
	// When true, all encoding/decoding uses reflection-based processing.
	// Generally not recommended unless you need consistent behavior across all types.
	NoFastSsz bool

	// NoFastHash disables the use of optimized hash tree root calculation.
	// When true, uses the standard hasher instead of the fast gohashtree implementation.
	NoFastHash bool

	// Verbose enables detailed logging of encoding/decoding operations.
	// Useful for debugging but impacts performance.
	Verbose bool
	// contains filtered or unexported fields
}

DynSsz is a dynamic SSZ encoder/decoder that uses runtime reflection to handle dynamic field sizes. It provides flexible SSZ encoding/decoding for any Go data structures that can adapt to different specifications through dynamic field sizing. While commonly used with Ethereum data structures and presets (mainnet, minimal, custom), it works with any SSZ-compatible types.

The instance maintains caches for type descriptors and specification values to optimize performance. It's recommended to reuse the same DynSsz instance across operations to benefit from caching.

Key features:

  • Hybrid approach: automatically uses fastssz for static types, reflection for dynamic types
  • Type caching: reduces overhead for repeated operations on the same types
  • Specification support: handles dynamic field sizes based on runtime specifications
  • Thread-safe: can be safely used from multiple goroutines

Example usage:

specs := map[string]any{
    "SLOTS_PER_HISTORICAL_ROOT": uint64(8192),
    "SYNC_COMMITTEE_SIZE":       uint64(512),
}
ds := dynssz.NewDynSsz(specs)

// Marshal
data, err := ds.MarshalSSZ(myStruct)

// Unmarshal
err = ds.UnmarshalSSZ(&myStruct, data)

// Hash tree root
root, err := ds.HashTreeRoot(myStruct)

func NewDynSsz

func NewDynSsz(specs map[string]any) *DynSsz

NewDynSsz creates a new instance of the DynSsz encoder/decoder.

The specs map contains dynamic properties and configurations that control SSZ serialization and deserialization. These specifications allow the library to handle different configurations by defining dynamic field sizes at runtime. While commonly used with Ethereum presets (mainnet, minimal, custom), they can define any dynamic sizing parameters for your data structures.

For non-Ethereum use cases, you can define any specifications relevant to your data structures.

The library supports mathematical expressions in dynssz-size tags that reference these specification values, enabling complex dynamic sizing behavior.

Parameters:

  • specs: A map of specification names to their values. Can be nil for default behavior.

Returns:

  • *DynSsz: A new DynSsz instance ready for encoding/decoding operations

Example:

// Ethereum mainnet specifications
specs := map[string]any{
    "SLOTS_PER_HISTORICAL_ROOT": uint64(8192),
    "SYNC_COMMITTEE_SIZE":       uint64(512),
}
ds := dynssz.NewDynSsz(specs)

// Custom application specifications
customSpecs := map[string]any{
    "MAX_ITEMS":           uint64(1000),
    "BUFFER_SIZE":         uint64(4096),
    "CUSTOM_ARRAY_LENGTH": uint64(256),
}
dsCustom := dynssz.NewDynSsz(customSpecs)

func (*DynSsz) GetTypeCache added in v1.0.0

func (d *DynSsz) GetTypeCache() *TypeCache

GetTypeCache returns the type cache for the DynSsz instance.

The type cache stores computed type descriptors for types used in encoding/decoding operations. Type descriptors contain optimized information about how to serialize/deserialize specific types, including field offsets, size information, and whether fastssz can be used.

This method is primarily useful for debugging, performance analysis, or advanced use cases where you need to inspect the cached type information.

Returns:

  • *TypeCache: The type cache instance containing all cached type descriptors

Example:

ds := dynssz.NewDynSsz(specs)
cache := ds.GetTypeCache()

// Dump type descriptor for debugging
json, err := cache.DumpTypeDescriptor(reflect.TypeOf(myStruct))

func (*DynSsz) HashTreeRoot added in v0.0.6

func (d *DynSsz) HashTreeRoot(source any) ([32]byte, error)

HashTreeRoot computes the hash tree root of the given source object. This method uses the default hasher pool to get a new hasher instance, builds the root from the source object, and returns the computed hash root. It returns the computed hash root and an error if the process fails.

func (*DynSsz) MarshalSSZ

func (d *DynSsz) MarshalSSZ(source any) ([]byte, error)

MarshalSSZ serializes the given source into its SSZ (Simple Serialize) representation.

This method dynamically handles the serialization of Go types to SSZ format, supporting both static and dynamic field sizes. For types without dynamic specifications, it automatically uses fastssz for optimal performance. For types with dynamic field sizes (based on runtime specifications), it uses reflection-based processing.

The method allocates a new byte slice for the result. For high-performance scenarios with frequent allocations, consider using MarshalSSZTo with a pre-allocated buffer.

Parameters:

  • source: Any Go value to be serialized. Must be a type supported by SSZ encoding.

Returns:

  • []byte: The SSZ-encoded data as a new byte slice
  • error: An error if serialization fails due to unsupported types, encoding errors, or size mismatches

Supported types include:

  • Basic types: bool, uint8, uint16, uint32, uint64
  • Arrays and slices of supported types
  • Structs with appropriate SSZ tags
  • Pointers to supported types
  • Types implementing fastssz.Marshaler interface

Example:

header := &phase0.BeaconBlockHeader{
    Slot:          12345,
    ProposerIndex: 42,
    // ... other fields
}

data, err := ds.MarshalSSZ(header)
if err != nil {
    log.Fatal("Failed to marshal:", err)
}
fmt.Printf("Encoded %d bytes\n", len(data))

func (*DynSsz) MarshalSSZTo

func (d *DynSsz) MarshalSSZTo(source any, buf []byte) ([]byte, error)

MarshalSSZTo serializes the given source into its SSZ (Simple Serialize) representation and writes the output to the provided buffer. This method allows direct control over the serialization output buffer, allowing optimizations like buffer reuse. The 'source' parameter is the structure to be serialized, and 'buf' is the pre-allocated slice where the serialized data will be written. It dynamically handles serialization for types with dynamic field sizes, seamlessly integrating with fastssz when possible. Returns the updated buffer containing the serialized data and an error if serialization fails.

func (*DynSsz) SizeSSZ

func (d *DynSsz) SizeSSZ(source any) (int, error)

SizeSSZ calculates the size of the given source object when serialized using SSZ encoding. This function is useful for pre-determining the amount of space needed to serialize a given source object. The 'source' parameter can be any Go value. It dynamically evaluates the size, accommodating types with dynamic field sizes efficiently. Returns the calculated size as an int and an error if the process fails.

func (*DynSsz) UnmarshalSSZ

func (d *DynSsz) UnmarshalSSZ(target any, ssz []byte) error

UnmarshalSSZ decodes the given SSZ-encoded data into the target object. The 'ssz' byte slice contains the SSZ-encoded data, and 'target' is a pointer to the Go value that will hold the decoded data. This method dynamically handles the decoding, accommodating for types with dynamic field sizes. It seamlessly integrates with fastssz for types without dynamic specifications to ensure efficient decoding. Returns an error if decoding fails or if the provided ssz data has not been fully used for decoding.

type FieldDescriptor added in v1.0.0

type FieldDescriptor struct {
	Name      string
	Offset    uintptr         // Unsafe offset within the struct
	Type      *TypeDescriptor // Type descriptor
	Index     int16           // Index of the field in the struct
	Size      int32           // SSZ size (-1 if dynamic)
	IsPtr     bool            // Whether field is a pointer
	IsDynamic bool            // Whether field has dynamic size
}

FieldDescriptor represents a cached descriptor for a struct field

type HashFn added in v0.0.6

type HashFn func(dst []byte, input []byte) error

func NativeHashWrapper added in v0.0.6

func NativeHashWrapper(hashFn hash.Hash) HashFn

NativeHashWrapper wraps a hash.Hash function into a HashFn

type HashWalker added in v1.0.0

type HashWalker interface {
	// Hash returns the latest hash generated during merkleize
	Hash() []byte

	// Methods for appending single values
	AppendUint8(i uint8)
	AppendUint32(i uint32)
	AppendUint64(i uint64)
	AppendBytes32(b []byte)

	// Methods for putting values into the buffer
	PutUint64Array(b []uint64, maxCapacity ...uint64)
	PutUint64(i uint64)
	PutUint32(i uint32)
	PutUint16(i uint16)
	PutUint8(i uint8)
	PutBitlist(bb []byte, maxSize uint64)
	PutBool(b bool)
	PutBytes(b []byte)

	// Buffer manipulation methods
	FillUpTo32()
	Append(i []byte)
	Index() int

	// Merkleization methods
	Merkleize(indx int)
	MerkleizeWithMixin(indx int, num, limit uint64)
}

HashWalker is our own interface that mirrors fastssz.HashWalker This allows us to avoid importing fastssz directly while still being compatible with types that implement HashTreeRootWith

type Hasher added in v0.0.6

type Hasher struct {
	// contains filtered or unexported fields
}

Hasher is a utility tool to hash SSZ structs

func NewHasher added in v0.0.6

func NewHasher() *Hasher

NewHasher creates a new Hasher object with sha256 hash

func NewHasherWithHash added in v0.0.6

func NewHasherWithHash(hh hash.Hash) *Hasher

NewHasherWithHash creates a new Hasher object with a custom hash.Hash function

func NewHasherWithHashFn added in v0.0.6

func NewHasherWithHashFn(hh HashFn) *Hasher

NewHasherWithHashFn creates a new Hasher object with a custom HashFn function

func (*Hasher) Append added in v0.0.6

func (h *Hasher) Append(i []byte)

func (*Hasher) AppendBytes32 added in v0.0.6

func (h *Hasher) AppendBytes32(b []byte)

func (*Hasher) AppendUint8 added in v0.0.6

func (h *Hasher) AppendUint8(i uint8)

func (*Hasher) AppendUint32 added in v0.0.6

func (h *Hasher) AppendUint32(i uint32)

func (*Hasher) AppendUint64 added in v0.0.6

func (h *Hasher) AppendUint64(i uint64)

func (*Hasher) FillUpTo32 added in v0.0.6

func (h *Hasher) FillUpTo32()

func (*Hasher) Hash added in v0.0.6

func (h *Hasher) Hash() []byte

func (*Hasher) HashRoot added in v0.0.6

func (h *Hasher) HashRoot() (res [32]byte, err error)

HashRoot creates the hash final hash root

func (*Hasher) Index added in v0.0.6

func (h *Hasher) Index() int

Index marks the current buffer index

func (*Hasher) Merkleize added in v0.0.6

func (h *Hasher) Merkleize(indx int)

Merkleize is used to merkleize the last group of the hasher

func (*Hasher) MerkleizeWithMixin added in v0.0.6

func (h *Hasher) MerkleizeWithMixin(indx int, num, limit uint64)

MerkleizeWithMixin is used to merkleize the last group of the hasher

func (*Hasher) PutBitlist added in v0.0.6

func (h *Hasher) PutBitlist(bb []byte, maxSize uint64)

PutBitlist appends a ssz bitlist

func (*Hasher) PutBool added in v0.0.6

func (h *Hasher) PutBool(b bool)

PutBool appends a boolean

func (*Hasher) PutBytes added in v0.0.6

func (h *Hasher) PutBytes(b []byte)

PutBytes appends bytes

func (*Hasher) PutRootVector added in v0.0.6

func (h *Hasher) PutRootVector(b [][]byte, maxCapacity ...uint64) error

PutRootVector appends an array of roots

func (*Hasher) PutUint8 added in v0.0.6

func (h *Hasher) PutUint8(i uint8)

PutUint8 appends a uint8 in 32 bytes

func (*Hasher) PutUint16 added in v0.0.6

func (h *Hasher) PutUint16(i uint16)

PutUint16 appends a uint16 in 32 bytes

func (*Hasher) PutUint32 added in v0.0.6

func (h *Hasher) PutUint32(i uint32)

PutUint32 appends a uint32 in 32 bytes

func (*Hasher) PutUint64 added in v0.0.6

func (h *Hasher) PutUint64(i uint64)

PutUint64 appends a uint64 in 32 bytes

func (*Hasher) PutUint64Array added in v0.0.6

func (h *Hasher) PutUint64Array(b []uint64, maxCapacity ...uint64)

PutUint64Array appends an array of uint64

func (*Hasher) Reset added in v0.0.6

func (h *Hasher) Reset()

Reset resets the Hasher obj

type HasherPool added in v0.0.6

type HasherPool struct {
	HashFn HashFn
	// contains filtered or unexported fields
}

HasherPool may be used for pooling Hashers for similarly typed SSZs.

var DefaultHasherPool HasherPool

DefaultHasherPool is a default hasher pool

var FastHasherPool HasherPool = HasherPool{
	HashFn: gohashtree.HashByteSlice,
}

func (*HasherPool) Get added in v0.0.6

func (hh *HasherPool) Get() *Hasher

Get acquires a Hasher from the pool.

func (*HasherPool) Put added in v0.0.6

func (hh *HasherPool) Put(h *Hasher)

Put releases the Hasher to the pool.

type SszMaxSizeHint added in v1.0.0

type SszMaxSizeHint struct {
	Size    uint64
	SpecVal bool
}

type SszSizeHint added in v1.0.0

type SszSizeHint struct {
	Size    uint32
	Dynamic bool
	SpecVal bool
}

type TypeCache added in v1.0.0

type TypeCache struct {
	// contains filtered or unexported fields
}

TypeCache manages cached type descriptors

func NewTypeCache added in v1.0.0

func NewTypeCache(dynssz *DynSsz) *TypeCache

NewTypeCache creates a new type cache

func (*TypeCache) DumpAllCachedTypes added in v1.0.0

func (tc *TypeCache) DumpAllCachedTypes() (string, error)

DumpAllCachedTypes returns a JSON representation of all cached type descriptors

func (*TypeCache) DumpTypeDescriptor added in v1.0.0

func (tc *TypeCache) DumpTypeDescriptor(t reflect.Type) (string, error)

DumpTypeDescriptor returns a JSON representation of a type descriptor for debugging

func (*TypeCache) GetTypeDescriptor added in v1.0.0

func (tc *TypeCache) GetTypeDescriptor(t reflect.Type, sizeHints []SszSizeHint, maxSizeHints []SszMaxSizeHint) (*TypeDescriptor, error)

GetTypeDescriptor returns a cached type descriptor, computing it if necessary, ensuring sequential processing

type TypeDescriptor added in v1.0.0

type TypeDescriptor struct {
	Kind                reflect.Kind
	Type                reflect.Type
	Size                int32                // SSZ size (-1 if dynamic)
	Len                 uint32               // Length of array/slice
	Fields              []FieldDescriptor    // For structs
	DynFields           []DynFieldDescriptor // Dynamic struct fields
	ElemDesc            *TypeDescriptor      // For slices/arrays
	SizeHints           []SszSizeHint        // Size hints from tags
	MaxSizeHints        []SszMaxSizeHint     // Max size hints from tags
	HasDynamicSize      bool                 // Whether this type uses dynamic spec size value that differs from the default
	HasDynamicMax       bool                 // Whether this type uses dynamic spec max value that differs from the default
	IsFastSSZMarshaler  bool                 // Whether the type implements fastssz.Marshaler
	IsFastSSZHasher     bool                 // Whether the type implements fastssz.HashRoot
	HasHashTreeRootWith bool                 // Whether the type implements HashTreeRootWith
	IsPtr               bool                 // Whether this is a pointer type
	IsByteArray         bool                 // Whether this is a byte array
}

TypeDescriptor represents a cached, optimized descriptor for a type's SSZ encoding/decoding

Directories

Path Synopsis
dynssz-gen module
test module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL