snowbridge_pallet_ethereum_client/benchmarking/
mod.rs1use 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 ¤t_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}