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 sushi example #317

Merged
merged 11 commits into from
Oct 25, 2024
2 changes: 2 additions & 0 deletions .github/workflows/lint-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ jobs:
run: cargo run --example avocado-prices
- name: Run plastics example
run: cargo run --example plastics
- name: Run sushi example
run: cargo run --example sushi
- 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 @@ -123,6 +123,10 @@ required-features = [ "arrow" ]
name = "avocado-prices"
required-features = [ "arrow" ]

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

[[bench]]
name = "posql_benches"
harness = false
Expand Down
13 changes: 13 additions & 0 deletions crates/proof-of-sql/examples/sushi/fish.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
nameEn,nameJa,kindEn,kindJa,pricePerPound
Tuna,Maguro,Lean Red Meat,Akami,25
Tuna,Maguro,Medium Fat Red Meat,Toro,65
Tuna,Maguro,Fatty Red Meat,Otoro,115
Bonito,Katsuo,Red Meat,Akami,20
Yellowtail,Hamachi,Red Meat,Akami,27
Salmon,Salmon,White Fish,Shiromi,17
Sea Bream,Tai,White Fish,Shiromi,32
Sea Bass,Suzuki,White Fish,Shiromi,28
Mackerel,Aji,Silver Skinned,Hikarimono,14
Sardine,Iwashi,Silver Skinned,Hikarimono,11
Scallops,Hotate,Shellfish,Kai,26
Ark-shell clams,Akagai,Shellfish,Kai,29
141 changes: 141 additions & 0 deletions crates/proof-of-sql/examples/sushi/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
//! This is an non-interactive example of using Proof of SQL with some sushi related datasets.
//! To run this, use `cargo run --example sushi`.

//! NOTE: If this doesn't work because you do not have the appropriate GPU drivers installed,
//! you can run `cargo run --release --example sushi --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, proof::QueryProof},
};
use rand::{rngs::StdRng, SeedableRng};
use std::{fs::File, time::Instant};

const DORY_SETUP_MAX_NU: usize = 8;
const DORY_SEED: [u8; 32] = *b"sushi-is-the-best-food-available";

/// # 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(),
"sushi".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();
println!("Verified in {} ms.", now.elapsed().as_secs_f64() * 1000.);
// Display the result
println!("Query Result:");
println!("{:?}", result.table);
}

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/sushi/fish.csv";
let fish_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();
println!("{fish_batch:?}");

// 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(
"sushi.fish".parse().unwrap(),
OwnedTable::try_from(fish_batch).unwrap(),
0,
);

prove_and_verify_query(
"SELECT * FROM fish",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT COUNT(*) FROM fish WHERE nameEn = 'Tuna'",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT kindEn FROM fish WHERE kindJa = 'Otoro'",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT kindEn FROM fish WHERE kindJa = 'Otoro'",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT * FROM fish WHERE pricePerPound > 25 AND pricePerPound < 75",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT kindJa, COUNT(*) FROM fish GROUP BY kindJa",
&accessor,
&prover_setup,
&verifier_setup,
);

prove_and_verify_query(
"SELECT kindJa, pricePerPound FROM fish WHERE nameEn = 'Tuna' ORDER BY pricePerPound ASC",
&accessor,
&prover_setup,
&verifier_setup,
);
}
Loading