Skip to content

Commit

Permalink
Changed receipt proof query to make fewer calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Zyouell committed Feb 5, 2025
1 parent 143ffa6 commit f5c75af
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 51 deletions.
27 changes: 15 additions & 12 deletions mp2-common/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ impl<const NO_TOPICS: usize, const MAX_DATA_WORDS: usize> EventLogInfo<NO_TOPICS
&self,
provider: &RootProvider<T>,
block: BlockNumberOrTag,
) -> Result<Vec<ReceiptProofInfo>, MP2EthError> {
) -> Result<(Vec<ReceiptProofInfo>, B256), MP2EthError> {
let receipts = query_block_receipts(provider, block).await?;

let memdb = Arc::new(MemoryDB::new(true));
Expand Down Expand Up @@ -471,20 +471,23 @@ impl<const NO_TOPICS: usize, const MAX_DATA_WORDS: usize> EventLogInfo<NO_TOPICS
})?;
let mpt_root = receipts_trie.root_hash()?;

indices
.iter()
.map(|&tx_index| {
let key = tx_index.rlp_bytes();
Ok((
indices
.iter()
.map(|&tx_index| {
let key = tx_index.rlp_bytes();

let proof = receipts_trie.get_proof(&key[..])?;
let proof = receipts_trie.get_proof(&key[..])?;

Ok(ReceiptProofInfo {
mpt_proof: proof,
mpt_root,
tx_index,
Ok(ReceiptProofInfo {
mpt_proof: proof,
mpt_root,
tx_index,
})
})
})
.collect::<Result<Vec<ReceiptProofInfo>, MP2EthError>>()
.collect::<Result<Vec<ReceiptProofInfo>, MP2EthError>>()?,
B256::from(mpt_root.0),
))
}
}

Expand Down
12 changes: 9 additions & 3 deletions mp2-test/src/mpt_sequential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloy::{
eips::BlockNumberOrTag,
network::TransactionBuilder,
node_bindings::Anvil,
primitives::{Address, U256},
primitives::{Address, B256, U256},
providers::{ext::AnvilApi, Provider, ProviderBuilder},
sol,
};
Expand Down Expand Up @@ -56,6 +56,8 @@ pub struct ReceiptTestInfo<const NO_TOPICS: usize, const MAX_DATA_WORDS: usize>
pub event: EventLogInfo<NO_TOPICS, MAX_DATA_WORDS>,
/// The proofs for receipts relating to `self.query`
pub proofs: Vec<ReceiptProofInfo>,
/// The root of the Receipt Trie at this block (in case there are no relevant events)
pub receipts_root: B256,
}

impl<const NO_TOPICS: usize, const MAX_DATA_WORDS: usize>
Expand Down Expand Up @@ -275,11 +277,15 @@ pub fn generate_receipt_test_info<const NO_TOPICS: usize, const MAX_DATA_WORDS:
&events[0].signature(),
);

let proofs = event
let (proofs, receipts_root) = event
.query_receipt_proofs(rpc.root(), BlockNumberOrTag::Number(block_number))
.await
.unwrap();

