/docs / regtest
Regtest guide
Three local-development paths, ordered by friction. Each one drops you in
front of a TensorCash JSON-RPC you can poke with bitcoin-cli
or any JSON-RPC client. The bcore functional test suite
is the canonical, executable spec for everything below — every walkthrough
on this page links the test it was distilled from.
bcore-only · docker-compose · functional tests
Validation modes
TensorCash inserts an external-validation step into block acceptance.
Which backend services that step is selected by -validationapi
and is the single most important decision for a local run — it determines
whether you need a GPU, a verifier process, or neither.
| Flag | What it is | When to use |
|---|---|---|
| -validationapi=real | Default. Talks to an external verifier over the bcore↔verifier ZMQ PUSH/PULL channel using FlatBuffers. Production setting. | Real verifier process required (see /docs/verifier/api/). Used in mainnet, testnet, and any regtest run that exercises actual model-replay logic. |
| -validationapi=mock | In-process, deterministic. The mock backend exposes three RPCs (validationmockdefault / validationmockclear / validationmockrequests) for canning Quick / Full / Model responses; combined with -mockval-default-* startup flags it makes every verification outcome scriptable. | The default mode for the functional test suite. Right choice for any walkthrough that wants to drive the chain logic without standing up a verifier or running real inference. |
| -validationapi=desktop | Hybrid. Quick checks run in-process; Full and Model are dispatched to a local HTTPS verifier (the default desktop binary). No ZMQ broker required. | Single-machine demos where you want a real Quick/Smell pass but do not want to operate a separate verifier service. |
For a first contact with the chain logic, mock
is the right answer — the rest of this page assumes it unless stated.
Path A · bcore-only with mock validation
Lowest friction. A single C++ daemon, no docker, no GPU, no model artefacts on disk. Suitable for any walkthrough on this page.
1 — Build the daemon
Follow the upstream Bitcoin Core build instructions
against services/core-node/bcore/. The
TensorCash-specific code paths build under the same CMake target as
upstream — there is no separate flag.
2 — Start a regtest node
The flag set below mirrors what test_framework/test_tensorcash.py
passes to every functional test, so anything that runs there will run
here too. Default mock responses are pinned to green so block acceptance
is deterministic.
./bitcoind \
-datadir=$HOME/.tensorcash-regtest \
-regtest \
-vdfspvcommitmentheight=0 \
-vdfspvvdfverifyheight=0 \
-maxtipage=999999 \
-spv-asn-min=1 \
-spv-hysteresis-base-bps=0 \
-spv-reorg-sampling-threshold=999 \
-useextapi=0 \
-par=1 \
-debug=net -debug=validation \
-validationapi=mock \
-mockval-force-external=1 \
-mockval-default-quick=quick_ok_smell_ok \
-mockval-default-full=full_green \
-mockval-default-model=model_ok \
-daemon 3 — Talk to it
Authentication is via the cookie file at
$HOME/.tensorcash-regtest/regtest/.cookie;
bitcoin-cli reads it automatically when you
pass -datadir. RPC port is the upstream
regtest default 18443.
alias bcli='bitcoin-cli -regtest -datadir=$HOME/.tensorcash-regtest'
bcli getblockchaininfo | jq '{chain, blocks, verificationprogress}' Path B · full local stack (docker compose)
When you want a real verifier process, a real model serving inference, and the miner-api wired in — i.e. when mock is not enough. There are wrapper scripts in the repo root for both Macs and Linux+CUDA hosts.
On Apple silicon the launcher pulls a llama.cpp build and stands up the
full core-node + miner-api + verification-api
compose stack:
export GITHUB_TOKEN="ghp_..."
export MODEL_FILE="$HOME/models/Qwen_Qwen3_8B.gguf"
./launch_macbook.sh
# brings up: core-node (RPC 18443, REST 8050) + miner-api + verification-api
On Linux + NVIDIA the equivalent is launch_linux.sh,
which boots the vLLM-based verifier instead of llama.cpp:
export API_KEY=super-secret-token
export MODEL_API_KEY=super-secret-token
sudo ./launch_linux.sh
# uses deployments/docker-compose/core-miner-validation-api/docker-compose.yaml
The compose file binds host ports 8333
(P2P), 8050 (core-node REST,
see /docs/core-node/api/),
and 7067 (ZMQ). The verifier exposes its
REST surface (/docs/verifier/api/)
on its own container port.
Path C · run the functional test suite
Once the daemon is built (Path A, step 1), the test runner brings up ephemeral nodes for you. Useful when you want a known-good sequence to crib from rather than a daemon to poke at.
cd services/core-node/bcore
# Single test
build/test/functional/test_runner.py feature_model_registration.py
# All TensorCash-specific tests
build/test/functional/test_runner.py 'feature_model_*' 'feature_asset*' 'feature_fairsign_*'
# All tests, parallelised
build/test/functional/test_runner.py --jobs=$(nproc) The TensorCash-specific tests group cleanly by surface — model lifecycle, native assets, fair-sign adaptors, covenant repo wallet. Each one is a self-contained scenario you can read top-to-bottom; the model-registration and asset-registration walkthroughs below point at the most representative ones.
Walkthroughs
Three short sequences against the bcore-only mock node from Path A. Each one is a sketch — the linked functional test is the full, executable scenario.
Mine your first block
Canonical test: wallet_basic.py
This is unchanged from upstream Bitcoin Core. Useful as a smoke test before any TensorCash-specific surface — confirms your daemon is up and the wallet is funded.
Touches: createwallet , getnewaddress , generatetoaddress , getbalance
# bitcoin-cli speaks to the regtest daemon over the cookie file.
ALIAS="bitcoin-cli -regtest -datadir=$HOME/.tensorcash-regtest"
$ALIAS createwallet sandbox
ADDR=$($ALIAS -rpcwallet=sandbox getnewaddress)
$ALIAS -rpcwallet=sandbox generatetoaddress 101 "$ADDR"
$ALIAS -rpcwallet=sandbox getbalance
# 50.00000000 (block 1's coinbase, mature after 100 confirmations) Register a model end-to-end
Canonical test: feature_model_registration.py
TensorCash-specific. A model is registered by escrowing a deposit, accumulating successful Quick + Model verifications across N commits, then transitioning to `registered` once the verification window closes. With `-validationapi=mock` you can drive every step from RPCs without a real verifier or GPU. Outline only — the linked functional test is the full scenario.
Touches: validationmockdefault , createmodeldeposit , createmodelcommit , getmodelstatus , generatetoaddress
# Pin every mock rung to the green response.
$ALIAS validationmockdefault quick quick_ok_smell_ok
$ALIAS validationmockdefault model model_ok
$ALIAS validationmockdefault full full_green
# Lay down 101 spendable coinbase outputs.
$ALIAS -rpcwallet=sandbox generatetoaddress 101 "$ADDR"
# 1. Escrow the deposit (1_000_000 sats == 0.01 BTC).
DEPOSIT=$($ALIAS -rpcwallet=sandbox createmodeldeposit \
tensor/registration-success success-commit 1000000)
TXID=$(echo "$DEPOSIT" | jq -r .txid)
VOUT=$(echo "$DEPOSIT" | jq -r .deposit_vout)
HASH=$(echo "$DEPOSIT" | jq -r .model_hash)
$ALIAS -rpcwallet=sandbox generatetoaddress 1 "$ADDR"
# 2. Accumulate 50 commits — feature_model_registration.py shows the funding
# plumbing in detail. Then mine to the verification window's close height.
# 3. Poll status.
$ALIAS getmodelstatus "$HASH"
# {"status": "registered", "verification_code": 0, ...} Issue a native asset
Canonical test: feature_assets_basic_highlevel.py
TensorCash-specific. `registerasset` is the high-level wallet RPC that constructs the bond + ICU outputs, attaches the issuer registration TLV and broadcasts. After one confirmation the asset is queryable by id or ticker. The full lifecycle (mint, transfer, burn) lives in the linked test.
Touches: registerasset , getassetpolicy , getassetbyticker , getassetbalance
ADDR=$($ALIAS -rpcwallet=sandbox getnewaddress)
ASSET_ID=$(printf 'my-first-asset' | shasum -a 256 | cut -d' ' -f1)
$ALIAS -rpcwallet=sandbox registerasset \
"$ADDR" `# ICU address` \
5.1 `# bond (BTC)` \
"$ASSET_ID" `# 32-byte asset id` \
3 `# policy bits: MINT | BURN` \
28 `# allowed families: P2WPKH | P2WSH | P2TR` \
510000000 `# unlock fees (sats)` \
TST `# ticker` \
8 `# decimals` \
'{"autofund":true,"broadcast":true,"fee_rate":10}'
$ALIAS -rpcwallet=sandbox generatetoaddress 1 "$ADDR"
$ALIAS getassetpolicy "$ASSET_ID"
$ALIAS getassetbyticker TST Flag reference
These are the flags Path A passes that diverge from a vanilla
bitcoind -regtest session. Source of truth:
test_framework/test_tensorcash.py and
init.cpp.
| Flag | Why it matters in regtest |
|---|---|
| -regtest | Selects the regtest chain (block subsidy, immediate maturity rules and the local-only port set 18443/18444). |
| -vdfspvcommitmentheight=0 | Activates VDF/SPV from genesis instead of the staged mainnet height. |
| -vdfspvvdfverifyheight=0 | Activates VDF verification from genesis. |
| -maxtipage=999999 | Accepts old timestamps so a stale chain state restart does not look like an unsynced node. |
| -spv-asn-min=1 | Lowers the ASN-corroboration floor; without this regtest blocks the VDF SPV switching logic. |
| -spv-hysteresis-base-bps=0 | Removes the base-margin hysteresis so chain reorgs in tests are immediate and deterministic. |
| -spv-reorg-sampling-threshold=999 | Effectively disables deep-reorg body sampling, which is impractical to drive at small heights. |
| -useextapi=0 | Disables the external miner-API; not needed for chain-only walkthroughs and shaves seconds off startup. |
| -debug=net,validation | Surfaces the most useful log lines for a regtest session (network and validation pipeline). |
| -par=1 | Single-threaded validation. Removes a class of test-only flakiness without affecting correctness. |
Where next
- /docs/rpc/ — full method index. 377 RPCs, organised by bucket; each method page carries stability tags and curl examples.
- /docs/verifier/api/
— once you graduate from
-validationapi=mockto a real verifier process. - /docs/schemas/ — FlatBuffer IDL + JSON Schema for the bcore↔verifier ZMQ payloads.
- bcore/test/functional/ — read tests as spec.