From 2387a2fe32bbdf860e09929e1a9268d54c097d17 Mon Sep 17 00:00:00 2001 From: Uncle Stinky Date: Sat, 5 Sep 2026 23:56:24 +0300 Subject: [PATCH] make exodus to change gatekeeped amount after bridge out Signed-off-by: Uncle Stinky --- pallets/exodus/Cargo.toml | 2 +- pallets/exodus/src/exodus.rs | 496 ----------------------------------- pallets/exodus/src/lib.rs | 58 +++- pallets/exodus/src/mock.rs | 2 +- pallets/exodus/src/tests.rs | 58 +++- 5 files changed, 103 insertions(+), 513 deletions(-) delete mode 100644 pallets/exodus/src/exodus.rs diff --git a/pallets/exodus/Cargo.toml b/pallets/exodus/Cargo.toml index dc952f6..fce2d5f 100644 --- a/pallets/exodus/Cargo.toml +++ b/pallets/exodus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-exodus" -version = "0.0.3" +version = "0.0.4" description = "Threshold signature generation with DKG included" license.workspace = true authors.workspace = true diff --git a/pallets/exodus/src/exodus.rs b/pallets/exodus/src/exodus.rs deleted file mode 100644 index 1ed7416..0000000 --- a/pallets/exodus/src/exodus.rs +++ /dev/null @@ -1,496 +0,0 @@ -use crate::{EncryptedMessage, FrostError}; -use ghost_networks::NetworkCurve; - -use chacha20poly1305::{ - aead::{self, Aead, AeadCore, KeyInit}, - Key as EncryptionKey, - Nonce as EncryptionNonce, - ChaCha20Poly1305 as EncryptionCipher, -}; - -use hkdf::Hkdf as KeyDerivation; -use sha2::{Digest, Sha256 as Hashing}; - -use rand_chacha::rand_core::{CryptoRng, RngCore}; -use sp_std::collections::btree_map::BTreeMap; - -macro_rules! with_ciphersuite { - ($curve:expr, |$alias:ident| $body:block) => { - match $curve { - ExodusCurve::Secp256k1 => { - use frost_secp256k1 as $alias; - $body - }, - NetworkCurve::Ed25519 => { - use frost_ed25519 as $alias; - $body - - } - } - } -} - -impl ExodusCurve { - pub fn dkg_verify_proof_of_knowledge( - &self, - index: u16, - round1_package_bytes: &[u8], - ) -> Result<(), FrostError> { - with_ciphersuite!(self, |f| { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let round1_package = f::keys::dkg::round1::Package::deserialize(round1_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - frost_core::keys::dkg::verify_proof_of_knowledge( - identifier, - &round1_package.commitment(), - &round1_package.proof_of_knowledge(), - ).map_err(|_| FrostError::InvalidProofOfKnowledge) - }) - } - - pub fn verify_signature_share( - &self, - index: u16, - verifying_share_bytes: &[u8], - signature_share_bytes: &[u8], - signing_package_bytes: &[u8], - verifying_key_bytes: &[u8], - ) -> Result<(), FrostError> { - with_ciphersuite!(self, |f| { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let verifying_share = f::keys::VerifyingShare::deserialize(verifying_share_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let signature_share = f::round2::SignatureShare::deserialize(signature_share_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let signing_package = f::SigningPackage::deserialize(signing_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let verifying_key = f::VerifyingKey::deserialize(verifying_key_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - frost_core::verify_signature_share( - identifier, - &verifying_share, - &signature_share, - &signing_package, - &verifying_key, - ).map_err(|err| match err { - f::Error::IdentityCommitment => FrostError::IdentityCommitment, - f::Error::UnknownIdentifier => FrostError::UnknownIdentifier, - f::Error::DuplicatedIdentifier => FrostError::DuplicatedIdentifier, - f::Error::InvalidSignatureShare { .. } => FrostError::InvalidSignatureShare, - _ => FrostError::Unknown, - }) - }) - } - - pub fn aggregate_signature( - &self, - signing_package_bytes: &[u8], - signature_shares_bytes: &BTreeMap>, - pubkeys_bytes: &[u8], - ) -> Result, FrostError> { - with_ciphersuite!(self, |f| { - let signing_package = f::SigningPackage::deserialize(signing_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let mut signature_shares = BTreeMap::new(); - for (&index, signature_share_bytes) in signature_shares_bytes.iter() { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let signature_share = f::round2::SignatureShare::deserialize(signature_share_bytes) - .map_err(|_| FrostError::DeserializationError)?; - signature_shares.insert(identifier, signature_share); - } - - let pubkeys = f::keys::PublicKeyPackage::deserialize(pubkeys_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let signature = f::aggregate(&signing_package, &signature_shares, &pubkeys) - .map_err(|err| match err { - f::Error::UnknownIdentifier => FrostError::UnknownIdentifier, - f::Error::SerializationError => FrostError::SerializationError, - f::Error::IdentityCommitment => FrostError::IdentityCommitment, - f::Error::IncorrectNumberOfIdentifiers => FrostError::IncorrectNumberOfIdentifiers, - f::Error::DuplicatedIdentifier => FrostError::DuplicatedIdentifier, - f::Error::InvalidSecretShare { .. } => FrostError::InvalidSecretShare, - f::Error::InvalidSignature { .. } => FrostError::InvalidSignature, - _ => FrostError::Unknown, - })?; - - let signature_bytes = signature.serialize() - .map_err(|_| FrostError::SerializationError)?; - - Ok(signature_bytes) - }) - } - - pub fn is_signature_valid( - &self, - pubkey_bytes: &[u8], - signature_bytes: &[u8], - message: &[u8], - ) -> bool { - with_ciphersuite!(self, |f| { - let get_verification_result = || -> Result<(), FrostError> { - let pubkeys = f::keys::PublicKeyPackage::deserialize(pubkey_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let signature = f::Signature::deserialize(signature_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - pubkeys.verifying_key() - .verify(message, &signature) - .map_err(|_| FrostError::InvalidSignature)?; - - Ok(()) - }; - - get_verification_result().is_ok() - }) - } - - pub fn dkg_part1( - &self, - index: u16, - max_signers: u16, - min_signers: u16, - mut rng: R, - ) -> Result<(Vec, Vec), FrostError> { - with_ciphersuite!(self, |f| { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let (round1_secret_package, round1_package) = f::keys::dkg::part1( - identifier, - max_signers, - min_signers, - &mut rng, - ).map_err(|err| { - match err { - f::Error::InvalidMinSigners => FrostError::InvalidMinSigners(min_signers, max_signers), - f::Error::InvalidMaxSigners => FrostError::InvalidMaxSigners(max_signers), - f::Error::DKGNotSupported => FrostError::DKGNotSupported(*self), - _ => FrostError::Unknown, - } - })?; - - let round1_secret_package_bytes = round1_secret_package.serialize() - .map_err(|_| FrostError::SerializationError)?; - - - let round1_package_bytes = round1_package.serialize() - .map_err(|_| FrostError::SerializationError)?; - - Ok((round1_secret_package_bytes, round1_package_bytes)) - }) - } - - fn convert_identifier_to_index( - identifier_bytes: Vec - ) -> Result { - const SIZE: usize = core::mem::size_of::(); - - let start = identifier_bytes.len().checked_sub(SIZE) - .ok_or(FrostError::InvalidParticipantId)?; - - let bytes_array = identifier_bytes.get(start..) - .and_then(|slice| slice.try_into().ok()) - .ok_or(FrostError::InvalidParticipantId)?; - - Ok(u16::from_be_bytes(bytes_array)) - } - - pub fn dkg_part2( - &self, - round1_secret_package_bytes: &[u8], - round1_packages_bytes: &BTreeMap>, - ) -> Result<(Vec, BTreeMap>), FrostError> { - with_ciphersuite!(self, |f| { - let round1_secret_package = f::keys::dkg::round1::SecretPackage::deserialize(round1_secret_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let mut round1_packages = BTreeMap::new(); - for (&index, round1_package_bytes) in round1_packages_bytes.iter() { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let round1_package = f::keys::dkg::round1::Package::deserialize(round1_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - round1_packages.insert(identifier, round1_package); - } - - let (round2_secret_package, round2_packages) = f::keys::dkg::part2( - round1_secret_package, - &round1_packages, - ).map_err(|err| match err { - f::Error::IncorrectNumberOfCommitments => FrostError::IncorrectNumberOfCommitments, - f::Error::IncorrectNumberOfPackages => FrostError::IncorrectNumberOfPackages, - f::Error::InvalidProofOfKnowledge { .. } => FrostError::InvalidProofOfKnowledge, - _ => FrostError::Unknown, - })?; - - let round2_secret_package_bytes = round2_secret_package.serialize() - .map_err(|_| FrostError::SerializationError)?; - - let mut round2_packages_bytes = BTreeMap::new(); - for (participant_identifier, round2_package) in round2_packages.iter() { - let index = Self::convert_identifier_to_index( - participant_identifier.serialize(), - )?; - - let round2_package_bytes = round2_package.serialize() - .map_err(|_| FrostError::SerializationError)?; - - round2_packages_bytes.insert(index as u16, round2_package_bytes); - } - - Ok((round2_secret_package_bytes, round2_packages_bytes)) - }) - } - - pub fn dkg_encrypt_round2_package( - &self, - cipher: &EncryptionCipher, - associated_data: &[u8], - round2_package_bytes: &[u8], - mut rng: R, - ) -> Result<(Vec, Vec), FrostError> { - let payload = aead::Payload { - msg: round2_package_bytes, - aad: associated_data, - }; - - let nonce = EncryptionCipher::generate_nonce(&mut rng); - let ciphertext = cipher.encrypt(&nonce, payload) - .map_err(|_| FrostError::EncryptionFailed)?; - - Ok((ciphertext, nonce.to_vec())) - } - - pub fn dkg_decrypt_round2_package( - &self, - cipher: &EncryptionCipher, - encrypted_message: &EncryptedMessage, - associated_data: &[u8], - ) -> Result, FrostError> { - let nonce = EncryptionNonce::from_iter(encrypted_message.nonce.iter().cloned()); - let payload = aead::Payload { - msg: &encrypted_message.ciphertext, - aad: associated_data, - }; - - cipher.decrypt(&nonce, payload) - .map_err(|_| FrostError::DecryptionFailed) - } - - pub fn prepare_additional_info( - &self, - sender_index: u16, - receiver_index: u16, - session_index: u16, - ) -> Vec { - let mut additional_info = match self { - ExodusCurve::Secp256k1 => b"EXODUS-SECP256K1-DKG-V1".to_vec(), - }; - - additional_info.extend_from_slice(&sender_index.to_be_bytes()); - additional_info.extend_from_slice(&receiver_index.to_be_bytes()); - additional_info.extend_from_slice(&session_index.to_be_bytes()); - - additional_info - } - - pub fn prepare_cipher_from_keys( - &self, - round1_receiver_package_bytes: &[u8], - round1_secret_package_bytes: &[u8], - additional_info: &[u8], - ) -> Result { - with_ciphersuite!(self, |f| { - let coefficients = - f::keys::dkg::round1::SecretPackage::deserialize(round1_secret_package_bytes) - .map_err(|_| FrostError::DeserializationError)? - .coefficients(); - - let sender_secret_key = coefficients - .first() - .ok_or(FrostError::IncorrectNumberOfCoefficients)?; - - let receiver_public_key = - f::keys::dkg::round1::Package::deserialize(round1_receiver_package_bytes) - .map_err(|_| FrostError::DeserializationError)? - .commitment() - .coefficients() - .first() - .ok_or(FrostError::MissingCommitment)? - .value(); - - let shared_secret_bytes = f::VerifyingKey::new(receiver_public_key * sender_secret_key) - .serialize() - .map_err(|_| FrostError::SerializationError)?; - - let salt = Hashing::digest(&additional_info); - let hk = KeyDerivation::::new(Some(&salt), &shared_secret_bytes); - - let mut encryption_key = EncryptionKey::default(); - hk.expand(additional_info, &mut encryption_key) - .map_err(|_| FrostError::HKDFFailed)?; - - let cipher = EncryptionCipher::new_from_slice(&encryption_key) - .expect("could not happen; length is already correct qed"); - - Ok(cipher) - }) - } - - pub fn dkg_verify_private_package( - &self, - index: u16, - round1_package_bytes: &[u8], - round2_package_bytes: &[u8], - ) -> Result<(), FrostError> { - with_ciphersuite!(self, |f| { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let commitment = f::keys::dkg::round1::Package::deserialize(round1_package_bytes) - .map(|round1_package| round1_package.commitment().clone()) - .map_err(|_| FrostError::DeserializationError)?; - - let secret_share = f::keys::dkg::round2::Package::deserialize(round2_package_bytes) - .map(|round2_package| { - let signing_share = round2_package.signing_share().clone(); - f::keys::SecretShare::new(identifier, signing_share, commitment) - }) - .map_err(|_| FrostError::DeserializationError)?; - - let _ = secret_share.verify().map_err(|_| FrostError::InvalidSecretShare)?; - - Ok(()) - }) - } - - pub fn dkg_part3( - &self, - round2_secret_package_bytes: &[u8], - round1_packages_bytes: &BTreeMap>, - round2_packages_bytes: &BTreeMap>, - ) -> Result<(Vec, Vec), FrostError> { - with_ciphersuite!(self, |f| { - let round2_secret_package = f::keys::dkg::round2::SecretPackage::deserialize(round2_secret_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let mut round1_packages = BTreeMap::new(); - for (&index, round1_package_bytes) in round1_packages_bytes.iter() { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let round1_package = f::keys::dkg::round1::Package::deserialize(round1_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - round1_packages.insert(identifier, round1_package); - } - - let mut round2_packages = BTreeMap::new(); - for (&index, round2_package_bytes) in round2_packages_bytes.iter() { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let round2_package = f::keys::dkg::round2::Package::deserialize(round2_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - round2_packages.insert(identifier, round2_package); - } - - let (key_package, pubkey_package) = f::keys::dkg::part3( - &round2_secret_package, - &round1_packages, - &round2_packages, - ).map_err(|err| match err { - f::Error::IncorrectNumberOfPackages => FrostError::IncorrectNumberOfPackages, - f::Error::IncorrectPackage => FrostError::IncorrectPackage, - f::Error::PackageNotFound => FrostError::PackageNotFound, - f::Error::InvalidSecretShare { .. } => FrostError::InvalidSecretShare, - f::Error::IncorrectNumberOfCommitments => FrostError::IncorrectNumberOfCommitments, - _ => FrostError::Unknown, - })?; - - let key_package_bytes = key_package.serialize() - .map_err(|_| FrostError::SerializationError)?; - - let pubkey_package_bytes = pubkey_package.serialize() - .map_err(|_| FrostError::SerializationError)?; - - Ok((key_package_bytes, pubkey_package_bytes)) - }) - } - - pub fn generate_nonce( - &self, - secret_key_package_bytes: &[u8], - mut rng: R - ) -> Result<(Vec, Vec), FrostError> { - with_ciphersuite!(self, |f| { - let signing_share = f::keys::KeyPackage::deserialize(secret_key_package_bytes) - .map(|key_package| *key_package.signing_share()) - .map_err(|_| FrostError::DeserializationError)?; - - let (signing_nonces, signing_commitments) = - f::round1::commit(&signing_share, &mut rng); - - let signing_nonces_bytes = signing_nonces.serialize() - .map_err(|_| FrostError::SerializationError)?; - - let signing_commitments_bytes = signing_commitments.serialize() - .map_err(|_| FrostError::SerializationError)?; - - Ok((signing_nonces_bytes, signing_commitments_bytes)) - }) - } - - pub fn generate_signing_package( - &self, - commitments_map_bytes: &BTreeMap>, - message: &[u8], - ) -> Result, FrostError> { - with_ciphersuite!(self, |f| { - let mut commitments_map = BTreeMap::new(); - for (&index, commitment_bytes) in commitments_map_bytes.iter() { - let identifier = index.try_into().map_err(|_| FrostError::InvalidParticipantId)?; - let commitment = f::round1::SigningCommitments::deserialize(commitment_bytes) - .map_err(|_| FrostError::DeserializationError)?; - commitments_map.insert(identifier, commitment); - } - - f::SigningPackage::new(commitments_map, message) - .serialize() - .map_err(|_| FrostError::SerializationError) - }) - } - - pub fn sign_message( - &self, - signing_package_bytes: &[u8], - signer_nonces_bytes: &[u8], - secret_key_share_bytes: &[u8] - ) -> Result, FrostError> { - with_ciphersuite!(self, |f| { - let signing_package = f::SigningPackage::deserialize(signing_package_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let signer_nonces = f::round1::SigningNonces::deserialize(signer_nonces_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let secret_key_share = f::keys::KeyPackage::deserialize(secret_key_share_bytes) - .map_err(|_| FrostError::DeserializationError)?; - - let signature_share_bytes = f::round2::sign(&signing_package, &signer_nonces, &secret_key_share) - .map(|signature_share| signature_share.serialize()) - .map_err(|err| match err { - f::Error::IncorrectNumberOfCommitments => FrostError::IncorrectNumberOfCommitments, - f::Error::MissingCommitment => FrostError::MissingCommitment, - f::Error::IncorrectCommitment => FrostError::IncorrectCommitment, - f::Error::SerializationError => FrostError::SerializationError, - f::Error::UnknownIdentifier => FrostError::UnknownIdentifier, - f::Error::IdentityCommitment => FrostError::IdentityCommitment, - f::Error::DuplicatedIdentifier => FrostError::DuplicatedIdentifier, - f::Error::IncorrectNumberOfIdentifiers => FrostError::IncorrectNumberOfIdentifiers, - _ => FrostError::Unknown, - })?; - - Ok(signature_share_bytes) - }) - } -} diff --git a/pallets/exodus/src/lib.rs b/pallets/exodus/src/lib.rs index 1c6029d..6ac9705 100644 --- a/pallets/exodus/src/lib.rs +++ b/pallets/exodus/src/lib.rs @@ -46,7 +46,7 @@ use ghost_traits::{ }, exodus::{ MerkleTreeBuilder, DistributedKeyGeneration, EllipticCurveDiffieHellman, - FlexibleRoundOptimizedSchnorrThresholdSignature, + FlexibleRoundOptimizedSchnorrThresholdSignature, EvmGovernanceRegistrar, }, networks::{ NetworkDataBasicHandler, NetworkDataInspectHandler, @@ -506,6 +506,7 @@ pub mod pallet { pub enum Error { DkgWrongRound, TooManyEntries, + BridgeOverflow, TooManyPackages, WrongNetworkType, InvalidMerkleProof, @@ -2135,12 +2136,13 @@ pub mod pallet { } impl Pallet { - fn do_register_evm_bridge_out_exodus( + fn do_register_evm_exodus( network_id: NetworkIdOf, - amount: BalanceOf, - bounty: Perbill, - receiver: EvmAddress, - ) -> DispatchResult { + request_builder: F, + ) -> DispatchResult + where + F: FnOnce(ExodusSession) -> ExodusRequest, BalanceOf>, + { let network = T::NetworkDataHandler::get(&network_id) .ok_or(Error::::NetworkDoesNotExist)?; @@ -2152,13 +2154,7 @@ impl Pallet { ensure!(network.r#type.is_evm(), Error::::WrongNetworkType); let exodus_session = CurrentExodus::::get(); - let request = ExodusRequest::evm_bridge_out( - exodus_session, - network_id, - amount, - bounty, - receiver - ); + let request = request_builder(exodus_session); ExodusRequests::::insert(&network.curve, &exodus_session, request); CurrentExodus::::put(exodus_session.saturating_add(1)); @@ -2166,6 +2162,42 @@ impl Pallet { Ok(()) } + fn do_register_evm_bridge_out_exodus( + network_id: NetworkIdOf, + amount: BalanceOf, + bounty: Perbill, + receiver: EvmAddress, + ) -> DispatchResult { + let out_amount = + T::NetworkDataHandler::register_outgoing(&network_id, amount) + .map_err(|_| Error::::BridgeOverflow)?; + + Self::do_register_evm_exodus(network_id, |exodus_session| { + ExodusRequest::evm_bridge_out( + exodus_session, + network_id, + out_amount, + bounty, + receiver, + ) + }) + } + + fn do_register_evm_governance( + network_id: NetworkIdOf, + target_address: EvmAddress, + governance_action: GovernanceAction, + ) -> DispatchResult { + Self::do_register_evm_exodus(network_id, |exodus_session| { + ExodusRequest::evm_governance( + exodus_session, + network_id, + target_address, + governance_action, + ) + }) + } + fn prepare_round_storage( network_curve: NetworkCurve, maybe_cursor: Option>, diff --git a/pallets/exodus/src/mock.rs b/pallets/exodus/src/mock.rs index b664de9..37f161a 100644 --- a/pallets/exodus/src/mock.rs +++ b/pallets/exodus/src/mock.rs @@ -181,7 +181,7 @@ pub fn new_test_ext() -> ( let networks = vec![ NetworkInitiationBuilder::::default() - .with_network_id(31_337) + .with_network_id(420) .with_gatekeeper_amount(0) .with_network_data(network_data) .build(), diff --git a/pallets/exodus/src/tests.rs b/pallets/exodus/src/tests.rs index e3d08b7..9a4f733 100644 --- a/pallets/exodus/src/tests.rs +++ b/pallets/exodus/src/tests.rs @@ -8,6 +8,7 @@ use sp_std::{ }; use frame_support::{assert_ok, assert_err, traits::Hooks}; use sp_runtime::testing::UintAuthorityId; +use ghost_helpers::networks::NetworkDataBuilder; use rand::Rng; use rand_chacha::rand_core::SeedableRng; @@ -1036,16 +1037,55 @@ fn test_all_validators_can_execute_initial_dkg() { fn test_all_validators_can_execute_dkg() { let curve = NetworkCurve::Secp256k1; let authorities_1 = FixedAuthorities::get(); + let dummy_address = EvmAddress::repeat_byte(1); + + let network_id = 31_337; let (mut ext, tx_pool_state) = run_initial_dkg_session(&authorities_1, curve); ext.execute_with(|| { + let network_data = NetworkDataBuilder::default() + .with_network_curve(curve) + .with_network_type(NetworkType::Evm) + .with_outgoing_share(500_000_000) + .build(); + + let _ = ::NetworkDataHandler::register(network_id, network_data).unwrap(); + let _ = ::NetworkDataHandler::register_incoming(&network_id, 1337).unwrap(); + Exodus::do_register_evm_bridge_out_exodus( - 31_337, + network_id, 69, Default::default(), EvmAddress::from_low_u64_be(1), ).unwrap(); + + let set_distributor = GovernanceAction::SetDistributor { distributor: dummy_address }; + let set_warmup = GovernanceAction::SetWarmupPeriod { warmup_period: 69 }; + let update_gatekeeper = GovernanceAction::UpdateGatekeeperAddress { new_gatekeeper: dummy_address }; + let set_bounty = GovernanceAction::SetBounty { bounty: 69 }; + let set_adjustment = GovernanceAction::SetAdjustment { rate: 69, target: 420, add: true }; + + let add_pool = GovernanceAction::AddPool { address: dummy_address }; + let remove_pool = GovernanceAction::RemovePool { index: 1337 }; + let close = GovernanceAction::Close { id: 420 }; + let create = GovernanceAction::Create { + market: [69, 420, 1337], + terms: [420, 1337], + token: dummy_address, + intervals: [34, 35], + booleans: [true, true], + }; + + Exodus::do_register_evm_governance(network_id, dummy_address, set_distributor).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, set_warmup).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, set_bounty).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, set_adjustment).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, update_gatekeeper).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, add_pool).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, remove_pool).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, close).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, create).unwrap(); }); let mut authorities_2 = authorities_1.clone(); @@ -1058,11 +1098,25 @@ fn test_all_validators_can_execute_dkg() { ext.execute_with(|| { Exodus::do_register_evm_bridge_out_exodus( - 31_337, + network_id, 420, Perbill::from_percent(50), EvmAddress::from_low_u64_be(2), ).unwrap(); + + let enable = GovernanceAction::Enable { status: GovernanceStatus::ReserveToken, address: dummy_address, calculator: dummy_address }; + let disable = GovernanceAction::Disable { status: GovernanceStatus::LiquidityToken, address: dummy_address }; + let forfeit = GovernanceAction::ForfeitReserves { router: dummy_address, liquidity: 420, destroyer_mode: true }; + let redeem = GovernanceAction::RedeemReserves { router: dummy_address, amount: 420 }; + let withdraw = GovernanceAction::Withdraw { token: dummy_address, amount: 420 }; + let audit = GovernanceAction::AuditReserves; + + Exodus::do_register_evm_governance(network_id, dummy_address, enable).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, disable).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, forfeit).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, redeem).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, withdraw).unwrap(); + Exodus::do_register_evm_governance(network_id, dummy_address, audit).unwrap(); }); let mut authorities_3 = FixedAuthorities::get();