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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
node_modules
npm-debug.log*
.git
.gitignore
.github
.idea
.vscode
coverage
docs
migration
dockerfile
proto
stores
tests
whitelist
docker-compose.yml
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ cert.pem
migration/*
!migration/.gitkeep
.vscode/

# Environment files
.env
188 changes: 130 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,149 @@

A peer-to-peer crypto validator network to verify and append transactions.

Release 1 (R1) must be used alongside Trac Network R1 releases to maintain contract consistency.
Always follow the guidance in the [Security Policy](SECURITY.md) for release compatibility, upgrade steps, and required follow-up actions.

The MSB is utilizing the [Pear Runtime and Holepunch](https://pears.com/).
The MSB leverages the [Pear Runtime and Holepunch](https://pears.com/).

## Prerequisites

Node.js is required to run the application. Before installing Node.js, refer to the official [Node.js documentation](https://nodejs.org) for the latest recommended version and installation instructions. For this project, Node.js v24.11.0 (LTS) and npm 11.6.1 or newer are compatible.

The Pear Runtime CLI is required to run the application. Before installing Pear, refer to the official [Pear documentation](https://docs.pears.com/guides/getting-started) for the latest recommended version and installation instructions. For this project, the latest Pear CLI is compatible.

Install Pear globally:

```sh
npm install -g pear
which pear
```

Docker is optional and only needed for running the containerized RPC node. Before installing Docker, refer to the official [Docker documentation](https://www.docker.com) for the latest recommended version and installation instructions. For running the containerized RPC node, the latest Docker is recommended. Tested with Docker version 28.3.2, build 578ccf6.

## Install

```shell
git clone -b msb-r1 --single-branch [email protected]:Trac-Systems/main_settlement_bus.git
git clone -b main --single-branch [email protected]:Trac-Systems/main_settlement_bus.git
cd main_settlement_bus
npm install
```

## Post-install checklist

- ✅ `npm run test:unit:all` – confirms the codebase builds and runs under both supported runtimes.
- 📋 `npm run test:acceptance` – optional but recommended before upgrades. This suite spins up in-process nodes and may take a few minutes.
- 🌐 RPC smoke test – start `MSB_STORE=smoke-store MSB_HOST=127.0.0.1 MSB_PORT=5000 npm run env-prod-rpc` in one terminal, then execute `curl -s http://127.0.0.1:5000/v1/fee` from another terminal to verify `/v1` routes respond. Stop the node with `Ctrl+C` once finished.

## Usage

While the MSB supports native node-js, it is encouraged to use Pear:
Runtime entry points cover CLI-driven runs (`prod`, `prod-rpc`) and `.env`-aware runs (`env-prod`, `env-prod-rpc`). Each section below lists the accepted configuration inputs.

### Interactive regular node

#### Regular node with .env file

This variant reads configuration from `.env`:

```
# .env
MSB_STORE=<store_name>
```
then
```
npm run env-prod
```

The script sources `.env` before invoking program and falls back to `node-store` when `MSB_STORE` is not defined.

#### Inline environment variables ####

```sh
MSB_STORE=<store_name> npm run env-prod
```

This run persists data under `./stores/${MSB_STORE}` (defaults to `node-store`) and is intended for inline or CLI-supplied configuration.

#### CLI flags

```sh
npm run prod --store=<store_name>
```

### RPC-enabled node

#### RPC with .env file
```
# .env
MSB_STORE=<store_name>
MSB_HOST=0.0.0.0
MSB_PORT=5000
```

```js
cd main_settlement_bus
npm install -g pear
npm install
```
npm run env-prod-rpc
```

This entry point sources `.env` automatically and defaults to `rpc-node-store`, `0.0.0.0`, and `5000` when variables are not present.

You can run the node in two modes:
1. Regular node (validator/indexer):
```js
pear run . store1
#### Inline environment variables

```sh
MSB_STORE=<store_name> MSB_HOST=<host> MSB_PORT=<port> npm run prod-rpc
```

2. Admin node (access to administrative commands):
```js
pear run . admin
Override any combination of `MSB_STORE`, `MSB_HOST`, or `MSB_PORT`. Data is persisted under `./stores/${MSB_STORE}` (default `rpc-node-store` for this script).

#### CLI flags

```sh
npm run prod-rpc --store=<store_name> --host=<host> --port=<port>
```

The admin mode provides access to additional commands such as `/add_admin`, `/add_whitelist`, `/balance_migration`, `/disable_initialization`, `/add_indexer`, `/remove_indexer`, and `/ban_writer`. These commands are only visible and available when running in admin mode.

**Deploy Bootstrap (admin):**

- Choose option 1)
- Copy and backup the seedphrase
- Copy the "MSB Writer" address
- With a text editor, open the file msb.mjs in document root
- Replace the bootstrap address with the copied writer address
- Choose a channel name (exactly 32 characters)
- Run again: pear run . store1
- After the options appear, type /add_admin and hit enter
- Your instance is now the Bootstrap and admin peer, required to control validators
- Keep your bootstrap node running
- Strongly recommended: add a couple of nodes as writers

**Running indexers (admin)**

- Install on different machines than the Bootstrap's (ideally different data centers)
- Follow the "Running as validator" and then "Adding validators" procedures below
- Copy the MSB Writer address from your writer screen
- In your Bootstrap screen, add activate the new writers:
- /add_indexer <MSB Writer address (not the MSB address!)>
- You should see a success confirmation
- Usually 2 indexers on different locations are enough, we recommend 2 to max. 4 in addition to the Bootstrap

**Running as validator (first run):**

- Choose option 1)
- Copy and backup the seedphrase
- Copy the "MSB Address" after the screen fully loaded
- Hand your "MSB Address" over to the MSB admin for whitelisting
- Wait for the admin to announce the whitelist event
- In the screen type /add_writer
- After a few seconds you should see your validator being added as a writer

**Adding validators (admin):**

- Open the file /Whitelist/pubkeys.csv with a text editor
- Add as man Trac Network addresses as you wish
- In the MSB screen, enter /add_whitelist
- Wait for the listto be fully processed
- Inform your validator community being whitelisted
## Docker usage

You can run the RPC node in a containerized environment using the provided `docker-compose.yml` file.

The provided `docker-compose.yml` uses the Pear-backed `npm run env-prod-rpc` entry point; the container image pre-installs the Pear CLI and bootstraps the runtime automatically when it first starts.

### Running `msb-rpc` with Docker Compose

The `msb-rpc` service uses the local `./stores` folder (mounted into `/app/stores`) and the environment variables `MSB_STORE`, `MSB_HOST`, and `MSB_PORT`. Any of the following launch methods can be applied:

1. **Using a `.env` file** – populate `.env`, then start the service:

```sh
docker compose --env-file .env up -d msb-rpc
```

Follow the logs with `docker compose logs -f msb-rpc` to ensure the node is healthy.

2. **Passing variables inline** – use this method when environment variables should be provided directly in the command line, without modifying the `.env` file:

```sh
MSB_STORE=<store_name> MSB_HOST=<host> MSB_PORT=<port> docker compose up -d msb-rpc
```

3. **Reusing an existing store directory** – mount the path that already holds your store:

```sh
docker compose run -d --name msb-rpc \
-e MSB_STORE=<store_name> \
-e MSB_HOST=<host> \
-e MSB_PORT=<port> \
-p <port>:<port> \
-v /absolute/path/to/your/stores:/app/stores \
msb-rpc
```

Adjust `/absolute/path/to/your/stores` to the directory that already contains the persisted store. Once the container exists, bring it back with `docker compose start msb-rpc`.

Stop the service with `docker compose stop msb-rpc`, remove the stack entirely with `docker compose down` when you are finished.

> Note: The RPC instance must synchronize with the network after startup, so full readiness may take some time.

## Troubleshooting

- **Dependency install failures** – confirm you are on Node.js v24.11.0 (LTS) and npm ≥ 11.6.1. If packages still fail to build, clear artifacts (`rm -rf node_modules package-lock.json && npm install`) and rerun `npm run test:unit:all`.
- **Unit tests fail only in one runtime** – run the targeted commands (`npm run test:unit:node` or `npm run test:unit:bare`) to isolate regressions, then inspect `tests/unit/unit.test.js` for the failing cases.
- **RPC port already in use** – set `MSB_PORT` to a free value (for example `MSB_PORT=5050 npm run prod-rpc --port=5050`) or free the port with `lsof -i :<port>` as needed.
- **Docker container exits immediately** – check `docker compose logs -f msb-rpc` for missing volume permissions or environment variables; the service requires the mounted `./stores` directory to be writable by the container user.
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

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

The line ends abruptly at position 150 without proper sentence completion. Consider verifying the intended content.

Copilot uses AI. Check for mistakes.
32 changes: 32 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
services:

# For now we won't support msb-node in docker-compose because docker stdin/out handling is problematic
# and it could make really bad user experience.
# msb-node:
# build:
# context: .
# dockerfile: dockerfile
# container_name: msb-node
# stdin_open: true
# tty: true
# restart: unless-stopped
# command: ["prod"]
# environment:
# MSB_STORE: ${MSB_STORE:-node-store}
# volumes:
# - ./stores:/app/stores

msb-rpc:
build:
context: .
dockerfile: dockerfile
container_name: msb-rpc
restart: always
environment:
MSB_STORE: ${MSB_STORE:-rpc-node-store}
MSB_HOST: ${MSB_HOST:-0.0.0.0}
MSB_PORT: ${MSB_PORT:-5000}
volumes:
- ./stores:/app/stores
ports:
- "${MSB_PORT:-5000}:${MSB_PORT:-5000}"
29 changes: 29 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM node:22-bookworm

RUN apt-get update \
&& apt-get install -y --no-install-recommends libatomic1 \
&& rm -rf /var/lib/apt/lists/*

RUN npm install -g pear

USER node

WORKDIR /app

RUN pear
ENV PATH="/home/node/.config/pear/bin:${PATH}"

COPY package*.json ./
RUN npm ci --omit=dev
COPY . .

ENV MSB_STORE=node-store \
MSB_HOST=0.0.0.0 \
MSB_PORT=5000

VOLUME ["/app/stores"]
EXPOSE 5000

#ENTRYPOINT ["npm", "run"]
#CMD ["env-prod-rpc"]
CMD ["tail", "-f", "/dev/null"]
Comment on lines +27 to +29
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

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

The CMD is set to 'tail -f /dev/null' instead of executing the application. Either uncomment the ENTRYPOINT/CMD directives to run 'env-prod-rpc' or remove the commented lines if the no-op tail command is intentional for debugging.

Suggested change
#ENTRYPOINT ["npm", "run"]
#CMD ["env-prod-rpc"]
CMD ["tail", "-f", "/dev/null"]
ENTRYPOINT ["npm", "run"]
CMD ["env-prod-rpc"]

Copilot uses AI. Check for mistakes.
3 changes: 2 additions & 1 deletion msb.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const rpc_opts = {
...opts,
enable_tx_apply_logs: false,
enable_error_apply_logs: false,
enable_wallet: false,
enable_interactive_mode: true,

}

Expand All @@ -44,4 +46,3 @@ msb.ready().then(async () => {

msb.interactiveMode();
});

Loading