Skip to content

Commit 7d72ff2

Browse files
committed
Add schema docs
1 parent 46398c9 commit 7d72ff2

File tree

9 files changed

+267
-3
lines changed

9 files changed

+267
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
* Make web assets optional in flake.
6+
* Add schema docs.
67

78
## v0.1.7
89

Cargo.lock

Lines changed: 43 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ repository = "https://github.com/nyonson/bitcoin-node-census"
99
keywords = ["bitcoin", "p2p", "network", "monitoring", "census"]
1010
categories = ["command-line-utilities", "network-programming"]
1111

12+
[features]
13+
schema = ["dep:schemars"]
14+
1215
[dependencies]
1316
bitcoin-peers-crawler = "0.1.6"
1417
bitcoin = "0.32"
@@ -21,3 +24,4 @@ fern = "0.6"
2124
serde = { version = "1.0", features = ["derive"] }
2225
serde_json = "1.0"
2326
csv = "1.3"
27+
schemars = { version = "0.8", optional = true }

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
Crawl the bitcoin network and aggregate stats for easy tracking.
1616

17-
Data published at [census.yonson.dev](https://census.yonson.dev/) and [census.labs.yonson.dev](https://census.labs.yonson.dev/).
17+
Data published at [census.yonson.dev](https://census.yonson.dev/) and [census.labs.yonson.dev](https://census.labs.yonson.dev/). The schema for the raw data is in [docs/census.schema.json](docs/census.schema.json).
1818

1919
## Usage
2020

docs/census.schema.json

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "CensusReport",
4+
"description": "A census report containing statistics from a network crawl.",
5+
"type": "object",
6+
"required": [
7+
"census_version",
8+
"duration_seconds",
9+
"stats",
10+
"timestamp"
11+
],
12+
"properties": {
13+
"census_version": {
14+
"description": "Version of the census tool.",
15+
"type": "string"
16+
},
17+
"duration_seconds": {
18+
"description": "Duration of the census in seconds.",
19+
"type": "integer",
20+
"format": "uint64",
21+
"minimum": 0.0
22+
},
23+
"stats": {
24+
"description": "Feature statistics.",
25+
"allOf": [
26+
{
27+
"$ref": "#/definitions/FeatureStats"
28+
}
29+
]
30+
},
31+
"timestamp": {
32+
"description": "When the census was taken (Unix timestamp in seconds).",
33+
"type": "integer",
34+
"format": "uint64",
35+
"minimum": 0.0
36+
},
37+
"total_contacted": {
38+
"description": "Total number of nodes contacted (listening + non-listening).",
39+
"default": 0,
40+
"type": "integer",
41+
"format": "uint",
42+
"minimum": 0.0
43+
}
44+
},
45+
"definitions": {
46+
"ConnectionTypeFeatures": {
47+
"description": "Feature statistics for a specific connection type.",
48+
"type": "object",
49+
"required": [
50+
"compact_filters",
51+
"total_nodes",
52+
"v2_and_filters",
53+
"v2_transport"
54+
],
55+
"properties": {
56+
"compact_filters": {
57+
"description": "Nodes supporting compact block filters (BIP-157/158).",
58+
"type": "integer",
59+
"format": "uint",
60+
"minimum": 0.0
61+
},
62+
"total_nodes": {
63+
"description": "Total number of nodes for this connection type.",
64+
"type": "integer",
65+
"format": "uint",
66+
"minimum": 0.0
67+
},
68+
"v2_and_filters": {
69+
"description": "Nodes supporting both v2 transport AND compact filters.",
70+
"type": "integer",
71+
"format": "uint",
72+
"minimum": 0.0
73+
},
74+
"v2_transport": {
75+
"description": "Nodes supporting v2 transport (BIP-324).",
76+
"type": "integer",
77+
"format": "uint",
78+
"minimum": 0.0
79+
}
80+
}
81+
},
82+
"ConnectionTypeStats": {
83+
"description": "Statistics broken down by connection type.",
84+
"type": "object",
85+
"required": [
86+
"cjdns",
87+
"i2p",
88+
"ipv4",
89+
"ipv6",
90+
"tor_v2",
91+
"tor_v3",
92+
"unknown"
93+
],
94+
"properties": {
95+
"cjdns": {
96+
"description": "CJDNS mesh network addresses.",
97+
"allOf": [
98+
{
99+
"$ref": "#/definitions/ConnectionTypeFeatures"
100+
}
101+
]
102+
},
103+
"i2p": {
104+
"description": "I2P addresses.",
105+
"allOf": [
106+
{
107+
"$ref": "#/definitions/ConnectionTypeFeatures"
108+
}
109+
]
110+
},
111+
"ipv4": {
112+
"description": "IPv4 clearnet connections.",
113+
"allOf": [
114+
{
115+
"$ref": "#/definitions/ConnectionTypeFeatures"
116+
}
117+
]
118+
},
119+
"ipv6": {
120+
"description": "IPv6 clearnet connections.",
121+
"allOf": [
122+
{
123+
"$ref": "#/definitions/ConnectionTypeFeatures"
124+
}
125+
]
126+
},
127+
"tor_v2": {
128+
"description": "Tor v2 onion addresses (deprecated).",
129+
"allOf": [
130+
{
131+
"$ref": "#/definitions/ConnectionTypeFeatures"
132+
}
133+
]
134+
},
135+
"tor_v3": {
136+
"description": "Tor v3 onion addresses.",
137+
"allOf": [
138+
{
139+
"$ref": "#/definitions/ConnectionTypeFeatures"
140+
}
141+
]
142+
},
143+
"unknown": {
144+
"description": "Unknown/future address types.",
145+
"allOf": [
146+
{
147+
"$ref": "#/definitions/ConnectionTypeFeatures"
148+
}
149+
]
150+
}
151+
}
152+
},
153+
"FeatureStats": {
154+
"description": "Statistics about node features and capabilities.",
155+
"type": "object",
156+
"required": [
157+
"compact_filters",
158+
"connection_types",
159+
"total_nodes",
160+
"v2_and_filters",
161+
"v2_transport"
162+
],
163+
"properties": {
164+
"compact_filters": {
165+
"description": "Nodes supporting compact block filters (BIP-157/158) (sum across all connection types).",
166+
"type": "integer",
167+
"format": "uint",
168+
"minimum": 0.0
169+
},
170+
"connection_types": {
171+
"description": "Detailed breakdown by connection type.",
172+
"allOf": [
173+
{
174+
"$ref": "#/definitions/ConnectionTypeStats"
175+
}
176+
]
177+
},
178+
"total_nodes": {
179+
"description": "Total number of nodes analyzed (sum across all connection types).",
180+
"type": "integer",
181+
"format": "uint",
182+
"minimum": 0.0
183+
},
184+
"v2_and_filters": {
185+
"description": "Nodes supporting both v2 transport AND compact filters (sum across all connection types).",
186+
"type": "integer",
187+
"format": "uint",
188+
"minimum": 0.0
189+
},
190+
"v2_transport": {
191+
"description": "Nodes supporting v2 transport (BIP-324) (sum across all connection types).",
192+
"type": "integer",
193+
"format": "uint",
194+
"minimum": 0.0
195+
}
196+
}
197+
}
198+
}
199+
}

examples/generate-schema.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use bitcoin_node_census::report::CensusReport;
2+
use schemars::schema_for;
3+
4+
fn main() {
5+
let schema = schema_for!(CensusReport);
6+
println!(
7+
"{}",
8+
serde_json::to_string_pretty(&schema).expect("Failed to serialize schema")
9+
);
10+
}

justfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ STABLE_TOOLCHAIN := "1.88.0"
4949
echo "Census result appended to site/census.jsonl"
5050

5151
# Publish a new version.
52-
@publish version remote="upstream":
52+
@publish version remote="upstream": schema
5353
# Requires write privileges on upsream repository.
5454

5555
# Publish guardrails: be on a clean master, updated changelog, updated manifest.
@@ -77,3 +77,7 @@ STABLE_TOOLCHAIN := "1.88.0"
7777
# Serve report locally.
7878
@serve:
7979
python3 -m http.server 8000 --directory {{justfile_directory()}}/site
80+
81+
# Generate JSON schema documentation.
82+
@schema:
83+
cargo +{{STABLE_TOOLCHAIN}} run --quiet --example generate-schema --features schema > {{justfile_directory()}}/docs/census.schema.json

src/report.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub enum OutputFormat {
1414

1515
/// A census report containing statistics from a network crawl.
1616
#[derive(Debug, Clone, Serialize, Deserialize)]
17+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
1718
pub struct CensusReport {
1819
/// When the census was taken (Unix timestamp in seconds).
1920
pub timestamp: u64,

src/stats.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
55

66
/// Feature statistics for a specific connection type.
77
#[derive(Debug, Clone, Serialize, Deserialize)]
8+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
89
pub struct ConnectionTypeFeatures {
910
/// Total number of nodes for this connection type.
1011
pub total_nodes: usize,
@@ -61,6 +62,7 @@ impl ConnectionTypeFeatures {
6162

6263
/// Statistics broken down by connection type.
6364
#[derive(Debug, Clone, Serialize, Deserialize)]
65+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
6466
pub struct ConnectionTypeStats {
6567
/// IPv4 clearnet connections.
6668
pub ipv4: ConnectionTypeFeatures,
@@ -134,6 +136,7 @@ impl ConnectionTypeStats {
134136

135137
/// Statistics about node features and capabilities.
136138
#[derive(Debug, Clone, Serialize, Deserialize)]
139+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
137140
pub struct FeatureStats {
138141
/// Total number of nodes analyzed (sum across all connection types).
139142
pub total_nodes: usize,

0 commit comments

Comments
 (0)