Protocol documentationSource snapshot: 0.1.0 alphaNetwork: testnet / devnet

Engineering

Testing & interoperability

Test layers, canonical vectors, cross-language conformance, negative consensus cases, P2P and API contract testing, release checks, and disciplined protocol evolution.

Engineering guide · executable specificationReviewed August 31, 2026
Specification status

This page documents the implemented alpha. Executable source, interoperability vectors, and tests remain authoritative if prose and code ever diverge.

What counts as protocol evidence

Luracoin’s specification has three layers, in descending order of executable authority:

  1. canonical serialization and validation code;
  2. shared vectors and boundary/negative tests;
  3. human documentation.

Documentation is centralized here for humans, but compatibility must be demonstrated with bytes and rejection behavior. If prose, fixtures, and implementation differ, treat that as a release-blocking defect—not permission to choose whichever result is convenient.

Test environments

Reference runtimes:

Python node   >=3.10,<3.13
Wallet/site   Node >=22.22.2
Redis         reachable, isolated test database where integration tests require it

The Python package pins development-tool ranges in pyproject.toml; the JavaScript packages carry lockfiles. CI and local reproduction should install from those project manifests rather than globally guessed versions.

Standard checks

Python:

cd luracoin-python
uv sync --extra dev
uv run pytest
uv run flake8 luracoin tests
uv run mypy luracoin

Wallet:

cd luracoin-wallet
npm ci
npm run check

Website:

cd luracoin-website
npm ci
npm run check
npm run build
npm run test:e2e

Run the repository’s release checklist for an actual release. A targeted test during development does not replace the full suite for consensus or signing changes.

Shared transaction vector

vectors.json defines a public testnet transaction fixture shared by Python and JavaScript. Stable outputs include:

chain ID              1
private key byte       0x1f repeated 32 times (test only)
from address           Lhic4rh3bPnjFMzReaoJDm291Sz23ZUmcu
unsigned length        85 bytes
public key raw length  64 bytes
signature length       64 bytes
unlock field length   128 bytes
complete length       213 bytes
transaction ID         2712bfd829c397e9fb32188bf705987115b1a2d180aac80ba28a2aa6edcbb9b6

The file also fixes the exact unsigned hex, single-SHA256 signing digest, raw x || y key, compact low-S r || s, unlocking field, and complete transaction hex.

This private key is intentionally public and must never fund anything of value. Test vectors are for deterministic conformance, not wallet examples.

Genesis vectors

The same vector file fixes educational genesis identity:

Network Chain ID PoW nonce Block ID
testnet 1 14,121,310 0000009e2bcc8e56cee8b5e0fbdac9edc04513542af5c5791ea6165179c468bf
devnet 2 11,943,016 00000033e4111007fd85423c7a527595e8efefe158a1250db62a32870857ef91

Initialization tests should reconstruct the canonical objects and verify these IDs, not simply insert the strings into local state.

Cross-language transaction conformance

Python and JavaScript must independently produce identical values for:

  1. mnemonic-to-seed behavior with BIP39 passphrase LURA;
  2. BIP32 root private/public key;
  3. compressed public key for address derivation;
  4. HASH160 and Base58Check address;
  5. unsigned field bounds and exact 85-byte order;
  6. SHA-256 signing digest;
  7. deterministic secp256k1 signature;
  8. low-S normalization;
  9. raw 64-byte public key and compact signature;
  10. exact 213-byte transaction;
  11. double-SHA256 transaction ID.

A JSON-level match is insufficient. Compare bytes at every stage so an endianness or encoding error is localized.

Negative signature suite

Acceptance tests need corresponding rejections:

  • zero, negative-equivalent, or out-of-range r/s;
  • high-S counterpart of an otherwise valid signature;
  • DER signature where compact form is required;
  • compressed key in the 64-byte raw-key slot;
  • uncompressed SEC prefix included accidentally;
  • public key not on secp256k1;
  • public key whose derived address differs from sender;
  • signature over JSON, hex text, txid, or double-SHA256 instead of the unsigned bytes;
  • one-bit changes in every signed field;
  • short, long, or trailing unlocking data.

The goal is canonical acceptance, not merely successful library verification.

Transaction state suite

Cover:

  • exact minimum/maximum integer bounds;
  • zero value rejection and zero fee acceptance;
  • wrong chain ID;
  • invalid zero destination sentinel;
  • absent sender and insufficient balance;
  • next nonce, replayed nonce, skipped nonce, and uint32 boundary;
  • self-transfer net fee behavior;
  • receiver uint64 overflow;
  • contiguous multi-transaction sequence;
  • Redis missing payload/reservation inconsistency;
  • atomic same-slot races and exact idempotent retry;
  • confirmation of a different transaction in the same sender/nonce slot;
  • Redis outage failure semantics.

Tests should assert both return/error and resulting accounts/Redis keys. A rejection that leaves a reservation behind is still a bug.

Block conformance suite

Byte tests should fix:

  • exact 118-byte transmitted header;
  • declared-ID offset and omission from the hash preimage;
  • transaction count insertion as little-endian uint16;
  • big-endian timestamp amid little-endian numeric fields;
  • ordered transaction commitment;
  • exact size formula and every schedule boundary;
  • trailing/unaligned/empty body rejection.

Context tests should cover:

  • wrong height, predecessor, bits, proof, or version;
  • ID exactly equal to target;
  • missing difficulty history;
  • timestamp equal to predecessor, +1, +500 future, and +501 future;
  • missing, duplicate, misplaced, underpaying, and overpaying coinbase;
  • coinbase nonce/miner/unlocking sentinel mismatch;
  • duplicate transaction IDs;
  • normal transaction spending earlier receipt;
  • forbidden same-block spend of current coinbase;
  • state overflow and all-or-nothing publication;
  • stale mined template rejection.

Difficulty and emission suite

Test compact expansion/encoding as its own consensus codec. Include exponents below/at/above three, zero, >256-bit expansion, precision truncation, maximum target, and normalization.

Retarget fixtures need exact 480-block boundaries, both 4× clamps, values just inside/outside clamps, integer-floor cases, and absent history.

Reward fixtures need height zero manifest behavior, each 259,200-block era boundary, odd lurashi truncation, and the permanent one-LURA floor.

P2P protocol suite

For every command, test:

  • exact 12-byte command encoding;
  • correct payload and empty-payload checksum;
  • wrong magic/checksum/length;
  • partial header/body reads;
  • global maximum and command-specific off-by-one values;
  • unknown command and unknown inventory type;
  • malformed count/length relationships;
  • v1 14-byte versus v2 18-byte handshake;
  • wrong protocol/chain/port and handshake order;
  • post-handshake version/verack rejection;
  • interleaved frames under a single dispatcher;
  • concurrent send serialization and timeout cleanup.

Use real asyncio stream behavior in addition to unit mocks for framing-sensitive cases.

Synchronization and relay suite

Model honest, slow, silent, malformed, behind, height-lying, and disconnecting peers. Verify:

  • one active sync peer;
  • highest eligible advertised height selection;
  • batches no larger than 50;
  • strict next-height application;
  • timeout and zero-progress failure;
  • exponential host-based cooldown and cap;
  • successful cooldown reset;
  • best-peer failover;
  • readiness transitions across task start/finish races;
  • inventory-cache bounds and loop suppression;
  • relay concurrency and partial success counts;
  • 1,000-item backlog eviction, 100-item slices, and five-second budget;
  • sender/nonce conflict pruning after a received block.

Explicitly test that equal heights with different tips do not magically converge; this documents the current limitation.

Persistence suite

Create temporary isolated data directories and verify:

  • record prefix and exact location encoding;
  • file rotation at 128 MiB boundaries without splitting a block;
  • length-prefix/index disagreement failure;
  • truncated record failure;
  • concurrent read versus append lock behavior;
  • adjacent append-before-index recovery at both possible positions;
  • conflict fails closed;
  • four-byte early-v2 location upgrade and batching;
  • unknown location versions/sizes rejection;
  • no cross-network state reuse;
  • idempotent re-opening of initialized genesis.

Crash tests should inspect on-disk results, not only mocked method calls.

API contract suite

Private RPC tests should assert loopback rejection, token creation/load hardening, bearer comparison, request-size cap, string money, cursor behavior, readiness/Redis gates, error codes, and 202 receipt semantics.

Explorer tests should assert core operation without SQLite, capability truth, every index state, response models, page limits, before_height, ID/address validation, exact monetary strings, bounded block loading, CORS GET policy, and stable 503 errors.

Generate and diff OpenAPI intentionally when public models change.

Wallet suite

The wallet suite covers domain signing, encrypted vault round-trips and failures, RPC parsing, browser gateway bridge, history reconciliation, preferences, QR/payment URIs, and critical UI paths.

High-risk UI tests should include:

  • password/mnemonic never displayed after expected transitions;
  • incorrect password and corrupted authentication tag;
  • lock on timer and platform events;
  • no send while node not ready or Redis unavailable;
  • BigInt amount validation and available-balance bounds;
  • one pending outgoing transaction policy;
  • transaction summary matches signed bytes;
  • delete confirmation and vault removal;
  • renderer cannot call arbitrary RPC/path/file operations.

Website suite

Static checks should cover every route at desktop/mobile widths, internal link integrity, documentation sidebar/search, heading anchors, explorer placeholder/live/error states, correct logo asset, wallet screenshot loading, no dark-theme regression, and accessible keyboard/focus behavior.

The build must succeed without a public explorer URL. A separate configuration test should build with a mock base origin.

Fuzzing priorities

High-value fuzz targets are:

  • P2P 24-byte headers and all payload parsers;
  • transaction and block deserializers;
  • compact target codec;
  • Base58Check/address inputs;
  • RPC raw hex and cursors;
  • explorer block/hash references and index adapters;
  • block-location decoder and length-prefix reads;
  • wallet payment URI and amount parsing.

Fuzzers should assert bounded resource use and clean rejection, not only absence of crashes.

Change classification

Before merging, label a change:

Class Examples Required coordination
consensus transaction/block bytes, validation, target, reward new/updated vectors, migration/version plan, all clients
wire P2P framing/payload/handshake protocol version and cross-node fixtures
local API RPC route/model/auth wallet/gateway compatibility
public API Explorer response/route OpenAPI, frontend, compatibility notice
storage RocksDB/file/index schema crash tests, migration/rebuild/rollback plan
client wallet UI without byte change wallet tests and release packaging
presentation website/docs site build/E2E/content review

Do not smuggle a consensus change inside a “refactor.” Serialized bytes and rejection sets are part of behavior.

Interoperability release gate

A new implementation or consensus release should not connect to a shared test network until it:

  1. matches every public vector byte-for-byte;
  2. passes shared negative fixtures;
  3. exchanges P2P v2 handshakes/messages with the Python node;
  4. reconstructs genesis IDs independently;
  5. validates and mines a controlled multi-block fixture chain;
  6. agrees on balances/nonces/IDs after every block;
  7. survives malformed and resource-boundary corpus tests;
  8. publishes its supported protocol/API/storage versions;
  9. documents any intentional incompatibility and requires a clean network/data namespace.

Agreement on a happy-path transaction alone is not interoperability.

Source anchors

Primary implementation files used for this chapter: