GitHub - open-web3-stack/PVQ: Cross-Consensus Query Language for Polkadot

PVQ: PolkaVM Query

License Build

PVQ is a unified query interface that bridges different chain runtime implementations and client tools/UIs. PVQ provides an extension-based system where runtime developers can expose chain-specific functionality through standardized interfaces, while allowing client-side developers to perform custom computations on the data through PolkaVM programs. By abstracting away concrete implementations across chains and supporting both off-chain and cross-chain scenarios, PVQ aims to reduce code duplication and development complexity while maintaining flexibility for custom use cases.

✨ Features

  • πŸ”’ Secure Execution: Sandboxed PolkaVM environment for safe query execution
  • 🧩 Modular Extensions: Extensible system for exposing runtime functionalities
  • ⚑ High Performance: Efficient RISC-V execution with minimal overhead
  • πŸ› οΈ Developer Friendly: Rust-first development experience with procedural macros
  • 🌐 Runtime Integration: Seamless integration with Substrate runtimes
  • πŸ” Rich Querying: Support for complex queries involving functions from multiple pallets

πŸ—οΈ Architecture

The PVQ system consists of several interconnected components:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   PVQ Program   │───▢│  PVQ Executor   │───▢│ Substrate       β”‚
β”‚  (Guest Code)   β”‚    β”‚   (Host Side)   β”‚    β”‚ Runtime         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚
         β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
         └─────────────▢│ PVQ Extensions  β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚   (Modules)     β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components

Component Description
PVQ Program Guest programs written in Rust that compile to RISC-V
PVQ Executor Host-side component managing PolkaVM instances and runtime interaction
PVQ Extensions Modular system exposing runtime functionalities to guest programs
PVQ Runtime API Substrate runtime API for external query submission
PVQ Primitives Common types and utilities shared across components

Available Example Extensions

πŸš€ Getting Started

Prerequisites

Ensure you have the following installed:

  • Rust (latest stable version)
  • Git with submodule support

Installation

  1. Clone the repository with submodules:

    git clone --recursive https://github.com/open-web3-stack/PVQ.git
    cd PVQ
  2. Install required tools:

    This installs polkatool for ELF to PolkaVM blob conversion and chain-spec-builder.

  3. Build the project:

Quick Start

Running Example Programs

  1. Build guest programs:

  2. Run a test program:

    cargo run -p pvq-test-runner -- --program output/guest-sum-balance

Available Example Programs

Program Description
guest-sum-balance Sum balances of multiple accounts
guest-total-supply Get total supply of an asset
guest-sum-balance-percent Calculate percentage of total supply for account balances
guest-swap-info Query DEX/swap information

Runtime Integration

Testing with PoC Runtime

  1. Start local test chain:

  2. Build and test programs:

    make guests
    cargo run -p pvq-test-runner -- --program output/guest-total-supply
  3. Use with Polkadot JS UI:

    • Copy the hex-encoded args from test runner logs
    • Upload program and arguments through the PJS UI

πŸ“– Documentation

Writing Your First PVQ Program

use pvq_program::program;
use pvq_extension_fungibles::ExtensionFungibles;

#[program]
fn query_balance(account: [u8; 32], asset_id: u32) -> u128 {
    ExtensionFungibles::balance(asset_id, &account)
}

Creating Custom Extensions

use pvq_extension::extension_decl;

#[extension_decl]
pub trait MyCustomExtension {
    fn my_query() -> String;
}