-
Notifications
You must be signed in to change notification settings - Fork 21
Feat/allow small pieces #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
for example, here's a piece using 32GiB for a 278KiB DAG: |
|
making a lot of changes to simplify this, belay review |
dbd68c0 to
e0f3723
Compare
|
ok this now works for not massively padding DAGs and tests pass, working on handling the "remainder" cars |
|
output for a DAG car: |
|
@parkan do you have a link to the FIP in question? In practice it seems SPs are taking smaller pieces. The DAG piece is still less than a GiB! Are these the tiny pieces that can then be aggregated and shipped/sealed as a 32GiB piece/sector? This approach will present a challenge to users and add a few complications and steps to their workflows. I think we are aligned that if miners can receive smaller pieces without an issue, we should settle at no padding beyond the normal power of 2 The DAG piece should be processed as the rest of the pieces in the preparation. |
FIP in question is https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0045.md (particularly here), some related concepts here https://spec.filecoin.io/#section-systems.filecoin_mining.sector.sector-quality it's not clear to me exactly how the implementation of the deal weight calculations shook out as there was quite a bit of back and forth on that, so any insights would be appreciated basically we have these overlapping concerns: to the best of my understanding: concern (2) primarily affects SPs (risk of lower deal weight, and potentially also https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0045.md#deal-packing) (1) and (2) are potentially in tension because clients don't want to pay (FIL, DC, or out of band) to store useless data, while SPs want to maximize DealWeight and VerifiedDealWeight per sector -- my understanding of the dynamics here is not deep enough to judge the balance (2a) comes into play whenever piece size < sector size, whether because client has chosen a (smaller) fixed value or we are only padding to powers of two (3) used to be a bigger problem before lower gas costs and aggregation, however it's still present (database and message bloat, operational complexity, etc) (4) is a concern primarily for clients with small amounts of data the existing implementation* in singularity has cut the gordian knot by optimizing for 2/2a/3 (with default settings i.e. piece size = 32GiB), making a significant compromise on (1) (1 piece per prep almost empty, 1 piece underfilled, e.g. with a 33GiB prep you are wasting ~63GiB on padding), and ignoring (4) the proposed changes aim to rebalance slightly in favor of the client by prioritizing (1), though as currently implemented (only DAGs can be < target piece size) at a relatively large cost in (2a) and thus potentially (2) there are several fixes, in order of increasing complexity:
|
|
why I am concerned about only using power of 2 padding:
I would feel much better changing things if I understood the above^ as well as the balance of concerns from clients, SPs, and FIL+ regarding padding and underfilled sectors |
|
additional note: some other approaches avoid this by addressing (4), i.e. pre-aggregating the data before packing; we were able to address this partially by enabling union storage support but this approach does rely on the user managing the inputs (by contrast to a continuous pool of input files as done by e.g. estuary) for larger datasets this is a fine approach but does present issues with smaller inputs |
|
reverted the experimental feature, which was meant to leverage behavior similar to the proper fix would be to add the equivalent query to dealpusher, however this is out of scope so I'm parking it an alternate workaround is in place for our tests |
cmd/dataprep/create.go
Outdated
| &cli.StringFlag{ | ||
| Name: "min-piece-size", | ||
| Usage: "The minimum size of a piece. Pieces smaller than this will be padded up to this size.", | ||
| Value: "256B", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to be 2MiB, fix incoming
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok bizarre this is correct in my local copy on the same commit?
|
this is confirmed as needed for curio as all pieces padded over ceil_pow2(payload) are being rejected |
bd47432 to
da7c1f1
Compare
|
this is ready for review, will merge #467 into this to hopefully get a green build |
|
ok this is fully ready for review, I propose an RC with the current changes and an API change for |
ianconsolata
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this is just a pure refactor -- you're taking the existing minPieceSize value, and making it a configurable setting, but not actually updating the logic to pack things differently. Is that correct?
If it is, LGTM with minor edits to documentation
| }, | ||
| &cli.StringFlag{ | ||
| Name: "min-piece-size", | ||
| Usage: "The minimum size of a piece. Pieces smaller than this will be padded up to this size. It's recommended to leave this as the default", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have to pad at all? And are we sure this is compatible with the limits on padding that the Fil+ program set? Whatever that limit is, I think it would be good to either document it here, or check elsewhere to ensure that min-piece-size isn't set high enough to cause an issue.
|
|
||
| // Verify piece size is a power of two | ||
| pieceSize := uint64(len(downloaded)) | ||
| require.True(t, util.IsPowerOfTwo(pieceSize), "piece size %d is not a power of two", pieceSize) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just testing the default value?
|
|
||
| if minPieceSize != util.NextPowerOfTwo(minPieceSize) { | ||
| return nil, errors.Wrap(handlererror.ErrInvalidParameter, "minPieceSize must be a power of two") | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add a check here to ensure the min-piece-size never over-pads in a way that makes things non-compliant.
|
|
||
| const ( | ||
| DataPiece PieceType = "data" | ||
| DagPiece PieceType = "dag" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you document the difference between these two? Data and DAG are both very overloaded terms in this space.
not quite, though I did try to reuse the existing code paths as much as possible and be surgical with my changes there are actual logic changes in two places: these use the min piece size as the target instead of the requested piece size/max-size, in effect all pieces > min_piece_size get a cel_pow2 padding the packing logic per se remains unchanged, we are only changing the "virtual" padding that gets passed to GetCommP the PieceSize parameter then effectively becomes "max piece size" only, which perhaps should be reflected better in the param naming/docs the other quality of life change I would consider adding is suppressing the warning here: Line 59 in 151fae5
as now the "target" piece size will almost always be less than actual |
|
the big question remains whether curio will allow 1MiB pieces an exception (@LexLuthr stated that "we can probably add it" but I'm waiting on an update) if not, then we'll need to get crafty -- either manipulate the DC allocation such that the <1MiB piece gets grouped at that level (unclear if that is even possible on the client side) or add an extra job type that aggregates pieces, though the latter is a real can of worms as it would need to work across preparations and is actually not guaranteed to succeed from the knapsack problem perspective (you could have some loose KiB that aren't groupable with anything) |
Sankara-Jefferson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- @parkan I changed the values of the 'sizes' and things ran well. Reasonable number of pieces and jobs. :)
- I created two preps (same data, different paths) under my main branch before your fix, and then under your PR's branch and ran the three commands in this order scan, pack, daggen while exploring the prep after each command.
- I got the same output. I pasted it below.
- Is there a way for me to test and confirm tha Packing DAG and data pieces no longer leads to excessive empty sector space?
- I think the next clear test will be that I can make deals through curio and that the data in these is retrievable.
- I would like to test for backward compatibility, can you think of how I can use my current build (main branch) to create car files that do not have DAG pieces and then using the branch with your PR, run and generate DAG pieces that I can then onboard and test retrievals...
jeffersonsankara@Jeffersons-MacBook-Pro singularity % singularity prep list-pieces 19
AttachmentID SourceStorageID
21 25
SourceStorage
ID Name Type Path
25 dpla_demo local /Users/jeffersonsankara/Documents/demo_dpla
Pieces
PieceCID PieceSize RootCID FileSize StoragePath
baga6ea4seaqiiyi76co7qvbcuhgl5oaygefi3no2ztfyedf2rtkm5kmczba4aby 4194304 bafkreie6tmbw3cwzs27s3us53r4zv3nyqetjd2gmt44ckcr3q422tnv5bi 2460037
baga6ea4seaqmg5xtmjmss6vmtvxfwjn5x6cssxsygue6wckourrczblclhxg6ni 4194304 bafybeihdcny2iwx4izst7ftfol7s3icxn27e2ybvkxoiosqeqhlwasgmyi 810
jeffersonsankara@Jeffersons-MacBook-Pro singularity %
AND
jeffersonsankara@Jeffersons-MacBook-Pro singularity % singularity prep list-pieces 20
AttachmentID SourceStorageID
22 26
SourceStorage
ID Name Type Path
26 demo_dpla_479 local /Users/jeffersonsankara/Documents/demo_dpla_479
Pieces
PieceCID PieceSize RootCID FileSize StoragePath
baga6ea4seaqiiyi76co7qvbcuhgl5oaygefi3no2ztfyedf2rtkm5kmczba4aby 4194304 bafkreie6tmbw3cwzs27s3us53r4zv3nyqetjd2gmt44ckcr3q422tnv5bi 2460037
baga6ea4seaqmg5xtmjmss6vmtvxfwjn5x6cssxsygue6wckourrczblclhxg6ni 4194304 bafybeihdcny2iwx4izst7ftfol7s3icxn27e2ybvkxoiosqeqhlwasgmyi 810
jeffersonsankara@Jeffersons-MacBook-Pro singularity %
|
could you please paste the exact command history, including when you switched branches and re-built the binary? I am going to post my other comments separately for ease of reference |
|
regarding the
in this case the old codebase will output 2 data pieces of 2MiB each, with the second being overpadded (it should be 1MiB) whereas the new code will output a 2MiB and a 1MiB piece (these are estimates but likely accurate) |
|
regarding these questions:
this is the expected outcome for the this suggests that something is not working correctly, or that your binary is not using the current code version I am very strongly suspecting the latter, because the output of note that I highly suggest verifying the correct binary version, it should be similar to this (minus the ...dirty part potentially): once this is done I suggest creating a fresh preparation with the above settings and retrying your test |
|
regarding backward compatibility, this is a very good question, and there are indeed certain complex limitations in that regard but let's establish the baseline functionality first (for what it's worth the test you proposed should work just fine) |
|
@parkan Here is everything I tried and ended up with an older version
git fetch origin pull/479/head:feat/allow-small-pieces
git checkout feat/allow-small-pieces
But the output remained: Next, I patched I replaced However, this failed to compile with: Questions:
|
|
we worked through the basic flow, a few small changes are added to scope (suppress the piece size warnings which are no longer relevant, update release metadata, etc) |
|
@parkan I checked the metadata API |
could you explain exactly what values you expect to see in this output? are you referring to having an empty value? can you confirm that this preparation was created using the new codebase? in general, when possible, please use the "actions taken/result expected/result seen" format for the quickest turnaround 👍 |
|
@parkan Yes, the 'pieceType' and yes I used the new codebase. Actions Taken: Result Expected: Result Seen: |
cannnot reproduce, tests and manual verification shows correct piece_type returned min_piece_size is not a property of the car much like min-size etc are not |
|
0.6.0-RC1 has been proposed and will be cut when this is merged |
|
not sure where the cancellations are coming from? 🤔 |
feat: allow configurable min-piece-size to reduce excessive padding for small segments This change introduces support for specifying a `--min-piece-size` when preparing data, improving behavior for small DAGs, remainder CARs, and small preparations that would otherwise be padded to the full target piece size (e.g. 32GiB). Such excessive padding leads to inefficiencies and causes sectors to be rejected by Storage Providers or fail verified deal requirements. ### Key changes: - Add support for `--min-piece-size` (default: 256B, subject to adjustment) - Pass both `min` and `target` piece sizes to `GetCommp`, enabling finer control over padding - Retain power-of-2 padding via `target size`, but allow flexibility by setting it to `0` This helps avoid generating 90%+ padding pieces and reduces transfer times in many cases. ### Notes: - Default behavior remains unchanged if `--min-piece-size` is not set - Full support for non-padded pieces now depends on both chunker accuracy and downstream deal acceptance - `pieceType` is now tracked in metadata (e.g., data vs. DAG) ### Out of scope: - No cross-preparation aggregation; that responsibility remains with SPs - Edge cases like aggregating under-1MiB pieces are not yet solved Closes #473 Co-authored-by: Arkadiy Kukarkin <arkadiy@archive.org>
This is an in-progress fix for the situation where very small data segments (e.g. DAG pieces, remainder data CARs from a larger preparation, or simply small preparations) get padded to the full piece size (generally 32GiB), potentially creating 90%+ padding pieces. During the original design process for singularity a high padding percentage within a sector was allowed, however currently such pieces will likely get rejected by SPs and sectors containing excess padding will not fulfill verified deal requirements. The fully padded pieces may also increase transfer times, depending on the download mechanism.
Currently, any piece will get padded up to the target piece size. We change this logic by:
minimumandtargetpiece sizes to the GetCommp function; this allows flexible control where we both retain the previous behavior (see below) but can optionally pass0for the target size, resulting in no padding beyond the normal power of 2why this is WIP:
what is outside the scope of this PR:
closes #473