Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
- name: Lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.10.1
version: v2.11.3
args: --timeout 10m
skip-cache: false
skip-cache: true
- name: Vet
run: make vet
- name: Whitespace check
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Beekeeper consumes Bee as a library (`github.com/ethersphere/bee/v2` in `go.mod`
```bash
make binary # build ./dist/beekeeper (CGO disabled, version stamped via -ldflags)
make test # unit tests: go test -v ./pkg/...
make lint # golangci-lint (pinned v2.10.1; auto-installs if missing)
make lint # golangci-lint (pinned v2.11.3; auto-installs if missing)
```

Run a single test: `go test -run TestName ./pkg/<package>/...` (add `-race` to mirror CI).
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GO ?= go
GOLANGCI_LINT ?= golangci-lint
GOLANGCI_LINT_VERSION ?= v2.10.1
GOLANGCI_LINT_VERSION ?= v2.11.3
COMMIT ?= "$(shell git describe --long --dirty --always --match "" || true)"
VERSION ?= "$(shell git describe --tags --abbrev=0 | cut -c2-)"
LDFLAGS ?= -s -w \
Expand Down
3 changes: 2 additions & 1 deletion config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ bee-configs:
db-disable-seeks-compaction: false
db-open-files-limit: 200
db-write-buffer-size: 33554432
full-node: true
node-mode: full
mainnet: false
nat-addr: ""
network-id: 12345
Expand Down Expand Up @@ -134,6 +134,7 @@ bee-configs:
bootnode:
_inherit: "default"
bootnode-mode: true
storage-incentives-enable: false # no effect on bootnodes; bee warns when it is true

# checks defines checks Beekeeper can execute against the cluster
# type filed allows defining same check with different names and options
Expand Down
3 changes: 2 additions & 1 deletion config/light-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
bee-configs:
light-node:
_inherit: default
full-node: false
node-mode: light
storage-incentives-enable: false # inherited true is rejected in light mode

# node groups for light nodes
node-groups:
Expand Down
25 changes: 21 additions & 4 deletions config/local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ clusters:
config: local-dns
count: 3
mode: node
bee-legacy:
bee-config: bee-local-dns-legacy
config: local-dns
count: 1
mode: node
light:
bee-config: bee-local-light
config: local-light
Expand Down Expand Up @@ -162,7 +167,7 @@ bee-configs:
db-disable-seeks-compaction: false
db-open-files-limit: 200
db-write-buffer-size: 33554432
full-node: true
node-mode: full
mainnet: false
nat-addr: ""
nat-wss-addr: ""
Expand Down Expand Up @@ -192,6 +197,7 @@ bee-configs:
bootnode-local-dns-autotls:
_inherit: "bee-local-dns"
bootnode-mode: true
storage-incentives-enable: false # no effect on bootnodes; bee warns when it is true
p2p-wss-enable: true
bee-local-autotls:
_inherit: "bee-local-dns"
Expand All @@ -201,27 +207,38 @@ bee-configs:
p2p-wss-enable: true
bee-local-ultralight-autotls:
_inherit: "bee-local-dns"
full-node: false
node-mode: ultra-light
p2p-wss-enable: true
blockchain-rpc-endpoint: # ultralight nodes don't connect to the blockchain
blockchain-rpc-endpoint: "" # ultralight nodes don't connect to the blockchain; empty, not null, so the inherited endpoint is cleared
swap-enable: false
chequebook-enable: false # inherited true is rejected without swap
storage-incentives-enable: false # inherited true is rejected in ultra-light mode
bootnode-local:
_inherit: "bee-local"
bootnode-mode: true
storage-incentives-enable: false # no effect on bootnodes; bee warns when it is true
bee-local-dns:
_inherit: "bee-local"
bee-local-dns-legacy:
_inherit: "bee-local-dns"
node-mode: "" # overrides the inherited mode so bee infers it from full-node (legacy regime)
full-node: true
bootnode-local-dns:
_inherit: "bee-local"
bootnode-mode: true
storage-incentives-enable: false # no effect on bootnodes; bee warns when it is true
bee-local-light:
_inherit: "bee-local"
full-node: false
node-mode: light
storage-incentives-enable: false # inherited true is rejected in light mode
bee-local-gc:
_inherit: "bee-local"
cache-capacity: 10
bootnode-local-gc:
_inherit: "bee-local"
cache-capacity: 10
bootnode-mode: true
storage-incentives-enable: false # no effect on bootnodes; bee warns when it is true

# CI checks
checks:
Expand Down
2 changes: 1 addition & 1 deletion config/public-testnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ bee-configs:
sepolia:
_inherit: ""
bootnode: ["/dnsaddr/testnet.ethswarm.org"]
full-node: true
node-mode: full

checks:
pt-pingpong:
Expand Down
2 changes: 1 addition & 1 deletion config/staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ bee-configs:
api-addr: ":1633"
blockchain-rpc-endpoint: http://rpc-sepolia-haproxy.default.svc.swarm1.local
bootnode: ["/dnsaddr/testnet.ethswarm.org"]
full-node: true
node-mode: full
mainnet: false
network-id: 10
p2p-addr: ":1634"
Expand Down
3 changes: 2 additions & 1 deletion config/testnet-bee-playground.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ bee-configs:
bootnode: []
chequebook-enable: true
data-dir: "/home/bee/.bee"
full-node: true
node-mode: full
mainnet: false
network-id: 12345
p2p-addr: :1634
Expand All @@ -65,6 +65,7 @@ bee-configs:
geth-playground-bootnode:
_inherit: "geth-playground"
bootnode-mode: true
storage-incentives-enable: false # no effect on bootnodes; bee warns when it is true

checks:
pg-pingpong:
Expand Down
66 changes: 66 additions & 0 deletions pkg/config/inherit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package config_test

import (
"io"
"os"
"testing"

"github.com/ethersphere/beekeeper/pkg/config"
"github.com/ethersphere/beekeeper/pkg/logging"
"gopkg.in/yaml.v3"
)

// TestBeeConfigInheritance verifies that _inherit still merges per flag (not
Expand Down Expand Up @@ -47,3 +49,67 @@ bee-configs:
t.Errorf("FullNode = %v, want child override false", c.FullNode)
}
}

