← همهٔ نوشته‌ها

فنی · Walkthrough

How to run a node: the chain, verified on your own machine

Running a full node is the most honest thing you can do on a chain: instead of asking a server what happened, your machine re-derives it from the rules. On most networks those rules are signatures and proof-of-work. On TensorCash there's one more — the block's proof-of-work is a real forward pass, so a full node also checks that the AI model actually ran.

This is the practical guide to running one. The first thing to settle isn't the hardware or the commands — it's who you trust to check that last rule.

The first decision: who verifies the AI?

Every block carries a proof that a specific, chain-approved model produced a specific output. A node has to decide that proof is good before the block counts. You run that check one of two ways.

Run your own verifierDelegate
Who does the full/model re-runyou, on your own hardware (GPU + model)a third party you point to
You trust someone else fornothingthe AI-execution claim only
Always checked locally, either waysignatures, proof-of-work, structure, the model registry, VDF proofs, and the fast quick/smell screensame

Two things are worth being precise about. First, a node always runs the cheap checks itself — signatures, proof-of-work, the model registry, and a fast "quick/smell" screen of the inference proof, all in-process. What this choice moves is the expensive part: actually re-executing the forward pass (the full and model checks) to confirm the registered model really produced that output — and that re-run needs a GPU and the model weights.

So running your own verifier means you trust nobody for "the model ran," at the cost of the hardware to do it; delegate means the node hands the full/model check to a verifier you've chosen and trusts its verdict for that one claim.

Second — and this trips people up — who runs the verifier is a separate question from how the node reaches it. The transport is either a local ZMQ socket (-validationapi=real with no verifier URL set; the Docker launch wrapper's --desktop) or HTTP (-validationapi=desktop, or real with a verifier URL from -validatorhttpurl or env VALIDATOR_BASE_URL; the wrapper's --http). HTTP can still point at a verifier on your own box (a local gateway), so HTTP doesn't imply delegation. What decides sovereignty is who runs the verifier, not the transport.

Running the verifier engine — for yourself or as a service others delegate to — is its own walkthrough; see How to run a verifier. Here we'll wire the node to one.

Step 1: Pick a network

Start on testnet. The node selects its chain with -chain (or a convenience alias). With no chain flag and no chain in its config, it runs mainnet, so pass the testnet flag explicitly:

NetworkFlagRPC port
Testnet (start here)-tensortest (-chain=tensor-test)29240 (P2P 29241)
Mainnet (coordinated)-tensor (-chain=tensor), the default39242 (P2P 39241)
Local private chain-regtest18443

In a Docker deployment the chain lives in the node's bitcoin.conf (mounted at the data dir), not on the command line — the provided testnet stack ships a ready-made bitcoin.tensor-test.conf and a run_tensor_testnet.sh helper that stages it for you. Mainnet mining and validation are coordinated — start on testnet, and bring your own node up there first.

For a throwaway local chain you control end to end — mine a block, register a model, see it confirm — the regtest quickstart is the fastest loop and never touches the public network.

Step 2: Pruned or archival?

A node stores the chain. You decide how much of it stays on disk.

  • Archival (-prune=0, the default): keep every block forever. Needed if you want a transaction index (-txindex) or plan to serve historical blocks to other nodes.
  • Pruned (-prune=N): keep only a recent window of blocks on disk, capped at N MiB. The floor is 550 MiB. -prune=550 is the smallest useful setting; -prune=2000 keeps a roomier window.

Pruning is a first-class, supported mode here — with one thing to understand about what it does and doesn't touch.

What pruning deletes: only old block and undo files. That's the bulky part of the chain, and a pruned node still fully validated every one of those blocks on the way past.

What pruning never touches:

  • the chainstate (the live UTXO set),
  • the asset registry (it rides inside the chainstate, not in block files), and
  • the ModelDB — the index of which models are registered and active, kept in its own database and advanced one block at a time with an undo journal.

So a pruned node still answers "is this model approved?" and "what's this asset?" in full. You give up serving old block bodies; you keep every consensus check.

The one caveat worth knowing. ModelDB can normally recover from an unclean shutdown by rewinding its undo journal — no historical blocks required, so this is safe on a pruned node. The only operation that needs old blocks is a ModelDB full rebuild from genesis, and on a pruned datadir the node will refuse it rather than build a corrupt index — exiting with a clear message. If you ever hit that, the fix is a full -reindex (it re-downloads the blocks), a wipe-and-resync, or restoring a ModelDB snapshot. Practical rule: on a pruned box, never reach for -reindex-chainstate (it's incompatible with pruning anyway) — use a full -reindex if you must rebuild.

Step 3: Run it

From source (bitcoind)

If you've built from source, every choice above is a plain flag — the most direct way to control a node. The verification backend is the -validationapi flag.

Verify locally with -validationapi=real (the default): with no verifier URL set, the full/model check runs over a local ZMQ socket, so it needs a verifier engine running and reachable (see How to run a verifier):

bitcoind \
  -tensortest \
  -prune=550 \
  -validationapi=real \
  -rpcuser=user1 -rpcpassword=change-me \
  -daemon

Delegate the full/model check over HTTPS with -validationapi=desktop — it keeps quick/smell local and sends full/model to a verifier you point it at. This is the light path: no GPU needed on your box.

bitcoind -tensortest -prune=550 \
  -validationapi=desktop \
  -validatorhttpurl=https://verify.example.org \
  -validatorapikey=change-me \
  -daemon
# Replace verify.example.org with your verifier's URL.

Without -validatorhttpurl, desktop mode uses the public endpoint https://verify.tensorcash.org; that's also what the packaged TensorCash Core builds ship in their default config. The API key is optional: without one the node reads verdicts from the verifier's public, read-only status lookup, and only authenticated submission needs a key. Several verifiers can be listed (VALIDATOR_HTTP_URLS, with -validatorapikeys). For an https:// verifier the node needs a CA trust store and refuses to start without one; point -validatorcafile=<pem> at a bundle if the system store isn't found.

(Pruning is incompatible with -txindex. For a full transaction index, run archival.)

Docker (the provided stacks)

The repo's docker-compose stacks are operator tooling rather than a one-line quickstart: they run the node alongside a verifier (and, in the full variant, a miner), so they expect a GPU and the model. A few things to know before reaching for them:

  • Chain and prune live in a bitcoin.conf mounted at the data dir, not on the compose command. The testnet stack ships a bitcoin.tensor-test.conf (chain + ports only) and a run_tensor_testnet.sh helper that stages it into your data dir — but it sets no pruning, so add a prune=550 line to that conf yourself for a pruned node.
  • OPERATOR_API_KEY is required — in core-validation-api/ the verifier's operator interface binds beyond loopback, and it exits at startup without a key — and the verifier is keyed by VERIFY_SHARED_API_KEY (setting VALIDATOR_API_KEY directly has no effect; the compose derives it).
  • Set VALIDATOR_SHARED_SECRET when the node talks to the verifier over ZMQ (--desktop): copy .env.example to .env and fill in $(openssl rand -hex 32). Without it the two containers refuse to exchange verdicts.
  • The launch wrapper's mode comes from NODE_START_FLAGS. --http (the default in core-validation-api/) sends the full check to VALIDATOR_BASE_URL, there the stack's own gateway; --desktop uses the local engine over ZMQ.
  • The core-node image autostarts a mining supervisor. It's gated by a MINING_AUTOSTART env that the base compose files don't expose, so silencing it takes a compose override, not a shell variable — plan on editing the stack if you want a node that never touches mining.

Because of all that, for a plain node the from-source path above is the simpler, pasteable one — especially a light, delegating node, which needs no GPU. Reach for the compose stacks (deployments/docker-compose/core-validation-api/ for node

  • your own verifier, core-miner-validation-api/ for node + verifier + miner) when you specifically want the bundled topology; the run_tensor_testnet.sh helper that ships with the latter is the supported way to bring the testnet stack up.

Step 4: Is it synced — and verifying?

Three checks, in order:

# 1. The chain is catching up to the tip.
bitcoin-cli -tensortest getblockchaininfo | grep -E 'blocks|headers|pruned|size_on_disk'

# 2. ModelDB is tracking the chain — a model query answers.
bitcoin-cli -tensortest getmodelslist                  # registered models (hash + name)
bitcoin-cli -tensortest getmodelinfo <model_hash>      # one model's full record

# 3. The verifier is wired. In the node's debug log you'll see either the local
#    verifier starting, or the node reaching the delegated endpoint.
bitcoin-cli -tensortest -getinfo            # or: tail the debug.log / `docker compose logs -f`

When blocks reaches headers you're at the tip. From then on, every new block your node accepts has had its signatures, its proof-of-work, and its model-execution proof checked — by you, if you verify locally.

Use the node

A synced node is a real Bitcoin-style RPC endpoint plus the TensorCash surfaces:

  • Wallet & assets — createwallet, getnewaddress, and the asset RPCs (mintasset, sendasset). TensorCash Core, the GUI over this same node, is its own walkthrough: How to run the wallet.
  • Mine against your own node — a sovereign miner takes jobs from your node instead of a provider's broker, and verifies on your verifier. That's the "full sovereignty" path in How to mine: WORKER_MODE=standalone pointed at this node, with --desktop doing the checks.

Where to go next

A full node here checks one thing nobody else's can: that the work behind the block was real.