Skip to content

Discovery only bootnode docker - #194

Merged
anunay-xin merged 4 commits into
masterfrom
discovery-only-bootnode-docker
Jul 8, 2026
Merged

Discovery only bootnode docker#194
anunay-xin merged 4 commits into
masterfrom
discovery-only-bootnode-docker

Conversation

@anunay-xin

@anunay-xin anunay-xin commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.

Types of changes

What types of changes does your code introduce to XDC network?
Put an in the boxes that apply

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update (if none of the other choices apply)
  • Regular KTLO or any of the maintaince work. e.g code style
  • CICD Improvement

Impacted Components

Which part of the codebase this PR will touch base on,

Put an in the boxes that apply

  • Consensus
  • Account
  • Network
  • Geth
  • Smart Contract
  • External components
  • Not sure (Please specify below)

Checklist

Put an in the boxes once you have confirmed below actions (or provide reasons on not doing so) that

  • This PR has sufficient test coverage (unit/integration test) OR I have provided reason in the PR description for not having test coverage
  • Provide an end-to-end test plan in the PR description on how to manually test it on the devnet/testnet.
  • Tested the backwards compatibility.
  • Tested with XDC nodes running this version co-exist with those running the previous version.
  • Relevant documentation has been updated as part of this PR
  • N/A

Summary by CodeRabbit

  • New Features

    • Added bootnode support with configurable peer lists, including file-based bootnode loading and a new Docker Compose setup for running a bootnode service.
    • Improved container startup behavior with automatic external IP detection, optional manual override, configurable ports, keys, logs, and verbosity.
  • Bug Fixes

    • Fixed network restriction handling so configured values are applied correctly.
    • Ensured bootnode startup uses the proper generated files and writes the resulting node address output.
  • Chores

    • Updated Docker and build settings to include required artifacts and keep build contexts lean.

- Introduced a new Docker Compose file for bootnode service.
- Updated `.dockerignore` to exclude the new `build/bin` directory.
- Enhanced `Makefile` to include bootnode as a target.
- Added `bootnodes.list` file for bootstrap node configurations.
- Modified `main.go` to support bootnode configuration via command-line flags.
- Updated Dockerfile to ensure bootnode is built and available.
- Refined `start-bootnode.sh` to handle bootnode parameters and logging more effectively.
- Updated Dockerfile to include curl installation and clean up APT lists.
- Modified start-bootnode.sh to auto-detect public IP if EXTIP is not set, with added logging for detection failures.
- Added DISABLE_EXTIP environment variable to docker-compose.bootnode.yml for controlling external IP detection.
- Updated start-bootnode.sh to handle DISABLE_EXTIP, allowing for bootnode startup without NAT external IP if set.
- Added multiple new enode entries to the bootnodes.list for mainnet
- Removed the k8s-bootnode.yaml file
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds bootnode discovery input support, introduces a bootnode container/service setup, and updates the bootnode launch script to derive runtime parameters, keys, logging, and NAT/address settings from environment variables.

Changes

Bootnode packaging and startup

Layer / File(s) Summary
Bootnode inputs and discover config
bootnode/bootnodes.list, cmd/bootnode/main.go
Adds a bootnode peer list file, new -bootnodes and -bootnodesfile flags, bootnode URL parsing, and discover.Config bootnode wiring.
Container build and service wiring
.dockerignore, Makefile, docker/Dockerfile, docker-compose.bootnode.yml
Ignores build/bin in Docker context, marks extra Make targets phony, updates Docker build steps, and adds a compose service for bootnode.
Bootnode launch script
docker/start-bootnode.sh
Updates extip detection, key handling, runtime flags, enode output, logging, and the final bootnode execution command.

Sequence Diagram(s)

