Skip to content

fix: default redundancy level#5383

Draft
nugaon wants to merge 13 commits intomasterfrom
fix/default-redundancy-level
Draft

fix: default redundancy level#5383
nugaon wants to merge 13 commits intomasterfrom
fix/default-redundancy-level

Conversation

@nugaon
Copy link
Copy Markdown
Member

@nugaon nugaon commented Feb 27, 2026

Resolves: #5282

Fix: Redundancy Level Validations and Default Handling

Problem Statement

The Bee API had inconsistent handling of redundancy levels across different endpoints:

  1. Missing validation: The Swarm-Redundancy-Level header was not validated, allowing invalid values to be passed through
  2. Hardcoded defaults: Many endpoints used hardcoded redundancy.DefaultLevel instead of respecting user-provided redundancy levels from request headers
  3. Incorrect semantic defaults: Upload and download operations used the same default redundancy level, despite having different safety/efficiency requirements
  4. Missing coverage: Several endpoints (stewardship, pinning, SOC, chunk, feed, ACT) had no support for the Swarm-Redundancy-Level header at all

Changes Made

1. Added Header Validation (validate:"omitempty,rLevel")

Added validation to all endpoints that accept the Swarm-Redundancy-Level header to ensure values are within the valid range (0-4):

  • pkg/api/accesscontrol.go - All 4 ACT handlers
  • pkg/api/chunk.go - Chunk upload handler (for ACT encryption only; ACT on raw chunk endpoints is debatable and may be removed in a future refactor)
  • pkg/api/feed.go - Feed post handler
  • pkg/api/pin.go - Pin root hash handler
  • pkg/api/soc.go - SOC upload handler (for ACT encryption only; not related to SOC dispersed replica behaviour — noted in OpenAPI docs)
  • pkg/api/stewardship.go - Both stewardship handlers

2. Introduced Semantic Default Levels

Created two distinct default redundancy levels in pkg/file/redundancy/level.go:

// DefaultDownloadLevel is the default redundancy level for downloading chunks
// expected to exist in the network (non-feed chunks)
const DefaultDownloadLevel = PARANOID  // Maximum safety for downloads

// DefaultUploadLevel is the default redundancy level for uploading chunks
const DefaultUploadLevel = MEDIUM  // Balanced efficiency for uploads

3. Fixed Hardcoded Redundancy Levels

Replaced hardcoded redundancy.DefaultLevel with appropriate context-aware defaults:

Upload Operations (use DefaultUploadLevel)

  • pkg/api/bytes.go - Bytes upload
  • pkg/api/feed.go - Feed post — manifest now carries the level encoding
  • pkg/api/accesscontrol.go - ACT grantee creation and grant/revoke
  • pkg/api/chunk.go - ACT encryption path only
  • pkg/api/soc.go - ACT encryption path only

Download Operations (use DefaultDownloadLevel)

  • pkg/api/bzz.go - BZZ download
  • pkg/api/accesscontrol.go - ACT decryption and list grantees
  • pkg/api/pin.go - Pinning operations
  • pkg/api/stewardship.go - Stewardship operations (previously no header support)

4. Moved rLevel from Traversal Struct to Traverse Method Parameter

pkg/traversal/traversal.go previously stored the redundancy level on the service struct at construction time. This was wrong because the same Traverser instance can be called from different sessions with different redundancy requirements (e.g. stewardship reupload vs. retrieval check). The level is now passed directly to Traverse(ctx, addr, fn, rLevel).

All callers updated accordingly:

  • pkg/api/pin.go
  • pkg/api/stewardship.go
  • pkg/steward/steward.go
  • pkg/traversal/traversal_test.go

5. Updated Steward Interface and Service

  • steward.Interface methods Reupload and IsRetrievable now accept a redundancy.Level parameter, forwarded from the API layer
  • pkg/steward/steward.go uses DefaultDownloadLevel as fallback when no level is provided via header
  • Steward tests updated to pass redundancy.PARANOID explicitly (previously no level was passed)
  • pkg/steward/mock/steward.go updated to match the new interface signatures

6. Added Swarm-Redundancy-Level Header to New Endpoints

The following endpoints previously had no support for the header and now accept it as an optional input:

  • POST /chunks — applies to ACT encryption only
  • POST /soc/{owner}/{id} — applies to ACT encryption only (OpenAPI description clarifies this is not related to SOC dispersed replicas)
  • POST /feeds/{owner}/{topic} — applies to ACT encryption
  • GET /stewardship/{reference} — controls traversal redundancy level for retrievability check
  • PUT /stewardship/{reference} — controls traversal redundancy level for re-upload
  • POST /pins/{reference} — controls traversal redundancy level for pinning
  • POST /grantee — ACT create grantee list
  • GET /grantee/{reference} — ACT read grantee list
  • PATCH /grantee/{reference} — ACT update grantee list

7. Updated OpenAPI Documentation

Updated openapi/Swarm.yaml to document the Swarm-Redundancy-Level header across all affected endpoints. Where the header only affects ACT encryption (not the primary upload/download behaviour of the endpoint), this is explicitly noted in the parameter description.

8. Updated Tests

  • Traversal tests: traversal.New no longer takes rLevel; level now passed to Traverse()
  • Steward tests: explicit redundancy.PARANOID passed to Reupload and IsRetrievable
  • Stewardship API tests: mock updated to match new interface
  • Access control, file operation, joiner, and loadsave tests updated for new defaults

Impact

Before

// All operations used the same default, no header support on most endpoints
ls := loadsave.NewReadonly(s.storer.Download(cache), s.storer.Cache(), redundancy.DefaultLevel)

After

// Downloads use PARANOID for safety, uploads use MEDIUM for efficiency
// Header is respected when provided
rLevel := redundancy.DefaultDownloadLevel
if headers.RLevel != nil {
    rLevel = *headers.RLevel
}
ls := loadsave.NewReadonly(s.storer.Download(cache), s.storer.Cache(), rLevel)

Benefits

  1. Better UX: Users can now control redundancy levels via headers across all endpoints
  2. Validation: Invalid redundancy levels are rejected early with clear error messages
  3. Semantic Defaults: Downloads prioritise safety (PARANOID), uploads prioritise efficiency (MEDIUM)
  4. Consistency: All API endpoints now handle redundancy levels uniformly
  5. ACT Support: All Access Control Trie operations now support configurable redundancy levels
  6. Correct Traversal Sessions: rLevel is now per-call rather than per-service-instance, enabling correct behaviour when the traverser is reused across different request contexts

Notes

  • The Swarm-Redundancy-Level header on POST /chunks and POST /soc/{owner}/{id} exclusively controls the ACT encryption redundancy. The chunk itself is not uploaded with erasure coding. Whether ACT should be supported on raw chunk/SOC endpoints at all is an open question for future consideration.
  • The steward service no longer handles dispersed replica re-upload internally; the redundancy level is passed through for traversal purposes only.

Checklist

  • I have read the coding guide.
  • My change requires a documentation update, and I have done it.
  • I have added tests to cover my changes.
  • I have filled out the description and linked the related issues.

Description

Open API Spec Version Changes (if applicable)

Motivation and Context (Optional)

Related Issue (Optional)

Screenshots (if appropriate):

@nugaon nugaon force-pushed the fix/default-redundancy-level branch from 975f137 to 8c4bbb0 Compare May 4, 2026 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent Swarm-Redundancy-Level Header Handling Across API Endpoints

1 participant