Skip to content

Commit 21a200b

Browse files
committed
Website: add docs regarding GraphQL and database
1 parent 6e54e3a commit 21a200b

File tree

3 files changed

+1007
-0
lines changed

3 files changed

+1007
-0
lines changed
Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
---
2+
title: Archive Database Queries
3+
description: SQL queries and database analysis for Mina Rust archive nodes
4+
sidebar_position: 7
5+
---
6+
7+
# Archive Database Queries
8+
9+
This guide provides comprehensive SQL queries and analysis techniques for
10+
querying Mina Rust archive node databases. Archive nodes store complete
11+
blockchain history in a structured PostgreSQL database with over 45 tables.
12+
13+
## Prerequisites
14+
15+
- Running archive node with PostgreSQL database
16+
- Database credentials (default: user `postgres`, database `archive`)
17+
- PostgreSQL client tools installed
18+
19+
## Database Connection
20+
21+
### Direct Connection
22+
23+
```bash
24+
# Connect using psql (requires PostgreSQL client installed)
25+
psql -h localhost -p 5432 -U postgres -d archive
26+
27+
# Or connect from within the Docker environment
28+
# Note: postgres-mina-rust is the container name from the archive node setup
29+
# See: https://o1-labs.github.io/mina-rust/node-operators/archive-node
30+
docker exec -it postgres-mina-rust psql -U postgres -d archive
31+
```
32+
33+
## Database Schema
34+
35+
### Schema Exploration
36+
37+
```sql
38+
-- List all tables in the archive database
39+
\dt
40+
41+
-- Get detailed information about table columns
42+
\d table_name
43+
44+
-- Example: Get structure of the blocks table
45+
\d blocks
46+
47+
-- Show all tables with their sizes
48+
SELECT
49+
schemaname,
50+
tablename,
51+
pg_size_pretty(pg_total_relation_size(tablename::text)) as size
52+
FROM pg_tables
53+
WHERE schemaname = 'public'
54+
ORDER BY pg_total_relation_size(tablename::text) DESC;
55+
```
56+
57+
### Key Tables
58+
59+
The archive database contains these primary tables:
60+
61+
- **`blocks`** - Block headers and metadata
62+
- **`user_commands`** - Payment and delegation transactions
63+
- **`internal_commands`** - Fee transfers, coinbase rewards
64+
- **`zkapp_commands`** - zkApp transactions and proof data
65+
- **`accounts_accessed`** - Account state changes
66+
- **`accounts_created`** - New account creations
67+
- **`blocks_user_commands`** - Links blocks to user commands
68+
- **`blocks_internal_commands`** - Links blocks to internal commands
69+
- **`public_keys`** - Public key identifiers
70+
- **`zkapp_*`** - Various zkApp-related tables for smart contract data
71+
72+
### Schema Files
73+
74+
The complete database schema definitions can be found in the repository:
75+
76+
- **Schema file**:
77+
[`producer-dashboard/docker/init-db/create_schema.sql`](https://github.com/o1-labs/mina-rust/blob/develop/producer-dashboard/docker/init-db/create_schema.sql)
78+
- **Indexes**:
79+
[`producer-dashboard/docker/init-db/add_indexes.sql`](https://github.com/o1-labs/mina-rust/blob/develop/producer-dashboard/docker/init-db/add_indexes.sql)
80+
- **Unique constraints**:
81+
[`producer-dashboard/docker/init-db/add_unique_constraints.sql`](https://github.com/o1-labs/mina-rust/blob/develop/producer-dashboard/docker/init-db/add_unique_constraints.sql)
82+
- **zkApp tables**:
83+
[`producer-dashboard/docker/init-db/zkapp_tables.sql`](https://github.com/o1-labs/mina-rust/blob/develop/producer-dashboard/docker/init-db/zkapp_tables.sql)
84+
- **Query examples**:
85+
[`producer-dashboard/src/archive/sql/`](https://github.com/o1-labs/mina-rust/tree/develop/producer-dashboard/src/archive/sql) -
86+
Pre-built queries for common operations
87+
88+
## Common SQL Queries
89+
90+
### Block Information
91+
92+
```sql
93+
-- Get recent blocks
94+
SELECT
95+
b.height,
96+
b.state_hash,
97+
b.parent_hash,
98+
pk.value as creator,
99+
b.timestamp
100+
FROM blocks b
101+
JOIN public_keys pk ON b.creator_id = pk.id
102+
ORDER BY b.height DESC
103+
LIMIT 10;
104+
105+
-- Get block statistics by creator
106+
SELECT
107+
pk.value as creator,
108+
COUNT(*) as blocks_produced,
109+
MIN(b.height) as first_block,
110+
MAX(b.height) as latest_block
111+
FROM blocks b
112+
JOIN public_keys pk ON b.creator_id = pk.id
113+
GROUP BY pk.value
114+
ORDER BY blocks_produced DESC;
115+
```
116+
117+
### Transaction Analysis
118+
119+
```sql
120+
-- Get recent payments
121+
SELECT
122+
b.height,
123+
b.timestamp,
124+
pk_source.value as source,
125+
pk_receiver.value as receiver,
126+
uc.amount,
127+
uc.fee
128+
FROM user_commands uc
129+
JOIN blocks_user_commands buc ON uc.id = buc.user_command_id
130+
JOIN blocks b ON buc.block_id = b.id
131+
JOIN public_keys pk_source ON uc.source_id = pk_source.id
132+
JOIN public_keys pk_receiver ON uc.receiver_id = pk_receiver.id
133+
WHERE uc.command_type = 'payment'
134+
ORDER BY b.height DESC
135+
LIMIT 20;
136+
137+
-- Transaction volume analysis
138+
SELECT
139+
DATE(to_timestamp(b.timestamp::bigint / 1000)) as date,
140+
COUNT(uc.id) as tx_count,
141+
SUM(uc.amount::bigint) as total_volume,
142+
AVG(uc.fee::bigint) as avg_fee
143+
FROM user_commands uc
144+
JOIN blocks_user_commands buc ON uc.id = buc.user_command_id
145+
JOIN blocks b ON buc.block_id = b.id
146+
WHERE uc.command_type = 'payment'
147+
GROUP BY DATE(to_timestamp(b.timestamp::bigint / 1000))
148+
ORDER BY date DESC;
149+
```
150+
151+
### Account Analysis
152+
153+
```sql
154+
-- Most active accounts
155+
SELECT
156+
pk.value as public_key,
157+
COUNT(*) as transaction_count
158+
FROM user_commands uc
159+
JOIN public_keys pk ON uc.source_id = pk.id
160+
GROUP BY pk.value
161+
ORDER BY transaction_count DESC
162+
LIMIT 10;
163+
164+
-- Account balance history (requires account state tracking)
165+
SELECT
166+
aa.account_identifier_id,
167+
pk.value as public_key,
168+
aa.balance,
169+
b.height,
170+
b.timestamp
171+
FROM accounts_accessed aa
172+
JOIN public_keys pk ON aa.account_identifier_id = pk.id
173+
JOIN blocks b ON aa.block_id = b.id
174+
WHERE pk.value = 'YOUR_PUBLIC_KEY_HERE'
175+
ORDER BY b.height DESC;
176+
```
177+
178+
## Analytics and Reporting
179+
180+
### Python Analysis Script
181+
182+
```python
183+
import psycopg2
184+
import pandas as pd
185+
import matplotlib.pyplot as plt
186+
187+
# Connect to archive database
188+
conn = psycopg2.connect(
189+
host="localhost",
190+
port=5432,
191+
database="archive",
192+
user="postgres",
193+
password="mina"
194+
)
195+
196+
# Analyze block production over time
197+
query = """
198+
SELECT
199+
DATE(to_timestamp(timestamp::bigint / 1000)) as date,
200+
COUNT(*) as blocks_per_day,
201+
COUNT(DISTINCT creator_id) as unique_producers
202+
FROM blocks
203+
WHERE timestamp > extract(epoch from now() - interval '30 days') * 1000
204+
GROUP BY date
205+
ORDER BY date;
206+
"""
207+
208+
df = pd.read_sql_query(query, conn)
209+
print(df)
210+
211+
# Plot block production
212+
df.plot(x='date', y='blocks_per_day', kind='line')
213+
plt.title('Daily Block Production')
214+
plt.show()
215+
```
216+
217+
### Export Data for Analysis
218+
219+
```bash
220+
# Export recent transactions to CSV
221+
docker exec postgres-mina-rust psql -U postgres -d archive -c "\COPY (
222+
SELECT
223+
b.height,
224+
b.timestamp,
225+
pk_source.value as source,
226+
pk_receiver.value as receiver,
227+
uc.amount,
228+
uc.fee,
229+
uc.memo
230+
FROM user_commands uc
231+
JOIN blocks_user_commands buc ON uc.id = buc.user_command_id
232+
JOIN blocks b ON buc.block_id = b.id
233+
JOIN public_keys pk_source ON uc.source_id = pk_source.id
234+
JOIN public_keys pk_receiver ON uc.receiver_id = pk_receiver.id
235+
WHERE uc.command_type = 'payment'
236+
ORDER BY b.height DESC
237+
LIMIT 1000
238+
) TO STDOUT WITH CSV HEADER" > transactions.csv
239+
```
240+
241+
## Database Maintenance
242+
243+
### Backup and Restore
244+
245+
```bash
246+
# Create database dump
247+
docker exec postgres-mina-rust pg_dump -U postgres archive > archive_backup.sql
248+
249+
# Restore from backup
250+
docker exec -i postgres-mina-rust psql -U postgres archive < archive_backup.sql
251+
```
252+
253+
### Performance Optimization
254+
255+
```sql
256+
-- Create indexes for common queries
257+
CREATE INDEX CONCURRENTLY idx_blocks_height ON blocks(height);
258+
CREATE INDEX CONCURRENTLY idx_blocks_timestamp ON blocks(timestamp);
259+
CREATE INDEX CONCURRENTLY idx_user_commands_source ON user_commands(source_id);
260+
CREATE INDEX CONCURRENTLY idx_user_commands_receiver ON user_commands(receiver_id);
261+
262+
-- Analyze table statistics
263+
ANALYZE blocks;
264+
ANALYZE user_commands;
265+
ANALYZE accounts_accessed;
266+
```
267+
268+
### Storage Management
269+
270+
```bash
271+
# Check database size
272+
docker exec postgres-mina-rust psql -U postgres -d archive -c "
273+
SELECT
274+
schemaname,
275+
tablename,
276+
pg_size_pretty(pg_total_relation_size(tablename::text)) as size
277+
FROM pg_tables
278+
WHERE schemaname = 'public'
279+
ORDER BY pg_total_relation_size(tablename::text) DESC;
280+
"
281+
282+
# Vacuum and analyze for performance
283+
docker exec postgres-mina-rust psql -U postgres -d archive -c "VACUUM ANALYZE;"
284+
```
285+
286+
## Advanced Queries
287+
288+
### Network Statistics
289+
290+
```sql
291+
-- Block production distribution
292+
SELECT
293+
pk.value as producer,
294+
COUNT(*) as blocks_produced,
295+
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER(), 2) as percentage
296+
FROM blocks b
297+
JOIN public_keys pk ON b.creator_id = pk.id
298+
GROUP BY pk.value
299+
ORDER BY blocks_produced DESC;
300+
301+
-- Transaction fee analysis
302+
SELECT
303+
percentile_cont(0.5) WITHIN GROUP (ORDER BY uc.fee::bigint) as median_fee,
304+
percentile_cont(0.75) WITHIN GROUP (ORDER BY uc.fee::bigint) as p75_fee,
305+
percentile_cont(0.95) WITHIN GROUP (ORDER BY uc.fee::bigint) as p95_fee,
306+
AVG(uc.fee::bigint) as avg_fee,
307+
MIN(uc.fee::bigint) as min_fee,
308+
MAX(uc.fee::bigint) as max_fee
309+
FROM user_commands uc
310+
WHERE uc.command_type = 'payment';
311+
```
312+
313+
### zkApp Analytics
314+
315+
```sql
316+
-- zkApp transaction volume
317+
SELECT
318+
DATE(to_timestamp(b.timestamp::bigint / 1000)) as date,
319+
COUNT(zc.id) as zkapp_count
320+
FROM zkapp_commands zc
321+
JOIN blocks_zkapp_commands bzc ON zc.id = bzc.zkapp_command_id
322+
JOIN blocks b ON bzc.block_id = b.id
323+
GROUP BY DATE(to_timestamp(b.timestamp::bigint / 1000))
324+
ORDER BY date DESC;
325+
326+
-- Most active zkApp accounts
327+
SELECT
328+
pk.value as public_key,
329+
COUNT(*) as zkapp_transactions
330+
FROM zkapp_commands zc
331+
JOIN zkapp_fee_payer_body zfpb ON zc.zkapp_fee_payer_body_id = zfpb.id
332+
JOIN public_keys pk ON zfpb.public_key_id = pk.id
333+
GROUP BY pk.value
334+
ORDER BY zkapp_transactions DESC
335+
LIMIT 10;
336+
```
337+
338+
## Use Cases
339+
340+
1. **Compliance and Auditing**: Track all transactions for regulatory compliance
341+
2. **Analytics Dashboards**: Build real-time blockchain analytics
342+
3. **Research**: Analyze network behavior, transaction patterns, and economics
343+
4. **Block Explorers**: Power blockchain explorer websites
344+
5. **Tax Reporting**: Generate transaction history for tax purposes
345+
6. **Network Monitoring**: Track network health and validator performance
346+
347+
## Performance Considerations
348+
349+
- **Complex queries**: Use appropriate indexes and LIMIT clauses
350+
- **Large result sets**: Consider pagination for web applications
351+
- **Historical data**: Older data may be slower to query
352+
- **Concurrent access**: Archive database can handle multiple read connections
353+
- **Memory usage**: Large analytical queries may require sufficient RAM
354+
355+
## Troubleshooting
356+
357+
### Common Issues
358+
359+
**Connection refused**:
360+
361+
```bash
362+
# Check if PostgreSQL container is running
363+
docker ps | grep postgres
364+
365+
# Check container logs
366+
docker logs postgres-mina-rust
367+
```
368+
369+
**Permission denied**:
370+
371+
```bash
372+
# Ensure proper database credentials
373+
docker exec postgres-mina-rust psql -U postgres -l
374+
```
375+
376+
**Query timeout**:
377+
378+
```sql
379+
-- Add appropriate indexes for slow queries
380+
-- Use EXPLAIN ANALYZE to understand query performance
381+
EXPLAIN ANALYZE SELECT ...;
382+
```
383+
384+
## Next Steps
385+
386+
- [GraphQL API Reference](./graphql-api) - Query blockchain data via GraphQL
387+
- [Node Architecture](./architecture) - Understanding the archive system
388+
- [Running Archive Nodes](../node-operators/archive-node) - Setting up archive
389+
infrastructure

0 commit comments

Comments
 (0)