Skip to content

Commit

Permalink
resolves CRY-23
Browse files Browse the repository at this point in the history
  • Loading branch information
Zyouell committed Dec 23, 2024
1 parent 07ecb08 commit d4cbfe1
Show file tree
Hide file tree
Showing 10 changed files with 551 additions and 47 deletions.
7 changes: 2 additions & 5 deletions mp2-v1/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ TEST_BINDINGS_OUT_PATH=$(TEST_CONTRACT_PATH)/out/$(TEST_BINDINGS_FOLDER)

# Generate the integration test contract bindings.
bindings:
rm -rf $(TEST_BINDINGS_MOD_PATH) $(TEST_BINDINGS_OUT_PATH)

# Generate new bindings.
forge install --root $(TEST_CONTRACT_PATH)
forge bind --alloy --module --root $(TEST_CONTRACT_PATH)

# Move the bindings module to the integration test location.
mv -f $(TEST_BINDINGS_OUT_PATH) $(TEST_BINDINGS_MOD_PATH)
forge bind --bindings-path $(TEST_BINDINGS_MOD_PATH) --alloy --module --root $(TEST_CONTRACT_PATH) --extra-output abi --overwrite
cargo fmt


# Declare phony targets
.PHONY: bindings
2 changes: 1 addition & 1 deletion mp2-v1/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ fn metadata_digest_mapping(address: &Address, chain_id: u64, extra: Vec<u8>, slo
compute_leaf_mapping_metadata_digest(key_id, value_id, slot)
}

