Skip to content

Commit

Permalink
Support time.Time (#100)
Browse files Browse the repository at this point in the history
* Support time.Time as a uint64.

* Move tests to testcases directory.

* Add reference for time type.

* Use helpers for marshal and unmarshal.

* DRY
  • Loading branch information
mcdee authored Aug 2, 2022
1 parent bd3f11a commit 82e4cce
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 2 deletions.
11 changes: 11 additions & 0 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/binary"
"fmt"
"math/bits"
"time"
)

// MarshalSSZ marshals an object
Expand Down Expand Up @@ -66,6 +67,11 @@ func UnmarshalBool(src []byte) bool {
return false
}

// UnmarshalTime unmarshals a time.Time from the src input
func UnmarshalTime(src []byte) time.Time {
return time.Unix(int64(UnmarshallUint64(src)), 0).UTC()
}

// ---- Marshal functions ----

// MarshalUint64 marshals a little endian uint64 to dst
Expand Down Expand Up @@ -108,6 +114,11 @@ func MarshalBool(dst []byte, b bool) []byte {
return dst
}

// MarshalTime marshals a time to dst
func MarshalTime(dst []byte, t time.Time) []byte {
return MarshalUint64(dst, uint64(t.Unix()))
}

// ---- offset functions ----

// WriteOffset writes an offset to dst
Expand Down
1 change: 1 addition & 0 deletions sszgen/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sszgen
10 changes: 9 additions & 1 deletion sszgen/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ const (
TypeContainer
// TypeReference is a SSZ reference
TypeReference
// TypeTime is a timestamp
TypeTime
)

func (t Type) String() string {
Expand All @@ -231,6 +233,8 @@ func (t Type) String() string {
return "container"
case TypeReference:
return "reference"
case TypeTime:
return "time.Time"
default:
panic("not found")
}
Expand Down Expand Up @@ -1056,7 +1060,9 @@ func (e *env) parseASTFieldType(name, tags string, expr ast.Expr) (*Value, error
name := obj.X.(*ast.Ident).Name
sel := obj.Sel.Name

if sel == "Bitlist" {
if name == "time" && sel == "Time" {
return &Value{t: TypeTime, s: 8}, nil
} else if sel == "Bitlist" {
// go-bitfield/Bitlist
maxSize, ok := getTagsInt(tags, "ssz-max")
if !ok {
Expand Down Expand Up @@ -1174,6 +1180,8 @@ func (v *Value) isFixed() bool {
return true
}
return false
case TypeTime:
return true
default:
// TypeUndefined should be the only type to fallthrough to this case
// TypeUndefined always means there is a fatal error in the parsing logic
Expand Down
3 changes: 3 additions & 0 deletions sszgen/generator/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ func (v *Value) hashTreeRoot(name string, appendBytes bool) string {
"htrCall": htrCall,
})

case TypeTime:
return fmt.Sprintf("hh.PutUint64(uint64(%s.Unix()))", name)

default:
panic(fmt.Errorf("hash not implemented for type %s", v.t.String()))
}
Expand Down
3 changes: 3 additions & 0 deletions sszgen/generator/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ func (v *Value) marshal() string {
case TypeList:
return v.marshalList()

case TypeTime:
return fmt.Sprintf("dst = ssz.MarshalTime(dst, ::.%s)", v.name)

default:
panic(fmt.Errorf("marshal not implemented for type %s", v.t.String()))
}
Expand Down
5 changes: 4 additions & 1 deletion sszgen/generator/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ func (v *Value) unmarshal(dst string) string {
case TypeBool:
return fmt.Sprintf("::.%s = ssz.UnmarshalBool(%s)", v.name, dst)

case TypeTime:
return fmt.Sprintf("::.%s = ssz.UnmarshalTime(%s)", v.name, dst)

default:
panic(fmt.Errorf("unmarshal not implemented for type %d", v.t))
}
Expand Down Expand Up @@ -352,6 +355,6 @@ func (v *Value) createSlice(useNumVariable bool) string {
return fmt.Sprintf("::.%s = make([][]byte, %s)", v.name, size)

default:
panic(fmt.Sprintf("create not implemented for type %s", v.e.t.String()))
panic(fmt.Sprintf("create not implemented for %s type %s", v.name, v.e.t.String()))
}
}
13 changes: 13 additions & 0 deletions sszgen/testcases/time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package testcases

import "time"

type TimeType struct {
Timestamp time.Time
Int uint64
}

type TimeRawType struct {
Timestamp uint64
Int uint64
}
137 changes: 137 additions & 0 deletions sszgen/testcases/time_encoding.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 82e4cce

Please sign in to comment.