-
Notifications
You must be signed in to change notification settings - Fork 35
/
bindnodeoptions.go
104 lines (87 loc) · 2.92 KB
/
bindnodeoptions.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
Package ipld provides tools for working with Filecoin types as IPLD nodes.
These functions allow you to wrap Filecoin types into a go-ipld-prime node
interface using the bindnode package.
*/
package ipld
import (
"fmt"
"github.com/ipld/go-ipld-prime/node/bindnode"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
)
// go type converter functions for bindnode for common Filecoin data types
// BigIntBindnodeOption converts a big.Int type to and from a Bytes field in a
// schema
var BigIntBindnodeOption = bindnode.TypedBytesConverter(&big.Int{}, bigIntFromBytes, bigIntToBytes)
// TokenAmountBindnodeOption converts a filecoin abi.TokenAmount type to and
// from a Bytes field in a schema
var TokenAmountBindnodeOption = bindnode.TypedBytesConverter(&abi.TokenAmount{}, tokenAmountFromBytes, tokenAmountToBytes)
// AddressBindnodeOption converts a filecoin Address type to and from a Bytes
// field in a schema
var AddressBindnodeOption = bindnode.TypedBytesConverter(&address.Address{}, addressFromBytes, addressToBytes)
// SignatureBindnodeOption converts a filecoin Signature type to and from a
// Bytes field in a schema
var SignatureBindnodeOption = bindnode.TypedBytesConverter(&crypto.Signature{}, signatureFromBytes, signatureToBytes)
func tokenAmountFromBytes(b []byte) (interface{}, error) {
return bigIntFromBytes(b)
}
func bigIntFromBytes(b []byte) (interface{}, error) {
if len(b) == 0 {
return big.NewInt(0), nil
}
return big.FromBytes(b)
}
func tokenAmountToBytes(iface interface{}) ([]byte, error) {
return bigIntToBytes(iface)
}
func bigIntToBytes(iface interface{}) ([]byte, error) {
bi, ok := iface.(*big.Int)
if !ok {
return nil, fmt.Errorf("expected *big.Int value")
}
if bi == nil || bi.Int == nil {
*bi = big.Zero()
}
return bi.Bytes()
}
func addressFromBytes(b []byte) (interface{}, error) {
return address.NewFromBytes(b)
}
func addressToBytes(iface interface{}) ([]byte, error) {
addr, ok := iface.(*address.Address)
if !ok {
return nil, fmt.Errorf("expected *Address value")
}
return addr.Bytes(), nil
}
// Signature is a byteprefix union
func signatureFromBytes(b []byte) (interface{}, error) {
if len(b) > crypto.SignatureMaxLength {
return nil, fmt.Errorf("string too long")
}
if len(b) == 0 {
return nil, fmt.Errorf("string empty")
}
var s crypto.Signature
switch crypto.SigType(b[0]) {
default:
return nil, fmt.Errorf("invalid signature type in cbor input: %d", b[0])
case crypto.SigTypeSecp256k1:
s.Type = crypto.SigTypeSecp256k1
case crypto.SigTypeBLS:
s.Type = crypto.SigTypeBLS
}
s.Data = b[1:]
return &s, nil
}
func signatureToBytes(iface interface{}) ([]byte, error) {
s, ok := iface.(*crypto.Signature)
if !ok {
return nil, fmt.Errorf("expected *Signature value")
}
ba := append([]byte{byte(s.Type)}, s.Data...)
return ba, nil
}