Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for uint8 en/decoding #10

Merged
merged 3 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ The table below is a summary of the methods available for `SizeSSZ` and `DefineS
| Type | Size API | Symmetric API | Asymmetric Encoding | Asymmetric Decoding | Asymmetric Hashing |
|:---------------------------:|:---------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------:|
| `bool` | `1 byte` | [`DefineBool`](https://pkg.go.dev/github.com/karalabe/ssz#DefineBool) | [`EncodeBool`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeBool) | [`DecodeBool`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeBool) | [`HashBool`](https://pkg.go.dev/github.com/karalabe/ssz#HashBool) |
| `uint8` | `1 bytes` | [`DefineUint8`](https://pkg.go.dev/github.com/karalabe/ssz#DefineUint8) | [`EncodeUint8`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeUint8) | [`DecodeUint8`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeUint8) | [`HashUint8`](https://pkg.go.dev/github.com/karalabe/ssz#HashUint8) |
| `uint64` | `8 bytes` | [`DefineUint64`](https://pkg.go.dev/github.com/karalabe/ssz#DefineUint64) | [`EncodeUint64`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeUint64) | [`DecodeUint64`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeUint64) | [`HashUint64`](https://pkg.go.dev/github.com/karalabe/ssz#HashUint64) |
| `[N]byte` as `bitvector[N]` | `N bytes` | [`DefineArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#DefineArrayOfBits) | [`EncodeArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeArrayOfBits) | [`DecodeArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeArrayOfBits) | [`HashArrayOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#HashArrayOfBits) |
| `bitfield.Bitlist`² | [`SizeSliceOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#SizeSliceOfBits) | [`DefineSliceOfBitsOffset`](https://pkg.go.dev/github.com/karalabe/ssz#DefineSliceOfBitsOffset) [`DefineSliceOfBitsContent`](https://pkg.go.dev/github.com/karalabe/ssz#DefineSliceOfBitsContent) | [`EncodeSliceOfBitsOffset`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeSliceOfBitsOffset) [`EncodeSliceOfBitsContent`](https://pkg.go.dev/github.com/karalabe/ssz#EncodeSliceOfBitsContent) | [`DecodeSliceOfBitsOffset`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeSliceOfBitsOffset) [`DecodeSliceOfBitsContent`](https://pkg.go.dev/github.com/karalabe/ssz#DecodeSliceOfBitsContent) | [`HashSliceOfBits`](https://pkg.go.dev/github.com/karalabe/ssz#HashSliceOfBits) |
Expand Down Expand Up @@ -587,4 +588,4 @@ BenchmarkMainnetState/beacon-state/208757379-bytes/encode-12 26
BenchmarkMainnetState/beacon-state/208757379-bytes/decode-12 27 40984980 ns/op 5093.51 MB/s 8456490 B/op 54910 allocs/op
BenchmarkMainnetState/beacon-state/208757379-bytes/merkleize-sequential-12 2 659472250 ns/op 316.55 MB/s 904 B/op 1 allocs/op
BenchmarkMainnetState/beacon-state/208757379-bytes/merkleize-concurrent-12 9 113414449 ns/op 1840.66 MB/s 16416 B/op 108 allocs/op
```
```
10 changes: 10 additions & 0 deletions cmd/sszgen/opset.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ func (p *parseContext) resolveBasicOpset(typ *types.Basic, tags *sizeTag) (opset
"DecodeBool({{.Codec}}, &{{.Field}})",
[]int{1},
}, nil
case types.Uint8:
if tags != nil && tags.size[0] != 1 {
return nil, fmt.Errorf("byte basic type requires ssz-size=1: have %d", tags.size[0])
}
return &opsetStatic{
"DefineUint8({{.Codec}}, &{{.Field}})",
"EncodeUint8({{.Codec}}, &{{.Field}})",
"DecodeUint8({{.Codec}}, &{{.Field}})",
[]int{1},
}, nil
case types.Uint64:
if tags != nil && tags.size[0] != 8 {
return nil, fmt.Errorf("uint64 basic type requires ssz-size=8: have %d", tags.size[0])
Expand Down
13 changes: 13 additions & 0 deletions codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ func DefineBool[T ~bool](c *Codec, v *T) {
HashBool(c.has, *v)
}

// DefineUint8 defines the next field as a uint8.
func DefineUint8[T ~uint8](c *Codec, n *T) {
if c.enc != nil {
EncodeUint8(c.enc, *n)
return
}
if c.dec != nil {
DecodeUint8(c.dec, n)
return
}
HashUint8(c.has, *n)
}

// DefineUint64 defines the next field as a uint64.
func DefineUint64[T ~uint64](c *Codec, n *T) {
if c.enc != nil {
Expand Down
19 changes: 19 additions & 0 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ func DecodeBool[T ~bool](dec *Decoder, v *T) {
}
}

// DecodeUint8 parses a uint8.
func DecodeUint8[T ~uint8](dec *Decoder, n *T) {
if dec.err != nil {
return
}
if dec.inReader != nil {
_, dec.err = io.ReadFull(dec.inReader, dec.buf[:1])
*n = T(dec.buf[0])
dec.inRead += 1
} else {
if len(dec.inBuffer) < 1 {
dec.err = io.ErrUnexpectedEOF
return
}
*n = T(dec.inBuffer[0])
dec.inBuffer = dec.inBuffer[1:]
}
}

// DecodeUint64 parses a uint64.
func DecodeUint64[T ~uint64](dec *Decoder, n *T) {
if dec.err != nil {
Expand Down
14 changes: 14 additions & 0 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ func EncodeBool[T ~bool](enc *Encoder, v T) {
}
}

// EncodeUint8 serializes a uint8.
func EncodeUint8[T ~uint8](enc *Encoder, n T) {
if enc.outWriter != nil {
if enc.err != nil {
return
}
enc.buf[0] = byte(n)
_, enc.err = enc.outWriter.Write(enc.buf[:1])
} else {
enc.outBuffer[0] = byte(n)
enc.outBuffer = enc.outBuffer[1:]
}
}

// EncodeUint64 serializes a uint64.
func EncodeUint64[T ~uint64](enc *Encoder, n T) {
// Nope, dive into actual encoding
Expand Down
7 changes: 7 additions & 0 deletions hasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ func HashBool[T ~bool](h *Hasher, v T) {
}
}

// HashUint8 hashes a uint8.
func HashUint8[T ~uint8](h *Hasher, n T) {
var buffer [32]byte
buffer[0] = uint8(n)
h.insertChunk(buffer, 0)
}

// HashUint64 hashes a uint64.
func HashUint64[T ~uint64](h *Hasher, n T) {
var buffer [32]byte
Expand Down