Skip to content

Generator v3.0.0 - #4

Open
wanwiset25 wants to merge 8 commits into
masterfrom
generator-v3.0.0
Open

Generator v3.0.0#4
wanwiset25 wants to merge 8 commits into
masterfrom
generator-v3.0.0

Conversation

@wanwiset25

@wanwiset25 wanwiset25 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Introduced XDPoS Privatechain Generator V3.
    • Added configuration for node versions, genesis versions, and Nethermind node count and version.
    • Added automatic generation of Nethermind-compatible chain specification files.
    • Added support for running in non-subnet mode with restricted subnet-management routes.
  • Documentation

    • Added instructions for starting the development server.
  • Chores

    • Updated the container runtime and generator release used by the startup script.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

XDPoS Generator V3

Layer / File(s) Summary
Genesis to chainspec conversion
container-manager/src/libs/genesis-to-chainspec.js
Adds exported translation functions and a CLI that maps genesis and XDPoS configuration into chainspec.json.
Nethermind generator integration
container-manager/src/libs/exec.js, container-manager/src/views/xdpos_generator/index.pug
Adds Nethermind node settings to the generator form, generated environment, and chainspec generation flow.
Non-subnet runtime and container wiring
container-manager/src/express.js, container-manager/start_xdpos.sh, container-manager/Dockerfile, container-manager/src/README.md, .gitignore
Adds NON_SUBNET route blocking, switches to the V3 image and Node 24, documents development startup, and ignores test.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant XDPoSGeneratorForm
  participant generateXdpos
  participant genesisToChainspec
  participant mountPath
  XDPoSGeneratorForm->>generateXdpos: provide Nethermind configuration
  generateXdpos->>genesisToChainspec: convert genesis.json
  genesisToChainspec->>mountPath: write chainspec.json
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: updating the generator to v3.0.0.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 generator-v3.0.0

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.

@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: 4

🤖 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 @.gitignore:
- Line 13: Update the .gitignore entry containing the slashless test pattern so
it no longer recursively ignores every file or directory named test. Remove the
broad pattern or scope it specifically to the intended generated artifact,
preserving visibility of test source files.

In `@container-manager/src/express.js`:
- Around line 55-62: Update the middleware registered with app.use so it
normalizes req.path before SUBNET_ROUTES.includes by removing one trailing slash
from non-root paths, ensuring variants like /submit/ remain blocked while / is
unchanged. Add coverage for blocked routes with and without the trailing slash.

In `@container-manager/src/libs/exec.js`:
- Around line 188-192: The Nethermind count is parsed inconsistently and can
allow negative or unsafe values into configuration. In
container-manager/src/libs/exec.js at lines 188-192, normalize or reject the
count as a non-negative safe integer before storing it; at lines 404-406, write
that same normalized value to NUM_NETHERMIND and use it for chainspec
generation. In container-manager/src/views/xdpos_generator/index.pug at lines
90-91, add min='0' and step='1' to the count input.

In `@container-manager/src/libs/genesis-to-chainspec.js`:
- Around line 143-150: Update the V2 round handling around expTimeoutConfig so
masternodeReward, protectorReward, and observerReward are not silently
overwritten. Preserve valid reward values from v2.allConfigs[round] in
chainspec.json; if Nethermind cannot represent them, fail generation with a
clear unsupported-rewards error rather than emitting zeroed rewards, unless an
explicit opt-in enables zeroing.
🪄 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 Plus

Run ID: 53ff0c14-f024-468c-9532-ca908b658490

📥 Commits

Reviewing files that changed from the base of the PR and between e4da44d and 6e162f9.

⛔ Files ignored due to path filters (4)
  • container-manager/src/gen/config_gen.js is excluded by !**/gen/**
  • container-manager/src/gen/gen_compose.js is excluded by !**/gen/**
  • container-manager/src/gen/gen_xdpos.js is excluded by !**/gen/**
  • container-manager/src/gen/scripts/xdc-nmc.json is excluded by !**/gen/**
📒 Files selected for processing (8)
  • .gitignore
  • container-manager/Dockerfile
  • container-manager/src/README.md
  • container-manager/src/express.js
  • container-manager/src/libs/exec.js
  • container-manager/src/libs/genesis-to-chainspec.js
  • container-manager/src/views/xdpos_generator/index.pug
  • container-manager/start_xdpos.sh

Comment thread .gitignore
**temp
*key*
*keys*
test No newline at end of file

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

Do not ignore every test path.

A slashless test pattern recursively ignores any file or directory with that name, which can silently exclude test source. Remove it or scope it to the intended generated artifact.

🤖 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 @.gitignore at line 13, Update the .gitignore entry containing the slashless
test pattern so it no longer recursively ignores every file or directory named
test. Remove the broad pattern or scope it specifically to the intended
generated artifact, preserving visibility of test source files.

Comment on lines +55 to +62
app.use((req, res, next) => {
if (NON_SUBNET && SUBNET_ROUTES.includes(req.path)) {
console.log(`NON_SUBNET: blocked ${req.path}`);
return res
.status(403)
.json({ error: "Subnet routes are disabled (NON_SUBNET mode)" });
}
next();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Files matching express.js:\n'
fd -a 'express\.js$' . || true

printf '\nRelevant file excerpts:\n'
for f in $(fd 'express\.js$' .); do
  echo "--- $f"
  wc -l "$f"
  sed -n '1,140p' "$f" | cat -n
done

printf '\nSubnet route declarations/usages:\n'
rg -n "SUBNET_ROUTES|/submit|submit|strictRouting|strict routing" container-manager/src || true

printf '\nPackage Express version if available:\n'
fd 'package\.json$' -d 5 . | xargs -r -n1 sh -c 'echo "--- $0"; jq ".dependencies.express, .devDependencies.express" "$0"'

Repository: XinFinOrg/Subnet-Deployment

Length of output: 50383


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Package.json/lock Express entries (if present):\n'
for f in $(fd 'package(-lock)?\.json$' -d 4 .); do
  echo "--- $f"
  jq -r '(.dependencies.express?, .devDependencies.express? // keys[]?|select(startswith("express@"))? // "none", (.["express@*"] // {})|keys[]?|select(startswith("express@"))? // "none")|select(type=="string")' "$f" 2>/dev/null || true
done

printf '\nRest of express.js route handlers and strict settings:\n'
sed -n '140,225p' container-manager/src/express.js | cat -n
grep -En "strictRouting|app\(strict|strict\(\)" container-manager/src || true

printf '\nProgrammatic simulation of current middleware vs Express-style non-strict GET routes for /submit and /submit/.submit variants:\n'
python3 - <<'PY'
BLOCKED = ["/submit", "/submit_preconfig", "/debug", "/"]
def current_checks(path):
    return path in BLOCKED
def express_like_matches(handler_path, req_path):
    if handler_path.endswith("/"):
        return req_path == handler_path or (handler_path[:-1] == req_path)
    return req_path == handler_path or req_path == handler_path + "/"

handler = "/submit"
for req_path in ["/submit", "/submit/", "/submit.submit", "/submit/submit", "/debug/"]:
    print(f"{req_path!r}: blocked={current_checks(req_path)} matching={express_like_matches(handler, req_path)}")
PY

Repository: XinFinOrg/Subnet-Deployment

Length of output: 3664


🌐 Web query:

Express.js 4.x 5.x strictRouting trailing slashes /foo and /foo/ route matching

💡 Result:

In Express.js, both version 4.x and 5.x provide a strict routing option that controls how the router handles trailing slashes in request paths [1][2]. By default, the strict routing option is disabled (false) [1][2]. When it is disabled, Express treats paths with and without a trailing slash (e.g., /foo and /foo/) as identical, meaning they will match the same route [1][2]. When the strict routing option is enabled (true), the router treats /foo and /foo/ as distinct, different routes [1][3]. To enable this behavior, you can pass the strict: true option when creating a router instance [1][2]: const router = express.Router({ strict: true }); This setting applies to the specific router instance. If you are using the main application object as a router, note that Express applications do not typically expose a direct configuration option for strict routing at the app level in the same way, though you can use a mounted router to enforce this behavior for specific sub-paths [1][2].

Citations:


Normalize paths before checking blocked routes.

Exact matching lets trailing-slash variants such as /submit/ bypass the middleware while Express still dispatches them to the /submit handler. Strip a single trailing slash from every non-root path before SUBNET_ROUTES.includes(...) and add coverage for the blocked route variants.

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 56-56: Logging request-derived input unsanitized allows log forging (CRLF injection); strip newlines / encode the value before logging.
Context: console.log(NON_SUBNET: blocked ${req.path})
Note: [CWE-117] Improper Output Neutralization for Logs. OWASP A09:2021 Security Logging and Monitoring Failures.

(log-injection-javascript)

🤖 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 `@container-manager/src/express.js` around lines 55 - 62, Update the middleware
registered with app.use so it normalizes req.path before SUBNET_ROUTES.includes
by removing one trailing slash from non-root paths, ensuring variants like
/submit/ remain blocked while / is unchanged. Add coverage for blocked routes
with and without the trailing slash.

Comment on lines +188 to +192
const nethermindCount =
"customversion-checkbox" in params &&
params["customversion-checkbox"] != ""
? parseInt(params["customversion-xdpos-nethermind-count"]) || 0
: 0;

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file sizes =="
wc -l container-manager/src/libs/exec.js container-manager/src/views/xdpos_generator/index.pug

echo "== relevant exec.js sections =="
sed -n '160,210p' container-manager/src/libs/exec.js
sed -n '380,420p' container-manager/src/libs/exec.js

echo "== relevant pug section =="
sed -n '80,100p' container-manager/src/views/xdpos_generator/index.pug

echo "== JS parse/runtime behavior probe =="
node - <<'JS'
const input = { "customversion-checkbox": "on", "customversion-xdpos-nethermind-count": "1e3" };
const nethermindCount =
  "customversion-checkbox" in input &&
  input["customversion-checkbox"] != ""
    ? parseInt(input["customversion-xdpos-nethermind-count"]) || 0
    : 0;

const emissionCondition = "customversion-checkbox" in input && input["customversion-checkbox"] != "" && "customversion-xdpos-nethermind-count" in input && input["customversion-xdpos-nethermind-count"] != "";
console.log({
  parseIntValue: nethermindCount,
  emissionCondition,
  emittedLine: emissionCondition ? `NUM_NETHERMIND=${input["customversion-xdpos-nethermind-count"]}` : "",
  isNaNNegative: isNaN(parseInt(input["customversion-xdpos-nethermind-count"])),
});

for (const value of ["-5", "", "abc", "3.7", "9007199254740991", "9007199254740992"]) {
  console.log(value, parseInt(value, 10));
}
JS

echo "== search for Nethermind count handling =="
rg -n "customversion-xdpos-nethermind-count|NUM_NETHERMIND|nethermind" container-manager/src

Repository: XinFinOrg/Subnet-Deployment

Length of output: 8224


Validate and canonicalize the Nethermind count before storing/updating it.

parseInt(params["...-count"]) can disagree with the raw NUM_NETHERMIND value, and negative values bypass chainspec generation while still being written to the environment. Server-side normalize the count to a non-negative safe integer (or reject invalid values), write that normalized value to NUM_NETHERMIND, and add min='0'/step='1' to the form input.

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: require("child_process")
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process)

📍 Affects 2 files
  • container-manager/src/libs/exec.js#L188-L192 (this comment)
  • container-manager/src/libs/exec.js#L404-L406
  • container-manager/src/views/xdpos_generator/index.pug#L90-L91
🤖 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 `@container-manager/src/libs/exec.js` around lines 188 - 192, The Nethermind
count is parsed inconsistently and can allow negative or unsafe values into
configuration. In container-manager/src/libs/exec.js at lines 188-192, normalize
or reject the count as a non-negative safe integer before storing it; at lines
404-406, write that same normalized value to NUM_NETHERMIND and use it for
chainspec generation. In container-manager/src/views/xdpos_generator/index.pug
at lines 90-91, add min='0' and step='1' to the count input.

Comment on lines +143 to +150
const { expTimeoutConfig, ...rest } = v2.allConfigs[round]; // drop expTimeoutConfig
// PLACEHOLDER: per-round reward amounts zeroed until XDC reward economics
// is finalized. Also avoids fractional puppeth defaults (e.g.
// protectorReward: 45.6) that Nethermind's UInt256 parser rejects.
rest.masternodeReward = 0;
rest.protectorReward = 0;
rest.observerReward = 0;
return rest;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate files =="
git ls-files | rg 'container-manager/src/(libs/genesis-to-chainspec|libs/exec)\.(js|ts)$' || true

echo "== File sizes =="
wc -l container-manager/src/libs/genesis-to-chainspec.js container-manager/src/libs/exec.js 2>/dev/null || true

echo "== Outline genesis-to-chainspec =="
ast-grep outline container-manager/src/libs/genesis-to-chainspec.js --view expanded 2>/dev/null || true

echo "== Relevant genesis-to-chainspec sections =="
cat -n container-manager/src/libs/genesis-to-chainspec.js | sed -n '1,230p'

echo "== exec relevant usages =="
rg -n "genesis-to-chainspec|chainspec|reward|nethermind" container-manager/src/libs/exec.js container-manager/src -g '*.js' -g '*.ts' | head -200

Repository: XinFinOrg/Subnet-Deployment

Length of output: 21874


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Genesis config generation sections around customrewards =="
cat -n container-manager/src/gen/config_gen.js | sed -n '1,100p'
cat -n container-manager/src/gen/gen_xdpos.js | sed -n '140,220p'
cat -n container-manager/src/gen/gen_xdpos.js | sed -n '300,365p'
cat -n container-manager/src/gen/gen_xdpos.js | sed -n '390,445p'

echo "== Find all references to v2 allConfigs/round configs and per-round rewards =="
rg -n "allConfigs|v2Configs|masternodeReward|protectorReward|observerReward|customrewards|rewardyield|reward_yield" container-manager/src -g '*.js' | sed -n '1,220p'

echo "== Search for Nethermind chainspec docs/schema references in repo =="
rg -n "chainspec|Nethermind|nethermind|XDPOS|XDPoS|AllConfigs|reward" README* container-manager -g '!node_modules' -g '!package-lock.json' 2>/dev/null | head -300

Repository: XinFinOrg/Subnet-Deployment

Length of output: 26318


🌐 Web query:

XDPoS v2 allConfigs masternodeReward protectorReward observerReward chainspec.json

💡 Result:

In the XDC Network's XDPoS v2 consensus mechanism, reward distribution is managed via a V2 configuration structure, often defined within the network's chain specifications [1][2]. These rewards are designed to incentivize different node roles, specifically Masternodes (Core Validators), Protector Nodes, and Observer Nodes [1][3][4]. The configuration parameters for these rewards are typically structured within a V2Config object or a similar configuration map, which can be found in source code files such as params/config_networks.go [1][2]. The relevant structure for these parameters is defined as follows [1]: type V2Config struct { MasternodeReward float64 json:"masternodeReward" ProtectorReward float64 json:"protectorReward" ObserverReward float64 json:"observerReward" MaxProtectorNodes int json:"maxProtectorNodes" MaxObserverNodes int json:"maxObserverNodes" } Key Implementation Details: 1. Reward Mechanism: Unlike V1, which focused on block rewards, XDPoS v2 calculates and distributes rewards per epoch (consisting of 900 rounds/blocks) [1][4]. 2. Configuration Storage: These parameters are part of the broader allConfigs map in the chainspec.json (or hardcoded genesis/params files), which allows the network to apply specific reward settings based on the current epoch or switch block [5][2]. 3. Hierarchy: The rewards are tiered. Core Validators (Masternodes) generally receive the highest rewards, followed by Protector Nodes (which act as hot backups), and then Observer Nodes (which monitor consensus without producing blocks) [3][4]. 4. Example Values: While these values are network-dependent, recent testnet configurations have used parameters such as MasternodeReward: 63.42, ProtectorReward: 50.27, and ObserverReward: 25.13 for specific protocol versions [2]. These are subject to governance and network upgrades [1][4]. For operators setting up nodes, these values are typically handled by the network's consensus engine parameters rather than manual configuration in a user-facing file, though they are visible and verifiable within the genesis block configuration or the node's chain parameters [2][6][4].

Citations:


Do not silently zero V2 round rewards for Nethermind.

genesis-to-chainspec.js emits chainspec.json for Nethermind nodes, and lines 147-149 overwrite every round’s masternodeReward, protectorReward, and observerReward. If the generated genesis.json is a valid XDPoS v2 genesis, persist those values (or fail generation with a clear unsupported-rewards error) instead of deploying a network where configured economics are changed without an explicit opt-in.

🤖 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 `@container-manager/src/libs/genesis-to-chainspec.js` around lines 143 - 150,
Update the V2 round handling around expTimeoutConfig so masternodeReward,
protectorReward, and observerReward are not silently overwritten. Preserve valid
reward values from v2.allConfigs[round] in chainspec.json; if Nethermind cannot
represent them, fail generation with a clear unsupported-rewards error rather
than emitting zeroed rewards, unless an explicit opt-in enables zeroing.

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.

1 participant