Project instructions for AI coding assistants and agents (OpenAI Codex, Cursor, GitHub Copilot, Claude Code, and similar tools). This file is the canonical source of shared project instructions; CLAUDE.md imports this file for Claude Code.
Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game).
Module: github.com/ethersphere/bee/v2
Go version: 1.26 (see go.mod)
License: BSD 3-clause (see LICENSE)
Human-oriented contributing docs: CONTRIBUTING.md, CODING.md, CODINGSTYLE.md, README.md.
Keep changes minimal and focused. Only touch code that belongs to the task. Do not refactor unrelated code, rename symbols for style only, or mix unrelated fixes in one commit or PR.
Read CONTRIBUTING.md, CODING.md, and CODINGSTYLE.md for process, patterns, and style. Prefer matching existing naming, types, imports, and log style in the files you edit.
Do not add, remove, or update go.mod dependencies unless the task explicitly requires it or the person asking for the work explicitly requests a dependency change.
Handle errors and logging the way this repo does: propagate errors with context (fmt.Errorf("…: %w", err)), avoid logging and returning the same error, and use structured logging with clear operator vs developer levels (see CODING.md).
Prefer package foo_test tests, export_test.go when you must export internals, and t.Parallel() only where it is safe. Add or update tests when behavior changes. Integration tests use -tags=integration.
Before you finish a change set (especially before a commit or PR), run these and fix failures:
- Formatting —
make format(gofumpt + gci; seeCODING.md). - Compile —
make build(all packages) and, when you need the binary artifact,make binary(dist/bee,CGO_ENABLED=0). - Tests —
make test(unit tests,-failfast). For a single package usego test ./pkg/<name>/.... Usemake test-racewhen concurrency is central to the change. Usemake test-integrationonly when you touch integration-tagged code. - Static checks —
make lintandmake vet(see.golangci.yml).
CI pipelines may use make test-ci / make test-ci-race (see Makefile for flags).
make binary # dist/bee
make build # compile all packages
make test # unit tests
make test-race # unit tests + race detector
make lint # golangci-lint (see .golangci.yml)
make vet # go vet
make protobuf # regenerate *.pb.go after changing .proto filesBinary built from cmd/bee/main.go. CLI uses Cobra + Viper:
bee start— full or light node (cmd/bee/cmd/start.go)bee init— initialize data directorybee deploy— deploy smart contractsbee db— database managementbee version— print version info
Configuration: option constants in cmd/bee/cmd/cmd.go. Viper reads CLI flags, environment variables (BEE_ prefix), and YAML config.
pkg/node/node.go is the main orchestrator. NewBee() wires subsystems via dependency injection; avoid global mutable state. The Bee struct holds service references and provides Shutdown() for teardown.
- Router:
gorilla/muxinpkg/api/router.go - Route groups in
Mount():mountTechnicalDebug()—/node,/addresses,/health,/readiness,/metrics,/loggers, pprofmountBusinessDebug()— topology, accounting, settlements, stamps managementmountAPI()—/bytes,/chunks,/bzz,/feeds,/soc,/stamps,/tags,/pins,/pss,/grantee
checkRouteAvailabilitycan block endpoints during sync- OpenAPI:
openapi/Swarm.yaml(API versioning follows SemVer there; the main Bee release version does not) - Endpoints exist at root (e.g.
/bytes) and under/v1/(e.g./v1/bytes)
- Transport: libp2p (
pkg/p2p/libp2p/) - Wire formats: protobuf (gogo) — each protocol area has a
pb/directory with.protoanddoc.go(go:generatecallingprotoc+--gogofaster_out) - Important protocol packages:
pushsync,pullsync,retrieval,pingpong,hive,pricing
- Chunk types: CAC (
pkg/cac/), SOC (pkg/soc/) - Interfaces:
pkg/storage/(Putter,Getter,Hasser,Deleter) - Local store:
pkg/storer/(reserve, cache, upload, pinning) - Blob engine:
pkg/sharky/ - BMT:
pkg/bmt/ - State:
pkg/statestore/(LevelDB);pkg/shed/(typed LevelDB layer)
pkg/postage/— batches, stamps, servicespkg/postage/listener/— on-chain eventspkg/postage/postagecontract/— contract interaction- Stamps: batch ID, depth (capacity), amount (per-chunk value)
pkg/storageincentives/— redistribution / storage incentive game
- Address — 32-byte hash (
pkg/swarm/). Chunk and overlay addresses; proximity is XOR-based (more shared prefix bits = closer), not lexicographic ordering. - Chunk — 4096 bytes of data (
ChunkSize = SectionSize * Branches = 32 * 128), plus 8-byte span (SpanSize);ChunkWithSpanSize = 4104. - CAC — content-addressed chunk; address from BMT root of data.
- SOC — single owner chunk; address from owner + id, with signature.
- PO — proximity order (shared prefix bits).
MaxPO = 31,ExtendedPO = 36. - Neighborhood — prefix / responsibility region for storage and sync.
- Kademlia — routing table over XOR distance (
pkg/topology/). - Postage stamp — payment signal attached to chunks.
- Push sync / pull sync — push new data toward neighborhood; pull historical sync between peers.
- Redistribution — incentive game proving reserve storage.
Every .go file starts with:
// Copyright <year> The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.- Propagate errors; do not log and return the same error. Use
fmt.Errorf("context: %w", err). Avoid stacking "failed to" prefixes. - Sentinel errors:
var ErrFoo = errors.New("package: description")— identity only, compared witherrors.Is. - Typed errors: a struct implementing
errorwith exported fields, inspected witherrors.Aswhen callers need data about the failure. - Logging: separate operator-facing (
Error/Warning) from developer detail (Debug, V-levels). Keys:lower_snake_case, specific names. Runtime log tuning:/loggersAPI. - Every goroutine needs a clear shutdown path. Channels: prefer unbuffered or size 1 unless strongly justified; an owning goroutine sends or closes.
- Prefer external test packages:
package foo_testnotpackage foo. export_test.goin the real package to export symbols only for tests.- Use
t.Parallel()where safe. Avoid the wordfailin test names. Integration:-tags=integration. Prefert.Fatal/t.FailNowoverpanicin tests.
- American English (e.g. marshaling, canceled).
- Avoid
init()where possible (gochecknoinits). - Enums often start at
iota + 1when zero should mean "unset". - Use
time.Time/time.Duration, not raw ints for time. var _ Interface = (*Impl)(nil)where useful.- Dependency injection over mutable globals. Exit only from
main().
Never commit or push to git.
- Do not confuse
ChunkSize(4096 data bytes) withChunkWithSpanSize(4104 including span). - XOR distance: XOR between two addresses produces smaller integers as more prefix bits are shared, do not confuse this with lexicographic ordering of addresses.
- Goroutines must be stoppable (context cancel, quit channel, etc.).
- Full node vs light node: reserve and storage incentives are full-node concerns.
- Postage batches can be unusable (expired, depleted, unsynced); check before relying on stamps. g