Unverified Commit dc351424 authored by Erin Swenson-Healey's avatar Erin Swenson-Healey Committed by GitHub
Browse files

Merge pull request #16 from filecoin-project/feat/rational-post

updates to consume new Rational PoSt API
parents b1ee4255 8b7ae87d
...@@ -106,7 +106,7 @@ commands: ...@@ -106,7 +106,7 @@ commands:
steps: steps:
- run: - run:
name: Test project name: Test project
command: go test command: RUST_LOG=info go test
restore_parameter_cache: restore_parameter_cache:
steps: steps:
- restore_cache: - restore_cache:
......
package go_sectorbuilder package go_sectorbuilder
import ( import (
"bytes"
"sort"
"time" "time"
"unsafe" "unsafe"
...@@ -22,6 +24,35 @@ func elapsed(what string) func() { ...@@ -22,6 +24,35 @@ func elapsed(what string) func() {
} }
} }
// SortedSectorInfo is a slice of SectorInfo sorted (lexicographically,
// ascending) by replica commitment (CommR).
type SortedSectorInfo struct {
f []SectorInfo
}
// NewSortedSectorInfo returns a SortedSectorInfo
func NewSortedSectorInfo(sectorInfo ...SectorInfo) SortedSectorInfo {
fn := func(i, j int) bool {
return bytes.Compare(sectorInfo[i].CommR[:], sectorInfo[j].CommR[:]) == -1
}
sort.Slice(sectorInfo[:], fn)
return SortedSectorInfo{
f: sectorInfo,
}
}
// Values returns the sorted SectorInfo as a slice
func (s *SortedSectorInfo) Values() []SectorInfo {
return s.f
}
type SectorInfo struct {
SectorID uint64
CommR [CommitmentBytesLen]byte
}
// CommitmentBytesLen is the number of bytes in a CommR, CommD, CommP, and CommRStar. // CommitmentBytesLen is the number of bytes in a CommR, CommD, CommP, and CommRStar.
const CommitmentBytesLen = 32 const CommitmentBytesLen = 32
...@@ -71,7 +102,7 @@ func VerifySeal( ...@@ -71,7 +102,7 @@ func VerifySeal(
commD [CommitmentBytesLen]byte, commD [CommitmentBytesLen]byte,
commRStar [CommitmentBytesLen]byte, commRStar [CommitmentBytesLen]byte,
proverID [31]byte, proverID [31]byte,
sectorID [31]byte, sectorID uint64,
proof []byte, proof []byte,
) (bool, error) { ) (bool, error) {
defer elapsed("VerifySeal")() defer elapsed("VerifySeal")()
...@@ -91,9 +122,6 @@ func VerifySeal( ...@@ -91,9 +122,6 @@ func VerifySeal(
proverIDCBytes := C.CBytes(proverID[:]) proverIDCBytes := C.CBytes(proverID[:])
defer C.free(proverIDCBytes) defer C.free(proverIDCBytes)
sectorIDCbytes := C.CBytes(sectorID[:])
defer C.free(sectorIDCbytes)
// a mutable pointer to a VerifySealResponse C-struct // a mutable pointer to a VerifySealResponse C-struct
resPtr := C.sector_builder_ffi_verify_seal( resPtr := C.sector_builder_ffi_verify_seal(
C.uint64_t(sectorSize), C.uint64_t(sectorSize),
...@@ -101,7 +129,7 @@ func VerifySeal( ...@@ -101,7 +129,7 @@ func VerifySeal(
(*[CommitmentBytesLen]C.uint8_t)(commDCBytes), (*[CommitmentBytesLen]C.uint8_t)(commDCBytes),
(*[CommitmentBytesLen]C.uint8_t)(commRStarCBytes), (*[CommitmentBytesLen]C.uint8_t)(commRStarCBytes),
(*[31]C.uint8_t)(proverIDCBytes), (*[31]C.uint8_t)(proverIDCBytes),
(*[31]C.uint8_t)(sectorIDCbytes), C.uint64_t(sectorID),
(*C.uint8_t)(proofCBytes), (*C.uint8_t)(proofCBytes),
C.size_t(len(proof)), C.size_t(len(proof)),
) )
...@@ -118,25 +146,25 @@ func VerifySeal( ...@@ -118,25 +146,25 @@ func VerifySeal(
// inputs were derived was valid, and false if not. // inputs were derived was valid, and false if not.
func VerifyPoSt( func VerifyPoSt(
sectorSize uint64, sectorSize uint64,
sortedCommRs [][CommitmentBytesLen]byte, sectorInfo SortedSectorInfo,
challengeSeed [CommitmentBytesLen]byte, challengeSeed [32]byte,
proofs [][]byte, proof []byte,
faults []uint64, faults []uint64,
) (bool, error) { ) (bool, error) {
defer elapsed("VerifyPoSt")() defer elapsed("VerifyPoSt")()
// validate verification request // CommRs and sector ids must be provided to C.verify_post in the same order
if len(proofs) == 0 { // that they were provided to the C.generate_post
return false, errors.New("must provide at least one proof to verify") sortedCommRs := make([][CommitmentBytesLen]byte, len(sectorInfo.Values()))
sortedSectorIds := make([]uint64, len(sectorInfo.Values()))
for idx, v := range sectorInfo.Values() {
sortedCommRs[idx] = v.CommR
sortedSectorIds[idx] = v.SectorID
} }
// CommRs must be provided to C.verify_post in the same order that they were
// provided to the C.generate_post
commRs := sortedCommRs
// flattening the byte slice makes it easier to copy into the C heap // flattening the byte slice makes it easier to copy into the C heap
flattened := make([]byte, CommitmentBytesLen*len(commRs)) flattened := make([]byte, CommitmentBytesLen*len(sortedCommRs))
for idx, commR := range commRs { for idx, commR := range sortedCommRs {
copy(flattened[(CommitmentBytesLen*idx):(CommitmentBytesLen*(1+idx))], commR[:]) copy(flattened[(CommitmentBytesLen*idx):(CommitmentBytesLen*(1+idx))], commR[:])
} }
...@@ -147,24 +175,28 @@ func VerifyPoSt( ...@@ -147,24 +175,28 @@ func VerifyPoSt(
challengeSeedCBytes := C.CBytes(challengeSeed[:]) challengeSeedCBytes := C.CBytes(challengeSeed[:])
defer C.free(challengeSeedCBytes) defer C.free(challengeSeedCBytes)
proofPartitions, proofsPtr, proofsLen := cPoStProofs(proofs) proofCBytes := C.CBytes(proof)
defer C.free(unsafe.Pointer(proofsPtr)) defer C.free(proofCBytes)
// allocate fixed-length array of uint64s in C heap // allocate fixed-length array of uint64s in C heap
sectorIdsPtr, sectorIdsSize := cUint64s(sortedSectorIds)
defer C.free(unsafe.Pointer(sectorIdsPtr))
faultsPtr, faultsSize := cUint64s(faults) faultsPtr, faultsSize := cUint64s(faults)
defer C.free(unsafe.Pointer(faultsPtr)) defer C.free(unsafe.Pointer(faultsPtr))
// a mutable pointer to a VerifyPoStResponse C-struct // a mutable pointer to a VerifyPoStResponse C-struct
resPtr := C.sector_builder_ffi_verify_post( resPtr := C.sector_builder_ffi_verify_post(
C.uint64_t(sectorSize), C.uint64_t(sectorSize),
proofPartitions,
(*C.uint8_t)(flattenedCommRsCBytes),
C.size_t(len(flattened)),
(*[CommitmentBytesLen]C.uint8_t)(challengeSeedCBytes), (*[CommitmentBytesLen]C.uint8_t)(challengeSeedCBytes),
proofsPtr, sectorIdsPtr,
proofsLen, sectorIdsSize,
faultsPtr, faultsPtr,
faultsSize, faultsSize,
(*C.uint8_t)(flattenedCommRsCBytes),
C.size_t(len(flattened)),
(*C.uint8_t)(proofCBytes),
C.size_t(len(proof)),
) )
defer C.sector_builder_ffi_destroy_verify_post_response(resPtr) defer C.sector_builder_ffi_destroy_verify_post_response(resPtr)
...@@ -210,7 +242,7 @@ func InitSectorBuilder( ...@@ -210,7 +242,7 @@ func InitSectorBuilder(
cSealedSectorDir := C.CString(sealedSectorDir) cSealedSectorDir := C.CString(sealedSectorDir)
defer C.free(unsafe.Pointer(cSealedSectorDir)) defer C.free(unsafe.Pointer(cSealedSectorDir))
class, err := cSectorClass(sectorSize, poRepProofPartitions, poStProofPartitions) class, err := cSectorClass(sectorSize, poRepProofPartitions)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get sector class") return nil, errors.Wrap(err, "failed to get sector class")
} }
...@@ -418,15 +450,22 @@ func GetSectorSealingStatusByID(sectorBuilderPtr unsafe.Pointer, sectorID uint64 ...@@ -418,15 +450,22 @@ func GetSectorSealingStatusByID(sectorBuilderPtr unsafe.Pointer, sectorID uint64
// GeneratePoSt produces a proof-of-spacetime for the provided replica commitments. // GeneratePoSt produces a proof-of-spacetime for the provided replica commitments.
func GeneratePoSt( func GeneratePoSt(
sectorBuilderPtr unsafe.Pointer, sectorBuilderPtr unsafe.Pointer,
sortedCommRs [][CommitmentBytesLen]byte, sectorInfo SortedSectorInfo,
challengeSeed [CommitmentBytesLen]byte, challengeSeed [CommitmentBytesLen]byte,
) ([][]byte, []uint64, error) { faults []uint64,
) ([]byte, error) {
defer elapsed("GeneratePoSt")() defer elapsed("GeneratePoSt")()
// CommRs and sector ids must be provided to C.verify_post in the same order
// that they were provided to the C.generate_post
sortedCommRs := make([][CommitmentBytesLen]byte, len(sectorInfo.Values()))
for idx, v := range sectorInfo.Values() {
sortedCommRs[idx] = v.CommR
}
// flattening the byte slice makes it easier to copy into the C heap // flattening the byte slice makes it easier to copy into the C heap
commRs := sortedCommRs flattened := make([]byte, CommitmentBytesLen*len(sortedCommRs))
flattened := make([]byte, CommitmentBytesLen*len(commRs)) for idx, commR := range sortedCommRs {
for idx, commR := range commRs {
copy(flattened[(CommitmentBytesLen*idx):(CommitmentBytesLen*(1+idx))], commR[:]) copy(flattened[(CommitmentBytesLen*idx):(CommitmentBytesLen*(1+idx))], commR[:])
} }
...@@ -436,25 +475,25 @@ func GeneratePoSt( ...@@ -436,25 +475,25 @@ func GeneratePoSt(
challengeSeedPtr := unsafe.Pointer(&(challengeSeed)[0]) challengeSeedPtr := unsafe.Pointer(&(challengeSeed)[0])
faultsPtr, faultsSize := cUint64s(faults)
defer C.free(unsafe.Pointer(faultsPtr))
// a mutable pointer to a GeneratePoStResponse C-struct // a mutable pointer to a GeneratePoStResponse C-struct
resPtr := C.sector_builder_ffi_generate_post( resPtr := C.sector_builder_ffi_generate_post(
(*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), (*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr),
(*C.uint8_t)(cflattened), (*C.uint8_t)(cflattened),
C.size_t(len(flattened)), C.size_t(len(flattened)),
(*[CommitmentBytesLen]C.uint8_t)(challengeSeedPtr), (*[CommitmentBytesLen]C.uint8_t)(challengeSeedPtr),
faultsPtr,
faultsSize,
) )
defer C.sector_builder_ffi_destroy_generate_post_response(resPtr) defer C.sector_builder_ffi_destroy_generate_post_response(resPtr)
if resPtr.status_code != 0 { if resPtr.status_code != 0 {
return nil, nil, errors.New(C.GoString(resPtr.error_msg)) return nil, errors.New(C.GoString(resPtr.error_msg))
}
proofs, err := goPoStProofs(resPtr.proof_partitions, resPtr.flattened_proofs_ptr, resPtr.flattened_proofs_len)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to convert to []PoStProof")
} }
return proofs, goUint64s(resPtr.faults_ptr, resPtr.faults_len), nil return goBytes(resPtr.proof_ptr, resPtr.proof_len), nil
} }
// VerifyPieceInclusionProof returns true if the piece inclusion proof is valid // VerifyPieceInclusionProof returns true if the piece inclusion proof is valid
......
...@@ -3,7 +3,6 @@ package go_sectorbuilder_test ...@@ -3,7 +3,6 @@ package go_sectorbuilder_test
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"encoding/binary"
"errors" "errors"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -64,7 +63,7 @@ func TestSectorBuilderLifecycle(t *testing.T) { ...@@ -64,7 +63,7 @@ func TestSectorBuilderLifecycle(t *testing.T) {
require.Equal(t, 1, len(status.Pieces), "expected to see the one piece we added") require.Equal(t, 1, len(status.Pieces), "expected to see the one piece we added")
// verify the seal proof // verify the seal proof
isValid, err := sb.VerifySeal(1024, status.CommR, status.CommD, status.CommRStar, [31]byte{}, sectorIdAsBytes(sectorID), status.Proof) isValid, err := sb.VerifySeal(1024, status.CommR, status.CommD, status.CommRStar, [31]byte{}, sectorID, status.Proof)
require.NoError(t, err) require.NoError(t, err)
require.True(t, isValid) require.True(t, isValid)
...@@ -73,12 +72,18 @@ func TestSectorBuilderLifecycle(t *testing.T) { ...@@ -73,12 +72,18 @@ func TestSectorBuilderLifecycle(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.True(t, isValid) require.True(t, isValid)
// enforces sort ordering of SectorInfo tuples
sectorInfo := sb.NewSortedSectorInfo(sb.SectorInfo{
SectorID: status.SectorID,
CommR: status.CommR,
})
// generate a PoSt // generate a PoSt
proofs, faults, err := sb.GeneratePoSt(ptr, [][32]byte{status.CommR}, [32]byte{}) proofs, err := sb.GeneratePoSt(ptr, sectorInfo, [32]byte{}, []uint64{})
require.NoError(t, err) require.NoError(t, err)
// verify the PoSt // verify the PoSt
isValid, err = sb.VerifyPoSt(1024, [][32]byte{status.CommR}, [32]byte{}, proofs, faults) isValid, err = sb.VerifyPoSt(1024, sectorInfo, [32]byte{}, proofs, []uint64{})
require.NoError(t, err) require.NoError(t, err)
require.True(t, isValid) require.True(t, isValid)
...@@ -124,16 +129,6 @@ func pollForSectorSealingStatus(ptr unsafe.Pointer, sectorID uint64, sealStatusC ...@@ -124,16 +129,6 @@ func pollForSectorSealingStatus(ptr unsafe.Pointer, sectorID uint64, sealStatusC
} }
} }
func sectorIdAsBytes(sectorID uint64) [31]byte {
slice := make([]byte, 31)
binary.LittleEndian.PutUint64(slice, sectorID)
var sectorIDAsBytes [31]byte
copy(sectorIDAsBytes[:], slice)
return sectorIDAsBytes
}
func requireTempFilePath(t *testing.T, fileContentsReader io.Reader) string { func requireTempFilePath(t *testing.T, fileContentsReader io.Reader) string {
file, err := ioutil.TempFile("", "") file, err := ioutil.TempFile("", "")
require.NoError(t, err) require.NoError(t, err)
......
...@@ -20,7 +20,7 @@ if download_release_tarball tarball_path "${subm_dir}"; then ...@@ -20,7 +20,7 @@ if download_release_tarball tarball_path "${subm_dir}"; then
mkdir -p bin mkdir -p bin
cp "${tmp_dir}/bin/paramfetch" bin cp "${tmp_dir}/bin/paramfetch" bin
else else
echo "failed to find or obtain precompiled assets for ${subm_dir}, falling back to local build" (>&2 echo "failed to find or obtain precompiled assets for ${subm_dir} - falling back to local build")
build_from_source "${subm_dir}" build_from_source "${subm_dir}"
mkdir -p include mkdir -p include
...@@ -32,10 +32,19 @@ else ...@@ -32,10 +32,19 @@ else
pushd $subm_dir pushd $subm_dir
# TODO https://github.com/filecoin-project/rust-fil-sector-builder/issues/39 s="WARNING: paramfetch cannot be built from rust-fil-sector-builder "
FP_VERSION=$(cat "Cargo.lock" | grep 'name = "filecoin-proofs"' -A1 | tail -n1 | cut -d' ' -f3 | tr -d '"') s+="sources. Installing from HEAD of rust-fil-proofs master. The installed "
s+="version of paramfetch may be incompatible with your version of "
cargo install --version $FP_VERSION filecoin-proofs --root '..' --bin paramfetch s+="rust-fil-sector-builder, which could result in you downloading "
s+="incompatible Groth parameters and verifying keys."
(>&2 echo s)
cargo install filecoin-proofs \
--bin paramfetch \
--force \
--git=https://github.com/filecoin-project/rust-fil-proofs.git \
--branch=master \
--root ".."
popd popd
fi fi
Subproject commit 604b487673fa52744218abbe45972c1ee0b8d8cb Subproject commit 0282a636f7911bcfd0348af5494da5932ac5808b
...@@ -37,7 +37,7 @@ for attempt in `seq 1 $attempts`; do ...@@ -37,7 +37,7 @@ for attempt in `seq 1 $attempts`; do
sleep_seconds=$(echo "scale=2; ${sleep_ms}/1000" | bc) sleep_seconds=$(echo "scale=2; ${sleep_ms}/1000" | bc)
>&2 echo "sleeping ${sleep_seconds}s and then retrying ($((attempt + 1))/${attempts})" (>&2 echo "sleeping ${sleep_seconds}s and then retrying ($((attempt + 1))/${attempts})")
sleep "${sleep_seconds}" sleep "${sleep_seconds}"
done done
...@@ -16,22 +16,6 @@ import "C" ...@@ -16,22 +16,6 @@ import "C"
// with the number of partitions used when creating that proof. // with the number of partitions used when creating that proof.
const SingleProofPartitionProofLen = 192 const SingleProofPartitionProofLen = 192
func cPoStProofs(src [][]byte) (C.uint8_t, *C.uint8_t, C.size_t) {
proofSize := len(src[0])
flattenedLen := C.size_t(proofSize * len(src))
// flattening the byte slice makes it easier to copy into the C heap
flattened := make([]byte, flattenedLen)
for idx, proof := range src {
copy(flattened[(proofSize*idx):(proofSize*(1+idx))], proof[:])
}
proofPartitions := proofSize / SingleProofPartitionProofLen
return C.uint8_t(proofPartitions), (*C.uint8_t)(C.CBytes(flattened)), flattenedLen
}
func cUint64s(src []uint64) (*C.uint64_t, C.size_t) { func cUint64s(src []uint64) (*C.uint64_t, C.size_t) {
srcCSizeT := C.size_t(len(src)) srcCSizeT := C.size_t(len(src))
...@@ -47,11 +31,10 @@ func cUint64s(src []uint64) (*C.uint64_t, C.size_t) { ...@@ -47,11 +31,10 @@ func cUint64s(src []uint64) (*C.uint64_t, C.size_t) {
return (*C.uint64_t)(cUint64s), srcCSizeT return (*C.uint64_t)(cUint64s), srcCSizeT
} }
func cSectorClass(sectorSize uint64, poRepProofPartitions uint8, poStProofPartitions uint8) (C.sector_builder_ffi_FFISectorClass, error) { func cSectorClass(sectorSize uint64, poRepProofPartitions uint8) (C.sector_builder_ffi_FFISectorClass, error) {
return C.sector_builder_ffi_FFISectorClass{ return C.sector_builder_ffi_FFISectorClass{
sector_size: C.uint64_t(sectorSize), sector_size: C.uint64_t(sectorSize),
porep_proof_partitions: C.uint8_t(poRepProofPartitions), porep_proof_partitions: C.uint8_t(poRepProofPartitions),
post_proof_partitions: C.uint8_t(poStProofPartitions),
}, nil }, nil
} }
...@@ -137,25 +120,3 @@ func goPieceMetadata(src *C.sector_builder_ffi_FFIPieceMetadata, size C.size_t) ...@@ -137,25 +120,3 @@ func goPieceMetadata(src *C.sector_builder_ffi_FFIPieceMetadata, size C.size_t)
return ps, nil return ps, nil
} }
func goPoStProofs(partitions C.uint8_t, src *C.uint8_t, size C.size_t) ([][]byte, error) {
tmp := goBytes(src, size)
arraySize := len(tmp)
chunkSize := int(partitions) * SingleProofPartitionProofLen
out := make([][]byte, arraySize/chunkSize)
for i := 0; i < len(out); i++ {
out[i] = append([]byte{}, tmp[i*chunkSize:(i+1)*chunkSize]...)
}
return out, 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
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment