prysm-pulse/shared/ssz
Preston Van Loon 5adbaa2e23
Add example encoding for godoc ssz (#1687)
* Add example encoding for godoc ssz

* A bit more comments

* Add comment about fatal error
2019-02-22 12:50:28 -05:00
..
BUILD.bazel Add example encoding for godoc ssz (#1687) 2019-02-22 12:50:28 -05:00
decode_test.go Support Encode/Decode of Nil Pointer (#1553) 2019-02-12 09:17:56 +05:30
decode.go Use Tree Hashing Algorithm Everywhere for Block Roots and State Root (#1577) 2019-02-14 14:04:47 -06:00
doc.go SSZ: Support More Types (#1079) 2018-12-14 12:35:32 -06:00
encode_test.go Support Encode/Decode of Nil Pointer (#1553) 2019-02-12 09:17:56 +05:30
encode.go Use Tree Hashing Algorithm Everywhere for Block Roots and State Root (#1577) 2019-02-14 14:04:47 -06:00
example_and_test.go Makes test naming consistent across codebase (#1636) 2019-02-22 07:11:26 -08:00
example_encode_test.go Add example encoding for godoc ssz (#1687) 2019-02-22 12:50:28 -05:00
hash_test.go Support typed nil pointer in tree hash (#1590) 2019-02-14 09:22:12 -06:00
hash.go Use Tree Hashing Algorithm Everywhere for Block Roots and State Root (#1577) 2019-02-14 14:04:47 -06:00
README.md Implement SSZ Tree Hash Algorithm (#1211) 2019-01-02 11:14:12 -08:00
ssz_utils_cache.go Implement SSZ Tree Hash Algorithm (#1211) 2019-01-02 11:14:12 -08:00

Simple Serialize (SSZ)

This package implements simple serialize algorithm specified in official Ethereum 2.0 spec.

Interface

Encodable

A type is Encodable if it implements EncodeSSZ and EncodeSSZSize function.

type Encodable interface {
	EncodeSSZ(io.Writer) error
	// Estimate the encoding size of the object without doing the actual encoding
	EncodeSSZSize() (uint32, error)
}

Decodable

A type is Decodable if it implements DecodeSSZ().

type Decodable interface {
	DecodeSSZ(io.Reader) error
}

Hashable

A type is Hashable if it implements TreeHashSSZ().

type Hashable interface {
	TreeHashSSZ() ([32]byte, error)
}

API

Encoding function

// Encode val and output the result into w.
func Encode(w io.Writer, val interface{}) error
// EncodeSize returns the target encoding size without doing the actual encoding.
// This is an optional pass. You don't need to call this before the encoding unless you
// want to know the output size first.
func EncodeSize(val interface{}) (uint32, error)

Decoding function

// Decode data read from r and output it into the object pointed by pointer val.
func Decode(r io.Reader, val interface{}) error

Hashing function

// Tree-hash data into [32]byte
func TreeHash(val interface{}) ([32]byte, error)

Usage

Say you have a struct like this

type exampleStruct1 struct {
	Field1 uint8
	Field2 []byte
}

You implement the Encoding interface for it:

func (e *exampleStruct1) EncodeSSZ(w io.Writer) error {
	return Encode(w, *e)
}

func (e *exampleStruct1) EncodeSSZSize() (uint32, error) {
	return EncodeSize(*e)
}

Now you can encode this object like this

e1 := &exampleStruct1{
    Field1: 10,
    Field2: []byte{1, 2, 3, 4},
}
wBuf := new(bytes.Buffer)
if err = e1.EncodeSSZ(wBuf); err != nil {
    return fmt.Errorf("failed to encode: %v", err)
}
encoding := wBuf.Bytes() // encoding becomes [0 0 0 9 10 0 0 0 4 1 2 3 4]

You can also get the estimated encoding size

var encodeSize uint32
if encodeSize, err = e1.EncodeSSZSize(); err != nil {
    return fmt.Errorf("failed to get encode size: %v", err)
}
// encodeSize becomes 13

To calculate tree-hash of the object

var hash [32]byte
if hash, err = e1.TreeHashSSZ(); err != nil {
    return fmt.Errorf("failed to hash: %v", err)
}
// hash stores the hashing result

Similarly, you can implement the Decodable interface for this struct

func (e *exampleStruct1) DecodeSSZ(r io.Reader) error {
	return Decode(r, e)
}

Now you can decode to create new struct

e2 := new(exampleStruct1)
rBuf := bytes.NewReader(encoding)
if err = e2.DecodeSSZ(rBuf); err != nil {
    return fmt.Errorf("failed to decode: %v", err)
}
// e2 now has the same content as e1

Notes

Supported data types

  • uint8
  • uint16
  • uint32
  • uint64
  • slice
  • array
  • struct
  • pointer (nil pointer is not supported)