ADAMANT Localnet and Config Overrides: Faster development, Easier testing, Better automation
0
0
ADAMANT development has become easier and faster for node operators, contributors, and application developers.

In addition to the public ADAMANT Testnet, developers can now run a lightweight local ADAMANT network directly on their own machine. This new Localnet setup is designed for quick experiments, automated checks, scenario testing, and development workflows that do not require a public network or heavy infrastructure.
At the same time, ADAMANT Node now supports flexible configuration overrides, allowing operators and test automation scripts to change node settings at startup without editing config.json or test/config.json manually.
Together, these improvements make the ADAMANT development environment more reproducible, more automation-friendly, and much easier to use.
From Testnet to Localnet
Earlier, ADAMANT updated its Testnet infrastructure to make development and testing more accessible. The Testnet provides public nodes, a bootstrap database snapshot, test ADM coins, and a dedicated test environment for applications and node operators:
https://news.adamant.im/updating-the-testnet-infrastructure-for-adamant-aac36fea2a56
Testnet remains important because it gives developers a shared public environment that is closer to real network conditions. It is useful for testing integrations, checking application behavior, validating node compatibility, and experimenting with features before they reach Mainnet.
However, not every development task needs a public network.
Sometimes developers need something smaller and faster:
- start several nodes locally
- test a consensus-related change
- check peer discovery and synchronization
- reproduce a bug
- run automated scenario tests
- validate node behavior before opening a pull request
- experiment without touching public Testnet nodes
This is where Localnet comes in.
What is ADAMANT Localnet?
ADAMANT Localnet is a managed local multi-node ADAMANT network that runs on a single machine.
Instead of connecting to public Testnet nodes, Localnet starts several isolated ADAMANT nodes locally. Each node has its own ports, runtime state, logs, configuration, process metadata, and database settings.
The basic workflow is simple:
npm run start:localnet -- --nodes 3
Then developers can inspect the local network status:
npm run status:localnet
And stop it gracefully:
npm run stop:localnet
When a full cleanup is needed, persisted local databases can be removed with:
npm run drop:localnet
Or by using the stop option:
npm run stop:localnet -- --dropOnStop
The goal is to make local ADAMANT development fast and repeatable. Developers should be able to launch a clean local network, run tests or experiments, inspect the result, and shut it down without maintaining several manual node setups.
Lightweight and resource-friendly
Localnet is intentionally designed to be lightweight.
It does not require a public server, a VPS, or long synchronization from the network. It runs locally, uses controlled test configuration, and is suitable for development machines.
This makes it especially useful for:
- contributors who want to test node changes before submitting them
- maintainers who need fast release checks
- developers building applications on top of ADAMANT APIs
- automation scripts and CI-like environments
- consensus activation checks and local operational experiments
Instead of preparing several independent test nodes manually, the localnet tooling generates the required runtime files automatically.
What Localnet creates under the hood
The Localnet implementation adds maintained npm scripts for the local network lifecycle.
When Localnet starts, it generates isolated runtime data for each node, including per-node configuration files, runtime state, PID files, manifest, local chain data, per-node log folders.
Logs are separated by node, for example:
logs-localnet/
node-1/
node-2/
node-3/
This is important because multi-node issues often require comparing behavior across different peers. A single log file is not enough when debugging propagation issues, reconnects, missed blocks, split-brain situations, forging behavior, or broadhash consensus.
The Localnet tooling also produces machine-readable metadata, which can later be consumed by scenario testing tools.
Localnet status reporting
A local network is only useful if developers can quickly understand whether it is healthy.
That is why Localnet includes status reporting. The status script can report useful per-node information such as API status, delegate counts, last forging time, nethash, live broadhash consensus.
Broadhash consensus is especially useful for checking whether local nodes are actually aligned with each other after startup.
In a local smoke test, a 3-node localnet was started, status was polled, live broadhash consensus reached 100% on all nodes, and then the localnet was gracefully stopped and dropped.
Graceful shutdown by default
Localnet is not stopped by simply killing processes.
The stop:localnet script is designed to use the node’s normal graceful shutdown path. This helps avoid unnecessary database or runtime state issues and keeps local testing closer to real operational behavior.
By default, local PostgreSQL databases are persistent. This is useful when developers want to inspect state after a run. When a clean reset is needed, developers can use:
npm run drop:localnet
or:
npm run stop:localnet -- --dropOnStop
Automatic database creation depends on the local PostgreSQL role having CREATEDB permission. If this permission is not available, developers can use an existing database setup or documented skip/create options.
Config overrides: no more manual config editing
The second major improvement is generic startup configuration overrides.
Previously, ADAMANT Node supported selecting a config file with --config and had several hard-coded CLI overrides such as -- port, -- address, -- peers, -- log, and —--snapshot.
That worked for simple cases, but it did not scale well. Operators and automation scripts often need to change nested configuration values: ports, Redis settings, database settings, peer lists, logging options, API settings, forging configuration, activation heights, or test-specific parameters.
Editing copied config files manually is error-prone. Adding one CLI flag per config key does not scale. Replacing the whole config file is often too heavy for small environment-specific changes.
Config overrides solve this problem.
Direct startup overrides
Developers can now pass individual config values directly at startup using dot-path keys that match the existing config object shape.
Example:
node app.js
--config test/config.json
--genesis test/genesisBlock.json
--config-set consensusActivationHeights.fairSystem=4359465
--config-set redis='{ "url": "redis://127.0.0.1:6379/1", "password": null }'
This allows scripts to override a single nested scalar value, such as:
consensusActivationHeights.fairSystem=4359465
or a whole object value, such as:
redis='{ "url": "redis://127.0.0.1:6379/1", "password": null }'Values are parsed as JSON-compatible values where possible, so numbers, booleans, null, arrays, and objects can be represented correctly instead of being treated as plain strings.
Override files
Config overrides also support files.
An env-style override file can contain entries like:
consensusActivationHeights.fairSystem=4359465
redis='{ "url": "redis://127.0.0.1:6379/1", "password": null }'
The implementation also supports JSON partial override files.
This is useful for local environments, test automation, CI-like workflows, and maintainers who want a repeatable set of changes without modifying tracked configuration files.
Localnet uses this mechanism by default through:
test/config.localnet.json
This keeps Localnet setup clean: the base configuration remains stable, while localnet-specific differences are applied through the same validated override flow.
Validation and safety
Configuration overrides are powerful, so they must be safe.
The final resolved configuration is still validated against the existing ADAMANT config schema after defaults, override files, direct overrides, and legacy CLI shortcuts are resolved.
Invalid paths, invalid value types, malformed JSON, and unsafe keys are expected to fail before startup instead of producing unpredictable runtime behavior.
Sensitive values are redacted from config override logs, including values such as passwords, passphrases, secrets, and tokens.
Legacy startup shortcuts are routed through the same validated override pipeline and keep the highest override precedence.
This means existing workflows can continue working, while new workflows gain a more generic and consistent configuration mechanism.
Consensus-sensitive settings
Some configuration values are consensus-sensitive.
For example, overriding keys such as consensusActivationHeights.* can be useful for local or test scenarios, but using network-incompatible activation heights against the wrong chain may cause a node to diverge from the network.
For this reason, config overrides are intended to be explicit and visible. They are useful for Localnet, Testnet, automation, and controlled operational scenarios, but they should be used carefully on production Mainnet nodes.
The feature changes startup configuration resolution. It does not directly change block logic, transaction serialization, reward logic, fee logic, delegate ordering, signature checks, or consensus rules.
Why this matters for developers
Localnet and config overrides are infrastructure improvements, but their impact is practical.
They reduce the time between “I want to test this” and “I have a running ADAMANT network.”
They also make development workflows more reproducible. Instead of describing manual setup steps, a contributor can use scripts and override files. Instead of editing config files by hand, automation can pass exact startup parameters. Instead of relying on public Testnet for every experiment, developers can run a controlled local network.
Localnet and Testnet work together
Localnet does not replace Testnet.
They solve different problems.
Localnet is best for fast, private, repeatable development on one machine. It is ideal when developers need full control, quick startup, and isolated experiments.
Testnet is best for public, shared, network-level testing. It is useful when developers need a persistent environment, public peers, test ADM coins, explorer access, and application-level checks against a shared network.
Together, they give ADAMANT contributors a stronger development pipeline:
- Test locally with Localnet
- Validate against public Testnet
- Prepare safer Mainnet releases
A better foundation for ADAMANT tooling
These changes also prepare the ground for more advanced testing tools.
Localnet lifecycle management was separated from scenario test execution on purpose. The Localnet scripts are responsible for starting, stopping, inspecting, and cleaning up the local network. Scenario runners can then target an already available Localnet or Testnet and produce reports.
This separation keeps responsibilities clear and makes future tooling easier to build.
Getting started
Developers can start by checking the latest dev branch of the ADAMANT Node repository:
https://github.com/Adamant-im/adamant
Try starting a local network:
npm run start:localnet -- --nodes 3
Check status:
npm run status:localnet
Stop the network:
npm run stop:localnet
Drop persisted localnet databases when needed:
npm run drop:localnet
For custom startup behavior, use config overrides:
node app.js
— config test/config.json
— genesis test/genesisBlock.json
— config-set redis='{ "url": "redis://127.0.0.1:6379/1", "password": null }'
Or provide an override file:
node app.js
--config test/config.json
--genesis test/genesisBlock.json
--config-overrides test/config.localnet.json
Conclusion
ADAMANT now gives developers a faster and more flexible way to work with the node.
The public Testnet remains available for shared testing and application validation. Localnet adds a lightweight, local, multi-node environment for quick experiments and automation. Config overrides make node startup more flexible without manual config edits.
For contributors and maintainers, this means faster iteration, cleaner testing, better reproducibility, and a stronger foundation for future ADAMANT development.
Happy testing!
ADAMANT Localnet and Config Overrides: Faster development, Easier testing, Better automation was originally published in ADAMANT on Medium, where people are continuing the conversation by highlighting and responding to this story.
0
0
Securely connect the portfolio you’re using to start.