// TestLocalDNSLegacyNodeGroup verifies that the local-dns cluster runs one node
// group in bee's legacy regime next to the node-mode groups: the legacy
// profile overrides the inherited node-mode with an empty value, so bee infers
// the mode from full-node, while its siblings keep the explicit mode.
func TestLocalDNSLegacyNodeGroup(t *testing.T) {
t.Parallel()

in, err := os.ReadFile("../../config/local.yaml")
if err != nil {
t.Fatalf("read local.yaml: %v", err)
}
cfg, err := config.Read(logging.New(io.Discard, 0), []config.YamlFile{{Name: "local.yaml", Content: in}})
if err != nil {
t.Fatalf("read config: %v", err)
}

cluster, ok := cfg.Clusters["local-dns"]
if !ok {
t.Fatal("local-dns cluster not found")
}
ng, ok := cluster.GetNodeGroups()["bee-legacy"]
if !ok {
t.Fatal("bee-legacy node group not found in local-dns")
}

legacy, ok := cfg.BeeConfigs[ng.BeeConfig]
if !ok {
t.Fatalf("bee-config %q not found", ng.BeeConfig)
}
l := legacy.Export()
if l.NodeMode == nil {
t.Error("NodeMode = nil, want explicit empty override")
} else if *l.NodeMode != "" {
t.Errorf("NodeMode = %q, want explicit empty override", *l.NodeMode)
}
if l.FullNode == nil || !*l.FullNode {
t.Errorf("FullNode = %v, want true", l.FullNode)
}
if !l.IsFullNode() {
t.Error("IsFullNode() = false, want true from the full-node fallback")
}

out, err := yaml.Marshal(l)
if err != nil {
t.Fatalf("marshal bee config: %v", err)
}
rendered := map[string]any{}
if err := yaml.Unmarshal(out, &rendered); err != nil {
t.Fatalf("unmarshal rendered config: %v", err)
}
if got, ok := rendered["node-mode"]; !ok || got != "" {
t.Errorf("rendered node-mode = %v (present %t), want empty string so bee selects the legacy regime", got, ok)
}
if got := rendered["full-node"]; got != true {
t.Errorf("rendered full-node = %v, want true", got)
}

dns := cfg.BeeConfigs["bee-local-dns"]
modern := dns.Export()
if !modern.IsFullNode() || modern.NodeMode == nil || *modern.NodeMode != "full" {
t.Error("bee-local-dns should keep the explicit node-mode full")
}
}
1 change: 1 addition & 0 deletions pkg/orchestration/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Cluster interface {
FullNodeNames() (names []string)
GlobalReplicationFactor(ctx context.Context, a swarm.Address) (grf int, err error)
LightNodeNames() (names []string)
UltraLightNodeNames() (names []string)
Name() string
Namespace() string
NodeGroup(name string) (ng NodeGroup, err error)
Expand Down
75 changes: 75 additions & 0 deletions pkg/orchestration/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,78 @@ func TestDeref(t *testing.T) {
t.Errorf("Deref(new(false)) = %v, want false", got)
}
}

