Skip to content

Commit

Permalink
Allow child-trie-friendly proofs (#680)
Browse files Browse the repository at this point in the history
* Allow multiple trie roots in `DecodedTrieProof::entries`

* Pass as parameter the trie root hash when querying a proof

* Allow multiple roots in proofs and no longer pass trie root in config

* Fix tests

* Fix check in closest_ancestor

* Make the return value of iterating more clear
  • Loading branch information
tomaka authored Jun 7, 2023
1 parent 8677e15 commit 5dfc3ed
Show file tree
Hide file tree
Showing 6 changed files with 429 additions and 312 deletions.
84 changes: 42 additions & 42 deletions lib/src/sync/warp_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,6 @@ impl<TSrc, TRq> BuildRuntime<TSrc, TRq> {
let decoded_downloaded_runtime =
match proof_decode::decode_and_verify_proof(proof_decode::Config {
proof: &downloaded_runtime[..],
trie_root_hash: &header.state_root,
}) {
Ok(p) => p,
Err(err) => {
Expand All @@ -1221,33 +1220,34 @@ impl<TSrc, TRq> BuildRuntime<TSrc, TRq> {
}
};

let finalized_storage_code = match decoded_downloaded_runtime.storage_value(b":code") {
Some(Some((code, _))) => code,
Some(None) => {
self.inner.phase = Phase::DownloadFragments {
previous_verifier_values: Some((
header.clone(),
chain_information_finality.clone(),
)),
};
return (WarpSync::InProgress(self.inner), Some(Error::MissingCode));
}
None => {
self.inner.phase = Phase::DownloadFragments {
previous_verifier_values: Some((
header.clone(),
chain_information_finality.clone(),
)),
};
return (
WarpSync::InProgress(self.inner),
Some(Error::MerkleProofEntriesMissing),
);
}
};
let finalized_storage_code =
match decoded_downloaded_runtime.storage_value(&header.state_root, b":code") {
Some(Some((code, _))) => code,
Some(None) => {
self.inner.phase = Phase::DownloadFragments {
previous_verifier_values: Some((
header.clone(),
chain_information_finality.clone(),
)),
};
return (WarpSync::InProgress(self.inner), Some(Error::MissingCode));
}
None => {
self.inner.phase = Phase::DownloadFragments {
previous_verifier_values: Some((
header.clone(),
chain_information_finality.clone(),
)),
};
return (
WarpSync::InProgress(self.inner),
Some(Error::MerkleProofEntriesMissing),
);
}
};

let finalized_storage_heappages =
match decoded_downloaded_runtime.storage_value(b":heappages") {
match decoded_downloaded_runtime.storage_value(&header.state_root, b":heappages") {
Some(val) => val.map(|(v, _)| v),
None => {
self.inner.phase = Phase::DownloadFragments {
Expand Down Expand Up @@ -1421,7 +1421,6 @@ impl<TSrc, TRq> BuildChainInformation<TSrc, TRq> {
let proof = proof.take().unwrap();
let decoded_proof =
match proof_decode::decode_and_verify_proof(proof_decode::Config {
trie_root_hash: &header.state_root,
proof: proof.into_iter(),
}) {
Ok(d) => d,
Expand Down Expand Up @@ -1450,21 +1449,22 @@ impl<TSrc, TRq> BuildChainInformation<TSrc, TRq> {
match chain_info_builder {
chain_information::build::InProgress::StorageGet(get) => {
let proof = calls.get(&get.call_in_progress()).unwrap();
let value = match proof.storage_value(get.key().as_ref()) {
Some(v) => v.map(|(v, _)| v),
None => {
self.inner.phase = Phase::DownloadFragments {
previous_verifier_values: Some((
header.clone(),
chain_information_finality.clone(),
)),
};
return (
WarpSync::InProgress(self.inner),
Some(Error::MerkleProofEntriesMissing),
);
}
};
let value =
match proof.storage_value(&header.state_root, get.key().as_ref()) {
Some(v) => v.map(|(v, _)| v),
None => {
self.inner.phase = Phase::DownloadFragments {
previous_verifier_values: Some((
header.clone(),
chain_information_finality.clone(),
)),
};
return (
WarpSync::InProgress(self.inner),
Some(Error::MerkleProofEntriesMissing),
);
}
};

match get.inject_value(value.map(iter::once)) {
chain_information::build::ChainInformationBuild::Finished {
Expand Down
17 changes: 9 additions & 8 deletions lib/src/trie/prefix_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,11 @@ impl PrefixScan {
///
/// Returns an error if the proof is invalid. In that case, `self` isn't modified.
pub fn resume(mut self, proof: &[u8]) -> Result<ResumeOutcome, (Self, Error)> {
let decoded_proof = match proof_decode::decode_and_verify_proof(proof_decode::Config {
proof,
trie_root_hash: &self.trie_root_hash,
}) {
Ok(d) => d,
Err(err) => return Err((self, Error::InvalidProof(err))),
};
let decoded_proof =
match proof_decode::decode_and_verify_proof(proof_decode::Config { proof }) {
Ok(d) => d,
Err(err) => return Err((self, Error::InvalidProof(err))),
};

let mut non_terminal_queries = mem::take(&mut self.next_queries);

Expand All @@ -118,7 +116,10 @@ impl PrefixScan {
QueryTy::Direction => &query_key[..query_key.len() - 1],
};

match (decoded_proof.trie_node_info(info_of_node), query_ty) {
match (
decoded_proof.trie_node_info(&self.trie_root_hash, info_of_node),
query_ty,
) {
(Some(info), QueryTy::Exact) => info,
(Some(info), QueryTy::Direction) => {
match info.children.child(query_key[query_key.len() - 1]) {
Expand Down
Loading

0 comments on commit 5dfc3ed

Please sign in to comment.