From 0ccbe84f7683e6dc1967041910e87f45608c460f Mon Sep 17 00:00:00 2001 From: ron Date: Sat, 2 Mar 2024 02:37:31 +0800 Subject: [PATCH 1/2] Replace bls libs with Arkwork's --- Cargo.lock | 7 + bridges/snowbridge/Cargo.lock | 7 + .../ethereum-client/src/benchmarking/mod.rs | 31 +- .../ethereum-client/src/benchmarking/util.rs | 18 +- .../pallets/ethereum-client/src/lib.rs | 38 +- .../pallets/ethereum-client/src/tests.rs | 12 +- .../snowbridge/primitives/beacon/Cargo.toml | 13 + .../snowbridge/primitives/beacon/src/bls.rs | 328 ++++++++++++++---- .../snowbridge/primitives/beacon/src/lib.rs | 9 +- .../snowbridge/primitives/beacon/src/types.rs | 45 +-- 10 files changed, 331 insertions(+), 177 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97c4400846b2..19a58bd7bdce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17760,6 +17760,12 @@ dependencies = [ name = "snowbridge-beacon-primitives" version = "0.9.0" dependencies = [ + "ark-bls12-381", + "ark-bls12-381-ext", + "ark-ec", + "ark-ff 0.4.2", + "ark-scale 0.0.12", + "ark-serialize 0.4.2", "byte-slice-cast", "frame-support", "frame-system", @@ -17769,6 +17775,7 @@ dependencies = [ "rlp", "scale-info", "serde", + "sha2 0.10.7", "snowbridge-ethereum", "snowbridge-milagro-bls", "sp-core", diff --git a/bridges/snowbridge/Cargo.lock b/bridges/snowbridge/Cargo.lock index f090b5a0395d..8a113ff7d717 100644 --- a/bridges/snowbridge/Cargo.lock +++ b/bridges/snowbridge/Cargo.lock @@ -5120,6 +5120,12 @@ dependencies = [ name = "snowbridge-beacon-primitives" version = "0.9.0" dependencies = [ + "ark-bls12-381", + "ark-bls12-381-ext", + "ark-ec", + "ark-ff 0.4.2", + "ark-scale", + "ark-serialize 0.4.2", "byte-slice-cast", "frame-support", "frame-system", @@ -5129,6 +5135,7 @@ dependencies = [ "rlp", "scale-info", "serde", + "sha2 0.10.8", "snowbridge-ethereum", "snowbridge-milagro-bls", "sp-core", diff --git a/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs b/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs index e1520cd71539..b659c7c802e1 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs @@ -9,10 +9,7 @@ use frame_system::RawOrigin; use snowbridge_pallet_ethereum_client_fixtures::*; -use primitives::{ - fast_aggregate_verify, prepare_aggregate_pubkey, prepare_aggregate_signature, - verify_merkle_branch, -}; +use primitives::{fast_aggregate_verify, verify_merkle_branch}; use util::*; #[benchmarks] @@ -83,39 +80,19 @@ mod benchmarks { Ok(()) } - #[benchmark(extra)] - fn bls_fast_aggregate_verify_pre_aggregated() -> Result<(), BenchmarkError> { - EthereumBeaconClient::::process_checkpoint_update(&make_checkpoint())?; - let update = make_sync_committee_update(); - let participant_pubkeys = participant_pubkeys::(&update)?; - let signing_root = signing_root::(&update)?; - let agg_sig = - prepare_aggregate_signature(&update.sync_aggregate.sync_committee_signature).unwrap(); - let agg_pub_key = prepare_aggregate_pubkey(&participant_pubkeys).unwrap(); - - #[block] - { - agg_sig.fast_aggregate_verify_pre_aggregated(signing_root.as_bytes(), &agg_pub_key); - } - - Ok(()) - } - #[benchmark(extra)] fn bls_fast_aggregate_verify() -> Result<(), BenchmarkError> { EthereumBeaconClient::::process_checkpoint_update(&make_checkpoint())?; let update = make_sync_committee_update(); - let current_sync_committee = >::get(); - let absent_pubkeys = absent_pubkeys::(&update)?; + let pub_keys = participant_pubkeys::(&update).unwrap(); let signing_root = signing_root::(&update)?; #[block] { fast_aggregate_verify( - ¤t_sync_committee.aggregate_pubkey, - &absent_pubkeys, + pub_keys, signing_root, - &update.sync_aggregate.sync_committee_signature, + update.sync_aggregate.sync_committee_signature, ) .unwrap(); } diff --git a/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/util.rs b/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/util.rs index 7e5ded6e1f0d..ec88af40f49c 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/util.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/util.rs @@ -1,10 +1,11 @@ +use codec::Decode; // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use crate::{ decompress_sync_committee_bits, Config, CurrentSyncCommittee, Pallet as EthereumBeaconClient, Update, ValidatorsRoot, Vec, }; -use primitives::PublicKeyPrepared; +use primitives::{PublicKeyPrepared, SyncCommitteePrepared}; use sp_core::H256; pub fn participant_pubkeys( @@ -12,7 +13,8 @@ pub fn participant_pubkeys( ) -> Result, &'static str> { let sync_committee_bits = decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits); - let current_sync_committee = >::get(); + let current_sync_committee: SyncCommitteePrepared<{ crate::config::SYNC_COMMITTEE_SIZE }> = + SyncCommitteePrepared::decode(&mut &>::get()[..]).unwrap(); let pubkeys = EthereumBeaconClient::::find_pubkeys( &sync_committee_bits, (*current_sync_committee.pubkeys).as_ref(), @@ -21,18 +23,6 @@ pub fn participant_pubkeys( Ok(pubkeys) } -pub fn absent_pubkeys(update: &Update) -> Result, &'static str> { - let sync_committee_bits = - decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits); - let current_sync_committee = >::get(); - let pubkeys = EthereumBeaconClient::::find_pubkeys( - &sync_committee_bits, - (*current_sync_committee.pubkeys).as_ref(), - false, - ); - Ok(pubkeys) -} - pub fn signing_root(update: &Update) -> Result { let validators_root = >::get(); let signing_root = EthereumBeaconClient::::signing_root( diff --git a/bridges/snowbridge/pallets/ethereum-client/src/lib.rs b/bridges/snowbridge/pallets/ethereum-client/src/lib.rs index a54d4a05ac58..6c149c037d0c 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/lib.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/lib.rs @@ -39,9 +39,9 @@ use frame_support::{ }; use frame_system::ensure_signed; use primitives::{ - fast_aggregate_verify, verify_merkle_branch, verify_receipt_proof, BeaconHeader, BlsError, - CompactBeaconState, CompactExecutionHeader, ExecutionHeaderState, ForkData, ForkVersion, - ForkVersions, PublicKeyPrepared, SigningData, + fast_aggregate_verify, verify_merkle_branch, verify_receipt_proof, ArkScaleProjective, + BeaconHeader, BlsError, CompactBeaconState, CompactExecutionHeader, ExecutionHeaderState, + ForkData, ForkVersion, ForkVersions, PublicKeyPrepared, SigningData, }; use snowbridge_core::{BasicOperatingMode, RingBufferMap}; use sp_core::H256; @@ -179,13 +179,13 @@ pub mod pallet { /// Sync committee for current period #[pallet::storage] - pub(super) type CurrentSyncCommittee = - StorageValue<_, SyncCommitteePrepared, ValueQuery>; + #[pallet::unbounded] + pub(super) type CurrentSyncCommittee = StorageValue<_, Vec, ValueQuery>; /// Sync committee for next period #[pallet::storage] - pub(super) type NextSyncCommittee = - StorageValue<_, SyncCommitteePrepared, ValueQuery>; + #[pallet::unbounded] + pub(super) type NextSyncCommittee = StorageValue<_, Vec, ValueQuery>; /// Latest imported execution header #[pallet::storage] @@ -318,7 +318,7 @@ pub mod pallet { let sync_committee_prepared: SyncCommitteePrepared = (&update.current_sync_committee) .try_into() .map_err(|_| >::BLSPreparePublicKeysFailed)?; - >::set(sync_committee_prepared); + >::set(sync_committee_prepared.encode()); >::kill(); InitialCheckpointRoot::::set(header_root); >::kill(); @@ -437,7 +437,10 @@ pub mod pallet { .hash_tree_root() .map_err(|_| Error::::SyncCommitteeHashTreeRootFailed)?; if update_attested_period == store_period && >::exists() { - let next_committee_root = >::get().root; + let next_sync_committee = + SyncCommitteePrepared::decode(&mut &>::get()[..]) + .map_err(|_| Error::::BLSPreparePublicKeysFailed)?; + let next_committee_root = next_sync_committee.root; ensure!( sync_committee_root == next_committee_root, Error::::InvalidSyncCommitteeUpdate @@ -461,8 +464,10 @@ pub mod pallet { } else { >::get() }; - let absent_pubkeys = - Self::find_pubkeys(&participation, (*sync_committee.pubkeys).as_ref(), false); + let sync_committee = SyncCommitteePrepared::decode(&mut &sync_committee[..]) + .map_err(|_| Error::::BLSPreparePublicKeysFailed)?; + let pubkeys = + Self::find_pubkeys(&participation, (*sync_committee.pubkeys).as_ref(), true); let signing_root = Self::signing_root( &update.attested_header, Self::validators_root(), @@ -472,10 +477,9 @@ pub mod pallet { // suggested start from the full set aggregate_pubkey then subtracting the absolute // minority that did not participate. fast_aggregate_verify( - &sync_committee.aggregate_pubkey, - &absent_pubkeys, + pubkeys, signing_root, - &update.sync_aggregate.sync_committee_signature, + update.sync_aggregate.sync_committee_signature, ) .map_err(|e| Error::::BLSVerificationFailed(e))?; @@ -503,10 +507,10 @@ pub mod pallet { update_finalized_period == store_period, >::InvalidSyncCommitteeUpdate ); - >::set(sync_committee_prepared); + >::set(sync_committee_prepared.encode()); } else if update_finalized_period == store_period + 1 { >::set(>::get()); - >::set(sync_committee_prepared); + >::set(sync_committee_prepared.encode()); } log::info!( target: LOG_TARGET, @@ -815,7 +819,7 @@ pub mod pallet { let mut pubkeys: Vec = Vec::new(); for (bit, pubkey) in sync_committee_bits.iter().zip(sync_committee_pubkeys.iter()) { if *bit == u8::from(participant) { - pubkeys.push(pubkey.clone()); + pubkeys.push(ArkScaleProjective::from(pubkey.0)); } } pubkeys diff --git a/bridges/snowbridge/pallets/ethereum-client/src/tests.rs b/bridges/snowbridge/pallets/ethereum-client/src/tests.rs index 50b6a25c3428..1deacb4a73be 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/tests.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/tests.rs @@ -317,8 +317,8 @@ fn find_absent_keys() { false, ); assert_eq!(pubkeys.len(), 2); - assert_eq!(pubkeys[0], sync_committee_prepared.pubkeys[0]); - assert_eq!(pubkeys[1], sync_committee_prepared.pubkeys[7]); + assert_eq!(pubkeys[0].0, sync_committee_prepared.pubkeys[0].0); + assert_eq!(pubkeys[1].0, sync_committee_prepared.pubkeys[7].0); }); } @@ -341,10 +341,10 @@ fn find_present_keys() { true, ); assert_eq!(pubkeys.len(), 4); - assert_eq!(pubkeys[0], sync_committee_prepared.pubkeys[1]); - assert_eq!(pubkeys[1], sync_committee_prepared.pubkeys[8]); - assert_eq!(pubkeys[2], sync_committee_prepared.pubkeys[26]); - assert_eq!(pubkeys[3], sync_committee_prepared.pubkeys[30]); + assert_eq!(pubkeys[0].0, sync_committee_prepared.pubkeys[1].0); + assert_eq!(pubkeys[1].0, sync_committee_prepared.pubkeys[8].0); + assert_eq!(pubkeys[2].0, sync_committee_prepared.pubkeys[26].0); + assert_eq!(pubkeys[3].0, sync_committee_prepared.pubkeys[30].0); }); } diff --git a/bridges/snowbridge/primitives/beacon/Cargo.toml b/bridges/snowbridge/primitives/beacon/Cargo.toml index 090bdb012365..8fcf63373288 100644 --- a/bridges/snowbridge/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/primitives/beacon/Cargo.toml @@ -33,12 +33,25 @@ snowbridge-ethereum = { path = "../ethereum", default-features = false } static_assertions = { version = "1.1.0" } milagro-bls = { package = "snowbridge-milagro-bls", version = "1.5.4", default-features = false } +# ark libs +ark-bls12-381 = { version = "0.4.0", default-features = false, features = ["curve"] } +ark-bls12-381-ext = { version = "0.4.1", default-features = false } +ark-ec = { version = "0.4.2", default-features = false } +ark-ff = { version = "0.4.2", default-features = false } +ark-serialize = { version = "0.4.1", default-features = false, features = ["derive"] } +sha2 = { version = "0.10.6", default-features = false } +ark-scale = { version = "0.0.12", features = ["hazmat"], default-features = false } + [dev-dependencies] hex-literal = { version = "0.4.1" } [features] default = ["std"] std = [ + "ark-bls12-381-ext/std", + "ark-bls12-381/std", + "ark-ec/std", + "ark-scale/std", "byte-slice-cast/std", "codec/std", "frame-support/std", diff --git a/bridges/snowbridge/primitives/beacon/src/bls.rs b/bridges/snowbridge/primitives/beacon/src/bls.rs index 589b72e67348..110c2db9ba35 100644 --- a/bridges/snowbridge/primitives/beacon/src/bls.rs +++ b/bridges/snowbridge/primitives/beacon/src/bls.rs @@ -1,16 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -use crate::{PublicKey, Signature}; use codec::{Decode, Encode}; -use frame_support::{ensure, PalletError}; -pub use milagro_bls::{ - AggregatePublicKey, AggregateSignature, PublicKey as PublicKeyPrepared, - Signature as SignaturePrepared, -}; +use frame_support::PalletError; use scale_info::TypeInfo; -use sp_core::H256; use sp_runtime::RuntimeDebug; -use sp_std::prelude::*; #[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, TypeInfo, RuntimeDebug, PalletError)] pub enum BlsError { @@ -18,70 +11,275 @@ pub enum BlsError { InvalidPublicKey, InvalidAggregatePublicKeys, SignatureVerificationFailed, + HashToCurveFailed, } -/// fast_aggregate_verify optimized with aggregate key subtracting absent ones. -pub fn fast_aggregate_verify( - aggregate_pubkey: &PublicKeyPrepared, - absent_pubkeys: &Vec, - message: H256, - signature: &Signature, -) -> Result<(), BlsError> { - let agg_sig = prepare_aggregate_signature(signature)?; - let agg_key = prepare_aggregate_pubkey_from_absent(aggregate_pubkey, absent_pubkeys)?; - fast_aggregate_verify_pre_aggregated(agg_sig, agg_key, message) -} +pub mod milagro { + use crate::{BlsError, PublicKey, Signature, SyncCommittee}; + use frame_support::{ + ensure, + pallet_prelude::{Decode, Encode, MaxEncodedLen, TypeInfo}, + }; + pub use milagro_bls::{ + AggregatePublicKey, AggregateSignature, PublicKey as PublicKeyPrepared, + Signature as SignaturePrepared, + }; + use snowbridge_ethereum::H256; + use sp_std::{boxed::Box, iter::repeat, prelude::*}; -/// Decompress one public key into a point in G1. -pub fn prepare_milagro_pubkey(pubkey: &PublicKey) -> Result { - PublicKeyPrepared::from_bytes_unchecked(&pubkey.0).map_err(|_| BlsError::InvalidPublicKey) -} + /// fast_aggregate_verify optimized with aggregate key subtracting absent ones. + pub fn fast_aggregate_verify( + aggregate_pubkey: &PublicKeyPrepared, + absent_pubkeys: &Vec, + message: H256, + signature: &Signature, + ) -> Result<(), BlsError> { + let agg_sig = prepare_aggregate_signature(signature)?; + let agg_key = prepare_aggregate_pubkey_from_absent(aggregate_pubkey, absent_pubkeys)?; + fast_aggregate_verify_pre_aggregated(agg_sig, agg_key, message) + } -/// Prepare for G1 public keys. -pub fn prepare_g1_pubkeys(pubkeys: &[PublicKey]) -> Result, BlsError> { - pubkeys - .iter() - // Deserialize one public key from compressed bytes - .map(prepare_milagro_pubkey) - .collect::, BlsError>>() -} + /// Decompress one public key into a point in G1. + pub fn prepare_milagro_pubkey(pubkey: &PublicKey) -> Result { + PublicKeyPrepared::from_bytes_unchecked(&pubkey.0).map_err(|_| BlsError::InvalidPublicKey) + } -/// Prepare for G1 AggregatePublicKey. -pub fn prepare_aggregate_pubkey( - pubkeys: &[PublicKeyPrepared], -) -> Result { - AggregatePublicKey::into_aggregate(pubkeys).map_err(|_| BlsError::InvalidPublicKey) -} + /// Prepare for G1 public keys. + pub fn prepare_g1_pubkeys(pubkeys: &[PublicKey]) -> Result, BlsError> { + pubkeys + .iter() + // Deserialize one public key from compressed bytes + .map(prepare_milagro_pubkey) + .collect::, BlsError>>() + } -/// Prepare for G1 AggregatePublicKey. -pub fn prepare_aggregate_pubkey_from_absent( - aggregate_key: &PublicKeyPrepared, - absent_pubkeys: &Vec, -) -> Result { - let mut aggregate_pubkey = AggregatePublicKey::from_public_key(aggregate_key); - if !absent_pubkeys.is_empty() { - let absent_aggregate_key = prepare_aggregate_pubkey(absent_pubkeys)?; - aggregate_pubkey.point.sub(&absent_aggregate_key.point); - } - Ok(AggregatePublicKey { point: aggregate_pubkey.point }) -} + /// Prepare for G1 AggregatePublicKey. + pub fn prepare_aggregate_pubkey( + pubkeys: &[PublicKeyPrepared], + ) -> Result { + AggregatePublicKey::into_aggregate(pubkeys).map_err(|_| BlsError::InvalidPublicKey) + } + + /// Prepare for G1 AggregatePublicKey. + pub fn prepare_aggregate_pubkey_from_absent( + aggregate_key: &PublicKeyPrepared, + absent_pubkeys: &Vec, + ) -> Result { + let mut aggregate_pubkey = AggregatePublicKey::from_public_key(aggregate_key); + if !absent_pubkeys.is_empty() { + let absent_aggregate_key = prepare_aggregate_pubkey(absent_pubkeys)?; + aggregate_pubkey.point.sub(&absent_aggregate_key.point); + } + Ok(AggregatePublicKey { point: aggregate_pubkey.point }) + } + + /// Prepare for G2 AggregateSignature, normally more expensive than G1 operation. + pub fn prepare_aggregate_signature( + signature: &Signature, + ) -> Result { + Ok(AggregateSignature::from_signature( + &SignaturePrepared::from_bytes(&signature.0).map_err(|_| BlsError::InvalidSignature)?, + )) + } + + /// fast_aggregate_verify_pre_aggregated which is the most expensive call in beacon light + /// client. + pub fn fast_aggregate_verify_pre_aggregated( + agg_sig: AggregateSignature, + aggregate_key: AggregatePublicKey, + message: H256, + ) -> Result<(), BlsError> { + ensure!( + agg_sig.fast_aggregate_verify_pre_aggregated(&message[..], &aggregate_key), + BlsError::SignatureVerificationFailed + ); + Ok(()) + } + + /// Prepared G1 public key of sync committee as it is stored in the runtime storage. + #[derive(Clone, PartialEq, Eq, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub struct SyncCommitteePrepared { + pub root: H256, + pub pubkeys: Box<[PublicKeyPrepared; COMMITTEE_SIZE]>, + pub aggregate_pubkey: PublicKeyPrepared, + } + + impl Default for SyncCommitteePrepared { + fn default() -> Self { + let pubkeys: Vec = + repeat(PublicKeyPrepared::default()).take(COMMITTEE_SIZE).collect(); + let pubkeys: Box<[PublicKeyPrepared; COMMITTEE_SIZE]> = + Box::new(pubkeys.try_into().map_err(|_| ()).expect("checked statically; qed")); -/// Prepare for G2 AggregateSignature, normally more expensive than G1 operation. -pub fn prepare_aggregate_signature(signature: &Signature) -> Result { - Ok(AggregateSignature::from_signature( - &SignaturePrepared::from_bytes(&signature.0).map_err(|_| BlsError::InvalidSignature)?, - )) + SyncCommitteePrepared { + root: H256::default(), + pubkeys, + aggregate_pubkey: PublicKeyPrepared::default(), + } + } + } + + impl TryFrom<&SyncCommittee> + for SyncCommitteePrepared + { + type Error = BlsError; + + fn try_from(sync_committee: &SyncCommittee) -> Result { + let g1_pubkeys = prepare_g1_pubkeys(&sync_committee.pubkeys)?; + let sync_committee_root = + sync_committee.hash_tree_root().expect("checked statically; qed"); + + Ok(SyncCommitteePrepared:: { + pubkeys: g1_pubkeys.try_into().map_err(|_| ()).expect("checked statically; qed"), + aggregate_pubkey: prepare_milagro_pubkey(&sync_committee.aggregate_pubkey)?, + root: sync_committee_root, + }) + } + } } -/// fast_aggregate_verify_pre_aggregated which is the most expensive call in beacon light client. -pub fn fast_aggregate_verify_pre_aggregated( - agg_sig: AggregateSignature, - aggregate_key: AggregatePublicKey, - message: H256, -) -> Result<(), BlsError> { - ensure!( - agg_sig.fast_aggregate_verify_pre_aggregated(&message[..], &aggregate_key), - BlsError::SignatureVerificationFailed - ); - Ok(()) +pub mod arkworks { + use crate::{BlsError, SyncCommittee}; + use ark_bls12_381::{ + g2::Config as G2Config, Bls12_381, G1Affine, G1Projective, G2Affine, G2Projective, + }; + use ark_ec::{ + hashing::{ + curve_maps::wb::WBMap, map_to_curve_hasher::MapToCurveBasedHasher, HashToCurve, + HashToCurveError, + }, + models::short_weierstrass::Projective, + pairing::Pairing, + AffineRepr, CurveGroup, + }; + use ark_ff::{field_hashers::DefaultFieldHasher, Zero}; + pub use ark_scale::hazmat::ArkScaleProjective; + use ark_serialize::*; + use core::{borrow::Borrow, ops::Neg}; + use frame_support::pallet_prelude::{Decode, Encode}; + use sha2::Sha256; + use snowbridge_ethereum::H256; + use sp_std::{boxed::Box, prelude::Vec}; + + /// Domain Separation Tag for signatures on G2 + pub const DST_G2: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; + + pub type PublicKeyPrepared = ArkScaleProjective; + + #[derive(Clone, Debug)] + pub struct Signature(G2Projective); + impl From for Signature { + fn from(sig: G2Projective) -> Signature { + Signature(sig) + } + } + impl AsRef for Signature { + fn as_ref(&self) -> &G2Projective { + &self.0 + } + } + impl Signature { + pub fn from_bytes(bytes: &[u8]) -> Result { + let p = G2Affine::deserialize_compressed_unchecked(bytes)?; + Ok(Self(p.into())) + } + + #[allow(dead_code)] + pub fn aggregate>( + signatures: impl IntoIterator, + ) -> Signature { + signatures.into_iter().map(|s| s.borrow().0).sum::().into() + } + } + + #[derive(Clone, Debug, Eq, PartialEq, Hash, CanonicalSerialize, CanonicalDeserialize)] + pub struct PublicKey(pub G1Projective); + impl From for PublicKey { + fn from(pk: G1Projective) -> PublicKey { + PublicKey(pk) + } + } + impl PublicKey { + pub fn from_bytes(bytes: &[u8]) -> Result { + let p = G1Affine::deserialize_compressed_unchecked(bytes)?; + Ok(Self(p.into())) + } + + pub fn encode_from_bytes(bytes: &[u8]) -> Result { + let pubkey = PublicKey::from_bytes(bytes)?; + Ok(ArkScaleProjective::from(pubkey.0)) + } + + pub fn aggregate>( + public_keys: impl IntoIterator, + ) -> PublicKey { + public_keys.into_iter().map(|s| s.borrow().0).sum::().into() + } + + pub fn verify(&self, signature: &Signature, message: &G2Projective) -> bool { + Bls12_381::multi_pairing( + [G1Affine::generator().neg(), self.0.into_affine()], + [signature.as_ref().into_affine(), message.into_affine()], + ) + .is_zero() + } + } + + pub fn prepare_pubkeys( + pubkeys: &[crate::PublicKey], + ) -> Result, SerializationError> { + pubkeys + .iter() + // Deserialize one public key from compressed bytes + .map(|pk| PublicKey::encode_from_bytes(pk.0.as_ref())) + .collect::, SerializationError>>() + } + + #[derive(Encode, Decode)] + pub struct SyncCommitteePrepared { + pub root: H256, + pub pubkeys: Box<[PublicKeyPrepared; COMMITTEE_SIZE]>, + pub aggregate_pubkey: PublicKeyPrepared, + } + + impl TryFrom<&SyncCommittee> + for SyncCommitteePrepared + { + type Error = SerializationError; + + fn try_from(sync_committee: &SyncCommittee) -> Result { + let aggregate_pubkey = + PublicKey::encode_from_bytes(sync_committee.aggregate_pubkey.0.as_ref())?; + let g1_pubkeys = prepare_pubkeys(&sync_committee.pubkeys)?; + let sync_committee_root = + sync_committee.hash_tree_root().expect("checked statically; qed"); + Ok(SyncCommitteePrepared:: { + pubkeys: g1_pubkeys.try_into().map_err(|_| ()).expect("checked statically; qed"), + aggregate_pubkey, + root: sync_committee_root, + }) + } + } + + pub fn hash_to_curve_g2(message: &[u8]) -> Result { + let wb_to_curve_hasher = MapToCurveBasedHasher::< + Projective, + DefaultFieldHasher, + WBMap, + >::new(DST_G2)?; + Ok(wb_to_curve_hasher.hash(message)?.into()) + } + + pub fn fast_aggregate_verify( + pub_keys: Vec, + message: H256, + signature: crate::Signature, + ) -> Result { + let sig = Signature::from_bytes(&signature.0).map_err(|_| BlsError::InvalidSignature)?; + let pub_keys: Vec = + pub_keys.into_iter().map(|pk| PublicKey::from(pk.0)).collect(); + let agg_pk = PublicKey::aggregate(pub_keys); + let msg = hash_to_curve_g2(&message.0).map_err(|_| BlsError::HashToCurveFailed)?; + Ok(agg_pk.verify(&sig, &msg)) + } } diff --git a/bridges/snowbridge/primitives/beacon/src/lib.rs b/bridges/snowbridge/primitives/beacon/src/lib.rs index 4c569d0176c2..605b81021c11 100644 --- a/bridges/snowbridge/primitives/beacon/src/lib.rs +++ b/bridges/snowbridge/primitives/beacon/src/lib.rs @@ -17,16 +17,17 @@ mod serde_utils; pub use types::{ BeaconHeader, CompactBeaconState, CompactExecutionHeader, ExecutionHeaderState, ExecutionPayloadHeader, FinalizedHeaderState, Fork, ForkData, ForkVersion, ForkVersions, Mode, - PublicKey, Signature, SigningData, SyncAggregate, SyncCommittee, SyncCommitteePrepared, + PublicKey, Signature, SigningData, SyncAggregate, SyncCommittee, VersionedExecutionPayloadHeader, }; pub use updates::{CheckpointUpdate, ExecutionHeaderUpdate, NextSyncCommitteeUpdate, Update}; pub use bits::decompress_sync_committee_bits; pub use bls::{ - fast_aggregate_verify, prepare_aggregate_pubkey, prepare_aggregate_pubkey_from_absent, - prepare_aggregate_signature, prepare_g1_pubkeys, AggregatePublicKey, AggregateSignature, - BlsError, PublicKeyPrepared, SignaturePrepared, + arkworks::{ + fast_aggregate_verify, ArkScaleProjective, PublicKeyPrepared, SyncCommitteePrepared, + }, + BlsError, }; pub use merkle_proof::verify_merkle_branch; pub use receipt::verify_receipt_proof; diff --git a/bridges/snowbridge/primitives/beacon/src/types.rs b/bridges/snowbridge/primitives/beacon/src/types.rs index 6f0886ba8b5c..f0e6d34c0ad8 100644 --- a/bridges/snowbridge/primitives/beacon/src/types.rs +++ b/bridges/snowbridge/primitives/beacon/src/types.rs @@ -5,7 +5,7 @@ use frame_support::{CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound}; use scale_info::TypeInfo; use sp_core::{H160, H256, U256}; use sp_runtime::RuntimeDebug; -use sp_std::{boxed::Box, iter::repeat, prelude::*}; +use sp_std::prelude::*; use crate::config::{PUBKEY_SIZE, SIGNATURE_SIZE}; @@ -23,9 +23,6 @@ use ssz_rs::SimpleSerializeError; pub use crate::bits::decompress_sync_committee_bits; -use crate::bls::{prepare_g1_pubkeys, prepare_milagro_pubkey, BlsError}; -use milagro_bls::PublicKey as PublicKeyPrepared; - pub type ValidatorIndex = u64; pub type ForkVersion = [u8; 4]; @@ -180,46 +177,6 @@ impl SyncCommittee { } } -/// Prepared G1 public key of sync committee as it is stored in the runtime storage. -#[derive(Clone, PartialEq, Eq, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct SyncCommitteePrepared { - pub root: H256, - pub pubkeys: Box<[PublicKeyPrepared; COMMITTEE_SIZE]>, - pub aggregate_pubkey: PublicKeyPrepared, -} - -impl Default for SyncCommitteePrepared { - fn default() -> Self { - let pubkeys: Vec = - repeat(PublicKeyPrepared::default()).take(COMMITTEE_SIZE).collect(); - let pubkeys: Box<[PublicKeyPrepared; COMMITTEE_SIZE]> = - Box::new(pubkeys.try_into().map_err(|_| ()).expect("checked statically; qed")); - - SyncCommitteePrepared { - root: H256::default(), - pubkeys, - aggregate_pubkey: PublicKeyPrepared::default(), - } - } -} - -impl TryFrom<&SyncCommittee> - for SyncCommitteePrepared -{ - type Error = BlsError; - - fn try_from(sync_committee: &SyncCommittee) -> Result { - let g1_pubkeys = prepare_g1_pubkeys(&sync_committee.pubkeys)?; - let sync_committee_root = sync_committee.hash_tree_root().expect("checked statically; qed"); - - Ok(SyncCommitteePrepared:: { - pubkeys: g1_pubkeys.try_into().map_err(|_| ()).expect("checked statically; qed"), - aggregate_pubkey: prepare_milagro_pubkey(&sync_committee.aggregate_pubkey)?, - root: sync_committee_root, - }) - } -} - /// Beacon block header as it is stored in the runtime storage. The block root is the /// Merkleization of a BeaconHeader. #[derive( From 873a7fe16e77ce458edb48dd3ceadb498285e2e4 Mon Sep 17 00:00:00 2001 From: ron Date: Sat, 2 Mar 2024 02:37:55 +0800 Subject: [PATCH 2/2] Benchmark --- ...wbridge_pallet_arkworks_ethereum_client.rs | 136 ++++++++++++++++++ ...owbridge_pallet_milagro_ethereum_client.rs | 136 ++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_arkworks_ethereum_client.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_milagro_ethereum_client.rs diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_arkworks_ethereum_client.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_arkworks_ethereum_client.rs new file mode 100644 index 000000000000..65b56b37c5c7 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_arkworks_ethereum_client.rs @@ -0,0 +1,136 @@ + +//! Autogenerated weights for `snowbridge_pallet_ethereum_client` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `yangdebijibendiannao.local`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/release/polkadot-parachain +// benchmark +// pallet +// --chain=bridge-hub-rococo-dev +// --pallet=snowbridge_pallet_ethereum_client +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --steps +// 50 +// --repeat +// 2 +// --output +// ./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_arkworks_ethereum_client.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `snowbridge_pallet_ethereum_client`. +pub struct WeightInfo(PhantomData); +impl snowbridge_pallet_ethereum_client::WeightInfo for WeightInfo { + /// Storage: `EthereumBeaconClient::FinalizedBeaconStateIndex` (r:1 w:1) + /// Proof: `EthereumBeaconClient::FinalizedBeaconStateIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconStateMapping` (r:1 w:1) + /// Proof: `EthereumBeaconClient::FinalizedBeaconStateMapping` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::NextSyncCommittee` (r:0 w:1) + /// Proof: `EthereumBeaconClient::NextSyncCommittee` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `EthereumBeaconClient::InitialCheckpointRoot` (r:0 w:1) + /// Proof: `EthereumBeaconClient::InitialCheckpointRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ValidatorsRoot` (r:0 w:1) + /// Proof: `EthereumBeaconClient::ValidatorsRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:0 w:1) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::CurrentSyncCommittee` (r:0 w:1) + /// Proof: `EthereumBeaconClient::CurrentSyncCommittee` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:0 w:1) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:0 w:1) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + fn force_checkpoint() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3501` + // Minimum execution time: 98_573_000_000 picoseconds. + Weight::from_parts(99_292_000_000, 0) + .saturating_add(Weight::from_parts(0, 3501)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: `EthereumBeaconClient::OperatingMode` (r:1 w:0) + /// Proof: `EthereumBeaconClient::OperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::NextSyncCommittee` (r:1 w:0) + /// Proof: `EthereumBeaconClient::NextSyncCommittee` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `EthereumBeaconClient::CurrentSyncCommittee` (r:1 w:0) + /// Proof: `EthereumBeaconClient::CurrentSyncCommittee` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `EthereumBeaconClient::ValidatorsRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::ValidatorsRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `74285` + // Estimated: `75770` + // Minimum execution time: 16_009_000_000 picoseconds. + Weight::from_parts(16_039_000_000, 0) + .saturating_add(Weight::from_parts(0, 75770)) + .saturating_add(T::DbWeight::get().reads(7)) + } + /// Storage: `EthereumBeaconClient::OperatingMode` (r:1 w:0) + /// Proof: `EthereumBeaconClient::OperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::NextSyncCommittee` (r:1 w:1) + /// Proof: `EthereumBeaconClient::NextSyncCommittee` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `EthereumBeaconClient::CurrentSyncCommittee` (r:1 w:0) + /// Proof: `EthereumBeaconClient::CurrentSyncCommittee` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `EthereumBeaconClient::ValidatorsRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::ValidatorsRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn submit_with_sync_committee() -> Weight { + // Proof Size summary in bytes: + // Measured: `74285` + // Estimated: `75770` + // Minimum execution time: 114_781_000_000 picoseconds. + Weight::from_parts(115_581_000_000, 0) + .saturating_add(Weight::from_parts(0, 75770)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `EthereumBeaconClient::OperatingMode` (r:1 w:0) + /// Proof: `EthereumBeaconClient::OperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:1 w:1) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ExecutionHeaderIndex` (r:1 w:1) + /// Proof: `EthereumBeaconClient::ExecutionHeaderIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ExecutionHeaderMapping` (r:1 w:1) + /// Proof: `EthereumBeaconClient::ExecutionHeaderMapping` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ExecutionHeaders` (r:0 w:1) + /// Proof: `EthereumBeaconClient::ExecutionHeaders` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`) + fn submit_execution_header() -> Weight { + // Proof Size summary in bytes: + // Measured: `380` + // Estimated: `3537` + // Minimum execution time: 113_000_000 picoseconds. + Weight::from_parts(120_000_000, 0) + .saturating_add(Weight::from_parts(0, 3537)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_milagro_ethereum_client.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_milagro_ethereum_client.rs new file mode 100644 index 000000000000..cf5c89032dad --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_milagro_ethereum_client.rs @@ -0,0 +1,136 @@ + +//! Autogenerated weights for `snowbridge_pallet_ethereum_client` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `yangdebijibendiannao.local`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/release/polkadot-parachain +// benchmark +// pallet +// --chain=bridge-hub-rococo-dev +// --pallet=snowbridge_pallet_ethereum_client +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --steps +// 50 +// --repeat +// 2 +// --output +// ./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `snowbridge_pallet_ethereum_client`. +pub struct WeightInfo(PhantomData); +impl snowbridge_pallet_ethereum_client::WeightInfo for WeightInfo { + /// Storage: `EthereumBeaconClient::FinalizedBeaconStateIndex` (r:1 w:1) + /// Proof: `EthereumBeaconClient::FinalizedBeaconStateIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconStateMapping` (r:1 w:1) + /// Proof: `EthereumBeaconClient::FinalizedBeaconStateMapping` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::NextSyncCommittee` (r:0 w:1) + /// Proof: `EthereumBeaconClient::NextSyncCommittee` (`max_values`: Some(1), `max_size`: Some(92372), added: 92867, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::InitialCheckpointRoot` (r:0 w:1) + /// Proof: `EthereumBeaconClient::InitialCheckpointRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ValidatorsRoot` (r:0 w:1) + /// Proof: `EthereumBeaconClient::ValidatorsRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:0 w:1) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::CurrentSyncCommittee` (r:0 w:1) + /// Proof: `EthereumBeaconClient::CurrentSyncCommittee` (`max_values`: Some(1), `max_size`: Some(92372), added: 92867, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:0 w:1) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:0 w:1) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + fn force_checkpoint() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3501` + // Minimum execution time: 72_756_000_000 picoseconds. + Weight::from_parts(85_575_000_000, 0) + .saturating_add(Weight::from_parts(0, 3501)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(9)) + } + /// Storage: `EthereumBeaconClient::OperatingMode` (r:1 w:0) + /// Proof: `EthereumBeaconClient::OperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::NextSyncCommittee` (r:1 w:0) + /// Proof: `EthereumBeaconClient::NextSyncCommittee` (`max_values`: Some(1), `max_size`: Some(92372), added: 92867, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::CurrentSyncCommittee` (r:1 w:0) + /// Proof: `EthereumBeaconClient::CurrentSyncCommittee` (`max_values`: Some(1), `max_size`: Some(92372), added: 92867, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ValidatorsRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::ValidatorsRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn submit() -> Weight { + // Proof Size summary in bytes: + // Measured: `92749` + // Estimated: `93857` + // Minimum execution time: 16_966_000_000 picoseconds. + Weight::from_parts(17_189_000_000, 0) + .saturating_add(Weight::from_parts(0, 93857)) + .saturating_add(T::DbWeight::get().reads(7)) + } + /// Storage: `EthereumBeaconClient::OperatingMode` (r:1 w:0) + /// Proof: `EthereumBeaconClient::OperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::NextSyncCommittee` (r:1 w:1) + /// Proof: `EthereumBeaconClient::NextSyncCommittee` (`max_values`: Some(1), `max_size`: Some(92372), added: 92867, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::CurrentSyncCommittee` (r:1 w:0) + /// Proof: `EthereumBeaconClient::CurrentSyncCommittee` (`max_values`: Some(1), `max_size`: Some(92372), added: 92867, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ValidatorsRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::ValidatorsRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn submit_with_sync_committee() -> Weight { + // Proof Size summary in bytes: + // Measured: `92749` + // Estimated: `93857` + // Minimum execution time: 87_667_000_000 picoseconds. + Weight::from_parts(88_179_000_000, 0) + .saturating_add(Weight::from_parts(0, 93857)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `EthereumBeaconClient::OperatingMode` (r:1 w:0) + /// Proof: `EthereumBeaconClient::OperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestFinalizedBlockRoot` (r:1 w:0) + /// Proof: `EthereumBeaconClient::LatestFinalizedBlockRoot` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::FinalizedBeaconState` (r:1 w:0) + /// Proof: `EthereumBeaconClient::FinalizedBeaconState` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::LatestExecutionState` (r:1 w:1) + /// Proof: `EthereumBeaconClient::LatestExecutionState` (`max_values`: Some(1), `max_size`: Some(80), added: 575, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ExecutionHeaderIndex` (r:1 w:1) + /// Proof: `EthereumBeaconClient::ExecutionHeaderIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ExecutionHeaderMapping` (r:1 w:1) + /// Proof: `EthereumBeaconClient::ExecutionHeaderMapping` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `EthereumBeaconClient::ExecutionHeaders` (r:0 w:1) + /// Proof: `EthereumBeaconClient::ExecutionHeaders` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`) + fn submit_execution_header() -> Weight { + // Proof Size summary in bytes: + // Measured: `380` + // Estimated: `3537` + // Minimum execution time: 99_000_000 picoseconds. + Weight::from_parts(104_000_000, 0) + .saturating_add(Weight::from_parts(0, 3537)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } +}