Skip to content

Commit

Permalink
fix: fix get_storage_proof
Browse files Browse the repository at this point in the history
The storage proofs were being returned out of order,
and certain use cases of the endpoint where there are no
storage keys but the root was still needed were not implemented.
  • Loading branch information
GMKrieger committed Jan 21, 2025
1 parent f3edbd7 commit 36a1656
Showing 1 changed file with 51 additions and 15 deletions.
66 changes: 51 additions & 15 deletions crates/rpc/src/method/get_storage_proof.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::HashSet;

use anyhow::Context;
use pathfinder_common::trie::TrieNode;
use pathfinder_common::{
Expand Down Expand Up @@ -378,7 +376,7 @@ fn get_class_proofs(
node_hash,
node: ProofNode(node),
})
.collect::<HashSet<_>>()
.collect::<Vec<_>>()
.into_iter()
.collect();
let classes_proof = NodeHashToNodeMappings(nodes);
Expand Down Expand Up @@ -423,7 +421,7 @@ fn get_contract_proofs(
node_hash,
node: ProofNode(node),
})
.collect::<HashSet<_>>()
.collect::<Vec<_>>()
.into_iter()
.collect();

Expand Down Expand Up @@ -476,24 +474,24 @@ fn get_contract_storage_proofs(
.context("Querying contract root index")?;

if let Some(root) = root {
let nodes: Vec<NodeHashToNodeMapping> = ContractsStorageTree::get_proofs(
ContractsStorageTree::get_proofs(
&tx,
csk.contract_address,
block_number,
&csk.storage_keys,
root,
)?
.into_iter()
.flatten()
.map(|(node, node_hash)| NodeHashToNodeMapping {
node_hash,
node: ProofNode(node),
})
.collect::<HashSet<_>>()
.into_iter()
.collect();

proofs.push(NodeHashToNodeMappings(nodes));
.for_each(|vec_nodes| {
let nodes = vec_nodes
.into_iter()
.map(|(node, node_hash)| NodeHashToNodeMapping {
node_hash,
node: ProofNode(node),
})
.collect::<Vec<_>>();
proofs.push(NodeHashToNodeMappings(nodes));
});
} else {
proofs.push(NodeHashToNodeMappings(vec![]));
}
Expand Down Expand Up @@ -872,6 +870,7 @@ mod tests {
Class,
ContractNonce,
ContractStorage,
ContractStorageEmptyKeys,
}

impl PartialRequest {
Expand Down Expand Up @@ -933,6 +932,25 @@ mod tests {
}]),
}
}
Self::ContractStorageEmptyKeys => {
let (contract_address, _update) = block
.state_update
.as_ref()
.unwrap()
.contract_updates
.iter()
.next()
.unwrap();
Input {
block_id: BlockId::Number(BlockNumber::new_or_panic(1)),
class_hashes: None,
contract_addresses: None,
contracts_storage_keys: Some(vec![ContractStorageKeys {
contract_address: *contract_address,
storage_keys: vec![],
}]),
}
}
}
}
}
Expand All @@ -941,6 +959,7 @@ mod tests {
#[case::class_request(PartialRequest::Class)]
#[case::contract_request(PartialRequest::ContractNonce)]
#[case::contract_storage_request(PartialRequest::ContractStorage)]
#[case::contract_storage_request(PartialRequest::ContractStorageEmptyKeys)]
#[tokio::test]
async fn partial_query(#[case] req: PartialRequest) {
use pathfinder_storage::fake::{fill, generate};
Expand Down Expand Up @@ -999,6 +1018,23 @@ mod tests {
assert!(output.contracts_proof.nodes.0.is_empty());
assert!(output.contracts_proof.contract_leaves_data.is_empty());
}
PartialRequest::ContractStorageEmptyKeys => {
// Some contract storage proof should be present
assert!(!output.contracts_storage_proofs.is_empty());
// It should have only one element and the nodes should be default empty
assert!(output.contracts_storage_proofs.len() == 1);
assert_eq!(
output.contracts_storage_proofs[0].0[0].node.0,
TrieNode::Binary {
left: Felt::default(),
right: Felt::default(),
}
);
// The rest should be empty
assert!(output.classes_proof.0.is_empty());
assert!(output.contracts_proof.nodes.0.is_empty());
assert!(output.contracts_proof.contract_leaves_data.is_empty());
}
}
}
}

0 comments on commit 36a1656

Please sign in to comment.