Skip to content

Commit fed07b5

Browse files
committed
Add mmr proof and domain runtime code proof verification benchmark with criterion
Signed-off-by: linning <[email protected]>
1 parent 98646d8 commit fed07b5

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

crates/sp-domains-fraud-proof/benches/fraud_proof_verification.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,161 @@ fn bundle_to_tx(
4646
.into()
4747
}
4848

49+
enum Error {
50+
BadMmrProof,
51+
UnexpectedMmrProof,
52+
BadStoragePoof,
53+
}
54+
55+
// Helper function port from `pallet-domains`
56+
fn verify_mmr_proof_and_extract_state_root(
57+
mmr_leaf_proof: ConsensusChainMmrLeafProof<NumberFor<Block>, BlockHashFor<Block>, mmr::Hash>,
58+
expected_block_number: NumberFor<Block>,
59+
) -> Result<BlockHashFor<Block>, Error> {
60+
let leaf_data = MmrProofVerifier::verify_proof_and_extract_leaf(mmr_leaf_proof)
61+
.ok_or(Error::BadMmrProof)?;
62+
63+
// Ensure it is a proof of the exact block that we expected
64+
if expected_block_number != leaf_data.block_number() {
65+
return Err(Error::UnexpectedMmrProof);
66+
}
67+
68+
Ok(leaf_data.state_root())
69+
}
70+
71+
async fn prepare_mmr_proof_and_runtime_code_proof(
72+
tokio_handle: Handle,
73+
) -> (
74+
(TempDir, MockConsensusNode, EvmDomainNode),
75+
NumberFor<Block>,
76+
NumberFor<Block>,
77+
ConsensusChainMmrLeafProof<NumberFor<Block>, BlockHashFor<Block>, mmr::Hash>,
78+
DomainRuntimeCodeAt<NumberFor<Block>, BlockHashFor<Block>, mmr::Hash>,
79+
) {
80+
let directory = TempDir::new().expect("Must be able to create temporary directory");
81+
82+
// Start Ferdie
83+
let mut ferdie = MockConsensusNode::run(
84+
tokio_handle.clone(),
85+
Ferdie,
86+
BasePath::new(directory.path().join("ferdie")),
87+
);
88+
89+
// Run Alice (a evm domain authority node)
90+
let alice = domain_test_service::DomainNodeBuilder::new(
91+
tokio_handle.clone(),
92+
BasePath::new(directory.path().join("alice")),
93+
)
94+
.build_evm_node(Role::Authority, Alice, &mut ferdie)
95+
.await;
96+
97+
produce_blocks!(ferdie, alice, 5).await.unwrap();
98+
99+
let consensus_block_number = ferdie.client.info().best_number;
100+
let (parent_consensus_number, parent_consensus_hash) = {
101+
let best_hash = ferdie.client.info().best_hash;
102+
let header = ferdie.client.header(best_hash).unwrap().unwrap();
103+
(consensus_block_number - 1, header.parent_hash)
104+
};
105+
106+
produce_blocks!(ferdie, alice, 1).await.unwrap();
107+
108+
let consensus_state_root_mmr_proof =
109+
sc_domains::generate_mmr_proof(&ferdie.client, consensus_block_number).unwrap();
110+
111+
let domain_runtime_code_at_proof = {
112+
let mmr_proof =
113+
sc_domains::generate_mmr_proof(&ferdie.client, parent_consensus_number).unwrap();
114+
let domain_runtime_code_proof = DomainRuntimeCodeProof::generate(
115+
ferdie.client.as_ref(),
116+
parent_consensus_hash,
117+
0, // runtime_id
118+
&FPStorageKeyProvider::new(ferdie.client.clone()),
119+
)
120+
.unwrap();
121+
DomainRuntimeCodeAt {
122+
mmr_proof,
123+
domain_runtime_code_proof,
124+
}
125+
};
126+
127+
(
128+
(directory, ferdie, alice),
129+
consensus_block_number,
130+
parent_consensus_number,
131+
consensus_state_root_mmr_proof,
132+
domain_runtime_code_at_proof,
133+
)
134+
}
135+
136+
fn mmr_proof_and_runtime_code_proof_verification(c: &mut Criterion) {
137+
let rt = TokioRuntime::new().unwrap();
138+
let tokio_handle = rt.handle();
139+
140+
let (
141+
(_dir, ferdie, _alice),
142+
consensus_block_number,
143+
parent_consensus_block_number,
144+
consensus_state_root_mmr_proof,
145+
domain_runtime_code_proof,
146+
) = tokio_handle.block_on(prepare_mmr_proof_and_runtime_code_proof(
147+
tokio_handle.clone(),
148+
));
149+
let runtime_id = 0;
150+
let mut overlay = OverlayedChanges::default();
151+
let state = ferdie
152+
.backend
153+
.state_at(ferdie.client.info().best_hash)
154+
.unwrap();
155+
let mut ext = Ext::new(&mut overlay, &state, None);
156+
157+
c.bench_function("Consensus state root MMR proof verification", |b| {
158+
b.iter_batched(
159+
|| consensus_state_root_mmr_proof.clone(),
160+
|consensus_state_root_mmr_proof| {
161+
assert!(
162+
sp_externalities::set_and_run_with_externalities(&mut ext, || {
163+
verify_mmr_proof_and_extract_state_root(
164+
consensus_state_root_mmr_proof,
165+
consensus_block_number,
166+
)
167+
})
168+
.is_ok()
169+
);
170+
},
171+
BatchSize::SmallInput,
172+
)
173+
});
174+
175+
c.bench_function("Domain runtime code proof verification", |b| {
176+
b.iter_batched(
177+
|| domain_runtime_code_proof.clone(),
178+
|domain_runtime_code_proof| {
179+
assert!(
180+
sp_externalities::set_and_run_with_externalities(&mut ext, || {
181+
let DomainRuntimeCodeAt {
182+
mmr_proof,
183+
domain_runtime_code_proof,
184+
} = domain_runtime_code_proof;
185+
186+
let state_root = verify_mmr_proof_and_extract_state_root(
187+
mmr_proof,
188+
parent_consensus_block_number,
189+
)?;
190+
191+
<DomainRuntimeCodeProof as BasicStorageProof<Block>>::verify::<
192+
StorageKeyProvider,
193+
>(domain_runtime_code_proof, runtime_id, &state_root)
194+
.map_err(|_| Error::BadStoragePoof)
195+
})
196+
.is_ok()
197+
);
198+
},
199+
BatchSize::SmallInput,
200+
)
201+
});
202+
}
203+
49204
async fn prepare_fraud_proof(
50205
tokio_handle: Handle,
51206
bad_receipt_maker: impl Fn(&mut ExecutionReceiptFor<HeaderFor<DomainBlock>, Block, Balance>)
@@ -765,6 +920,7 @@ fn invalid_bundle_weight_fraud_proof_verification(c: &mut Criterion) {
765920

766921
criterion_group!(
767922
benches,
923+
mmr_proof_and_runtime_code_proof_verification,
768924
invalid_state_transition_proof_verification,
769925
valid_bundle_proof_verification,
770926
invalid_domain_extrinsics_root_fraud_proof,

0 commit comments

Comments
 (0)