func TestNodeModeHelpers(t *testing.T) {
t.Parallel()

strPtr := func(s string) *string { return &s }
boolPtr := func(b bool) *bool { return &b }

tests := []struct {
name string
cfg orchestration.Config
wantFull bool
wantLight bool
wantUltraLight bool
}{
{
name: "explicit node-mode full",
cfg: orchestration.Config{NodeMode: strPtr("full")},
wantFull: true,
wantLight: false,
wantUltraLight: false,
},
{
name: "explicit node-mode light",
cfg: orchestration.Config{NodeMode: strPtr("light")},
wantFull: false,
wantLight: true,
wantUltraLight: false,
},
{
name: "explicit node-mode ultra-light",
cfg: orchestration.Config{NodeMode: strPtr("ultra-light")},
wantFull: false,
wantLight: false,
wantUltraLight: true,
},
{
name: "legacy full-node true",
cfg: orchestration.Config{FullNode: boolPtr(true)},
wantFull: true,
wantLight: false,
wantUltraLight: false,
},
{
name: "legacy full-node false with rpc (light)",
cfg: orchestration.Config{
FullNode: boolPtr(false),
BlockchainRPCEndpoint: strPtr("http://localhost:8545"),
},
wantFull: false,
wantLight: true,
wantUltraLight: false,
},
{
name: "legacy full-node false without rpc (ultra-light)",
cfg: orchestration.Config{FullNode: boolPtr(false)},
wantFull: false,
wantLight: false,
wantUltraLight: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.cfg.IsFullNode(); got != tt.wantFull {
t.Errorf("IsFullNode() = %v, want %v", got, tt.wantFull)
}
if got := tt.cfg.IsLightNode(); got != tt.wantLight {
t.Errorf("IsLightNode() = %v, want %v", got, tt.wantLight)
}
if got := tt.cfg.IsUltraLightNode(); got != tt.wantUltraLight {
t.Errorf("IsUltraLightNode() = %v, want %v", got, tt.wantUltraLight)
}
})
}
}
18 changes: 14 additions & 4 deletions pkg/orchestration/k8s/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,17 @@ func (c *Cluster) NodeNames() (names []string) {
// LightNodeNames returns a list of light node names
func (c *Cluster) LightNodeNames() (names []string) {
for name, node := range c.Nodes() {
if !orchestration.Deref(node.Config().FullNode) {
if node.Config().IsLightNode() {
names = append(names, name)
}
}
return names
}

// UltraLightNodeNames returns a list of ultra-light node names
func (c *Cluster) UltraLightNodeNames() (names []string) {
for name, node := range c.Nodes() {
if node.Config().IsUltraLightNode() {
names = append(names, name)
}
}
Expand All @@ -237,7 +247,7 @@ func (c *Cluster) LightNodeNames() (names []string) {
func (c *Cluster) FullNodeNames() (names []string) {
for name, node := range c.Nodes() {
cfg := node.Config()
if orchestration.Deref(cfg.FullNode) && !orchestration.Deref(cfg.BootnodeMode) {
if cfg.IsFullNode() && !orchestration.Deref(cfg.BootnodeMode) {
names = append(names, name)
}
}
Expand All @@ -249,7 +259,7 @@ func (c *Cluster) ShuffledFullNodeClients(ctx context.Context, r *rand.Rand) (or
var res orchestration.ClientList
for _, node := range c.Nodes() {
cfg := node.Config()
if orchestration.Deref(cfg.FullNode) && !orchestration.Deref(cfg.BootnodeMode) {
if cfg.IsFullNode() && !orchestration.Deref(cfg.BootnodeMode) {
res = append(res, node.Client())
}
}
Expand Down Expand Up @@ -464,7 +474,7 @@ func (c *Cluster) ClosestFullNodeClient(ctx context.Context, s *bee.Client) (*be
}
cfg := node.Config()
// closet peer is not a full node. Check other peers in the same bin
if !orchestration.Deref(cfg.FullNode) || orchestration.Deref(cfg.BootnodeMode) {
if !cfg.IsFullNode() || orchestration.Deref(cfg.BootnodeMode) {
skipList = append(skipList, addr)
b--
continue
Expand Down
Loading
Loading