Skip to content

Commit

Permalink
feat: add sushi example (#317)
Browse files Browse the repository at this point in the history
# Rationale for this change
Add sushi example to improve documentation.

# What changes are included in this PR?
+ added sushi example

# Are these changes tested?
Yes
```
Parsing the query: SELECT * FROM fish...
Done in 3.734125 ms.
Generating proof...Done in 155.35108400000001 ms.
Verifying proof...Verified in 47.697167 ms.
Query Result:
OwnedTable { table: {Identifier { name: "nameen" }: VarChar(["Tuna", "Tuna", "Tuna", "Bonito", "Yellowtail", "Salmon", "Sea Bream", "Sea Bass", "Mackerel", "Sardine", "Scallops", "Ark-shell clams"]), Identifier { name: "nameja" }: VarChar(["Maguro", "Maguro", "Maguro", "Katsuo", "Hamachi", "Salmon", "Tai", "Suzuki", "Aji", "Iwashi", "Hotate", "Akagai"]), Identifier { name: "kinden" }: VarChar(["Lean Red Meat", "Medium Fat Read Meat", "Fatty Red Meat", "Red Meat", "Red Meat", "White Fish", "White Fish", "White Fish", "Silver Skinned", "Silver Skinned", "Shellfish", "Shellfish"]), Identifier { name: "kindja" }: VarChar(["Akami", "Toro", "Otoro", "Akami", "Akami", "Shiromi", "Shiromi", "Shiromi", "Hikarimono", "Hikarimono", "Kai", "Kai"]), Identifier { name: "priceperpound" }: BigInt([25, 65, 115, 20, 27, 17, 32, 28, 14, 11, 26, 29])} }
Parsing the query: SELECT COUNT(*) FROM fish WHERE nameEn = 'Tuna'...
Done in 3.082333 ms.
Generating proof...Done in 67.26070800000001 ms.
Verifying proof...Verified in 18.704874999999998 ms.
Query Result:
OwnedTable { table: {Identifier { name: "__count__" }: BigInt([3])} }
Parsing the query: SELECT kindEn FROM fish WHERE kindJa = 'Otoro'...
Done in 0.718417 ms.
Generating proof...Done in 63.59820800000001 ms.
Verifying proof...Verified in 20.705375 ms.
Query Result:
OwnedTable { table: {Identifier { name: "kinden" }: VarChar(["Fatty Red Meat"])} }
Parsing the query: SELECT kindEn FROM fish WHERE kindJa = 'Otoro'...
Done in 0.547541 ms.
Generating proof...Done in 61.422833000000004 ms.
Verifying proof...Verified in 21.06175 ms.
Query Result:
OwnedTable { table: {Identifier { name: "kinden" }: VarChar(["Fatty Red Meat"])} }
Parsing the query: SELECT * FROM fish WHERE pricePerPound > 25 AND pricePerPound < 75...
Done in 1.942583 ms.
Generating proof...Done in 115.769708 ms.
Verifying proof...Verified in 32.798791 ms.
Query Result:
OwnedTable { table: {Identifier { name: "nameen" }: VarChar(["Tuna", "Yellowtail", "Sea Bream", "Sea Bass", "Scallops", "Ark-shell clams"]), Identifier { name: "nameja" }: VarChar(["Maguro", "Hamachi", "Tai", "Suzuki", "Hotate", "Akagai"]), Identifier { name: "kinden" }: VarChar(["Medium Fat Read Meat", "Red Meat", "White Fish", "White Fish", "Shellfish", "Shellfish"]), Identifier { name: "kindja" }: VarChar(["Toro", "Akami", "Shiromi", "Shiromi", "Kai", "Kai"]), Identifier { name: "priceperpound" }: BigInt([65, 27, 32, 28, 26, 29])} }
Parsing the query: SELECT kindJa, COUNT(*) FROM fish GROUP BY kindJa...
Done in 1.163541 ms.
Generating proof...Done in 60.395042000000004 ms.
Verifying proof...Verified in 18.322499999999998 ms.
Query Result:
OwnedTable { table: {Identifier { name: "kindja" }: VarChar(["Akami", "Hikarimono", "Kai", "Otoro", "Shiromi", "Toro"]), Identifier { name: "__count__" }: BigInt([3, 2, 2, 1, 3, 1])} }
Parsing the query: SELECT kindJa, pricePerPound FROM fish WHERE nameEn = 'Tuna' ORDER BY pricePerPound ASC...
Done in 1.0535830000000002 ms.
Generating proof...Done in 64.5145 ms.
Verifying proof...Verified in 21.811167 ms.
Query Result:
OwnedTable { table: {Identifier { name: "kindja" }: VarChar(["Akami", "Toro", "Otoro"]), Identifier { name: "priceperpound" }: BigInt([25, 65, 115])} }
```
  • Loading branch information
aw-sxt authored Oct 25, 2024
2 parents b5fed3d + 37235f4 commit df1d799
Show file tree
Hide file tree
Showing 4 changed files with 160 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 @@ -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,
);
}

0 comments on commit df1d799

Please sign in to comment.