Commit 7ac74f81 authored by laser's avatar laser
Browse files

feat(enforce sort order-invariant with type system)

parent 8bec037d
package go_sectorbuilder
import (
"bytes"
"sort"
"time"
"unsafe"
......@@ -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.
const CommitmentBytesLen = 32
......@@ -115,21 +146,25 @@ func VerifySeal(
// inputs were derived was valid, and false if not.
func VerifyPoSt(
sectorSize uint64,
sortedCommRs [][CommitmentBytesLen]byte,
sortedSectorIds []uint64, // TODO: Use a better type, combining with sortedCommRs
sectorInfo SortedSectorInfo,
challengeSeed [32]byte,
proof []byte,
faults []uint64,
) (bool, error) {
defer elapsed("VerifyPoSt")()
// CommRs must be provided to C.verify_post in the same order that they were
// provided to the C.generate_post
commRs := sortedCommRs
// 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()))
sortedSectorIds := make([]uint64, len(sectorInfo.Values()))
for idx, v := range sectorInfo.Values() {
sortedCommRs[idx] = v.CommR
sortedSectorIds[idx] = v.SectorID
}
// flattening the byte slice makes it easier to copy into the C heap
flattened := make([]byte, CommitmentBytesLen*len(commRs))
for idx, commR := range commRs {
flattened := make([]byte, CommitmentBytesLen*len(sortedCommRs))
for idx, commR := range sortedCommRs {
copy(flattened[(CommitmentBytesLen*idx):(CommitmentBytesLen*(1+idx))], commR[:])
}
......@@ -415,16 +450,22 @@ func GetSectorSealingStatusByID(sectorBuilderPtr unsafe.Pointer, sectorID uint64
// GeneratePoSt produces a proof-of-spacetime for the provided replica commitments.
func GeneratePoSt(
sectorBuilderPtr unsafe.Pointer,
sortedCommRs [][CommitmentBytesLen]byte,
sectorInfo SortedSectorInfo,
challengeSeed [CommitmentBytesLen]byte,
faults []uint64,
) ([]byte, error) {
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
commRs := sortedCommRs
flattened := make([]byte, CommitmentBytesLen*len(commRs))
for idx, commR := range commRs {
flattened := make([]byte, CommitmentBytesLen*len(sortedCommRs))
for idx, commR := range sortedCommRs {
copy(flattened[(CommitmentBytesLen*idx):(CommitmentBytesLen*(1+idx))], commR[:])
}
......
......@@ -73,12 +73,18 @@ func TestSectorBuilderLifecycle(t *testing.T) {
require.NoError(t, err)
require.True(t, isValid)
// enforces sort ordering of SectorInfo tuples
sectorInfo := sb.NewSortedSectorInfo(sb.SectorInfo{
SectorID: status.SectorID,
CommR: status.CommR,
})
// generate a PoSt
proofs, err := sb.GeneratePoSt(ptr, [][32]byte{status.CommR}, [32]byte{}, []uint64{})
proofs, err := sb.GeneratePoSt(ptr, sectorInfo, [32]byte{}, []uint64{})
require.NoError(t, err)
// verify the PoSt
isValid, err = sb.VerifyPoSt(1024, [][32]byte{status.CommR}, []uint64{status.SectorID}, [32]byte{}, proofs, []uint64{})
isValid, err = sb.VerifyPoSt(1024, sectorInfo, [32]byte{}, proofs, []uint64{})
require.NoError(t, err)
require.True(t, isValid)
......
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