Skip to content

Commit

Permalink
feat: dog_breeds example
Browse files Browse the repository at this point in the history
  • Loading branch information
henrymai committed Oct 23, 2024
1 parent b55765d commit 72a2fbb
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .github/workflows/lint-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ jobs:
run: cargo run --example hello_world --no-default-features --features="test"
- name: Run space example
run: cargo run --example space
- name: Run dog breeds example
run: cargo run --example dog_breeds
- name: Run posql_db example (With Blitzar)
run: bash crates/proof-of-sql/examples/posql_db/run_example.sh
- name: Run posql_db example (Without Blitzar)
Expand Down Expand Up @@ -228,4 +230,4 @@ jobs:
- name: Install solhint
run: npm install -g solhint
- name: Run tests
run: solhint -c 'crates/proof-of-sql/.solhint.json' 'crates/proof-of-sql/**/*.sol' -w 0
run: solhint -c 'crates/proof-of-sql/.solhint.json' 'crates/proof-of-sql/**/*.sol' -w 0
4 changes: 4 additions & 0 deletions crates/proof-of-sql/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ required-features = [ "arrow" ]
name = "space"
required-features = [ "arrow" ]

[[example]]
name = "dog_breeds"
required-features = [ "arrow" ]

[[bench]]
name = "posql_benches"
harness = false
Expand Down
26 changes: 26 additions & 0 deletions crates/proof-of-sql/examples/dog_breeds/dog_breeds.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Name,Origin,Size,Lifespan
Labrador Retriever,Canada,Large,12
German Shepherd,Germany,Large,11
Chihuahua,Mexico,Small,14
Siberian Husky,Russia,Medium,12
Poodle,France,Medium,14
Shiba Inu,Japan,Small,13
Australian Shepherd,United States,Medium,13
Bernese Mountain Dog,Switzerland,Large,8
Beagle,United Kingdom,Small,12
Rottweiler,Germany,Large,9
Dachshund,Germany,Small,12
Golden Retriever,United Kingdom,Large,11
Bulldog,United Kingdom,Medium,8
Pug,China,Small,12
Great Dane,Germany,Large,8
Border Collie,United Kingdom,Medium,12
Akita,Japan,Large,10
Corgi,United Kingdom,Small,12
Doberman Pinscher,Germany,Large,10
Boxer,Germany,Medium,10
Shih Tzu,China,Small,13
Irish Setter,Ireland,Large,12
Alaskan Malamute,United States,Large,11
Cocker Spaniel,United Kingdom,Medium,12
Vizsla,Hungary,Medium,12
123 changes: 123 additions & 0 deletions crates/proof-of-sql/examples/dog_breeds/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//! This is a non-interactive example of using Proof of SQL with a dog breeds dataset.
//! To run this, use `cargo run --release --example dog_breeds`.
//!
//! NOTE: If this doesn't work because you do not have the appropriate GPU drivers installed,
//! you can run `cargo run --release --example dog_breeds --no-default-features --features="arrow cpu-perf"` instead. It will be slower for proof generation.

use arrow::datatypes::SchemaRef;
use arrow_csv::{infer_schema_from_files, ReaderBuilder};
use proof_of_sql::{
base::database::{OwnedTable, OwnedTableTestAccessor, TestAccessor},
proof_primitive::dory::{
DynamicDoryCommitment, DynamicDoryEvaluationProof, ProverSetup, PublicParameters,
VerifierSetup,
},
sql::{parse::QueryExpr, postprocessing::apply_postprocessing_steps, proof::QueryProof},
};
use rand::{rngs::StdRng, SeedableRng};
use std::{fs::File, time::Instant};

// We generate the public parameters and the setups used by the prover and verifier for the Dory PCS.
// The `max_nu` should be set such that the maximum table size is less than `2^(2*max_nu-1)`.
const DORY_SETUP_MAX_NU: usize = 8;
// This should be a "nothing-up-my-sleeve" phrase or number.
const DORY_SEED: [u8; 32] = *b"93c0d245eb104663bfdcd25e36bc3f97";

/// # Panics
/// Will panic if the query does not parse or the proof fails to verify.
fn prove_and_verify_query(
sql: &str,
accessor: &OwnedTableTestAccessor<DynamicDoryEvaluationProof>,
prover_setup: &ProverSetup,
verifier_setup: &VerifierSetup,
) {
// Parse the query:
println!("Parsing the query: {sql}...");
let now = Instant::now();
let query_plan = QueryExpr::<DynamicDoryCommitment>::try_new(
sql.parse().unwrap(),
"dog_breeds".parse().unwrap(),
accessor,
)
.unwrap();
println!("Done in {} ms.", now.elapsed().as_secs_f64() * 1000.);

// Generate the proof and result:
print!("Generating proof...");
let now = Instant::now();
let (proof, provable_result) = QueryProof::<DynamicDoryEvaluationProof>::new(
query_plan.proof_expr(),
accessor,
&prover_setup,
);
println!("Done in {} ms.", now.elapsed().as_secs_f64() * 1000.);

// Verify the result with the proof:
print!("Verifying proof...");
let now = Instant::now();
let result = proof
.verify(
query_plan.proof_expr(),
accessor,
&provable_result,
&verifier_setup,
)
.unwrap();
let result = apply_postprocessing_steps(result.table, query_plan.postprocessing());
println!("Verified in {} ms.", now.elapsed().as_secs_f64() * 1000.);

// Display the result
println!("Query Result:");
println!("{result:?}");
}

fn main() {
let mut rng = StdRng::from_seed(DORY_SEED);
let public_parameters = PublicParameters::rand(DORY_SETUP_MAX_NU, &mut rng);
let prover_setup = ProverSetup::from(&public_parameters);
let verifier_setup = VerifierSetup::from(&public_parameters);

let filename = "./crates/proof-of-sql/examples/dog_breeds/dog_breeds.csv";
let dog_breeds_batch = ReaderBuilder::new(SchemaRef::new(
infer_schema_from_files(&[filename.to_string()], b',', None, true).unwrap(),
))
.with_header(true)
.build(File::open(filename).unwrap())
.unwrap()
.next()
.unwrap()
.unwrap();

// Load the table into an "Accessor" so that the prover and verifier can access the data/commitments.
let mut accessor =
OwnedTableTestAccessor::<DynamicDoryEvaluationProof>::new_empty_with_setup(&prover_setup);
accessor.add_table(
"dog_breeds.breeds".parse().unwrap(),
OwnedTable::try_from(dog_breeds_batch).unwrap(),
0,
);

// Query 1: Count the total number of dog breeds
prove_and_verify_query(
"SELECT COUNT(*) AS total_breeds FROM breeds",
&accessor,
&prover_setup,
&verifier_setup,
);

// Query 2: List the names of large dog breeds
prove_and_verify_query(
"SELECT Name FROM breeds WHERE Size = 'Large'",
&accessor,
&prover_setup,
&verifier_setup,
);

// Query 3: List the top 5 countries with the most dog breeds, ordered by count
prove_and_verify_query(
"SELECT Origin, COUNT(*) AS breed_count FROM breeds GROUP BY Origin ORDER BY breed_count DESC LIMIT 5",
&accessor,
&prover_setup,
&verifier_setup,
);
}

0 comments on commit 72a2fbb

Please sign in to comment.