Skip to content

Commit

Permalink
feat: dinosaurs-example
Browse files Browse the repository at this point in the history
  • Loading branch information
henrymai committed Oct 23, 2024
1 parent aa8dac5 commit 31ed00b
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .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 dinosaurs example
run: cargo run --example dinosaurs
- 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
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 = "dinosaurs"
required-features = [ "arrow" ]

[[bench]]
name = "posql_benches"
harness = false
Expand Down
11 changes: 11 additions & 0 deletions crates/proof-of-sql/examples/dinosaurs/dinosaurs.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
id,name,period,diet,length_meters,weight_tons
1,Tyrannosaurus Rex,Cretaceous,Carnivore,12.3,7.0
2,Stegosaurus,Jurassic,Herbivore,9.0,5.5
3,Triceratops,Cretaceous,Herbivore,8.5,10.0
4,Velociraptor,Cretaceous,Carnivore,1.8,0.015
5,Brachiosaurus,Jurassic,Herbivore,26.0,50.0
6,Ankylosaurus,Cretaceous,Herbivore,6.5,6.0
7,Spinosaurus,Cretaceous,Carnivore,15.0,7.5
8,Diplodocus,Jurassic,Herbivore,27.0,25.0
9,Allosaurus,Jurassic,Carnivore,9.7,2.3
10,Parasaurolophus,Cretaceous,Herbivore,10.0,3.5
125 changes: 125 additions & 0 deletions crates/proof-of-sql/examples/dinosaurs/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//! This is a non-interactive example of using Proof of SQL with a dinosaur dataset.
//! To run this, use `cargo run --release --example dinosaurs`.
//!
//! NOTE: If this doesn't work because you do not have the appropriate GPU drivers installed,
//! you can run `cargo run --release --example dinosaurs --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::{
arrow_schema_utility::get_posql_compatible_schema, 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"262a6aa18b5c43d589677c13dd33e6dc";

/// # 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(),
"dinosaurs".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/dinosaurs/dinosaurs.csv";
let inferred_schema =
SchemaRef::new(infer_schema_from_files(&[filename.to_string()], b',', None, true).unwrap());
let posql_compatible_schema = get_posql_compatible_schema(&inferred_schema);

let dinosaurs_batch = ReaderBuilder::new(posql_compatible_schema)
.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(
"dinosaurs.dinosaurs".parse().unwrap(),
OwnedTable::try_from(dinosaurs_batch).unwrap(),
0,
);

prove_and_verify_query(
"SELECT COUNT(*) AS total_dinosaurs FROM dinosaurs",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT name, weight_tons FROM dinosaurs WHERE diet = 'Carnivore' ORDER BY weight_tons DESC LIMIT 1",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT name, length_meters FROM dinosaurs ORDER BY length_meters DESC LIMIT 3",
&accessor,
&prover_setup,
&verifier_setup,
);
}

0 comments on commit 31ed00b

Please sign in to comment.