Skip to content

Commit 8901eb2

Browse files
committed
Implement fraud proof verify on primary node
1 parent f1a7a84 commit 8901eb2

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

crates/sp-executor/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,16 @@ impl ExecutionArguments {
196196

197197
/// Error type of fraud proof verification on primary node.
198198
#[derive(RuntimeDebug)]
199-
pub struct VerificationError;
199+
pub enum VerificationError {
200+
/// Runtime code backend unavailable.
201+
RuntimeCodeBackend,
202+
/// Runtime code can not be fetched from the backend.
203+
RuntimeCode(&'static str),
204+
/// Failed to pass the execution proof check.
205+
BadProof(sp_std::boxed::Box<dyn sp_state_machine::Error>),
206+
/// The `post_state_root` calculated by farmer does not match the one declared in [`FraudProof`].
207+
BadPostStateRoot { expected: H256, got: H256 },
208+
}
200209

201210
/// Fraud proof for the state computation.
202211
#[derive(Decode, Encode, TypeInfo, PartialEq, Eq, Clone, RuntimeDebug)]

crates/subspace-fraud-proof/src/lib.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
88
#![warn(missing_docs)]
99

10-
use codec::Codec;
10+
use codec::{Codec, Decode, Encode};
1111
use hash_db::{HashDB, Hasher, Prefix};
1212
use sc_client_api::backend;
1313
use sc_client_api::execution_extensions::ExtensionsFactory;
@@ -206,8 +206,55 @@ impl<
206206
}
207207

208208
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+
}
211258
}
212259
}
213260

0 commit comments

Comments
 (0)