ReceiptTestInfo { event, proofs }
ReceiptTestInfo {
event,
proofs,
receipts_root,
}
})
}
48 changes: 14 additions & 34 deletions mp2-v1/src/values_extraction/planner.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! This code returns an [`UpdateTree`] used to plan how we prove a series of values was extracted from a Merkle Patricia Trie.
use alloy::{
eips::BlockNumberOrTag,
network::Ethereum,
primitives::{keccak256, B256},
providers::{Provider, RootProvider},
providers::RootProvider,
transports::Transport,
};
use anyhow::Result;
Expand Down Expand Up @@ -310,21 +309,12 @@ impl<const NO_TOPICS: usize, const MAX_DATA_WORDS: usize> Extractable
provider: &RootProvider<T, Ethereum>,
) -> Result<ExtractionUpdatePlan<Self>, MP2PlannerError> {
// Query for the receipt proofs relating to this event at block number `epoch`
let proofs = self.query_receipt_proofs(provider, epoch.into()).await?;
let (proofs, receipt_root) = self.query_receipt_proofs(provider, epoch.into()).await?;

let mut proof_cache = HashMap::<B256, ProofData<Self>>::new();

// Convert the paths into their keys using keccak
if proofs.is_empty() {
let block = provider
.get_block_by_number(BlockNumberOrTag::Number(epoch), false.into())
.await
.map_err(|_| MP2PlannerError::FetchError)?
.ok_or(MP2PlannerError::UpdateTreeError(
"Fetched Block with no relevant events but the result was None".to_string(),
))?;
let receipt_root = block.header.receipts_root;

let dummy_input = InputEnum::Dummy(receipt_root);
let proof_data = ProofData::<Self> {
node: vec![],
Expand Down Expand Up @@ -426,12 +416,12 @@ impl<const NO_TOPICS: usize, const MAX_DATA_WORDS: usize> Extractable
#[cfg(test)]
pub mod tests {

use alloy::{eips::BlockNumberOrTag, primitives::Address, providers::ProviderBuilder, sol};
use alloy::{primitives::Address, providers::ProviderBuilder, sol};
use anyhow::anyhow;
use eth_trie::Trie;

use mp2_common::{
digest::Digest,
eth::{BlockUtil, ReceiptProofInfo},
eth::ReceiptProofInfo,
proof::ProofWithVK,
types::GFp,
utils::{Endianness, Packer},
Expand All @@ -451,18 +441,15 @@ pub mod tests {
async fn test_receipt_update_tree() -> Result<()> {
// First get the info we will feed in to our function
let epoch: u64 = 21362445;
let (block_util, event_info, _) = build_test_data(epoch).await?;
let (receipts_root, event_info, _) = build_test_data(epoch).await?;

let url = get_mainnet_url();
// get some tx and receipt
let provider = ProviderBuilder::new().on_http(url.parse().unwrap());

let extraction_plan = event_info.create_update_plan(epoch, &provider).await?;

assert_eq!(
*extraction_plan.update_tree.root(),
block_util.block.header.receipts_root
);
assert_eq!(*extraction_plan.update_tree.root(), receipts_root);
Ok(())
}

Expand All @@ -477,7 +464,7 @@ pub mod tests {

async fn test_receipt_proving(epoch: u64, pp: &PublicParameters<512, 5>) -> Result<()> {
// First get the info we will feed in to our function
let (mut block_util, event_info, proof_info) = build_test_data(epoch).await?;
let (receipts_root, event_info, proof_info) = build_test_data(epoch).await?;

let url = get_mainnet_url();
// get some tx and receipt
Expand Down Expand Up @@ -511,12 +498,7 @@ pub mod tests {
{
assert_eq!(
pi.root_hash(),
block_util
.receipts_trie
.root_hash()?
.0
.to_vec()
.pack(Endianness::Little)
receipts_root.0.to_vec().pack(Endianness::Little)
);
}

Expand All @@ -537,28 +519,26 @@ pub mod tests {
Ok(())
}

type TestData = (BlockUtil, EventLogInfo<2, 1>, Vec<ReceiptProofInfo>);
type TestData = (B256, EventLogInfo<2, 1>, Vec<ReceiptProofInfo>);
/// Function that fetches a block together with its transaction trie and receipt trie for testing purposes.
async fn build_test_data(block_number: u64) -> Result<TestData> {
let url = get_mainnet_url();
// get some tx and receipt
let provider = ProviderBuilder::new().on_http(url.parse()?);

// We fetch a specific block which we know includes transactions relating to the PudgyPenguins contract.
let block_util =
BlockUtil::fetch(&provider, BlockNumberOrTag::Number(block_number)).await?;

let event_info = test_receipt_trie_helper().await?;
let mut proof_info = vec![];
let mut root = B256::default();
let mut success = false;
for _ in 0..10 {
match event_info
.query_receipt_proofs(&provider, block_number.into())
.await
{
// For each of the logs return the transacion its included in, then sort and remove duplicates.
Ok(response) => {
Ok((response, fetched_root)) => {
proof_info = response;
root = fetched_root;
success = true;
break;
}
Expand All @@ -573,7 +553,7 @@ pub mod tests {
return Err(anyhow!("Could not query mainnet successfully"));
}

Ok((block_util, event_info, proof_info))
Ok((root, event_info, proof_info))
}

/// Function to build a list of [`ReceiptProofInfo`] for a set block.
Expand Down
4 changes: 2 additions & 2 deletions mp2-v1/tests/common/cases/table_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ where
let block_number = ctx.block_number().await;
let new_block_number = block_number as BlockPrimaryIndex;

let proof_infos = event
let (proof_infos, _) = event
.query_receipt_proofs(provider.root(), block_number.into())
.await
.unwrap();
Expand Down Expand Up @@ -934,7 +934,7 @@ where
let block_number = ctx.block_number().await;
let new_block_number = block_number as BlockPrimaryIndex;

let proof_infos = event
let (proof_infos, _) = event
.query_receipt_proofs(provider.root(), block_number.into())
.await
.unwrap();
Expand Down

0 comments on commit f5c75af

Please sign in to comment.