Skip to content

Latest commit

 

History

History
187 lines (130 loc) · 10.2 KB

AGENTS.md

File metadata and controls

187 lines (130 loc) · 10.2 KB

AGENTS.md

This file provides guidance to coding assistants (Claude Code, Codex, Cursor, etc.) when working with code in this repository.

Overview

Quip Network solochain node built on Substrate (Polkadot SDK polkadot-stable2603). This is a standalone blockchain with hybrid H4 BABE block authoring and H2 GRANDPA finality.

Chain specs

Omit --chain to join the live public Quip Testnet (EIP-155 20033). --chain=local is a disposable Alice-and-Bob chain. It is not the public testnet.

Flag Preset Network EIP-155
(omit --chain) quip-testnet live public testnet 20033
--chain=quip-testnet quip-testnet live public testnet 20033
--dev or --chain=dev Development Alice-only local 1337
--chain=local Local Testnet Alice and Bob local 1337
--chain=local3 Local Testnet (3 Validators) Alice, Bob, and Charlie local 1337

Aliases for the public testnet: quip_testnet, testnet. A path argument loads that JSON file and uses the chain ID in its genesis.

Runtime 117 is the H2/H4 chain-wipe relaunch, not an in-place upgrade from the earlier H1/H3 network. Work on this launch must assume fresh genesis/state, fresh validator databases, re-inserted H4 BABE and H2 GRANDPA keys, and incompatible old signed extrinsics (transaction_version = 7).

Commands

# Build (release, compiles both native binary and Wasm runtime)
cargo build --release

# Build (debug, faster compilation)
cargo build

# Run all tests
cargo test

# Test a single pallet
cargo test -p pallet-template

# Run a single test by name
cargo test -p pallet-template it_works_for_default_value

# Check without building (fast feedback)
cargo check

# Clippy (workspace lints defined in root Cargo.toml)
cargo clippy --all-targets

# Build benchmarks
cargo build --release --features runtime-benchmarks

# Join the live public testnet (default: omit --chain, EIP-155 20033)
cargo build --release
./target/release/quip-network-node

# Same network, explicit flag
./target/release/quip-network-node --chain=quip-testnet

# Alice-only local chain (EIP-155 1337). Required for a single validator.
./target/release/quip-network-node --dev

# Purge Alice-only local chain state (EIP-155 1337)
./target/release/quip-network-node purge-chain --dev

# Alice and Bob local chain (EIP-155 1337). Not the public testnet.
./target/release/quip-network-node --chain=local

# Three-validator local chain (EIP-155 1337)
./target/release/quip-network-node --chain=local3

# Generate rust docs
cargo +nightly doc --open

CI (.gitlab-ci.yml) runs cargo fmt --check, cargo clippy --workspace -D warnings, cargo test, and a runtime release build on every merge request. browser-signer-test also checks the signing fixture. Run cargo clippy --all-targets and cargo test locally before pushing to catch failures early.

Two further merge-request jobs run automatically and cover benchmarks. benchmark-preflight exercises every benchmark against the production runtime constants at low resolution, without touching tracked weights. weights-staleness-check warns (yellow, never blocking) when a pallet's lib.rs/benchmarking.rs changed but its weights.rs/benchmark_weights.rs did not. Regenerating weights is the separate benchmark-weights job — manual by design, because it runs on the single serialized reference machine and pushes the regenerated files back to the MR branch. Play it when your change can affect weights.

Architecture

Three-crate workspace:

node/ — Native binary (quip-network-node). Handles networking (libp2p), consensus orchestration, RPC server, and chain specification. Key files:

  • chain_spec.rs — Genesis configuration. Default (no --chain) is quip-testnet.
  • service.rs — Node service wiring (hybrid BABE + GRANDPA consensus, transaction pool, networking)
  • rpc.rs — Custom RPC endpoint registration

runtime/ — Blockchain state transition function (quip-protocol-runtime). Compiles to both native and Wasm. The Wasm blob is embedded in the native binary and supports ordinary on-chain upgrades; Runtime 117 (the H2/H4 launch) is explicitly a chain-wipe relaunch instead.

  • lib.rs — Runtime type definitions, pallet composition via #[frame_support::runtime] macro, block time constants (6s slots)
  • configs/mod.rs — All pallet Config trait implementations (system params, weights, fees)
  • apis.rs — Runtime API implementations exposed to the node
  • genesis_config_presets.rs — Genesis state presets for dev/testnet

pallets/evm-chain-id/ — Stores the EIP-155 chain ID set at genesis (1337 local, 20033 testnet). pallet-revive reads it through Get<u64>.

pallets/template/ — Custom FRAME pallet (pallet-template). Starting point for Quip-specific logic.

  • lib.rs — Pallet definition (storage, events, errors, dispatchable calls)
  • mock.rs — Mock runtime for unit tests
  • tests.rs — Pallet unit tests using frame_support::assert_ok! / assert_noop!
  • weights.rs — Benchmark-derived weight constants
  • benchmarking.rs — Benchmark definitions (behind runtime-benchmarks feature)

Key Patterns

no_std by default: Runtime and pallet crates use #![cfg_attr(not(feature = "std"), no_std)]. All dependencies in these crates must support no_std. Use default-features = false for Substrate deps and gate std-only code behind #[cfg(feature = "std")].

Pallet indices are stable: Pallet indices in runtime/src/lib.rs (e.g., #[runtime::pallet_index(7)]) must never change after chain launch — they're encoded in storage keys and extrinsics.

Call indices are stable: Similarly, #[pallet::call_index(N)] values in pallet dispatchables must remain fixed for backward compatibility.

Feature flags:

  • runtime-benchmarks enables benchmark code.
  • try-runtime enables migration testing.
  • metadata-hash embeds a runtime metadata hash at compile time (slows builds; used for release artifacts).
  • on-chain-release-build is the convenience aggregate enabled for production runtime blobs.

These gate code at both pallet and runtime level.

Workspace lints: The root Cargo.toml defines strict clippy + rustc lints that apply to every crate via [workspace.lints]. CI enforces these (cargo clippy --workspace -D warnings); run cargo clippy --all-targets locally before pushing.

Implementation Rules

General

  • Prefer small, reviewable changes over broad refactors.
  • Keep new abstractions narrowly scoped to the problem being solved.
  • Follow existing workspace patterns for crate layout, runtime wiring, tests, and features.

FRAME / Substrate

  • Do not add #[pallet::getter(...)] storage getter macros.
  • Do not call generated pallet storage getter methods.
  • Access pallet storage directly through the storage types by default, for example:
    • JobOrders::<T>::get(order_id)
    • Solvers::<T>::insert(account, info)
  • If the same storage read is needed in multiple places, an explicit helper method may be added on the pallet impl.
  • Prefer explicit named helpers over generated getters so the access path stays visible in code review.
  • When a test needs to read pallet storage, import the storage type directly unless there is an existing explicit helper with real reuse value.
  • Keep pallet APIs explicit. Avoid convenience wrappers that merely rename storage access unless they materially improve reuse or readability.

Runtime

  • Keep pallet indices stable once introduced.
  • Prefer runtime configuration via parameter_types! and explicit impl pallet_x::Config for Runtime blocks.
  • Avoid adding runtime-only behavior into pure helper crates.
  • Bump spec_version only after the current spec has shipped (a release tag that nodes actually run). If the current spec has not gone live, keep that number and do not invent the next one. Example: 115 has not shipped, so pallet-evm-chain-id stayed on 115 instead of 116.
  • When you do change spec_version, transaction_version, or the signed-extension set in runtime/src/lib.rs, regenerate the Polkadot.js signing fixture before you push. docs/polkadotjs/fixtures/hybrid-signing.json embeds those values. browser-signer-test runs cargo test -p quip-protocol-runtime --test signing_fixture and fails if the fixture is stale:
cargo run -p quip-protocol-runtime --example generate_polkadotjs_signing_fixture -- --write
cargo test -p quip-protocol-runtime --test signing_fixture

Validation / Pure logic

  • Put pure deterministic math and validation into standalone crates where possible.
  • Keep Substrate-bound types and dispatch logic in pallets.
  • When parity with a reference implementation matters, prefer checked-in fixtures generated from the real reference implementation.

Environment Setup

Rust toolchain is pinned in env-setup/rust-toolchain.toml (stable channel, includes wasm32-unknown-unknown target). Alternatively, use Nix: cd env-setup && nix develop (requires clang, protobuf, rustup).

Versioning & release tags

Cross-repo standard — quip-protocol/docs/VERSIONING.md is canonical; docs/release.md is the release checklist.

Artifact Format Example
Git tag (pre-release) SemVer hyphenated vMAJOR.MINOR.PATCH-rcN v0.2.1-rc18
Git tag (stable) vMAJOR.MINOR.PATCH v0.2.1
Cargo.toml version bare SemVer (toolchain-native) 0.2.1

Rules:

  • Pre-release git tags MUST be hyphenated (-rcN / -alphaN / -betaN). Never the PEP 440 no-hyphen form (v0.2.1rc18) for a git tag: quip-node-manager orders release candidates by splitting on the hyphen, so a no-hyphen tag collapses every rc to one value and freezes node updates.
  • The MAJOR.MINOR.PATCH numerics must match Cargo.toml's version; only the separator and the rc suffix differ. A Cargo SemVer pre-release, if ever set, is also hyphenated (0.2.1-rc.18).
  • CI (.gitlab-ci.yml): container images publish on release tags ONLY — branch pushes never build or push images. The floating tag follows the branch the tag was cut from (resolved by the resolve-floating-tag job via commit ancestry): a tag on v0.2 publishes :<tag> + :v0.2, a tag on main publishes :<tag> + :latest, both plus :sha-<short-sha>.

License

Unlicense (public domain).