Skip to content

Stewardship Reupload Does Not Re-create Dispersed Replicas for Root Chunk #5450

@nugaon

Description

@nugaon

Context

  • Bee version: v2.7.2-rc1
  • Network: mainnet / testnet
  • Relevant flags: --full-node

Summary

When calling PUT /stewardship/{reference} with a non-zero Swarm-Redundancy-Level header, the stewardship service traverses and re-uploads all BMT trie chunks (data shards + RS parity shards) but silently skips re-creating the dispersed replicas for the root chunk. Dispersed replicas are SOC-wrapped copies of the root chunk spread across different Kademlia neighborhoods to provide resilience when the root chunk's own neighborhood degrades. After a reupload, these replicas remain absent or expired, leaving the content more vulnerable to retrieval failure than the requested redundancy level implies.

Expected behavior

A PUT /stewardship/{reference} call with Swarm-Redundancy-Level: N (where N > 0) should:

  1. Re-stamp and re-push all BMT trie chunks (data + RS parity) — already done.
  2. Re-create and push the 2^N dispersed replica SOC chunks for the root chunk to their target neighborhoods, consistent with what replicas.NewPutter does at original upload time.

This ensures the full redundancy guarantee for the given level is restored, not just the erasure-coded intermediate structure.

Actual behavior

Only the BMT trie chunks are re-uploaded. The dispersed replicas are not re-created.

Inspecting the implementation in pkg/steward/steward.go:

if err := s.traverser.Traverse(ctx, root, fn, rLevel); err != nil { ... }
return uploaderSession.Done(root)

traversal.Traversejoiner.IterateChunkAddresses only walks the BMT trie. Dispersed replicas are SOC chunks outside the trie, created by replicas.NewPutter, and are never visited nor re-uploaded.

Calling the API:

curl -X PUT http://localhost:1633/stewardship/<reference> \
  -H "Swarm-Postage-Batch-Id: <batch-id>" \
  -H "Swarm-Redundancy-Level: 4"

Returns 200 OK with no error, but the dispersed replicas for the root chunk are not re-pushed to the network.

Steps to reproduce

  1. Upload a file with redundancy enabled:
    curl -X POST http://localhost:1633/bzz \
      -H "Swarm-Postage-Batch-Id: <batch-id>" \
      -H "Swarm-Redundancy-Level: 4" \
      -H "Content-Type: application/octet-stream" \
      --data-binary @file.bin
    # note the returned <reference>
  2. Wait for dispersed replica stamps to expire, or simulate their loss.
  3. Call reupload:
    curl -X PUT http://localhost:1633/stewardship/<reference> \
      -H "Swarm-Postage-Batch-Id: <new-batch-id>" \
      -H "Swarm-Redundancy-Level: 4"
  4. Verify no dispersed replicas (SOC chunks with well-known owner swarm.ReplicasOwner) have been pushed to the network by checking pushsync logs at level=trace.

Possible solution

After the traversal completes successfully, fetch the root chunk from local storage (already cached from traversal) and pass it through replicas.NewPutter with the requested rLevel:

The root chunk is already in local storage at this point (fetched during traversal), so no extra network retrieval is required.

AI Disclosure

  • This issue contains suggestions and text generated by an LLM.
  • I have reviewed the AI generated content thoroughly.
  • I possess the technical expertise to responsibly review the AI generated content mentioned in this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions