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

Feat/interactive porep (#40)

* feat(porep): update API for interactive PoRep

* fix(build): grab .pc file from appropriate location

* fix(leak): point to patched sector builder

* feat(workers): configurable number worker threads

* fix(leak): point to patched sector builder

* fix(lint): use proper error formatter

* tidy

* fix(opencl): install opencl

* fix(cache): v15 cache
parent 89761b33
......@@ -11,7 +11,7 @@ jobs:
- run:
name: Install Rust toolchain
command: |
(sudo apt-get update && sudo apt-get install -y clang libssl-dev && which cargo && which rustc) || (curl https://sh.rustup.rs -sSf | sh -s -- -y)
(sudo apt-get update && sudo apt-get install -y ocl-icd-opencl-dev clang libssl-dev && which cargo && which rustc) || (curl https://sh.rustup.rs -sSf | sh -s -- -y)
rustc --version
- run:
name: Install jq
......@@ -116,11 +116,11 @@ commands:
steps:
- restore_cache:
keys:
- v14-proof-params-{{ arch }}
- v15-proof-params-{{ arch }}
save_parameter_cache:
steps:
- save_cache:
key: v14-proof-params-{{ arch }}
key: v15-proof-params-{{ arch }}
paths:
- "~/filecoin-proof-parameters/"
......@@ -36,12 +36,18 @@ type SortedSectorInfo struct {
f []SectorInfo
}
// SealTicket commits a sector to a subchain.
// SealTicket is required for the first step of Interactive PoRep.
type SealTicket struct {
BlockHeight uint64
TicketBytes [32]byte
}
// SealSeed is required for the second step of Interactive PoRep.
type SealSeed struct {
BlockHeight uint64
TicketBytes [32]byte
}
// NewSortedSectorInfo returns a SortedSectorInfo
func NewSortedSectorInfo(sectorInfo ...SectorInfo) SortedSectorInfo {
fn := func(i, j int) bool {
......@@ -91,14 +97,35 @@ type StagedSectorMetadata struct {
// SealedSectorMetadata represents a sector in the builder that has been sealed.
type SealedSectorMetadata struct {
SectorID uint64
CommD [CommitmentBytesLen]byte
CommR [CommitmentBytesLen]byte
CommRStar [CommitmentBytesLen]byte
Proof []byte
Pieces []PieceMetadata
Health sealed_sector_health.Health
Ticket SealTicket
SectorID uint64
CommD [CommitmentBytesLen]byte
CommR [CommitmentBytesLen]byte
Proof []byte
Pieces []PieceMetadata
Health sealed_sector_health.Health
Ticket SealTicket
Seed SealSeed
}
// SealPreCommitOutput is used to acquire a seed from the chain for the second
// step of Interactive PoRep.
type SealPreCommitOutput struct {
SectorID uint64
CommD [CommitmentBytesLen]byte
CommR [CommitmentBytesLen]byte
Pieces []PieceMetadata
Ticket SealTicket
}
// SealCommitOutput is produced by the second step of Interactive PoRep.
type SealCommitOutput struct {
SectorID uint64
CommD [CommitmentBytesLen]byte
CommR [CommitmentBytesLen]byte
Proof []byte
Pieces []PieceMetadata
Ticket SealTicket
Seed SealSeed
}
// SectorSealingStatus communicates how far along in the sealing process a
......@@ -107,19 +134,25 @@ type SectorSealingStatus struct {
SectorID uint64
State sealing_state.State
SealErrorMsg string // will be nil unless State == Failed
CommD [CommitmentBytesLen]byte // will be empty unless State == Sealed
CommR [CommitmentBytesLen]byte // will be empty unless State == Sealed
Proof []byte // will be empty unless State == Sealed
Pieces []PieceMetadata // will be empty unless State == Sealed
Ticket SealTicket // will be empty unless State == Sealed
CommD [CommitmentBytesLen]byte // will be empty unless State == Committed
CommR [CommitmentBytesLen]byte // will be empty unless State == Committed
Proof []byte // will be empty unless State == Committed
Pieces []PieceMetadata // will be empty unless State == Committed
Ticket SealTicket // will be empty unless State == Committed
Seed SealSeed // will be empty unless State == Committed
}
// PieceMetadata represents a piece stored by the sector builder.
type PieceMetadata struct {
Key string
Size uint64
InclusionProof []byte
CommP [CommitmentBytesLen]byte
Key string
Size uint64
CommP [CommitmentBytesLen]byte
}
// PublicPieceInfo is an on-chain tuple of CommP and aligned piece-size.
type PublicPieceInfo struct {
Size uint64
CommP [CommitmentBytesLen]byte
}
// VerifySeal returns true if the sealing operation from which its inputs were
......@@ -130,8 +163,10 @@ func VerifySeal(
commD [CommitmentBytesLen]byte,
proverID [32]byte,
ticket [32]byte,
seed [32]byte,
sectorID uint64,
proof []byte,
pieces []PublicPieceInfo,
) (bool, error) {
defer elapsed("VerifySeal")()
......@@ -150,6 +185,12 @@ func VerifySeal(
ticketCBytes := C.CBytes(ticket[:])
defer C.free(ticketCBytes)
seedCBytes := C.CBytes(seed[:])
defer C.free(seedCBytes)
cPiecesPtr, cPiecesLen := cPublicPieceInfo(pieces)
defer C.free(unsafe.Pointer(cPiecesPtr))
// a mutable pointer to a VerifySealResponse C-struct
resPtr := C.sector_builder_ffi_verify_seal(
C.uint64_t(sectorSize),
......@@ -158,8 +199,11 @@ func VerifySeal(
(*[32]C.uint8_t)(proverIDCBytes),
C.uint64_t(sectorID),
(*[32]C.uint8_t)(ticketCBytes),
(*[32]C.uint8_t)(seedCBytes),
(*C.uint8_t)(proofCBytes),
C.size_t(len(proof)),
(*C.sector_builder_ffi_FFIPublicPieceInfo)(cPiecesPtr),
cPiecesLen,
)
defer C.sector_builder_ffi_destroy_verify_seal_response(resPtr)
......@@ -255,6 +299,7 @@ func InitSectorBuilder(
stagedSectorDir string,
sectorCacheRootDir string,
maxNumOpenStagedSectors uint8,
numWorkerThreads uint8,
) (unsafe.Pointer, error) {
defer elapsed("InitSectorBuilder")()
......@@ -287,6 +332,7 @@ func InitSectorBuilder(
cStagedSectorDir,
cSectorCacheRootDir,
C.uint8_t(maxNumOpenStagedSectors),
C.uint8_t(numWorkerThreads),
)
defer C.sector_builder_ffi_destroy_init_sector_builder_response(resPtr)
......@@ -388,11 +434,11 @@ func ReadPieceFromSealedSector(sectorBuilderPtr unsafe.Pointer, pieceKey string)
return goBytes(resPtr.data_ptr, resPtr.data_len), nil
}
// SealSector seals the sector with the provided id, blocking until sealing
// completes. If no staged sector exists in the ReadyToSeal state with such an
// id, an error will be returned.
func SealSector(sectorBuilderPtr unsafe.Pointer, sectorID uint64, ticket SealTicket) (SealedSectorMetadata, error) {
defer elapsed("SealSector")()
// SealPreCommit pre-commits the sector with the provided id to the ticket,
// blocking until completion. If no staged sector with the provided id exists in
// the FullyPacked or AcceptingPieces state, an error will be returned.
func SealPreCommit(sectorBuilderPtr unsafe.Pointer, sectorID uint64, ticket SealTicket) (SealPreCommitOutput, error) {
defer elapsed("SealPreCommit")()
cTicketBytes := C.CBytes(ticket.TicketBytes[:])
defer C.free(cTicketBytes)
......@@ -402,67 +448,90 @@ func SealSector(sectorBuilderPtr unsafe.Pointer, sectorID uint64, ticket SealTic
ticket_bytes: *(*[32]C.uint8_t)(cTicketBytes),
}
resPtr := C.sector_builder_ffi_seal_sector((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.uint64_t(sectorID), cSealTicket)
defer C.sector_builder_ffi_destroy_seal_sector_response(resPtr)
resPtr := C.sector_builder_ffi_seal_pre_commit((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.uint64_t(sectorID), cSealTicket)
defer C.sector_builder_ffi_destroy_seal_pre_commit_response(resPtr)
if resPtr.status_code != 0 {
return SealedSectorMetadata{}, errors.New(C.GoString(resPtr.error_msg))
return SealPreCommitOutput{}, errors.New(C.GoString(resPtr.error_msg))
}
meta, err := goSealedSectorMetadata((*C.sector_builder_ffi_FFISealedSectorMetadata)(unsafe.Pointer(&resPtr.meta)), 1)
out, err := goSealPreCommitOutput(resPtr)
if err != nil {
return SealedSectorMetadata{}, err
return SealPreCommitOutput{}, err
}
return meta[0], nil
return out, nil
}
// ResumeSealSector resumes sealing for a sector in the Paused state. If no
// staged sector exists in such a state, an error will be returned.
func ResumeSealSector(sectorBuilderPtr unsafe.Pointer, sectorID uint64) (SealedSectorMetadata, error) {
defer elapsed("ResumeSealSector")()
// ResumeSealPreCommit resumes the pre-commit operation for a sector with the
// provided id. If no sector exists with the given id that is in the
// PreCommittingPaused state, an error will be returned.
func ResumeSealPreCommit(sectorBuilderPtr unsafe.Pointer, sectorID uint64) (SealPreCommitOutput, error) {
defer elapsed("ResumeSealPreCommit")()
resPtr := C.sector_builder_ffi_resume_seal_sector((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.uint64_t(sectorID))
defer C.sector_builder_ffi_destroy_resume_seal_sector_response(resPtr)
resPtr := C.sector_builder_ffi_resume_seal_pre_commit((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.uint64_t(sectorID))
defer C.sector_builder_ffi_destroy_resume_seal_pre_commit_response(resPtr)
if resPtr.status_code != 0 {
return SealedSectorMetadata{}, errors.New(C.GoString(resPtr.error_msg))
return SealPreCommitOutput{}, errors.New(C.GoString(resPtr.error_msg))
}
meta, err := goSealedSectorMetadata((*C.sector_builder_ffi_FFISealedSectorMetadata)(unsafe.Pointer(&resPtr.meta)), 1)
out, err := goResumeSealPreCommitOutput(resPtr)
if err != nil {
return SealedSectorMetadata{}, err
return SealPreCommitOutput{}, err
}
return meta[0], nil
return out, nil
}
// SealAllStagedSectors seals all staged sectors and returns sealed sector
// metadata for all successfully sealed sectors.
func SealAllStagedSectors(sectorBuilderPtr unsafe.Pointer, ticket SealTicket) ([]SealedSectorMetadata, error) {
defer elapsed("SealAllStagedSectors")()
// SealCommit commits the sector with the provided id to the seed, blocking
// until completion. If no staged sector exists in the PreCommitted state with
// such an id, an error will be returned.
func SealCommit(sectorBuilderPtr unsafe.Pointer, sectorID uint64, seed SealSeed) (SealCommitOutput, error) {
defer elapsed("SealCommit")()
cTicketBytes := C.CBytes(ticket.TicketBytes[:])
defer C.free(cTicketBytes)
cSeedBytes := C.CBytes(seed.TicketBytes[:])
defer C.free(cSeedBytes)
cSealTicket := C.sector_builder_ffi_FFISealTicket{
block_height: C.uint64_t(ticket.BlockHeight),
ticket_bytes: *(*[32]C.uint8_t)(cTicketBytes),
cSealSeed := C.sector_builder_ffi_FFISealSeed{
block_height: C.uint64_t(seed.BlockHeight),
ticket_bytes: *(*[32]C.uint8_t)(cSeedBytes),
}
resPtr := C.sector_builder_ffi_seal_all_staged_sectors((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), cSealTicket)
defer C.sector_builder_ffi_destroy_seal_all_staged_sectors_response(resPtr)
resPtr := C.sector_builder_ffi_seal_commit((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.uint64_t(sectorID), cSealSeed)
defer C.sector_builder_ffi_destroy_seal_commit_response(resPtr)
if resPtr.status_code != 0 {
return nil, errors.New(C.GoString(resPtr.error_msg))
return SealCommitOutput{}, errors.New(C.GoString(resPtr.error_msg))
}
meta, err := goSealedSectorMetadata(resPtr.meta_ptr, resPtr.meta_len)
out, err := goSealCommitOutput(resPtr)
if err != nil {
return nil, err
return SealCommitOutput{}, err
}
return meta, nil
return out, nil
}
// ResumeSealCommit resumes sector commit (the second stage of Interactive
// PoRep) for a sector in the CommittingPaused state. If no staged sector exists
// in such a state, an error will be returned.
func ResumeSealCommit(sectorBuilderPtr unsafe.Pointer, sectorID uint64) (SealCommitOutput, error) {
defer elapsed("ResumeSealCommit")()
resPtr := C.sector_builder_ffi_resume_seal_commit((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.uint64_t(sectorID))
defer C.sector_builder_ffi_destroy_resume_seal_commit_response(resPtr)
if resPtr.status_code != 0 {
return SealCommitOutput{}, errors.New(C.GoString(resPtr.error_msg))
}
out, err := goResumeSealCommitOutput(resPtr)
if err != nil {
return SealCommitOutput{}, err
}
return out, nil
}
// GetAllStagedSectors returns a slice of all staged sector metadata for the sector builder.
......@@ -519,15 +588,21 @@ func GetSectorSealingStatusByID(sectorBuilderPtr unsafe.Pointer, sectorID uint64
if resPtr.seal_status_code == C.Failed {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.Failed, SealErrorMsg: C.GoString(resPtr.seal_error_msg)}, nil
} else if resPtr.seal_status_code == C.ReadyForSealing {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.ReadyForSealing}, nil
} else if resPtr.seal_status_code == C.Paused {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.Paused}, nil
} else if resPtr.seal_status_code == C.Pending {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.Pending}, nil
} else if resPtr.seal_status_code == C.Sealing {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.Sealing}, nil
} else if resPtr.seal_status_code == C.Sealed {
} else if resPtr.seal_status_code == C.AcceptingPieces {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.AcceptingPieces}, nil
} else if resPtr.seal_status_code == C.Committing {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.Committing}, nil
} else if resPtr.seal_status_code == C.CommittingPaused {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.CommittingPaused}, nil
} else if resPtr.seal_status_code == C.FullyPacked {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.FullyPacked}, nil
} else if resPtr.seal_status_code == C.PreCommitted {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.PreCommitted}, nil
} else if resPtr.seal_status_code == C.PreCommitting {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.PreCommitting}, nil
} else if resPtr.seal_status_code == C.PreCommittingPaused {
return SectorSealingStatus{SectorID: sectorID, State: sealing_state.PreCommittingPaused}, nil
} else if resPtr.seal_status_code == C.Committed {
commRSlice := goBytes(&resPtr.comm_r[0], CommitmentBytesLen)
var commR [CommitmentBytesLen]byte
copy(commR[:], commRSlice)
......@@ -545,12 +620,13 @@ func GetSectorSealingStatusByID(sectorBuilderPtr unsafe.Pointer, sectorID uint64
return SectorSealingStatus{
SectorID: sectorID,
State: sealing_state.Sealed,
State: sealing_state.Committed,
CommD: commD,
CommR: commR,
Proof: proof,
Pieces: ps,
Ticket: goSealTicket(resPtr.seal_ticket),
Seed: goSealSeed(resPtr.seal_seed),
}, nil
} else {
// unknown
......@@ -607,35 +683,6 @@ func GeneratePoSt(
return goBytes(resPtr.proof_ptr, resPtr.proof_len), nil
}
// VerifyPieceInclusionProof returns true if the piece inclusion proof is valid
// with the given arguments.
func VerifyPieceInclusionProof(sectorSize uint64, pieceSize uint64, commP [CommitmentBytesLen]byte, commD [CommitmentBytesLen]byte, proof []byte) (bool, error) {
commDCBytes := C.CBytes(commD[:])
defer C.free(commDCBytes)
commPCBytes := C.CBytes(commP[:])
defer C.free(commPCBytes)
pieceInclusionProofCBytes := C.CBytes(proof)
defer C.free(pieceInclusionProofCBytes)
resPtr := C.sector_builder_ffi_verify_piece_inclusion_proof(
(*[CommitmentBytesLen]C.uint8_t)(commDCBytes),
(*[CommitmentBytesLen]C.uint8_t)(commPCBytes),
(*C.uint8_t)(pieceInclusionProofCBytes),
C.size_t(len(proof)),
C.uint64_t(pieceSize),
C.uint64_t(sectorSize),
)
defer C.sector_builder_ffi_destroy_verify_piece_inclusion_proof_response(resPtr)
if resPtr.status_code != 0 {
return false, errors.New(C.GoString(resPtr.error_msg))
}
return bool(resPtr.is_valid), nil
}
// GeneratePieceCommitment produces a piece commitment for the provided data
// stored at a given path.
func GeneratePieceCommitment(piecePath string, pieceSize uint64) ([CommitmentBytesLen]byte, error) {
......
......@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/rand"
"errors"
"fmt"
"io"
"io/ioutil"
"math/big"
......@@ -22,7 +23,7 @@ import (
func TestSectorBuilderLifecycle(t *testing.T) {
ticketA := sb.SealTicket{
BlockHeight: 0,
TicketBytes: [32]byte{},
TicketBytes: [32]byte{5, 4, 2},
}
ticketB := sb.SealTicket{
......@@ -30,6 +31,16 @@ func TestSectorBuilderLifecycle(t *testing.T) {
TicketBytes: [32]byte{1, 2, 3},
}
seedA := sb.SealSeed{
BlockHeight: 50,
TicketBytes: [32]byte{7, 4, 2},
}
seedB := sb.SealSeed{
BlockHeight: 60,
TicketBytes: [32]byte{9, 10, 11},
}
proverID := [32]byte{6, 7, 8}
metadataDir := requireTempDirPath(t)
......@@ -44,7 +55,7 @@ func TestSectorBuilderLifecycle(t *testing.T) {
sectorCacheRootDir := requireTempDirPath(t)
defer require.NoError(t, os.Remove(sectorCacheRootDir))
ptr, err := sb.InitSectorBuilder(1024, 2, 0, metadataDir, proverID, sealedSectorDir, stagedSectorDir, sectorCacheRootDir, 1)
ptr, err := sb.InitSectorBuilder(1024, 2, 0, metadataDir, proverID, sealedSectorDir, stagedSectorDir, sectorCacheRootDir, 1, 2)
require.NoError(t, err)
defer sb.DestroySectorBuilder(ptr)
......@@ -73,6 +84,11 @@ func TestSectorBuilderLifecycle(t *testing.T) {
commP, err := sb.GeneratePieceCommitmentFromFile(pieceFileA, maxPieceSize)
require.NoError(t, err)
publicPieceInfoA := []sb.PublicPieceInfo{{
Size: maxPieceSize,
CommP: commP,
}}
// seek to the beginning
_, err = pieceFileA.Seek(0, 0)
require.NoError(t, err)
......@@ -88,49 +104,64 @@ func TestSectorBuilderLifecycle(t *testing.T) {
require.Equal(t, uint64(1), stagedSector.SectorID)
// block until the sector is ready for us to begin sealing
statusA, err := pollForSectorSealingStatus(ptr, sectorIDA, sealing_state.ReadyForSealing, time.Minute)
statusA, err := pollForSectorSealingStatus(ptr, sectorIDA, sealing_state.FullyPacked, time.Minute)
require.NoError(t, err)
// seal all staged sectors
// pre-commit sector to a ticket (in a non-blocking fashion)
go func() {
// blocks until sealing has completed
meta, err := sb.SealAllStagedSectors(ptr, ticketA)
out, err := sb.SealPreCommit(ptr, statusA.SectorID, ticketA)
require.NoError(t, err)
require.Equal(t, 1, len(meta))
require.Equal(t, 1, len(meta[0].Pieces), "expected to see the one piece we added")
require.Equal(t, stagedSector.SectorID, meta[0].SectorID)
require.Equal(t, sectorIDA, out.SectorID)
require.Equal(t, ticketA.TicketBytes, out.Ticket.TicketBytes)
}()
// block until the sector begins to seal
_, err = pollForSectorSealingStatus(ptr, sectorIDA, sealing_state.Sealing, 15*time.Second)
require.NoError(t, err)
// write a second piece to a staged sector, reducing remaining space to 0
sectorIDB, err := sb.AddPieceFromFile(ptr, "duvall", maxPieceSize, pieceFileB)
require.NoError(t, err)
// pre-commit second sector to a ticket too
go func() {
meta, err := sb.SealSector(ptr, sectorIDB, ticketB)
_, err := sb.SealPreCommit(ptr, sectorIDB, ticketB)
require.NoError(t, err)
require.Equal(t, sectorIDB, meta.SectorID)
}()
// block until both sectors have successfully sealed
statusA, err = pollForSectorSealingStatus(ptr, sectorIDA, sealing_state.Sealed, 30*time.Minute)
// block until both sectors have successfully pre-committed
statusA, err = pollForSectorSealingStatus(ptr, sectorIDA, sealing_state.PreCommitted, 30*time.Minute)
require.NoError(t, err)
require.Equal(t, ticketA, statusA.Ticket)
statusB, err := pollForSectorSealingStatus(ptr, sectorIDB, sealing_state.Sealed, 30*time.Minute)
statusB, err := pollForSectorSealingStatus(ptr, sectorIDB, sealing_state.PreCommitted, 30*time.Minute)
require.NoError(t, err)
require.Equal(t, ticketB, statusB.Ticket)
// verify the seal proof
isValid, err := sb.VerifySeal(1024, statusA.CommR, statusA.CommD, proverID, ticketA.TicketBytes, sectorIDA, statusA.Proof)
// commit both sectors concurrently
go func() {
out, err := sb.SealCommit(ptr, sectorIDA, seedA)
require.NoError(t, err)
require.Equal(t, sectorIDA, out.SectorID)
require.Equal(t, ticketA.TicketBytes, out.Ticket.TicketBytes)
require.Equal(t, seedA.TicketBytes, out.Seed.TicketBytes)
}()
go func() {
out, err := sb.SealCommit(ptr, sectorIDB, seedB)
require.NoError(t, err)
require.Equal(t, sectorIDB, out.SectorID)
}()
// block until both sectors have finished sealing (successfully)
statusA, err = pollForSectorSealingStatus(ptr, sectorIDA, sealing_state.Committed, 30*time.Minute)
require.NoError(t, err)
require.True(t, isValid)
// verify the piece inclusion proof
isValid, err = sb.VerifyPieceInclusionProof(1024, maxPieceSize, commP, statusA.CommD, statusA.Pieces[0].InclusionProof)
statusB, err = pollForSectorSealingStatus(ptr, sectorIDB, sealing_state.Committed, 30*time.Minute)
require.NoError(t, err)
// verify that we used the tickets and seeds we'd intended to use
require.Equal(t, ticketA.TicketBytes, statusA.Ticket.TicketBytes)
require.Equal(t, ticketB.TicketBytes, statusB.Ticket.TicketBytes)
require.Equal(t, seedA.TicketBytes, statusA.Seed.TicketBytes)
require.Equal(t, seedB.TicketBytes, statusB.Seed.TicketBytes)
// verify the seal proof
isValid, err := sb.VerifySeal(1024, statusA.CommR, statusA.CommD, proverID, ticketA.TicketBytes, seedA.TicketBytes, sectorIDA, statusA.Proof, publicPieceInfoA)
require.NoError(t, err)
require.True(t, isValid)
......@@ -194,13 +225,14 @@ func TestJsonMarshalSymmetry(t *testing.T) {
func pollForSectorSealingStatus(ptr unsafe.Pointer, sectorID uint64, targetState sealing_state.State, timeout time.Duration) (status sb.SectorSealingStatus, retErr error) {
timeoutCh := time.After(timeout)
lastState := sealing_state.Unknown
tick := time.Tick(5 * time.Second)
tick := time.Tick(1 * time.Second)
for {
select {
case <-timeoutCh:
retErr = errors.New("timed out waiting for sector to finish sealing")
retErr = fmt.Errorf("timed out waiting for sector hit desired state (last state: %s)", lastState)
return
case <-tick:
sealingStatus, err := sb.GetSectorSealingStatusByID(ptr, sectorID)
......@@ -209,9 +241,14 @@ func pollForSectorSealingStatus(ptr unsafe.Pointer, sectorID uint64, targetState
return
}
lastState = sealingStatus.State
if sealingStatus.State == targetState {
status = sealingStatus
return
} else if sealingStatus.State == sealing_state.Failed {
retErr = errors.New(sealingStatus.SealErrorMsg)
return
}
}
}
......
......@@ -5,8 +5,12 @@ go 1.12
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ipfs/go-log v0.0.1
github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.3.0
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect
github.com/stretchr/testify v1.4.0
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 // indirect
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.2.4 // indirect
)
......@@ -9,10 +9,19 @@ github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
......@@ -22,18 +31,26 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo=
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo=
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635 h1:2eB4G6bDQDeP69ZXbOKC00S2Kf6TIiRS+DzfKsKeQU0=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
......@@ -27,7 +27,7 @@ else
find "${subm_dir}/target/release" -type f -name sector_builder_ffi.h -exec cp -- "{}" . \;
find "${subm_dir}/target/release" -type f -name libsector_builder_ffi.a -exec cp -- "{}" . \;
find "${subm_dir}/target/release" -type f -name sector_builder_ffi.pc -exec cp -- "{}" . \;
find "${subm_dir}" -type f -name sector_builder_ffi.pc -exec cp -- "{}" . \;
if [[ ! -f "./sector_builder_ffi.h" ]]; then
(>&2 echo "failed to install sector_builder_ffi.h")
......
Subproject commit 776764ae4791e9d61ffa6c009c26349d1261c0c1
Subproject commit 8ed121f63c40e692860644c93c5cd76ea16c58a0
......@@ -4,23 +4,29 @@ package sealing_state
type State int
const (
Unknown State = iota
Pending // sector is still accepting user data
Failed // sealing failed
Sealing // sector is currently being sealed
Sealed // sector has been sealed successfully
Paused // sector sealing has been paused and can be resumed
ReadyForSealing // staged sector is full and is ready to seal
Unknown State = iota
AcceptingPieces // sector is still accepting user data
Committed // sector has been committed to a ticket and seed
Committing // sector is being committed
CommittingPaused // sector was committing, but now paused
Failed // sector failed during pre-commit or commit
FullyPacked // sector is no longer accepting pieces; is fully packed
PreCommitted // sector has been pre-committed to a ticket
PreCommitting // sector is pre-committing
PreCommittingPaused // sector was paused during pre-commit
)
var labels = [...]string{
"Unknown",
"Pending",
"AcceptingPieces",
"Committed",
"Committing",
"CommittingPaused",
"Failed",
"Sealing",
"Sealed",
"Paused",
"ReadyForSealing",
"FullyPacked",
"PreCommitted",
"PreCommitting",
"PreCommittingPaused",
}
func (el State) String() string {
......
......@@ -18,6 +18,24 @@ import "C"
// with the number of partitions used when creating that proof.
const SingleProofPartitionProofLen = 192
func cPublicPieceInfo(src []PublicPieceInfo) (*C.sector_builder_ffi_FFIPublicPieceInfo, C.size_t) {
srcCSizeT := C.size_t(len(src))
// allocate array in C heap
cPublicPieceInfos := C.malloc(srcCSizeT * C.sizeof_sector_builder_ffi_FFIPublicPieceInfo)
// create a Go slice backed by the C-array
xs := (*[1 << 30]C.sector_builder_ffi_FFIPublicPieceInfo)(cPublicPieceInfos)
for i, v := range src {
xs[i] = C.sector_builder_ffi_FFIPublicPieceInfo{
num_bytes: C.uint64_t(v.Size),
comm_p: *(*[32]C.uint8_t)(unsafe.Pointer(&v.CommP)),
}
}
return (*C.sector_builder_ffi_FFIPublicPieceInfo)(cPublicPieceInfos), srcCSizeT
}
func cUint64s(src []uint64) (*C.uint64_t, C.size_t) {
srcCSizeT := C.size_t(len(src))
......@@ -55,6 +73,117 @@ func goSealTicket(src C.sector_builder_ffi_FFISealTicket) SealTicket {
}
}
func goSealCommitOutput(src *C.sector_builder_ffi_SealCommitResponse) (SealCommitOutput, error) {
commDSlice := goBytes(&src.comm_d[0], CommitmentBytesLen)
var commD [CommitmentBytesLen]byte
copy(commD[:], commDSlice)
commRSlice := goBytes(&src.comm_r[0], CommitmentBytesLen)
var commR [CommitmentBytesLen]byte
copy(commR[:], commRSlice)
proof := goBytes(src.proofs_ptr, src.proofs_len)
pieces, err := goPieceMetadata(src.pieces_ptr, src.pieces_len)
if err != nil {
return SealCommitOutput{}, errors.Wrap(err, "failed to marshal piece metadata")
}
return SealCommitOutput{
SectorID: uint64(src.sector_id),
CommD: commD,
CommR: commR,
Proof: proof,
Pieces: pieces,
Ticket: goSealTicket(src.seal_ticket),
Seed: goSealSeed(src.seal_seed),
}, nil
}
func goResumeSealCommitOutput(src *C.sector_builder_ffi_ResumeSealCommitResponse) (SealCommitOutput, error) {
commDSlice := goBytes(&src.comm_d[0], CommitmentBytesLen)
var commD [CommitmentBytesLen]byte
copy(commD[:], commDSlice)
commRSlice := goBytes(&src.comm_r[0], CommitmentBytesLen)
var commR [CommitmentBytesLen]byte
copy(commR[:], commRSlice)
proof := goBytes(src.proofs_ptr, src.proofs_len)
pieces, err := goPieceMetadata(src.pieces_ptr, src.pieces_len)
if err != nil {
return SealCommitOutput{}, errors.Wrap(err, "failed to marshal piece metadata")
}
return SealCommitOutput{
SectorID: uint64(src.sector_id),
CommD: commD,
CommR: commR,
Proof: proof,
Pieces: pieces,
Ticket: goSealTicket(src.seal_ticket),
Seed: goSealSeed(src.seal_seed),
}, nil
}
func goSealPreCommitOutput(src *C.sector_builder_ffi_SealPreCommitResponse) (SealPreCommitOutput, error) {
commDSlice := goBytes(&src.comm_d[0], CommitmentBytesLen)
var commD [CommitmentBytesLen]byte
copy(commD[:], commDSlice)
commRSlice := goBytes(&src.comm_r[0], CommitmentBytesLen)
var commR [CommitmentBytesLen]byte
copy(commR[:], commRSlice)
pieces, err := goPieceMetadata(src.pieces_ptr, src.pieces_len)
if err != nil {
return SealPreCommitOutput{}, errors.Wrap(err, "failed to marshal piece metadata")
}
return SealPreCommitOutput{
SectorID: uint64(src.sector_id),
CommD: commD,
CommR: commR,
Pieces: pieces,
Ticket: goSealTicket(src.seal_ticket),
}, nil
}
func goResumeSealPreCommitOutput(src *C.sector_builder_ffi_ResumeSealPreCommitResponse) (SealPreCommitOutput, error) {
commDSlice := goBytes(&src.comm_d[0], CommitmentBytesLen)
var commD [CommitmentBytesLen]byte
copy(commD[:], commDSlice)
commRSlice := goBytes(&src.comm_r[0], CommitmentBytesLen)
var commR [CommitmentBytesLen]byte
copy(commR[:], commRSlice)
pieces, err := goPieceMetadata(src.pieces_ptr, src.pieces_len)
if err != nil {
return SealPreCommitOutput{}, errors.Wrap(err, "failed to marshal piece metadata")
}
return SealPreCommitOutput{
SectorID: uint64(src.sector_id),
CommD: commD,
CommR: commR,
Pieces: pieces,
Ticket: goSealTicket(src.seal_ticket),
}, nil
}
func goSealSeed(src C.sector_builder_ffi_FFISealTicket) SealSeed {
seedBytesSlice := C.GoBytes(unsafe.Pointer(&src.ticket_bytes[0]), 32)
var seedBytes [CommitmentBytesLen]byte
copy(seedBytes[:], seedBytesSlice)
return SealSeed{
TicketBytes: seedBytes,
BlockHeight: uint64(src.block_height),
}
}
func goStagedSectorMetadata(src *C.sector_builder_ffi_FFIStagedSectorMetadata, size C.size_t) ([]StagedSectorMetadata, error) {
sectors := make([]StagedSectorMetadata, size)
if src == nil || size == 0 {
......@@ -107,6 +236,7 @@ func goSealedSectorMetadata(src *C.sector_builder_ffi_FFISealedSectorMetadata, s
Pieces: pieces,
Health: health,
Ticket: goSealTicket(ptrs[i].seal_ticket),
Seed: goSealSeed(ptrs[i].seal_seed),
}
}
......@@ -126,10 +256,9 @@ func goPieceMetadata(src *C.sector_builder_ffi_FFIPieceMetadata, size C.size_t)
copy(commP[:], commPSlice)
ps[i] = PieceMetadata{
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),
Key: C.GoString(ptrs[i].piece_key),
Size: uint64(ptrs[i].num_bytes),
CommP: commP,
}
}
......
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