/
genhtr.go
69 lines (63 loc) · 1.85 KB
/
genhtr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package backend
import (
"bytes"
"fmt"
"strings"
"text/template"
"github.com/OffchainLabs/methodical-ssz/sszgen/interfaces"
)
// ChunkSize is used to check if packed bytes align to the chunk sized used by the
// merkleization algorithm. If not, the bytes should be zero-padded to the
// nearest multiple of ChunkSize.
const ChunkSize = 32
var htrTmpl = `func ({{.Receiver}} {{.Type}}) HashTreeRoot() ([32]byte, error) {
hh := ssz.DefaultHasherPool.Get()
if err := {{.Receiver}}.HashTreeRootWith(hh); err != nil {
ssz.DefaultHasherPool.Put(hh)
return [32]byte{}, err
}
root, err := hh.HashRoot()
ssz.DefaultHasherPool.Put(hh)
return root, err
}
func ({{.Receiver}} {{.Type}}) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
{{.HTRSteps}}
hh.Merkleize(indx)
return nil
}`
func GenerateHashTreeRoot(g *generateContainer) (*generatedCode, error) {
htrTmpl, err := template.New("GenerateHashTreeRoot").Parse(htrTmpl)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(nil)
htrSteps := make([]string, 0)
for i, c := range g.Contents {
fieldName := fmt.Sprintf("%s.%s", receiverName, c.Key)
htrSteps = append(htrSteps, fmt.Sprintf("\t// Field %d: %s", i, c.Key))
vg := newValueGenerator(interfaces.SszLightHasher, c.Value, g.targetPackage, g.importNamer)
htrp, ok := vg.(htrPutter)
if !ok {
continue
}
htrSteps = append(htrSteps, htrp.generateHTRPutter(fieldName))
}
err = htrTmpl.Execute(buf, struct {
Receiver string
Type string
HTRSteps string
}{
Receiver: receiverName,
Type: fmt.Sprintf("*%s", g.TypeName()),
HTRSteps: strings.Join(htrSteps, "\n"),
})
if err != nil {
return nil, err
}
// TODO: allow GenerateHashTreeRoot to return an error since template.Execute
// can technically return an error (get rid of the panics)
return &generatedCode{
blocks: []string{buf.String()},
}, nil
}