fn combine_digest_and_block(digest: Digest) -> HashOutput {
pub fn combine_digest_and_block(digest: Digest) -> HashOutput {
let block_id = identifier_block_column();
let inputs = digest
.to_fields()
Expand Down
42 changes: 28 additions & 14 deletions mp2-v1/src/values_extraction/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,27 +716,41 @@ mod tests {
let receipt_proof_infos = generate_receipt_test_info::<1, 0>();
let receipt_proofs = receipt_proof_infos.proofs();
let query = receipt_proof_infos.query();
// We check that we have enough receipts and then take the second and third info
// (the MPT proof for the first node is different).
// Then check that the node above both is a branch.
assert!(receipt_proofs.len() > 3);
let second_info = &receipt_proofs[1];
let third_info = &receipt_proofs[2];
// We need two nodes that are children of the same branch so we compare the last but two nodes for each of them until we find a case that works
let (info_one, info_two) = if let Some((one, two)) = receipt_proofs
.iter()
.enumerate()
.find_map(|(i, current_proof)| {
let current_node_second_to_last =
current_proof.mpt_proof[current_proof.mpt_proof.len() - 2].clone();
receipt_proofs
.iter()
.skip(i + 1)
.find(|find_info| {
find_info.mpt_proof[find_info.mpt_proof.len() - 2].clone()
== current_node_second_to_last
})
.map(|matching| (current_proof, matching))
}) {
(one, two)
} else {
panic!("No relevant events with same branch node parent")
};

let proof_length_1 = second_info.mpt_proof.len();
let proof_length_2 = third_info.mpt_proof.len();
let proof_length_1 = info_one.mpt_proof.len();
let proof_length_2 = info_two.mpt_proof.len();

let list_one = rlp::decode_list::<Vec<u8>>(&second_info.mpt_proof[proof_length_1 - 2]);
let list_two = rlp::decode_list::<Vec<u8>>(&third_info.mpt_proof[proof_length_2 - 2]);
let list_one = rlp::decode_list::<Vec<u8>>(&info_one.mpt_proof[proof_length_1 - 2]);
let list_two = rlp::decode_list::<Vec<u8>>(&info_two.mpt_proof[proof_length_2 - 2]);

assert!(list_one == list_two);
assert_eq!(list_one, list_two);
assert!(list_one.len() == 17);

println!("Generating params...");
let params = build_circuits_params();

println!("Proving leaf 1...");
let leaf_input_1 = CircuitInput::new_receipt_leaf(second_info, query);
let leaf_input_1 = CircuitInput::new_receipt_leaf(info_one, query);
let now = std::time::Instant::now();
let leaf_proof1 = generate_proof(&params, leaf_input_1).unwrap();
{
Expand All @@ -751,7 +765,7 @@ mod tests {
);

println!("Proving leaf 2...");
let leaf_input_2 = CircuitInput::new_receipt_leaf(third_info, query);
let leaf_input_2 = CircuitInput::new_receipt_leaf(info_two, query);
let now = std::time::Instant::now();
let leaf_proof2 = generate_proof(&params, leaf_input_2).unwrap();
println!(
Expand All @@ -762,7 +776,7 @@ mod tests {
// The branch case for receipts is identical to that of a mapping so we use the same api.
println!("Proving branch...");
let branch_input = CircuitInput::new_mapping_variable_branch(
second_info.mpt_proof[proof_length_1 - 2].clone(),
info_one.mpt_proof[proof_length_1 - 2].clone(),
vec![leaf_proof1, leaf_proof2],
);

Expand Down
91 changes: 90 additions & 1 deletion mp2-v1/src/values_extraction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,26 @@ pub(crate) const BLOCK_ID_DST: &[u8] = b"BLOCK_NUMBER";

/// Prefix used for making a topic column id.
const TOPIC_PREFIX: &[u8] = b"topic";
/// [`TOPIC_PREFIX`] as a [`str`]
const TOPIC_NAME: &str = "topic";

/// Prefix used for making a data column id.
const DATA_PREFIX: &[u8] = b"data";
/// [`DATA_PREFIX`] as a [`str`]
const DATA_NAME: &str = "data";

/// Prefix for transaction index
const TX_INDEX_PREFIX: &[u8] = b"tx index";

/// Prefix for log number
const LOG_NUMBER_PREFIX: &[u8] = b"log number";
/// [`LOG_NUMBER_PREFIX`] as a [`str`]
const LOG_NUMBER_NAME: &str = "log number";

/// Prefix for gas used
const GAS_USED_PREFIX: &[u8] = b" gas used";
const GAS_USED_PREFIX: &[u8] = b"gas used";
/// [`GAS_USED_PREFIX`] as a [`str`]
const GAS_USED_NAME: &str = "gas used";

pub fn identifier_block_column() -> u64 {
let inputs: Vec<F> = BLOCK_ID_DST.to_fields();
Expand Down Expand Up @@ -401,3 +409,84 @@ pub fn compute_receipt_leaf_value_digest<const NO_TOPICS: usize, const MAX_DATA:
})
.fold(Digest::NEUTRAL, |acc, p| acc + p)
}

/// Function that computes the column identifiers for the non-indexed columns together with their names as [`String`]s.
pub fn compute_non_indexed_receipt_column_ids<const NO_TOPICS: usize, const MAX_DATA: usize>(
event: &EventLogInfo<NO_TOPICS, MAX_DATA>,
) -> Vec<(String, GFp)> {
let log_number_input = [
event.address.as_slice(),
event.event_signature.as_slice(),
LOG_NUMBER_PREFIX,
]
.concat()
.into_iter()
.map(GFp::from_canonical_u8)
.collect::<Vec<GFp>>();
let log_number_column_id = H::hash_no_pad(&log_number_input).elements[0];

let gas_used_input = [
event.address.as_slice(),
event.event_signature.as_slice(),
GAS_USED_PREFIX,
]
.concat()
.into_iter()
.map(GFp::from_canonical_u8)
.collect::<Vec<GFp>>();
let gas_used_column_id = H::hash_no_pad(&gas_used_input).elements[0];

let topic_ids = event
.topics
.iter()
.enumerate()
.map(|(j, _)| {
let input = [
event.address.as_slice(),
event.event_signature.as_slice(),
TOPIC_PREFIX,
&[j as u8 + 1],
]
.concat()
.into_iter()
.map(GFp::from_canonical_u8)
.collect::<Vec<GFp>>();
(
format!("{}_{}", TOPIC_NAME, j + 1),
H::hash_no_pad(&input).elements[0],
)
})
.collect::<Vec<(String, GFp)>>();

let data_ids = event
.data
.iter()
.enumerate()
.map(|(j, _)| {
let input = [
event.address.as_slice(),
event.event_signature.as_slice(),
DATA_PREFIX,
&[j as u8 + 1],
]
.concat()
.into_iter()
.map(GFp::from_canonical_u8)
.collect::<Vec<GFp>>();
(
format!("{}_{}", DATA_NAME, j + 1),
H::hash_no_pad(&input).elements[0],
)
})
.collect::<Vec<(String, GFp)>>();

[
vec![
(LOG_NUMBER_NAME.to_string(), log_number_column_id),
(GAS_USED_NAME.to_string(), gas_used_column_id),
],
topic_ids,
data_ids,
]
.concat()
}
Binary file removed mp2-v1/store/test_proofs.store
Binary file not shown.
26 changes: 24 additions & 2 deletions mp2-v1/tests/common/cases/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ use anyhow::Result;
use log::info;

use crate::common::{
bindings::simple::Simple::{self, SimpleInstance},
bindings::{
eventemitter::EventEmitter::{self, EventEmitterInstance},
simple::Simple::{self, SimpleInstance},
},
TestContext,
};

use super::indexing::{ContractUpdate, SimpleSingleValue, UpdateSimpleStorage};
use super::indexing::{ContractUpdate, ReceiptUpdate, SimpleSingleValue, UpdateSimpleStorage};

pub struct Contract {
pub address: Address,
Expand Down Expand Up @@ -89,3 +92,22 @@ where
})
}
}

pub struct EventContract<T: Transport + Clone> {
pub instance: EventEmitterInstance<T, RootProvider<T, Ethereum>, Ethereum>,
}

impl<T: Transport + Clone> TestContract<T> for EventContract<T> {
type Update = ReceiptUpdate;
type Contract = EventEmitterInstance<T, RootProvider<T, Ethereum>>;

fn new(address: Address, provider: &RootProvider<T>) -> Self {
Self {
instance: EventEmitter::new(address, provider.clone()),
}
}

fn get_instance(&self) -> &Self::Contract {
&self.instance
}
}
Loading

0 comments on commit d4cbfe1

Please sign in to comment.