|
7 | 7 |
|
8 | 8 | #![warn(missing_docs)]
|
9 | 9 |
|
10 |
| -use codec::Codec; |
| 10 | +use codec::{Codec, Decode, Encode}; |
11 | 11 | use hash_db::{HashDB, Hasher, Prefix};
|
12 | 12 | use sc_client_api::backend;
|
13 | 13 | use sc_client_api::execution_extensions::ExtensionsFactory;
|
@@ -206,8 +206,55 @@ impl<
|
206 | 206 | }
|
207 | 207 |
|
208 | 208 | fn verify(&self, proof: &FraudProof) -> Result<(), VerificationError> {
|
209 |
| - // TODO: impl |
210 |
| - Ok(()) |
| 209 | + let FraudProof { |
| 210 | + pre_state_root, |
| 211 | + post_state_root, |
| 212 | + proof, |
| 213 | + execution_args, |
| 214 | + } = proof; |
| 215 | + |
| 216 | + // TODO: we should use parent_hash. |
| 217 | + let at = BlockId::Hash(Block::Hash::default()); |
| 218 | + |
| 219 | + let state = self |
| 220 | + .backend |
| 221 | + .state_at(at) |
| 222 | + .map_err(|_| VerificationError::RuntimeCodeBackend)?; |
| 223 | + |
| 224 | + let trie_backend = state |
| 225 | + .as_trie_backend() |
| 226 | + .ok_or(VerificationError::RuntimeCodeBackend)?; |
| 227 | + |
| 228 | + let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(trie_backend); |
| 229 | + let runtime_code = state_runtime_code |
| 230 | + .runtime_code() |
| 231 | + .map_err(VerificationError::RuntimeCode)?; |
| 232 | + |
| 233 | + let execution_result = sp_state_machine::execution_proof_check::<BlakeTwo256, _, _>( |
| 234 | + *pre_state_root, |
| 235 | + proof.clone(), |
| 236 | + &mut Default::default(), |
| 237 | + &self.executor, |
| 238 | + self.spawn_handle.clone(), |
| 239 | + execution_args.verifying_method(), |
| 240 | + execution_args.call_data(), |
| 241 | + &runtime_code, |
| 242 | + ) |
| 243 | + .map_err(VerificationError::BadProof)?; |
| 244 | + |
| 245 | + let new_post_state_root = |
| 246 | + execution_args.decode_execution_result::<Block::Header>(execution_result); |
| 247 | + let new_post_state_root = H256::decode(&mut new_post_state_root.encode().as_slice()) |
| 248 | + .expect("Block Hash must be H256; qed"); |
| 249 | + |
| 250 | + if new_post_state_root == *post_state_root { |
| 251 | + Ok(()) |
| 252 | + } else { |
| 253 | + Err(VerificationError::BadPostStateRoot { |
| 254 | + expected: new_post_state_root, |
| 255 | + got: *post_state_root, |
| 256 | + }) |
| 257 | + } |
211 | 258 | }
|
212 | 259 | }
|
213 | 260 |
|
|
0 commit comments