diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 49c807412..f339fd66a 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -35,7 +35,7 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error } func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error { - return sm.Miner.StoreGarbageData(ctx) + return sm.Miner.StoreGarbageData() } func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (api.SectorInfo, error) { diff --git a/storage/garbage.go b/storage/garbage.go index 28e33e77d..f61ff50cc 100644 --- a/storage/garbage.go +++ b/storage/garbage.go @@ -62,7 +62,6 @@ func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, existingPiece return nil, xerrors.Errorf("serializing PublishStorageDeals params failed: ", aerr) } - // TODO: We may want this to happen after fetching data smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{ To: actors.StorageMarketAddress, From: m.worker, @@ -112,9 +111,12 @@ func (m *Miner) storeGarbage(ctx context.Context, sectorID uint64, existingPiece return out, nil } -func (m *Miner) StoreGarbageData(_ context.Context) error { - ctx := context.TODO() +func (m *Miner) StoreGarbageData() error { go func() { + ctx := context.TODO() // we can't use the context from command which invokes + // this, as we run everything here async, and it's cancelled when the + // command exits + size := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) sid, err := m.sb.AcquireSectorId() diff --git a/storage/sealing_utils.go b/storage/sealing_utils.go index 26591e0ac..d8d5225bb 100644 --- a/storage/sealing_utils.go +++ b/storage/sealing_utils.go @@ -7,13 +7,36 @@ import ( ) func fillersFromRem(toFill uint64) ([]uint64, error) { - toFill += toFill / 127 // convert to in-sector bytes for easier math + // 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 += toFill / 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([]uint64, 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] = sectorbuilder.UserBytesForSectorSize(psize) } return out, nil