Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
cd191cd
feat: allow for either aggregation-only or tabular-only queries
delehef Sep 10, 2024
719a0c0
Add Merkle-path verification gadget
nicholas-mainardi Sep 11, 2024
3794779
merge MPT extraction
nikkolasg Sep 12, 2024
3793aa1
is_multiplier
nikkolasg Sep 12, 2024
ebdd33a
multiplier for rows
nikkolasg Sep 12, 2024
071a2f0
and api
nikkolasg Sep 12, 2024
ac3443e
Add revelation circuit unproven offset
nicholas-mainardi Sep 12, 2024
3b735cd
refactoring of cell logic
nikkolasg Sep 13, 2024
2b3c289
wip
nikkolasg Sep 13, 2024
d3ae335
row leaf passing
nikkolasg Sep 13, 2024
ff8039c
Add APIs for simple select
nicholas-mainardi Sep 13, 2024
5079597
Update general query APIs
nicholas-mainardi Sep 13, 2024
36673ef
partial fixed
nikkolasg Sep 13, 2024
6713f66
full node fixed
nikkolasg Sep 13, 2024
90f8d1c
row tree test passing
nikkolasg Sep 13, 2024
3fe4b55
Fix build integration test
nicholas-mainardi Sep 13, 2024
8dcdc05
testing merge circuit
nikkolasg Sep 13, 2024
0ea3f41
API for merge
nikkolasg Sep 13, 2024
2d7de6f
adding one more circuit set size
nikkolasg Sep 13, 2024
f8a79d1
Fix build groth-16 crate
nicholas-mainardi Sep 13, 2024
e9c3bcb
wip
nikkolasg Sep 15, 2024
dbb8e7a
Refactor query test cases code
nicholas-mainardi Sep 16, 2024
799a60f
Merge with main
nicholas-mainardi Sep 16, 2024
b26ea94
fix: ORDER BY is not supported
delehef Sep 16, 2024
a36fd13
Merge pull request #355 from Lagrange-Labs/feat/drop-scalar-check
nikkolasg Sep 16, 2024
dfaa7d7
WiP: keep both queries types in a single test
nicholas-mainardi Sep 16, 2024
8fc299f
Merge branch 'main' into feat/tabular-queries
nicholas-mainardi Sep 16, 2024
76a4bdd
wip
nikkolasg Sep 17, 2024
4f7aec5
compiling
nikkolasg Sep 17, 2024
c0bb9a6
Merge branch 'feat/tabular-queries' into feat/unproven-limit-offset-q…
nicholas-mainardi Sep 18, 2024
28a3383
Working intergation test for simple select queries
nicholas-mainardi Sep 18, 2024
c3c199d
fmt
nicholas-mainardi Sep 18, 2024
170ad44
Run also commented test cases
nicholas-mainardi Sep 18, 2024
676dfec
Bind matching row keys and results in a single query
nicholas-mainardi Sep 18, 2024
34d88ec
Remove dead code
nicholas-mainardi Sep 18, 2024
689b929
Add distinct to circuit and Parsil
nicholas-mainardi Sep 19, 2024
56e0dde
Support DISTINCT and SELECT * queries in integration test
nicholas-mainardi Sep 19, 2024
17cd47f
Comment out test cases
nicholas-mainardi Sep 19, 2024
84fe37a
passing test
nikkolasg Sep 19, 2024
cd59ea3
More complex test case with wildcards
nicholas-mainardi Sep 19, 2024
d8bc019
integrated test refactor #1
nikkolasg Sep 19, 2024
1fb227d
refactoring #2 compiling
nikkolasg Sep 20, 2024
735b415
correct size of circuit set
nikkolasg Sep 20, 2024
cebaf1c
full refactoring #3
nikkolasg Sep 20, 2024
a1274ae
multiplier columns
nikkolasg Sep 20, 2024
aee4872
test case for merge
nikkolasg Sep 20, 2024
2ea4e0d
add metadata from contract
nikkolasg Sep 20, 2024
99022b6
merge updates
nikkolasg Sep 21, 2024
1024dbe
default sec cell
nikkolasg Sep 21, 2024
abd9989
debug storage root
nikkolasg Sep 21, 2024
c7bea49
fixing block
nikkolasg Sep 21, 2024
12e083f
ordered cells
nikkolasg Sep 21, 2024
f6a5647
more debug
nikkolasg Sep 21, 2024
4368993
debug
nikkolasg Sep 21, 2024
1d4c10e
fixing vdb row digest
nikkolasg Sep 21, 2024
e0ad8d5
correct update depending on type
nikkolasg Sep 21, 2024
8407145
fixing update of mapping
nikkolasg Sep 21, 2024
6352db1
final test
nikkolasg Sep 21, 2024
84cd5cb
handle deletion for single
nikkolasg Sep 21, 2024
619c950
multiple rows
nikkolasg Sep 22, 2024
ab88009
Update verifiable-db/src/cells_tree/api.rs
nikkolasg Sep 23, 2024
c580c01
Update verifiable-db/src/cells_tree/api.rs
nikkolasg Sep 23, 2024
2c51871
reviews first pass
nikkolasg Sep 23, 2024
8184bd3
correct conditional scalar mul
nikkolasg Sep 23, 2024
8b30e6a
better API
nikkolasg Sep 23, 2024
3b83417
more debug
nikkolasg Sep 23, 2024
e5635d0
more debug
nikkolasg Sep 23, 2024
1d05c47
Optimize SQL queries to get Merkle-path
nicholas-mainardi Sep 23, 2024
f877735
testing split digest
nikkolasg Sep 23, 2024
90e4d42
with correct name
nikkolasg Sep 23, 2024
5e057ed
more tests
nikkolasg Sep 23, 2024
9020e54
fixes
nikkolasg Sep 23, 2024
c90e821
query adaptable
nikkolasg Sep 23, 2024
edad5fa
putting back ignoring query
nikkolasg Sep 23, 2024
71c2ce7
Merge branch 'main' into feat/merge_table
nikkolasg Sep 23, 2024
8ce5ca1
Fix non-existence proven node selection
nicholas-mainardi Sep 25, 2024
185ff79
Comment to clarify non-existence node selection logic
nicholas-mainardi Sep 25, 2024
994a115
Check query upper bounds in Parsil + add LIMIT to query if missing
nicholas-mainardi Sep 26, 2024
5fd774f
Refactor revelation APIs to avoid calling ids_for_placeholder_hash
nicholas-mainardi Sep 26, 2024
c89fc0f
Add comment for cells tree hash construction
nicholas-mainardi Sep 27, 2024
0f706cf
Fix: ensure we always use the appropriate merge flag in rows tre circ…
nicholas-mainardi Oct 1, 2024
5a656bd
Merkle path with predecessor/successor gadget
nicholas-mainardi Oct 4, 2024
0cd9487
Merge branch 'main' into feat/merge_table
nikkolasg Oct 10, 2024
61dc87a
Universal query gadgets + refactor universal query circuit
nicholas-mainardi Oct 10, 2024
40ecb96
fmt
nicholas-mainardi Oct 10, 2024
f772131
Add universal_query_gadget file
nicholas-mainardi Oct 10, 2024
5916860
Merge branch 'feat/merge_table' into feat/tabular-queries
nicholas-mainardi Oct 15, 2024
9002398
Merge branch 'feat/tabular-queries' into feat/unproven-limit-offset-q…
nicholas-mainardi Oct 15, 2024
c87856f
Add LIMIT by default only in simple SELECT queries
nicholas-mainardi Oct 15, 2024
c7bd811
Avoid running wildcard queries on merged tables
nicholas-mainardi Oct 15, 2024
a5a6962
Fix parsil test
nicholas-mainardi Oct 15, 2024
94dca85
fix: MemoryStorage::all_keys_at should not return dead keys
delehef Oct 17, 2024
e58faee
feat: add random_key_at
delehef Oct 17, 2024
600a6e9
Address comments
nicholas-mainardi Oct 25, 2024
85cdb54
Merge branch 'feat/merge_table' into feat/tabular-queries
nicholas-mainardi Oct 29, 2024
791ba8a
Merge branch 'feat/tabular-queries' into feat/unproven-limit-offset-q…
nicholas-mainardi Oct 29, 2024
e17ff40
Merge branch 'feat/unproven-limit-offset-queries' into feat/merkle-pa…
nicholas-mainardi Oct 29, 2024
5e2df85
Simple Select Queries with Unchecked Offset (#365)
nicholas-mainardi Oct 29, 2024
55e0421
Merge branch 'feat/tabular-queries' into feat/merkle-path-with-succes…
nicholas-mainardi Oct 29, 2024
1b7a41c
Fix build
nicholas-mainardi Oct 30, 2024
5483d50
chore: clippy
delehef Oct 31, 2024
60d3f34
[parsil] correctly handle LIMIT/OFFSET
delehef Nov 5, 2024
35d9623
[mp2] use more explicit names
delehef Nov 5, 2024
5bb0490
fix: imports
delehef Nov 5, 2024
2e32687
Merge branch 'main' into feat/tabular-queries
nicholas-mainardi Nov 6, 2024
3644f30
Fix integration test + fmt
nicholas-mainardi Nov 6, 2024
6a27c73
use u32's for offset & limit
delehef Nov 6, 2024
ec32679
Fix test failing from time to time
nicholas-mainardi Nov 6, 2024
a65bf3b
merged with main
nikkolasg Nov 7, 2024
d23c0b7
add reset-db to devenv
delehef Nov 7, 2024
d008cf8
Update result check + re-enable test with nonexisting secondary index
nicholas-mainardi Nov 8, 2024
c8f4bff
Merge branch 'feat/tabular-queries' into feat/merkle-path-with-succes…
nicholas-mainardi Nov 13, 2024
71513df
Merge branch 'main' into feat/merkle-path-with-successor-gadget
nicholas-mainardi Nov 30, 2024
3bf074c
fmt
nicholas-mainardi Dec 2, 2024
fcf3030
Feat/batching circuit gadgets (#396)
nicholas-mainardi Jan 8, 2025
75ecf25
Merge remote-tracking branch 'origin/main' into feat/merkle-path-with…
silathdiir Jan 8, 2025
41017b7
Fix fmt.
silathdiir Jan 8, 2025
773b6a3
Delete useless `planner.rs`.
silathdiir Jan 8, 2025
e69232c
Fix MerkleTreeVdb aggregate in ryhope
nicholas-mainardi Jan 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
810 changes: 538 additions & 272 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions groth16-framework/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ itertools.workspace = true
rand.workspace = true
serial_test.workspace = true
sha2.workspace = true
mp2_test = { path = "../mp2-test" }

recursion_framework = { path = "../recursion-framework" }
verifiable-db = { path = "../verifiable-db" }
7 changes: 6 additions & 1 deletion groth16-framework/tests/common/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
use super::{NUM_PREPROCESSING_IO, NUM_QUERY_IO};
use groth16_framework::{compile_and_generate_assets, utils::clone_circuit_data};
use mp2_common::{C, D, F};
use mp2_test::circuit::TestDummyCircuit;
use recursion_framework::framework_testing::TestingRecursiveCircuits;
use verifiable_db::{
api::WrapCircuitParams,
query::pi_len,
revelation::api::Parameters as RevelationParameters,
test_utils::{
INDEX_TREE_MAX_DEPTH, MAX_NUM_COLUMNS, MAX_NUM_ITEMS_PER_OUTPUT, MAX_NUM_OUTPUTS,
Expand Down Expand Up @@ -40,6 +42,8 @@ impl TestContext {

// Generate a fake query circuit set.
let query_circuits = TestingRecursiveCircuits::<F, C, D, NUM_QUERY_IO>::default();
let dummy_universal_circuit =
TestDummyCircuit::<{ pi_len::<MAX_NUM_ITEMS_PER_OUTPUT>() }>::build();

// Create the revelation parameters.
let revelation_params = RevelationParameters::<
Expand All @@ -52,7 +56,8 @@ impl TestContext {
MAX_NUM_ITEMS_PER_OUTPUT,
MAX_NUM_PLACEHOLDERS,
>::build(
query_circuits.get_recursive_circuit_set(),
query_circuits.get_recursive_circuit_set(), // unused, so we provide a dummy one
dummy_universal_circuit.circuit_data().verifier_data(),
preprocessing_circuits.get_recursive_circuit_set(),
preprocessing_circuits
.verifier_data_for_input_proofs::<1>()
Expand Down
35 changes: 1 addition & 34 deletions mp2-common/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ mod test {
types::MAX_BLOCK_LEN,
utils::{Endianness, Packer},
};
use mp2_test::eth::{get_mainnet_url, get_sepolia_url};
use mp2_test::eth::get_sepolia_url;

#[tokio::test]
#[ignore]
Expand Down Expand Up @@ -426,39 +426,6 @@ mod test {
Ok(())
}

#[tokio::test]
async fn test_pidgy_pinguin_mapping_slot() -> Result<()> {
// first pinguin holder https://dune.com/queries/2450476/4027653
// holder: 0x188b264aa1456b869c3a92eeed32117ebb835f47
// NFT id https://opensea.io/assets/ethereum/0xbd3531da5cf5857e7cfaa92426877b022e612cf8/1116
let mapping_value =
Address::from_str("0x188B264AA1456B869C3a92eeeD32117EbB835f47").unwrap();
let nft_id: u32 = 1116;
let mapping_key = left_pad32(&nft_id.to_be_bytes());
let url = get_mainnet_url();
let provider = ProviderBuilder::new().on_http(url.parse().unwrap());

// extracting from
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol
// assuming it's using ERC731Enumerable that inherits ERC721
let mapping_slot = 2;
// pudgy pinguins
let pudgy_address = Address::from_str("0xBd3531dA5CF5857e7CfAA92426877b022e612cf8")?;
let query = ProofQuery::new_mapping_slot(pudgy_address, mapping_slot, mapping_key.to_vec());
let res = query
.query_mpt_proof(&provider, BlockNumberOrTag::Latest)
.await?;
let raw_address = ProofQuery::verify_storage_proof(&res)?;
// the value is actually RLP encoded !
let decoded_address: Vec<u8> = rlp::decode(&raw_address).unwrap();
let leaf_node: Vec<Vec<u8>> = rlp::decode_list(res.storage_proof[0].proof.last().unwrap());
println!("leaf_node[1].len() = {}", leaf_node[1].len());
// this is read in the same order
let found_address = Address::from_slice(&decoded_address.into_iter().collect::<Vec<u8>>());
assert_eq!(found_address, mapping_value);
Ok(())
}

#[tokio::test]
async fn test_kashish_contract_proof_query() -> Result<()> {
// https://sepolia.etherscan.io/address/0xd6a2bFb7f76cAa64Dad0d13Ed8A9EFB73398F39E#code
Expand Down
2 changes: 2 additions & 0 deletions mp2-common/src/group_hashing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ impl ToTargets for QuinticExtensionTarget {
}

impl FromTargets for CurveTarget {
const NUM_TARGETS: usize = CURVE_TARGET_LEN;

fn from_targets(t: &[Target]) -> Self {
assert!(t.len() >= CURVE_TARGET_LEN);
let x = QuinticExtensionTarget(t[0..EXTENSION_DEGREE].try_into().unwrap());
Expand Down
2 changes: 2 additions & 0 deletions mp2-common/src/keccak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ pub type OutputHash = Array<U32Target, PACKED_HASH_LEN>;
pub type OutputByteHash = Array<Target, HASH_LEN>;

impl FromTargets for OutputHash {
const NUM_TARGETS: usize = PACKED_HASH_LEN;

fn from_targets(t: &[Target]) -> Self {
OutputHash::from_array(array::from_fn(|i| U32Target(t[i])))
}
Expand Down
9 changes: 4 additions & 5 deletions mp2-common/src/u256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,11 +500,9 @@ impl<F: SerializableRichField<D>, const D: usize> CircuitBuilderU256<F, D>
left: &UInt256Target,
right: &UInt256Target,
) -> BoolTarget {
// left <= right iff left - right requires a borrow or left - right == 0
let (res, borrow) = self.sub_u256(left, right);
let less_than = BoolTarget::new_unsafe(borrow.0);
let is_eq = self.is_zero(&res);
self.or(less_than, is_eq)
// left <= right iff ! right < left
let is_greater = self.is_less_than_u256(right, left);
self.not(is_greater)
}

fn is_zero(&mut self, target: &UInt256Target) -> BoolTarget {
Expand Down Expand Up @@ -827,6 +825,7 @@ impl ToTargets for UInt256Target {
}

impl FromTargets for UInt256Target {
const NUM_TARGETS: usize = NUM_LIMBS;
// Expects big endian limbs as the standard format for IO
fn from_targets(t: &[Target]) -> Self {
Self::new_from_be_target_limbs(&t[..NUM_LIMBS]).unwrap()
Expand Down
60 changes: 45 additions & 15 deletions mp2-common/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anyhow::{anyhow, Result};
use itertools::Itertools;
use plonky2::field::extension::Extendable;
use plonky2::field::goldilocks_field::GoldilocksField;
use plonky2::hash::hash_types::{HashOut, HashOutTarget, RichField};
use plonky2::hash::hash_types::{HashOut, HashOutTarget, RichField, NUM_HASH_OUT_ELTS};
use plonky2::iop::target::{BoolTarget, Target};
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
use plonky2::plonk::circuit_builder::CircuitBuilder;
Expand All @@ -19,26 +19,25 @@ use sha3::Keccak256;

use crate::array::Targetable;
use crate::poseidon::{HashableField, H};
use crate::serialization::circuit_data_serialization::SerializableRichField;
use crate::{group_hashing::EXTENSION_DEGREE, types::HashOutput, ProofTuple};
use crate::{D, F};

const TWO_POWER_8: usize = 256;
const TWO_POWER_16: usize = 65536;
const TWO_POWER_24: usize = 16777216;

#[allow(dead_code)]
trait ConnectSlice {
fn connect_slice(&mut self, a: &[Target], b: &[Target]);
// check that the closure $f actually panics, printing $msg as error message if the function
// did not panic; this macro is employed in tests in place of #[should_panic] to ensure that a
// panic occurred in the expected function rather than in other parts of the test
#[macro_export]
macro_rules! check_panic {
($f: expr, $msg: expr) => {{
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe($f));
assert!(result.is_err(), $msg);
}};
}

impl ConnectSlice for CircuitBuilder<F, D> {
fn connect_slice(&mut self, a: &[Target], b: &[Target]) {
assert_eq!(a.len(), b.len());
for (ai, bi) in a.iter().zip(b) {
self.connect(*ai, *bi);
}
}
}
pub use check_panic;

pub fn verify_proof_tuple<
F: RichField + Extendable<D>,
Expand Down Expand Up @@ -326,17 +325,20 @@ pub fn pack_and_compute_poseidon_target<F: HashableField + Extendable<D>, const
b.hash_n_to_hash_no_pad::<H>(packed)
}

pub trait SelectHashBuilder {
pub trait HashBuilder {
/// Select `first_hash` or `second_hash` as output depending on the Boolean `cond`
fn select_hash(
&mut self,
cond: BoolTarget,
first_hash: &HashOutTarget,
second_hash: &HashOutTarget,
) -> HashOutTarget;

/// Determine whether `first_hash == second_hash`
fn hash_eq(&mut self, first_hash: &HashOutTarget, second_hash: &HashOutTarget) -> BoolTarget;
}

impl<F: RichField + Extendable<D>, const D: usize> SelectHashBuilder for CircuitBuilder<F, D> {
impl<F: RichField + Extendable<D>, const D: usize> HashBuilder for CircuitBuilder<F, D> {
fn select_hash(
&mut self,
cond: BoolTarget,
Expand All @@ -352,6 +354,28 @@ impl<F: RichField + Extendable<D>, const D: usize> SelectHashBuilder for Circuit
.collect_vec(),
)
}

fn hash_eq(&mut self, first_hash: &HashOutTarget, second_hash: &HashOutTarget) -> BoolTarget {
let _true = self._true();
first_hash
.elements
.iter()
.zip(second_hash.elements.iter())
.fold(_true, |acc, (first, second)| {
let is_eq = self.is_equal(*first, *second);
self.and(acc, is_eq)
})
}
}

pub trait SelectTarget {
/// Return `first` if `cond` is true, `second` otherwise
fn select<F: SerializableRichField<D>, const D: usize>(
b: &mut CircuitBuilder<F, D>,
cond: &BoolTarget,
first: &Self,
second: &Self,
) -> Self;
}

pub trait ToFields<F: RichField> {
Expand Down Expand Up @@ -414,10 +438,16 @@ impl<F: RichField> Fieldable<F> for u64 {
}

pub trait FromTargets {
/// Number of targets necessary to instantiate `Self`
const NUM_TARGETS: usize;

/// Number of targets in `t` must be at least `Self::NUM_TARGETS`
fn from_targets(t: &[Target]) -> Self;
}

impl FromTargets for HashOutTarget {
const NUM_TARGETS: usize = NUM_HASH_OUT_ELTS;

fn from_targets(t: &[Target]) -> Self {
HashOutTarget {
elements: create_array(|i| t[i]),
Expand Down
Loading