/
marshal.go
68 lines (61 loc) · 2.07 KB
/
marshal.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
package uncles
import (
"fmt"
"io"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ipld/go-ipld-prime"
dageth "github.com/vulcanize/go-codec-dageth"
dageth_header "github.com/vulcanize/go-codec-dageth/header"
"github.com/vulcanize/go-codec-dageth/shared"
)
// Encode provides an IPLD codec encode interface for eth uncles IPLDs (header list).
// This function is registered via the go-ipld-prime link loader for multicodec
// code 0x91 when this package is invoked via init.
func Encode(node ipld.Node, w io.Writer) error {
// 1KiB can be allocated on the stack, and covers most small nodes
// without having to grow the buffer and cause allocations.
enc := make([]byte, 0, 1024)
enc, err := AppendEncode(enc, node)
if err != nil {
return err
}
_, err = w.Write(enc)
return err
}
// AppendEncode is like Encode, but it uses a destination buffer directly.
// This means less copying of bytes, and if the destination has enough capacity,
// fewer allocations.
func AppendEncode(enc []byte, inNode ipld.Node) ([]byte, error) {
uncles := make([]*types.Header, 0, inNode.Length())
if err := EncodeUncles(&uncles, inNode); err != nil {
return enc, err
}
wbs := shared.NewWriteableByteSlice(&enc)
if err := rlp.Encode(wbs, uncles); err != nil {
return enc, fmt.Errorf("invalid DAG-ETH Uncles form (unable to RLP encode uncles: %v)", err)
}
return enc, nil
}
// EncodeUncles packs the node into a list of go-ethereum headers
func EncodeUncles(uncles *[]*types.Header, inNode ipld.Node) error {
// Wrap in a typed node for some basic schema form checking
builder := dageth.Type.Uncles.NewBuilder()
if err := builder.AssignNode(inNode); err != nil {
return err
}
node := builder.Build()
unclesIt := node.ListIterator()
for !unclesIt.Done() {
_, uncleNode, err := unclesIt.Next()
if err != nil {
return err
}
uncle := new(types.Header)
if err := dageth_header.EncodeHeader(uncle, uncleNode); err != nil {
return fmt.Errorf("invalid DAG-ETH Uncles form (%v)", err)
}
*uncles = append(*uncles, uncle)
}
return nil
}