sequenceDiagram
  participant BootnodeService as bootnode service
  participant StartScript as docker/start-bootnode.sh
  participant Curl as curl
  participant Bootnode as bootnode
  participant Discover as discover.ListenUDP

  BootnodeService->>StartScript: start container with bootnode env vars
  StartScript->>Curl: resolve EXTIP when unset and extip is enabled
  StartScript->>Bootnode: exec bootnode -nodekey "$NODEKEY_FILE" $params "$@"
  Bootnode->>Discover: pass Bootnodes in discover.Config
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through bootnodes, bright and new,
With Docker jars and flags in view.
A key, a port, a whispered name,
Then bootnode sprang to start the game.
Thump-thump — the rabbit cheers from grass!

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is only the template and does not fill in the required sections or checklist. Add a real summary, select change types and impacted components, and complete the checklist with testing and compatibility details.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is related to the PR, but it's vague and doesn't clearly state the main change. Use a more specific title like "Add Docker bootnode support and discovery bootnodes".
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch discovery-only-bootnode-docker

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@anunay-xin
anunay-xin marked this pull request as ready for review June 26, 2026 13:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
cmd/bootnode/main.go (1)

103-127: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

utils.Fatalf on any single bad entry aborts the whole bootnode.

With a large, externally-maintained bootnodes.list, one malformed enode (or a stray non-enode line) kills startup entirely. Consider logging and skipping invalid entries instead of fatally exiting, so the bootnode still comes up with the valid peers.

♻️ Skip-and-warn instead of fatal
 		for _, url := range urls {
 			node, err := discover.ParseNode(url)
 			if err != nil {
-				utils.Fatalf("invalid bootnode %q: %v", url, err)
+				log.Warn("skipping invalid bootnode", "url", url, "err", err)
+				continue
 			}
 			bootnodeList = append(bootnodeList, node)
 		}

