Skip to content

hclivess/bismuth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

748 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bismuth

Bismuth is a proof-of-work cryptocurrency and smart-contract platform written in Python. A node validates blocks, maintains the ledger, talks to peers, mines, and serves wallets and explorers.

Status — modernization fork. This tree is an in-progress modernization of the Bismuth node. The guiding rule is that consensus does not change: the same blocks must produce the same hashes and validate identically. Every change is replay-verified (the chain is re-hashed end-to-end through a frozen serialization boundary) and gated by the test suite, so storage, networking and APIs can be modernized safely behind a fixed consensus layer. See the Roadmap and doc/16.

For production, use a tagged release — main may be ahead of what's network-validated.


Quickstart

Requires Python 3.8+ (developed/tested on 3.12).

# 1. install dependencies
pip3 install -r requirements-node.txt

# 2. run a node (mainnet)
python3 node.py

# 3. stop it cleanly
python3 node_stop.py

Run as a service (systemd) — recommended

Don't babysit a screen/nohup. Install the node as a systemd service — it survives reboots, restarts on failure, and stops gracefully (systemd sends SIGTERM, the node finishes its in-flight block and drains db_lock, so ledger.db/hyper.db stay consistent):

sudo bash scripts/install-node-service.sh

The installer auto-detects the repo dir, python3, and user; gracefully stops any node already running on :5658; writes /etc/systemd/system/bismuth-node.service; and enables + starts it. After that:

systemctl status  bismuth-node     # up / synced?
systemctl stop    bismuth-node     # graceful stop
systemctl restart bismuth-node     # graceful restart
journalctl -u bismuth-node -f      # follow the logs

The service sets BISMUTH_IGNORE_CONFIG_CUSTOM=1 so it always boots mainnet even if a leftover regnet config_custom.txt is present.

Local dev chain (regnet) + tests

regnet is a private, instantly-mineable chain for development — no peers, no real PoW. The test suite spins one up automatically:

# run the full test suite (launches a throwaway regnet node, ~90 tests)
python3 -m pytest

# or run a regnet node yourself (REST API on :3031, socket on :3030)
cp tests/config_custom.txt config_custom.txt
python3 node.py regnet2

Configuration lives in config.txt (see doc/11); regnet/test overrides are in tests/config_custom.txt.


REST API

A modern, read-only HTTP API runs alongside the legacy socket protocol (opt in with rest_api=True; default port 5659, regnet 3031). It is self-describing — GET /api (or the bare root /) lists every method:

Endpoint Purpose
GET /api/status node height, peers, difficulty, consensus
GET /api/capabilities REST/transport capabilities for peer sync (reachable = capable)
GET /api/block/height/{n} · GET /api/block/hash/{h} a single block
GET /api/blocks/since/{h} · GET /api/blocks/range/{a}/{b} block ranges, for parallel sync
GET /api/balance/{address} confirmed balance
GET /api/transaction/{txid} a transaction
GET /api/address/{address}/transactions recent txs (?limit=N)
GET /api/mempool · GET /api/peers pending txs · known peers

Transport compression is applied at the HTTP layer: responses are gzip/br compressed for any client that sends Accept-Encoding (browsers, and the bundled rest_client.py). Add ?compress=none to read plaintext, or ?compress=gzip|br to force a codec.

rest_client.py is the parallel block-fetch client: it discovers a peer (GET /api/capabilities) and pulls /api/blocks/range in concurrent, compressed chunks — the modern alternative to the serial socket sync. Full REST API reference: doc/15.


Architecture at a glance

Concern Where Notes
Consensus serialization bismuth_serialize.py frozen signing/block-hash byte forms; the boundary everything hides behind
Block processing digest.py validates and applies blocks
PoW / difficulty mining_heavy3.py, difficulty Heavy3 hashing
Ledger / storage dbhandler.py, amounts.py, SQLite integer atomic-unit storage behind the frozen boundary (opt-in)
Schema migrations db_migrations.py ordered, PRAGMA user_version-tracked
Mempool mempool.py pending transactions
Networking (legacy) node.py, connections.py length-prefixed JSON over sockets
Networking (modern) rest_api.py, rest_client.py, transport.py HTTP API + parallel fetch + compression
Crypto / keys polysign/ RSA / ECDSA / ed25519 signers

Full design docs are in doc/ — start with doc/01-overview.md and the file reference.


Documentation

01 Overview 02 Architecture & threads 03 Consensus, blocks, digest
04 PoW & difficulty 05 Database & ledger 06 Networking protocol
07 Mempool 08 API & commands 09 Crypto, wallets, keys
10 Features 11 Configuration 12 Tooling, build, tests
13 File reference 14 Known issues & improvements 15 REST API
16 Database rework plan 17 Roadmap

Roadmap

Detailed plan: doc/17-roadmap.md. Database deep-dive: doc/16.

✅ Done

  • Frozen consensus boundary — signing-buffer and block-hash byte forms extracted into bismuth_serialize.py and characterization-locked, so storage/transport can change without touching consensus.
  • Schema versioning & migrations — ordered, user_version-tracked (db_migrations.py).
  • Integer atomic-unit storage — exact integer amounts behind the frozen boundary, replay-verified (every block hash byte-identical), live on regnet behind ledger_integer_amounts (default off).
  • Modern HTTP layer — read-only REST API; capability discovery (reachable = capable); parallel, gzip/br-compressed block fetch client (rest_client.py); mainnet0023 capability signal.

◑ In progress / next

  • Wire the parallel REST fetch into the actual sync path, so nodes catch up over the HTTP API instead of the serial, blocking socket loop.
  • Incremental balance index — O(1) maintained credit/debit, bit-matching the authoritative sum.
  • Explicit reward & pruning model — replace negative-height "mirror" rows and Hyperblock string rows with real columns/tables.

🗺️ Planned

  • Consensus hard fork — sign/hash native integer units + a binary tx encoding (deleting the '%.8f'/'%.2f' string conversions, all tagged # HARDFORK (doc/16)), and adopt a bounded, content-derived txid (nado-style BLAKE2b, the signature signs the txid).
  • Deprecate the blocking socket protocol in favour of the HTTP API for node-to-node traffic.
  • Storage-engine evaluation — modernize SQLite usage, benchmark, and consider a KV store (LMDB/RocksDB) for block bodies while keeping SQLite for queryable indexes — decided on data.
  • Repository reorganization — group modules, retire dead files.

Community & links

License

GNU General Public License — see LICENSE.

About

The first Python blockchain protocol and platform

Topics

Resources

License

GPL-3.0, Unknown licenses found

Licenses found

GPL-3.0
LICENSE
Unknown
license.txt

Stars

180 stars

Watchers

2 watching

Forks

Packages

 
 
 

Contributors