package sealing import ( "io" "math/bits" "math/rand" "sync" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/hashicorp/go-multierror" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" ) func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { // Convert to in-sector bytes for easier math: // // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B // of user-usable data. // // (1024/1016 = 128/127) // // Given that we can get sector size by simply adding 1/127 of the user // bytes // // (we convert to sector bytes as they are nice round binary numbers) toFill := uint64(in + (in / 127)) // We need to fill the sector with pieces that are powers of 2. Conveniently // computers store numbers in binary, which means we can look at 1s to get // all the piece sizes we need to fill the sector. It also means that number // of pieces is the number of 1s in the number of remaining bytes to fill out := make([]abi.UnpaddedPieceSize, bits.OnesCount64(toFill)) for i := range out { // Extract the next lowest non-zero bit next := bits.TrailingZeros64(toFill) psize := uint64(1) << next // e.g: if the number is 0b010100, psize will be 0b000100 // set that bit to 0 by XORing it, so the next iteration looks at the // next bit toFill ^= psize // Add the piece size to the list of pieces we need to create out[i] = abi.PaddedPieceSize(psize).Unpadded() } return out, nil } func (m *Sealing) fastPledgeCommitment(size abi.UnpaddedPieceSize, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 if uint64(size)/parts < 127 { parts = uint64(size) / 127 } piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() out := make([]sectorbuilder.PublicPieceInfo, parts) var lk sync.Mutex var wg sync.WaitGroup wg.Add(int(parts)) for i := uint64(0); i < parts; i++ { go func(i uint64) { defer wg.Done() commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)), piece) lk.Lock() if perr != nil { err = multierror.Append(err, perr) } out[i] = sectorbuilder.PublicPieceInfo{ Size: uint64(piece), CommP: commP, } lk.Unlock() }(i) } wg.Wait() if err != nil { return [32]byte{}, err } return sectorbuilder.GenerateDataCommitment(m.sb.SectorSize(), out) } func (m *Sealing) ListSectors() ([]SectorInfo, error) { var sectors []SectorInfo if err := m.sectors.List(§ors); err != nil { return nil, err } return sectors, nil } func (m *Sealing) GetSectorInfo(sid uint64) (SectorInfo, error) { var out SectorInfo err := m.sectors.Get(sid).Get(&out) return out, err }