ferranbt / fastssz

Fast Ethereum2.0 SSZ encoder/decoder
MIT License
73 stars 44 forks source link

support custom marshal/unmarshal/hashroot #161

Closed jshufro closed 3 months ago

jshufro commented 3 months ago

Similar to json custom marshaling and unmarshaling, if a type already defines receivers that make it a Marshaler and Unmarshaler, use those receivers when that type is encountered by the generator.

This is particularly useful because fastssz doesn't provide a uint256 type, etc

e.g.:

type Foo struct {
  FieldOne Bar
}

type Bar struct {
  ssz.Unmarshaler
  ssz.Marshaler
  ssz.HashRoot
  ... unexported fields ...
}

sszgen should be able to create a serializer for Foo that calls Bar.MarshalSSZTo etc wherever appropriate.

jshufro commented 3 months ago

More specifically, it'd be great if i could import https://github.com/holiman/uint256

and then use *uint256.Int fields in a struct and then generate ssz encoding for that struct

ferranbt commented 3 months ago

This feature is already available (example).

jshufro commented 3 months ago

when trying to use the imported type i get:

$ ./gen.sh 
[ERR]: failed to encode SSZFile_v1: could not find struct with name 'Int'

where the struct has:

import "github.com/holiman/uint256"

// static type assertions
var _ ssz.Marshaler = (*uint256.Int)(nil)
var _ ssz.Unmarshaler = (*uint256.Int)(nil)
var _ ssz.HashRoot = (*uint256.Int)(nil)

type SSZFile_v1 struct {
  Test *uint256.Int
}

Wrapping gives me this error: [ERR]: failed to encode SSZFile_v1: failed to encode UU: embed type expects a typed object in same package but *ast.SelectorExpr found

ie

type UU struct {
        uint256.Int
}
jshufro commented 3 months ago

Ah I just noticed that holiman's library doesn't implement HashTreeRootWith :cry:

jshufro commented 3 months ago

Managed to get it working with a wrapper. Holiman's MarshalSSZTo implementation is incompatible, interestingly, and I had to do some man-in-the-middle stuff.