referrerpolicy=no-referrer-when-downgrade

snowbridge_pallet_ethereum_client/benchmarking/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
3use super::*;
4mod util;
5
6use crate::Pallet as EthereumBeaconClient;
7use frame_benchmarking::v2::*;
8use frame_system::RawOrigin;
9use snowbridge_beacon_primitives::{
10	fast_aggregate_verify,
11	merkle_proof::{generalized_index_length, subtree_index},
12	prepare_aggregate_pubkey, prepare_aggregate_signature, verify_merkle_branch,
13};
14use snowbridge_pallet_ethereum_client_fixtures::{
15	make_gloas_checkpoint as make_checkpoint,
16	make_gloas_finalized_header_update as make_finalized_header_update,
17	make_gloas_sync_committee_update as make_sync_committee_update,
18};
19use util::*;
20
21#[benchmarks]
22mod benchmarks {
23	use super::*;
24
25	#[benchmark]
26	fn force_checkpoint() -> Result<(), BenchmarkError> {
27		let checkpoint_update = make_checkpoint();
28		let block_root: H256 = checkpoint_update.header.hash_tree_root().unwrap();
29
30		#[extrinsic_call]
31		_(RawOrigin::Root, Box::new(*checkpoint_update));
32
33		assert!(<LatestFinalizedBlockRoot<T>>::get() == block_root);
34		assert!(<FinalizedBeaconState<T>>::get(block_root).is_some());
35
36		Ok(())
37	}
38
39	#[benchmark]
40	fn submit() -> Result<(), BenchmarkError> {
41		let caller: T::AccountId = whitelisted_caller();
42		let checkpoint_update = make_checkpoint();
43		let finalized_header_update = make_finalized_header_update();
44		let block_root: H256 = finalized_header_update.finalized_header.hash_tree_root().unwrap();
45		EthereumBeaconClient::<T>::process_checkpoint_update(&checkpoint_update)?;
46
47		#[extrinsic_call]
48		submit(RawOrigin::Signed(caller.clone()), Box::new(*finalized_header_update));
49
50		assert!(<LatestFinalizedBlockRoot<T>>::get() == block_root);
51		assert!(<FinalizedBeaconState<T>>::get(block_root).is_some());
52
53		Ok(())
54	}
55
56	#[benchmark]
57	fn submit_with_sync_committee() -> Result<(), BenchmarkError> {
58		let caller: T::AccountId = whitelisted_caller();
59		let checkpoint_update = make_checkpoint();
60		let sync_committee_update = make_sync_committee_update();
61		EthereumBeaconClient::<T>::process_checkpoint_update(&checkpoint_update)?;
62
63		#[extrinsic_call]
64		submit(RawOrigin::Signed(caller.clone()), Box::new(*sync_committee_update));
65
66		assert!(<NextSyncCommittee<T>>::exists());
67
68		Ok(())
69	}
70
71	#[benchmark(extra)]
72	fn bls_fast_aggregate_verify_pre_aggregated() -> Result<(), BenchmarkError> {
73		EthereumBeaconClient::<T>::process_checkpoint_update(&make_checkpoint())?;
74		let update = make_sync_committee_update();
75		let participant_pubkeys = participant_pubkeys::<T>(&update)?;
76		let signing_root = signing_root::<T>(&update)?;
77		let agg_sig =
78			prepare_aggregate_signature(&update.sync_aggregate.sync_committee_signature).unwrap();
79		let agg_pub_key = prepare_aggregate_pubkey(&participant_pubkeys).unwrap();
80
81		#[block]
82		{
83			agg_sig.fast_aggregate_verify_pre_aggregated(signing_root.as_bytes(), &agg_pub_key);
84		}
85
86		Ok(())
87	}
88
89	#[benchmark(extra)]
90	fn bls_fast_aggregate_verify() -> Result<(), BenchmarkError> {
91		EthereumBeaconClient::<T>::process_checkpoint_update(&make_checkpoint())?;
92		let update = make_sync_committee_update();
93		let current_sync_committee = <CurrentSyncCommittee<T>>::get();
94		let absent_pubkeys = absent_pubkeys::<T>(&update)?;
95		let signing_root = signing_root::<T>(&update)?;
96
97		#[block]
98		{
99			fast_aggregate_verify(
100				&current_sync_committee.aggregate_pubkey,
101				&absent_pubkeys,
102				signing_root,
103				&update.sync_aggregate.sync_committee_signature,
104			)
105			.unwrap();
106		}
107
108		Ok(())
109	}
110
111	#[benchmark(extra)]
112	fn verify_merkle_proof() -> Result<(), BenchmarkError> {
113		EthereumBeaconClient::<T>::process_checkpoint_update(&make_checkpoint())?;
114		let update = make_sync_committee_update();
115		let block_root: H256 = update.finalized_header.hash_tree_root().unwrap();
116
117		let finalized_root_gindex = EthereumBeaconClient::<T>::finalized_root_gindex_at_slot(
118			update.attested_header.slot,
119			T::ForkVersions::get(),
120		);
121		let verified;
122		#[block]
123		{
124			verified = verify_merkle_branch(
125				block_root,
126				&update.finality_branch,
127				subtree_index(finalized_root_gindex),
128				generalized_index_length(finalized_root_gindex),
129				update.attested_header.state_root,
130			);
131		}
132		assert!(verified, "benchmark must measure a real verification, not a length rejection");
133
134		Ok(())
135	}
136
137	impl_benchmark_test_suite!(EthereumBeaconClient, crate::mock::new_tester(), crate::mock::Test);
138}