transforms.go 3.78 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
88
89
90
91
92
93
94
95
96
97
98
99
100
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")
		}

		sectors[i] = SealedSectorMetadata{
			SectorID:  uint64(ptrs[i].sector_id),
			CommD:     commD,
			CommR:     commR,
			CommRStar: commRStar,
			Proof:     proof,
			Pieces:    pieces,
		}
	}

	return sectors, nil
}

101
102
103
104
105
106
107
108
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++ {
109
110
111
112
		commPSlice := goBytes(&ptrs[i].comm_p[0], CommitmentBytesLen)
		var commP [CommitmentBytesLen]byte
		copy(commP[:], commPSlice)

113
		ps[i] = PieceMetadata{
114
115
116
117
			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),
118
119
120
121
122
123
124
125
126
127
128
129
130
		}
	}

	return ps, nil
}

func goUint64s(src *C.uint64_t, size C.size_t) []uint64 {
	out := make([]uint64, size)
	if src != nil {
		copy(out, (*(*[1 << 30]uint64)(unsafe.Pointer(src)))[:size:size])
	}
	return out
}