mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 16:51:03 +00:00
Child trie storage proof (#2433)
* proof on child trie * higher level api for child storage proof * boilerplate for proof from light fetch * actually check proof on light fetch * Do not break former encoding * tabify * tabify2 * Add child trie root tx to full_storage_root transaction. * Shorten long lines. * Temp rename for audit * Make full_storage a trait method * Name back and replace some code with full_storage where it looks fine. * fix indentations, remove unused import * flush child root to top when calculated * impl +1
This commit is contained in:
@@ -631,7 +631,7 @@ where
|
||||
Exec: CodeExecutor<H>,
|
||||
H::Out: Ord,
|
||||
{
|
||||
let trie_backend = proving_backend::create_proof_check_backend::<H>(root.into(), proof)?;
|
||||
let trie_backend = create_proof_check_backend::<H>(root.into(), proof)?;
|
||||
execution_proof_check_on_trie_backend(&trie_backend, overlay, exec, method, call_data)
|
||||
}
|
||||
|
||||
@@ -676,10 +676,29 @@ where
|
||||
H::Out: Ord
|
||||
{
|
||||
let trie_backend = backend.try_into_trie_backend()
|
||||
.ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box<Error>)?;
|
||||
.ok_or_else(
|
||||
||Box::new(ExecutionError::UnableToGenerateProof) as Box<Error>
|
||||
)?;
|
||||
prove_read_on_trie_backend(&trie_backend, key)
|
||||
}
|
||||
|
||||
/// Generate child storage read proof.
|
||||
pub fn prove_child_read<B, H>(
|
||||
backend: B,
|
||||
storage_key: &[u8],
|
||||
key: &[u8],
|
||||
) -> Result<(Option<Vec<u8>>, Vec<Vec<u8>>), Box<Error>>
|
||||
where
|
||||
B: Backend<H>,
|
||||
H: Hasher,
|
||||
H::Out: Ord
|
||||
{
|
||||
let trie_backend = backend.try_into_trie_backend()
|
||||
.ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box<Error>)?;
|
||||
prove_child_read_on_trie_backend(&trie_backend, storage_key, key)
|
||||
}
|
||||
|
||||
|
||||
/// Generate storage read proof on pre-created trie backend.
|
||||
pub fn prove_read_on_trie_backend<S, H>(
|
||||
trie_backend: &TrieBackend<S, H>,
|
||||
@@ -695,6 +714,23 @@ where
|
||||
Ok((result, proving_backend.extract_proof()))
|
||||
}
|
||||
|
||||
/// Generate storage read proof on pre-created trie backend.
|
||||
pub fn prove_child_read_on_trie_backend<S, H>(
|
||||
trie_backend: &TrieBackend<S, H>,
|
||||
storage_key: &[u8],
|
||||
key: &[u8]
|
||||
) -> Result<(Option<Vec<u8>>, Vec<Vec<u8>>), Box<Error>>
|
||||
where
|
||||
S: trie_backend_essence::TrieBackendStorage<H>,
|
||||
H: Hasher,
|
||||
H::Out: Ord
|
||||
{
|
||||
let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend);
|
||||
let result = proving_backend.child_storage(storage_key, key)
|
||||
.map_err(|e| Box::new(e) as Box<Error>)?;
|
||||
Ok((result, proving_backend.extract_proof()))
|
||||
}
|
||||
|
||||
/// Check storage read proof, generated by `prove_read` call.
|
||||
pub fn read_proof_check<H>(
|
||||
root: H::Out,
|
||||
@@ -705,10 +741,26 @@ where
|
||||
H: Hasher,
|
||||
H::Out: Ord
|
||||
{
|
||||
let proving_backend = proving_backend::create_proof_check_backend::<H>(root, proof)?;
|
||||
let proving_backend = create_proof_check_backend::<H>(root, proof)?;
|
||||
read_proof_check_on_proving_backend(&proving_backend, key)
|
||||
}
|
||||
|
||||
/// Check child storage read proof, generated by `prove_child_read` call.
|
||||
pub fn read_child_proof_check<H>(
|
||||
root: H::Out,
|
||||
proof: Vec<Vec<u8>>,
|
||||
storage_key: &[u8],
|
||||
key: &[u8],
|
||||
) -> Result<Option<Vec<u8>>, Box<Error>>
|
||||
where
|
||||
H: Hasher,
|
||||
H::Out: Ord
|
||||
{
|
||||
let proving_backend = create_proof_check_backend::<H>(root, proof)?;
|
||||
read_child_proof_check_on_proving_backend(&proving_backend, storage_key, key)
|
||||
}
|
||||
|
||||
|
||||
/// Check storage read proof on pre-created proving backend.
|
||||
pub fn read_proof_check_on_proving_backend<H>(
|
||||
proving_backend: &TrieBackend<MemoryDB<H>, H>,
|
||||
@@ -721,6 +773,19 @@ where
|
||||
proving_backend.storage(key).map_err(|e| Box::new(e) as Box<Error>)
|
||||
}
|
||||
|
||||
/// Check child storage read proof on pre-created proving backend.
|
||||
pub fn read_child_proof_check_on_proving_backend<H>(
|
||||
proving_backend: &TrieBackend<MemoryDB<H>, H>,
|
||||
storage_key: &[u8],
|
||||
key: &[u8],
|
||||
) -> Result<Option<Vec<u8>>, Box<Error>>
|
||||
where
|
||||
H: Hasher,
|
||||
H::Out: Ord
|
||||
{
|
||||
proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box<Error>)
|
||||
}
|
||||
|
||||
/// Sets overlayed changes' changes trie configuration. Returns error if configuration
|
||||
/// differs from previous OR config decode has failed.
|
||||
pub(crate) fn set_changes_trie_config(overlay: &mut OverlayedChanges, config: Option<Vec<u8>>, final_check: bool) -> Result<(), Box<Error>> {
|
||||
@@ -1001,11 +1066,40 @@ mod tests {
|
||||
let remote_root = remote_backend.storage_root(::std::iter::empty()).0;
|
||||
let remote_proof = prove_read(remote_backend, b"value2").unwrap().1;
|
||||
// check proof locally
|
||||
let local_result1 = read_proof_check::<Blake2Hasher>(remote_root, remote_proof.clone(), b"value2").unwrap();
|
||||
let local_result2 = read_proof_check::<Blake2Hasher>(remote_root, remote_proof.clone(), &[0xff]).is_ok();
|
||||
let local_result1 = read_proof_check::<Blake2Hasher>(
|
||||
remote_root,
|
||||
remote_proof.clone(),
|
||||
b"value2"
|
||||
).unwrap();
|
||||
let local_result2 = read_proof_check::<Blake2Hasher>(
|
||||
remote_root,
|
||||
remote_proof.clone(),
|
||||
&[0xff]
|
||||
).is_ok();
|
||||
// check that results are correct
|
||||
assert_eq!(local_result1, Some(vec![24]));
|
||||
assert_eq!(local_result2, false);
|
||||
// on child trie
|
||||
let remote_backend = trie_backend::tests::test_trie();
|
||||
let remote_root = remote_backend.storage_root(::std::iter::empty()).0;
|
||||
let remote_proof = prove_child_read(
|
||||
remote_backend,
|
||||
b":child_storage:default:sub1",
|
||||
b"value3"
|
||||
).unwrap().1;
|
||||
let local_result1 = read_child_proof_check::<Blake2Hasher>(
|
||||
remote_root,
|
||||
remote_proof.clone(),
|
||||
b":child_storage:default:sub1",b"value3"
|
||||
).unwrap();
|
||||
let local_result2 = read_child_proof_check::<Blake2Hasher>(
|
||||
remote_root,
|
||||
remote_proof.clone(),
|
||||
b":child_storage:default:sub1",
|
||||
b"value2"
|
||||
).unwrap();
|
||||
assert_eq!(local_result1, Some(vec![142]));
|
||||
assert_eq!(local_result2, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user