Compare commits
No commits in common. "main" and "ghost-exodus" have entirely different histories.
main
...
ghost-exod
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -1195,7 +1195,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "casper-runtime"
|
||||
version = "4.0.14"
|
||||
version = "4.0.10"
|
||||
dependencies = [
|
||||
"casper-runtime-constants",
|
||||
"frame-benchmarking",
|
||||
@ -3684,7 +3684,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ghost-exodus"
|
||||
version = "0.0.17"
|
||||
version = "0.0.11"
|
||||
dependencies = [
|
||||
"chacha20poly1305",
|
||||
"frame-benchmarking",
|
||||
@ -3733,7 +3733,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ghost-governance"
|
||||
version = "0.3.10"
|
||||
version = "0.3.7"
|
||||
dependencies = [
|
||||
"frame-benchmarking",
|
||||
"frame-support",
|
||||
@ -3743,7 +3743,6 @@ dependencies = [
|
||||
"ghost-traits",
|
||||
"hex-literal",
|
||||
"libsecp256k1",
|
||||
"num-traits",
|
||||
"pallet-balances",
|
||||
"parity-scale-codec",
|
||||
"rustc-hex",
|
||||
@ -4110,7 +4109,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ghost-weaver"
|
||||
version = "0.0.14"
|
||||
version = "0.0.8"
|
||||
dependencies = [
|
||||
"frame-benchmarking",
|
||||
"frame-support",
|
||||
|
||||
@ -346,7 +346,7 @@ sha256sum /etc/ghost/casper.json
|
||||
|
||||
You should see:
|
||||
```
|
||||
74f5a6df5e33dac94a8852ddfb73e472283bba0b30e260ca581919eb50c734db /etc/ghost/casper.json
|
||||
9da6045ed6d4fd844e3939573b31c013d0e564e542029330faa6d978cb4a915a
|
||||
```
|
||||
|
||||
Create running `ghost-node` service that starts on system boot using `--unit-file` flag.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ghost-exodus"
|
||||
version = "0.0.17"
|
||||
version = "0.0.11"
|
||||
description = "Threshold signature generation with DKG included"
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
@ -488,7 +488,7 @@ mod benchmarks {
|
||||
let dummy_nonce = vec![0u8; network_curve.element_bytes_len()];
|
||||
|
||||
let create_bond = GovernanceAction::Create {
|
||||
market: [69, 420, 1337, 0],
|
||||
market: [69, 420, 1337],
|
||||
terms: [420, 1337],
|
||||
token: dummy_address,
|
||||
intervals: [34, 35],
|
||||
@ -506,7 +506,7 @@ mod benchmarks {
|
||||
QualificationDkgState::<T>::insert(&network_curve, dkg_state);
|
||||
ActiveDkgAuthorities::<T>::insert(&network_curve, active_dkg);
|
||||
ActiveAuthorities::<T>::insert(&network_curve, authorities);
|
||||
ExodusRequests::<T>::insert((network_curve, exodus_session), request);
|
||||
ExodusRequests::<T>::insert(network_curve, exodus_session, request);
|
||||
|
||||
let nonce_package = PackageContext::default()
|
||||
.with_network_curve(NetworkCurve::Secp256k1)
|
||||
@ -566,7 +566,7 @@ mod benchmarks {
|
||||
let dummy_group_commitment = vec![0u8; network_curve.element_bytes_len()];
|
||||
|
||||
let create_bond = GovernanceAction::Create {
|
||||
market: [69, 420, 1337, 0],
|
||||
market: [69, 420, 1337],
|
||||
terms: [420, 1337],
|
||||
token: dummy_address,
|
||||
intervals: [34, 35],
|
||||
@ -584,7 +584,7 @@ mod benchmarks {
|
||||
QualificationDkgState::<T>::insert(&network_curve, dkg_state);
|
||||
ActiveDkgAuthorities::<T>::insert(&network_curve, active_dkg);
|
||||
ActiveAuthorities::<T>::insert(&network_curve, authorities);
|
||||
ExodusRequests::<T>::insert((network_curve, exodus_session), request);
|
||||
ExodusRequests::<T>::insert(network_curve, exodus_session, request);
|
||||
|
||||
let mut roast_state = RoastSessionState::<ParticipantsBitmap::<T>>::default();
|
||||
roast_state.status = RoastStatus::GroupCommitments;
|
||||
@ -664,7 +664,7 @@ mod benchmarks {
|
||||
|
||||
let dummy_address = EvmAddress::repeat_byte(69);
|
||||
let create_bond = GovernanceAction::Create {
|
||||
market: [69, 420, 1337, 0],
|
||||
market: [69, 420, 1337],
|
||||
terms: [420, 1337],
|
||||
token: dummy_address,
|
||||
intervals: [34, 35],
|
||||
@ -723,7 +723,7 @@ mod benchmarks {
|
||||
QualificationDkgState::<T>::insert(&network_curve, dkg_state);
|
||||
ActiveDkgAuthorities::<T>::insert(&network_curve, active_dkg);
|
||||
ActiveAuthorities::<T>::insert(&network_curve, authorities);
|
||||
ExodusRequests::<T>::insert((network_curve, exodus_session), request);
|
||||
ExodusRequests::<T>::insert(network_curve, exodus_session, request);
|
||||
|
||||
let mut roast_state = RoastSessionState::<ParticipantsBitmap::<T>>::default();
|
||||
roast_state.status = RoastStatus::PartialSignatures;
|
||||
@ -796,7 +796,7 @@ mod benchmarks {
|
||||
assert!(!consensus_exists);
|
||||
assert!(!committers_exists);
|
||||
|
||||
assert!(!ExodusRequests::<T>::contains_key((&network_curve, &exodus_session)));
|
||||
assert!(!ExodusRequests::<T>::contains_key(&network_curve, &exodus_session));
|
||||
assert!(ExodusSignedGovernance::<T>::contains_key((&exodus_session, network_id), dkg_index));
|
||||
|
||||
Ok(())
|
||||
@ -808,9 +808,7 @@ mod benchmarks {
|
||||
let (_, network_curve, _, _) = prepare_pallet::<T>(1usize);
|
||||
|
||||
let network_id = NetworkIdOf::<T>::default();
|
||||
let base_amount: BalanceOf<T> = T::BaseEvmAmount::get().unique_saturated_into();
|
||||
let amount = base_amount.saturating_add(T::Currency::minimum_balance());
|
||||
|
||||
let amount: BalanceOf<T> = 10_000u32.into();
|
||||
let bounty = Perbill::from_percent(5);
|
||||
let receiver = EvmAddress::from([69u8; 20]);
|
||||
|
||||
@ -821,14 +819,14 @@ mod benchmarks {
|
||||
}
|
||||
});
|
||||
|
||||
let initial_balance = T::Currency::minimum_balance()
|
||||
let total_existential = T::Currency::minimum_balance();
|
||||
let initial_balance = total_existential
|
||||
.saturating_mul(5u32.into())
|
||||
.saturating_add(amount);
|
||||
|
||||
T::Currency::mint_into(&caller, initial_balance).unwrap();
|
||||
let _ = T::Currency::make_free_balance_be(&caller, initial_balance);
|
||||
let _ = T::NetworkDataHandler::register_incoming(&network_id, amount).unwrap();
|
||||
|
||||
let total_issuance = T::Currency::total_issuance();
|
||||
let current_exodus_session = CurrentExodus::<T>::get();
|
||||
|
||||
#[extrinsic_call]
|
||||
@ -840,10 +838,9 @@ mod benchmarks {
|
||||
receiver,
|
||||
);
|
||||
|
||||
assert!(ExodusRequests::<T>::contains_key((&network_curve, current_exodus_session)));
|
||||
assert!(ExodusRequests::<T>::contains_key(&network_curve, current_exodus_session));
|
||||
assert_eq!(CurrentExodus::<T>::get(), current_exodus_session + 1);
|
||||
assert_eq!(T::Currency::balance(&caller), initial_balance - amount);
|
||||
assert_eq!(T::Currency::total_issuance(), total_issuance - amount);
|
||||
assert_eq!(T::Currency::free_balance(&caller), initial_balance - amount);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -49,45 +49,45 @@ pub enum ExodusError {
|
||||
impl core::fmt::Debug for ExodusError {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
match *self {
|
||||
ExodusError::InvalidParticipantId => write!(fmt, "Participant index could not be parsed as an identifier."),
|
||||
ExodusError::DeserializationError => write!(fmt, "Error while deserializing value."),
|
||||
ExodusError::SerializationError => write!(fmt, "Error while serializing value."),
|
||||
ExodusError::InvalidParticipantId => write!(fmt, "Participant index could not be parsed to identifier."),
|
||||
ExodusError::DeserializationError => write!(fmt, "Error during deserializing value."),
|
||||
ExodusError::SerializationError => write!(fmt, "Error serializing value."),
|
||||
ExodusError::InvalidMinSigners(min, max) => write!(fmt, "Number of min_signers ({min}) must be at least 2 and not larger than max_signers ({max})."),
|
||||
ExodusError::InvalidMaxSigners(max_signers) => write!(fmt, "Number of max_signers must be at least 2, {max_signers} given."),
|
||||
ExodusError::DKGNotSupported(ref curve) => write!(fmt, "The ciphersuite {curve:?} does not support DKG."),
|
||||
ExodusError::IncorrectNumberOfCoefficients => write!(fmt, "Incorrect number of coefficients; should be equal to min signers."),
|
||||
ExodusError::IncorrectNumberOfCommitments => write!(fmt, "Incorrect number of commitments; should be equal to min signers."),
|
||||
ExodusError::InvalidNonceCommitments => write!(fmt, "Hiding nonce commitment indices should match binding nonce commitments."),
|
||||
ExodusError::InvalidProofOfKnowledge => write!(fmt, "Invalid proof of knowledge."),
|
||||
ExodusError::InvalidNonceCommitments => write!(fmt, "Hiding nonce commitments indexes should match binding nonce commitments."),
|
||||
ExodusError::InvalidProofOfKnowledge => write!(fmt, "The proof of knowledge is not valid."),
|
||||
ExodusError::IncorrectNumberOfPackages => write!(fmt, "Incorrect number of packages; should be equal to max signers."),
|
||||
ExodusError::IncorrectPackage => write!(fmt, "An incorrect package was specified."),
|
||||
ExodusError::IncorrectPackage => write!(fmt, "The incorrect package was specified."),
|
||||
ExodusError::PackageNotFound => write!(fmt, "Round 1 package not found for Round 2 participant."),
|
||||
ExodusError::InvalidSecretShare => write!(fmt, "Invalid secret share."),
|
||||
ExodusError::MissingCommitment => write!(fmt, "The signing package must contain the participant's Commitments."),
|
||||
ExodusError::MissingCommitment => write!(fmt, "The Signing Package must contain the participant's Commitments."),
|
||||
ExodusError::IncorrectCommitment => write!(fmt, "The participant's commitment is incorrect."),
|
||||
ExodusError::UnknownIdentifier => write!(fmt, "Unknown identifier provided."),
|
||||
ExodusError::UnknownIdentifier => write!(fmt, "Unknown identifier."),
|
||||
ExodusError::IdentityCommitment => write!(fmt, "Commitment equals the identity."),
|
||||
ExodusError::DuplicatedIdentifier => write!(fmt, "Duplicated identifier."),
|
||||
ExodusError::IncorrectNumberOfIdentifiers => write!(fmt, "Incorrect number of identifiers."),
|
||||
ExodusError::InvalidSignature => write!(fmt, "Invalid signature provided."),
|
||||
ExodusError::InvalidSignatureShare => write!(fmt, "Invalid signature share provided."),
|
||||
ExodusError::InvalidSignature => write!(fmt, "Invalid signature."),
|
||||
ExodusError::InvalidSignatureShare => write!(fmt, "Invalid signature share."),
|
||||
ExodusError::EncryptionFailed => write!(fmt, "Encryption failed."),
|
||||
ExodusError::DecryptionFailed => write!(fmt, "Decryption failed."),
|
||||
ExodusError::HKDFFailed => write!(fmt, "HKDF failed."),
|
||||
ExodusError::InvalidNonceLength => write!(fmt, "Encryption nonce has invalid length."),
|
||||
ExodusError::MalformedSigningKey => write!(fmt, "Malformed signing key encoding."),
|
||||
ExodusError::NoStoredNetworks => write!(fmt, "No stored networks to work on."),
|
||||
ExodusError::NoStoredNetworks => write!(fmt, "No stored networks to be worked on."),
|
||||
ExodusError::OffchainTimeoutPeriod => write!(fmt, "Offchain request should be in-flight."),
|
||||
ExodusError::BadSignature(auth_index) => write!(fmt, "Signature could not be created from {auth_index}."),
|
||||
ExodusError::TransactionSubmissionFailed(auth_index) => write!(fmt, "Could not submit transaction from {auth_index}."),
|
||||
ExodusError::UnknownReceiverIndex(receiver_index) => write!(fmt, "Unknown receiver index {receiver_index} found."),
|
||||
ExodusError::CouldNotConstructMessage(auth_index) => write!(fmt, "Could not construct message during OCW from {auth_index}."),
|
||||
ExodusError::NothingToWrite => write!(fmt, "Nothing to write to local storage."),
|
||||
ExodusError::NothingToWrite => write!(fmt, "Nothing to write into local storage."),
|
||||
ExodusError::UnknownPrefix => write!(fmt, "Unknown prefix used for local storage."),
|
||||
ExodusError::UnexpectedRound => write!(fmt, "Unexpected round provided."),
|
||||
ExodusError::InvalidMerkleProof => write!(fmt, "Invalid Merkle proof provided."),
|
||||
ExodusError::InvalidMerkleProof => write!(fmt, "Invalid merkle proof provided."),
|
||||
ExodusError::InvalidIdentityElement => write!(fmt, "Invalid identity element provided."),
|
||||
ExodusError::NoActiveAuthorities => write!(fmt, "No active authorities for signing EXODUS transactions."),
|
||||
ExodusError::NoActiveAuthorities => write!(fmt, "No active authorities for signing exodus transactions."),
|
||||
ExodusError::Unknown => write!(fmt, "Unknown error."),
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,8 @@
|
||||
use frame_support::{
|
||||
pallet_prelude::*,
|
||||
traits::{
|
||||
tokens::{Preservation, Precision, Fortitude}, fungible::{Inspect, Mutate},
|
||||
DisabledValidators, ValidatorSet, ValidatorSetWithIdentification,
|
||||
OneSessionHandler,
|
||||
Currency, DisabledValidators, ValidatorSet, ValidatorSetWithIdentification,
|
||||
OneSessionHandler, WithdrawReasons, ExistenceRequirement,
|
||||
},
|
||||
};
|
||||
use frame_system::{
|
||||
@ -109,7 +108,7 @@ const EXODUS_PREFIX_SHARES: &[u8] = b"exodus-shares";
|
||||
const EXODUS_PREFIX_BLENDS: &[u8] = b"exodus-blends";
|
||||
const EXODUS_PREFIX_EXILES: &[u8] = b"exodus-exiles";
|
||||
|
||||
const MAX_MESSAGE_SIZE : u32 = 544;
|
||||
const MAX_MESSAGE_SIZE : u32 = 512;
|
||||
const HEADER_MAX_BYTES : u32 = 1 + 4;
|
||||
const ELEMENT_MAX_BYTES : u32 = 33;
|
||||
const SCALAR_MAX_BYTES : u32 = 32;
|
||||
@ -224,8 +223,11 @@ type BitmapByAuthority<T> = BoundedBTreeMap<AuthIndex, ParticipantsBitmap<T>, <T
|
||||
type QualifyingState<T> = PendingDkgAuthorities<ParticipantsBitmap<T>, BlockNumberFor<T>>;
|
||||
type ActivatedState<T> = ReadyDkgAuthorities<ParticipantsBitmap<T>>;
|
||||
|
||||
pub type BalanceOf<T> = <<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
pub type NetworkIdOf<T> = <<T as Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId;
|
||||
pub type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
pub type NetworkIdOf<T> =
|
||||
<<T as Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId;
|
||||
|
||||
pub type ValidatorId<T> = <<T as Config>::ValidatorSet as ValidatorSet<
|
||||
<T as frame_system::Config>::AccountId,
|
||||
@ -392,7 +394,7 @@ pub mod pallet {
|
||||
+ MaxEncodedLen;
|
||||
|
||||
type ValidatorSet: ValidatorSetWithIdentification<Self::AccountId>;
|
||||
type Currency: Inspect<Self::AccountId> + Mutate<Self::AccountId>;
|
||||
type Currency: Currency<Self::AccountId>;
|
||||
|
||||
type NetworkDataHandler: NetworkDataInspectHandler<NetworkData>
|
||||
+ NetworkDataMutateHandler<NetworkData, BalanceOf<Self>>
|
||||
@ -423,9 +425,6 @@ pub mod pallet {
|
||||
#[pallet::constant]
|
||||
type MaxCursorLen: Get<u32>;
|
||||
|
||||
#[pallet::constant]
|
||||
type BaseEvmAmount: Get<u128>;
|
||||
|
||||
type WeightInfo: WeightInfo;
|
||||
}
|
||||
|
||||
@ -505,7 +504,6 @@ pub mod pallet {
|
||||
NoActiveAuthorities,
|
||||
InvalidSignatureShare,
|
||||
VerifyingShareNotFound,
|
||||
BridgeQueueMinimumNotMet,
|
||||
DkgAuthoritiesInProgress,
|
||||
PackagesAlreadyRegistered,
|
||||
DkgAuthoritiesNotInitialized,
|
||||
@ -554,12 +552,10 @@ pub mod pallet {
|
||||
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn exodus_requests)]
|
||||
pub(super) type ExodusRequests<T: Config> = CountedStorageNMap<
|
||||
pub(super) type ExodusRequests<T: Config> = StorageDoubleMap<
|
||||
_,
|
||||
(
|
||||
NMapKey<Twox64Concat, NetworkCurve>,
|
||||
NMapKey<Twox64Concat, ExodusSession>,
|
||||
),
|
||||
Twox64Concat, NetworkCurve,
|
||||
Twox64Concat, ExodusSession,
|
||||
ExodusRequest<NetworkIdOf<T>, BalanceOf<T>>,
|
||||
OptionQuery,
|
||||
>;
|
||||
@ -1455,7 +1451,7 @@ pub mod pallet {
|
||||
exodus_request.next_roast_session = roast_session
|
||||
.saturating_add(1);
|
||||
|
||||
ExodusRequests::<T>::insert((&network_curve, &exodus_session), exodus_request);
|
||||
ExodusRequests::<T>::insert(&network_curve, &exodus_session, exodus_request);
|
||||
}
|
||||
|
||||
RoastSessions::<T>::insert(&exodus_session, &authority_index, roast_session);
|
||||
@ -1513,7 +1509,7 @@ pub mod pallet {
|
||||
let exodus_session = package.session;
|
||||
|
||||
ensure!(
|
||||
ExodusRequests::<T>::contains_key((&network_curve, &exodus_session)),
|
||||
ExodusRequests::<T>::contains_key(&network_curve, &exodus_session),
|
||||
Error::<T>::ExodusRequestNotFound
|
||||
);
|
||||
|
||||
@ -1645,7 +1641,7 @@ pub mod pallet {
|
||||
);
|
||||
|
||||
let exodus_request =
|
||||
ExodusRequests::<T>::get((&network_curve, &exodus_session))
|
||||
ExodusRequests::<T>::get(&network_curve, &exodus_session)
|
||||
.ok_or(Error::<T>::ExodusRequestNotFound)?;
|
||||
|
||||
ensure!(
|
||||
@ -1800,7 +1796,7 @@ pub mod pallet {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
ExodusRequests::<T>::remove((&network_curve, &exodus_session));
|
||||
ExodusRequests::<T>::remove(&network_curve, &exodus_session);
|
||||
|
||||
match exodus_request.r#type {
|
||||
ExodusRequestType::EvmRotation { .. } => {
|
||||
@ -1843,31 +1839,16 @@ pub mod pallet {
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
let base_evm_amount: BalanceOf<T> = T::BaseEvmAmount::get()
|
||||
.unique_saturated_into();
|
||||
|
||||
let is_amount_sufficient = 1u32.checked_shl(ExodusRequests::<T>::count())
|
||||
.map(|scale| {
|
||||
T::Currency::minimum_balance()
|
||||
.saturating_mul(scale.unique_saturated_into())
|
||||
.saturating_add(base_evm_amount)
|
||||
.le(&amount)
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
ensure!(is_amount_sufficient, Error::<T>::BridgeQueueMinimumNotMet);
|
||||
|
||||
let actual_amount = T::Currency::burn_from(
|
||||
let _imbalance = T::Currency::withdraw(
|
||||
&who,
|
||||
amount,
|
||||
Preservation::Expendable,
|
||||
Precision::Exact,
|
||||
Fortitude::Polite,
|
||||
WithdrawReasons::TRANSFER,
|
||||
ExistenceRequirement::AllowDeath,
|
||||
)?;
|
||||
|
||||
Self::do_register_evm_bridge_out_exodus(
|
||||
network_id,
|
||||
actual_amount,
|
||||
amount,
|
||||
bounty,
|
||||
receiver,
|
||||
)?;
|
||||
@ -1875,7 +1856,7 @@ pub mod pallet {
|
||||
Self::deposit_event(Event::<T>::EvmBridgeOutRegistered {
|
||||
who,
|
||||
network_id,
|
||||
amount: actual_amount,
|
||||
amount,
|
||||
bounty,
|
||||
receiver,
|
||||
});
|
||||
@ -1972,7 +1953,7 @@ pub mod pallet {
|
||||
|
||||
},
|
||||
Err(err) => {
|
||||
log::error!(target: PALLET_LOG_TARGET, "🗺️ Exodus skipped at {:?}: {:?}", current_block, err);
|
||||
log::error!(target: PALLET_LOG_TARGET, "🗺️ Exodus skipped or failed initialization at {:?}: {:?}", current_block, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2165,7 +2146,7 @@ impl<T: Config> Pallet<T> {
|
||||
let exodus_session = CurrentExodus::<T>::get();
|
||||
let request = request_builder(exodus_session);
|
||||
|
||||
ExodusRequests::<T>::insert((&network.curve, &exodus_session), request);
|
||||
ExodusRequests::<T>::insert(&network.curve, &exodus_session, request);
|
||||
CurrentExodus::<T>::put(exodus_session.saturating_add(1));
|
||||
|
||||
Ok(())
|
||||
@ -2580,7 +2561,7 @@ impl<T: Config> Pallet<T> {
|
||||
};
|
||||
|
||||
weight.saturating_accrue(T::DbWeight::get().writes(1));
|
||||
ExodusRequests::<T>::insert((&network_curve, &exodus_session), exodus_request);
|
||||
ExodusRequests::<T>::insert(&network_curve, &exodus_session, exodus_request);
|
||||
|
||||
if let None = dkg_qualification
|
||||
.try_push_rotation_session(exodus_session, network_type) {
|
||||
@ -2621,7 +2602,7 @@ impl<T: Config> Pallet<T> {
|
||||
let r#type = rotation_session.network_type;
|
||||
|
||||
weight.saturating_accrue(T::DbWeight::get().reads(1));
|
||||
if ExodusRequests::<T>::contains_key((&network_curve, &session)) {
|
||||
if ExodusRequests::<T>::contains_key(&network_curve, &session) {
|
||||
return false
|
||||
};
|
||||
|
||||
@ -3102,7 +3083,7 @@ impl<T: Config> Pallet<T> {
|
||||
}
|
||||
|
||||
let exodus_request =
|
||||
ExodusRequests::<T>::get((&network_curve, &package.session))
|
||||
ExodusRequests::<T>::get(&network_curve, &package.session)
|
||||
.ok_or(InvalidTransaction::BadProof)?;
|
||||
|
||||
let roast_session =
|
||||
@ -3300,7 +3281,7 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
let threshold = get_byzantium_quorum_threshold(max_authorities);
|
||||
|
||||
let mut exodus_requests = ExodusRequests::<T>::iter_prefix((&network_curve,))
|
||||
let mut exodus_requests = ExodusRequests::<T>::iter_prefix(&network_curve)
|
||||
.collect::<Vec<(ExodusSession, ExodusRequest<_, _>)>>();
|
||||
|
||||
exodus_requests.sort_by_key(|&(session, _)| session);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
use frame_system::EnsureRoot;
|
||||
use frame_support::{
|
||||
derive_impl, parameter_types,
|
||||
traits::{ConstU32, ConstU64, ConstU128},
|
||||
traits::{ConstU32, ConstU64},
|
||||
};
|
||||
use crate as ghost_exodus;
|
||||
|
||||
@ -143,7 +143,6 @@ impl ghost_exodus::Config for Runtime {
|
||||
type DkgRoundPeriod = ConstU64<100>;
|
||||
type RemovalLimit = ConstU32<20>;
|
||||
type MaxCursorLen = ConstU32<20>;
|
||||
type BaseEvmAmount = ConstU128<5>;
|
||||
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
@ -810,7 +810,7 @@ fn run_dkg_session(
|
||||
return Err(TestError::InvalidStorageAfter);
|
||||
}
|
||||
|
||||
if ExodusRequests::<Runtime>::contains_key((curve, exodus)) {
|
||||
if ExodusRequests::<Runtime>::contains_key(curve, exodus) {
|
||||
let roast_state = RoastSessionStates::<Runtime>::get(exodus, roast);
|
||||
if !roast_state.partial_signers.contains(idx)
|
||||
|| !roast_state.nonce_committers.contains(idx)
|
||||
@ -854,7 +854,11 @@ fn run_dkg_session(
|
||||
let throttled = prev_authorities.last().copied().unwrap();
|
||||
let prev_len = prev_authorities.len() as AuthIndex;
|
||||
|
||||
let mut start = 0;
|
||||
loop {
|
||||
if start >= 100 { break; }
|
||||
start += 1;
|
||||
|
||||
let mut current_pending_requests: Vec<ExodusSession> = ext.execute_with(|| {
|
||||
ExodusRequests::<Runtime>::iter_keys()
|
||||
.filter_map(|(current_curve, exodus_session)| {
|
||||
@ -877,7 +881,7 @@ fn run_dkg_session(
|
||||
|
||||
for auth in prev_authorities.iter() {
|
||||
let request_exists = ext.execute_with(|| {
|
||||
ExodusRequests::<Runtime>::contains_key((&curve, &exodus_session))
|
||||
ExodusRequests::<Runtime>::contains_key(&curve, &exodus_session)
|
||||
});
|
||||
|
||||
if !request_exists { break; }
|
||||
@ -1066,7 +1070,7 @@ fn test_all_validators_can_execute_dkg() {
|
||||
let remove_pool = GovernanceAction::RemovePool { index: 1337 };
|
||||
let close = GovernanceAction::Close { id: 420 };
|
||||
let create = GovernanceAction::Create {
|
||||
market: [69, 420, 1337, 0],
|
||||
market: [69, 420, 1337],
|
||||
terms: [420, 1337],
|
||||
token: dummy_address,
|
||||
intervals: [34, 35],
|
||||
@ -1132,14 +1136,9 @@ fn test_all_validators_can_execute_dkg() {
|
||||
ExodusSignedGovernance::<Runtime>::iter().count()
|
||||
});
|
||||
|
||||
let pending_exodus_requests = ext.execute_with(|| {
|
||||
ExodusRequests::<Runtime>::count()
|
||||
});
|
||||
|
||||
assert_eq!(rotations_count, 3);
|
||||
assert_eq!(bridges_count, 2);
|
||||
assert_eq!(governances_count, 15);
|
||||
assert_eq!(pending_exodus_requests, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1447,124 +1446,6 @@ fn test_prepare_round5_kick_on_empty_justifications() {
|
||||
assert_eq!(indexes.active_bits_count(), authorities_len as u32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_evm_bridge_out_dynamic_threshold_works() {
|
||||
let (mut ext, _) = new_test_ext();
|
||||
|
||||
ext.execute_with(|| {
|
||||
let network_curve = NetworkCurve::Secp256k1;
|
||||
let network_id = 69u64;
|
||||
let user = 420u64;
|
||||
|
||||
let receiver = EvmAddress::from([2u8; 20]);
|
||||
let bounty = Perbill::from_percent(10);
|
||||
|
||||
let initial_balance: BalanceOf<Runtime> = 100_000u128.unique_saturated_into();
|
||||
let _ = <Runtime as Config>::Currency::set_balance(&user, initial_balance);
|
||||
|
||||
let base_evm_amount_u128 = <<Runtime as Config>::BaseEvmAmount as Get<u128>>::get();
|
||||
let base_evm_amount: BalanceOf<Runtime> = base_evm_amount_u128.unique_saturated_into();
|
||||
let existential_deposit = <Runtime as Config>::Currency::minimum_balance();
|
||||
|
||||
let network_data = NetworkDataBuilder::default()
|
||||
.with_network_curve(network_curve)
|
||||
.build();
|
||||
|
||||
let _ = <Runtime as Config>::NetworkDataHandler::register(network_id, network_data).unwrap();
|
||||
let _ = <Runtime as Config>::NetworkDataHandler::register_incoming(&network_id, 1337).unwrap();
|
||||
|
||||
let mut dkg_state = PendingDkgAuthorities::default();
|
||||
loop {
|
||||
if dkg_state.is_dkg_finalized() { break; }
|
||||
dkg_state.next_phase();
|
||||
}
|
||||
|
||||
QualificationDkgState::<Runtime>::insert(&network_curve, dkg_state);
|
||||
|
||||
let amount_1 = base_evm_amount.saturating_add(existential_deposit);
|
||||
assert_ok!(Exodus::register_evm_bridge_out_exodus(
|
||||
RuntimeOrigin::signed(user.clone()),
|
||||
network_id,
|
||||
amount_1,
|
||||
bounty,
|
||||
receiver,
|
||||
));
|
||||
|
||||
assert_eq!(ExodusRequests::<Runtime>::count(), 1);
|
||||
|
||||
System::assert_last_event(RuntimeEvent::Exodus(
|
||||
Event::EvmBridgeOutRegistered {
|
||||
who: user.clone(),
|
||||
network_id,
|
||||
amount: amount_1,
|
||||
bounty,
|
||||
receiver,
|
||||
}
|
||||
));
|
||||
|
||||
assert_err!(
|
||||
Exodus::register_evm_bridge_out_exodus(
|
||||
RuntimeOrigin::signed(user.clone()),
|
||||
network_id,
|
||||
amount_1,
|
||||
bounty,
|
||||
receiver,
|
||||
),
|
||||
Error::<Runtime>::BridgeQueueMinimumNotMet
|
||||
);
|
||||
|
||||
let amount_2 = existential_deposit
|
||||
.saturating_mul(2)
|
||||
.saturating_add(base_evm_amount);
|
||||
|
||||
assert_ok!(Exodus::register_evm_bridge_out_exodus(
|
||||
RuntimeOrigin::signed(user.clone()),
|
||||
network_id,
|
||||
amount_2,
|
||||
bounty,
|
||||
receiver,
|
||||
));
|
||||
|
||||
assert_err!(
|
||||
Exodus::register_evm_bridge_out_exodus(
|
||||
RuntimeOrigin::signed(user.clone()),
|
||||
network_id,
|
||||
amount_2,
|
||||
bounty,
|
||||
receiver,
|
||||
),
|
||||
Error::<Runtime>::BridgeQueueMinimumNotMet
|
||||
);
|
||||
|
||||
assert_eq!(ExodusRequests::<Runtime>::count(), 2);
|
||||
|
||||
let amount_3 = existential_deposit
|
||||
.saturating_mul(4)
|
||||
.saturating_add(base_evm_amount);
|
||||
|
||||
assert_ok!(Exodus::register_evm_bridge_out_exodus(
|
||||
RuntimeOrigin::signed(user.clone()),
|
||||
network_id,
|
||||
amount_3,
|
||||
bounty,
|
||||
receiver,
|
||||
));
|
||||
|
||||
assert_eq!(ExodusRequests::<Runtime>::count(), 3);
|
||||
|
||||
assert_err!(
|
||||
Exodus::register_evm_bridge_out_exodus(
|
||||
RuntimeOrigin::signed(user.clone()),
|
||||
network_id,
|
||||
amount_3,
|
||||
bounty,
|
||||
receiver,
|
||||
),
|
||||
Error::<Runtime>::BridgeQueueMinimumNotMet
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merkle_tree_success_power_of_two_for_shares() {
|
||||
let network_curve = NetworkCurve::Secp256k1;
|
||||
|
||||
@ -133,7 +133,7 @@ macro_rules! impl_evm_encodable {
|
||||
|
||||
impl_evm_encodable!(numeric: u8, u16, u32, u64, u128);
|
||||
impl_evm_encodable!(bytes_fixed: EvmAddress, EvmBytes32);
|
||||
impl_evm_encodable!(const_array: [u128; 4], [u128; 2], [u32; 2], [u8; 2]);
|
||||
impl_evm_encodable!(const_array: [u128; 3], [u128; 2], [u32; 2], [u8; 2]);
|
||||
impl_evm_encodable!(bytes_slice:);
|
||||
|
||||
macro_rules! abi_encode_evm_message {
|
||||
@ -192,7 +192,7 @@ pub enum GovernanceAction {
|
||||
|
||||
Close { id: u128 },
|
||||
Create {
|
||||
market: [u128; 4],
|
||||
market: [u128; 3],
|
||||
terms: [u128; 2],
|
||||
token: EvmAddress,
|
||||
intervals: [u32; 2],
|
||||
@ -300,7 +300,7 @@ impl GovernanceAction {
|
||||
let booleans_u8 = [booleans[0] as u8, booleans[1] as u8];
|
||||
abi_encode_evm_message!(
|
||||
message_buffer,
|
||||
"create(uint256[4],uint256[2],address,uint32[2],bool[2])",
|
||||
"create(uint256[3],uint256[2],address,uint32[2],bool[2])",
|
||||
[market, terms, token, intervals, &booleans_u8]
|
||||
)
|
||||
},
|
||||
@ -582,7 +582,7 @@ mod tests {
|
||||
|
||||
GovernanceAction::Close { id: 99 },
|
||||
GovernanceAction::Create {
|
||||
market: [69, 420, 1337, 0],
|
||||
market: [69, 420, 1337],
|
||||
terms: [69, 420],
|
||||
token: EvmAddress::repeat_byte(0x99),
|
||||
intervals: [69, 1337],
|
||||
@ -706,26 +706,25 @@ mod tests {
|
||||
assert_eq!(inner_payload[inner_payload.len() - 1], id as u8);
|
||||
},
|
||||
GovernanceAction::Create { market, terms, token, intervals, booleans } => {
|
||||
let hash = keccak_256("create(uint256[4],uint256[2],address,uint32[2],bool[2])".as_bytes());
|
||||
let hash = keccak_256("create(uint256[3],uint256[2],address,uint32[2],bool[2])".as_bytes());
|
||||
assert_eq!(inner_payload[0..4], hash[0..4]);
|
||||
assert_eq!(inner_payload.len(), 356);
|
||||
assert_eq!(inner_payload.len(), 324);
|
||||
assert_eq!(inner_payload[35], 69);
|
||||
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[20..36].try_into().unwrap()), market[0]);
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[52..68].try_into().unwrap()), market[1]);
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[84..100].try_into().unwrap()), market[2]);
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[116..132].try_into().unwrap()), market[3]);
|
||||
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[148..164].try_into().unwrap()), terms[0]);
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[180..196].try_into().unwrap()), terms[1]);
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[116..132].try_into().unwrap()), terms[0]);
|
||||
assert_eq!(u128::from_be_bytes(inner_payload[148..164].try_into().unwrap()), terms[1]);
|
||||
|
||||
assert_eq!(&inner_payload[208..228], token.as_ref());
|
||||
assert_eq!(&inner_payload[176..196], token.as_ref());
|
||||
|
||||
assert_eq!(u32::from_be_bytes(inner_payload[256..260].try_into().unwrap()), intervals[0]);
|
||||
assert_eq!(u32::from_be_bytes(inner_payload[288..292].try_into().unwrap()), intervals[1]);
|
||||
assert_eq!(u32::from_be_bytes(inner_payload[224..228].try_into().unwrap()), intervals[0]);
|
||||
assert_eq!(u32::from_be_bytes(inner_payload[256..260].try_into().unwrap()), intervals[1]);
|
||||
|
||||
assert_eq!(inner_payload[323], booleans[0] as u8);
|
||||
assert_eq!(inner_payload[355], booleans[1] as u8);
|
||||
assert_eq!(inner_payload[291], booleans[0] as u8);
|
||||
assert_eq!(inner_payload[323], booleans[1] as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
//! Autogenerated weights for `ghost_exodus`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2026-09-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2026-09-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
|
||||
@ -77,8 +77,8 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `351`
|
||||
// Estimated: `3816`
|
||||
// Minimum execution time: 240_813_000 picoseconds.
|
||||
Weight::from_parts(243_523_000, 0)
|
||||
// Minimum execution time: 239_012_000 picoseconds.
|
||||
Weight::from_parts(241_388_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3816))
|
||||
.saturating_add(RocksDbWeight::get().reads(4))
|
||||
.saturating_add(RocksDbWeight::get().writes(3))
|
||||
@ -100,11 +100,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `391 + c * (32 ±0)`
|
||||
// Estimated: `3856 + c * (32 ±0)`
|
||||
// Minimum execution time: 1_356_791_000 picoseconds.
|
||||
Weight::from_parts(1_221_760_215, 0)
|
||||
// Minimum execution time: 1_339_828_000 picoseconds.
|
||||
Weight::from_parts(1_212_625_790, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3856))
|
||||
// Standard Error: 16_481
|
||||
.saturating_add(Weight::from_parts(33_163_393, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 11_831
|
||||
.saturating_add(Weight::from_parts(33_120_868, 0).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(6))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into()))
|
||||
@ -124,11 +124,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `317 + c * (257 ±0)`
|
||||
// Estimated: `3783 + c * (257 ±0)`
|
||||
// Minimum execution time: 254_590_000 picoseconds.
|
||||
Weight::from_parts(258_091_105, 0)
|
||||
// Minimum execution time: 251_478_000 picoseconds.
|
||||
Weight::from_parts(254_144_621, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3783))
|
||||
// Standard Error: 25_082
|
||||
.saturating_add(Weight::from_parts(6_595_878, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 24_613
|
||||
.saturating_add(Weight::from_parts(6_595_819, 0).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 257).saturating_mul(c.into()))
|
||||
@ -148,11 +148,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `317 + c * (257 ±0)`
|
||||
// Estimated: `3783 + c * (257 ±0)`
|
||||
// Minimum execution time: 240_888_000 picoseconds.
|
||||
Weight::from_parts(245_480_975, 0)
|
||||
// Minimum execution time: 236_155_000 picoseconds.
|
||||
Weight::from_parts(242_055_948, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3783))
|
||||
// Standard Error: 13_733
|
||||
.saturating_add(Weight::from_parts(371_161, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 15_623
|
||||
.saturating_add(Weight::from_parts(360_411, 0).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 257).saturating_mul(c.into()))
|
||||
@ -172,11 +172,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `317 + c * (257 ±0)`
|
||||
// Estimated: `3783 + c * (257 ±0)`
|
||||
// Minimum execution time: 251_521_000 picoseconds.
|
||||
Weight::from_parts(253_053_636, 0)
|
||||
// Minimum execution time: 249_507_000 picoseconds.
|
||||
Weight::from_parts(248_505_595, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3783))
|
||||
// Standard Error: 14_691
|
||||
.saturating_add(Weight::from_parts(4_101_872, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 20_302
|
||||
.saturating_add(Weight::from_parts(4_191_526, 0).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 257).saturating_mul(c.into()))
|
||||
@ -197,8 +197,8 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `448`
|
||||
// Estimated: `3913`
|
||||
// Minimum execution time: 265_187_000 picoseconds.
|
||||
Weight::from_parts(269_124_000, 0)
|
||||
// Minimum execution time: 264_214_000 picoseconds.
|
||||
Weight::from_parts(266_905_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3913))
|
||||
.saturating_add(RocksDbWeight::get().reads(6))
|
||||
.saturating_add(RocksDbWeight::get().writes(3))
|
||||
@ -222,11 +222,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + c * (770 ±0)`
|
||||
// Estimated: `1551 + c * (1019 ±27)`
|
||||
// Minimum execution time: 284_558_000 picoseconds.
|
||||
Weight::from_parts(284_117_484, 0)
|
||||
// Minimum execution time: 281_073_000 picoseconds.
|
||||
Weight::from_parts(280_778_987, 0)
|
||||
.saturating_add(Weight::from_parts(0, 1551))
|
||||
// Standard Error: 74_361
|
||||
.saturating_add(Weight::from_parts(3_551_271, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 92_951
|
||||
.saturating_add(Weight::from_parts(3_489_552, 0).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(7))
|
||||
.saturating_add(RocksDbWeight::get().writes(3))
|
||||
.saturating_add(Weight::from_parts(0, 1019).saturating_mul(c.into()))
|
||||
@ -251,11 +251,11 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostExodus::NonceCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_nonce_commitment() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `627`
|
||||
// Estimated: `4092`
|
||||
// Minimum execution time: 315_066_000 picoseconds.
|
||||
Weight::from_parts(318_561_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4092))
|
||||
// Measured: `588`
|
||||
// Estimated: `4053`
|
||||
// Minimum execution time: 291_972_000 picoseconds.
|
||||
Weight::from_parts(295_122_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4053))
|
||||
.saturating_add(RocksDbWeight::get().reads(8))
|
||||
.saturating_add(RocksDbWeight::get().writes(5))
|
||||
}
|
||||
@ -281,11 +281,11 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostExodus::GroupCommitmentsConsensus` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_group_commitment() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `992`
|
||||
// Estimated: `4457`
|
||||
// Minimum execution time: 338_644_000 picoseconds.
|
||||
Weight::from_parts(343_954_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4457))
|
||||
// Measured: `968`
|
||||
// Estimated: `4433`
|
||||
// Minimum execution time: 331_528_000 picoseconds.
|
||||
Weight::from_parts(333_974_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4433))
|
||||
.saturating_add(RocksDbWeight::get().reads(10))
|
||||
.saturating_add(RocksDbWeight::get().writes(4))
|
||||
}
|
||||
@ -319,17 +319,15 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostExodus::SignatureScalars` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::GroupCommitters` (r:0 w:1)
|
||||
/// Proof: `GhostExodus::GroupCommitters` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::CounterForExodusRequests` (r:1 w1)
|
||||
/// Proof: `GhostExodus::CounterForExodusRequests` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
fn register_signature_share() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `11299`
|
||||
// Estimated: `14764`
|
||||
// Minimum execution time: 3_968_938_000 picoseconds.
|
||||
Weight::from_parts(3_975_088_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 14764))
|
||||
.saturating_add(RocksDbWeight::get().reads(15))
|
||||
.saturating_add(RocksDbWeight::get().writes(9))
|
||||
// Measured: `11259`
|
||||
// Estimated: `14724`
|
||||
// Minimum execution time: 3_842_259_000 picoseconds.
|
||||
Weight::from_parts(3_985_167_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 14724))
|
||||
.saturating_add(RocksDbWeight::get().reads(14))
|
||||
.saturating_add(RocksDbWeight::get().writes(8))
|
||||
}
|
||||
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
|
||||
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
@ -341,16 +339,16 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostExodus::QualificationDkgState` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::CurrentExodus` (r:1 w:1)
|
||||
/// Proof: `GhostExodus::CurrentExodus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::ExodusRequests` (r:1 w:1)
|
||||
/// Storage: `GhostExodus::ExodusRequests` (r:0 w:1)
|
||||
/// Proof: `GhostExodus::ExodusRequests` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_evm_bridge_out_exodus() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `448`
|
||||
// Estimated: `3913`
|
||||
// Minimum execution time: 191_374_000 picoseconds.
|
||||
Weight::from_parts(192_991_000, 0)
|
||||
// Minimum execution time: 137_053_000 picoseconds.
|
||||
Weight::from_parts(138_693_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3913))
|
||||
.saturating_add(RocksDbWeight::get().reads(7))
|
||||
.saturating_add(RocksDbWeight::get().writes(5))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(4))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ghost-governance"
|
||||
version = "0.3.10"
|
||||
version = "0.3.7"
|
||||
description = "Full-chain and cross-chain governance pallet with early adopter share claims"
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
@ -13,7 +13,6 @@ codec = { workspace = true, features = ["derive"] }
|
||||
scale-info = { workspace = true, features = ["derive"] }
|
||||
serde = { workspace = true }
|
||||
serde_derive = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
rustc-hex = { workspace = true }
|
||||
libsecp256k1 = { workspace = true, default-features = false }
|
||||
|
||||
@ -43,7 +42,6 @@ std = [
|
||||
"serde/std",
|
||||
"codec/std",
|
||||
"scale-info/std",
|
||||
"num-traits/std",
|
||||
"libsecp256k1/std",
|
||||
"frame-support/std",
|
||||
"frame-system/std",
|
||||
|
||||
@ -32,7 +32,7 @@ mod benchmarks {
|
||||
let dummy_evm_address = EvmAddress::from(evm_addr_bytes);
|
||||
|
||||
let target_index = max_proof_depth - 1;
|
||||
let claim_package_init = ClaimPackage::<T> {
|
||||
let claim_package_init = ClaimPackage {
|
||||
shares: dummy_shares,
|
||||
merkle_proof: Default::default(),
|
||||
token_id: 0,
|
||||
@ -99,8 +99,7 @@ mod benchmarks {
|
||||
let message_string_bytes = Pallet::<T>::ethereum_signable_message(
|
||||
¤t_account,
|
||||
&network_id,
|
||||
&preimage_hash,
|
||||
0u8,
|
||||
&preimage_hash
|
||||
);
|
||||
|
||||
let message_hash = SubstrateKeccakHasher::hash(&message_string_bytes);
|
||||
@ -125,7 +124,6 @@ mod benchmarks {
|
||||
claim_package,
|
||||
dummy_evm_address,
|
||||
evm_signature,
|
||||
dummy_shares,
|
||||
);
|
||||
|
||||
assert_eq!(dummy_shares, GlobalShares::<T>::get().claimed_shares);
|
||||
|
||||
@ -9,11 +9,7 @@ use frame_system::pallet_prelude::*;
|
||||
use sp_core::U256;
|
||||
use sp_std::vec::Vec;
|
||||
use sp_io::crypto::secp256k1_ecdsa_recover;
|
||||
use sp_runtime::traits::{
|
||||
AtLeast32BitUnsigned, CheckedAdd, Saturating, UniqueSaturatedInto,
|
||||
};
|
||||
|
||||
use num_traits::PrimInt;
|
||||
use sp_runtime::traits::{AtLeast32BitUnsigned, CheckedAdd, UniqueSaturatedInto};
|
||||
|
||||
use ghost_helpers::{
|
||||
SubstrateKeccakHasher, merkle_tree::verify_tree_proof,
|
||||
@ -36,8 +32,9 @@ mod benchmarking;
|
||||
mod mock;
|
||||
mod tests;
|
||||
|
||||
const MAX_POSSIBLE_PROOF_DEPTH: u32 = 256;
|
||||
|
||||
type TokenId = u128;
|
||||
type ClaimNonce = u8;
|
||||
type EvmHash = sp_core::H256;
|
||||
type EvmAddress = sp_core::H160;
|
||||
type EvmSignature = [u8; 65];
|
||||
@ -137,41 +134,25 @@ where
|
||||
}
|
||||
|
||||
pub fn lock_balance(&mut self, extra_balance: Balance) {
|
||||
self.locked_balance = self.locked_balance
|
||||
.saturating_add(extra_balance);
|
||||
self.locked_balance.saturating_add(extra_balance);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, RuntimeDebug, TypeInfo)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct ClaimPackage<T: pallet::Config> {
|
||||
#[derive(Encode, Decode, Clone, RuntimeDebug, TypeInfo, PartialEq, Eq)]
|
||||
pub struct ClaimPackage<Balance>
|
||||
where
|
||||
Balance: Default + Copy + Clone,
|
||||
{
|
||||
pub index: u32,
|
||||
pub token_id: TokenId,
|
||||
pub shares: BalanceOf<T>,
|
||||
pub merkle_proof: BoundedVec<EvmHash, T::MaxProofDepth>,
|
||||
pub shares: Balance,
|
||||
pub merkle_proof: BoundedVec<EvmHash, ConstU32<MAX_POSSIBLE_PROOF_DEPTH>>,
|
||||
}
|
||||
|
||||
impl<T: pallet::Config> Clone for ClaimPackage<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
index: self.index,
|
||||
token_id: self.token_id,
|
||||
shares: self.shares,
|
||||
merkle_proof: self.merkle_proof.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: pallet::Config> PartialEq for ClaimPackage<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.index == other.index &&
|
||||
self.token_id == other.token_id &&
|
||||
self.shares == other.shares &&
|
||||
self.merkle_proof == other.merkle_proof
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: pallet::Config> ClaimPackage<T> {
|
||||
impl<Balance> ClaimPackage<Balance>
|
||||
where
|
||||
Balance: Default + Copy + Clone + UniqueSaturatedInto<u128>,
|
||||
{
|
||||
pub fn get_preimage<NetworkId>(
|
||||
&self,
|
||||
evm_address: &EvmAddress,
|
||||
@ -233,9 +214,6 @@ pub mod pallet {
|
||||
#[pallet::constant]
|
||||
type MaxProofDepth: Get<u32>;
|
||||
|
||||
#[pallet::constant]
|
||||
type MaxPartialClaims: Get<ClaimNonce>;
|
||||
|
||||
type WeightInfo: WeightInfo;
|
||||
}
|
||||
|
||||
@ -251,10 +229,9 @@ pub mod pallet {
|
||||
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
PartialClaimsExhausted,
|
||||
PreimageAlreadyClaimed,
|
||||
BoundedToOtherNetwork,
|
||||
AuthorityNotGovernor,
|
||||
ExceedsAllowedShares,
|
||||
NetworkHasNoGenesis,
|
||||
InvalidMerkleProof,
|
||||
SharesOverflowed,
|
||||
@ -292,16 +269,7 @@ pub mod pallet {
|
||||
pub type ClaimedHashes<T: Config> = StorageMap<
|
||||
_,
|
||||
Blake2_256, EvmHash,
|
||||
ClaimNonce,
|
||||
ValueQuery,
|
||||
>;
|
||||
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn claimed_shares)]
|
||||
pub type ClaimedShares<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat, EvmHash,
|
||||
BalanceOf<T>,
|
||||
bool,
|
||||
ValueQuery,
|
||||
>;
|
||||
|
||||
@ -346,10 +314,9 @@ pub mod pallet {
|
||||
pub fn claim(
|
||||
origin: OriginFor<T>,
|
||||
network_id: NetworkIdOf<T>,
|
||||
claim_package: ClaimPackage<T>,
|
||||
claim_package: ClaimPackage<BalanceOf<T>>,
|
||||
evm_address: EvmAddress,
|
||||
evm_signature: EvmSignature,
|
||||
requested_shares: BalanceOf<T>,
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
@ -371,21 +338,12 @@ pub mod pallet {
|
||||
let preimage = claim_package.get_preimage(&evm_address, network_id);
|
||||
let preimage_hash = SubstrateKeccakHasher::hash(&preimage);
|
||||
|
||||
let max_claim_nonces = T::MaxPartialClaims::get();
|
||||
let current_nonce = ClaimedHashes::<T>::get(&preimage_hash);
|
||||
ensure!(
|
||||
!ClaimedHashes::<T>::contains_key(&preimage_hash),
|
||||
Error::<T>::PreimageAlreadyClaimed
|
||||
);
|
||||
|
||||
ensure!(current_nonce < max_claim_nonces, Error::<T>::PartialClaimsExhausted);
|
||||
|
||||
let already_claimed = ClaimedShares::<T>::get(&preimage_hash);
|
||||
let claimed_shares = if current_nonce == max_claim_nonces.saturating_sub(1) {
|
||||
claim_package.shares.saturating_sub(already_claimed)
|
||||
} else {
|
||||
let cumulative_shares = already_claimed.saturating_add(requested_shares);
|
||||
ensure!(cumulative_shares <= claim_package.shares, Error::<T>::ExceedsAllowedShares);
|
||||
requested_shares
|
||||
};
|
||||
|
||||
Self::verify_signature(&who, &network_id, &preimage_hash, &evm_address, &evm_signature, current_nonce)?;
|
||||
Self::verify_signature(&who, &network_id, &preimage_hash, &evm_address, &evm_signature)?;
|
||||
Self::verify_merkle_proof(&network_id, &preimage, &claim_package)?;
|
||||
|
||||
NetworkShares::<T>::try_mutate(&network_id, |state| -> DispatchResult {
|
||||
@ -393,29 +351,25 @@ pub mod pallet {
|
||||
let proof_size_match = package_proof_size == state.proofs_size;
|
||||
ensure!(proof_size_match, Error::<T>::SharesOverflowed);
|
||||
|
||||
let increased = state.try_increase_claimed(claimed_shares);
|
||||
let increased = state.try_increase_claimed(claim_package.shares);
|
||||
ensure!(increased.is_some(), Error::<T>::SharesOverflowed);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
GlobalShares::<T>::try_mutate(|state| -> DispatchResult {
|
||||
let increased = state.try_increase_claimed(claimed_shares);
|
||||
let increased = state.try_increase_claimed(claim_package.shares);
|
||||
ensure!(increased.is_some(), Error::<T>::SharesOverflowed);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
member_share.increase_activated_shares(claimed_shares);
|
||||
member_share.increase_activated_shares(claim_package.shares);
|
||||
member_share.initiate_on_network(network_id);
|
||||
|
||||
MemberShares::<T>::insert(&who, member_share);
|
||||
ClaimedHashes::<T>::insert(&preimage_hash, current_nonce.saturating_add(1));
|
||||
ClaimedShares::<T>::insert(
|
||||
&preimage_hash,
|
||||
already_claimed.saturating_add(claimed_shares),
|
||||
);
|
||||
ClaimedHashes::<T>::insert(&preimage_hash, true);
|
||||
|
||||
Self::deposit_event(Event::<T>::SharesClaimed {
|
||||
shares: claimed_shares,
|
||||
shares: claim_package.shares,
|
||||
network_id,
|
||||
who,
|
||||
});
|
||||
@ -436,73 +390,45 @@ impl<T: Config> Pallet<T> {
|
||||
r
|
||||
}
|
||||
|
||||
fn to_ascii_base10<N: PrimInt + UniqueSaturatedInto<u128>>(num: N) -> Vec<u8> {
|
||||
let zero = N::zero();
|
||||
if num == zero { return sp_std::vec![b'0']; }
|
||||
|
||||
let ten = N::from(10).unwrap_or_else(|| N::zero());
|
||||
let num_u128 = num.unique_saturated_into();
|
||||
let capacity = (num_u128.ilog10() + 1) as usize;
|
||||
|
||||
let mut result = Vec::with_capacity(capacity);
|
||||
let mut n = num;
|
||||
|
||||
while n > zero {
|
||||
result.push(b'0' + (n % ten).to_u8().unwrap_or(0));
|
||||
n = n / ten;
|
||||
}
|
||||
result.reverse();
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn ethereum_signable_message(
|
||||
receiver: &T::AccountId,
|
||||
network_id: &NetworkIdOf<T>,
|
||||
preimage_hash: &EvmHash,
|
||||
nonce: ClaimNonce,
|
||||
) -> Vec<u8> {
|
||||
let prefix = b"GMV Claim:";
|
||||
let network_id_u64: u64 = (*network_id).unique_saturated_into();
|
||||
|
||||
let receiver_ascii_hex = Self::to_ascii_hex(&receiver.encode());
|
||||
let preimage_ascii_hex = Self::to_ascii_hex(preimage_hash.as_ref());
|
||||
let network_ascii = Self::to_ascii_base10(network_id_u64);
|
||||
let nonce_ascii = Self::to_ascii_base10(nonce);
|
||||
let network_ascii_hex = Self::to_ascii_hex(&network_id_u64.to_be_bytes());
|
||||
|
||||
let account_label = b"\naccount:0x";
|
||||
let preimage_label = b"\npreimage:0x";
|
||||
let network_label = b"\nnetwork:";
|
||||
let nonce_label = b"\nnonce:";
|
||||
|
||||
let what_length = prefix.len()
|
||||
.saturating_add(account_label.len()).saturating_add(receiver_ascii_hex.len())
|
||||
.saturating_add(preimage_label.len()).saturating_add(preimage_ascii_hex.len())
|
||||
.saturating_add(network_label.len()).saturating_add(network_ascii.len())
|
||||
.saturating_add(nonce_label.len()).saturating_add(nonce_ascii.len());
|
||||
let what_length = receiver_ascii_hex.len()
|
||||
.saturating_add(preimage_ascii_hex.len())
|
||||
.saturating_add(network_ascii_hex.len())
|
||||
.saturating_add(10 + 11 + 12 + 11); // all 4 prefixes
|
||||
|
||||
let mut what = Vec::with_capacity(what_length);
|
||||
what.extend_from_slice(prefix);
|
||||
|
||||
what.extend_from_slice(account_label);
|
||||
what.extend_from_slice(b"\naccount:0x");
|
||||
what.extend_from_slice(&receiver_ascii_hex);
|
||||
|
||||
what.extend_from_slice(preimage_label);
|
||||
what.extend_from_slice(b"\npreimage:0x");
|
||||
what.extend_from_slice(&preimage_ascii_hex);
|
||||
|
||||
what.extend_from_slice(network_label);
|
||||
what.extend_from_slice(&network_ascii);
|
||||
what.extend_from_slice(b"\nnetwork:0x");
|
||||
what.extend_from_slice(&network_ascii_hex);
|
||||
|
||||
what.extend_from_slice(nonce_label);
|
||||
what.extend_from_slice(&nonce_ascii);
|
||||
let mut l = what.len();
|
||||
let mut rev = Vec::new();
|
||||
while l > 0 {
|
||||
rev.push(b'0' + (l % 10) as u8);
|
||||
l /= 10;
|
||||
}
|
||||
|
||||
let length_ascii = Self::to_ascii_base10(what.len());
|
||||
let message_prefix = b"\x19Ethereum Signed Message:\n";
|
||||
|
||||
let message_capacity = message_prefix.len() + length_ascii.len() + what.len();
|
||||
let mut v = Vec::with_capacity(message_capacity);
|
||||
v.extend_from_slice(message_prefix);
|
||||
v.extend_from_slice(&length_ascii);
|
||||
let mut v = Vec::with_capacity(26 + rev.len() + what.len());
|
||||
v.extend_from_slice(b"\x19Ethereum Signed Message:\n");
|
||||
v.extend(rev.into_iter().rev());
|
||||
v.extend(what);
|
||||
|
||||
v
|
||||
@ -514,9 +440,8 @@ impl<T: Config> Pallet<T> {
|
||||
preimage_hash: &EvmHash,
|
||||
evm_address: &EvmAddress,
|
||||
evm_signature: &EvmSignature,
|
||||
nonce: ClaimNonce,
|
||||
) -> DispatchResult {
|
||||
let message = Self::ethereum_signable_message(who, network_id, preimage_hash, nonce);
|
||||
let message = Self::ethereum_signable_message(who, network_id, preimage_hash);
|
||||
let message_bytes = SubstrateKeccakHasher::hash(&message).to_fixed_bytes();
|
||||
|
||||
let recovered_pubkey = secp256k1_ecdsa_recover(evm_signature, &message_bytes)
|
||||
@ -532,7 +457,7 @@ impl<T: Config> Pallet<T> {
|
||||
fn verify_merkle_proof(
|
||||
network_id: &NetworkIdOf<T>,
|
||||
preimage: &[u8],
|
||||
claim_package: &ClaimPackage<T>,
|
||||
claim_package: &ClaimPackage<BalanceOf<T>>,
|
||||
) -> DispatchResult {
|
||||
let network_state = NetworkShares::<T>::get(network_id);
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use super::*;
|
||||
pub use crate as ghost_governance;
|
||||
use frame_support::{
|
||||
derive_impl, parameter_types,
|
||||
traits::{ConstU8, ConstU32, ConstU128},
|
||||
traits::{ConstU32, ConstU128},
|
||||
};
|
||||
use frame_system::EnsureRoot;
|
||||
use sp_runtime::BuildStorage;
|
||||
@ -52,8 +52,7 @@ impl Config for Test {
|
||||
type NetworkDataHandler = Networks;
|
||||
|
||||
type MinimumDonation = ConstU128<69>;
|
||||
type MaxProofDepth = ConstU32<7>;
|
||||
type MaxPartialClaims = ConstU8<3>;
|
||||
type MaxProofDepth = ConstU32<5>;
|
||||
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use hex_literal::hex;
|
||||
|
||||
use sp_runtime::AccountId32;
|
||||
use frame_support::traits::Get;
|
||||
use frame_support::{assert_ok, assert_err};
|
||||
use frame_support::assert_ok;
|
||||
use libsecp256k1::{Message, SecretKey, PublicKey};
|
||||
|
||||
use ghost_helpers::merkle_tree::{generate_tree, generate_proof};
|
||||
@ -87,7 +87,7 @@ fn claim_happy_path() {
|
||||
|item: (u8, &NewTestUser)| -> Result<(usize, Vec<u8>), ()> {
|
||||
let (index, u) = item;
|
||||
|
||||
let tmp_package = ClaimPackage::<Test> {
|
||||
let tmp_package = ClaimPackage {
|
||||
shares: u.allowed_shares,
|
||||
merkle_proof: Default::default(),
|
||||
token_id: u.token_id,
|
||||
@ -118,7 +118,7 @@ fn claim_happy_path() {
|
||||
|
||||
let proof = generate_proof::<SubstrateKeccakHasher, u8>(&merkle_tree, max_index, slot_index as u8);
|
||||
|
||||
let claim_package = ClaimPackage::<Test> {
|
||||
let claim_package = ClaimPackage {
|
||||
shares: current_user.allowed_shares,
|
||||
merkle_proof: BoundedVec::try_from(proof).unwrap(),
|
||||
token_id: current_user.token_id,
|
||||
@ -131,8 +131,7 @@ fn claim_happy_path() {
|
||||
let message_string_bytes = Governance::ethereum_signable_message(
|
||||
¤t_user.substrate_account,
|
||||
&network_id,
|
||||
&preimage_hash,
|
||||
0u8,
|
||||
&preimage_hash
|
||||
);
|
||||
|
||||
let message_hash = SubstrateKeccakHasher::hash(&message_string_bytes);
|
||||
@ -155,8 +154,7 @@ fn claim_happy_path() {
|
||||
network_id,
|
||||
claim_package,
|
||||
current_user.evm_address.clone(),
|
||||
evm_signature,
|
||||
current_user.allowed_shares,
|
||||
evm_signature
|
||||
));
|
||||
|
||||
let updated_share = MemberShares::<Test>::get(¤t_user.substrate_account);
|
||||
@ -174,201 +172,6 @@ fn claim_happy_path() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partial_claims_happy_path() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let network_id = 69u64;
|
||||
|
||||
let minimum_donation_u128 = <<Test as crate::Config>::MinimumDonation as Get<u128>>::get();
|
||||
let minimum_donation: BalanceOf<Test> = minimum_donation_u128.unique_saturated_into();
|
||||
|
||||
let secret_key = SecretKey::parse(&[7u8; 32]).unwrap();
|
||||
let public_key = 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 substrate_account_a = AccountId32::new([11u8; 32]);
|
||||
let substrate_account_b = AccountId32::new([22u8; 32]);
|
||||
let substrate_account_c = AccountId32::new([33u8; 32]);
|
||||
|
||||
let current_user = NewTestUser {
|
||||
substrate_account: substrate_account_a.clone(),
|
||||
evm_secret: secret_key,
|
||||
evm_address: EvmAddress::from(evm_addr_bytes),
|
||||
allowed_shares: 1000u128,
|
||||
token_id: 7,
|
||||
};
|
||||
|
||||
let max_index = 0u8;
|
||||
let raw_values_complex = vec![(0u8, ¤t_user)];
|
||||
|
||||
let merkle_tree = generate_tree::<SubstrateKeccakHasher, u8, _, _, _>(
|
||||
max_index,
|
||||
raw_values_complex,
|
||||
|
||||
|item: (u8, &NewTestUser)| -> Result<(usize, Vec<u8>), ()> {
|
||||
let (index, u) = item;
|
||||
let tmp_package = ClaimPackage::<Test> {
|
||||
shares: u.allowed_shares,
|
||||
merkle_proof: Default::default(),
|
||||
token_id: u.token_id,
|
||||
index: index as u32
|
||||
};
|
||||
Ok((index as usize, tmp_package.get_preimage(&u.evm_address, network_id).to_vec()))
|
||||
}
|
||||
).unwrap();
|
||||
|
||||
let total_shares = 1_000_000;
|
||||
let merkle_root = *merkle_tree.last().unwrap();
|
||||
let network_state = NetworkShare::new(total_shares, merkle_root, 0);
|
||||
let global_state = ShareState::new(total_shares);
|
||||
|
||||
NetworkShares::<Test>::insert(&network_id, network_state);
|
||||
GlobalShares::<Test>::put(global_state);
|
||||
|
||||
let setup_governor = |account: &<Test as frame_system::Config>::AccountId| {
|
||||
MemberShares::<Test>::insert(account, MemberShare {
|
||||
locked_balance: minimum_donation,
|
||||
initiated_network: None,
|
||||
activated_shares: 0,
|
||||
});
|
||||
};
|
||||
setup_governor(&substrate_account_a);
|
||||
setup_governor(&substrate_account_b);
|
||||
setup_governor(&substrate_account_c);
|
||||
|
||||
let proof = generate_proof::<SubstrateKeccakHasher, u8>(&merkle_tree, max_index, 0u8);
|
||||
let claim_package = ClaimPackage {
|
||||
shares: current_user.allowed_shares,
|
||||
merkle_proof: BoundedVec::try_from(proof).unwrap(),
|
||||
token_id: current_user.token_id,
|
||||
index: 0,
|
||||
};
|
||||
|
||||
let preimage = claim_package.get_preimage(¤t_user.evm_address, network_id);
|
||||
let preimage_hash = SubstrateKeccakHasher::hash(&preimage);
|
||||
|
||||
let generate_test_signature = |target_account: &<Test as frame_system::Config>::AccountId| -> EvmSignature {
|
||||
let active_nonce = ClaimedHashes::<Test>::get(&preimage_hash);
|
||||
let message_string_bytes = Governance::ethereum_signable_message(
|
||||
&target_account,
|
||||
&network_id,
|
||||
&preimage_hash,
|
||||
active_nonce,
|
||||
);
|
||||
|
||||
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 = Message::parse(&message_bytes);
|
||||
let (sig, recovery_id) = libsecp256k1::sign(&msg_to_sign, ¤t_user.evm_secret);
|
||||
|
||||
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();
|
||||
|
||||
EvmSignature::from(signature_raw)
|
||||
};
|
||||
|
||||
let sig_0 = generate_test_signature(&substrate_account_a);
|
||||
assert_ok!(Governance::claim(
|
||||
RuntimeOrigin::signed(substrate_account_a.clone()),
|
||||
network_id,
|
||||
claim_package.clone(),
|
||||
current_user.evm_address.clone(),
|
||||
sig_0,
|
||||
400,
|
||||
));
|
||||
|
||||
let global_share = GlobalShares::<Test>::get();
|
||||
assert_eq!(global_share.claimed_shares, 400);
|
||||
assert_eq!(global_share.total_shares, total_shares);
|
||||
|
||||
let network_share = NetworkShares::<Test>::get(&network_id);
|
||||
assert_eq!(network_share.claimed_shares(), 400);
|
||||
assert_eq!(network_share.total_shares(), total_shares);
|
||||
|
||||
assert_eq!(MemberShares::<Test>::get(&substrate_account_a).activated_shares, 400);
|
||||
assert_eq!(ClaimedHashes::<Test>::get(&preimage_hash), 1);
|
||||
assert_eq!(ClaimedShares::<Test>::get(&preimage_hash), 400);
|
||||
|
||||
let sig_1_fail = generate_test_signature(&substrate_account_b);
|
||||
assert_err!(
|
||||
Governance::claim(
|
||||
RuntimeOrigin::signed(substrate_account_b.clone()),
|
||||
network_id,
|
||||
claim_package.clone(),
|
||||
current_user.evm_address.clone(),
|
||||
sig_1_fail,
|
||||
700,
|
||||
),
|
||||
Error::<Test>::ExceedsAllowedShares
|
||||
);
|
||||
|
||||
let sig_1_success = generate_test_signature(&substrate_account_b);
|
||||
assert_ok!(Governance::claim(
|
||||
RuntimeOrigin::signed(substrate_account_b.clone()),
|
||||
network_id,
|
||||
claim_package.clone(),
|
||||
current_user.evm_address.clone(),
|
||||
sig_1_success,
|
||||
100,
|
||||
));
|
||||
|
||||
let global_share = GlobalShares::<Test>::get();
|
||||
assert_eq!(global_share.claimed_shares, 500);
|
||||
assert_eq!(global_share.total_shares, total_shares);
|
||||
|
||||
let network_share = NetworkShares::<Test>::get(&network_id);
|
||||
assert_eq!(network_share.claimed_shares(), 500);
|
||||
assert_eq!(network_share.total_shares(), total_shares);
|
||||
|
||||
assert_eq!(MemberShares::<Test>::get(&substrate_account_b).activated_shares, 100);
|
||||
assert_eq!(ClaimedHashes::<Test>::get(&preimage_hash), 2);
|
||||
assert_eq!(ClaimedShares::<Test>::get(&preimage_hash), 500);
|
||||
|
||||
let sig_2_final = generate_test_signature(&substrate_account_c);
|
||||
assert_ok!(Governance::claim(
|
||||
RuntimeOrigin::signed(substrate_account_c.clone()),
|
||||
network_id,
|
||||
claim_package.clone(),
|
||||
current_user.evm_address.clone(),
|
||||
sig_2_final,
|
||||
300,
|
||||
));
|
||||
|
||||
let global_share = GlobalShares::<Test>::get();
|
||||
assert_eq!(global_share.claimed_shares, 1_000);
|
||||
assert_eq!(global_share.total_shares, total_shares);
|
||||
|
||||
let network_share = NetworkShares::<Test>::get(&network_id);
|
||||
assert_eq!(network_share.claimed_shares(), 1_000);
|
||||
assert_eq!(network_share.total_shares(), total_shares);
|
||||
|
||||
assert_eq!(MemberShares::<Test>::get(&substrate_account_c).activated_shares, 500);
|
||||
assert_eq!(ClaimedHashes::<Test>::get(&preimage_hash), 3);
|
||||
assert_eq!(ClaimedShares::<Test>::get(&preimage_hash), 1_000);
|
||||
|
||||
let sig_3_exhausted = generate_test_signature(&substrate_account_a);
|
||||
assert_err!(
|
||||
Governance::claim(
|
||||
RuntimeOrigin::signed(substrate_account_a),
|
||||
network_id,
|
||||
claim_package,
|
||||
current_user.evm_address.clone(),
|
||||
sig_3_exhausted,
|
||||
100,
|
||||
),
|
||||
Error::<Test>::PartialClaimsExhausted
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_proof_from_python_preclaims_for_sepolia() {
|
||||
new_test_ext().execute_with(|| {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
//! Autogenerated weights for `ghost_governance`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2026-09-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2026-09-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
|
||||
@ -56,23 +56,21 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostGovernance::MemberShares` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::ClaimedHashes` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::ClaimedHashes` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::ClaimedShares` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::ClaimedShares` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::NetworkShares` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::NetworkShares` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::GlobalShares` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::GlobalShares` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// The range of component `p` is `[1, 18]`.
|
||||
/// The range of component `p` is `[1, 20]`.
|
||||
fn claim(p: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `283`
|
||||
// Estimated: `3748`
|
||||
// Minimum execution time: 229_254_000 picoseconds.
|
||||
Weight::from_parts(229_992_093, 0)
|
||||
// Minimum execution time: 214_208_000 picoseconds.
|
||||
Weight::from_parts(216_987_870, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3748))
|
||||
// Standard Error: 25_680
|
||||
.saturating_add(Weight::from_parts(1_874_433, 0).saturating_mul(p.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(5))
|
||||
// Standard Error: 30_856
|
||||
.saturating_add(Weight::from_parts(1_702_104, 0).saturating_mul(p.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(4))
|
||||
.saturating_add(RocksDbWeight::get().writes(4))
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,6 @@ use ghost_networks::{
|
||||
NetworkData, NetworkDataBasicHandler, NetworkDataInspectHandler, NetworkDataMutateHandler,
|
||||
NetworkType,
|
||||
};
|
||||
use ghost_traits::evictor::StakingEvictor;
|
||||
use ghost_traits::exposure::ExposureListener;
|
||||
|
||||
pub mod migrations;
|
||||
@ -310,7 +309,6 @@ pub mod pallet {
|
||||
>;
|
||||
type DisabledValidators: DisabledValidators;
|
||||
type ExposureListener: ExposureListener<BalanceOf<Self>, Self::AccountId>;
|
||||
type StakingEvictor: StakingEvictor<Self::AccountId>;
|
||||
|
||||
#[pallet::constant]
|
||||
type MaxAuthorities: Get<u32>;
|
||||
@ -1457,15 +1455,7 @@ impl<T: Config> Pallet<T> {
|
||||
let authority_index = index as AuthIndex;
|
||||
|
||||
if offence_bitmap.exists(&authority_index) {
|
||||
weight.saturating_accrue(T::DbWeight::get().reads(2));
|
||||
|
||||
if let Some(account_id) = T::ExposureListener::get_account_by_index(index) {
|
||||
weight.saturating_accrue(T::DbWeight::get().reads(1));
|
||||
if T::StakingEvictor::try_evict_validator(&account_id) {
|
||||
weight.saturating_accrue(T::DbWeight::get().writes(2));
|
||||
}
|
||||
}
|
||||
|
||||
weight.saturating_accrue(T::DbWeight::get().reads(1));
|
||||
if let Some(full_id) = <T::ValidatorSet as ValidatorSetWithIdentification<
|
||||
T::AccountId,
|
||||
>>::IdentificationOf::convert(id.clone())
|
||||
@ -1647,7 +1637,7 @@ impl<Offender: Clone> Offence<Offender> for SlowClapOffence<Offender> {
|
||||
missed_percent.saturating_mul(Perbill::from_rational(1, offenders_count))
|
||||
}
|
||||
OffenceType::CommitmentOffence => offenders_count
|
||||
.checked_sub(Perbill::from_percent(9).mul_floor(self.validator_set_count))
|
||||
.checked_sub(Perbill::from_percent(9).mul_ceil(self.validator_set_count))
|
||||
.map(|threshold| {
|
||||
Perbill::from_rational(threshold.saturating_mul(4), self.validator_set_count)
|
||||
.square()
|
||||
|
||||
@ -5,7 +5,6 @@ use frame_support::{
|
||||
traits::{ConstU32, ConstU64},
|
||||
};
|
||||
use frame_system::EnsureRoot;
|
||||
use ghost_traits::evictor::StakingEvictor;
|
||||
use pallet_session::historical as pallet_session_historical;
|
||||
use sp_runtime::{
|
||||
curve::PiecewiseLinear,
|
||||
@ -37,7 +36,6 @@ frame_support::construct_runtime!(
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub static EvicatedValidators: Vec<u64> = vec![];
|
||||
pub static FixedValidators: Vec<u64> = vec![0, 1, 2, 3];
|
||||
}
|
||||
|
||||
@ -174,25 +172,6 @@ impl pallet_balances::Config for Runtime {
|
||||
|
||||
type Balance = u64;
|
||||
|
||||
pub struct TestStakingEvictor;
|
||||
impl StakingEvictor<u64> for TestStakingEvictor {
|
||||
fn try_evict_validator(who: &u64) -> bool {
|
||||
if !FixedValidators::get().contains(who) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut evicted_validators = EvicatedValidators::get();
|
||||
match evicted_validators.iter().position(|x| x == who) {
|
||||
Some(_) => false,
|
||||
None => {
|
||||
evicted_validators.push(*who);
|
||||
EvicatedValidators::set(evicted_validators);
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestExposureListener;
|
||||
impl ExposureListener<Balance, u64> for TestExposureListener
|
||||
where
|
||||
@ -238,7 +217,6 @@ impl Config for Runtime {
|
||||
type ReportUnresponsiveness = OffenceHandler;
|
||||
type DisabledValidators = Session;
|
||||
type ExposureListener = TestExposureListener;
|
||||
type StakingEvictor = TestStakingEvictor;
|
||||
|
||||
type MaxAuthorities = ConstU32<5>;
|
||||
type ApplauseThreshold = ConstU32<500_000_000>;
|
||||
|
||||
@ -1691,40 +1691,6 @@ fn migration_from_v2_to_v3_works_fine() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validators_are_evicted_during_offence() {
|
||||
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
|
||||
|
||||
new_test_ext().execute_with(|| {
|
||||
let session_index = advance_session_and_get_index();
|
||||
prepare_evm_network(None, None);
|
||||
|
||||
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
|
||||
System::set_block_number(5 * EpochDuration::get() / 2);
|
||||
let last_stored_block = 69;
|
||||
|
||||
for i in 0..3 {
|
||||
assert_ok!(do_block_commitment(
|
||||
session_index,
|
||||
network_id,
|
||||
i,
|
||||
last_stored_block,
|
||||
));
|
||||
}
|
||||
|
||||
assert_eq!(EvicatedValidators::get().len(), 0);
|
||||
let current_block = SlowClap::current_block_number();
|
||||
|
||||
SlowClap::on_initialize(current_block);
|
||||
System::assert_has_event(RuntimeEvent::SlowClap(
|
||||
crate::Event::SomeAuthoritiesDelayed {
|
||||
delayed: vec![(3, 3)],
|
||||
},
|
||||
));
|
||||
assert_eq!(EvicatedValidators::get().len(), 1);
|
||||
});
|
||||
}
|
||||
|
||||
fn assert_clapped_amount(
|
||||
session_index: &SessionIndex,
|
||||
unique_hash: &H256,
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
pub trait StakingEvictor<AccountId> {
|
||||
fn try_evict_validator(who: &AccountId) -> bool;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ghost-weaver"
|
||||
version = "0.0.14"
|
||||
version = "0.0.8"
|
||||
description = "Weaving a secure cryptographic tapestry across different external chains."
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
@ -3,14 +3,12 @@
|
||||
use super::*;
|
||||
use frame_benchmarking::v2::*;
|
||||
use frame_system::RawOrigin;
|
||||
use sp_runtime::traits::Saturating;
|
||||
use sp_std::vec;
|
||||
|
||||
use ghost_helpers::networks::NetworkDataBuilder;
|
||||
|
||||
fn prepare_pallet<T: Config>(
|
||||
authorities_len: u32,
|
||||
maybe_network_id: Option<u64>,
|
||||
authorities_len: u32
|
||||
) -> (NetworkIdOf<T>, T::AuthorityId, AuthIndex) {
|
||||
let authority = T::AuthorityId::generate_pair(None);
|
||||
let authorities = vec![authority.clone(); authorities_len as usize];
|
||||
@ -20,9 +18,7 @@ fn prepare_pallet<T: Config>(
|
||||
|
||||
Authorities::<T>::put(bounded_authorities);
|
||||
|
||||
let network_id_u64 = maybe_network_id.unwrap_or_default();
|
||||
let network_id: NetworkIdOf<T> = network_id_u64.unique_saturated_into();
|
||||
|
||||
let network_id = NetworkIdOf::<T>::default();
|
||||
let network_data = NetworkDataBuilder::default()
|
||||
.with_network_type(NetworkType::Utxo)
|
||||
.with_gatekeeper(
|
||||
@ -46,7 +42,7 @@ mod benchmarks {
|
||||
fn extend_warp(
|
||||
a: Linear<1, { T::MaxAuthorities::get() as u32 }>,
|
||||
) -> Result<(), BenchmarkError> {
|
||||
let (network_id, authority, authority_index) = prepare_pallet::<T>(a, None);
|
||||
let (network_id, authority, authority_index) = prepare_pallet::<T>(a);
|
||||
|
||||
TapestryDrafts::<T>::remove(&network_id);
|
||||
|
||||
@ -77,7 +73,7 @@ mod benchmarks {
|
||||
let next_session = weaving_session + 1;
|
||||
let root_hash = H256::repeat_byte(0x69);
|
||||
|
||||
let (network_id, authority, authority_index) = prepare_pallet::<T>(a, None);
|
||||
let (network_id, authority, authority_index) = prepare_pallet::<T>(a);
|
||||
|
||||
let tapestry_key = (network_id, weaving_session, next_session, root_hash);
|
||||
TapestryStrands::<T>::mutate(&tapestry_key, |tapestry| {
|
||||
@ -143,18 +139,7 @@ mod benchmarks {
|
||||
) -> Result<(), BenchmarkError> {
|
||||
let session = 69;
|
||||
let max_history_depth = a as usize;
|
||||
let (network_id, _, _) = prepare_pallet::<T>(1, None);
|
||||
|
||||
let expected_receiver_bytes = hex::decode("1657090d02985f0cdb41436fe2d5a83a3acb1995d963a698e7e619e927bdcc5e").unwrap();
|
||||
let mut receiver_raw = [0u8; 32];
|
||||
receiver_raw.copy_from_slice(&expected_receiver_bytes);
|
||||
|
||||
let transfer_amount: u64 = 153348847;
|
||||
let receiver = T::AccountId::decode(&mut &receiver_raw[..])
|
||||
.expect("32-byte array must cleanly decode into T::AccountId");
|
||||
|
||||
let existential_deposit = <T as Config>::Currency::minimum_balance();
|
||||
<T as Config>::Currency::set_balance(&receiver, existential_deposit);
|
||||
let (network_id, _, _) = prepare_pallet::<T>(1);
|
||||
|
||||
// Real world tx at block #481838
|
||||
// Block https://blockstream.info/block/0000000000000000011bdccb39e19e942a60edffdccd9779653c5b46b337904a
|
||||
@ -331,34 +316,28 @@ mod benchmarks {
|
||||
);
|
||||
|
||||
let thread_proof = ThreadProof::UtxoThreadProof(utxo_thread_proof);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session, network_id);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session);
|
||||
|
||||
assert!(!PulledThreads::<T>::contains_key(&pulled_thread_key));
|
||||
assert_eq!(T::Currency::balance(&receiver), existential_deposit);
|
||||
|
||||
#[extrinsic_call]
|
||||
pull_thread(RawOrigin::None, network_id, session, thread_proof);
|
||||
|
||||
let final_amount = existential_deposit.saturating_add(
|
||||
transfer_amount.unique_saturated_into()
|
||||
);
|
||||
assert!(PulledThreads::<T>::contains_key(&pulled_thread_key));
|
||||
assert_eq!(T::Currency::balance(&receiver), final_amount);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn pull_evm_thread() -> Result<(), BenchmarkError> {
|
||||
let session = 0;
|
||||
let sepolia_network_id = 11155111;
|
||||
let (network_id, _, _) = prepare_pallet::<T>(1, Some(sepolia_network_id));
|
||||
let session = 69;
|
||||
let (network_id, _, _) = prepare_pallet::<T>(1);
|
||||
|
||||
// https://sepolia.etherscan.io/address/0x7fec11e652f4d54e8cf11c4b52c360380332f2bd#readContract
|
||||
// getRoot: session 0, atBlock 11716130
|
||||
// https://sepolia.etherscan.io/address/0x81acdf2da6b50d806c96aecd9a498a5359e373c0#readContract
|
||||
// getRoot: session 0, atBlock 11660400
|
||||
|
||||
let root_string =
|
||||
hex::decode("07f4a5ba4750d9ddfc080429287cbcbde7464aa2f8ae13feaade0dcb45ca6129")
|
||||
hex::decode("28d1e6b476b03a464f74d531d532572db29d6b57349e4f17f84e92843f6c4ee7")
|
||||
.expect("EVM Root hex should be valid");
|
||||
let expected_root = H256::from_slice(&root_string);
|
||||
LoomStates::<T>::insert(&network_id, &session, expected_root);
|
||||
@ -369,17 +348,12 @@ mod benchmarks {
|
||||
.try_into()
|
||||
.expect("Hex string must be exactly 32 bytes long");
|
||||
|
||||
let transfer_amount: BalanceOf<T> = 420u64.unique_saturated_into();
|
||||
let receiver_account = sp_runtime::AccountId32::from(receiver_32);
|
||||
let receiver_account_t = T::AccountId::decode(&mut &receiver_32[..])
|
||||
.expect("32-byte array must cleanly decode into T::AccountId");
|
||||
|
||||
let existential_deposit = <T as Config>::Currency::minimum_balance();
|
||||
<T as Config>::Currency::set_balance(&receiver_account_t, existential_deposit);
|
||||
let transfer_amount: BalanceOf<T> = 420u64.unique_saturated_into();
|
||||
|
||||
let proof = vec![
|
||||
H256::from_slice(&hex::decode("7d831a4be9e37572687117870c3f96669a66bf07971e4fd705a36a0a4d6365b0").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("9f00b99751b7ccea1903949210408edb3ce50343985708c36a0b1d44e0a7628c").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("c5354289f0397c916949373043eb1d5ea99447f67fe014324d96c58ef02a2d11").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("da1fbdfefa1e9aedfedcfc48fb17cb0e731529f7a3695114e0a9caa1989dd420").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f").expect("Proof should be valid")),
|
||||
@ -388,14 +362,14 @@ mod benchmarks {
|
||||
H256::from_slice(&hex::decode("de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040").expect("Proof should be valid")),
|
||||
];
|
||||
let slots = vec![H256::from_slice(
|
||||
&hex::decode("f6182b8c276793f53d1820ad0405665177516e46e40af45e0dfea73c39a2306e")
|
||||
&hex::decode("2e474dabf492786b3505d7b7cf0bf07c9dbce92c91982fa7344c77e24fd4310d")
|
||||
.expect("Slot should be valid hex"),
|
||||
)];
|
||||
|
||||
let evm_thread_proof = EvmThreadProof::new(0, 1, receiver_account.into(), transfer_amount, proof, slots);
|
||||
let evm_thread_proof = EvmThreadProof::new(0, 1, receiver_account, transfer_amount, proof, slots);
|
||||
|
||||
let thread_proof = ThreadProof::EvmThreadProof(evm_thread_proof);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session, network_id);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session);
|
||||
|
||||
assert!(!PulledThreads::<T>::contains_key(&pulled_thread_key));
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ pub enum WeavingError<NetworkId> {
|
||||
impl<NetworkId: core::fmt::Debug> core::fmt::Debug for WeavingError<NetworkId> {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
match self {
|
||||
Self::NoStoredNetworks => write!(fmt, "No stored networks to work on."),
|
||||
Self::NoStoredNetworks => write!(fmt, "No stored networks to be watch on."),
|
||||
Self::UnparsableRequestBody => {
|
||||
write!(fmt, "HTTP request body contains invalid UTF-8 sequences.")
|
||||
}
|
||||
@ -22,25 +22,25 @@ impl<NetworkId: core::fmt::Debug> core::fmt::Debug for WeavingError<NetworkId> {
|
||||
write!(fmt, "The request deadline or network timeout was hit.")
|
||||
}
|
||||
Self::UnknownWeavingPhase(network_id) => {
|
||||
write!(fmt, "Unknown weaving phase for network #{:?}.", network_id)
|
||||
write!(fmt, "Unknown weaving phase for network: {:?}.", network_id)
|
||||
}
|
||||
Self::OffchainLockPeriod(network_id) => write!(
|
||||
fmt,
|
||||
"Storage lock is still held for network #{:?}.",
|
||||
"Storage lock is still held for network: {:?}.",
|
||||
network_id
|
||||
),
|
||||
Self::NoEndpointsAvailable(network_id) => write!(
|
||||
fmt,
|
||||
"No RPC URLs configured for network #{:?}.",
|
||||
"Zero RPC URLs configured for network: {:?}.",
|
||||
network_id
|
||||
),
|
||||
Self::ContradictoryHashes(network_id) => write!(
|
||||
fmt,
|
||||
"Divergence among reported hashes for network #{:?}.",
|
||||
"Divergence among reported hashes for network: {:?}.",
|
||||
network_id
|
||||
),
|
||||
Self::ContradictoryBlocks(len, deviation, network_id) => {
|
||||
write!(fmt, "Divergence among {len} reported blocks exceeds the maximum allowed deviation of {deviation} for network #{:?}.", network_id)
|
||||
write!(fmt, "Divergence among {len} reported blocks exceeds the maximum threshold of {deviation} provided for network: {:?}.", network_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ impl core::fmt::Debug for RpcResolverError {
|
||||
"The 'result' field in the JSON-RPC response is missing or null."
|
||||
),
|
||||
Self::UnknownNetworkType => {
|
||||
write!(fmt, "The provided network type identifier is not supported.")
|
||||
write!(fmt, "he provided network type identifier is not supported.")
|
||||
}
|
||||
Self::RpcProtocolError => write!(
|
||||
fmt,
|
||||
|
||||
@ -3,10 +3,7 @@
|
||||
|
||||
use frame_support::{
|
||||
pallet_prelude::*,
|
||||
traits::{
|
||||
Get, OneSessionHandler,
|
||||
tokens::fungible::{Inspect, Mutate},
|
||||
},
|
||||
traits::{Currency, Get, OneSessionHandler},
|
||||
};
|
||||
use frame_system::{
|
||||
pallet_prelude::*,
|
||||
@ -89,10 +86,13 @@ type ThreadId = u64;
|
||||
type WeavingSession = u64;
|
||||
type ExternalBlockNumber = u64;
|
||||
|
||||
type BalanceOf<T> = <<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
type NetworkIdOf<T> = <<T as Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId;
|
||||
type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
pub type NetworkIdOf<T> = <<T as Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId;
|
||||
|
||||
type WeavingResult<T, O> = Result<O, WeavingError<NetworkIdOf<T>>>;
|
||||
|
||||
type WeaversBitmap<T> = BoundedBitmap<BitmapChunk, <T as Config>::MaxAuthoritiesChunks>;
|
||||
|
||||
#[frame_support::pallet]
|
||||
@ -117,7 +117,7 @@ pub mod pallet {
|
||||
+ MaybeSerializeDeserialize
|
||||
+ MaxEncodedLen;
|
||||
|
||||
type Currency: Inspect<Self::AccountId> + Mutate<Self::AccountId>;
|
||||
type Currency: Currency<Self::AccountId>;
|
||||
|
||||
type NetworkDataHandler: NetworkDataBasicHandler
|
||||
+ NetworkDataInspectHandler<NetworkData>
|
||||
@ -439,7 +439,7 @@ pub mod pallet {
|
||||
.ok_or(Error::<T>::NonExistentNetworkId)?;
|
||||
|
||||
let root_hash = LoomStates::<T>::get(&network_id, &session);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session, network_id);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session);
|
||||
|
||||
ensure!(
|
||||
!PulledThreads::<T>::contains_key(&pulled_thread_key),
|
||||
@ -447,7 +447,7 @@ pub mod pallet {
|
||||
);
|
||||
|
||||
let (receiver_account, amount) = thread_proof
|
||||
.verify_thread_proof(root_hash, network_id, &network_data.gatekeeper)
|
||||
.verify_thread_proof(root_hash, &network_data.gatekeeper)
|
||||
.ok_or(Error::<T>::InvalidMerkleProof)?;
|
||||
|
||||
let receiver_bytes: &[u8; 32] = receiver_account.as_ref();
|
||||
@ -458,7 +458,7 @@ pub mod pallet {
|
||||
T::NetworkDataHandler::register_incoming(&network_id, amount)
|
||||
.map_err(|_| Error::<T>::CouldNotRegisterIncoming)?;
|
||||
|
||||
T::Currency::mint_into(&receiver, pure_amount)?;
|
||||
let _ = T::Currency::deposit_creating(&receiver, pure_amount);
|
||||
PulledThreads::<T>::insert(pulled_thread_key, ());
|
||||
|
||||
Self::deposit_event(Event::<T>::ThreadPulled {
|
||||
|
||||
@ -560,7 +560,7 @@ fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
|
||||
fn should_successfully_pull_evm_thread_and_mint_currency() {
|
||||
let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
|
||||
|
||||
let network_id = 11155111;
|
||||
let network_id = 1;
|
||||
let network_data = NetworkDataBuilder::default()
|
||||
.with_network_type(NetworkType::Evm)
|
||||
.build();
|
||||
@ -568,84 +568,208 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
|
||||
let authorities = vec![pair.clone()];
|
||||
let networks = vec![(network_id, network_data, Default::default())];
|
||||
|
||||
// Contract address: 0x7fec11e652f4d54e8cf11c4b52c360380332f2bd
|
||||
// Contract address: 0x9a52C28dA655b69d8ddc430d6ebD04630BA0e845
|
||||
//
|
||||
// three inserts
|
||||
// 69 sfJ9hc4A7r578XM35nd48B3FWcd33XjpVnAbGC5tvtwthMWdU - 0xc477f0a42fdd861485bd854c7a5851614ea163bd295f7844e1c5493d662fdc4e
|
||||
// 420 sfDxNicCEPts6CVttVMPCs2eoymDpQahu1GUVyGPWu6dhwADJ - 0x0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e
|
||||
// 1337 sfH6zJ63fcxrFAZ1RmiHbxgy2t3sEufY26WdsBSS359AzJd4w - 0x962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b
|
||||
|
||||
// https://sepolia.etherscan.io/address/0x7fec11e652f4d54e8cf11c4b52c360380332f2bd#readContract
|
||||
// getRoot: atBlock 11716130, globalIndexes from 0 to 2
|
||||
// https://sepolia.etherscan.io/address/0x81acdf2da6b50d806c96aecd9a498a5359e373c0#readContract
|
||||
// getRoot: atBlock 11660400, globalIndexes from 0 to 2
|
||||
let inserts = vec![
|
||||
(
|
||||
0,
|
||||
hex::decode("c477f0a42fdd861485bd854c7a5851614ea163bd295f7844e1c5493d662fdc4e").expect("Bytes32 from EVM should be valid"),
|
||||
hex::decode("c477f0a42fdd861485bd854c7a5851614ea163bd295f7844e1c5493d662fdc4e")
|
||||
.expect("Bytes32 from EVM should be valid"),
|
||||
69u64,
|
||||
vec![
|
||||
H256::from_slice(&hex::decode("2d931b11b1652669a04e7b5b50418f5e1e2fabb6791dabc9a196e719ad5cf9c6").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("9f00b99751b7ccea1903949210408edb3ce50343985708c36a0b1d44e0a7628c").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040").expect("Proof should be valid")),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"675a2e7b05b8b3932cd0faf88f1bc29767b7462667f56d051b8d5325bda0ee73",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"da1fbdfefa1e9aedfedcfc48fb17cb0e731529f7a3695114e0a9caa1989dd420",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
],
|
||||
vec![H256::from_slice(
|
||||
&hex::decode("f494b2065ca61f2af007a3dd5f1f3d228a3ad09f4f7b7c5ef3eeb3aee6718ee2").expect("Slot should be valid hex"),
|
||||
&hex::decode("350a78f78c810898b7c60ddba671543bfbe683ffb0ac393df0e132f607b5f738")
|
||||
.expect("Slot should be valid hex"),
|
||||
)],
|
||||
),
|
||||
(
|
||||
1,
|
||||
hex::decode("0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e").expect("Bytes32 from EVM should be valid"),
|
||||
hex::decode("0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e")
|
||||
.expect("Bytes32 from EVM should be valid"),
|
||||
420u64,
|
||||
vec![
|
||||
H256::from_slice(&hex::decode("7d831a4be9e37572687117870c3f96669a66bf07971e4fd705a36a0a4d6365b0").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("9f00b99751b7ccea1903949210408edb3ce50343985708c36a0b1d44e0a7628c").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040").expect("Proof should be valid")),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"c5354289f0397c916949373043eb1d5ea99447f67fe014324d96c58ef02a2d11",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"da1fbdfefa1e9aedfedcfc48fb17cb0e731529f7a3695114e0a9caa1989dd420",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
],
|
||||
vec![H256::from_slice(
|
||||
&hex::decode("f6182b8c276793f53d1820ad0405665177516e46e40af45e0dfea73c39a2306e").expect("Slot should be valid hex"),
|
||||
&hex::decode("2e474dabf492786b3505d7b7cf0bf07c9dbce92c91982fa7344c77e24fd4310d")
|
||||
.expect("Slot should be valid hex"),
|
||||
)],
|
||||
),
|
||||
(
|
||||
2,
|
||||
hex::decode("962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b").expect("Bytes32 from EVM should be valid"),
|
||||
hex::decode("962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b")
|
||||
.expect("Bytes32 from EVM should be valid"),
|
||||
1337u64,
|
||||
vec![
|
||||
H256::from_slice(&hex::decode("f39a869f62e75cf5f0bf914688a6b289caf2049435d8e68c5c5e6d05e44913f3").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("385de173dc8295d4153b2de3bd705dd96556c8c316a996b3e56adce0970ffa36").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f").expect("Proof should be valid")),
|
||||
H256::from_slice(&hex::decode("de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040").expect("Proof should be valid")),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"f39a869f62e75cf5f0bf914688a6b289caf2049435d8e68c5c5e6d05e44913f3",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"e0090094ce1d7af8a81ba78bef4b137c1ab32d20d5487224a9f8df95b516c1e4",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
H256::from_slice(
|
||||
&hex::decode(
|
||||
"de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040",
|
||||
)
|
||||
.expect("Proof should be valid"),
|
||||
),
|
||||
],
|
||||
vec![H256::from_slice(
|
||||
&hex::decode("2f52c7d2d3f4167c436f3b6cc0a7d944a45846ba87f74998100b83122d5eb0ad").expect("Slot should be valid hex"),
|
||||
&hex::decode("bde870fce92d701a7a5d6f63003e1cd2cb61c3266fc1be256844b8ca61d9c9ab")
|
||||
.expect("Slot should be valid hex"),
|
||||
)],
|
||||
),
|
||||
];
|
||||
|
||||
new_test_ext(authorities, networks).execute_with(|| {
|
||||
// https://sepolia.etherscan.io/address/0x7fec11e652f4d54e8cf11c4b52c360380332f2bd#readContract
|
||||
// getRoot: session 0, atBlock 11716130
|
||||
// https://sepolia.etherscan.io/address/0x81acdf2da6b50d806c96aecd9a498a5359e373c0#readContract
|
||||
// getRoot: session 0, atBlock 11660400
|
||||
let session = 0;
|
||||
let root_string =
|
||||
hex::decode("07f4a5ba4750d9ddfc080429287cbcbde7464aa2f8ae13feaade0dcb45ca6129")
|
||||
hex::decode("28d1e6b476b03a464f74d531d532572db29d6b57349e4f17f84e92843f6c4ee7")
|
||||
.expect("Root hex should be valid");
|
||||
let expected_root = H256::from_slice(&root_string);
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);
|
||||
|
||||
let mut total_issuance = 0;
|
||||
|
||||
for insert in inserts.into_iter() {
|
||||
let index_usize = insert.0 as crate::ThreadId;
|
||||
let proof_index = index_usize % 256; // tree depth is fixed to 8
|
||||
@ -671,9 +795,8 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
|
||||
);
|
||||
|
||||
let thread_info = ThreadProof::EvmThreadProof(evm_thread_proof);
|
||||
let pulled_thread_key = thread_info.get_unique_key(session, network_id);
|
||||
let pulled_thread_key = thread_info.get_unique_key(session);
|
||||
|
||||
assert_eq!(Balances::total_issuance(), total_issuance);
|
||||
assert_eq!(Balances::free_balance(&receiver_account), 0);
|
||||
assert!(!PulledThreads::<TestRuntime>::contains_key(
|
||||
&pulled_thread_key
|
||||
@ -683,7 +806,8 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
|
||||
network_id,
|
||||
session,
|
||||
thread_info
|
||||
).is_ok());
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert!(PulledThreads::<TestRuntime>::contains_key(
|
||||
&pulled_thread_key
|
||||
@ -691,15 +815,12 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
|
||||
|
||||
let expected_commission = 0u64;
|
||||
let expected_pure_amount = transfer_amount - expected_commission;
|
||||
total_issuance = total_issuance.saturating_add(expected_pure_amount);
|
||||
|
||||
assert_eq!(Balances::total_issuance(), total_issuance);
|
||||
assert_eq!(
|
||||
Balances::free_balance(&receiver_account),
|
||||
expected_pure_amount
|
||||
);
|
||||
|
||||
|
||||
System::assert_last_event(RuntimeEvent::GhostWeaver(Event::ThreadPulled {
|
||||
pulled_thread_key,
|
||||
network_id,
|
||||
@ -766,7 +887,7 @@ fn should_successfully_pull_utxo_thread_and_mint_currency() {
|
||||
|
||||
let utxo_thread_proof = UtxoThreadProof::new(payload.0, payload.1, payload.2);
|
||||
let thread_info = ThreadProof::UtxoThreadProof(utxo_thread_proof);
|
||||
let pulled_thread_key = thread_info.get_unique_key(session, network_id);
|
||||
let pulled_thread_key = thread_info.get_unique_key(session);
|
||||
|
||||
assert_eq!(Balances::free_balance(&receiver_account), 0);
|
||||
assert!(!PulledThreads::<TestRuntime>::contains_key(
|
||||
|
||||
@ -288,40 +288,31 @@ where
|
||||
Balance: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u128>,
|
||||
u64: UniqueSaturatedInto<Balance>,
|
||||
{
|
||||
pub fn verify_thread_proof<NetworkId>(
|
||||
&self,
|
||||
root_hash: H256,
|
||||
network_id: NetworkId,
|
||||
gatekeeper: &[u8]
|
||||
) -> Option<(AccountId32, Balance)>
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
pub fn is_evm_proof_correct(&self) -> bool {
|
||||
match self {
|
||||
Self::UtxoThreadProof(utxo_thread) => {
|
||||
utxo_thread.verify_thread_proof(root_hash, gatekeeper)
|
||||
},
|
||||
Self::EvmThreadProof(evm_thread) => {
|
||||
evm_thread.verify_thread_proof(root_hash, network_id)
|
||||
},
|
||||
Self::EvmThreadProof(_) => true,
|
||||
Self::UtxoThreadProof(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_unique_key<NetworkId>(
|
||||
&self,
|
||||
session: WeavingSession,
|
||||
network_id: NetworkId,
|
||||
) -> H256
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
pub fn is_utxo_proof_correct(&self) -> bool {
|
||||
match self {
|
||||
Self::EvmThreadProof(thread_info) => {
|
||||
thread_info.get_unique_key(session, network_id)
|
||||
},
|
||||
Self::UtxoThreadProof(utxo_thread) => {
|
||||
utxo_thread.get_unique_key(network_id)
|
||||
},
|
||||
Self::UtxoThreadProof(_) => true,
|
||||
Self::EvmThreadProof(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify_thread_proof(&self, root_hash: H256, gatekeeper: &[u8]) -> Option<(AccountId32, Balance)> {
|
||||
match self {
|
||||
Self::UtxoThreadProof(utxo_thread) => utxo_thread.verify_thread_proof(root_hash, gatekeeper),
|
||||
Self::EvmThreadProof(evm_thread) => evm_thread.verify_thread_proof(root_hash),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_unique_key(&self, session: WeavingSession) -> H256 {
|
||||
match self {
|
||||
Self::EvmThreadProof(thread_info) => thread_info.get_unique_key(session),
|
||||
Self::UtxoThreadProof(utxo_thread) => utxo_thread.get_unique_key(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,18 +331,11 @@ impl<Balance> EvmThreadProof<Balance>
|
||||
where
|
||||
Balance: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u128>,
|
||||
{
|
||||
pub fn verify_thread_proof<NetworkId>(
|
||||
&self,
|
||||
root_hash: H256,
|
||||
network_id: NetworkId,
|
||||
) -> Option<(AccountId32, Balance)>
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
pub fn verify_thread_proof(&self, root_hash: H256) -> Option<(AccountId32, Balance)> {
|
||||
if EVM_MERKLE_DEPTH as usize != self.proof.len() { return None; }
|
||||
|
||||
let proof_valid = verify_tree_proof::<SubstrateKeccakHasher, _>(
|
||||
&self.get_preimage_slice(network_id).to_fixed_bytes(),
|
||||
&self.get_preimage_slice().to_fixed_bytes(),
|
||||
self.proof.as_ref(),
|
||||
root_hash,
|
||||
self.proof_index,
|
||||
@ -362,85 +346,41 @@ where
|
||||
Some((self.receiver.clone(), self.amount))
|
||||
}
|
||||
|
||||
fn get_preimage_slice<NetworkId>(&self, network_id: NetworkId) -> H256
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
fn get_preimage_slice(&self) -> H256 {
|
||||
let slot_index_usize: usize = self.slot_index.unique_saturated_into();
|
||||
let mut slot_values: Vec<H256> = self.slots.to_vec();
|
||||
|
||||
match slot_values.get_mut(slot_index_usize) {
|
||||
Some(slot) => {
|
||||
*slot = self.compute_arguments_hash(network_id);
|
||||
cumulative_hash::<SubstrateKeccakHasher, _>(slot_values)
|
||||
}
|
||||
None => {
|
||||
SubstrateKeccakHasher::empty()
|
||||
}
|
||||
}
|
||||
(slot_index_usize < self.slots.len())
|
||||
.then(|| {
|
||||
self.slots
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, &preimage)| {
|
||||
if index == slot_index_usize {
|
||||
self.compute_arguments_hash()
|
||||
} else {
|
||||
preimage
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.map(|slots| cumulative_hash::<SubstrateKeccakHasher, _>(slots))
|
||||
.unwrap_or(SubstrateKeccakHasher::empty())
|
||||
}
|
||||
|
||||
pub fn get_unique_key<NetworkId>(
|
||||
&self,
|
||||
session: WeavingSession,
|
||||
network_id: NetworkId,
|
||||
) -> H256
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
pub fn get_unique_key(&self, session: WeavingSession) -> H256 {
|
||||
let session_bytes = (session as u64).to_be_bytes();
|
||||
let slot_index_bytes = (self.slot_index as u64).to_be_bytes();
|
||||
let proof_index_bytes = (self.proof_index as u64).to_be_bytes();
|
||||
|
||||
let network_id_u64: u64 = network_id.unique_saturated_into();
|
||||
let network_id_bytes = network_id_u64.to_be_bytes();
|
||||
let slot_bytes = (self.slot_index as u64).to_be_bytes();
|
||||
let proof_bytes = (self.proof_index as u64).to_be_bytes();
|
||||
|
||||
let mut h1 = [0u8; 32]; h1[24..32].copy_from_slice(&session_bytes);
|
||||
let mut h2 = [0u8; 32]; h2[24..32].copy_from_slice(&slot_index_bytes);
|
||||
let mut h3 = [0u8; 32]; h3[24..32].copy_from_slice(&proof_index_bytes);
|
||||
let mut h4 = [0u8; 32]; h4[24..32].copy_from_slice(&network_id_bytes);
|
||||
let mut h2 = [0u8; 32]; h2[24..32].copy_from_slice(&slot_bytes);
|
||||
let mut h3 = [0u8; 32]; h3[24..32].copy_from_slice(&proof_bytes);
|
||||
|
||||
let metadata: [H256; 4] = [
|
||||
H256::from(h1),
|
||||
H256::from(h2),
|
||||
H256::from(h3),
|
||||
H256::from(h4),
|
||||
];
|
||||
let metadata: [H256; 3] = [H256::from(h1), H256::from(h2), H256::from(h3)];
|
||||
|
||||
sequential_hash::<SubstrateBlake2Hasher, _>(metadata)
|
||||
}
|
||||
|
||||
fn compute_arguments_hash<NetworkId>(&self, network_id: NetworkId) -> H256
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
let amount_u128: u128 = self.amount.unique_saturated_into();
|
||||
let slot_index_u64: u64 = self.slot_index.unique_saturated_into();
|
||||
let network_id_u64: u64 = network_id.unique_saturated_into();
|
||||
|
||||
let amount_u256 = U256::from(amount_u128);
|
||||
let slot_index_u256 = U256::from(slot_index_u64);
|
||||
let network_id_u256 = U256::from(network_id_u64);
|
||||
|
||||
let mut padded_amount = [0u8; 32];
|
||||
amount_u256.to_big_endian(&mut padded_amount);
|
||||
|
||||
let mut padded_slot_index = [0u8; 32];
|
||||
slot_index_u256.to_big_endian(&mut padded_slot_index);
|
||||
|
||||
let mut padded_network_id = [0u8; 32];
|
||||
network_id_u256.to_big_endian(&mut padded_network_id);
|
||||
|
||||
let inputs: [&[u8]; 4] = [
|
||||
padded_amount.as_ref(),
|
||||
self.receiver.as_ref(),
|
||||
padded_slot_index.as_ref(),
|
||||
padded_network_id.as_ref(),
|
||||
];
|
||||
|
||||
sequential_hash::<SubstrateKeccakHasher, _>(inputs)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
slot_index: ThreadId,
|
||||
proof_index: ThreadId,
|
||||
@ -464,6 +404,27 @@ where
|
||||
slots,
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_arguments_hash(&self) -> H256 {
|
||||
let amount_u128: u128 = self.amount.unique_saturated_into();
|
||||
let amount_u256 = U256::from(amount_u128);
|
||||
|
||||
let slot_index_u64: u64 = self.slot_index.unique_saturated_into();
|
||||
let slot_index_u256 = U256::from(slot_index_u64);
|
||||
|
||||
let mut padded_amount = [0u8; 32];
|
||||
amount_u256.to_big_endian(&mut padded_amount);
|
||||
|
||||
let mut padded_slot_index = [0u8; 32];
|
||||
slot_index_u256.to_big_endian(&mut padded_slot_index);
|
||||
|
||||
let inputs: [&[u8]; 3] = [
|
||||
padded_amount.as_ref(),
|
||||
self.receiver.as_ref(),
|
||||
padded_slot_index.as_ref(),
|
||||
];
|
||||
sequential_hash::<SubstrateKeccakHasher, _>(inputs)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
@ -486,7 +447,7 @@ impl UtxoThreadProof {
|
||||
root_hash: H256,
|
||||
gatekeeper_ref: &[u8],
|
||||
) -> Option<(AccountId32, Balance)>
|
||||
where
|
||||
where
|
||||
Balance: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u128>,
|
||||
u64: UniqueSaturatedInto<Balance>,
|
||||
{
|
||||
@ -527,17 +488,10 @@ impl UtxoThreadProof {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn get_unique_key<NetworkId>(&self, network_id: NetworkId) -> H256
|
||||
where
|
||||
NetworkId: Copy + Clone + Eq + PartialEq + UniqueSaturatedInto<u64>,
|
||||
{
|
||||
let network_id_u64: u64 = network_id.unique_saturated_into();
|
||||
let network_id_bytes = network_id_u64.to_be_bytes();
|
||||
|
||||
pub fn get_unique_key(&self) -> H256 {
|
||||
let metadata: &[&[u8]] = &[
|
||||
self.gettxproof_bytes.as_ref(),
|
||||
self.getrawtransaction_bytes.as_ref(),
|
||||
network_id_bytes.as_ref(),
|
||||
];
|
||||
|
||||
sequential_hash::<SubstrateBlake2Hasher, _>(metadata)
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
//! Autogenerated weights for `ghost_weaver`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2026-09-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2026-09-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
|
||||
@ -69,11 +69,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `223 + a * (32 ±0)`
|
||||
// Estimated: `3687 + a * (32 ±0)`
|
||||
// Minimum execution time: 212_751_000 picoseconds.
|
||||
Weight::from_parts(215_022_916, 0)
|
||||
// Minimum execution time: 210_105_000 picoseconds.
|
||||
Weight::from_parts(214_589_101, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3687))
|
||||
// Standard Error: 1_319
|
||||
.saturating_add(Weight::from_parts(53_379, 0).saturating_mul(a.into()))
|
||||
// Standard Error: 1_420
|
||||
.saturating_add(Weight::from_parts(50_124, 0).saturating_mul(a.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(1))
|
||||
.saturating_add(Weight::from_parts(0, 32).saturating_mul(a.into()))
|
||||
@ -95,11 +95,11 @@ impl WeightInfo for () {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `518 + a * (32 ±0)`
|
||||
// Estimated: `3982 + a * (32 ±0)`
|
||||
// Minimum execution time: 212_751_000 picoseconds.
|
||||
Weight::from_parts(246_374_350, 0)
|
||||
// Minimum execution time: 241_676_000 picoseconds.
|
||||
Weight::from_parts(246_243_389, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3982))
|
||||
// Standard Error: 1_865
|
||||
.saturating_add(Weight::from_parts(38_601, 0).saturating_mul(a.into()))
|
||||
// Standard Error: 1_686
|
||||
.saturating_add(Weight::from_parts(32_125, 0).saturating_mul(a.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(6))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 32).saturating_mul(a.into()))
|
||||
@ -114,19 +114,19 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostNetworks::GatekeeperAmounts` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostNetworks::NetworkImbalance` (r:1 w:1)
|
||||
/// Proof: `GhostNetworks::NetworkImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `System::Account` (r:1 w:1)
|
||||
/// Storage: `System::Account` (r:1 w:0)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// The range of component `a` is `[1, 144]`.
|
||||
fn pull_utxo_thread(a: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `449`
|
||||
// Estimated: `3914`
|
||||
// Minimum execution time: 217_880_000 picoseconds.
|
||||
Weight::from_parts(217_119_201, 0)
|
||||
// Standard Error: 4_368
|
||||
.saturating_add(Weight::from_parts(3_445_491, 0).saturating_mul(a.into()))
|
||||
// Measured: `346`
|
||||
// Estimated: `3811`
|
||||
// Minimum execution time: 170_554_000 picoseconds.
|
||||
Weight::from_parts(170_660_694, 0)
|
||||
// Standard Error: 4_207
|
||||
.saturating_add(Weight::from_parts(3_450_120, 0).saturating_mul(a.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(6))
|
||||
.saturating_add(RocksDbWeight::get().writes(4))
|
||||
.saturating_add(RocksDbWeight::get().writes(3))
|
||||
}
|
||||
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
|
||||
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
@ -138,16 +138,16 @@ impl WeightInfo for () {
|
||||
/// Proof: `GhostNetworks::GatekeeperAmounts` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostNetworks::NetworkImbalance` (r:1 w:1)
|
||||
/// Proof: `GhostNetworks::NetworkImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `System::Account` (r:1 w:1)
|
||||
/// Storage: `System::Account` (r:1 w:0)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
fn pull_evm_thread() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `449`
|
||||
// Estimated: `3914`
|
||||
// Minimum execution time: 183_413_000 picoseconds.
|
||||
Weight::from_parts(186_271_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3914))
|
||||
// Measured: `3446`
|
||||
// Estimated: `3811`
|
||||
// Minimum execution time: 136_258_000 picoseconds.
|
||||
Weight::from_parts(137_856_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3811))
|
||||
.saturating_add(RocksDbWeight::get().reads(6))
|
||||
.saturating_add(RocksDbWeight::get().writes(4))
|
||||
.saturating_add(RocksDbWeight::get().writes(3))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "casper-runtime"
|
||||
version = "4.0.14"
|
||||
version = "4.0.10"
|
||||
build = "build.rs"
|
||||
description = "Runtime of the Casper Network"
|
||||
edition.workspace = true
|
||||
|
||||
@ -15,7 +15,7 @@ use frame_support::{
|
||||
traits::{
|
||||
fungible::HoldConsideration,
|
||||
tokens::{imbalance::ResolveTo, UnityAssetBalanceConversion},
|
||||
ConstU128, ConstU32, ConstU8, InstanceFilter, KeyOwnerProofSystem,
|
||||
ConstU128, ConstU32, InstanceFilter, KeyOwnerProofSystem,
|
||||
LinearStoragePrice,
|
||||
},
|
||||
};
|
||||
@ -123,8 +123,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("casper"),
|
||||
impl_name: create_runtime_str!("casper-svengali"),
|
||||
authoring_version: 0,
|
||||
spec_version: 7,
|
||||
impl_version: 0,
|
||||
spec_version: 6,
|
||||
impl_version: 4,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
state_version: 1,
|
||||
@ -860,7 +860,7 @@ impl ghost_nomination_pools::Config for Runtime {
|
||||
type PalletId = PoolsPalletId;
|
||||
type MaxPointsToBalance = MaxPointsToBalance;
|
||||
type AdminOrigin = EnsureRoot<Self::AccountId>;
|
||||
type WeightInfo = weights::ghost_nomination_pools::WeightInfo<Runtime>;
|
||||
type WeightInfo = weights::ghost_nomination_pools::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
impl ghost_networks::Config for Runtime {
|
||||
@ -887,8 +887,7 @@ impl ghost_governance::Config for Runtime {
|
||||
type Currency = Balances;
|
||||
type NetworkDataHandler = GhostNetworks;
|
||||
type MinimumDonation = ConstU128<{ 6_900 * STRH }>;
|
||||
type MaxProofDepth = ConstU32<18>;
|
||||
type MaxPartialClaims = ConstU8<20>;
|
||||
type MaxProofDepth = ConstU32<20>;
|
||||
|
||||
type WeightInfo = weights::ghost_governance::WeightInfo<Runtime>;
|
||||
}
|
||||
@ -914,7 +913,6 @@ parameter_types! {
|
||||
pub ExodusDkgRoundPeriod: u64 = 50;
|
||||
pub ExodusRemovalLimit: u32 = 64;
|
||||
pub ExodusMaxCursorLen: u32 = 100;
|
||||
pub MinBridgeOut: u128 = 500 * STRH;
|
||||
}
|
||||
|
||||
impl ghost_weaver::Config for Runtime {
|
||||
@ -953,7 +951,6 @@ impl ghost_exodus::Config for Runtime {
|
||||
type DkgRoundPeriod = ExodusDkgRoundPeriod;
|
||||
type RemovalLimit = ExodusRemovalLimit;
|
||||
type MaxCursorLen = ExodusMaxCursorLen;
|
||||
type BaseEvmAmount = MinBridgeOut;
|
||||
|
||||
type WeightInfo = weights::ghost_exodus::WeightInfo<Runtime>;
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
//! Autogenerated weights for `ghost_exodus`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2026-09-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2026-09-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
|
||||
@ -60,8 +60,8 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `351`
|
||||
// Estimated: `3816`
|
||||
// Minimum execution time: 240_813_000 picoseconds.
|
||||
Weight::from_parts(243_523_000, 0)
|
||||
// Minimum execution time: 239_012_000 picoseconds.
|
||||
Weight::from_parts(241_388_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3816))
|
||||
.saturating_add(T::DbWeight::get().reads(4))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
@ -83,11 +83,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `391 + c * (32 ±0)`
|
||||
// Estimated: `3856 + c * (32 ±0)`
|
||||
// Minimum execution time: 1_356_791_000 picoseconds.
|
||||
Weight::from_parts(1_221_760_215, 0)
|
||||
// Minimum execution time: 1_339_828_000 picoseconds.
|
||||
Weight::from_parts(1_212_625_790, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3856))
|
||||
// Standard Error: 16_481
|
||||
.saturating_add(Weight::from_parts(33_163_393, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 11_831
|
||||
.saturating_add(Weight::from_parts(33_120_868, 0).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into()))
|
||||
@ -107,11 +107,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `317 + c * (257 ±0)`
|
||||
// Estimated: `3783 + c * (257 ±0)`
|
||||
// Minimum execution time: 254_590_000 picoseconds.
|
||||
Weight::from_parts(258_091_105, 0)
|
||||
// Minimum execution time: 251_478_000 picoseconds.
|
||||
Weight::from_parts(254_144_621, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3783))
|
||||
// Standard Error: 25_082
|
||||
.saturating_add(Weight::from_parts(6_595_878, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 24_613
|
||||
.saturating_add(Weight::from_parts(6_595_819, 0).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 257).saturating_mul(c.into()))
|
||||
@ -131,11 +131,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `317 + c * (257 ±0)`
|
||||
// Estimated: `3783 + c * (257 ±0)`
|
||||
// Minimum execution time: 240_888_000 picoseconds.
|
||||
Weight::from_parts(245_480_975, 0)
|
||||
// Minimum execution time: 236_155_000 picoseconds.
|
||||
Weight::from_parts(242_055_898, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3783))
|
||||
// Standard Error: 13_733
|
||||
.saturating_add(Weight::from_parts(371_161, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 15_623
|
||||
.saturating_add(Weight::from_parts(360_411, 0).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 257).saturating_mul(c.into()))
|
||||
@ -155,11 +155,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `317 + c * (257 ±0)`
|
||||
// Estimated: `3783 + c * (257 ±0)`
|
||||
// Minimum execution time: 251_521_000 picoseconds.
|
||||
Weight::from_parts(253_053_636, 0)
|
||||
// Minimum execution time: 249_507_000 picoseconds.
|
||||
Weight::from_parts(248_505_595, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3783))
|
||||
// Standard Error: 14_691
|
||||
.saturating_add(Weight::from_parts(4_101_872, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 20_302
|
||||
.saturating_add(Weight::from_parts(4_191_526, 0).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 257).saturating_mul(c.into()))
|
||||
@ -180,8 +180,8 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `448`
|
||||
// Estimated: `3913`
|
||||
// Minimum execution time: 265_187_000 picoseconds.
|
||||
Weight::from_parts(269_124_000, 0)
|
||||
// Minimum execution time: 264_214_000 picoseconds.
|
||||
Weight::from_parts(266_905_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3913))
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
@ -205,11 +205,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + c * (770 ±0)`
|
||||
// Estimated: `1551 + c * (1019 ±27)`
|
||||
// Minimum execution time: 284_558_000 picoseconds.
|
||||
Weight::from_parts(284_117_484, 0)
|
||||
// Minimum execution time: 281_073_000 picoseconds.
|
||||
Weight::from_parts(280_778_987, 0)
|
||||
.saturating_add(Weight::from_parts(0, 1551))
|
||||
// Standard Error: 74_361
|
||||
.saturating_add(Weight::from_parts(3_551_271, 0).saturating_mul(c.into()))
|
||||
// Standard Error: 79_426
|
||||
.saturating_add(Weight::from_parts(3_449_552, 0).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(7))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
.saturating_add(Weight::from_parts(0, 1019).saturating_mul(c.into()))
|
||||
@ -234,11 +234,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostExodus::NonceCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_nonce_commitment() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `627`
|
||||
// Estimated: `4092`
|
||||
// Minimum execution time: 315_066_000 picoseconds.
|
||||
Weight::from_parts(318_561_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4092))
|
||||
// Measured: `588`
|
||||
// Estimated: `4053`
|
||||
// Minimum execution time: 291_972_000 picoseconds.
|
||||
Weight::from_parts(295_122_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4053))
|
||||
.saturating_add(T::DbWeight::get().reads(8))
|
||||
.saturating_add(T::DbWeight::get().writes(5))
|
||||
}
|
||||
@ -264,11 +264,11 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostExodus::GroupCommitmentsConsensus` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_group_commitment() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `992`
|
||||
// Estimated: `4457`
|
||||
// Minimum execution time: 338_644_000 picoseconds.
|
||||
Weight::from_parts(343_954_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4457))
|
||||
// Measured: `968`
|
||||
// Estimated: `4433`
|
||||
// Minimum execution time: 331_528_000 picoseconds.
|
||||
Weight::from_parts(333_974_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 4433))
|
||||
.saturating_add(T::DbWeight::get().reads(10))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
@ -300,22 +300,18 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostExodus::ActiveVerifyingKey` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::SignatureScalars` (r:1 w:1)
|
||||
/// Proof: `GhostExodus::SignatureScalars` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::CounterForExodusRequests` (r:1 w:1)
|
||||
/// Proof: `GhostExodus::CounterForExodusRequests` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::GroupCommitters` (r:0 w:1)
|
||||
/// Proof: `GhostExodus::GroupCommitters` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_signature_share() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `11299`
|
||||
// Estimated: `14764`
|
||||
// Minimum execution time: 3_968_938_000 picoseconds.
|
||||
Weight::from_parts(3_975_088_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 14764))
|
||||
.saturating_add(T::DbWeight::get().reads(15))
|
||||
.saturating_add(T::DbWeight::get().writes(9))
|
||||
// Measured: `11259`
|
||||
// Estimated: `14724`
|
||||
// Minimum execution time: 3_980_585_000 picoseconds.
|
||||
Weight::from_parts(3_985_167_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 14724))
|
||||
.saturating_add(T::DbWeight::get().reads(14))
|
||||
.saturating_add(T::DbWeight::get().writes(8))
|
||||
}
|
||||
/// Storage: `GhostExodus::CounterForExodusRequests` (r:1 w:1)
|
||||
/// Proof: `GhostExodus::CounterForExodusRequests` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
|
||||
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostNetworks::GatekeeperAmounts` (r:1 w:1)
|
||||
@ -326,16 +322,16 @@ impl<T: frame_system::Config> ghost_exodus::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostExodus::QualificationDkgState` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::CurrentExodus` (r:1 w:1)
|
||||
/// Proof: `GhostExodus::CurrentExodus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostExodus::ExodusRequests` (r:1 w:1)
|
||||
/// Storage: `GhostExodus::ExodusRequests` (r:0 w:1)
|
||||
/// Proof: `GhostExodus::ExodusRequests` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn register_evm_bridge_out_exodus() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `448`
|
||||
// Estimated: `3913`
|
||||
// Minimum execution time: 191_374_000 picoseconds.
|
||||
Weight::from_parts(192_991_000, 0)
|
||||
// Minimum execution time: 137_053_000 picoseconds.
|
||||
Weight::from_parts(138_693_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3913))
|
||||
.saturating_add(T::DbWeight::get().reads(7))
|
||||
.saturating_add(T::DbWeight::get().writes(5))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
//! Autogenerated weights for `ghost_governance`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2026-09-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2026-09-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
|
||||
@ -50,23 +50,21 @@ impl<T: frame_system::Config> ghost_governance::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostGovernance::MemberShares` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::ClaimedHashes` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::ClaimedHashes` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::ClaimedShares` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::ClaimedShares` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::NetworkShares` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::NetworkShares` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostGovernance::GlobalShares` (r:1 w:1)
|
||||
/// Proof: `GhostGovernance::GlobalShares` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// The range of component `p` is `[1, 18]`.
|
||||
/// The range of component `p` is `[1, 20]`.
|
||||
fn claim(p: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `283`
|
||||
// Estimated: `3748`
|
||||
// Minimum execution time: 229_254_000 picoseconds.
|
||||
Weight::from_parts(229_992_093, 0)
|
||||
// Minimum execution time: 214_208_000 picoseconds.
|
||||
Weight::from_parts(216_987_870, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3748))
|
||||
// Standard Error: 25_680
|
||||
.saturating_add(Weight::from_parts(1_874_433, 0).saturating_mul(p.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(5))
|
||||
// Standard Error: 30_856
|
||||
.saturating_add(Weight::from_parts(1_702_104, 0).saturating_mul(p.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(4))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
//! Autogenerated weights for `ghost_weaver`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2026-09-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2026-09-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
|
||||
@ -61,11 +61,11 @@ impl<T: frame_system::Config> ghost_weaver::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `223 + a * (32 ±0)`
|
||||
// Estimated: `3687 + a * (32 ±0)`
|
||||
// Minimum execution time: 212_751_000 picoseconds.
|
||||
Weight::from_parts(215_022_916, 0)
|
||||
// Minimum execution time: 210_105_000 picoseconds.
|
||||
Weight::from_parts(214_589_101, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3687))
|
||||
// Standard Error: 1_319
|
||||
.saturating_add(Weight::from_parts(53_379, 0).saturating_mul(a.into()))
|
||||
// Standard Error: 1_420
|
||||
.saturating_add(Weight::from_parts(50_124, 0).saturating_mul(a.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
.saturating_add(Weight::from_parts(0, 32).saturating_mul(a.into()))
|
||||
@ -87,11 +87,11 @@ impl<T: frame_system::Config> ghost_weaver::WeightInfo for WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `518 + a * (32 ±0)`
|
||||
// Estimated: `3982 + a * (32 ±0)`
|
||||
// Minimum execution time: 243_006_000 picoseconds.
|
||||
Weight::from_parts(246_374_350, 0)
|
||||
// Minimum execution time: 241_676_000 picoseconds.
|
||||
Weight::from_parts(246_243_389, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3982))
|
||||
// Standard Error: 1_865
|
||||
.saturating_add(Weight::from_parts(38_601, 0).saturating_mul(a.into()))
|
||||
// Standard Error: 1_686
|
||||
.saturating_add(Weight::from_parts(32_125, 0).saturating_mul(a.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
.saturating_add(Weight::from_parts(0, 32).saturating_mul(a.into()))
|
||||
@ -106,20 +106,20 @@ impl<T: frame_system::Config> ghost_weaver::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostNetworks::GatekeeperAmounts` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostNetworks::NetworkImbalance` (r:1 w:1)
|
||||
/// Proof: `GhostNetworks::NetworkImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `System::Account` (r:1 w:1)
|
||||
/// Storage: `System::Account` (r:1 w:0)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
/// The range of component `a` is `[1, 144]`.
|
||||
fn pull_utxo_thread(a: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `449`
|
||||
// Estimated: `3914`
|
||||
// Minimum execution time: 217_880_000 picoseconds.
|
||||
Weight::from_parts(217_119_201, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3914))
|
||||
// Standard Error: 5_460
|
||||
.saturating_add(Weight::from_parts(3_445_491, 0).saturating_mul(a.into()))
|
||||
// Measured: `346`
|
||||
// Estimated: `3811`
|
||||
// Minimum execution time: 170_554_000 picoseconds.
|
||||
Weight::from_parts(170_660_694, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3811))
|
||||
// Standard Error: 4_207
|
||||
.saturating_add(Weight::from_parts(3_450_120, 0).saturating_mul(a.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
}
|
||||
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
|
||||
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
@ -131,16 +131,16 @@ impl<T: frame_system::Config> ghost_weaver::WeightInfo for WeightInfo<T> {
|
||||
/// Proof: `GhostNetworks::GatekeeperAmounts` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `GhostNetworks::NetworkImbalance` (r:1 w:1)
|
||||
/// Proof: `GhostNetworks::NetworkImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `System::Account` (r:1 w:1)
|
||||
/// Storage: `System::Account` (r:1 w:0)
|
||||
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
fn pull_evm_thread() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `449`
|
||||
// Estimated: `3914`
|
||||
// Minimum execution time: 183_413_000 picoseconds.
|
||||
Weight::from_parts(186_271_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3914))
|
||||
// Measured: `346`
|
||||
// Estimated: `3811`
|
||||
// Minimum execution time: 136_258_000 picoseconds.
|
||||
Weight::from_parts(137_856_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3811))
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
[toolchain]
|
||||
channel = "1.93.1"
|
||||
components = ["rustfmt", "clippy", "rust-src"]
|
||||
targets = ["wasm32-unknown-unknown"]
|
||||
@ -17,21 +17,15 @@ MORDOR_RPC=(
|
||||
"https://rpc.mordor.etccooperative.org"
|
||||
)
|
||||
|
||||
HOODI_RPC=(
|
||||
"https://rpc.hoodi.ethpandaops.io"
|
||||
"https://0xrpc.io/hoodi"
|
||||
"https://ethereum-hoodi.gateway.tatum.io"
|
||||
"https://rpc.sentio.xyz/hoodi"
|
||||
)
|
||||
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Usage: $(basename "$0") [OPTIONS]
|
||||
|
||||
Options:
|
||||
--chain <name> Specify network: 'sepolia', 'hoodi' or 'mordor'. If omitted, checks all.
|
||||
--chain <name> Specify network: 'sepolia' or 'mordor'. If omitted, checks both.
|
||||
--output <dir> Base directory to save results. Creates a subfolder with Unix Timestamp.
|
||||
--rpcs <urls> Comma-separated list of custom RPC endpoints. Disables default networks lists.
|
||||
--rpcs <urls> Comma-separated list of custom RPC endpoints.
|
||||
Disables default Sepolia/Mordor lists.
|
||||
--help Show this help message.
|
||||
|
||||
Example:
|
||||
@ -135,11 +129,8 @@ else
|
||||
check_network "Sepolia" "${SEPOLIA_RPC[@]}"
|
||||
elif [ "$CHOSEN_CHAIN" == "mordor" ]; then
|
||||
check_network "Mordor" "${MORDOR_RPC[@]}"
|
||||
elif [ "$CHOSEN_CHAIN" == "hoodi" ]; then
|
||||
check_network "Hoodi" "${HOODI_RPC[@]}"
|
||||
else
|
||||
check_network "Sepolia" "${SEPOLIA_RPC[@]}"
|
||||
check_network "Mordor" "${MORDOR_RPC[@]}"
|
||||
check_network "Hoodi" "${HOODI_RPC[@]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -85,16 +85,30 @@ extract_seed() {
|
||||
echo $seed
|
||||
}
|
||||
|
||||
apply_patches_if_needed() {
|
||||
local PATCH_STATUS=0
|
||||
upgrade_compiler_if_needed() {
|
||||
UPDATE_STATUS=$(rustup check 2>&1)
|
||||
"$SCRIPT_FOLDER"/patch.sh || PATCH_STATUS=$?
|
||||
|
||||
if [ "$PATCH_STATUS" -eq 2 ]; then
|
||||
if echo "$UPDATE_STATUS" | grep -q "Update available" || [ $PATCH_STATUS -eq 2 ]; then
|
||||
echo "[+] clean all cache on the current system"
|
||||
cargo clean
|
||||
cargo install cargo-cache
|
||||
cargo clean
|
||||
cargo cache --remove-dir all
|
||||
|
||||
echo "[+] upgrading rustc compiler version to latest"
|
||||
rustup update
|
||||
toolchain_name=$(rustup show | grep default | head -n 1 | cut -d' ' -f1)
|
||||
|
||||
if ! rustup target list --installed | grep -q "wasm32-unknown-unknown"; then
|
||||
echo "[+] installing wasm32-unknown-unknown target"
|
||||
rustup target add wasm32-unknown-unknown
|
||||
fi
|
||||
|
||||
if ! rustup component list --installed | grep -q "rust-src"; then
|
||||
echo "[+] installing rust-src component"
|
||||
rustup component add rust-src
|
||||
fi
|
||||
|
||||
echo "[+] fetching all dependencies"
|
||||
cargo fetch
|
||||
|
||||
@ -226,7 +240,7 @@ if [[ $HARD_RESET = true ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apply_patches_if_needed
|
||||
upgrade_compiler_if_needed
|
||||
|
||||
echo "[+] trying to stop current ghost-node"
|
||||
sudo systemctl stop ghost-node
|
||||
@ -335,12 +349,12 @@ if [[ $SET_ENVIRONMENT = true ]]; then
|
||||
|
||||
if prompt "[?] setup the rust environment (e.g. WASM support)?"; then
|
||||
rustup default stable
|
||||
apply_patches_if_needed
|
||||
upgrade_compiler_if_needed
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -z $RELEASE ]]; then
|
||||
apply_patches_if_needed
|
||||
upgrade_compiler_if_needed
|
||||
if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then
|
||||
cd $PROJECT_FOLDER
|
||||
echo "[+] starting build in 3 seconds..."
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user