Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add space example #292

Merged
merged 9 commits into from
Oct 22, 2024
Merged
2 changes: 2 additions & 0 deletions .github/workflows/lint-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ jobs:
run: cargo run --example hello_world --no-default-features --features="rayon test"
- name: Run hello_world example (Without Blitzar and Without Rayon)
run: cargo run --example hello_world --no-default-features --features="test"
- name: Run space example
run: cargo run --example space
- 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
7 changes: 6 additions & 1 deletion crates/proof-of-sql/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ default = ["arrow", "perf"]
arrow = ["dep:arrow", "std"]
blitzar = ["dep:blitzar", "dep:merlin", "std"]
test = ["dep:rand", "std"]
perf = ["blitzar", "rayon", "ark-ec/parallel", "ark-poly/parallel", "ark-ff/asm"]
perf = ["blitzar", "cpu-perf"]
cpu-perf = ["rayon", "ark-ec/parallel", "ark-poly/parallel", "ark-ff/asm"]
iajoiner marked this conversation as resolved.
Show resolved Hide resolved
rayon = ["dep:rayon", "std"]
std = ["snafu/std"]

Expand All @@ -90,6 +91,10 @@ required-features = ["test"]
name = "posql_db"
required-features = [ "arrow" ]

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

[[bench]]
name = "posql_benches"
harness = false
Expand Down
152 changes: 152 additions & 0 deletions crates/proof-of-sql/examples/space/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
//! This is an non-interactive example of using Proof of SQL with some space related datasets.
//! To run this, use `cargo run --release --example space`.
//!
//! NOTE: If this doesn't work because you do not have the appropriate GPU drivers installed,
//! you can run `cargo run --release --example space --no-default-features --features="arrow cpu-perf"` instead. It will be slower for proof generation.

// Note: the space_travellers.csv file was obtained from
// https://www.kaggle.com/datasets/kaushiksinghrawat/humans-to-have-visited-space
// under the Apache 2.0 license.

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)`.
// For a sampling:
// max_nu = 3 => max table size is 32 rows
// max_nu = 4 => max table size is 128 rows
// max_nu = 8 => max table size is 32768 rows
// max_nu = 10 => max table size is 0.5 million rows
// max_nu = 15 => max table size is 0.5 billion rows
// max_nu = 20 => max table size is 0.5 trillion rows
// Note: we will eventually load these from a file.
Comment on lines +24 to +33
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like these comments a lot

const DORY_SETUP_MAX_NU: usize = 8;
// This should be a "nothing-up-my-sleeve" phrase or number.
const DORY_SEED: [u8; 32] = *b"len 32 rng seed - Space and Time";

/// # 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(),
"space".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 filenames = [
"./crates/proof-of-sql/examples/space/space_travellers.csv",
"./crates/proof-of-sql/examples/space/planets.csv",
];
let [space_travellers_batch, planets_batch] = filenames.map(|filename| {
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(
"space.travellers".parse().unwrap(),
OwnedTable::try_from(space_travellers_batch).unwrap(),
0,
);
accessor.add_table(
"space.planets".parse().unwrap(),
OwnedTable::try_from(planets_batch).unwrap(),
0,
);

prove_and_verify_query(
"SELECT COUNT(*) AS total_travellers FROM travellers",
&accessor,
&prover_setup,
&verifier_setup,
);
prove_and_verify_query(
"SELECT Nationality, COUNT(*) AS num_travellers FROM travellers GROUP BY Nationality ORDER BY num_travellers",
&accessor,
&prover_setup,
&verifier_setup,
);
prove_and_verify_query(
"SELECT Flight, COUNT(*) AS num_travellers FROM travellers WHERE Date > timestamp '2000-01-01T00:00:00Z' GROUP BY Flight ORDER BY num_travellers DESC LIMIT 5",
&accessor,
&prover_setup,
&verifier_setup,
);
prove_and_verify_query(
"SELECT name FROM planets WHERE NOT dwarf",
&accessor,
&prover_setup,
&verifier_setup,
);
prove_and_verify_query(
"SELECT name, density FROM planets ORDER BY density DESC LIMIT 3",
&accessor,
&prover_setup,
&verifier_setup,
);
}
14 changes: 14 additions & 0 deletions crates/proof-of-sql/examples/space/planets.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Name,Distance,Dwarf,Density
Mercury,36,FALSE,5400
Venus,67,FALSE,5200
Earth,93,FALSE,5500
Mars,140,FALSE,3900
Ceres,260,TRUE,2200
Jupiter,480,FALSE,1300
Saturn,890,FALSE,700
Uranus,1800,FALSE,1300
Neptune,2800,FALSE,1600
Pluto,3700,TRUE,1900
Haumea,4000,TRUE,2000
Makemake,4300,TRUE,2100
Eris,6300,TRUE,1500
Loading
Loading