transforms.go 4.23 KB
Newer Older
1
package go_sectorbuilder
2
3
4

import (
	"unsafe"
Sidney Keese's avatar
Sidney Keese committed
5
6

	"github.com/pkg/errors"
7
8
)

9
10
11
// #cgo LDFLAGS: ${SRCDIR}/libsector_builder_ffi.a
// #cgo pkg-config: ${SRCDIR}/sector_builder_ffi.pc
// #include "./sector_builder_ffi.h"
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import "C"

// SingleProofPartitionProofLen denotes the number of bytes in a proof generated
// with a single partition. The number of bytes in a proof increases linearly
// with the number of partitions used when creating that proof.
const SingleProofPartitionProofLen = 192

func cUint64s(src []uint64) (*C.uint64_t, C.size_t) {
	srcCSizeT := C.size_t(len(src))

	// allocate array in C heap
	cUint64s := C.malloc(srcCSizeT * C.sizeof_uint64_t)

	// create a Go slice backed by the C-array
	pp := (*[1 << 30]C.uint64_t)(cUint64s)
	for i, v := range src {
		pp[i] = C.uint64_t(v)
	}

	return (*C.uint64_t)(cUint64s), srcCSizeT
}

laser's avatar
laser committed
34
func cSectorClass(sectorSize uint64, poRepProofPartitions uint8) (C.sector_builder_ffi_FFISectorClass, error) {
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
	return C.sector_builder_ffi_FFISectorClass{
		sector_size:            C.uint64_t(sectorSize),
		porep_proof_partitions: C.uint8_t(poRepProofPartitions),
	}, nil
}

func goBytes(src *C.uint8_t, size C.size_t) []byte {
	return C.GoBytes(unsafe.Pointer(src), C.int(size))
}

func goStagedSectorMetadata(src *C.sector_builder_ffi_FFIStagedSectorMetadata, size C.size_t) ([]StagedSectorMetadata, error) {
	sectors := make([]StagedSectorMetadata, size)
	if src == nil || size == 0 {
		return sectors, nil
	}

	sectorPtrs := (*[1 << 30]C.sector_builder_ffi_FFIStagedSectorMetadata)(unsafe.Pointer(src))[:size:size]
	for i := 0; i < int(size); i++ {
		sectors[i] = StagedSectorMetadata{
			SectorID: uint64(sectorPtrs[i].sector_id),
		}
	}

	return sectors, nil
}

Sidney Keese's avatar
Sidney Keese committed
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
func goSealedSectorMetadata(src *C.sector_builder_ffi_FFISealedSectorMetadata, size C.size_t) ([]SealedSectorMetadata, error) {
	sectors := make([]SealedSectorMetadata, size)
	if src == nil || size == 0 {
		return sectors, nil
	}

	ptrs := (*[1 << 30]C.sector_builder_ffi_FFISealedSectorMetadata)(unsafe.Pointer(src))[:size:size]
	for i := 0; i < int(size); i++ {
		commDSlice := goBytes(&ptrs[i].comm_d[0], CommitmentBytesLen)
		var commD [CommitmentBytesLen]byte
		copy(commD[:], commDSlice)

		commRSlice := goBytes(&ptrs[i].comm_r[0], CommitmentBytesLen)
		var commR [CommitmentBytesLen]byte
		copy(commR[:], commRSlice)

		commRStarSlice := goBytes(&ptrs[i].comm_r_star[0], CommitmentBytesLen)
		var commRStar [CommitmentBytesLen]byte
		copy(commRStar[:], commRStarSlice)

		proof := goBytes(ptrs[i].proofs_ptr, ptrs[i].proofs_len)

		pieces, err := goPieceMetadata(ptrs[i].pieces_ptr, ptrs[i].pieces_len)
		if err != nil {
			return []SealedSectorMetadata{}, errors.Wrap(err, "failed to marshal piece metadata")
		}

88
89
90
91
92
		health, err := goSealedSectorHealth(ptrs[i].health)
		if err != nil {
			return []SealedSectorMetadata{}, errors.Wrap(err, "failed to marshal sealed sector health")
		}

Sidney Keese's avatar
Sidney Keese committed
93
94
95
96
97
98
99
		sectors[i] = SealedSectorMetadata{
			SectorID:  uint64(ptrs[i].sector_id),
			CommD:     commD,
			CommR:     commR,
			CommRStar: commRStar,
			Proof:     proof,
			Pieces:    pieces,
100
			Health:    health,
Sidney Keese's avatar
Sidney Keese committed
101
102
103
104
105
106
		}
	}

	return sectors, nil
}

107
108
109
110
111
112
113
114
func goPieceMetadata(src *C.sector_builder_ffi_FFIPieceMetadata, size C.size_t) ([]PieceMetadata, error) {
	ps := make([]PieceMetadata, size)
	if src == nil || size == 0 {
		return ps, nil
	}

	ptrs := (*[1 << 30]C.sector_builder_ffi_FFIPieceMetadata)(unsafe.Pointer(src))[:size:size]
	for i := 0; i < int(size); i++ {
115
116
117
118
		commPSlice := goBytes(&ptrs[i].comm_p[0], CommitmentBytesLen)
		var commP [CommitmentBytesLen]byte
		copy(commP[:], commPSlice)

119
		ps[i] = PieceMetadata{
120
121
122
123
			Key:            C.GoString(ptrs[i].piece_key),
			Size:           uint64(ptrs[i].num_bytes),
			CommP:          commP,
			InclusionProof: goBytes(ptrs[i].piece_inclusion_proof_ptr, ptrs[i].piece_inclusion_proof_len),
124
125
126
127
128
		}
	}

	return ps, nil
}
129
130
131

func goSealedSectorHealth(health C.sector_builder_ffi_FFISealedSectorHealth) (SealedSectorHealth, error) {
	switch health {
132
	case C.Unknown:
133
		return Unknown, nil
134
	case C.Ok:
135
		return Ok, nil
136
	case C.ErrorInvalidChecksum:
137
		return ErrorInvalidChecksum, nil
138
	case C.ErrorInvalidLength:
139
		return ErrorInvalidLength, nil
140
	case C.ErrorMissing:
141
142
143
144
145
		return ErrorMissing, nil
	default:
		return Unknown, errors.Errorf("unhandled sealed sector health: %v", health)
	}
}