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

Merge pull request #17 from filecoin-project/feat/detect-and-report-faults

expose sector health through CGO bindings
parents dc351424 7b7ba3f5
......@@ -24,6 +24,18 @@ func elapsed(what string) func() {
}
}
// SealedSectorHealth represents the healthiness of a sector managed by a
// sector builder.
type SealedSectorHealth int
const (
Unknown SealedSectorHealth = iota
Ok // everything is fine
ErrorInvalidChecksum // sector exists, but checksum is invalid
ErrorInvalidLength // sector exists, but length is incorrect
ErrorMissing // sector no longer exists
)
// SortedSectorInfo is a slice of SectorInfo sorted (lexicographically,
// ascending) by replica commitment (CommR).
type SortedSectorInfo struct {
......@@ -50,7 +62,7 @@ func (s *SortedSectorInfo) Values() []SectorInfo {
type SectorInfo struct {
SectorID uint64
CommR [CommitmentBytesLen]byte
CommR [CommitmentBytesLen]byte
}
// CommitmentBytesLen is the number of bytes in a CommR, CommD, CommP, and CommRStar.
......@@ -71,6 +83,7 @@ type SealedSectorMetadata struct {
CommRStar [CommitmentBytesLen]byte
Proof []byte
Pieces []PieceMetadata
Health SealedSectorHealth
}
// SectorSealingStatus communicates how far along in the sealing process a
......@@ -371,28 +384,26 @@ func GetAllStagedSectors(sectorBuilderPtr unsafe.Pointer) ([]StagedSectorMetadat
return meta, nil
}
// GetAllSealedSectors returns a slice of all sealed sector metadata for the sector builder.
// GetAllSealedSectors returns a slice of all sealed sector metadata, excluding
// sector health.
func GetAllSealedSectors(sectorBuilderPtr unsafe.Pointer) ([]SealedSectorMetadata, error) {
defer elapsed("GetAllSealedSectors")()
resPtr := C.sector_builder_ffi_get_sealed_sectors((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr))
defer C.sector_builder_ffi_destroy_get_sealed_sectors_response(resPtr)
if resPtr.status_code != 0 {
return nil, errors.New(C.GoString(resPtr.error_msg))
}
return getAllSealedSectors(sectorBuilderPtr, false)
}
meta, err := goSealedSectorMetadata(resPtr.sectors_ptr, resPtr.sectors_len)
if err != nil {
return nil, err
}
// GetAllSealedSectorsWithHealth returns a slice of all sealed sector metadata
// for the sector builder, including sector health info (which can be expensive
// to compute).
func GetAllSealedSectorsWithHealth(sectorBuilderPtr unsafe.Pointer) ([]SealedSectorMetadata, error) {
defer elapsed("GetAllSealedSectorsWithHealth")()
return meta, nil
return getAllSealedSectors(sectorBuilderPtr, true)
}
// GetSectorSealingStatusByID produces sector sealing status (staged, sealinG in
// progress, sealed, failed) for the provided sector id if it exists, otherwise
// an error.
// GetSectorSealingStatusByID produces sector sealing status (staged, sealing in
// progress, sealed, failed) for the provided sector id. If no sector
// corresponding to the provided id exists, this function returns an error.
func GetSectorSealingStatusByID(sectorBuilderPtr unsafe.Pointer, sectorID uint64) (SectorSealingStatus, error) {
defer elapsed("GetSectorSealingStatusByID")()
......@@ -544,3 +555,19 @@ func GeneratePieceCommitment(piecePath string, pieceSize uint64) (commP [Commitm
return commitment, nil
}
func getAllSealedSectors(sectorBuilderPtr unsafe.Pointer, performHealthchecks bool) ([]SealedSectorMetadata, error) {
resPtr := C.sector_builder_ffi_get_sealed_sectors((*C.sector_builder_ffi_SectorBuilder)(sectorBuilderPtr), C.bool(performHealthchecks))
defer C.sector_builder_ffi_destroy_get_sealed_sectors_response(resPtr)
if resPtr.status_code != 0 {
return nil, errors.New(C.GoString(resPtr.error_msg))
}
meta, err := goSealedSectorMetadata(resPtr.sectors_ptr, resPtr.sectors_len)
if err != nil {
return nil, err
}
return meta, nil
}
......@@ -30,6 +30,11 @@ func TestSectorBuilderLifecycle(t *testing.T) {
require.NoError(t, err)
defer sb.DestroySectorBuilder(ptr)
// verify that we've not yet sealed a sector
sealedSectors, err := sb.GetAllSealedSectorsWithHealth(ptr)
require.NoError(t, err)
require.Equal(t, 0, len(sealedSectors), "expected to see zero sealed sectors")
// compute the max user-bytes that can fit into a staged sector such that
// bit-padding ("preprocessing") expands the file to $SECTOR_SIZE
maxPieceSize := sb.GetMaxUserBytesPerStagedSector(1024)
......@@ -87,12 +92,13 @@ func TestSectorBuilderLifecycle(t *testing.T) {
require.NoError(t, err)
require.True(t, isValid)
sealedSectors, err := sb.GetAllSealedSectors(ptr)
sealedSectors, err = sb.GetAllSealedSectorsWithHealth(ptr)
require.NoError(t, err)
require.Equal(t, 1, len(sealedSectors), "expected to see one sealed sector")
sealedSector := sealedSectors[0]
require.Equal(t, uint64(1), sealedSector.SectorID)
require.Equal(t, 1, len(sealedSector.Pieces))
require.Equal(t, sb.Ok, sealedSector.Health)
// the piece is the size of the sector, so its piece commitment should be the
// data commitment
require.Equal(t, commP, sealedSector.CommD)
......
Subproject commit 0282a636f7911bcfd0348af5494da5932ac5808b
Subproject commit 60ff4b59300ee2e49eadacedd15979e8ec78613b
......@@ -85,6 +85,11 @@ func goSealedSectorMetadata(src *C.sector_builder_ffi_FFISealedSectorMetadata, s
return []SealedSectorMetadata{}, errors.Wrap(err, "failed to marshal piece metadata")
}
health, err := goSealedSectorHealth(ptrs[i].health)
if err != nil {
return []SealedSectorMetadata{}, errors.Wrap(err, "failed to marshal sealed sector health")
}
sectors[i] = SealedSectorMetadata{
SectorID: uint64(ptrs[i].sector_id),
CommD: commD,
......@@ -92,6 +97,7 @@ func goSealedSectorMetadata(src *C.sector_builder_ffi_FFISealedSectorMetadata, s
CommRStar: commRStar,
Proof: proof,
Pieces: pieces,
Health: health,
}
}
......@@ -120,3 +126,20 @@ func goPieceMetadata(src *C.sector_builder_ffi_FFIPieceMetadata, size C.size_t)
return ps, nil
}
func goSealedSectorHealth(health C.sector_builder_ffi_FFISealedSectorHealth) (SealedSectorHealth, error) {
switch health {
case C.Unknown:
return Unknown, nil
case C.Ok:
return Ok, nil
case C.ErrorInvalidChecksum:
return ErrorInvalidChecksum, nil
case C.ErrorInvalidLength:
return ErrorInvalidLength, nil
case C.ErrorMissing:
return ErrorMissing, nil
default:
return Unknown, errors.Errorf("unhandled sealed sector health: %v", health)
}
}
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