Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle allocations for problematic structs to avoid sharing pointers-to-pointers with C (from Go) #82

Merged
merged 8 commits into from
May 5, 2020
5 changes: 2 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ workflows:
branches:
only:
- master
- feat/lint-during-build
- build_darwin_cgo_bindings
- publish_darwin_staticlib:
filters:
Expand Down Expand Up @@ -320,13 +319,13 @@ commands:
no_output_timeout: 60m
- run:
name: Test project
command: RUST_LOG=info go test -p 1 -timeout 60m
command: GODEBUG=cgocheck=2 RUST_LOG=info go test -p 1 -timeout 60m
no_output_timeout: 60m
compile_tests:
steps:
- run:
name: Build project and tests, but don't actually run the tests (used to verify that build/link works with Darwin)
command: RUST_LOG=info go test -run=^$
command: GODEBUG=cgocheck=2 RUST_LOG=info go test -run=^$
restore_parameter_cache:
steps:
- restore_cache:
Expand Down
10 changes: 5 additions & 5 deletions bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ func Verify(signature *Signature, digests []Digest, publicKeys []PublicKey) bool

// HashVerify verifies that a signature is the aggregated signature of hashed messages.
func HashVerify(signature *Signature, messages []Message, publicKeys []PublicKey) bool {
messagesPtrs := make([]string, len(messages))
var flattenedMessages string
messagesSizes := make([]uint, len(messages))
for idx, msg := range messages {
messagesPtrs[idx] = string(msg)
messagesSizes[idx] = uint(len(msg))
for idx := range messages {
flattenedMessages = flattenedMessages + string(messages[idx])
messagesSizes[idx] = uint(len(messages[idx]))
}

flattenedPublicKeys := make([]byte, PublicKeyBytes*len(publicKeys))
for idx, publicKey := range publicKeys {
copy(flattenedPublicKeys[(PublicKeyBytes*idx):(PublicKeyBytes*(1+idx))], publicKey[:])
}

isValid := generated.FilHashVerify(string(signature[:]), messagesPtrs, messagesSizes, uint(len(messages)), string(flattenedPublicKeys), uint(len(flattenedPublicKeys)))
isValid := generated.FilHashVerify(string(signature[:]), flattenedMessages, uint(len(flattenedMessages)), messagesSizes, uint(len(messagesSizes)), string(flattenedPublicKeys), uint(len(flattenedPublicKeys)))

return isValid > 0
}
Expand Down
48 changes: 0 additions & 48 deletions generated/cgo_helpers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions generated/customallocs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package generated

/*
#cgo LDFLAGS: -L${SRCDIR}/.. -lfilcrypto
#cgo pkg-config: ${SRCDIR}/../filcrypto.pc
#include "../filcrypto.h"
#include <stdlib.h>
#include "cgo_helpers.h"
*/
import "C"
import (
"unsafe"
)

// AllocateProxy allocates a FilPrivateReplicaInfo proxy object in the C heap,
// returning a function which, when called, frees the allocated memory. This
// method exists because the default c-for-go allocation strategy allocates a
// C struct with a field whose values is a pointer into the Go heap, which is
// not permitted by the most strict CGO check (cgocheck=2).
func (x *FilPrivateReplicaInfo) AllocateProxy() func() {
mem := allocFilPrivateReplicaInfoMemory(1)
proxy := (*C.fil_PrivateReplicaInfo)(mem)
proxy.cache_dir_path = C.CString(x.CacheDirPath)
proxy.comm_r = *(*[32]C.uint8_t)(unsafe.Pointer(&x.CommR))
proxy.registered_proof = (C.fil_RegisteredPoStProof)(x.RegisteredProof)
proxy.replica_path = C.CString(x.ReplicaPath)
proxy.sector_id = (C.uint64_t)(x.SectorId)

x.ref81a31e9b = proxy

return func() {
C.free(unsafe.Pointer(proxy.cache_dir_path))
C.free(unsafe.Pointer(proxy.replica_path))
C.free(unsafe.Pointer(proxy))
}
}

// AllocateProxy allocates a FilPoStProof proxy object in the C heap,
// returning a function which, when called, frees the allocated memory.
func (x *FilPoStProof) AllocateProxy() func() {
mem := allocFilPoStProofMemory(1)
proxy := (*C.fil_PoStProof)(mem)

proxy.registered_proof = (C.fil_RegisteredPoStProof)(x.RegisteredProof)
proxy.proof_len = (C.size_t)(x.ProofLen)
proxy.proof_ptr = (*C.uchar)(unsafe.Pointer(C.CString(x.ProofPtr)))

x.ref3451bfa = proxy

return func() {
C.free(unsafe.Pointer(proxy.proof_ptr))
C.free(unsafe.Pointer(proxy))
}
}
55 changes: 29 additions & 26 deletions generated/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading