fix(data): return flagged estimate for partially-stored files#115
Merged
Conversation
estimate_upload_cost sampled only the first ESTIMATE_SAMPLE_CAP chunk addresses, so a file whose leading chunks were already stored but whose tail was new returned CostEstimationInconclusive even though a real estimate was obtainable. Display consumers (the GUI) were left with no value to show. - Distributed sampling: sample addresses spread evenly across the whole chunk list instead of the first N (distributed_sample_indices, unit- tested). Files with <= cap chunks still sample every chunk, preserving exact "whole file sampled" detection. - The residual all-stored-but-incomplete case returns Ok with storage_cost_atto "0" instead of erroring, tagged with a new CostEstimateConfidence enum (PricedSample / VerifiedAllAlreadyStored / AllSamplesAlreadyStoredIncomplete). The CLI renders the confidence. UploadCostEstimate is now #[non_exhaustive] with a #[serde(default)] confidence field. Error::CostEstimationInconclusive is retained (no longer produced) to avoid removing a public variant. BREAKING CHANGE: UploadCostEstimate is #[non_exhaustive] and gained a `confidence` field; downstream code constructing or exhaustively destructuring it must update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jacderida
approved these changes
Jun 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Client::estimate_upload_costreturnedErr(CostEstimationInconclusive)for a benign, common case — a file whose leading chunks are already stored but whose tail is new — leaving display consumers (the desktop GUI) with no estimate to show. This fixes that in two parts, following the discussion on #114.Changes
1. Distributed sampling. Sample chunk addresses spread evenly across the whole file (
distributed_sample_indices) instead of the firstESTIMATE_SAMPLE_CAP. A shared leading prefix (compressed archives, similar headers) no longer biases the probe toward already-stored chunks. When the file has ≤ cap chunks every chunk is sampled, preserving the exact "whole file sampled" detection. Covered by unit tests.2. Flagged estimate instead of an error. The residual case — every sampled chunk already stored, but the tail unsampled — now returns
Okwithstorage_cost_atto: "0"rather than erroring. A newCostEstimateConfidenceenum tells the three outcomes apart:storage_cost_attoPricedSampleVerifiedAllAlreadyStored"0"(exactly free)AllSamplesAlreadyStoredIncomplete"0"(best-effort; payment reconciles)The CLI renders the confidence ("likely already stored — free (confirmed at payment)") instead of catching the error.
API compatibility
UploadCostEstimateis now#[non_exhaustive](matchingFileUploadResult) so future field additions aren't breaking. This addition is the one-time break: downstream code that constructs or exhaustively destructures the struct must update.confidencefield is#[serde(default)], so existing JSON deserializes unchanged (defaults toPricedSample).Error::CostEstimationInconclusiveis retained (no longer produced) to avoid removing a public variant.Tests
distributed_sample_indicesspread / coverage / range invariants.e2e_cost_estimate.rs): a fully-stored >5-chunk file re-estimates toOk+AllSamplesAlreadyStoredIncomplete(the regression); a fully-stored small file re-estimates toVerifiedAllAlreadyStored.cargo clippy --all-targets --all-features -- -D warningsandcargo fmtare clean; unit tests pass. (E2E tests require a testnet to run.)Closes #114
🤖 Generated with Claude Code