diff --git a/.github/workflows/beekeeper.yml b/.github/workflows/beekeeper.yml index 51f8de9f1ba..f8e5cf97fea 100644 --- a/.github/workflows/beekeeper.yml +++ b/.github/workflows/beekeeper.yml @@ -20,7 +20,7 @@ env: SETUP_CONTRACT_IMAGE: "ethersphere/bee-localchain" SETUP_CONTRACT_IMAGE_TAG: "0.9.4" BEELOCAL_BRANCH: "main" - BEEKEEPER_BRANCH: "master" + BEEKEEPER_BRANCH: "refactor/node-mode-two-regimes" BEEKEEPER_METRICS_ENABLED: false REACHABILITY_OVERRIDE_PUBLIC: true BATCHFACTOR_OVERRIDE_PUBLIC: 2 diff --git a/.golangci.yml b/.golangci.yml index ad34693a925..ae7330aaace 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,6 +73,10 @@ linters: - linters: - staticcheck text: "SA5008: malformed `json` tag: invalid trailing ',' character" + - linters: + - staticcheck + path: cmd/bee/cmd + text: "(this comparison is always true|never returns a nil interface value|the lhs of the comparison)" paths: - third_party$ - builtin$ diff --git a/cmd/bee/cmd/cmd.go b/cmd/bee/cmd/cmd.go index 658012fabce..23056913c0d 100644 --- a/cmd/bee/cmd/cmd.go +++ b/cmd/bee/cmd/cmd.go @@ -55,11 +55,12 @@ const ( optionNameBzzTokenAddress = "bzz-token-address" optionNameSwapFactoryAddress = "swap-factory-address" optionNameSwapInitialDeposit = "swap-initial-deposit" + optionNameNodeMode = "node-mode" optionNameSwapEnable = "swap-enable" optionNameChequebookEnable = "chequebook-enable" optionNameChequebookVerification = "chequebook-verification" optionNameChequebookMinBalance = "chequebook-min-balance" - optionNameFullNode = "full-node" + optionNameFullNode = "full-node" // Deprecated: use node-mode instead. optionNameLightNodeLimit = "light-node-limit" optionNamePostageContractAddress = "postage-stamp-address" optionNamePostageContractStartBlock = "postage-stamp-start-block" @@ -357,11 +358,15 @@ func (c *command) setAllFlags(cmd *cobra.Command) { cmd.Flags().String(optionNameSwapFactoryAddress, "", "swap factory addresses") cmd.Flags().String(optionNameBzzTokenAddress, "", "bzz token contract address") cmd.Flags().String(optionNameSwapInitialDeposit, "0", "initial deposit if deploying a new chequebook") + cmd.Flags().String(optionNameNodeMode, "", "node operational mode: full, light, or ultra-light (unset: inferred from deprecated full-node and blockchain-rpc-endpoint)") cmd.Flags().Bool(optionNameSwapEnable, false, "enable swap") - cmd.Flags().Bool(optionNameChequebookEnable, true, "enable chequebook") + cmd.Flags().Bool(optionNameChequebookEnable, false, "enable chequebook (requires swap-enable)") cmd.Flags().Bool(optionNameChequebookVerification, false, "reject full-node hive/handshake records that carry no chequebook address") cmd.Flags().String(optionNameChequebookMinBalance, "110000000000000000", "minimum chequebook token balance required for verification, in token small units (default 11 BZZ)") - cmd.Flags().Bool(optionNameFullNode, false, "cause the node to start in full mode") + cmd.Flags().Bool(optionNameFullNode, false, "cause the node to start in full mode (deprecated: use --node-mode=full)") + if err := cmd.Flags().MarkDeprecated(optionNameFullNode, "use --node-mode=full instead"); err != nil { + panic(err) + } cmd.Flags().Int(optionNameLightNodeLimit, 100, "light node limit") cmd.Flags().String(optionNamePostageContractAddress, "", "postage stamp contract address") cmd.Flags().Uint64(optionNamePostageContractStartBlock, 0, "postage stamp contract start block number") @@ -378,7 +383,7 @@ func (c *command) setAllFlags(cmd *cobra.Command) { cmd.Flags().Bool(optionNamePProfMutex, false, "enable pprof mutex profile") cmd.Flags().StringSlice(optionNameStaticNodes, []string{}, "protect nodes from getting kicked out on bootnode") cmd.Flags().Bool(optionNameAllowPrivateCIDRs, false, "allow to advertise private CIDRs to the public network") - cmd.Flags().Bool(optionNameStorageIncentivesEnable, true, "enable storage incentives feature") + cmd.Flags().Bool(optionNameStorageIncentivesEnable, false, "enable storage incentives feature (full node only)") cmd.Flags().Uint64(optionNameStateStoreCacheCapacity, 100_000, "lru memory caching capacity in number of statestore entries") cmd.Flags().String(optionNameTargetNeighborhood, "", "neighborhood to target in binary format (ex: 111111001) for mining the initial overlay") cmd.Flags().String(optionNameNeighborhoodSuggester, "https://api.swarmscan.io/v1/network/neighborhoods/suggestion", "suggester for target neighborhood") diff --git a/cmd/bee/cmd/resolve_node_mode_test.go b/cmd/bee/cmd/resolve_node_mode_test.go new file mode 100644 index 00000000000..c9c9e5c6fdb --- /dev/null +++ b/cmd/bee/cmd/resolve_node_mode_test.go @@ -0,0 +1,517 @@ +// Copyright 2026 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. + +package cmd + +import ( + "strings" + "testing" + + "github.com/ethersphere/bee/v2/pkg/log" + "github.com/ethersphere/bee/v2/pkg/node" + "github.com/spf13/viper" +) + +const testRPCEndpoint = "http://localhost:8545" + +func TestResolveNodeMode(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + config map[string]any + wantMode node.NodeMode + wantErr string + // wantOptions holds the values the resolver must leave in config for the + // rest of startup to read. Keys not listed are not checked. + wantOptions map[string]bool + }{ + // ── node-mode set: the mode owns the config ────────────────────────────── + { + name: "full with rpc only implies swap, chequebook and incentives", + config: map[string]any{ + optionNameNodeMode: "full", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + }, + { + name: "full with all options explicitly enabled succeeds", + config: map[string]any{ + optionNameNodeMode: "full", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + wantMode: node.FullMode, + }, + { + name: "full without rpc fails", + config: map[string]any{ + optionNameNodeMode: "full", + }, + wantErr: "full node requires blockchain-rpc-endpoint", + }, + { + // A non-staking full node is a legitimate opt-out. + name: "full with storage-incentives explicitly false honours the opt-out", + config: map[string]any{ + optionNameNodeMode: "full", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameStorageIncentivesEnable: false, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: false, + }, + }, + { + // Disabling swap must not drag an implied chequebook into a + // contradiction the operator never wrote. + name: "full with swap explicitly false leaves chequebook off", + config: map[string]any{ + optionNameNodeMode: "full", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: false, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: true, + }, + }, + { + // Receive-only swap: cash out cheques without issuing them. + name: "full with chequebook explicitly false keeps swap on", + config: map[string]any{ + optionNameNodeMode: "full", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameChequebookEnable: false, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: true, + optionNameChequebookEnable: false, + }, + }, + { + name: "full with chequebook explicitly true and swap explicitly false fails", + config: map[string]any{ + optionNameNodeMode: "full", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: false, + optionNameChequebookEnable: true, + }, + wantErr: "chequebook-enable requires swap-enable", + }, + { + // NewBee never starts swap, push-sync or the incentives agent for a + // bootnode, so full mode must not imply them there. + name: "full bootnode does not imply swap, chequebook or incentives", + config: map[string]any{ + optionNameNodeMode: "full", + optionNameBootnodeMode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + }, + { + name: "full bootnode with storage-incentives explicitly false succeeds", + config: map[string]any{ + optionNameNodeMode: "full", + optionNameBootnodeMode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameStorageIncentivesEnable: false, + }, + wantMode: node.FullMode, + }, + { + name: "light with rpc succeeds without swap", + config: map[string]any{ + optionNameNodeMode: "light", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.LightMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + }, + { + name: "light with rpc, swap and chequebook succeeds", + config: map[string]any{ + optionNameNodeMode: "light", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + }, + wantMode: node.LightMode, + }, + { + name: "light without rpc fails", + config: map[string]any{ + optionNameNodeMode: "light", + }, + wantErr: "light node requires blockchain-rpc-endpoint", + }, + { + name: "light with chequebook but no swap fails", + config: map[string]any{ + optionNameNodeMode: "light", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameChequebookEnable: true, + }, + wantErr: "chequebook-enable requires swap-enable", + }, + { + name: "light rejects storage-incentives-enable", + config: map[string]any{ + optionNameNodeMode: "light", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameStorageIncentivesEnable: true, + }, + wantErr: "light node cannot have storage-incentives-enable", + }, + { + name: "ultra-light succeeds", + config: map[string]any{ + optionNameNodeMode: "ultra-light", + }, + wantMode: node.UltraLightMode, + }, + { + name: "ultra-light with rpc ignores rpc and succeeds", + config: map[string]any{ + optionNameNodeMode: "ultra-light", + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.UltraLightMode, + }, + { + name: "ultra-light rejects swap-enable", + config: map[string]any{ + optionNameNodeMode: "ultra-light", + optionNameSwapEnable: true, + }, + wantErr: "ultra-light node cannot have swap-enable", + }, + { + name: "ultra-light rejects storage-incentives-enable", + config: map[string]any{ + optionNameNodeMode: "ultra-light", + optionNameStorageIncentivesEnable: true, + }, + wantErr: "ultra-light node cannot have storage-incentives-enable", + }, + { + name: "node-mode takes precedence over legacy full-node", + config: map[string]any{ + optionNameNodeMode: "light", + optionNameFullNode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.LightMode, + }, + { + name: "invalid node-mode value fails", + config: map[string]any{ + optionNameNodeMode: "superlight", + }, + wantErr: "invalid node-mode", + }, + { + name: "uppercase node-mode fails", + config: map[string]any{ + optionNameNodeMode: "FULL", + }, + wantErr: "invalid node-mode", + }, + { + name: "whitespace node-mode fails", + config: map[string]any{ + optionNameNodeMode: " full ", + }, + wantErr: "invalid node-mode", + }, + + // ── node-mode unset: legacy behaviour, verbatim ───────────────────────── + { + // The most common pre-node-mode light config. chequebook-enable used + // to default to true, so this node issued cheques; it must keep doing so. + name: "legacy light with swap only restores chequebook default", + config: map[string]any{ + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: true, + }, + wantMode: node.LightMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + }, + { + // The old shipped default; chequebook stays gated on swap in NewBee. + name: "legacy chequebook without swap starts", + config: map[string]any{ + optionNameChequebookEnable: true, + }, + wantMode: node.UltraLightMode, + }, + { + name: "legacy full-node with rpc only restores old defaults and leaves swap off", + config: map[string]any{ + optionNameFullNode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + }, + { + name: "legacy full-node with all options set maps to full", + config: map[string]any{ + optionNameFullNode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + wantMode: node.FullMode, + }, + { + name: "legacy full-node with explicit opt-outs is not validated", + config: map[string]any{ + optionNameFullNode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: false, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + }, + { + name: "legacy bootnode with storage-incentives false starts", + config: map[string]any{ + optionNameFullNode: true, + optionNameBootnodeMode: true, + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameStorageIncentivesEnable: false, + }, + wantMode: node.FullMode, + }, + { + // Previous releases enabled the chain backend for every full node and + // failed at chain init without an endpoint; keep failing, earlier. + name: "legacy full-node without rpc fails", + config: map[string]any{ + optionNameFullNode: true, + }, + wantErr: "full node requires blockchain-rpc-endpoint", + }, + { + name: "legacy with rpc infers light", + config: map[string]any{ + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + }, + wantMode: node.LightMode, + }, + { + name: "legacy without rpc infers ultra-light", + config: map[string]any{}, + wantMode: node.UltraLightMode, + }, + { + // Beekeeper's inherited-config scenario: swap-enable inherited from the + // base profile on a node without rpc. Legacy must not validate it. + name: "legacy without rpc but with swap infers ultra-light without error", + config: map[string]any{ + optionNameSwapEnable: true, + }, + wantMode: node.UltraLightMode, + }, + { + // Legacy must not restore a default the operator overrode. + name: "legacy explicit false is preserved", + config: map[string]any{ + configKeyBlockchainRpcEndpoint: testRPCEndpoint, + optionNameSwapEnable: true, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + wantMode: node.LightMode, + wantOptions: map[string]bool{ + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + c := &command{ + config: viper.New(), + logger: log.Noop, + } + for k, v := range tt.config { + c.config.Set(k, v) + } + + gotMode, err := c.resolveNodeMode(c.logger) + + if tt.wantErr != "" { + if err == nil { + t.Fatalf("expected error containing %q, got nil (mode=%q)", tt.wantErr, gotMode) + } + if !strings.Contains(err.Error(), tt.wantErr) { + t.Fatalf("expected error containing %q, got %q", tt.wantErr, err.Error()) + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if gotMode != tt.wantMode { + t.Errorf("got mode %q, want %q", gotMode, tt.wantMode) + } + for key, want := range tt.wantOptions { + if got := c.config.GetBool(key); got != want { + t.Errorf("option %q: got %t, want %t", key, got, want) + } + } + }) + } +} + +// TestResolveNodeModeWithBoundFlags runs the resolver against a viper bound to +// the real start command flags, as production does, so the flag defaults are +// exercised: an unset node-mode must select the legacy regime, and the flag +// defaults of the sub-options must not count as explicitly set. +func TestResolveNodeModeWithBoundFlags(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + args []string + wantMode node.NodeMode + wantOptions map[string]bool + }{ + { + name: "no flags selects legacy regime and restores old defaults", + args: nil, + wantMode: node.UltraLightMode, + wantOptions: map[string]bool{ + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + }, + { + name: "legacy full-node flag with rpc", + args: []string{"--full-node", "--blockchain-rpc-endpoint=" + testRPCEndpoint}, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + }, + { + name: "node-mode full with rpc implies the full stack", + args: []string{"--node-mode=full", "--blockchain-rpc-endpoint=" + testRPCEndpoint}, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: true, + }, + }, + { + name: "node-mode light with rpc keeps sub-option defaults", + args: []string{"--node-mode=light", "--blockchain-rpc-endpoint=" + testRPCEndpoint}, + wantMode: node.LightMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: false, + optionNameChequebookEnable: false, + optionNameStorageIncentivesEnable: false, + }, + }, + { + name: "node-mode full with incentives explicitly disabled", + args: []string{"--node-mode=full", "--blockchain-rpc-endpoint=" + testRPCEndpoint, "--storage-incentives-enable=false"}, + wantMode: node.FullMode, + wantOptions: map[string]bool{ + optionNameSwapEnable: true, + optionNameChequebookEnable: true, + optionNameStorageIncentivesEnable: false, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + root, err := newCommand(func(c *command) { c.homeDir = t.TempDir() }) + if err != nil { + t.Fatal(err) + } + startCmd := root.SubCommandForTest("start") + if startCmd == nil { + t.Fatal("start subcommand not found") + } + if err := startCmd.ParseFlags(tt.args); err != nil { + t.Fatal(err) + } + + // Mirror the start command's PreRunE: bind flags, then map the flat + // blockchain-rpc-* flags onto their nested config keys. + c := &command{ + config: viper.New(), + logger: log.Noop, + } + if err := c.config.BindPFlags(startCmd.Flags()); err != nil { + t.Fatal(err) + } + c.bindBlockchainRpcConfig(startCmd) + + gotMode, err := c.resolveNodeMode(c.logger) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if gotMode != tt.wantMode { + t.Errorf("got mode %q, want %q", gotMode, tt.wantMode) + } + for key, want := range tt.wantOptions { + if got := c.config.GetBool(key); got != want { + t.Errorf("option %q: got %t, want %t", key, got, want) + } + } + }) + } +} diff --git a/cmd/bee/cmd/start.go b/cmd/bee/cmd/start.go index 7e7ab4a27cd..2cff7db0fc4 100644 --- a/cmd/bee/cmd/start.go +++ b/cmd/bee/cmd/start.go @@ -211,9 +211,13 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo } bootNode := c.config.GetBool(optionNameBootnodeMode) - fullNode := c.config.GetBool(optionNameFullNode) - if bootNode && !fullNode { + nodeMode, err := c.resolveNodeMode(logger) + if err != nil { + return nil, err + } + + if bootNode && nodeMode != node.FullMode { return nil, errors.New("boot node must be started as a full node") } @@ -324,7 +328,7 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo EnableWS: c.config.GetBool(optionNameP2PWSEnable), AutoTLSDomain: c.config.GetString(optionAutoTLSDomain), AutoTLSRegistrationEndpoint: c.config.GetString(optionAutoTLSRegistrationEndpoint), - FullNodeMode: fullNode, + NodeMode: nodeMode, LightNodeLimit: c.config.GetInt(optionNameLightNodeLimit), Logger: logger, MinimumGasTipCap: c.config.GetUint64(optionNameMinimumGasTipCap), @@ -369,6 +373,132 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo return b, err } +// legacyNodeModeRemovalVersion is the release in which node-mode inference from +// the deprecated full-node option and blockchain-rpc-endpoint presence is +// removed. From that release on, node-mode is required. +const legacyNodeModeRemovalVersion = "v2.11.0" + +// resolveNodeMode determines the effective node mode from config. There are +// two regimes, selected by whether node-mode is set. +// +// node-mode unset (legacy): the node behaves exactly as releases before +// node-mode existed. chequebook-enable and storage-incentives-enable fall back +// to their former default of true when not set, the mode is inferred from the +// deprecated full-node option and the presence of blockchain-rpc-endpoint, and +// no further validation is applied. A deprecation warning names the equivalent +// node-mode value and the release in which the inference is removed. +// +// node-mode set: the mode owns the config. Options the mode implies are +// enabled unless the operator explicitly disabled them, options the mode +// cannot support are rejected when explicitly enabled, and +// blockchain-rpc-endpoint is required for light and full nodes. Implied values +// are written back to config so the rest of node startup picks them up. +func (c *command) resolveNodeMode(logger log.Logger) (node.NodeMode, error) { + modeStr := c.config.GetString(optionNameNodeMode) + if modeStr == "" { + return c.resolveLegacyNodeMode(logger) + } + + mode := node.NodeMode(modeStr) + if !mode.IsValid() { + return "", fmt.Errorf("invalid node-mode %q: must be one of full, light, ultra-light", mode) + } + if c.config.GetBool(optionNameFullNode) { + logger.Warning("--full-node is set alongside --node-mode; --full-node is ignored") + } + + rpcEndpoint := c.config.GetString(configKeyBlockchainRpcEndpoint) + + switch mode { + case node.FullMode: + if rpcEndpoint == "" { + return "", errors.New("full node requires blockchain-rpc-endpoint to be set") + } + // A full node implies swap, chequebook and storage incentives. Bootnodes + // are exempt: NewBee never starts swap, push-sync or the incentives agent + // for them, so implying the options would only cost a chequebook deploy. + if !c.config.GetBool(optionNameBootnodeMode) { + c.enableImpliedOption(logger, mode, optionNameSwapEnable) + if c.config.GetBool(optionNameSwapEnable) { + c.enableImpliedOption(logger, mode, optionNameChequebookEnable) + } + c.enableImpliedOption(logger, mode, optionNameStorageIncentivesEnable) + } + case node.LightMode: + if rpcEndpoint == "" { + return "", errors.New("light node requires blockchain-rpc-endpoint to be set") + } + if c.config.GetBool(optionNameStorageIncentivesEnable) { + return "", errors.New("light node cannot have storage-incentives-enable set to true") + } + case node.UltraLightMode: + if c.config.GetBool(optionNameSwapEnable) { + return "", errors.New("ultra-light node cannot have swap-enable set to true") + } + if c.config.GetBool(optionNameStorageIncentivesEnable) { + return "", errors.New("ultra-light node cannot have storage-incentives-enable set to true") + } + } + + // chequebook init is gated on swap-enable in NewBee. With node-mode set the + // implied values above never produce this combination, so it is always an + // explicit contradiction rather than a silent no-op. + if c.config.GetBool(optionNameChequebookEnable) && !c.config.GetBool(optionNameSwapEnable) { + return "", errors.New("chequebook-enable requires swap-enable to be true") + } + + return mode, nil +} + +// enableImpliedOption turns on an option implied by the node mode unless the +// operator set it explicitly. An explicit false is honoured and reported, since +// it degrades the node relative to what the mode normally provides. +func (c *command) enableImpliedOption(logger log.Logger, mode node.NodeMode, key string) { + if !c.config.IsSet(key) { + logger.Debug("enabling option implied by node-mode", "node_mode", mode, "option", key) + c.config.Set(key, true) + return + } + if !c.config.GetBool(key) { + logger.Warning("option implied by node-mode is explicitly disabled", "node_mode", mode, "option", key) + } +} + +// resolveLegacyNodeMode reproduces the behaviour of releases before node-mode +// existed, for configs that do not set node-mode. The only check kept is that +// a full node has a blockchain-rpc-endpoint: those releases enabled the chain +// backend for every full node and failed at chain init without one, so the +// early error changes the message, not the outcome. +func (c *command) resolveLegacyNodeMode(logger log.Logger) (node.NodeMode, error) { + // chequebook-enable and storage-incentives-enable used to default to true. + // Restore that for configs that leave them unset so an upgraded node keeps + // its settlement and incentives behaviour. Both stay gated in NewBee + // (chequebook on swap-enable, incentives on full mode), so this cannot start + // anything the previous release would not have started. + for _, key := range []string{optionNameChequebookEnable, optionNameStorageIncentivesEnable} { + if !c.config.IsSet(key) { + c.config.Set(key, true) + } + } + + mode := node.UltraLightMode + switch { + case c.config.GetBool(optionNameFullNode): + if c.config.GetString(configKeyBlockchainRpcEndpoint) == "" { + return "", errors.New("full node requires blockchain-rpc-endpoint to be set") + } + mode = node.FullMode + case c.config.GetString(configKeyBlockchainRpcEndpoint) != "": + mode = node.LightMode + } + + logger.Warning("node-mode is not set and was inferred from legacy options; add it to your config, inference will be removed", + "node_mode", mode, + "removed_in", legacyNodeModeRemovalVersion, + ) + return mode, nil +} + type program struct { start func() stop func() diff --git a/packaging/bee.yaml b/packaging/bee.yaml index b52934faefb..0c94069ee94 100644 --- a/packaging/bee.yaml +++ b/packaging/bee.yaml @@ -1,13 +1,16 @@ ## Bee configuration - https://docs.ethswarm.org/docs/working-with-bee/configuration -## allow to advertise private CIDRs to the public network -# allow-private-cidrs: false -## HTTP API listen address -# api-addr: 127.0.0.1:1633 -## chain block time -# block-time: "5" -## block number cache sync interval in blocks -# block-sync-interval: 10 +## ── Node mode ──────────────────────────────────────────────────────────────── +## Selects the operational mode of this node. +## full - participates in storage and incentives; requires blockchain-rpc; +## implies swap-enable, chequebook-enable and storage-incentives-enable +## light - uploads and downloads only; requires blockchain-rpc +## ultra-light - free-tier downloads only; no blockchain connection needed +## When unset, the mode is inferred from the deprecated full-node option and +## blockchain-rpc presence (deprecated, removed in v2.11.0). +# node-mode: ultra-light + +## ── Blockchain / RPC (required for full and light nodes) ───────────────────── ## blockchain rpc configuration # blockchain-rpc: # endpoint: "" @@ -15,26 +18,100 @@ # tls-timeout: 10s # idle-timeout: 90s # keepalive: 30s +## chain block time +# block-time: "5" +## block number cache sync interval in blocks +# block-sync-interval: 10 + +## ── Swap / chequebook (full and light nodes only) ──────────────────────────── +## enable swap +# swap-enable: false +## enable chequebook (requires swap-enable; implied by node-mode: full) +# chequebook-enable: false +## reject full-node hive/handshake records that carry no chequebook address +# chequebook-verification: false +## swap factory addresses +# swap-factory-address: "" +## initial deposit if deploying a new chequebook +# swap-initial-deposit: "0" + +## ── Full node only ──────────────────────────────────────────────────────────── +## enable storage incentives feature (implied by node-mode: full) +# storage-incentives-enable: false +## reserve capacity doubling +# reserve-capacity-doubling: 0 +## minimum radius storage threshold +# minimum-storage-radius: "0" +## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay +# target-neighborhood: "" +## suggester for target neighborhood +# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion +## redistribution contract address +# redistribution-address: "" +## staking contract address +# staking-address: "" + +## ── Network ─────────────────────────────────────────────────────────────────── +## triggers connect to main net bootnodes +# mainnet: true +## ID of the Swarm network +# network-id: "1" ## initial nodes to connect to # bootnode: ["/dnsaddr/mainnet.ethswarm.org"] ## cause the node to always accept incoming connections # bootnode-mode: false +## protect nodes from getting kicked out on bootnode +# static-nodes: [] +## P2P listen address +# p2p-addr: :1634 +## enable P2P WebSocket transport +# p2p-ws-enable: false +## enable wss p2p connections +# p2p-wss-enable: false +## wss address +# p2p-wss-addr: :1635 +## NAT exposed address +# nat-addr: "" +## WSS NAT exposed address +# nat-wss-addr: "" +## autotls domain +# autotls-domain: "" +## autotls registration endpoint +# autotls-registration-endpoint: "" +## autotls ca endpoint +# autotls-ca-endpoint: "" +## allow to advertise private CIDRs to the public network +# allow-private-cidrs: false + +## ── HTTP API ────────────────────────────────────────────────────────────────── +## HTTP API listen address +# api-addr: 127.0.0.1:1633 +## origins with CORS headers enabled +# cors-allowed-origins: [] + +## ── Storage ─────────────────────────────────────────────────────────────────── +## data directory +data-dir: "/var/lib/bee" ## bzz token contract address # bzz-token-address: "" ## cache capacity in chunks, multiply by 4096 to get approximate capacity in bytes # cache-capacity: "1000000" ## enable forwarded content caching # cache-retrieval: true -## enable chequebook -# chequebook-enable: true -## reject full-node hive/handshake records that carry no chequebook address -# chequebook-verification: false -## config file (default is $HOME/.bee.yaml) -config: "/etc/bee/bee.yaml" -## origins with CORS headers enabled -# cors-allowed-origins: [] -## data directory -data-dir: "/var/lib/bee" +## postage stamp contract address +# postage-stamp-address: "" +## postage stamp contract start block number +# postage-stamp-start-block: "0" +## skip postage snapshot +# skip-postage-snapshot: false +## forces the node to resync postage contract data +# resync: false +## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url +# resolver-options: [] +## price oracle contract address +# price-oracle-address: "" + +## ── Database ────────────────────────────────────────────────────────────────── ## size of block cache of the database in bytes # db-block-cache-capacity: "33554432" ## disables db compactions triggered by seeks @@ -43,72 +120,36 @@ data-dir: "/var/lib/bee" # db-open-files-limit: "200" ## size of the database write buffer in bytes # db-write-buffer-size: "33554432" -## cause the node to start in full mode -# full-node: false -## help for printconfig -# help: false -## triggers connect to main net bootnodes. -# mainnet: true +## lru memory caching capacity in number of statestore entries +# statestore-cache-capacity: "100000" + +## ── Payments ────────────────────────────────────────────────────────────────── +## threshold in BZZ where you expect to get paid from your peers +# payment-threshold: "13500000" +## percentage below the peers payment threshold when we initiate settlement +# payment-early-percent: 50 +## excess debt above payment threshold in percentages where you disconnect from your peer +# payment-tolerance-percent: 25 ## minimum gas tip cap in wei for transactions, 0 means use suggested gas tip cap # minimum-gas-tip-cap: 0 -## minimum radius storage threshold -# minimum-storage-radius: "0" -## NAT exposed address -# nat-addr: "" -## suggester for target neighborhood -# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion -## ID of the Swarm network -# network-id: "1" -## P2P listen address -# p2p-addr: :1634 -## enable P2P WebSocket transport -# p2p-ws-enable: false +## gas limit fallback when estimation fails for contract transactions (default 500000) +# gas-limit-fallback: 500000 +## skips the gas estimate step for contract transactions +# transaction-debug-mode: false +## withdrawal target addresses +# withdrawal-addresses-whitelist: [] + +## ── Keys / identity ─────────────────────────────────────────────────────────── +## config file (default is $HOME/.bee.yaml) +config: "/etc/bee/bee.yaml" ## password for decrypting keys # password: "" ## path to a file that contains password for decrypting keys password-file: "/var/lib/bee/password" -## percentage below the peers payment threshold when we initiate settlement -# payment-early-percent: 50 -## threshold in BZZ where you expect to get paid from your peers -# payment-threshold: "13500000" -## excess debt above payment threshold in percentages where you disconnect from your peer -# payment-tolerance-percent: 25 -## postage stamp contract address -# postage-stamp-address: "" -## postage stamp contract start block number -# postage-stamp-start-block: "0" -## enable pprof mutex profile -# pprof-mutex: false -## enable pprof block profile -# pprof-profile: false -## price oracle contract address -# price-oracle-address: "" -## redistribution contract address -# redistribution-address: "" -## reserve capacity doubling -# reserve-capacity-doubling: 0 -## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url -# resolver-options: [] -## forces the node to resync postage contract data -# resync: false -## skip postage snapshot -# skip-postage-snapshot: false -## staking contract address -# staking-address: "" -## lru memory caching capacity in number of statestore entries -# statestore-cache-capacity: "100000" -## protect nodes from getting kicked out on bootnode -# static-nodes: [] -## enable storage incentives feature -# storage-incentives-enable: true -## enable swap -# swap-enable: false -## swap factory addresses -# swap-factory-address: "" -## initial deposit if deploying a new chequebook -# swap-initial-deposit: "0" -## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay -# target-neighborhood: "" + +## ── Logging / tracing ───────────────────────────────────────────────────────── +## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace +# verbosity: info ## tracing settings # tracing: # ## enable tracing @@ -125,30 +166,16 @@ password-file: "/var/lib/bee/password" # sampling-ratio: 1.0 # ## service name identifier for tracing # service-name: bee -## gas limit fallback when estimation fails for contract transactions (default 500000) -# gas-limit-fallback: 500000 -## skips the gas estimate step for contract transactions -# transaction-debug-mode: false -## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace -# verbosity: info +## enable pprof mutex profile +# pprof-mutex: false +## enable pprof block profile +# pprof-profile: false + +## ── Miscellaneous ───────────────────────────────────────────────────────────── ## maximum node warmup duration; proceeds when stable or after this time # warmup-time: 5m0s ## send a welcome message string during handshakes # welcome-message: "" -## withdrawal target addresses -# withdrawal-addresses-whitelist: [] -## enable wss p2p connections (default: false) -# p2p-wss-enable: false -## wss address (default: :1635) -# p2p-wss-addr: :1635 -## WSS NAT exposed address -# nat-wss-addr: "" -## autotls domain (default: libp2p.direct) -# autotls-domain: "" -## autotls registration endpoint (default: https://registration.libp2p.direct) -# autotls-registration-endpoint: "" -## autotls ca endpoint (default: https://acme-v02.api.letsencrypt.org/directory) -# autotls-ca-endpoint: "" ## SIMD BMT hashing opt-in flag (only available on linux amd64) # use-simd-hashing: false ## limit of possible connected light nodes (default: 100) diff --git a/packaging/docker/README.md b/packaging/docker/README.md index db118ff1ef0..ee73934432c 100644 --- a/packaging/docker/README.md +++ b/packaging/docker/README.md @@ -11,7 +11,7 @@ wget -q https://raw.githubusercontent.com/ethersphere/bee/master/packaging/docke Set all configuration variables inside `.env` -If you want to run node in full mode, set `BEE_FULL_NODE=true` +Select the node mode with `BEE_NODE_MODE` (`full`, `light`, or `ultra-light`). A full node needs `BEE_BLOCKCHAIN_RPC_ENDPOINT` and implies swap, chequebook and storage incentives. Bee requires an Ethereum endpoint to function. Obtain a free Infura account and set: diff --git a/packaging/docker/docker-compose.yml b/packaging/docker/docker-compose.yml index 16818215c7c..4f8ba110f12 100644 --- a/packaging/docker/docker-compose.yml +++ b/packaging/docker/docker-compose.yml @@ -39,6 +39,7 @@ services: - BEE_NAT_WSS_ADDR - BEE_NEIGHBORHOOD_SUGGESTER - BEE_NETWORK_ID + - BEE_NODE_MODE - BEE_P2P_ADDR - BEE_P2P_WS_ENABLE - BEE_P2P_WSS_ADDR diff --git a/packaging/docker/env b/packaging/docker/env index f33a62c0f15..cfb51cbbafb 100644 --- a/packaging/docker/env +++ b/packaging/docker/env @@ -37,8 +37,8 @@ # BEE_CACHE_CAPACITY=1000000 ## enable forwarded content caching (default true) # BEE_CACHE_RETRIEVAL=true -## enable chequebook (default true) -# BEE_CHEQUEBOOK_ENABLE=true +## enable chequebook; requires swap; implied by BEE_NODE_MODE=full (default false) +# BEE_CHEQUEBOOK_ENABLE=false ## reject full-node hive/handshake records that carry no chequebook address # BEE_CHEQUEBOOK_VERIFICATION=false ## origins with CORS headers enabled (default []) @@ -53,7 +53,7 @@ # BEE_DB_OPEN_FILES_LIMIT=200 ## size of the database write buffer in bytes (default 33554432) # BEE_DB_WRITE_BUFFER_SIZE=33554432 -## cause the node to start in full mode (default false) +## cause the node to start in full mode (deprecated: use BEE_NODE_MODE=full) (default false) # BEE_FULL_NODE=false ## gas limit fallback when estimation fails for contract transactions (default 500000) # BEE_GAS_LIMIT_FALLBACK=500000 @@ -71,6 +71,8 @@ # BEE_NEIGHBORHOOD_SUGGESTER=https://api.swarmscan.io/v1/network/neighborhoods/suggestion ## ID of the Swarm network (default mainnet id from bee) # BEE_NETWORK_ID=1 +## node operational mode: full, light, or ultra-light; unset infers the mode from BEE_FULL_NODE and BEE_BLOCKCHAIN_RPC_ENDPOINT (deprecated) +# BEE_NODE_MODE=ultra-light ## P2P listen address (default :1634) # BEE_P2P_ADDR=:1634 ## enable P2P WebSocket transport (default false) @@ -115,8 +117,8 @@ # BEE_STATIC_NODES=[] ## lru memory caching capacity in number of statestore entries (default 100000) # BEE_STATESTORE_CACHE_CAPACITY=100000 -## enable storage incentives feature (default true) -# BEE_STORAGE_INCENTIVES_ENABLE=true +## enable storage incentives feature; full node only; implied by BEE_NODE_MODE=full (default false) +# BEE_STORAGE_INCENTIVES_ENABLE=false ## enable swap (default false) # BEE_SWAP_ENABLE=false ## swap factory addresses (default empty) diff --git a/packaging/homebrew-amd64/bee.yaml b/packaging/homebrew-amd64/bee.yaml index 095e53a6047..315b58689bd 100644 --- a/packaging/homebrew-amd64/bee.yaml +++ b/packaging/homebrew-amd64/bee.yaml @@ -1,13 +1,16 @@ ## Bee configuration - https://docs.ethswarm.org/docs/working-with-bee/configuration -## allow to advertise private CIDRs to the public network -# allow-private-cidrs: false -## HTTP API listen address -# api-addr: 127.0.0.1:1633 -## chain block time -# block-time: "5" -## block number cache sync interval in blocks -# block-sync-interval: 10 +## ── Node mode ──────────────────────────────────────────────────────────────── +## Selects the operational mode of this node. +## full - participates in storage and incentives; requires blockchain-rpc; +## implies swap-enable, chequebook-enable and storage-incentives-enable +## light - uploads and downloads only; requires blockchain-rpc +## ultra-light - free-tier downloads only; no blockchain connection needed +## When unset, the mode is inferred from the deprecated full-node option and +## blockchain-rpc presence (deprecated, removed in v2.11.0). +# node-mode: ultra-light + +## ── Blockchain / RPC (required for full and light nodes) ───────────────────── ## blockchain rpc configuration # blockchain-rpc: # endpoint: "" @@ -15,26 +18,100 @@ # tls-timeout: 10s # idle-timeout: 90s # keepalive: 30s +## chain block time +# block-time: "5" +## block number cache sync interval in blocks +# block-sync-interval: 10 + +## ── Swap / chequebook (full and light nodes only) ──────────────────────────── +## enable swap +# swap-enable: false +## enable chequebook (requires swap-enable; implied by node-mode: full) +# chequebook-enable: false +## reject full-node hive/handshake records that carry no chequebook address +# chequebook-verification: false +## swap factory addresses +# swap-factory-address: "" +## initial deposit if deploying a new chequebook +# swap-initial-deposit: "0" + +## ── Full node only ──────────────────────────────────────────────────────────── +## enable storage incentives feature (implied by node-mode: full) +# storage-incentives-enable: false +## reserve capacity doubling +# reserve-capacity-doubling: 0 +## minimum radius storage threshold +# minimum-storage-radius: "0" +## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay +# target-neighborhood: "" +## suggester for target neighborhood +# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion +## redistribution contract address +# redistribution-address: "" +## staking contract address +# staking-address: "" + +## ── Network ─────────────────────────────────────────────────────────────────── +## triggers connect to main net bootnodes +# mainnet: true +## ID of the Swarm network +# network-id: "1" ## initial nodes to connect to # bootnode: ["/dnsaddr/mainnet.ethswarm.org"] ## cause the node to always accept incoming connections # bootnode-mode: false +## protect nodes from getting kicked out on bootnode +# static-nodes: [] +## P2P listen address +# p2p-addr: :1634 +## enable P2P WebSocket transport +# p2p-ws-enable: false +## enable wss p2p connections +# p2p-wss-enable: false +## wss address +# p2p-wss-addr: :1635 +## NAT exposed address +# nat-addr: "" +## WSS NAT exposed address +# nat-wss-addr: "" +## autotls domain +# autotls-domain: "" +## autotls registration endpoint +# autotls-registration-endpoint: "" +## autotls ca endpoint +# autotls-ca-endpoint: "" +## allow to advertise private CIDRs to the public network +# allow-private-cidrs: false + +## ── HTTP API ────────────────────────────────────────────────────────────────── +## HTTP API listen address +# api-addr: 127.0.0.1:1633 +## origins with CORS headers enabled +# cors-allowed-origins: [] + +## ── Storage ─────────────────────────────────────────────────────────────────── +## data directory +data-dir: "/usr/local/var/lib/swarm-bee" ## bzz token contract address # bzz-token-address: "" ## cache capacity in chunks, multiply by 4096 to get approximate capacity in bytes # cache-capacity: "1000000" ## enable forwarded content caching # cache-retrieval: true -## enable chequebook -# chequebook-enable: true -## reject full-node hive/handshake records that carry no chequebook address -# chequebook-verification: false -## config file (default is $HOME/.bee.yaml) -config: "/usr/local/etc/swarm-bee/bee.yaml" -## origins with CORS headers enabled -# cors-allowed-origins: [] -## data directory -data-dir: "/usr/local/var/lib/swarm-bee" +## postage stamp contract address +# postage-stamp-address: "" +## postage stamp contract start block number +# postage-stamp-start-block: "0" +## skip postage snapshot +# skip-postage-snapshot: false +## forces the node to resync postage contract data +# resync: false +## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url +# resolver-options: [] +## price oracle contract address +# price-oracle-address: "" + +## ── Database ────────────────────────────────────────────────────────────────── ## size of block cache of the database in bytes # db-block-cache-capacity: "33554432" ## disables db compactions triggered by seeks @@ -43,72 +120,36 @@ data-dir: "/usr/local/var/lib/swarm-bee" # db-open-files-limit: "200" ## size of the database write buffer in bytes # db-write-buffer-size: "33554432" -## cause the node to start in full mode -# full-node: false -## help for printconfig -# help: false -## triggers connect to main net bootnodes. -# mainnet: true +## lru memory caching capacity in number of statestore entries +# statestore-cache-capacity: "100000" + +## ── Payments ────────────────────────────────────────────────────────────────── +## threshold in BZZ where you expect to get paid from your peers +# payment-threshold: "13500000" +## percentage below the peers payment threshold when we initiate settlement +# payment-early-percent: 50 +## excess debt above payment threshold in percentages where you disconnect from your peer +# payment-tolerance-percent: 25 ## minimum gas tip cap in wei for transactions, 0 means use suggested gas tip cap # minimum-gas-tip-cap: 0 -## minimum radius storage threshold -# minimum-storage-radius: "0" -## NAT exposed address -# nat-addr: "" -## suggester for target neighborhood -# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion -## ID of the Swarm network -# network-id: "1" -## P2P listen address -# p2p-addr: :1634 -## enable P2P WebSocket transport -# p2p-ws-enable: false +## gas limit fallback when estimation fails for contract transactions (default 500000) +# gas-limit-fallback: 500000 +## skips the gas estimate step for contract transactions +# transaction-debug-mode: false +## withdrawal target addresses +# withdrawal-addresses-whitelist: [] + +## ── Keys / identity ─────────────────────────────────────────────────────────── +## config file (default is $HOME/.bee.yaml) +config: "/usr/local/etc/swarm-bee/bee.yaml" ## password for decrypting keys # password: "" ## path to a file that contains password for decrypting keys password-file: "/usr/local/var/lib/swarm-bee/password" -## percentage below the peers payment threshold when we initiate settlement -# payment-early-percent: 50 -## threshold in BZZ where you expect to get paid from your peers -# payment-threshold: "13500000" -## excess debt above payment threshold in percentages where you disconnect from your peer -# payment-tolerance-percent: 25 -## postage stamp contract address -# postage-stamp-address: "" -## postage stamp contract start block number -# postage-stamp-start-block: "0" -## enable pprof mutex profile -# pprof-mutex: false -## enable pprof block profile -# pprof-profile: false -## price oracle contract address -# price-oracle-address: "" -## redistribution contract address -# redistribution-address: "" -## reserve capacity doubling -# reserve-capacity-doubling: 0 -## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url -# resolver-options: [] -## forces the node to resync postage contract data -# resync: false -## skip postage snapshot -# skip-postage-snapshot: false -## staking contract address -# staking-address: "" -## lru memory caching capacity in number of statestore entries -# statestore-cache-capacity: "100000" -## protect nodes from getting kicked out on bootnode -# static-nodes: [] -## enable storage incentives feature -# storage-incentives-enable: true -## enable swap -# swap-enable: false -## swap factory addresses -# swap-factory-address: "" -## initial deposit if deploying a new chequebook -# swap-initial-deposit: "0" -## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay -# target-neighborhood: "" + +## ── Logging / tracing ───────────────────────────────────────────────────────── +## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace +# verbosity: info ## tracing settings # tracing: # ## enable tracing @@ -125,30 +166,16 @@ password-file: "/usr/local/var/lib/swarm-bee/password" # sampling-ratio: 1.0 # ## service name identifier for tracing # service-name: bee -## gas limit fallback when estimation fails for contract transactions (default 500000) -# gas-limit-fallback: 500000 -## skips the gas estimate step for contract transactions -# transaction-debug-mode: false -## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace -# verbosity: info +## enable pprof mutex profile +# pprof-mutex: false +## enable pprof block profile +# pprof-profile: false + +## ── Miscellaneous ───────────────────────────────────────────────────────────── ## maximum node warmup duration; proceeds when stable or after this time # warmup-time: 5m0s ## send a welcome message string during handshakes # welcome-message: "" -## withdrawal target addresses -# withdrawal-addresses-whitelist: [] -## enable wss p2p connections (default: false) -# p2p-wss-enable: false -## wss address (default: :1635) -# p2p-wss-addr: :1635 -## WSS NAT exposed address -# nat-wss-addr: "" -## autotls domain (default: libp2p.direct) -# autotls-domain: "" -## autotls registration endpoint (default: https://registration.libp2p.direct) -# autotls-registration-endpoint: "" -## autotls ca endpoint (default: https://acme-v02.api.letsencrypt.org/directory) -# autotls-ca-endpoint: "" ## SIMD BMT hashing opt-in flag (only available on linux amd64) # use-simd-hashing: false ## limit of possible connected light nodes (default: 100) diff --git a/packaging/homebrew-arm64/bee.yaml b/packaging/homebrew-arm64/bee.yaml index 25e5594caec..6da2d4e6ef4 100644 --- a/packaging/homebrew-arm64/bee.yaml +++ b/packaging/homebrew-arm64/bee.yaml @@ -1,13 +1,16 @@ ## Bee configuration - https://docs.ethswarm.org/docs/working-with-bee/configuration -## allow to advertise private CIDRs to the public network -# allow-private-cidrs: false -## HTTP API listen address -# api-addr: 127.0.0.1:1633 -## chain block time -# block-time: "5" -## block number cache sync interval in blocks -# block-sync-interval: 10 +## ── Node mode ──────────────────────────────────────────────────────────────── +## Selects the operational mode of this node. +## full - participates in storage and incentives; requires blockchain-rpc; +## implies swap-enable, chequebook-enable and storage-incentives-enable +## light - uploads and downloads only; requires blockchain-rpc +## ultra-light - free-tier downloads only; no blockchain connection needed +## When unset, the mode is inferred from the deprecated full-node option and +## blockchain-rpc presence (deprecated, removed in v2.11.0). +# node-mode: ultra-light + +## ── Blockchain / RPC (required for full and light nodes) ───────────────────── ## blockchain rpc configuration # blockchain-rpc: # endpoint: "" @@ -15,26 +18,100 @@ # tls-timeout: 10s # idle-timeout: 90s # keepalive: 30s +## chain block time +# block-time: "5" +## block number cache sync interval in blocks +# block-sync-interval: 10 + +## ── Swap / chequebook (full and light nodes only) ──────────────────────────── +## enable swap +# swap-enable: false +## enable chequebook (requires swap-enable; implied by node-mode: full) +# chequebook-enable: false +## reject full-node hive/handshake records that carry no chequebook address +# chequebook-verification: false +## swap factory addresses +# swap-factory-address: "" +## initial deposit if deploying a new chequebook +# swap-initial-deposit: "0" + +## ── Full node only ──────────────────────────────────────────────────────────── +## enable storage incentives feature (implied by node-mode: full) +# storage-incentives-enable: false +## reserve capacity doubling +# reserve-capacity-doubling: 0 +## minimum radius storage threshold +# minimum-storage-radius: "0" +## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay +# target-neighborhood: "" +## suggester for target neighborhood +# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion +## redistribution contract address +# redistribution-address: "" +## staking contract address +# staking-address: "" + +## ── Network ─────────────────────────────────────────────────────────────────── +## triggers connect to main net bootnodes +# mainnet: true +## ID of the Swarm network +# network-id: "1" ## initial nodes to connect to # bootnode: ["/dnsaddr/mainnet.ethswarm.org"] ## cause the node to always accept incoming connections # bootnode-mode: false +## protect nodes from getting kicked out on bootnode +# static-nodes: [] +## P2P listen address +# p2p-addr: :1634 +## enable P2P WebSocket transport +# p2p-ws-enable: false +## enable wss p2p connections +# p2p-wss-enable: false +## wss address +# p2p-wss-addr: :1635 +## NAT exposed address +# nat-addr: "" +## WSS NAT exposed address +# nat-wss-addr: "" +## autotls domain +# autotls-domain: "" +## autotls registration endpoint +# autotls-registration-endpoint: "" +## autotls ca endpoint +# autotls-ca-endpoint: "" +## allow to advertise private CIDRs to the public network +# allow-private-cidrs: false + +## ── HTTP API ────────────────────────────────────────────────────────────────── +## HTTP API listen address +# api-addr: 127.0.0.1:1633 +## origins with CORS headers enabled +# cors-allowed-origins: [] + +## ── Storage ─────────────────────────────────────────────────────────────────── +## data directory +data-dir: "/opt/homebrew/var/lib/swarm-bee" ## bzz token contract address # bzz-token-address: "" ## cache capacity in chunks, multiply by 4096 to get approximate capacity in bytes # cache-capacity: "1000000" ## enable forwarded content caching # cache-retrieval: true -## enable chequebook -# chequebook-enable: true -## reject full-node hive/handshake records that carry no chequebook address -# chequebook-verification: false -## config file (default is $HOME/.bee.yaml) -config: "/opt/homebrew/etc/swarm-bee/bee.yaml" -## origins with CORS headers enabled -# cors-allowed-origins: [] -## data directory -data-dir: "/opt/homebrew/var/lib/swarm-bee" +## postage stamp contract address +# postage-stamp-address: "" +## postage stamp contract start block number +# postage-stamp-start-block: "0" +## skip postage snapshot +# skip-postage-snapshot: false +## forces the node to resync postage contract data +# resync: false +## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url +# resolver-options: [] +## price oracle contract address +# price-oracle-address: "" + +## ── Database ────────────────────────────────────────────────────────────────── ## size of block cache of the database in bytes # db-block-cache-capacity: "33554432" ## disables db compactions triggered by seeks @@ -43,72 +120,36 @@ data-dir: "/opt/homebrew/var/lib/swarm-bee" # db-open-files-limit: "200" ## size of the database write buffer in bytes # db-write-buffer-size: "33554432" -## cause the node to start in full mode -# full-node: false -## help for printconfig -# help: false -## triggers connect to main net bootnodes. -# mainnet: true +## lru memory caching capacity in number of statestore entries +# statestore-cache-capacity: "100000" + +## ── Payments ────────────────────────────────────────────────────────────────── +## threshold in BZZ where you expect to get paid from your peers +# payment-threshold: "13500000" +## percentage below the peers payment threshold when we initiate settlement +# payment-early-percent: 50 +## excess debt above payment threshold in percentages where you disconnect from your peer +# payment-tolerance-percent: 25 ## minimum gas tip cap in wei for transactions, 0 means use suggested gas tip cap # minimum-gas-tip-cap: 0 -## minimum radius storage threshold -# minimum-storage-radius: "0" -## NAT exposed address -# nat-addr: "" -## suggester for target neighborhood -# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion -## ID of the Swarm network -# network-id: "1" -## P2P listen address -# p2p-addr: :1634 -## enable P2P WebSocket transport -# p2p-ws-enable: false +## gas limit fallback when estimation fails for contract transactions (default 500000) +# gas-limit-fallback: 500000 +## skips the gas estimate step for contract transactions +# transaction-debug-mode: false +## withdrawal target addresses +# withdrawal-addresses-whitelist: [] + +## ── Keys / identity ─────────────────────────────────────────────────────────── +## config file (default is $HOME/.bee.yaml) +config: "/opt/homebrew/etc/swarm-bee/bee.yaml" ## password for decrypting keys # password: "" ## path to a file that contains password for decrypting keys password-file: "/opt/homebrew/var/lib/swarm-bee/password" -## percentage below the peers payment threshold when we initiate settlement -# payment-early-percent: 50 -## threshold in BZZ where you expect to get paid from your peers -# payment-threshold: "13500000" -## excess debt above payment threshold in percentages where you disconnect from your peer -# payment-tolerance-percent: 25 -## postage stamp contract address -# postage-stamp-address: "" -## postage stamp contract start block number -# postage-stamp-start-block: "0" -## enable pprof mutex profile -# pprof-mutex: false -## enable pprof block profile -# pprof-profile: false -## price oracle contract address -# price-oracle-address: "" -## redistribution contract address -# redistribution-address: "" -## reserve capacity doubling -# reserve-capacity-doubling: 0 -## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url -# resolver-options: [] -## forces the node to resync postage contract data -# resync: false -## skip postage snapshot -# skip-postage-snapshot: false -## staking contract address -# staking-address: "" -## lru memory caching capacity in number of statestore entries -# statestore-cache-capacity: "100000" -## protect nodes from getting kicked out on bootnode -# static-nodes: [] -## enable storage incentives feature -# storage-incentives-enable: true -## enable swap -# swap-enable: false -## swap factory addresses -# swap-factory-address: "" -## initial deposit if deploying a new chequebook -# swap-initial-deposit: "0" -## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay -# target-neighborhood: "" + +## ── Logging / tracing ───────────────────────────────────────────────────────── +## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace +# verbosity: info ## tracing settings # tracing: # ## enable tracing @@ -125,30 +166,16 @@ password-file: "/opt/homebrew/var/lib/swarm-bee/password" # sampling-ratio: 1.0 # ## service name identifier for tracing # service-name: bee -## gas limit fallback when estimation fails for contract transactions (default 500000) -# gas-limit-fallback: 500000 -## skips the gas estimate step for contract transactions -# transaction-debug-mode: false -## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace -# verbosity: info +## enable pprof mutex profile +# pprof-mutex: false +## enable pprof block profile +# pprof-profile: false + +## ── Miscellaneous ───────────────────────────────────────────────────────────── ## maximum node warmup duration; proceeds when stable or after this time # warmup-time: 5m0s ## send a welcome message string during handshakes # welcome-message: "" -## withdrawal target addresses -# withdrawal-addresses-whitelist: [] -## enable wss p2p connections (default: false) -# p2p-wss-enable: false -## wss address (default: :1635) -# p2p-wss-addr: :1635 -## WSS NAT exposed address -# nat-wss-addr: "" -## autotls domain (default: libp2p.direct) -# autotls-domain: "" -## autotls registration endpoint (default: https://registration.libp2p.direct) -# autotls-registration-endpoint: "" -## autotls ca endpoint (default: https://acme-v02.api.letsencrypt.org/directory) -# autotls-ca-endpoint: "" ## SIMD BMT hashing opt-in flag (only available on linux amd64) # use-simd-hashing: false ## limit of possible connected light nodes (default: 100) diff --git a/packaging/scoop/bee.yaml b/packaging/scoop/bee.yaml index a9596776257..52eca12ada6 100644 --- a/packaging/scoop/bee.yaml +++ b/packaging/scoop/bee.yaml @@ -1,13 +1,16 @@ ## Bee configuration - https://docs.ethswarm.org/docs/working-with-bee/configuration -## allow to advertise private CIDRs to the public network -# allow-private-cidrs: false -## HTTP API listen address -# api-addr: 127.0.0.1:1633 -## chain block time -# block-time: "5" -## block number cache sync interval in blocks -# block-sync-interval: 10 +## ── Node mode ──────────────────────────────────────────────────────────────── +## Selects the operational mode of this node. +## full - participates in storage and incentives; requires blockchain-rpc; +## implies swap-enable, chequebook-enable and storage-incentives-enable +## light - uploads and downloads only; requires blockchain-rpc +## ultra-light - free-tier downloads only; no blockchain connection needed +## When unset, the mode is inferred from the deprecated full-node option and +## blockchain-rpc presence (deprecated, removed in v2.11.0). +# node-mode: ultra-light + +## ── Blockchain / RPC (required for full and light nodes) ───────────────────── ## blockchain rpc configuration # blockchain-rpc: # endpoint: "" @@ -15,26 +18,100 @@ # tls-timeout: 10s # idle-timeout: 90s # keepalive: 30s +## chain block time +# block-time: "5" +## block number cache sync interval in blocks +# block-sync-interval: 10 + +## ── Swap / chequebook (full and light nodes only) ──────────────────────────── +## enable swap +# swap-enable: false +## enable chequebook (requires swap-enable; implied by node-mode: full) +# chequebook-enable: false +## reject full-node hive/handshake records that carry no chequebook address +# chequebook-verification: false +## swap factory addresses +# swap-factory-address: "" +## initial deposit if deploying a new chequebook +# swap-initial-deposit: "0" + +## ── Full node only ──────────────────────────────────────────────────────────── +## enable storage incentives feature (implied by node-mode: full) +# storage-incentives-enable: false +## reserve capacity doubling +# reserve-capacity-doubling: 0 +## minimum radius storage threshold +# minimum-storage-radius: "0" +## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay +# target-neighborhood: "" +## suggester for target neighborhood +# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion +## redistribution contract address +# redistribution-address: "" +## staking contract address +# staking-address: "" + +## ── Network ─────────────────────────────────────────────────────────────────── +## triggers connect to main net bootnodes +# mainnet: true +## ID of the Swarm network +# network-id: "1" ## initial nodes to connect to # bootnode: ["/dnsaddr/mainnet.ethswarm.org"] ## cause the node to always accept incoming connections # bootnode-mode: false +## protect nodes from getting kicked out on bootnode +# static-nodes: [] +## P2P listen address +# p2p-addr: :1634 +## enable P2P WebSocket transport +# p2p-ws-enable: false +## enable wss p2p connections +# p2p-wss-enable: false +## wss address +# p2p-wss-addr: :1635 +## NAT exposed address +# nat-addr: "" +## WSS NAT exposed address +# nat-wss-addr: "" +## autotls domain +# autotls-domain: "" +## autotls registration endpoint +# autotls-registration-endpoint: "" +## autotls ca endpoint +# autotls-ca-endpoint: "" +## allow to advertise private CIDRs to the public network +# allow-private-cidrs: false + +## ── HTTP API ────────────────────────────────────────────────────────────────── +## HTTP API listen address +# api-addr: 127.0.0.1:1633 +## origins with CORS headers enabled +# cors-allowed-origins: [] + +## ── Storage ─────────────────────────────────────────────────────────────────── +## data directory +data-dir: "./data" ## bzz token contract address # bzz-token-address: "" ## cache capacity in chunks, multiply by 4096 to get approximate capacity in bytes # cache-capacity: "1000000" ## enable forwarded content caching # cache-retrieval: true -## enable chequebook -# chequebook-enable: true -## reject full-node hive/handshake records that carry no chequebook address -# chequebook-verification: false -## config file (default is $HOME/.bee.yaml) -config: "./bee.yaml" -## origins with CORS headers enabled -# cors-allowed-origins: [] -## data directory -data-dir: "./data" +## postage stamp contract address +# postage-stamp-address: "" +## postage stamp contract start block number +# postage-stamp-start-block: "0" +## skip postage snapshot +# skip-postage-snapshot: false +## forces the node to resync postage contract data +# resync: false +## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url +# resolver-options: [] +## price oracle contract address +# price-oracle-address: "" + +## ── Database ────────────────────────────────────────────────────────────────── ## size of block cache of the database in bytes # db-block-cache-capacity: "33554432" ## disables db compactions triggered by seeks @@ -43,72 +120,36 @@ data-dir: "./data" # db-open-files-limit: "200" ## size of the database write buffer in bytes # db-write-buffer-size: "33554432" -## cause the node to start in full mode -# full-node: false -## help for printconfig -# help: false -## triggers connect to main net bootnodes. -# mainnet: true +## lru memory caching capacity in number of statestore entries +# statestore-cache-capacity: "100000" + +## ── Payments ────────────────────────────────────────────────────────────────── +## threshold in BZZ where you expect to get paid from your peers +# payment-threshold: "13500000" +## percentage below the peers payment threshold when we initiate settlement +# payment-early-percent: 50 +## excess debt above payment threshold in percentages where you disconnect from your peer +# payment-tolerance-percent: 25 ## minimum gas tip cap in wei for transactions, 0 means use suggested gas tip cap # minimum-gas-tip-cap: 0 -## minimum radius storage threshold -# minimum-storage-radius: "0" -## NAT exposed address -# nat-addr: "" -## suggester for target neighborhood -# neighborhood-suggester: https://api.swarmscan.io/v1/network/neighborhoods/suggestion -## ID of the Swarm network -# network-id: "1" -## P2P listen address -# p2p-addr: :1634 -## enable P2P WebSocket transport -# p2p-ws-enable: false +## gas limit fallback when estimation fails for contract transactions (default 500000) +# gas-limit-fallback: 500000 +## skips the gas estimate step for contract transactions +# transaction-debug-mode: false +## withdrawal target addresses +# withdrawal-addresses-whitelist: [] + +## ── Keys / identity ─────────────────────────────────────────────────────────── +## config file (default is $HOME/.bee.yaml) +config: "./bee.yaml" ## password for decrypting keys # password: "" ## path to a file that contains password for decrypting keys password-file: "./password" -## percentage below the peers payment threshold when we initiate settlement -# payment-early-percent: 50 -## threshold in BZZ where you expect to get paid from your peers -# payment-threshold: "13500000" -## excess debt above payment threshold in percentages where you disconnect from your peer -# payment-tolerance-percent: 25 -## postage stamp contract address -# postage-stamp-address: "" -## postage stamp contract start block number -# postage-stamp-start-block: "0" -## enable pprof mutex profile -# pprof-mutex: false -## enable pprof block profile -# pprof-profile: false -## price oracle contract address -# price-oracle-address: "" -## redistribution contract address -# redistribution-address: "" -## reserve capacity doubling -# reserve-capacity-doubling: 0 -## ENS compatible API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url -# resolver-options: [] -## forces the node to resync postage contract data -# resync: false -## skip postage snapshot -# skip-postage-snapshot: false -## staking contract address -# staking-address: "" -## lru memory caching capacity in number of statestore entries -# statestore-cache-capacity: "100000" -## protect nodes from getting kicked out on bootnode -# static-nodes: [] -## enable storage incentives feature -# storage-incentives-enable: true -## enable swap -# swap-enable: false -## swap factory addresses -# swap-factory-address: "" -## initial deposit if deploying a new chequebook -# swap-initial-deposit: "0" -## neighborhood to target in binary format (ex: 111111001) for mining the initial overlay -# target-neighborhood: "" + +## ── Logging / tracing ───────────────────────────────────────────────────────── +## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace +# verbosity: info ## tracing settings # tracing: # ## enable tracing @@ -125,30 +166,16 @@ password-file: "./password" # sampling-ratio: 1.0 # ## service name identifier for tracing # service-name: bee -## gas limit fallback when estimation fails for contract transactions (default 500000) -# gas-limit-fallback: 500000 -## skips the gas estimate step for contract transactions -# transaction-debug-mode: false -## log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace -# verbosity: info +## enable pprof mutex profile +# pprof-mutex: false +## enable pprof block profile +# pprof-profile: false + +## ── Miscellaneous ───────────────────────────────────────────────────────────── ## maximum node warmup duration; proceeds when stable or after this time # warmup-time: 5m0s ## send a welcome message string during handshakes # welcome-message: "" -## withdrawal target addresses -# withdrawal-addresses-whitelist: [] -## enable wss p2p connections (default: false) -# p2p-wss-enable: false -## wss address (default: :1635) -# p2p-wss-addr: :1635 -## WSS NAT exposed address -# nat-wss-addr: "" -## autotls domain (default: libp2p.direct) -# autotls-domain: "" -## autotls registration endpoint (default: https://registration.libp2p.direct) -# autotls-registration-endpoint: "" -## autotls ca endpoint (default: https://acme-v02.api.letsencrypt.org/directory) -# autotls-ca-endpoint: "" ## SIMD BMT hashing opt-in flag (only available on linux amd64) # use-simd-hashing: false ## limit of possible connected light nodes (default: 100) diff --git a/pkg/node/node.go b/pkg/node/node.go index c05517ad5be..7be62bb50cc 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -131,6 +131,23 @@ type Bee struct { ethClientCloser func() } +// NodeMode represents the operational mode of a Bee node as configured by the operator. +type NodeMode string + +const ( + FullMode NodeMode = "full" + LightMode NodeMode = "light" + UltraLightMode NodeMode = "ultra-light" +) + +func (m NodeMode) IsValid() bool { + switch m { + case FullMode, LightMode, UltraLightMode: + return true + } + return false +} + type Options struct { Addr string AllowPrivateCIDRs bool @@ -165,7 +182,7 @@ type Options struct { EnableWS bool AutoTLSDomain string AutoTLSRegistrationEndpoint string - FullNodeMode bool + NodeMode NodeMode LightNodeLimit int GasLimitFallback uint64 Logger log.Logger @@ -276,7 +293,7 @@ func NewBee( // light nodes have zero warmup time for pull/pushsync protocols warmupTime := o.WarmupTime - if !o.FullNodeMode { + if o.NodeMode != FullMode { warmupTime = 0 } @@ -301,7 +318,7 @@ func NewBee( } }(b) - if !o.FullNodeMode && o.ReserveCapacityDoubling != 0 { + if o.NodeMode != FullMode && o.ReserveCapacityDoubling != 0 { return nil, fmt.Errorf("reserve capacity doubling is only allowed for full nodes") } @@ -424,14 +441,14 @@ func NewBee( erc20Service erc20.Service ) - chainEnabled := isChainEnabled(o, o.BlockchainRpcEndpoint, logger) + chainEnabled := isChainEnabled(o, logger) if o.SwapEnable && !chainEnabled { return nil, errors.New("swap is enabled but the chain backend is not; provide --blockchain-rpc-endpoint or disable swap") } - if o.ChequebookVerification && (!o.FullNodeMode || !o.ChequebookEnable || !chainEnabled) { - return nil, fmt.Errorf("chequebook-verification requires full-node mode, chequebook-enable, and an enabled chain backend (full_node=%t, chequebook_enable=%t, chain_enabled=%t)", o.FullNodeMode, o.ChequebookEnable, chainEnabled) + if o.ChequebookVerification && (o.NodeMode != FullMode || !o.ChequebookEnable || !chainEnabled) { + return nil, fmt.Errorf("chequebook-verification requires full-node mode, chequebook-enable, and an enabled chain backend (full_node=%t, chequebook_enable=%t, chain_enabled=%t)", o.NodeMode == FullMode, o.ChequebookEnable, chainEnabled) } var batchStore postage.Storer = new(postage.NoOpBatchStore) @@ -480,10 +497,13 @@ func NewBee( b.transactionCloser = tracerCloser b.transactionMonitorCloser = transactionMonitor - beeNodeMode := api.LightMode - if o.FullNodeMode { + var beeNodeMode api.BeeNodeMode + switch o.NodeMode { + case FullMode: beeNodeMode = api.FullMode - } else if !chainEnabled { + case LightMode: + beeNodeMode = api.LightMode + default: beeNodeMode = api.UltraLightMode } @@ -734,7 +754,7 @@ func NewBee( AutoTLSRegistrationEndpoint: o.AutoTLSRegistrationEndpoint, AutoTLSCAEndpoint: o.AutoTLSCAEndpoint, WelcomeMessage: o.WelcomeMessage, - FullNode: o.FullNodeMode, + FullNode: o.NodeMode == FullMode, LightNodeLimit: o.LightNodeLimit, Nonce: nonce, AllowPrivateCIDRs: o.AllowPrivateCIDRs, @@ -868,7 +888,7 @@ func NewBee( MinimumStorageRadius: o.MinimumStorageRadius, } - if o.FullNodeMode && !o.BootnodeMode { + if o.NodeMode == FullMode && !o.BootnodeMode { // configure reserve only for full node lo.ReserveCapacity = reserveCapacity lo.ReserveWakeUpDuration = reserveWakeUpDuration @@ -983,7 +1003,7 @@ func NewBee( } } - if o.FullNodeMode { + if o.NodeMode == FullMode { err = batchSvc.Start(ctx, postageSyncStart) syncStatus.Store(true) if err != nil { @@ -1008,7 +1028,7 @@ func NewBee( minThreshold := big.NewInt(2 * refreshRate) maxThreshold := big.NewInt(24 * refreshRate) - if !o.FullNodeMode { + if o.NodeMode != FullMode { minThreshold = big.NewInt(2 * lightRefreshRate) } @@ -1041,7 +1061,7 @@ func NewBee( var enforcedRefreshRate *big.Int - if o.FullNodeMode { + if o.NodeMode == FullMode { enforcedRefreshRate = big.NewInt(refreshRate) } else { enforcedRefreshRate = big.NewInt(lightRefreshRate) @@ -1136,7 +1156,7 @@ func NewBee( if prev == uint32(swarm.MaxBins) { close(initialRadiusC) } - if !o.FullNodeMode { // light and ultra-light nodes do not have a reserve worker to set the radius. + if o.NodeMode != FullMode { // light and ultra-light nodes do not have a reserve worker to set the radius. kad.SetStorageRadius(r) } case <-ctx.Done(): @@ -1163,7 +1183,7 @@ func NewBee( } } - pushSyncProtocol := pushsync.New(swarmAddress, networkID, nonce, p2ps, localStore, waitNetworkRFunc, kad, o.FullNodeMode && !o.BootnodeMode, pssService.TryUnwrap, gsocService.Handle, validStamp, logger, acc, pricer, signer, tracer, detector, uint8(shallowReceiptTolerance)) + pushSyncProtocol := pushsync.New(swarmAddress, networkID, nonce, p2ps, localStore, waitNetworkRFunc, kad, o.NodeMode == FullMode && !o.BootnodeMode, pssService.TryUnwrap, gsocService.Handle, validStamp, logger, acc, pricer, signer, tracer, detector, uint8(shallowReceiptTolerance)) b.pushSyncCloser = pushSyncProtocol // set the pushSyncer in the PSS @@ -1187,7 +1207,7 @@ func NewBee( pushSyncProtocolSpec := pushSyncProtocol.Protocol() pullSyncProtocolSpec := pullSyncProtocol.Protocol() - if o.FullNodeMode && !o.BootnodeMode { + if o.NodeMode == FullMode && !o.BootnodeMode { logger.Info("starting in full mode") } else { if chainEnabled { @@ -1272,7 +1292,7 @@ func NewBee( agent *storageincentives.Agent ) - if o.FullNodeMode && !o.BootnodeMode { + if o.NodeMode == FullMode && !o.BootnodeMode { pullerService = puller.New(swarmAddress, stateStore, kad, localStore, pullSyncProtocol, p2ps, logger, puller.Options{}) b.pullerCloser = pullerService @@ -1601,21 +1621,13 @@ func (b *Bee) Shutdown() error { var ErrShutdownInProgress = errors.New("shutdown in progress") -func isChainEnabled(o *Options, swapEndpoint string, logger log.Logger) bool { - chainDisabled := swapEndpoint == "" - lightMode := !o.FullNodeMode - - if lightMode && chainDisabled { - logger.Info("chain backend disabled - starting in ultra-light mode", - "full_node_mode", o.FullNodeMode, - "blockchain-rpc-endpoint", swapEndpoint) +func isChainEnabled(o *Options, logger log.Logger) bool { + if o.NodeMode == UltraLightMode { + logger.Info("chain backend disabled - starting in ultra-light mode") return false } - - logger.Info("chain backend enabled - blockchain functionality available", - "full_node_mode", o.FullNodeMode, - "blockchain-rpc-endpoint", swapEndpoint) - return true // all other modes operate require chain enabled + logger.Info("chain backend enabled - blockchain functionality available", "node_mode", o.NodeMode) + return true } func validatePublicAddress(addr string) error {