use super::*; use frame_support::{assert_err, assert_ok}; use mock::{ ExtBuilder, GhostNetworks, RandomAccount, RegistererAccount, RemoverAccount, RewardCurve, RuntimeEvent, RuntimeOrigin, System, Test, UpdaterAccount, }; use pallet_staking::EraPayout; use sp_runtime::DispatchError; fn prepare_network_data() -> (u32, NetworkData) { ( 1u32, NetworkData { chain_name: "Ethereum".into(), default_endpoints: vec![ "https:://some-endpoint.my-server.com/v1/my-super-secret-key".into(), "https:://another-endpoint.my-server.com/v1/my-super-secret-key".into(), ], finality_delay: 69, rate_limit_delay: 69, block_distance: 69, network_type: NetworkType::Evm, gatekeeper: b"0x1234567891234567891234567891234567891234".to_vec(), topic_name: b"0x12345678912345678912345678912345678912345678912345678912345678" .to_vec(), incoming_fee: 0, outgoing_fee: 0, }, ) } fn register_and_check_network(chain_id: u32, network: NetworkData) { assert_ok!(GhostNetworks::register_network( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, network.clone() )); assert_eq!(Networks::::get(chain_id), Some(network.clone())); } #[test] fn could_add_network_from_authority() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); assert_eq!(Networks::::get(chain_id), None); assert_ok!(GhostNetworks::register_network( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, network.clone(), )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkRegistered { chain_id, network: network.clone(), }, )); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_add_network_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::register_network( RuntimeOrigin::signed(RandomAccount::get()), chain_id, network.clone(), ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::register_network( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, network.clone(), ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::register_network( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, network, ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_update_network_name_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_name = b"Polygon".to_vec(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_name( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_name.clone() )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkNameUpdated { chain_id, chain_name: new_name.clone(), }, )); let mut final_network = network.clone(); final_network.chain_name = new_name; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_add_network_endpoint_from_authority_account() { ExtBuilder::build().execute_with(|| { let raw_endpoint: Vec = "https:://new-endpoint.my-server.com/v1/my-super-secret-key".into(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, None, Some(raw_endpoint.clone()), )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkEndpointAdded { chain_id, endpoint: raw_endpoint.clone(), }, )); let current_network = Networks::::get(chain_id).unwrap(); assert_eq!( current_network.default_endpoints.len(), network.default_endpoints.len() + 1 ); assert_eq!( current_network .default_endpoints .last() .cloned() .unwrap_or_default(), raw_endpoint ); assert_ne!(&network, ¤t_network); }); } #[test] fn could_remove_network_endpoint_from_authority_account() { ExtBuilder::build().execute_with(|| { let index_to_remove = 0u32; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, Some(index_to_remove), None, )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkEndpointRemoved { chain_id, index: index_to_remove, }, )); let current_network = Networks::::get(chain_id).unwrap(); assert_eq!( current_network.default_endpoints.len(), network.default_endpoints.len() - 1 ); assert_ne!( current_network .default_endpoints .get(index_to_remove as usize), network.default_endpoints.get(index_to_remove as usize) ); assert_ne!(&network, ¤t_network); }); } #[test] fn could_update_network_endpoint_from_authority_account() { ExtBuilder::build().execute_with(|| { let index_to_update = 0u32; let raw_endpoint: Vec = "https:://new-endpoint.my-server.com/v1/my-super-secret-key".into(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, Some(index_to_update), Some(raw_endpoint.clone()), )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkEndpointUpdated { chain_id, index: index_to_update, endpoint: raw_endpoint.clone(), }, )); let previous_endpoints_len = network.default_endpoints.len(); let mut final_network = network.clone(); if let Some(endpoint_by_index) = final_network .default_endpoints .get_mut(index_to_update as usize) { *endpoint_by_index = raw_endpoint.clone(); } let current_network = Networks::::get(chain_id).unwrap(); assert_eq!( current_network.default_endpoints.len(), previous_endpoints_len ); assert_eq!( current_network .default_endpoints .get(index_to_update as usize) .cloned() .unwrap_or_default(), raw_endpoint ); assert_ne!(&network, &final_network); }); } #[test] fn could_update_network_finality_delay_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_finality_delay = 1337; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_finality_delay( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_finality_delay )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkFinalityDelayUpdated { chain_id, finality_delay: new_finality_delay, }, )); let mut final_network = network.clone(); final_network.finality_delay = new_finality_delay; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_network_rate_limit_delay_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_rate_limit_delay = 1337; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_rate_limit_delay( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_rate_limit_delay )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkRateLimitDelayUpdated { chain_id, rate_limit_delay: new_rate_limit_delay, }, )); let mut final_network = network.clone(); final_network.rate_limit_delay = new_rate_limit_delay; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_network_block_distance_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_block_distance = 1337; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_block_distance( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_block_distance )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkBlockDistanceUpdated { chain_id, block_distance: new_block_distance, }, )); let mut final_network = network.clone(); final_network.block_distance = new_block_distance; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_network_type_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_type = NetworkType::Utxo; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_type( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_type.clone() )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkTypeUpdated { chain_id, network_type: new_type.clone(), }, )); let mut final_network = network.clone(); final_network.network_type = new_type; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_network_gatekeeper_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_gatekeeper = b"0x9876543219876543219876543219876543219876".to_vec(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_gatekeeper( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_gatekeeper.clone() )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkGatekeeperUpdated { chain_id, gatekeeper: new_gatekeeper.clone(), }, )); let mut final_network = network.clone(); final_network.gatekeeper = new_gatekeeper; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_network_topic_name_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_topic_name = b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_network_topic_name( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_topic_name.clone() )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkTopicNameUpdated { chain_id, topic_name: new_topic_name.clone(), }, )); let mut final_network = network.clone(); final_network.topic_name = new_topic_name; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_incoming_network_fee_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_incoming_fee = 69; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_incoming_network_fee( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_incoming_fee )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkIncomingFeeUpdated { chain_id, incoming_fee: new_incoming_fee, }, )); let mut final_network = network.clone(); final_network.incoming_fee = new_incoming_fee; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_update_outgoing_network_fee_from_authority_account() { ExtBuilder::build().execute_with(|| { let new_outgoing_fee = 69; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::update_outgoing_network_fee( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, new_outgoing_fee )); System::assert_last_event(RuntimeEvent::GhostNetworks( crate::Event::NetworkOutgoingFeeUpdated { chain_id, outgoing_fee: new_outgoing_fee, }, )); let mut final_network = network.clone(); final_network.outgoing_fee = new_outgoing_fee; assert_eq!(Networks::::get(chain_id), Some(final_network.clone())); assert_ne!(network, final_network); }); } #[test] fn could_not_update_network_name_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_name( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, "Binance".into() ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_name( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, "Binance".into() ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_name( RuntimeOrigin::signed(RandomAccount::get()), chain_id, "Binance".into() ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_endpoint_from_random_account() { ExtBuilder::build().execute_with(|| { let index_to_update = 0u32; let raw_endpoint: Vec = "https:://new-endpoint.my-server.com/v1/my-super-secret-key".into(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, Some(index_to_update), Some(raw_endpoint.clone()), ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, Some(index_to_update), Some(raw_endpoint.clone()), ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RandomAccount::get()), chain_id, Some(index_to_update), Some(raw_endpoint.clone()), ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_add_network_endpoint_from_random_account() { ExtBuilder::build().execute_with(|| { let raw_endpoint: Vec = "https:://new-endpoint.my-server.com/v1/my-super-secret-key".into(); let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, None, Some(raw_endpoint.clone()), ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, None, Some(raw_endpoint.clone()), ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RandomAccount::get()), chain_id, None, Some(raw_endpoint.clone()), ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_remove_network_endpoint_from_random_account() { ExtBuilder::build().execute_with(|| { let index_to_remove = 0u32; let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, Some(index_to_remove), None, ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, Some(index_to_remove), None, ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(RandomAccount::get()), chain_id, Some(index_to_remove), None, ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_finality_delay_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); let finality_delay = 1337; register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_finality_delay( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, finality_delay ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_finality_delay( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, finality_delay ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_finality_delay( RuntimeOrigin::signed(RandomAccount::get()), chain_id, finality_delay ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_rate_limit_delay_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); let rate_limit_delay = 1337; register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_rate_limit_delay( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, rate_limit_delay ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_rate_limit_delay( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, rate_limit_delay ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_rate_limit_delay( RuntimeOrigin::signed(RandomAccount::get()), chain_id, rate_limit_delay ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_release_delay_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); let block_distance = 1337; register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_block_distance( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, block_distance ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_block_distance( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, block_distance ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_block_distance( RuntimeOrigin::signed(RandomAccount::get()), chain_id, block_distance ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_type_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_type( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, NetworkType::Utxo ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_type( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, NetworkType::Utxo ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_type( RuntimeOrigin::signed(RandomAccount::get()), chain_id, NetworkType::Utxo ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_gatekeeper_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_gatekeeper( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876".to_vec() ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_gatekeeper( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876".to_vec() ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_gatekeeper( RuntimeOrigin::signed(RandomAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876".to_vec() ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_topic_name_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_network_topic_name( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec() ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_topic_name( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec() ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_network_topic_name( RuntimeOrigin::signed(RandomAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec() ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_incoming_fee_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_incoming_network_fee( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, 69 ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_incoming_network_fee( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, 69 ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_incoming_network_fee( RuntimeOrigin::signed(RandomAccount::get()), chain_id, 69 ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_network_outgoing_fee_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::update_outgoing_network_fee( RuntimeOrigin::signed(RegistererAccount::get()), chain_id, 69 ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_outgoing_network_fee( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, 69 ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::update_outgoing_network_fee( RuntimeOrigin::signed(RandomAccount::get()), chain_id, 69 ), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_update_name_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_name( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, "Binance".into() ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_endpoint_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, Some(0u32), Some("https:://new-endpoint.my-server.com/v1/my-super-secret-key".into()), ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_add_endpoint_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, None, Some("https:://new-endpoint.my-server.com/v1/my-super-secret-key".into()), ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_remove_endpoint_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_endpoint( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, Some(0u32), None, ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_finality_delay_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_finality_delay( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, 1337 ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_rate_limit_delay_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_rate_limit_delay( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, 1337 ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_release_delay_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_block_distance( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, 1337 ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_type_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_type( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, NetworkType::Utxo ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_gatekeeper_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_gatekeeper( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876".to_vec() ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_topic_name_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_network_topic_name( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec() ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_incoming_fee_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_incoming_network_fee( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, 1337 ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_update_outgoing_fee_for_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::update_outgoing_network_fee( RuntimeOrigin::signed(UpdaterAccount::get()), chain_id, 1337 ), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_remove_network_from_authority_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_ok!(GhostNetworks::remove_network( RuntimeOrigin::signed(RemoverAccount::get()), chain_id, )); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn could_not_remove_network_from_random_account() { ExtBuilder::build().execute_with(|| { let (chain_id, network) = prepare_network_data(); register_and_check_network(chain_id, network.clone()); assert_err!( GhostNetworks::remove_network( RuntimeOrigin::signed(RegistererAccount::get()), chain_id ), DispatchError::BadOrigin ); assert_err!( GhostNetworks::remove_network(RuntimeOrigin::signed(UpdaterAccount::get()), chain_id), DispatchError::BadOrigin ); assert_err!( GhostNetworks::remove_network(RuntimeOrigin::signed(RandomAccount::get()), chain_id), DispatchError::BadOrigin ); assert_eq!(Networks::::get(chain_id), Some(network)); }); } #[test] fn could_not_remove_non_existent_network() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; assert_eq!(Networks::::get(chain_id), None); assert_err!( GhostNetworks::remove_network(RuntimeOrigin::signed(RemoverAccount::get()), chain_id), crate::Error::::NetworkDoesNotExist ); assert_eq!(Networks::::get(chain_id), None); }); } #[test] fn bridge_storage_is_empty_by_default() { ExtBuilder::build().execute_with(|| { assert_eq!(AccumulatedCommission::::get(), 0); assert_eq!(BridgedImbalance::::get(), BridgeAdjustment::default()); }); } #[test] fn gatekeeper_amount_changes_correctly() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; let amount_in: u128 = 420; let amount_out: u128 = 69; let result = amount_in - 3 * amount_out; assert_eq!(GatekeeperAmount::::get(&chain_id), 0); assert_ok!(GhostNetworks::increase_gatekeeper_amount( &chain_id, &amount_in )); assert_ok!(GhostNetworks::decrease_gatekeeper_amount( &chain_id, &amount_out )); assert_ok!(GhostNetworks::decrease_gatekeeper_amount( &chain_id, &amount_out )); assert_ok!(GhostNetworks::decrease_gatekeeper_amount( &chain_id, &amount_out )); assert_eq!(GatekeeperAmount::::get(&chain_id), result); }); } #[test] fn bridged_imbalance_accumulated_correctly() { ExtBuilder::build().execute_with(|| { let amount_in: u128 = 420; let amount_out: u128 = 69; let imbalance_before = BridgedImbalance::::get(); assert_eq!(imbalance_before.bridged_in, 0); assert_eq!(imbalance_before.bridged_out, 0); assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount_in)); assert_ok!(GhostNetworks::accumulate_outgoing_imbalance(&amount_out)); let imbalance_after = BridgedImbalance::::get(); assert_eq!(imbalance_after.bridged_in, amount_in); assert_eq!(imbalance_after.bridged_out, amount_out); }); } #[test] fn commission_accumulation_is_correct() { ExtBuilder::build().execute_with(|| { let commission_first: u128 = 420; let commission_second: u128 = 69; let result = commission_first + commission_second; assert_eq!(AccumulatedCommission::::get(), 0); assert_ok!(GhostNetworks::accumulate_commission(&commission_first)); assert_ok!(GhostNetworks::accumulate_commission(&commission_second)); assert_eq!(AccumulatedCommission::::get(), result); }); } #[test] fn commission_overflow_and_underflow_emits_error() { ExtBuilder::build().execute_with(|| { let commission: u128 = u128::MAX - 69; assert_eq!(AccumulatedCommission::::get(), 0); assert_ok!(GhostNetworks::accumulate_commission(&commission)); assert_err!(GhostNetworks::accumulate_commission(&commission), ()); assert_eq!(AccumulatedCommission::::get(), commission); }); } #[test] fn gatekeeper_amount_overflow_and_underflow_emits_error() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; let commission: u128 = u128::MAX - 69; assert_eq!(GatekeeperAmount::::get(&chain_id), 0); assert_ok!( GhostNetworks::increase_gatekeeper_amount(&chain_id, &commission,), commission ); assert_err!( GhostNetworks::increase_gatekeeper_amount(&chain_id, &commission,), () ); assert_eq!(GatekeeperAmount::::get(&chain_id), commission); assert_ok!( GhostNetworks::decrease_gatekeeper_amount(&chain_id, &commission,), 0 ); assert_err!( GhostNetworks::decrease_gatekeeper_amount(&chain_id, &commission,), () ); assert_eq!(GatekeeperAmount::::get(&chain_id), 0); }); } #[test] fn bridged_imbalance_overflow_emits_error() { ExtBuilder::build().execute_with(|| { let chain_id: u32 = 1; let amount: u128 = u128::MAX - 69; assert_eq!(GatekeeperAmount::::get(&chain_id), 0); assert_ok!( GhostNetworks::accumulate_outgoing_imbalance(&amount), amount ); assert_ok!( GhostNetworks::accumulate_incoming_imbalance(&amount), amount ); assert_err!(GhostNetworks::accumulate_outgoing_imbalance(&amount), ()); assert_err!(GhostNetworks::accumulate_incoming_imbalance(&amount), ()); assert_err!(GhostNetworks::accumulate_outgoing_imbalance(&u128::MAX), ()); assert_err!(GhostNetworks::accumulate_incoming_imbalance(&u128::MAX), ()); let bridged_imbalance = BridgedImbalance::::get(); assert_eq!(bridged_imbalance.bridged_out, amount); assert_eq!(bridged_imbalance.bridged_in, amount); }); } #[test] fn bridged_amount_overflow_and_underflow_emits_error() { ExtBuilder::build().execute_with(|| { let chain_id_first: u32 = 1; let chain_id_second: u32 = 2; let commission: u128 = u128::MAX - 69; assert_ok!( GhostNetworks::increase_gatekeeper_amount(&chain_id_first, &commission,), commission ); assert_ok!( GhostNetworks::increase_gatekeeper_amount(&chain_id_second, &commission,), commission ); assert_err!( GhostNetworks::increase_gatekeeper_amount(&chain_id_first, &u128::MAX,), () ); assert_err!( GhostNetworks::increase_gatekeeper_amount(&chain_id_first, &commission,), () ); assert_err!( GhostNetworks::decrease_gatekeeper_amount(&chain_id_second, &u128::MAX,), () ); assert_ok!( GhostNetworks::decrease_gatekeeper_amount(&chain_id_second, &commission,), 0 ); assert_eq!(GatekeeperAmount::::get(&chain_id_first), commission); assert_eq!(GatekeeperAmount::::get(&chain_id_second), 0); }); } #[test] fn accumulated_commission_could_be_nullified() { ExtBuilder::build().execute_with(|| { let commission_first: u128 = 420; let commission_second: u128 = 69; assert_eq!(AccumulatedCommission::::get(), 0); assert_ok!( GhostNetworks::accumulate_commission(&commission_first), commission_first ); assert_ok!( GhostNetworks::accumulate_commission(&commission_second,), commission_first + commission_second ); assert_eq!( AccumulatedCommission::::get(), commission_first + commission_second ); GhostNetworks::nullify_commission(); assert_eq!(AccumulatedCommission::::get(), 0); }); } #[test] fn bridged_inlation_reward_works() { ExtBuilder::build().execute_with(|| { let amount_full: u128 = 1337 * 1_000_000_000; let commission: u128 = amount_full / 100; // 1% commission let amount: u128 = amount_full - commission; let total_staked_ideal: u128 = 69; let total_staked_not_ideal: u128 = 68; let total_issuance: u128 = 100; assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000, total_issuance * 1_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000_000_000_000, total_issuance * 1_000_000_000_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000_000_000_000_000_000_000_000, total_issuance * 1_000_000_000_000_000_000_000_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000, total_issuance * 1_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000_000_000_000, total_issuance * 1_000_000_000_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000_000_000_000_000_000_000_000, total_issuance * 1_000_000_000_000_000_000_000_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout(1, total_issuance * 1_000, 0), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000_000_000_000, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000_000_000_000_000_000_000_000, 0 ), (0, 0) ); assert_ok!(GhostNetworks::accumulate_commission(&commission)); assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount)); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000, total_issuance * 1_000 + amount, 0 ), (commission, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000_000_000_000, total_issuance * 1_000_000_000_000 + amount, 0 ), (commission, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000_000_000_000_000_000_000_000, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0 ), (commission, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000, total_issuance * 1_000 + amount, 0 ), (13177472000, 192528000) ); assert_eq!(13177472000 + 192528000, commission); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000_000_000_000, total_issuance * 1_000_000_000_000 + amount, 0 ), (13177568884, 192431116) ); assert_eq!(13177568884 + 192431116, commission); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000_000_000_000_000_000_000_000, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0 ), (13177568884, 192431116) ); assert_eq!(13177568884 + 192431116, commission); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000 + amount, 0 ), (92386700, 13277613300) ); assert_eq!(92386700 + 13277613300, commission); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000_000_000_000 + amount, 0 ), (92253000, 13277747000) ); assert_eq!(92253000 + 13277747000, commission); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0 ), (92253000, 13277747000) ); assert_eq!(92253000 + 13277747000, commission); GhostNetworks::nullify_commission(); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000, total_issuance * 1_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000_000_000_000, total_issuance * 1_000_000_000_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000_000_000_000_000_000_000_000, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000, total_issuance * 1_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000_000_000_000, total_issuance * 1_000_000_000_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_not_ideal * 1_000_000_000_000_000_000_000_000, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000_000_000_000 + amount, 0 ), (0, 0) ); assert_eq!( BridgedInflationCurve::::era_payout( 1, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0 ), (0, 0) ); }); } #[test] fn bridged_inflation_era_payout_triggers_need_of_nullification() { ExtBuilder::build().execute_with(|| { let amount_full: u128 = 1337 * 1_000_000_000; let commission: u128 = amount_full / 100; // 1% commission let amount: u128 = amount_full - commission; let total_staked_ideal: u128 = 69; let total_issuance: u128 = 100; assert_ok!(GhostNetworks::accumulate_commission(&commission)); assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount)); assert_eq!(NullifyNeeded::::get(), false); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal * 1_000, total_issuance * 1_000 + amount, 0 ), (commission, 0) ); assert_eq!(NullifyNeeded::::get(), true); GhostNetworks::on_finalize(69); assert_eq!(NullifyNeeded::::get(), false); }); } #[test] fn trigger_nullification_works_as_expected() { ExtBuilder::build().execute_with(|| { let commission: u128 = 69; let imbalance = BridgeAdjustment { bridged_in: 1337u128, bridged_out: 420u128, }; assert_eq!(AccumulatedCommission::::get(), 0); assert_eq!(BridgedImbalance::::get(), BridgeAdjustment::default()); AccumulatedCommission::::set(commission); BridgedImbalance::::set(imbalance.clone()); assert_eq!(AccumulatedCommission::::get(), commission); assert_eq!(BridgedImbalance::::get(), imbalance); assert_eq!(NullifyNeeded::::get(), false); GhostNetworks::trigger_nullification(); assert_eq!(NullifyNeeded::::get(), true); GhostNetworks::trigger_nullification(); assert_eq!(NullifyNeeded::::get(), false); assert_eq!(AccumulatedCommission::::get(), 0); assert_eq!(BridgedImbalance::::get(), BridgeAdjustment::default()); }); } #[test] fn check_substrate_guarantees_not_to_overflow_u128() { ExtBuilder::build().execute_with(|| { let reward_curve = RewardCurve::get(); let mut n: u128 = 69; let mut d: u128 = 100; loop { n = match n.checked_mul(1_000) { Some(value) => value, None => break, }; d = match d.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!( reward_curve.calculate_for_fraction_times_denominator(n, d), d ); } }); } #[test] fn check_substrate_guarantees_not_to_overflow_u64() { ExtBuilder::build().execute_with(|| { let reward_curve = RewardCurve::get(); let mut n: u64 = 69; let mut d: u64 = 100; loop { n = match n.checked_mul(1_000) { Some(value) => value, None => break, }; d = match d.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!( reward_curve.calculate_for_fraction_times_denominator(n, d), d ); } }); } #[test] fn check_substrate_guarantees_not_to_overflow_u32() { ExtBuilder::build().execute_with(|| { let reward_curve = RewardCurve::get(); let mut n: u32 = 69; let mut d: u32 = 100; loop { n = match n.checked_mul(1_000) { Some(value) => value, None => break, }; d = match d.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!( reward_curve.calculate_for_fraction_times_denominator(n, d), d ); } }); } #[test] fn check_muldiv_guarantees_not_to_overflow_for_u128() { ExtBuilder::build().execute_with(|| { let mut a: u128 = 2; let mut b: u128 = 3; let mut c: u128 = 6; let mut result: u128 = 1; loop { a = match a.checked_mul(1_000) { Some(value) => value, None => break, }; b = match b.checked_mul(1_000) { Some(value) => value, None => break, }; c = match c.checked_mul(1_000) { Some(value) => value, None => break, }; result = match result.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!(MulDiv::::calculate(a, b, c), result); } assert_eq!( MulDiv::::calculate(u128::MAX, u128::MAX, u128::MAX), u128::MAX ); assert_eq!(MulDiv::::calculate(u128::MAX, 0, 0), 0); assert_eq!(MulDiv::::calculate(0, u128::MAX, 0), 0); assert_eq!(MulDiv::::calculate(0, 0, u128::MAX), 0); }); } #[test] fn check_muldiv_guarantees_not_to_overflow_for_u64() { ExtBuilder::build().execute_with(|| { let mut a: u64 = 2; let mut b: u64 = 3; let mut c: u64 = 6; let mut result: u64 = 1; loop { a = match a.checked_mul(1_000) { Some(value) => value, None => break, }; b = match b.checked_mul(1_000) { Some(value) => value, None => break, }; c = match c.checked_mul(1_000) { Some(value) => value, None => break, }; result = match result.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!(MulDiv::::calculate(a, b, c), result); } assert_eq!( MulDiv::::calculate(u64::MAX, u64::MAX, u64::MAX), u64::MAX ); assert_eq!(MulDiv::::calculate(u64::MAX, 0, 0), 0); assert_eq!(MulDiv::::calculate(0, u64::MAX, 0), 0); assert_eq!(MulDiv::::calculate(0, 0, u64::MAX), 0); }); } #[test] fn check_muldiv_guarantees_not_to_overflow_for_u32() { ExtBuilder::build().execute_with(|| { let mut a: u32 = 2; let mut b: u32 = 3; let mut c: u32 = 6; let mut result: u32 = 1; loop { a = match a.checked_mul(1_000) { Some(value) => value, None => break, }; b = match b.checked_mul(1_000) { Some(value) => value, None => break, }; c = match c.checked_mul(1_000) { Some(value) => value, None => break, }; result = match result.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!(MulDiv::::calculate(a, b, c), result); } assert_eq!( MulDiv::::calculate(u32::MAX, u32::MAX, u32::MAX), u32::MAX ); assert_eq!(MulDiv::::calculate(u32::MAX, 0, 0), 0); assert_eq!(MulDiv::::calculate(0, u32::MAX, 0), 0); assert_eq!(MulDiv::::calculate(0, 0, u32::MAX), 0); }); } #[test] fn check_bridged_inflation_curve_for_overflow() { ExtBuilder::build().execute_with(|| { let amount_full: u128 = 1337 * 1_000_000_000; let commission: u128 = amount_full / 100; // 1% commission let amount: u128 = amount_full - commission; let tollerance: u128 = commission / 100; // 1% tollerance let precomputed_payout: u128 = 13177568884; let precomputed_rest: u128 = 192431116; assert_eq!(precomputed_payout + precomputed_rest, commission); let mut total_staked_ideal: u128 = 69_000; let mut total_staked_not_ideal: u128 = 68_000; let mut total_issuance: u128 = 100_000; assert_ok!(GhostNetworks::accumulate_commission(&commission)); assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount)); loop { total_staked_ideal = match total_staked_ideal.checked_mul(1_000) { Some(value) => value, None => break, }; total_staked_not_ideal = match total_staked_not_ideal.checked_mul(1_000) { Some(value) => value, None => break, }; total_issuance = match total_issuance.checked_mul(1_000) { Some(value) => value, None => break, }; assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal, total_issuance + amount, 0 ), (commission, 0) ); let (payout, rest) = BridgedInflationCurve::::era_payout( total_staked_not_ideal, total_issuance + amount, 0, ); let payout_deviation = if precomputed_payout > payout { precomputed_payout - payout } else { payout - precomputed_payout }; let rest_deviation = if precomputed_rest > rest { precomputed_rest - rest } else { rest - precomputed_rest }; assert!(payout_deviation < tollerance); assert!(rest_deviation < tollerance); } }); } #[test] fn check_bridged_inflation_curve_for_big_commissions() { ExtBuilder::build().execute_with(|| { let mut amount_full: u128 = 1337; let total_staked_ideal: u128 = 69_000_000; let total_staked_gt_ideal: u128 = 100_000_000; let total_staked_lt_ideal: u128 = 3_000_000; let total_issuance: u128 = 100_000_000; loop { amount_full = match amount_full.checked_mul(1_000) { Some(value) => value, None => break, }; let commission: u128 = amount_full / 100; // 1% commission let amount: u128 = amount_full - commission; AccumulatedCommission::::set(commission); BridgedImbalance::::set(BridgeAdjustment { bridged_in: amount, bridged_out: 0, }); assert_eq!( BridgedInflationCurve::::era_payout( total_staked_ideal, total_issuance + amount, 0 ), (commission, 0) ); let (payout, rest) = BridgedInflationCurve::::era_payout( total_staked_gt_ideal, total_issuance + amount, 0 ); assert!(payout < commission); assert!(rest < commission); let (payout, rest) = BridgedInflationCurve::::era_payout( total_staked_lt_ideal, total_issuance + amount, 0 ); assert!(payout < commission); assert!(rest < commission); } }); }