This project is the codebase for the Tau Testnet Alpha Blockchain. Its primary goal is to provide a live, working demonstration of a blockchain where core state transitions and rules are governed by Tau's formal logic. The architecture is designed around the principle of extralogical processing. The core engine, written in Python, handles networking, storage, and any operations not yet implemented in pure Tau logic, such as cryptographic signature verification. This engine prepares transactions and validates them against a separate Tau logic program (executed either via Docker or direct native bindings), which serves as the ultimate arbiter of the chain's rules. This hybrid model allows us to build a robust and feature-complete testnet today, showcasing the power of Tau's logical core while providing all the necessary functions for a working blockchain.
Tau logic is fully integrated into the blockchain pipeline, but runtime evaluation is currently disabled by default through the TAU_FORCE_TEST switch. When this flag is enabled, the node bypasses real Tau logic execution and uses a deterministic "test" validator path instead. This allows development and debugging without requiring a running Tau Docker instance. To enable true Tau-driven validation, unset TAU_FORCE_TEST in your environment or configuration.
For improved performance and simplified deployment, you can bypass the Docker container and interact directly with the local native Tau library (libtau via tau_native.py).
To enable this mode, set TAU_USE_DIRECT_BINDINGS=1 in your environment or .env file. This mode requires the tau native python extension to be available in your PYTHONPATH or properly installed.
When enabled, the system maintains a single tau::interpreter instance and captures state updates directly from the engine's stdout.
- TCP Server: Handles client connections and commands.
- P2P Networking (libp2p shim):
- Protocols (all implemented on the libp2p shim):
TAU_PROTOCOL_HANDSHAKE(/tau/handshake/1.0.0): Exchange node info and current tip.TAU_PROTOCOL_PING(/tau/ping/1.0.0): Latency/keepalive round-trip with a nonce.TAU_PROTOCOL_SYNC(/tau/sync/1.0.0): Header/tip synchronization with locator/stop/limit semantics.TAU_PROTOCOL_BLOCKS(/tau/blocks/1.0.0): Serve block bodies by hash list or by range (from/from_number+limit).TAU_PROTOCOL_STATE(/tau/state/1.0.0): Fetch the latest known block metadata alongside requested account/receipt data.TAU_PROTOCOL_TX(/tau/tx/1.0.0): Compatibility channel for submitting transactions, which queues locally and re-broadcasts over gossipsub.TAU_PROTOCOL_GOSSIP(/tau/gossip/1.0.0): Gossipsub-style transport used for topic-based dissemination.
- Gossip topics:
tau/blocks/1.0.0: Propagates new headers/tip summaries prior to full sync.tau/transactions/1.0.0: Propagates canonical, signed transactions across the mesh.
- Bootstrapping connects to peers, performs handshake + sync, fetches missing blocks, rebuilds state, and replays gossip subscriptions so the node immediately participates in block/transaction mesh traffic.
- Tip semantics: Block numbers are 0-indexed. A node with no persisted blocks may still report
head_number: 0withhead_hashset to thegenesis_hashsentinel. A node with exactly one block (block#0) will also reporthead_number: 0, but withhead_hashequal to that block hash. Sync decisions must considerhead_hash(not justhead_number). - Verbose debug logging traces requests/responses and bootstrap progress for easier development.
- Protocols (all implemented on the libp2p shim):
- Persistent Blockchain & Fork Choice:
- Creates blocks from transactions stored in the mempool.
- Links blocks together in a chain by referencing the previous block's hash.
- Persists the entire chain of blocks to a SQLite database, tracking multiple competing tips and forks.
- Evaluates the heaviest valid branch using a robust, fork-choice algorithm based on highest-block-height with deterministic tie-breaking.
- Performs chain reorganizations ("reorgs") seamlessly, reverting and re-applying transactions and state when the main chain tips to a different path log.
- Tau-Driven Pluggable Consensus Architecture:
- The node's consensus policy (who can propose blocks, what makes a block valid) is governed entirely by living Tau rules (
consensus_rules). - The Python host orchestrates state storage and cryptographic checks, while Tau evaluates the block against the active rules to emit
o6 = 1for validity. - Governance is fully on-chain. Active validators can submit
consensus_rule_updateandconsensus_rule_votetransactions to dynamically mutate the chain's consensus rules with built-in activation delays.
- The node's consensus policy (who can propose blocks, what makes a block valid) is governed entirely by living Tau rules (
- Authenticated Transactions via BLS Signatures:
- Transactions are cryptographically signed using BLS12-381 signatures.
- The server verifies the signature against the
sender_pubkeyand a canonical representation of the transaction data. - Requires
py_ecc.blsfor signature verification.
- Replay Protection with Sequence Numbers:
- Each account (
sender_pubkey) has a sequence number managed bychain_state.py. - Transactions must include the correct sequence number, which is incremented upon successful validation.
- Each account (
- Transaction Expiration:
- Transactions include an
expiration_time(Unix timestamp) after which they are considered invalid.
- Transactions include an
- Typed JSON Transaction Structure:
- The
sendtxcommand now expects typed JSON transactions parameterized bytx_type:tx_type="user_tx": Standard application payload supporting customoperationsand rules.tx_type="consensus_rule_update": A governance transaction containingrule_revisionsand anactivate_at_heightinteger.tx_type="consensus_rule_vote": A vote referencing a pendingupdate_idto approve a rule change.
- Common fields across all types include
sender_pubkey,sequence_number,expiration_time,fee_limit, and a BLSsignaturesecuring the payload.
- The
- Tau Integration for Operation Validation: The
genesis.tauprogram validates the logic of operations within a transaction (e.g., coin transfers via Tau bitvectors). This now includes robust structural validation to ensure transfer data is complete and well-formed. - String-to-ID Mapping: Dynamically assigns
y<ID>identifiers for Tau payloads. - In-Memory Balances & Sequence Numbers: Tracks account balances and sequence numbers for rapid validation.
- SQLite Mempool: Persists transactions awaiting inclusion in a block.
- BLS12-381 Public Key Validation: Format and optional cryptographic checks for public keys.
- Strict Execution Validation: Transactions that are structurally valid but fail during execution (e.g., Tau errors, insufficient funds) are accepted into the block (consuming the nonce) but marked with a "failed" status in the receipt.
The libp2p-based DHT layer now exposes several runtime knobs through NetworkConfig:
| Option | Default | Purpose |
|---|---|---|
dht_refresh_interval |
60.0 |
Seconds between background calls to KadDHT.refresh_routing_table. |
dht_bucket_refresh_interval |
dht_refresh_interval |
Interval for opportunistic stale peer refresh/eviction. |
dht_bucket_refresh_limit |
8 |
Maximum stale peers revalidated per cycle. |
dht_stale_peer_threshold |
3600.0 |
Age (seconds) before a peer is considered stale. |
dht_opportunistic_cooldown |
120.0 |
Minimum time between reseeding the same peer discovered via gossip/handshake. |
gossip_health_window |
120.0 |
Sliding window used by get_metrics_snapshot() to flag gossip as healthy/stale. |
Call NetworkService.get_metrics_snapshot() (or read the periodic [metrics] log line) to monitor gossip activity, routing table counts, and bucket refresh results.
- Python 3.8+
- Docker
- A Tau Docker image (default:
tau, configurable inconfig.py). py_ecc(specificallypy_ecc.bls): Required for BLS public key validation and transaction signature verification.
-
Clone the Repository:
git clone <repository_url> cd <repository_directory>
-
Set up Python Environment (Recommended):
python3 -m venv venv source venv/bin/activate pip install py_ecc -
Ensure
genesis.tauis Present: Place yourgenesis.taufile in the location specified byconfig.TAU_PROGRAM_FILE(defaults to the project root). -
Ensure Tau Docker Image: Make sure the Docker image specified in
config.TAU_DOCKER_IMAGE(default:tau) is available. -
Run the Server:
python server.py
The server will initialize the database and manage the Tau Docker process.
This repository now includes a standalone container build that embeds both:
- the Tau Testnet node (
server.py) - the Tau language engine (compiled from
tau-langwith Python nanobind bindings)
The container defaults to native bindings mode (TAU_USE_DIRECT_BINDINGS=1), so it does not require Docker-in-Docker.
-
Build the standalone image:
docker build -f Dockerfile.standalone -t tau-testnet-standalone . -
Run a single standalone node:
docker run --rm -it \ -p 65432:65432 -p 65433:65433 -p 4001:4001 \ -v "$(pwd)/data:/data" \ tau-testnet-standaloneImportant: without the
-pmappings, the node will only be reachable from inside the container network.Or use the helper script (publishes required ports by default):
./scripts/run_standalone_node.sh
-
Or run with Compose:
docker compose -f docker-compose.standalone.yml up --build
Useful runtime toggles:
TAU_MINING_ENABLED=trueto enable local PoA mining.TAU_BOOTSTRAP_PEERS='[]'to keep the node isolated.TAU_BOOTSTRAP_PEERS='[{"peer_id":"...","addrs":["/ip4/X.X.X.X/tcp/4001"]}]'to connect to peers.
Use this routine when you want the latest tau-testnet code and a fresh tau-lang build:
-
Update
tau-testnet:git fetch origin git checkout main git pull --ff-only
-
Resolve the latest
tau-langmain commit (or replace withmain/ a tag):TAU_LANG_REF=$(git ls-remote https://github.com/IDNI/tau-lang.git refs/heads/main | awk '{print $1}') -
Rebuild:
docker build --pull \ -f Dockerfile.standalone \ --build-arg TAU_LANG_REF="$TAU_LANG_REF" \ --build-arg TAU_BUILD_JOBS=4 \ -t tau-testnet-standalone:latest .
Notes:
TAU_LANG_REFsupports branch, tag, or commit SHA.- Keep
TAU_BUILD_JOBSpositive (do not use0for dependency build steps). - Mount only persistent node data to
/data(for example-v "$(pwd)/data:/data"), not the whole repository.
- Optional: Configure Bootstrap Peers
Edit
config.pyto point at one or more peers to sync from:On start, the node will connect, handshake, sync headers, request missing block bodies, and rebuild its state.BOOTSTRAP_PEERS = [ { "peer_id": "<REMOTE_NODE_ID>", "addrs": ["/ip4/127.0.0.1/tcp/12345"] }, ]
This runs an isolated PoA miner in the standalone container and persists state in ./data.
-
Build image (if needed):
docker build -f Dockerfile.standalone -t tau-testnet-standalone . -
Start miner with test networking (no bootstrap peers):
docker run --rm -it \ -p 65432:65432 -p 65433:65433 -p 4001:4001 \ -v "$(pwd)/data:/data" \ -e TAU_ENV=test \ -e TAU_BOOTSTRAP_PEERS='[]' \ -e TAU_NETWORK_LISTEN='/ip4/0.0.0.0/tcp/4001' \ -e TAU_MINING_ENABLED=true \ tau-testnet-standalone
-
Miner keys behavior:
- If
/data/test_miner.keyand/data/test_miner.pubare missing, the container entrypoint generates them automatically on first start. - Because
/datais mounted from./data, keys and DB persist across restarts. - Optional manual key generation on host:
python scripts/generate_miner_keys.py mkdir -p data mv test_miner.key test_miner.pub data/
- If
This runs as a follower node that syncs from testnet.tau.net. Mining stays off unless you explicitly configure a miner key.
python server.pyOptional safety (explicitly disable mining on followers):
TAU_MINING_ENABLED=false python server.pyThis project uses Trio for async tests. Recommended invocation (Trio-only, disable asyncio plugin):
./venv/bin/python3 -m pytest -p no:asyncioTo bypass Tau Docker during tests/dev, set TAU_FORCE_TEST=1 (see Tau Execution Mode above).
Use any TCP client, e.g., netcat:
netcat 127.0.0.1 65432server.py: The main TCP server application.tau_manager.py: Manages the Tau Docker process lifecycle and communication.commands/: Modules for handling client commands:sendtx.py: Handles submission and validation of complex transactions (including signature checks, sequence numbers, and Tau logic for operations).getmempool.py: Retrieves mempool content.createblock.py: Creates new blocks from mempool transactions.
db.py: SQLite database interface, managing the mempool, string-to-ID mappings, and persistent block storage.network/: P2P protocols and service implementation (handshake,ping,sync,blocks,tx).chain_state.py: Manages in-memory state (account balances, sequence numbers).tau_defs.py: Tau stream constants for validator interaction.utils.py: Utilities for Tau bitvectors, data conversions, and transaction message canonicalization.config.py: Centralized configuration.block.py: Defines block data structures (block header, transactions list) and merkle root computation.genesis.tau: The Tau logic program for validating operations, including structural checks on transaction data and logic for applying new rules via pointwise revision.wallet.py: Command-line wallet interface for interacting with the Tau node (seeWALLET_USAGE.mdfor comprehensive usage guide).rules/: Directory containing Tau rule files:01_handle_insufficient_funds.tau: Logic for handling insufficient fund scenarios.
tests/: Directory containing unit tests:test_sendtx_basic.py: Basic transaction functionality tests.test_sendtx_validation.py: Transaction validation logic tests.test_sendtx_tx_meta.py: Transaction metadata handling tests.test_sendtx_crypto.py: Cryptographic signature verification tests.test_sendtx_sequential.py: Sequential multi-operation transaction tests.test_tau_logic.py: Tests all logic paths and validation rules directly withingenesis.tau.test_chain_state.py: Tests balance and sequence number management.test_block.py: Tests the block data structure and the persistent block creation/chaining logic.test_persistent_chain_state.py: Tests for persistent chain state management (currently skipped).test_state_reconstruction.py: Tests for state reconstruction from blockchain data.test_p2p.py: Connectivity and custom protocol round-trip using libp2p shim.test_network_protocols.py: End-to-end tests for Tau protocols (handshake, ping, sync, blocks, state, tx, gossip). Coverage includes header sync, transaction gossip, subscription handling, DHT routing-table refresh, gossip health metrics, opportunistic peer seeding, and multi-hop gossip propagation driven solely by KadDHT lookups.
A comprehensive command-line wallet wallet.py is provided to interact with the Tau node. It supports generating a new keypair, sending complex multi-operation transactions (including rules, transfers, and custom operations), querying balances, and listing transaction history. For detailed usage instructions, see WALLET_USAGE.md.
Requires py_ecc for BLS operations (install with pip install py_ecc).
# Generate a new keypair
python wallet.py new
# Query balance (by private key or address)
python wallet.py balance --privkey <hex_privkey>
python wallet.py balance --address <pubkey_hex>
# List transaction history
python wallet.py history --privkey <hex_privkey>
python wallet.py history --address <pubkey_hex>
# Send a simple transaction
python wallet.py send --privkey <hex_privkey> --to <recipient_pubkey_hex> --amount <amount> [--fee <fee_limit>] [--expiry <seconds>]
# Send a transaction with rules
python wallet.py send --privkey <hex_privkey> --rule "o2[t]=i1[t]" --transfer "recipient:amount"
# Send multi-operation transaction
python wallet.py send --privkey <hex_privkey> --rule "rule_formula" --transfer "addr:amt" --operation "2:custom_data"-
Send Transaction (New Structure):
sendtx '{ "sender_pubkey": "a63b...ea73", "sequence_number": 0, "expiration_time": 1700000000, "operations": { "1": [["a63b...ea73", "000a...000a", "10"]] }, "fee_limit": "0", "signature": "HEX_SIGNATURE_OVER_OTHER_FIELDS" }'- Replace placeholders with actual values.
- The client is responsible for creating the canonical message, hashing it, signing the hash, and providing the hex-encoded signature.
-
Get Mempool:
getmempool -
Create Block:
createblock
A block is a fundamental data structure that organizes transactions into an atomic unit for chain progression. Each block consists of:
- A block header containing:
block_number(integer): Height of the block in the chain.previous_hash(string): Hex-encoded SHA256 hash of the previous block's header.timestamp(integer): Unix timestamp when the block was created.merkle_root(string): Hex-encoded Merkle root of the included transactions.state_hash(string): Hex-encoded hash of the current Tau/rules snapshot (used to bind state to a block).state_locator(string): A namespaced lookup key (e.g.state:<hash>) for DHT/state distribution.
- A block body containing:
transactions(list): Ordered list of transactions (user_tx,consensus_rule_update, orconsensus_rule_vote).tx_ids(list): Transaction hashes used to build the Merkle root.
- Consensus fields:
consensus_proof(string): Proof/signature verified against the active rules. Replaces legacyblock_signature.
Blocks do not include proof-of-work. Block validity and proposer eligibility are governed strictly by the living Tau consensus logic program evaluated dynamically at each height.
The block.py module provides the Block and BlockHeader classes, along with utility functions for computing transaction hashes (compute_tx_hash), Merkle roots (compute_merkle_root), and block hashes.
- The fee model (
fee_limit) is a placeholder and not yet enforced. - Gossipsub topics (
tau/blocks/1.0.0,tau/transactions/1.0.0) must be subscribed to by peers that expect block or transaction updates.
Please submit issues at the following link: Tau Testnet issues
Alpha: This is an early alpha version. It's under active development and is intended for testing and experimentation. The core engine for a functional blockchain is in place, including transaction validation, mempool management, and persistent block creation.
- Expansion of Tau logic.
- Multi-authority PoA (validator set, rotation) and stronger fork-choice/finality rules.
- More robust error handling and reporting.
- More comprehensive unit and integration tests.
