Skip to content

Commit 43591f1

Browse files
authored
Improve readme and docs (#99)
1 parent 1138f11 commit 43591f1

File tree

34 files changed

+1871
-85
lines changed

34 files changed

+1871
-85
lines changed

README.md

Lines changed: 190 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,202 @@
1-
# PVQ
1+
# PVQ: PolkaVM Query System for Polkadot
22

3-
PolkaVM Query for Polkadot
3+
<!-- generated by polka.codes -->
44

5-
## Getting Started
5+
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
6+
[![Rust](https://github.com/open-web3-stack/PVQ/workflows/Rust/badge.svg)](https://github.com/open-web3-stack/PVQ/actions)
7+
8+
A powerful and secure query system for Polkadot parachains that enables developers to write expressive, sandboxed guest programs using PolkaVM. PVQ provides a safe and efficient alternative to custom RPC endpoints for runtime data queries.
9+
10+
## ✨ Features
11+
12+
- **🔒 Secure Execution**: Sandboxed PolkaVM environment for safe query execution
13+
- **🧩 Modular Extensions**: Extensible system for exposing runtime functionalities
14+
- **⚡ High Performance**: Efficient RISC-V execution with minimal overhead
15+
- **🛠️ Developer Friendly**: Rust-first development experience with procedural macros
16+
- **🌐 Runtime Integration**: Seamless integration with Substrate runtimes
17+
- **🔍 Rich Querying**: Support for complex queries involving multiple runtime components
18+
19+
## 🏗️ Architecture
20+
21+
The PVQ system consists of several interconnected components:
22+
23+
```
24+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
25+
│ PVQ Program │───▶│ PVQ Executor │───▶│ Substrate │
26+
│ (Guest Code) │ │ (Host Side) │ │ Runtime │
27+
└─────────────────┘ └─────────────────┘ └─────────────────┘
28+
│ │ │
29+
│ ┌─────────────────┐ │
30+
└─────────────▶│ PVQ Extensions │◀─────────────┘
31+
│ (Modules) │
32+
└─────────────────┘
33+
```
34+
35+
### Core Components
36+
37+
| Component | Description |
38+
|-----------|-------------|
39+
| **[PVQ Program](pvq-program/)** | Guest programs written in Rust that compile to RISC-V |
40+
| **[PVQ Executor](pvq-executor/)** | Host-side component managing PolkaVM instances and runtime interaction |
41+
| **[PVQ Extensions](pvq-extension/)** | Modular system exposing runtime functionalities to guest programs |
42+
| **[PVQ Runtime API](pvq-runtime-api/)** | Substrate runtime API for external query submission |
43+
| **[PVQ Primitives](pvq-primitives/)** | Common types and utilities shared across components |
44+
45+
### Available Extensions
46+
47+
- **[Core Extension](pvq-extension-core/)**: Fundamental functionalities and extension discovery
48+
- **[Fungibles Extension](pvq-extension-fungibles/)**: Asset querying, balances, and metadata
49+
- **[Swap Extension](pvq-extension-swap/)**: DEX interactions, liquidity pools, and price quotes
50+
51+
## 🚀 Getting Started
652

753
### Prerequisites
854

9-
- Pull vendored `polkavm`: `git submodule update --init --recursive`.
10-
- Install `polkatool` (for relinking the standard RV32E ELF to a PolkaVM blob) and `chain-spec-builder` (for building chainspec from a wasm): `make tools`
55+
Ensure you have the following installed:
56+
57+
- **Rust** (latest stable version)
58+
- **Git** with submodule support
59+
60+
### Installation
61+
62+
1. **Clone the repository with submodules:**
63+
```bash
64+
git clone --recursive https://github.com/open-web3-stack/PVQ.git
65+
cd PVQ
66+
```
67+
68+
2. **Install required tools:**
69+
```bash
70+
make tools
71+
```
72+
This installs `polkatool` for ELF to PolkaVM blob conversion and `chain-spec-builder`.
73+
74+
3. **Build the project:**
75+
```bash
76+
cargo build --release
77+
```
78+
79+
### Quick Start
80+
81+
#### Running Example Programs
82+
83+
1. **Build guest programs:**
84+
```bash
85+
make guests
86+
```
87+
88+
2. **Run a test program:**
89+
```bash
90+
cargo run -p pvq-test-runner -- --program output/guest-sum-balance
91+
```
92+
93+
#### Available Example Programs
94+
95+
| Program | Description |
96+
|---------|-------------|
97+
| `guest-sum-balance` | Sum balances of multiple accounts |
98+
| `guest-total-supply` | Get total supply of an asset |
99+
| `guest-sum-balance-percent` | Calculate percentage of total supply for account balances |
100+
| `guest-swap-info` | Query DEX/swap information |
101+
102+
### Runtime Integration
103+
104+
#### Testing with PoC Runtime
105+
106+
1. **Start local test chain:**
107+
```bash
108+
make run
109+
```
110+
111+
2. **Build and test programs:**
112+
```bash
113+
make guests
114+
cargo run -p pvq-test-runner -- --program output/guest-total-supply
115+
```
116+
117+
3. **Use with Polkadot JS UI:**
118+
- Copy the hex-encoded `args` from test runner logs
119+
- Upload program and arguments through the PJS UI
120+
121+
## 📖 Documentation
122+
123+
### Writing Your First PVQ Program
124+
125+
```rust
126+
use pvq_program::program;
127+
use pvq_extension_fungibles::ExtensionFungibles;
128+
129+
#[program]
130+
fn query_balance(account: [u8; 32], asset_id: u32) -> u128 {
131+
ExtensionFungibles::balance(asset_id, &account)
132+
}
133+
```
134+
135+
### Creating Custom Extensions
136+
137+
```rust
138+
use pvq_extension::extension_decl;
139+
140+
#[extension_decl]
141+
pub trait MyCustomExtension {
142+
fn my_query() -> String;
143+
}
144+
```
145+
146+
### Component Documentation
147+
148+
- 📚 **[Development Guide](docs/development.md)** - Comprehensive development setup
149+
- 🔧 **[Extension Development](docs/extensions.md)** - Creating custom extensions
150+
- 🏗️ **[Architecture Deep Dive](docs/architecture.md)** - System design and internals
151+
- 📋 **[API Reference](docs/api.md)** - Complete API documentation
152+
153+
## 🛠️ Development
154+
155+
### Project Structure
156+
157+
```
158+
PVQ/
159+
├── poc/runtime/ # PoC Substrate runtime
160+
├── pvq-program/ # Program macro and utilities
161+
├── pvq-executor/ # Core execution engine
162+
├── pvq-extension*/ # Extension system and implementations
163+
├── pvq-runtime-api/ # Runtime API definition
164+
├── pvq-test-runner/ # Testing utilities
165+
├── guest-examples/ # Example programs
166+
└── vendor/polkavm/ # Vendored PolkaVM dependency
167+
```
168+
169+
### Building from Source
170+
171+
```bash
172+
# Development build
173+
cargo build
174+
175+
# Release build with optimizations
176+
cargo build --release
177+
178+
# Build guest examples
179+
make guests
11180

12-
### Run Examples
181+
# Run all tests
182+
cargo test --all
13183

14-
`guest-examples` contains several guest programs to test the PVQ.
184+
# Run clippy lints
185+
cargo clippy --all --all-targets
186+
```
15187

16-
1. Build guest program: `make guests`
17-
2. Run test runner: `cargo run -p pvq-test-runner -- --program output/<guest-program>`
188+
### Testing
18189

19-
Available PoC guest programs:
190+
```bash
191+
# Run unit tests
192+
cargo test
20193

21-
- `guest-sum-balance`: sum the balances of multiple accounts
22-
- `guest-total-supply`: get the total supply of an asset
23-
- `guest-sum-balance-percent`: sum the balances of multiple accounts and calculate the percentage of the total supply
194+
# Run integration tests
195+
cargo test --test integration
24196

25-
### RuntimeAPI PoC
197+
# Test specific component
198+
cargo test -p pvq-executor
26199

27-
1. Use chopsticks to start a local chain with the RuntimeAPI enabled: `make run`
28-
2. Build guest programs: `make guests`
29-
3. Run test runner to display hex-encoded `args` in tracing logs: `cargo run -p pvq-test-runner -- --program output/<guest-program>`
30-
4. Upload `program` and `args` in PJS UI.
200+
# Run example programs
201+
make test-guests
202+
```

guest-examples/sum-balance-percent/src/main.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
1+
//! A guest program that sums the balances of a set of accounts for a given asset and returns the percentage of the total supply.
12
#![no_std]
23
#![no_main]
34

5+
/// The primary module for the sum-balance-percent guest program.
6+
///
7+
/// This module defines the necessary types, extension functions, and the main entrypoint
8+
/// for calculating the percentage of total supply represented by the sum of balances
9+
/// for a given set of accounts.
410
#[pvq_program::program]
511
mod sum_balance_percent {
12+
/// A type alias for the asset identifier.
613
type AssetId = u32;
14+
/// A type alias for the account identifier.
715
type AccountId = [u8; 32];
16+
/// A type alias for the balance of an account.
817
type Balance = u64;
18+
19+
/// Retrieves the balance of a specific account for a given asset.
20+
///
21+
/// This is an extension function that calls into the runtime.
922
#[program::extension_fn(extension_id = 1248491991627109725u64, fn_index = 6)]
1023
fn balance(asset: AssetId, who: AccountId) -> Balance {}
24+
25+
/// Retrieves the total supply of a given asset.
26+
///
27+
/// This is an extension function that calls into the runtime.
1128
#[program::extension_fn(extension_id = 1248491991627109725u64, fn_index = 5)]
1229
fn total_supply(asset: AssetId) -> Balance {}
1330

31+
/// The entrypoint of the program.
32+
///
33+
/// It takes an asset ID and a vector of account IDs, calculates the sum of their balances,
34+
/// and returns the percentage of this sum with respect to the total supply of the asset.
1435
#[program::entrypoint]
1536
fn sum_balance(asset: AssetId, accounts: alloc::vec::Vec<AccountId>) -> Balance {
1637
let mut sum_balance = 0;

guest-examples/sum-balance/src/main.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,59 @@
1+
//! A guest program that sums the balance of a given asset for a list of accounts.
12
#![no_std]
23
#![no_main]
34

5+
/// A guest program that sums the balance of a given asset for a list of accounts.
46
#[pvq_program::program]
57
mod sum_balance {
68

79
cfg_if::cfg_if! {
810
if #[cfg(feature = "option_version_1")] {
11+
/// Represents a unique identifier for an account.
912
type AccountId = [u8; 64];
13+
/// Represents a unique identifier for an asset.
1014
type AssetId = u64;
15+
/// Represents the balance of an asset.
1116
type Balance = u128;
1217
} else if #[cfg(feature = "option_version_2")] {
18+
/// Represents a unique identifier for an account.
1319
type AccountId = [u8; 32];
20+
/// Represents a unique identifier for an asset.
1421
type AssetId = u32;
22+
/// Represents the balance of an asset.
1523
type Balance = u64;
1624
} else {
25+
/// Represents a unique identifier for an account.
1726
type AccountId = [u8; 32];
27+
/// Represents a unique identifier for an asset.
1828
type AssetId = u32;
29+
/// Represents the balance of an asset.
1930
type Balance = u64;
2031
}
2132
}
2233

34+
/// Get the balance of a given asset for a specific account.
35+
///
36+
/// # Arguments
37+
///
38+
/// * `asset`: The identifier of the asset.
39+
/// * `who`: The account identifier.
40+
///
41+
/// # Returns
42+
///
43+
/// The balance of the asset for the specified account.
2344
#[program::extension_fn(extension_id = 1248491991627109725u64, fn_index = 6)]
2445
fn balance(asset: AssetId, who: AccountId) -> Balance {}
2546

47+
/// Sums the balance of a given asset for a list of accounts.
48+
///
49+
/// # Arguments
50+
///
51+
/// * `asset`: The identifier of the asset.
52+
/// * `accounts`: A list of account identifiers.
53+
///
54+
/// # Returns
55+
///
56+
/// The total balance of the asset for all the specified accounts.
2657
#[program::entrypoint]
2758
fn sum_balance(asset: AssetId, accounts: alloc::vec::Vec<AccountId>) -> Balance {
2859
let mut sum = 0;

0 commit comments

Comments
 (0)