#![cfg(feature = "runtime-benchmarks")] use super::*; use frame_benchmarking::v2::*; use frame_support::dispatch::RawOrigin; #[benchmarks(where T: Config)] mod benchmarks { use super::*; #[benchmark] fn claim( p: Linear<1, { T::MaxProofDepth::get() }> ) -> Result<(), BenchmarkError> { let network_id = Default::default(); let current_account: T::AccountId = frame_benchmarking::whitelisted_caller(); let max_proof_depth = p; let minimum_donation_u128 = <::MinimumDonation as Get>::get(); let minimum_donation: BalanceOf = minimum_donation_u128.unique_saturated_into(); let dummy_shares_u128 = 420u128; let dummy_shares: BalanceOf = dummy_shares_u128.unique_saturated_into(); let secret_key = libsecp256k1::SecretKey::parse(&[69u8; 32]).unwrap(); let public_key = libsecp256k1::PublicKey::from_secret_key(&secret_key); let pubkey_raw = &public_key.serialize()[1..65]; let pubkey_hash = SubstrateKeccakHasher::hash(pubkey_raw); let mut evm_addr_bytes = [0u8; 20]; evm_addr_bytes.copy_from_slice(&pubkey_hash.as_ref()[12..32]); let dummy_evm_address = EvmAddress::from(evm_addr_bytes); let target_index = 0u32; let claim_package_init = ClaimPackage { shares: dummy_shares, merkle_proof: Default::default(), token_id: 0, index: target_index, }; let preimage_init = claim_package_init.get_preimage(&dummy_evm_address, network_id); let mut current_hash = SubstrateKeccakHasher::hash(&preimage_init); let mut proof_hashes = Vec::with_capacity(max_proof_depth as usize); let mut current_index = target_index as usize; let hash_len = SubstrateKeccakHasher::hash_len(); let mut combined = sp_std::vec![0u8; hash_len * 2]; for i in 0..max_proof_depth { let mut sibling_bytes = [0u8; 32]; sibling_bytes[24..32].copy_from_slice(&(i as u64).to_be_bytes()); let sibling_hash = EvmHash::from_slice(&sibling_bytes); proof_hashes.push(sibling_hash); let sibling_bytes_ref = sibling_hash.as_ref(); let hash_bytes = current_hash.as_ref(); if current_index % 2 == 0 { combined[..hash_len].copy_from_slice(hash_bytes); combined[hash_len..].copy_from_slice(sibling_bytes_ref); } else { combined[..hash_len].copy_from_slice(sibling_bytes_ref); combined[hash_len..].copy_from_slice(hash_bytes); } current_hash = SubstrateKeccakHasher::hash(&combined); current_index >>= 1; } let merkle_root = current_hash; let member_share = MemberShare { initiated_network: None, activated_shares: Default::default(), locked_balance: minimum_donation, }; MemberShares::::insert(¤t_account, member_share); let network_state = NetworkShare::new( dummy_shares, merkle_root, max_proof_depth, ); NetworkShares::::insert(&network_id, network_state); let global_state = ShareState::new(dummy_shares); GlobalShares::::put(global_state); let claim_package = ClaimPackage { index: 0, merkle_proof: BoundedVec::try_from(proof_hashes).unwrap(), shares: dummy_shares, token_id: 0 }; let preimage = claim_package.get_preimage(&dummy_evm_address, network_id); let preimage_hash = SubstrateKeccakHasher::hash(&preimage); let message_string_bytes = Pallet::::ethereum_signable_message( ¤t_account, &network_id, &preimage_hash ); let message_hash = SubstrateKeccakHasher::hash(&message_string_bytes); let mut message_bytes = [0u8; 32]; message_bytes.copy_from_slice(message_hash.as_ref()); let msg_to_sign = libsecp256k1::Message::parse(&message_bytes); let (sig, recovery_id) = libsecp256k1::sign(&msg_to_sign, &secret_key); let mut signature_raw = [0u8; 65]; signature_raw[0..32].copy_from_slice(&sig.r.b32()); signature_raw[32..64].copy_from_slice(&sig.s.b32()); signature_raw[64] = recovery_id.serialize(); let evm_signature = EvmSignature::from(signature_raw); #[extrinsic_call] claim( RawOrigin::Signed(current_account.clone()), network_id, claim_package, dummy_evm_address, evm_signature, ); assert_eq!(dummy_shares, GlobalShares::::get().claimed_shares); assert_eq!( dummy_shares, MemberShares::::get(¤t_account).activated_shares ); assert_eq!( dummy_shares, NetworkShares::::get(&network_id).claimed_shares(), ); Ok(()) } impl_benchmark_test_suite!( Pallet, crate::mock::new_test_ext(), crate::mock::Test, ); }