discover.ParseNode behavior (rejecting non-enode:// lines, comments, blanks) per go-ethereum 1.9.11.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/bootnode/main.go` around lines 103 - 127, The bootnode parsing in main
should not abort startup when a single entry fails to parse. Update the
bootnodes processing in main and the discover.ParseNode loop to warn and skip
invalid URLs or non-enode/comment/blank lines instead of calling utils.Fatalf
for each bad entry, while still collecting all valid peers into bootnodeList.
docker/Dockerfile (1)

3-4: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add --no-install-recommends to apt-get install.

Reduces image size and attack surface by avoiding recommended-but-unneeded packages. Applies to both the builder and runtime stages.

🔧 Proposed change
-RUN apt-get update && apt-get install -y git build-essential curl \
-    && rm -rf /var/lib/apt/lists/*
+RUN apt-get update && apt-get install -y --no-install-recommends git build-essential curl \
+    && rm -rf /var/lib/apt/lists/*
As per static analysis hint Trivy DS-0029 ('apt-get' missing '--no-install-recommends').

Also applies to: 14-15

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/Dockerfile` around lines 3 - 4, The apt-get install step in the
Dockerfile is missing --no-install-recommends, which should be added to reduce
the image size and avoid pulling unnecessary packages. Update the install
command used in the builder/runtime stages so the apt-get install invocations
include --no-install-recommends alongside the existing packages, keeping the
same cleanup step afterward.

Source: Linters/SAST tools

docker/start-bootnode.sh (1)

5-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consolidate the duplicated DISABLE_EXTIP blocks.

The DISABLE_EXTIP guard is evaluated twice (lines 5 and 17) with the first block only printing a message. The two branches can be merged into a single conditional, simplifying the extip flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/start-bootnode.sh` around lines 5 - 24, The EXTIP flow in the bootnode
startup script duplicates the DISABLE_EXTIP check in two separate conditionals,
with the first branch only emitting a message and the second handling NAT setup.
Merge the logic into a single conditional around the existing EXTIP detection
and parameter assignment so DISABLE_EXTIP is handled once, and keep the behavior
for auto-detection, explicit EXTIP, and the fallback warning intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bootnode/bootnodes.list`:
- Line 9: The bootnode entry uses an inconsistent discovery port compared with
the other entries, so verify the enode address in bootnodes.list and change the
port to match the expected discovery port if this was accidental. Update the
specific bootnode line with the correct port value so it is consistent with the
rest of the list and remains discoverable.

In `@docker/start-bootnode.sh`:
- Around line 40-45: The PRIVATE_KEY path in start-bootnode.sh writes directly
to NODEKEY_FILE without ensuring the parent directory exists, so the echo
redirection can fail when the bootnode directory is missing. Update the
PRIVATE_KEY branch to create the parent directory before writing, matching the
mkdir -p behavior used in the bootnode -genkey branch. Keep the fix localized to
the NODEKEY_FILE handling logic so both branches consistently prepare the
destination path.
- Around line 67-70: Quote the shell variable expansions in the bootnode startup
script to satisfy SC2086: update the `address=` assignment in
`start-bootnode.sh` so `NODEKEY_FILE` is passed as a quoted argument to
`bootnode`, and change the `echo` write that uses `address` so the variable is
quoted when redirected to `BOOTNODE_ENODE_OUT`. Leave the later `$params` usage
unchanged, since it is intentionally unquoted for splitting.

---

Nitpick comments:
In `@cmd/bootnode/main.go`:
- Around line 103-127: The bootnode parsing in main should not abort startup
when a single entry fails to parse. Update the bootnodes processing in main and
the discover.ParseNode loop to warn and skip invalid URLs or
non-enode/comment/blank lines instead of calling utils.Fatalf for each bad
entry, while still collecting all valid peers into bootnodeList.

In `@docker/Dockerfile`:
- Around line 3-4: The apt-get install step in the Dockerfile is missing
--no-install-recommends, which should be added to reduce the image size and
avoid pulling unnecessary packages. Update the install command used in the
builder/runtime stages so the apt-get install invocations include
--no-install-recommends alongside the existing packages, keeping the same
cleanup step afterward.

In `@docker/start-bootnode.sh`:
- Around line 5-24: The EXTIP flow in the bootnode startup script duplicates the
DISABLE_EXTIP check in two separate conditionals, with the first branch only
emitting a message and the second handling NAT setup. Merge the logic into a
single conditional around the existing EXTIP detection and parameter assignment
so DISABLE_EXTIP is handled once, and keep the behavior for auto-detection,
explicit EXTIP, and the fallback warning intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d3225e8e-564c-4dc2-bee0-29c9ad0cfc08

📥 Commits

Reviewing files that changed from the base of the PR and between 82d26c1 and cf71693.

📒 Files selected for processing (7)
  • .dockerignore
  • Makefile
  • bootnode/bootnodes.list
  • cmd/bootnode/main.go
  • docker-compose.bootnode.yml
  • docker/Dockerfile
  • docker/start-bootnode.sh

Comment thread bootnode/bootnodes.list
enode://938f2e3f409a12573e6da6460b6497c45e2bec393756b989b8874f647911cca39d0ffef8554a45698a8f21a7e870288beb638b3770537a12118e30bd6f9ae806@109.199.104.176:30303
enode://f8848e405142b8e88f054fe85ac5e4a75cfd7e353aee7e66797719828d3d5aa2cd62f1355140c0852d3dcb2439a076234c77415ca701318ea1f69a496a0b4b32@109.123.232.199:30303
enode://0857894c01314e75520fbdb7e37869666f230c8ab96c0e3067561077209e8f48a9cefb3a71c3c8094448629c152f22c2e5e66bb7ed2c38bfbd9f24941f571beb@103.7.54.103:30303
enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.142.140:30304

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Verify the discovery port 30304 on line 9.

Every other entry uses 30303; line 9 alone uses 30304. If unintentional, peers will fail to discover this node on the expected port.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bootnode/bootnodes.list` at line 9, The bootnode entry uses an inconsistent
discovery port compared with the other entries, so verify the enode address in
bootnodes.list and change the port to match the expected discovery port if this
was accidental. Update the specific bootnode line with the correct port value so
it is consistent with the rest of the list and remains discoverable.

Comment thread docker/start-bootnode.sh
Comment on lines 40 to 45
if [[ ! -z "$PRIVATE_KEY" ]]; then
echo "$PRIVATE_KEY" > bootnode.key
elif [[ ! -f ./bootnode.key ]]; then
bootnode -genkey bootnode.key
echo "$PRIVATE_KEY" > "$NODEKEY_FILE"
elif [[ ! -f "${NODEKEY_FILE}" ]]; then
mkdir -p "$(dirname "${NODEKEY_FILE}")"
bootnode -genkey "$NODEKEY_FILE"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

PRIVATE_KEY branch can fail when the key directory doesn't exist.

The genkey branch creates the parent dir via mkdir -p, but the PRIVATE_KEY branch writes directly to $NODEKEY_FILE. If the directory (e.g. bootnode/) is missing, the redirection on line 41 fails and the script aborts. Create the directory before writing.

🐛 Proposed fix
 if [[ ! -z "$PRIVATE_KEY" ]]; then
+  mkdir -p "$(dirname "${NODEKEY_FILE}")"
   echo "$PRIVATE_KEY" > "$NODEKEY_FILE"
 elif [[ ! -f "${NODEKEY_FILE}" ]]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ ! -z "$PRIVATE_KEY" ]]; then
echo "$PRIVATE_KEY" > bootnode.key
elif [[ ! -f ./bootnode.key ]]; then
bootnode -genkey bootnode.key
echo "$PRIVATE_KEY" > "$NODEKEY_FILE"
elif [[ ! -f "${NODEKEY_FILE}" ]]; then
mkdir -p "$(dirname "${NODEKEY_FILE}")"
bootnode -genkey "$NODEKEY_FILE"
fi
if [[ ! -z "$PRIVATE_KEY" ]]; then
mkdir -p "$(dirname "${NODEKEY_FILE}")"
echo "$PRIVATE_KEY" > "$NODEKEY_FILE"
elif [[ ! -f "${NODEKEY_FILE}" ]]; then
mkdir -p "$(dirname "${NODEKEY_FILE}")"
bootnode -genkey "$NODEKEY_FILE"
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/start-bootnode.sh` around lines 40 - 45, The PRIVATE_KEY path in
start-bootnode.sh writes directly to NODEKEY_FILE without ensuring the parent
directory exists, so the echo redirection can fail when the bootnode directory
is missing. Update the PRIVATE_KEY branch to create the parent directory before
writing, matching the mkdir -p behavior used in the bootnode -genkey branch.
Keep the fix localized to the NODEKEY_FILE handling logic so both branches
consistently prepare the destination path.

Comment thread docker/start-bootnode.sh
Comment on lines +67 to +70
address="enode://$(bootnode -nodekey ${NODEKEY_FILE} -writeaddress)@${host}:${BOOTNODE_PORT}"
echo "Starting the bootnode with address at $address"
BOOTNODE_ENODE_OUT="${BOOTNODE_ENODE_OUT:-bootnode/bootnode.enode}"
echo $address > "$BOOTNODE_ENODE_OUT"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Quote variable expansions (SC2086) on lines 67 and 70.

${NODEKEY_FILE} (line 67) and $address (line 70) should be quoted to prevent word splitting/globbing. Note line 78's $params is intentionally left unquoted for argument splitting and can be ignored.

🔧 Proposed change
-address="enode://$(bootnode -nodekey ${NODEKEY_FILE} -writeaddress)@${host}:${BOOTNODE_PORT}"
+address="enode://$(bootnode -nodekey "${NODEKEY_FILE}" -writeaddress)@${host}:${BOOTNODE_PORT}"
@@
-echo $address > "$BOOTNODE_ENODE_OUT"
+echo "$address" > "$BOOTNODE_ENODE_OUT"
As per static analysis hint Shellcheck SC2086.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
address="enode://$(bootnode -nodekey ${NODEKEY_FILE} -writeaddress)@${host}:${BOOTNODE_PORT}"
echo "Starting the bootnode with address at $address"
BOOTNODE_ENODE_OUT="${BOOTNODE_ENODE_OUT:-bootnode/bootnode.enode}"
echo $address > "$BOOTNODE_ENODE_OUT"
address="enode://$(bootnode -nodekey "${NODEKEY_FILE}" -writeaddress)@${host}:${BOOTNODE_PORT}"
echo "Starting the bootnode with address at $address"
BOOTNODE_ENODE_OUT="${BOOTNODE_ENODE_OUT:-bootnode/bootnode.enode}"
echo "$address" > "$BOOTNODE_ENODE_OUT"
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 67-67: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 70-70: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/start-bootnode.sh` around lines 67 - 70, Quote the shell variable
expansions in the bootnode startup script to satisfy SC2086: update the
`address=` assignment in `start-bootnode.sh` so `NODEKEY_FILE` is passed as a
quoted argument to `bootnode`, and change the `echo` write that uses `address`
so the variable is quoted when redirected to `BOOTNODE_ENODE_OUT`. Leave the
later `$params` usage unchanged, since it is intentionally unquoted for
splitting.

Source: Linters/SAST tools

@anunay-xin
anunay-xin merged commit 5f9d766 into master Jul 8, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants