Cargo workspace plus a Vite frontend, following ~/git/architecture/generic.md. Every block header carries its author's wormhole reward preimage in a `pow_` PreRuntime digest, so authorship for the whole network is derivable from headers alone — no indexer, no registration, no way for a miner to be left out. That decoding, the hashrate maths and the telemetry name attribution live in blackbeard-core with no I/O at all, so the parts that are easy to get subtly wrong are exercised by unit tests rather than only against a live chain. The browser holds one WebSocket: snapshot on subscribe, deltas thereafter. The head stream is itself a push (chain_subscribeNewHeads), so a block reaches the page the moment the node imports it. Messages are serialised once per broadcast, and leaderboards are recomputed only for windows a socket is actually watching. No RxJS — useSyncExternalStore is React's own contract for this. Verified against the live Planck testnet: 12/12 headers decoded, telemetry names attributed (quanpool-planck, baba-gorchitsa, …), warm start restoring 84 blocks and 5 held names across a restart. Three findings worth recording, all in CLAUDE.md: - substrate-telemetry sends its JSON in *binary* frames. A text-only client connects, subscribes, reports healthy and receives nothing at all — and a Python probe hides it, because json.loads accepts bytes. - Difficulty is a little-endian U512; decoding it big-endian gives a number wrong by ~10^150 that still renders fine. - Planck's real block interval is ~13-15s against a 6s target with enormous variance, so a measured interval needs 20 tip samples before it is publishable. Deploy assets, the Gitea Actions workflow and script/infra-setup.sh are included; port 25864 is registered in architecture/port-allocations.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSDYiibCtELsrjQq6KXnoi
52 lines
1.9 KiB
TOML
52 lines
1.9 KiB
TOML
[workspace]
|
|
resolver = "3"
|
|
members = ["crates/*"]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
rust-version = "1.85"
|
|
license = "GPL-3.0-or-later"
|
|
authors = ["Rob Thijssen <rob@lair.cafe>"]
|
|
repository = "https://git.lair.cafe/Quantus-Network/blackbeard.observer"
|
|
|
|
[workspace.dependencies]
|
|
blackbeard-entities = { path = "crates/blackbeard-entities", version = "=0.1.0" }
|
|
blackbeard-core = { path = "crates/blackbeard-core", version = "=0.1.0" }
|
|
blackbeard-data = { path = "crates/blackbeard-data", version = "=0.1.0" }
|
|
|
|
anyhow = "1"
|
|
axum = { version = "0.8", features = ["ws", "macros"] }
|
|
chrono = { version = "0.4", default-features = false, features = ["clock", "serde", "std"] }
|
|
clap = { version = "4", features = ["derive", "env"] }
|
|
figment = { version = "0.10", features = ["toml", "env"] }
|
|
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
|
|
hex = "0.4"
|
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls-native-roots"] }
|
|
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
sqlx = { version = "0.8", default-features = false, features = [
|
|
"postgres",
|
|
"runtime-tokio-rustls",
|
|
"macros",
|
|
"migrate",
|
|
"chrono",
|
|
"bigdecimal",
|
|
] }
|
|
bigdecimal = "0.4"
|
|
primitive-types = { version = "0.13", default-features = false }
|
|
thiserror = "2"
|
|
tokio = { version = "1", features = ["full"] }
|
|
tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "rustls-tls-native-roots"] }
|
|
tower-http = { version = "0.6", features = ["cors", "trace", "compression-gzip"] }
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
|
ts-rs = { version = "10", features = ["serde-compat", "chrono-impl", "no-serde-warnings"] }
|
|
url = "2"
|
|
|
|
[profile.release]
|
|
lto = "thin"
|
|
codegen-units = 1
|
|
strip = "debuginfo"
|