From a620912a73ee454f7f7c42fffd9cb71975c88c43 Mon Sep 17 00:00:00 2001 From: Rivers Yang Date: Fri, 9 Sep 2022 07:57:21 +0800 Subject: [PATCH] Remove some dangerous sudo functions. And fix testing code. --- Cargo.lock | 1 + Cargo.toml | 1 + appchain-anchor/src/appchain_messages.rs | 20 +- appchain-anchor/src/interfaces.rs | 50 -- appchain-anchor/src/lib.rs | 2 +- .../src/permissionless_actions/mod.rs | 6 +- .../src/user_actions/sudo_actions.rs | 296 +----------- tests/simulator/common/basic_actions.rs | 8 + tests/simulator/common/complex_actions.rs | 71 ++- tests/simulator/common/mod.rs | 6 + tests/simulator/contract_interfaces/mod.rs | 1 - .../permissionless_actions.rs | 25 + .../contract_interfaces/settings_manager.rs | 32 ++ .../contract_interfaces/sudo_actions.rs | 91 ---- tests/simulator/test_anchor_actions.rs | 134 +++--- tests/simulator/test_beefy_light_client.rs | 70 ++- tests/simulator/test_beefy_light_client_2.rs | 5 + tests/simulator/test_transfer_nft.rs | 195 +++++--- .../simulator/test_wrapped_appchain_token.rs | 447 +++++++++++------- 19 files changed, 650 insertions(+), 811 deletions(-) delete mode 100644 tests/simulator/contract_interfaces/sudo_actions.rs diff --git a/Cargo.lock b/Cargo.lock index d147dea..d4ce143 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,6 +124,7 @@ dependencies = [ "near-sdk", "near-units", "num-format", + "parity-scale-codec 2.3.1", "parity-scale-codec 3.1.5", "secp256k1", "tokio", diff --git a/Cargo.toml b/Cargo.toml index e5988bd..45e0590 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ near-primitives = "0.5.0" near-units = "0.2.0" hex = "0.4.2" num-format = "0.4.0" +parity-scale-codec = "2.0.0" secp256k1-test = { package = "secp256k1", version = "0.20.3", features = ["rand-std", "recovery"] } beefy-light-client = { git = "https://github.com/octopus-network/beefy-light-client.git", branch = "main" } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } diff --git a/appchain-anchor/src/appchain_messages.rs b/appchain-anchor/src/appchain_messages.rs index 3d44bea..9fcbfb3 100644 --- a/appchain-anchor/src/appchain_messages.rs +++ b/appchain-anchor/src/appchain_messages.rs @@ -14,18 +14,18 @@ pub enum PayloadType { #[derive(Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] #[serde(crate = "near_sdk::serde")] pub struct BurnAssetPayload { - token_id: String, - sender: String, - receiver_id: AccountId, - amount: u128, + pub token_id: String, + pub sender: String, + pub receiver_id: AccountId, + pub amount: u128, } #[derive(Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] #[serde(crate = "near_sdk::serde")] pub struct LockPayload { - sender: String, - receiver_id: AccountId, - amount: u128, + pub sender: String, + pub receiver_id: AccountId, + pub amount: u128, } #[derive(Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize)] @@ -81,9 +81,9 @@ pub enum MessagePayload { #[derive(Encode, Decode, Clone)] pub struct RawMessage { - nonce: u64, - payload_type: PayloadType, - payload: Vec, + pub nonce: u64, + pub payload_type: PayloadType, + pub payload: Vec, } impl RawMessage { diff --git a/appchain-anchor/src/interfaces.rs b/appchain-anchor/src/interfaces.rs index 7954523..a98dcce 100644 --- a/appchain-anchor/src/interfaces.rs +++ b/appchain-anchor/src/interfaces.rs @@ -331,10 +331,6 @@ pub trait StakingManager { pub trait SudoActions { /// fn set_owner_pk(&mut self, public_key: PublicKey); - /// Apply a certain `AppchainMessage` - fn stage_appchain_message(&mut self, appchain_message: AppchainMessage); - /// - fn stage_appchain_encoded_messages(&mut self, encoded_messages: Vec); /// fn set_metadata_of_wrapped_appchain_token(&mut self, metadata: FungibleTokenMetadata); /// @@ -344,38 +340,14 @@ pub trait SudoActions { value: U128, ); /// - fn reset_validator_set_histories_to( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult; - /// - fn reset_staking_histories_to(&mut self, era_number: U64) -> MultiTxsOperationProcessingResult; - /// - fn clear_user_staking_histories(&mut self) -> MultiTxsOperationProcessingResult; - /// fn regenerate_user_staking_histories(&mut self) -> MultiTxsOperationProcessingResult; /// - fn reset_next_validator_set_to(&mut self, era_number: U64) - -> MultiTxsOperationProcessingResult; - /// - fn clear_appchain_notification_histories(&mut self) -> MultiTxsOperationProcessingResult; - /// fn reset_beefy_light_client(&mut self, initial_public_keys: Vec); /// - fn clear_reward_distribution_records(&mut self, era_number: U64); - /// - fn clear_unbonded_stakes(&mut self); - /// - fn clear_unwithdrawn_rewards(&mut self, era_number: U64); - /// - fn reset_validator_profiles_to(&mut self, era_number: U64); - /// fn pause_asset_transfer(&mut self); /// fn resume_asset_transfer(&mut self); /// - fn remove_staking_history_at(&mut self, index: U64); - /// fn pause_rewards_withdrawal(&mut self); /// fn resume_rewards_withdrawal(&mut self); @@ -386,30 +358,8 @@ pub trait SudoActions { account_id_in_appchain: String, ); /// - fn force_change_account_id_in_appchain_of_staking_history( - &mut self, - index: U64, - account_id_in_appchain: String, - ); - /// - fn remove_duplicated_message_nonces_in_reward_distribution_records(&mut self, era_number: U64); - /// fn set_latest_applied_appchain_message_nonce(&mut self, nonce: u32); /// - fn clear_appchain_messages(&mut self) -> MultiTxsOperationProcessingResult; - /// - fn try_complete_switching_era(&mut self) -> MultiTxsOperationProcessingResult; - /// - fn remove_validator_set_history_of( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult; - /// - fn remove_validator_set_histories_before( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult; - /// fn unlock_auto_unbonded_stake_of( &mut self, delegator_id: Option, diff --git a/appchain-anchor/src/lib.rs b/appchain-anchor/src/lib.rs index a57a38a..9eb2f8c 100644 --- a/appchain-anchor/src/lib.rs +++ b/appchain-anchor/src/lib.rs @@ -1,6 +1,6 @@ mod anchor_viewer; pub mod appchain_challenge; -mod appchain_messages; +pub mod appchain_messages; mod assets; pub mod interfaces; mod lookup_array; diff --git a/appchain-anchor/src/permissionless_actions/mod.rs b/appchain-anchor/src/permissionless_actions/mod.rs index e9cd62e..fa73310 100644 --- a/appchain-anchor/src/permissionless_actions/mod.rs +++ b/appchain-anchor/src/permissionless_actions/mod.rs @@ -224,8 +224,10 @@ impl PermissionlessActions for AppchainAnchor { panic!("Failed in verifying appchain messages: {:?}", err); } } - let messages = Decode::decode(&mut &encoded_messages[..]).unwrap(); - self.internal_stage_appchain_messages(&messages); + match Decode::decode(&mut &encoded_messages[..]) { + Ok(messages) => self.internal_stage_appchain_messages(&messages), + Err(err) => panic!("Failed to decode messages: {}", err), + } } // fn process_appchain_messages(&mut self) -> MultiTxsOperationProcessingResult { diff --git a/appchain-anchor/src/user_actions/sudo_actions.rs b/appchain-anchor/src/user_actions/sudo_actions.rs index fcb2d3c..5e78e5d 100644 --- a/appchain-anchor/src/user_actions/sudo_actions.rs +++ b/appchain-anchor/src/user_actions/sudo_actions.rs @@ -1,8 +1,5 @@ -use crate::permissionless_actions::AppchainMessagesProcessingContext; +use crate::interfaces::SudoActions; use crate::*; -use crate::{appchain_messages::AppchainMessage, interfaces::SudoActions}; -use codec::Decode; -use core::panic; use near_contract_standards::fungible_token::core::ext_ft_core; use near_contract_standards::fungible_token::metadata::FungibleTokenMetadata; @@ -14,22 +11,6 @@ impl SudoActions for AppchainAnchor { self.owner_pk = public_key; } // - fn stage_appchain_message(&mut self, appchain_message: AppchainMessage) { - self.assert_owner(); - let mut processing_status = self.permissionless_actions_status.get().unwrap(); - let mut appchain_messages = self.appchain_messages.get().unwrap(); - appchain_messages.insert_message(&appchain_message); - self.appchain_messages.set(&appchain_messages); - processing_status.max_nonce_of_staged_appchain_messages = appchain_messages.max_nonce(); - self.permissionless_actions_status.set(&processing_status); - } - // - fn stage_appchain_encoded_messages(&mut self, encoded_messages: Vec) { - self.assert_owner(); - let messages = Decode::decode(&mut &encoded_messages[..]).unwrap(); - self.internal_stage_appchain_messages(&messages); - } - // fn set_metadata_of_wrapped_appchain_token(&mut self, metadata: FungibleTokenMetadata) { self.assert_owner(); let mut wrapped_appchain_token = self.wrapped_appchain_token.get().unwrap(); @@ -49,47 +30,6 @@ impl SudoActions for AppchainAnchor { self.wrapped_appchain_token.set(&wrapped_appchain_token); } // - fn reset_validator_set_histories_to( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let mut validator_set_histories = self.validator_set_histories.get().unwrap(); - let result = validator_set_histories.reset_to(&era_number.0); - if !result.is_error() { - self.validator_set_histories.set(&validator_set_histories); - } - result - } - // - fn reset_staking_histories_to(&mut self, era_number: U64) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let validator_set_histories = self.validator_set_histories.get().unwrap(); - if let Some(validator_set_of_era) = validator_set_histories.get(&era_number.0) { - let mut staking_histories = self.staking_histories.get().unwrap(); - let result = staking_histories.reset_to(&validator_set_of_era.staking_history_index()); - if !result.is_error() { - self.staking_histories.set(&staking_histories); - } - return result; - } else { - panic!( - "Missing validator set history of era_number '{}'.", - era_number.0 - ); - } - } - // - fn clear_user_staking_histories(&mut self) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let mut user_staking_histories = self.user_staking_histories.get().unwrap(); - let result = user_staking_histories.clear(); - if !result.is_error() { - self.user_staking_histories.set(&user_staking_histories); - } - result - } - // fn regenerate_user_staking_histories(&mut self) -> MultiTxsOperationProcessingResult { self.assert_owner(); let mut user_staking_histories = self.user_staking_histories.get().unwrap(); @@ -108,149 +48,12 @@ impl SudoActions for AppchainAnchor { MultiTxsOperationProcessingResult::Ok } // - // While using this function to reset data of next validator set, this contract must - // refuse any other actions which will change the state of next validator set. - // - fn reset_next_validator_set_to( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let validator_set_histories = self.validator_set_histories.get().unwrap(); - if let Some(validator_set_of_era) = validator_set_histories.get(&era_number.0) { - let mut next_validator_set = self.next_validator_set.get().unwrap(); - let result = next_validator_set.clear(); - match result { - MultiTxsOperationProcessingResult::Ok => (), - MultiTxsOperationProcessingResult::NeedMoreGas => { - self.next_validator_set.set(&next_validator_set); - return result; - } - MultiTxsOperationProcessingResult::Error(_) => { - return result; - } - } - let staking_history_index = validator_set_of_era.staking_history_index(); - let staking_histories = self.staking_histories.get().unwrap(); - for index in 0..staking_history_index + 1 { - if let Some(staking_history) = staking_histories.get(&index) { - next_validator_set.apply_staking_fact(&staking_history.staking_fact); - } - if env::used_gas() > Gas::ONE_TERA.mul(T_GAS_CAP_FOR_MULTI_TXS_PROCESSING) { - self.next_validator_set.set(&next_validator_set); - return MultiTxsOperationProcessingResult::NeedMoreGas; - } - } - self.next_validator_set.set(&next_validator_set); - MultiTxsOperationProcessingResult::Ok - } else { - panic!( - "Missing validator set history of era_number '{}'.", - era_number.0 - ); - } - } - // - fn clear_appchain_notification_histories(&mut self) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let mut appchain_notification_histories = - self.appchain_notification_histories.get().unwrap(); - let result = appchain_notification_histories.clear(); - if !result.is_error() { - self.appchain_notification_histories - .set(&appchain_notification_histories); - } - result - } - // fn reset_beefy_light_client(&mut self, initial_public_keys: Vec) { self.assert_owner(); self.beefy_light_client_state .set(&beefy_light_client::new(initial_public_keys)); } // - fn clear_reward_distribution_records(&mut self, era_number: U64) { - self.assert_owner(); - let mut reward_distribution_records = self.reward_distribution_records.get().unwrap(); - let mut validator_set_histories = self.validator_set_histories.get().unwrap(); - if let Some(mut validator_set_of_era) = validator_set_histories.get(&era_number.0) { - reward_distribution_records.clear(&validator_set_of_era, &era_number.0); - self.reward_distribution_records - .set(&reward_distribution_records); - validator_set_of_era.clear_reward_distribution_records(); - validator_set_histories.insert(&era_number.0, &validator_set_of_era); - } - } - // - fn clear_unbonded_stakes(&mut self) { - self.assert_owner(); - let staking_histories = self.staking_histories.get().unwrap(); - let index_range = staking_histories.index_range(); - for index in index_range.start_index.0..index_range.end_index.0 + 1 { - if let Some(staking_history) = staking_histories.get(&index) { - match staking_history.staking_fact { - StakingFact::StakeDecreased { validator_id, .. } - | StakingFact::ValidatorUnbonded { validator_id, .. } - | StakingFact::ValidatorAutoUnbonded { validator_id, .. } => { - self.unbonded_stakes.remove(&validator_id); - } - StakingFact::DelegationDecreased { delegator_id, .. } - | StakingFact::DelegatorUnbonded { delegator_id, .. } - | StakingFact::DelegatorAutoUnbonded { delegator_id, .. } => { - self.unbonded_stakes.remove(&delegator_id); - } - _ => (), - } - } - } - } - // - fn clear_unwithdrawn_rewards(&mut self, era_number: U64) { - self.assert_owner(); - let validator_set_histories = self.validator_set_histories.get().unwrap(); - if let Some(validator_set_of_era) = validator_set_histories.get(&era_number.0) { - validator_set_of_era - .get_validator_ids() - .iter() - .for_each(|validator_id| { - validator_set_of_era - .get_delegator_ids_of(validator_id) - .iter() - .for_each(|delegator_id| { - self.unwithdrawn_delegator_rewards.remove(&( - era_number.0, - delegator_id.clone(), - validator_id.clone(), - )); - }); - self.unwithdrawn_validator_rewards - .remove(&(era_number.0, validator_id.clone())); - }); - } - } - // - fn reset_validator_profiles_to(&mut self, era_number: U64) { - self.assert_owner(); - let mut validator_profiles = self.validator_profiles.get().unwrap(); - let validator_set_histories = self.validator_set_histories.get().unwrap(); - let mut data_changed = false; - if let Some(validator_set_of_era) = validator_set_histories.get(&era_number.0) { - validator_profiles - .get_validator_ids() - .iter() - .for_each(|validator_id| { - if !validator_set_of_era.contains_validator(validator_id) { - if validator_profiles.remove(validator_id) { - data_changed = true; - } - } - }); - } - if data_changed { - self.validator_profiles.set(&validator_profiles); - } - } - // fn pause_asset_transfer(&mut self) { self.assert_owner(); assert!( @@ -269,12 +72,6 @@ impl SudoActions for AppchainAnchor { self.asset_transfer_is_paused = false; } // - fn remove_staking_history_at(&mut self, index: U64) { - self.assert_owner(); - let mut staking_histories = self.staking_histories.get().unwrap(); - staking_histories.remove_at(&index.0); - } - // fn pause_rewards_withdrawal(&mut self) { self.assert_owner(); assert!( @@ -305,43 +102,6 @@ impl SudoActions for AppchainAnchor { ); } // - fn force_change_account_id_in_appchain_of_staking_history( - &mut self, - index: U64, - account_id_in_appchain: String, - ) { - self.assert_owner(); - let mut staking_histories = self.staking_histories.get().unwrap(); - if let Some(mut staking_history) = staking_histories.get(&index.0) { - match staking_history.staking_fact { - StakingFact::ValidatorRegistered { - validator_id, - validator_id_in_appchain: _, - amount, - can_be_delegated_to, - } => { - staking_history.staking_fact = StakingFact::ValidatorRegistered { - validator_id, - validator_id_in_appchain: account_id_in_appchain, - amount, - can_be_delegated_to, - }; - staking_histories.insert(&index.0, &staking_history); - self.staking_histories.set(&staking_histories); - } - _ => (), - } - } - } - // - fn remove_duplicated_message_nonces_in_reward_distribution_records(&mut self, era_number: U64) { - self.assert_owner(); - let mut reward_distribution_records = self.reward_distribution_records.get().unwrap(); - reward_distribution_records.remove_duplicated_message_nonces(era_number.0); - self.reward_distribution_records - .set(&reward_distribution_records); - } - // fn set_latest_applied_appchain_message_nonce(&mut self, nonce: u32) { self.assert_owner(); let mut permissionless_actions_status = self.permissionless_actions_status.get().unwrap(); @@ -351,60 +111,6 @@ impl SudoActions for AppchainAnchor { .set(&permissionless_actions_status); } // - fn clear_appchain_messages(&mut self) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let mut appchain_messages = self.appchain_messages.get().unwrap(); - let result = appchain_messages.clear(); - if !result.is_error() { - self.appchain_messages.set(&appchain_messages); - } - result - } - // - fn try_complete_switching_era(&mut self) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let processing_status = self.permissionless_actions_status.get().unwrap(); - let mut processing_context = AppchainMessagesProcessingContext::new(processing_status); - let mut validator_set_histories = self.validator_set_histories.get().unwrap(); - if let Some(era_number) = processing_context.switching_era_number() { - let result = self.complete_switching_era( - &mut processing_context, - &mut validator_set_histories, - era_number, - ); - self.permissionless_actions_status - .set(processing_context.processing_status()); - result - } else { - MultiTxsOperationProcessingResult::Ok - } - } - // - fn remove_validator_set_history_of( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult { - let mut validator_set_histories = self.validator_set_histories.get().unwrap(); - let result = validator_set_histories.remove_at(&era_number.0); - if !result.is_error() { - self.validator_set_histories.set(&validator_set_histories); - } - result - } - // - fn remove_validator_set_histories_before( - &mut self, - era_number: U64, - ) -> MultiTxsOperationProcessingResult { - self.assert_owner(); - let mut validator_set_histories = self.validator_set_histories.get().unwrap(); - let result = validator_set_histories.remove_before(&era_number.0); - if !result.is_error() { - self.validator_set_histories.set(&validator_set_histories); - } - result - } - // fn unlock_auto_unbonded_stake_of( &mut self, delegator_id: Option, diff --git a/tests/simulator/common/basic_actions.rs b/tests/simulator/common/basic_actions.rs index faa7d90..ec37f0d 100644 --- a/tests/simulator/common/basic_actions.rs +++ b/tests/simulator/common/basic_actions.rs @@ -199,6 +199,14 @@ pub async fn initialize_contracts_and_users( register_user_to_ft_contract(worker, &eve, &oct_token).await?; super::call_ft_transfer(worker, &root, &eve, total_supply / 10, &oct_token).await?; users.push(eve); + // relayer + let relayer = root + .create_subaccount(worker, "relayer") + .initial_balance(parse_near!("50 N")) + .transact() + .await? + .unwrap(); + users.push(relayer); // Return initialized UserAccounts Ok(( root, diff --git a/tests/simulator/common/complex_actions.rs b/tests/simulator/common/complex_actions.rs index 5ee01f5..c06cf60 100644 --- a/tests/simulator/common/complex_actions.rs +++ b/tests/simulator/common/complex_actions.rs @@ -7,13 +7,16 @@ use crate::{ print_wat_balance_of_anchor, }, }, - contract_interfaces::{anchor_viewer, permissionless_actions, staking_actions, sudo_actions}, + contract_interfaces::{anchor_viewer, permissionless_actions, staking_actions}, }; use appchain_anchor::{ + appchain_messages::{EraPayoutPayload, RawMessage}, + appchain_messages::{PayloadType, PlanNewEraPayload}, types::{AnchorStatus, MultiTxsOperationProcessingResult, ValidatorSetInfo}, - AppchainEvent, AppchainMessage, }; +use near_primitives::borsh::BorshSerialize; use near_sdk::{json_types::U64, serde_json}; +use parity_scale_codec::Encode; use workspaces::network::Sandbox; use workspaces::{Account, Contract, Worker}; @@ -44,22 +47,36 @@ pub async fn process_appchain_messages( pub async fn switch_era( worker: &Worker, - root: &Account, + relayer: &Account, anchor: &Contract, era_number: u32, appchain_message_nonce: u32, to_confirm_view_result: bool, ) -> anyhow::Result<()> { if era_number > 0 { - let appchain_message = AppchainMessage { - appchain_event: AppchainEvent::EraSwitchPlaned { era_number }, - nonce: appchain_message_nonce, + let payload = PlanNewEraPayload { + new_era: era_number, }; - sudo_actions::stage_appchain_message(worker, root, anchor, appchain_message) - .await - .expect("Failed to call 'stage_appchain_message'"); + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::PlanNewEra, + payload: payload.try_to_vec().unwrap(), + }; + let mut raw_messages = Vec::new(); + raw_messages.push(raw_message); + permissionless_actions::verify_and_stage_appchain_messages( + worker, + relayer, + anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); } - process_appchain_messages(worker, root, anchor).await?; + process_appchain_messages(worker, relayer, anchor).await?; if to_confirm_view_result { let anchor_status = anchor_viewer::get_anchor_status(worker, anchor).await?; println!( @@ -85,7 +102,7 @@ pub async fn switch_era( pub async fn distribute_reward_of( worker: &Worker, - root: &Account, + relayer: &Account, anchor: &Contract, wrapped_appchain_token: &Contract, nonce: u32, @@ -95,15 +112,29 @@ pub async fn distribute_reward_of( ) -> anyhow::Result<()> { let anchor_balance_of_wat = common::get_ft_balance_of(worker, &anchor.as_account(), &wrapped_appchain_token).await?; - let appchain_message = AppchainMessage { - appchain_event: AppchainEvent::EraRewardConcluded { - era_number, - unprofitable_validator_ids, - offenders: Vec::new(), - }, - nonce, + let payload = EraPayoutPayload { + end_era: era_number, + excluded_validators: unprofitable_validator_ids, + offenders: Vec::new(), + }; + let raw_message = RawMessage { + nonce: nonce as u64, + payload_type: PayloadType::EraPayout, + payload: payload.try_to_vec().unwrap(), }; - sudo_actions::stage_appchain_message(worker, root, anchor, appchain_message).await?; + let mut raw_messages = Vec::new(); + raw_messages.push(raw_message); + permissionless_actions::verify_and_stage_appchain_messages( + worker, + relayer, + anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); if to_confirm_view_result { let anchor_status = anchor_viewer::get_anchor_status(worker, anchor).await?; println!( @@ -112,7 +143,7 @@ pub async fn distribute_reward_of( ); println!(); } - process_appchain_messages(worker, root, anchor).await?; + process_appchain_messages(worker, relayer, anchor).await?; assert_eq!( common::get_ft_balance_of(worker, &anchor.as_account(), &wrapped_appchain_token) .await? diff --git a/tests/simulator/common/mod.rs b/tests/simulator/common/mod.rs index a58b2fe..ba37e49 100644 --- a/tests/simulator/common/mod.rs +++ b/tests/simulator/common/mod.rs @@ -522,6 +522,12 @@ pub async fn test_normal_actions( lifecycle_actions::initialize_beefy_light_client(worker, &root, &anchor, initial_public_keys) .await .expect("Failed in calling 'initialize_beefy_light_client'"); + settings_manager::turn_on_beefy_light_client_witness_mode(&worker, &root, &anchor) + .await + .expect("Failed in calling 'turn_on_beefy_light_client_witness_mode'"); + settings_manager::set_relayer_account(&worker, &root, &anchor, &users[5]) + .await + .expect("Failed to call 'set_relayer_account'"); // // Go live // diff --git a/tests/simulator/contract_interfaces/mod.rs b/tests/simulator/contract_interfaces/mod.rs index faffa7b..2787a03 100644 --- a/tests/simulator/contract_interfaces/mod.rs +++ b/tests/simulator/contract_interfaces/mod.rs @@ -4,7 +4,6 @@ pub mod near_fungible_token_manager; pub mod permissionless_actions; pub mod settings_manager; pub mod staking_actions; -pub mod sudo_actions; pub mod validator_actions; pub mod wrapped_appchain_nft_manager; pub mod wrapped_appchain_token_manager; diff --git a/tests/simulator/contract_interfaces/permissionless_actions.rs b/tests/simulator/contract_interfaces/permissionless_actions.rs index 96096d9..fd57660 100644 --- a/tests/simulator/contract_interfaces/permissionless_actions.rs +++ b/tests/simulator/contract_interfaces/permissionless_actions.rs @@ -2,6 +2,31 @@ use appchain_anchor::types::{MultiTxsOperationProcessingResult, ValidatorMerkleP use near_sdk::serde_json::json; use workspaces::{network::Sandbox, result::CallExecutionDetails, Account, Contract, Worker}; +pub async fn verify_and_stage_appchain_messages( + worker: &Worker, + signer: &Account, + anchor: &Contract, + encoded_messages: Vec, + header: Vec, + mmr_leaf: Vec, + mmr_proof: Vec, +) -> anyhow::Result { + let result = signer + .call(worker, anchor.id(), "verify_and_stage_appchain_messages") + .gas(300_000_000_000_000) + .args_json(json!({ + "encoded_messages": encoded_messages, + "header": header, + "mmr_leaf": mmr_leaf, + "mmr_proof": mmr_proof + }))? + .transact() + .await; + println!("{:?}", result); + println!(); + result +} + pub async fn process_appchain_messages( worker: &Worker, signer: &Account, diff --git a/tests/simulator/contract_interfaces/settings_manager.rs b/tests/simulator/contract_interfaces/settings_manager.rs index d27225d..fc77768 100644 --- a/tests/simulator/contract_interfaces/settings_manager.rs +++ b/tests/simulator/contract_interfaces/settings_manager.rs @@ -90,6 +90,22 @@ pub async fn set_token_price_maintainer_account( .await } +pub async fn set_relayer_account( + worker: &Worker, + signer: &Account, + anchor: &Contract, + account: &Account, +) -> anyhow::Result { + signer + .call(worker, anchor.id(), "set_relayer_account") + .args_json(json!({ + "account_id": account.id() + }))? + .gas(200_000_000_000_000) + .transact() + .await +} + pub async fn set_price_of_oct_token( worker: &Worker, signer: &Account, @@ -155,3 +171,19 @@ pub async fn turn_on_beefy_light_client_witness_mode( .transact() .await } + +pub async fn turn_off_beefy_light_client_witness_mode( + worker: &Worker, + signer: &Account, + anchor: &Contract, +) -> anyhow::Result { + signer + .call( + worker, + anchor.id(), + "turn_off_beefy_light_client_witness_mode", + ) + .gas(200_000_000_000_000) + .transact() + .await +} diff --git a/tests/simulator/contract_interfaces/sudo_actions.rs b/tests/simulator/contract_interfaces/sudo_actions.rs deleted file mode 100644 index 71e2a13..0000000 --- a/tests/simulator/contract_interfaces/sudo_actions.rs +++ /dev/null @@ -1,91 +0,0 @@ -use appchain_anchor::AppchainMessage; -use near_sdk::{ - json_types::U64, - serde_json::{self, json}, -}; -use workspaces::{network::Sandbox, result::CallExecutionDetails, Account, Contract, Worker}; - -pub async fn stage_appchain_message( - worker: &Worker, - signer: &Account, - anchor: &Contract, - message: AppchainMessage, -) -> anyhow::Result { - println!( - "Appchain message: {}", - serde_json::to_string::(&message).unwrap() - ); - println!(); - signer - .call(worker, anchor.id(), "stage_appchain_message") - .args_json(json!({ "appchain_message": message }))? - .gas(200_000_000_000_000) - .transact() - .await -} - -pub async fn reset_validator_set_histories_to( - worker: &Worker, - signer: &Account, - anchor: &Contract, - era_number: U64, -) -> anyhow::Result { - signer - .call(worker, anchor.id(), "reset_validator_set_histories_to") - .args_json(json!({ "era_number": era_number }))? - .gas(200_000_000_000_000) - .transact() - .await -} - -pub async fn clear_appchain_notification_histories( - worker: &Worker, - signer: &Account, - anchor: &Contract, -) -> anyhow::Result { - signer - .call(worker, anchor.id(), "clear_appchain_notification_histories") - .gas(200_000_000_000_000) - .transact() - .await -} - -pub async fn clear_reward_distribution_records( - worker: &Worker, - signer: &Account, - anchor: &Contract, - era_number: U64, -) -> anyhow::Result { - signer - .call(worker, anchor.id(), "clear_reward_distribution_records") - .args_json(json!({ "era_number": era_number }))? - .gas(200_000_000_000_000) - .transact() - .await -} - -pub async fn clear_unbonded_stakes( - worker: &Worker, - signer: &Account, - anchor: &Contract, -) -> anyhow::Result { - signer - .call(worker, anchor.id(), "clear_unbonded_stakes") - .gas(200_000_000_000_000) - .transact() - .await -} - -pub async fn clear_unwithdrawn_rewards( - worker: &Worker, - signer: &Account, - anchor: &Contract, - era_number: U64, -) -> anyhow::Result { - signer - .call(worker, anchor.id(), "clear_unwithdrawn_rewards") - .args_json(json!({ "era_number": era_number }))? - .gas(200_000_000_000_000) - .transact() - .await -} diff --git a/tests/simulator/test_anchor_actions.rs b/tests/simulator/test_anchor_actions.rs index 7f27983..db9b498 100644 --- a/tests/simulator/test_anchor_actions.rs +++ b/tests/simulator/test_anchor_actions.rs @@ -1,6 +1,6 @@ use crate::{ common, - contract_interfaces::{anchor_viewer, settings_manager, staking_actions, sudo_actions}, + contract_interfaces::{anchor_viewer, settings_manager, staking_actions}, }; use near_sdk::json_types::U64; use std::collections::HashMap; @@ -23,9 +23,16 @@ async fn test_anchor_actions() -> anyhow::Result<()> { // Try start and complete switching era1 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 1, appchain_message_nonce, false) - .await - .expect("Failed to switch era"); + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 1, + appchain_message_nonce, + false, + ) + .await + .expect("Failed to switch era"); common::complex_viewer::print_validator_set_info_of(&worker, &anchor, U64::from(1)).await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(1)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 1, &users[0]).await?; @@ -35,7 +42,7 @@ async fn test_anchor_actions() -> anyhow::Result<()> { appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -74,61 +81,6 @@ async fn test_anchor_actions() -> anyhow::Result<()> { ) .await?; // - // Reset contract status - // - let result = - sudo_actions::clear_reward_distribution_records(&worker, &root, &anchor, U64::from(3)) - .await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_reward_distribution_records(&worker, &root, &anchor, U64::from(2)) - .await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_reward_distribution_records(&worker, &root, &anchor, U64::from(1)) - .await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_reward_distribution_records(&worker, &root, &anchor, U64::from(0)) - .await?; - assert!(result.is_success()); - let result = sudo_actions::clear_unbonded_stakes(&worker, &root, &anchor).await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_unwithdrawn_rewards(&worker, &root, &anchor, U64::from(3)).await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_unwithdrawn_rewards(&worker, &root, &anchor, U64::from(2)).await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_unwithdrawn_rewards(&worker, &root, &anchor, U64::from(1)).await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_unwithdrawn_rewards(&worker, &root, &anchor, U64::from(0)).await?; - assert!(result.is_success()); - let result = - sudo_actions::clear_appchain_notification_histories(&worker, &root, &anchor).await?; - assert!(result.is_success()); - let result = - sudo_actions::reset_validator_set_histories_to(&worker, &root, &anchor, U64::from(2)) - .await?; - assert!(result.is_success()); - let result = - sudo_actions::reset_validator_set_histories_to(&worker, &root, &anchor, U64::from(1)) - .await?; - assert!(result.is_success()); - let result = - sudo_actions::reset_validator_set_histories_to(&worker, &root, &anchor, U64::from(0)) - .await?; - assert!(result.is_success()); - common::complex_viewer::print_anchor_status(&worker, &anchor).await?; - common::complex_viewer::print_wrapped_appchain_token_info(&worker, &anchor).await?; - common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(0)).await?; - common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(1)).await?; - common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(2)).await?; - common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(3)).await?; - common::complex_viewer::print_staking_histories(&worker, &anchor).await?; - common::complex_viewer::print_appchain_notifications(&worker, &anchor).await?; Ok(()) } @@ -192,9 +144,16 @@ async fn test_staking_actions( // Try start and complete switching era2 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 2, appchain_message_nonce, true) - .await - .expect("Failed to switch era"); + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 2, + appchain_message_nonce, + true, + ) + .await + .expect("Failed to switch era"); common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(2)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 2, &users[0]).await?; // @@ -203,7 +162,7 @@ async fn test_staking_actions( appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -267,9 +226,16 @@ async fn test_staking_actions( // Try start and complete switching era3 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 3, appchain_message_nonce, true) - .await - .expect("Failed to switch era"); + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 3, + appchain_message_nonce, + true, + ) + .await + .expect("Failed to switch era"); common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(3)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 3, &users[0]).await?; // @@ -278,7 +244,7 @@ async fn test_staking_actions( appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -333,9 +299,16 @@ async fn test_staking_actions( // Try start and complete switching era4 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 4, appchain_message_nonce, true) - .await - .expect("Failed to switch era"); + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 4, + appchain_message_nonce, + true, + ) + .await + .expect("Failed to switch era"); common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(4)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 4, &users[0]).await?; // @@ -345,7 +318,7 @@ async fn test_staking_actions( appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -379,7 +352,7 @@ async fn test_staking_actions( appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -413,9 +386,16 @@ async fn test_staking_actions( // Try start and complete switching era5 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 5, appchain_message_nonce, true) - .await - .expect("Failed to switch era"); + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 5, + appchain_message_nonce, + true, + ) + .await + .expect("Failed to switch era"); common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(5)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 5, &users[0]).await?; // @@ -425,7 +405,7 @@ async fn test_staking_actions( appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, diff --git a/tests/simulator/test_beefy_light_client.rs b/tests/simulator/test_beefy_light_client.rs index aac2e42..9b438bb 100644 --- a/tests/simulator/test_beefy_light_client.rs +++ b/tests/simulator/test_beefy_light_client.rs @@ -1,7 +1,7 @@ use crate::{ common, contract_interfaces::{ - anchor_viewer, permissionless_actions, settings_manager, staking_actions, sudo_actions, + anchor_viewer, permissionless_actions, settings_manager, staking_actions, }, }; use appchain_anchor::types::{MultiTxsOperationProcessingResult, ValidatorMerkleProof}; @@ -9,7 +9,7 @@ use beefy_light_client::mmr::{MmrLeaf, MmrLeafProof}; use beefy_light_client::{beefy_ecdsa_to_ethereum, commitment::SignedCommitment}; use codec::Decode; use hex_literal::hex; -use near_sdk::{json_types::U64, serde_json}; +use near_sdk::serde_json; use workspaces::{network::Sandbox, Account, Contract, Worker}; #[tokio::test] @@ -33,6 +33,10 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { mut appchain_message_nonce, ) = common::test_normal_actions(&worker, false, true, initial_public_keys).await?; // + settings_manager::turn_off_beefy_light_client_witness_mode(&worker, &root, &anchor) + .await + .expect("Failed to call 'turn_off_beefy_light_client_witness_mode'"); + // // Update state of beefy light client // update_state_of_beefy_light_client_1(&worker, &anchor, &users[4]).await?; @@ -40,11 +44,22 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { update_state_of_beefy_light_client_2(&worker, &anchor, &users[1]).await?; common::complex_viewer::print_latest_appchain_commitment(&worker, &anchor).await?; // + settings_manager::turn_on_beefy_light_client_witness_mode(&worker, &root, &anchor) + .await + .expect("Failed to call 'turn_on_beefy_light_client_witness_mode'"); + // // Try start and complete switching era1 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 1, appchain_message_nonce, true) - .await?; + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 1, + appchain_message_nonce, + true, + ) + .await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(1)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 1, &users[0]).await?; // @@ -53,7 +68,7 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -116,8 +131,15 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { // Try start and complete switching era2 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 2, appchain_message_nonce, true) - .await?; + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 2, + appchain_message_nonce, + true, + ) + .await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(2)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 2, &users[0]).await?; // @@ -126,7 +148,7 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -189,8 +211,15 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { // Try start and complete switching era3 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 3, appchain_message_nonce, true) - .await?; + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 3, + appchain_message_nonce, + true, + ) + .await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(3)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 3, &users[0]).await?; // @@ -199,7 +228,7 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -245,8 +274,15 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { // Try start and complete switching era3 // appchain_message_nonce += 1; - common::complex_actions::switch_era(&worker, &root, &anchor, 4, appchain_message_nonce, true) - .await?; + common::complex_actions::switch_era( + &worker, + &users[5], + &anchor, + 4, + appchain_message_nonce, + true, + ) + .await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(4)).await?; common::complex_viewer::print_delegator_list_of(&worker, &anchor, 4, &users[0]).await?; // @@ -255,7 +291,7 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { appchain_message_nonce += 1; common::complex_actions::distribute_reward_of( &worker, - &root, + &users[5], &anchor, &wrapped_appchain_token, appchain_message_nonce, @@ -341,12 +377,8 @@ async fn test_beefy_light_client() -> anyhow::Result<()> { common::complex_actions::withdraw_stake_of(&worker, &anchor, &users[3], &oct_token).await?; common::complex_actions::withdraw_stake_of(&worker, &anchor, &users[4], &oct_token).await?; // - // Reset history data // - let result = - sudo_actions::reset_validator_set_histories_to(&worker, &root, &anchor, U64::from(0)) - .await?; - assert!(result.is_success()); + // common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(0)).await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(1)).await?; common::complex_viewer::print_validator_list_of(&worker, &anchor, Some(2)).await?; diff --git a/tests/simulator/test_beefy_light_client_2.rs b/tests/simulator/test_beefy_light_client_2.rs index 32af53f..9610d9e 100644 --- a/tests/simulator/test_beefy_light_client_2.rs +++ b/tests/simulator/test_beefy_light_client_2.rs @@ -1,3 +1,4 @@ +use crate::contract_interfaces::settings_manager; use crate::{common, contract_interfaces::permissionless_actions}; use appchain_anchor::types::{MultiTxsOperationProcessingResult, ValidatorMerkleProof}; use beefy_light_client::commitment::{Commitment, Payload, Signature}; @@ -84,6 +85,10 @@ async fn test_beefy_light_client_2() -> anyhow::Result<()> { _appchain_message_nonce, ) = common::test_normal_actions(&worker, false, true, initial_public_keys).await?; // + settings_manager::turn_off_beefy_light_client_witness_mode(&worker, &root, &anchor) + .await + .expect("Failed to call 'turn_off_beefy_light_client_witness_mode'"); + // permissionless_actions::start_updating_state_of_beefy_light_client( &worker, &root, diff --git a/tests/simulator/test_transfer_nft.rs b/tests/simulator/test_transfer_nft.rs index 8961fb8..1f4c1ab 100644 --- a/tests/simulator/test_transfer_nft.rs +++ b/tests/simulator/test_transfer_nft.rs @@ -1,13 +1,20 @@ use crate::{ common, - contract_interfaces::{settings_manager, sudo_actions, wrapped_appchain_nft_manager}, + contract_interfaces::{permissionless_actions, wrapped_appchain_nft_manager}, +}; +use appchain_anchor::{ + appchain_messages::{LockNftPayload, PayloadType, RawMessage}, + types::NFTTransferMessage, }; -use appchain_anchor::{types::NFTTransferMessage, AppchainEvent, AppchainMessage}; use near_contract_standards::non_fungible_token::metadata::{ NFTContractMetadata, TokenMetadata, NFT_METADATA_SPEC, }; -use near_sdk::serde_json::{self, json}; +use near_sdk::{ + borsh::BorshSerialize, + serde_json::{self, json}, +}; use near_units::parse_near; +use parity_scale_codec::Encode; use std::str::FromStr; use workspaces::AccountId; @@ -75,7 +82,7 @@ async fn test_transfer_nft_to_near() -> anyhow::Result<()> { .await .expect("Failed in calling 'store_wasm_of_wrapped_appchain_nft_contract'"); // - let class_id = "nft_class1".to_string(); + let class_id = "1".to_string(); wrapped_appchain_nft_manager::register_wrapped_appchain_nft( &worker, &root, @@ -98,37 +105,48 @@ async fn test_transfer_nft_to_near() -> anyhow::Result<()> { // let user0_id_in_appchain = "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d".to_string(); - settings_manager::turn_on_beefy_light_client_witness_mode(&worker, &root, &anchor) - .await - .expect("Failed in calling 'turn_on_beefy_light_client_witness_mode'"); // // // appchain_message_nonce += 1; - let appchain_message = AppchainMessage { - appchain_event: AppchainEvent::NonFungibleTokenLocked { - owner_id_in_appchain: user0_id_in_appchain.clone(), - receiver_id_in_near: users[0].id().to_string().parse().unwrap(), - class_id: class_id.clone(), - instance_id: "token_id1".to_string(), - token_metadata: TokenMetadata { - title: Some("token_id1 title".to_string()), - description: Some("token_id1 description".to_string()), - media: None, - media_hash: None, - copies: Some(1), - issued_at: None, - expires_at: None, - starts_at: None, - updated_at: None, - extra: None, - reference: None, - reference_hash: None, - }, + let payload = LockNftPayload { + sender: user0_id_in_appchain.clone(), + receiver_id: users[0].id().to_string().parse().unwrap(), + class: 1 as u128, + instance: 1 as u128, + metadata: TokenMetadata { + title: Some("token_id1 title".to_string()), + description: Some("token_id1 description".to_string()), + media: None, + media_hash: None, + copies: Some(1), + issued_at: None, + expires_at: None, + starts_at: None, + updated_at: None, + extra: None, + reference: None, + reference_hash: None, }, - nonce: appchain_message_nonce, }; - sudo_actions::stage_appchain_message(&worker, &root, &anchor, appchain_message).await?; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::LockNft, + payload: payload.try_to_vec().unwrap(), + }; + let mut raw_messages = Vec::new(); + raw_messages.push(raw_message); + permissionless_actions::verify_and_stage_appchain_messages( + &worker, + &users[5], + &anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); common::complex_actions::process_appchain_messages(&worker, &users[4], &anchor).await?; common::complex_viewer::print_appchain_messages(&worker, &anchor).await?; common::complex_viewer::print_appchain_messages_processing_results(&worker, &anchor).await?; @@ -144,32 +162,45 @@ async fn test_transfer_nft_to_near() -> anyhow::Result<()> { ) .await?; assert!(result.is_success()); - let token_id = "token_id1".to_string(); appchain_message_nonce += 1; - let appchain_message = AppchainMessage { - appchain_event: AppchainEvent::NonFungibleTokenLocked { - owner_id_in_appchain: user0_id_in_appchain.clone(), - receiver_id_in_near: users[0].id().to_string().parse().unwrap(), - class_id: class_id.clone(), - instance_id: token_id.clone(), - token_metadata: TokenMetadata { - title: Some("token_id1 title".to_string()), - description: Some("token_id1 description".to_string()), - media: None, - media_hash: None, - copies: Some(1), - issued_at: None, - expires_at: None, - starts_at: None, - updated_at: None, - extra: None, - reference: None, - reference_hash: None, - }, + let payload = LockNftPayload { + sender: user0_id_in_appchain.clone(), + receiver_id: users[0].id().to_string().parse().unwrap(), + class: 1 as u128, + instance: 1 as u128, + metadata: TokenMetadata { + title: Some("token_id1 title".to_string()), + description: Some("token_id1 description".to_string()), + media: None, + media_hash: None, + copies: Some(1), + issued_at: None, + expires_at: None, + starts_at: None, + updated_at: None, + extra: None, + reference: None, + reference_hash: None, }, - nonce: appchain_message_nonce, }; - sudo_actions::stage_appchain_message(&worker, &root, &anchor, appchain_message).await?; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::LockNft, + payload: payload.try_to_vec().unwrap(), + }; + let mut raw_messages = Vec::new(); + raw_messages.push(raw_message); + permissionless_actions::verify_and_stage_appchain_messages( + &worker, + &users[5], + &anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); common::complex_actions::process_appchain_messages(&worker, &users[4], &anchor).await?; common::complex_viewer::print_appchain_messages(&worker, &anchor).await?; common::complex_viewer::print_appchain_messages_processing_results(&worker, &anchor).await?; @@ -188,7 +219,7 @@ async fn test_transfer_nft_to_near() -> anyhow::Result<()> { ) .args_json(json!({ "receiver_id": anchor.id(), - "token_id": token_id.clone(), + "token_id": "1".to_string(), "approval_Id": Option::::None, "memo": Option::::None, "msg": serde_json::ser::to_string(&NFTTransferMessage::BridgeToAppchain { @@ -205,30 +236,44 @@ async fn test_transfer_nft_to_near() -> anyhow::Result<()> { // // appchain_message_nonce += 1; - let appchain_message = AppchainMessage { - appchain_event: AppchainEvent::NonFungibleTokenLocked { - owner_id_in_appchain: user0_id_in_appchain.clone(), - receiver_id_in_near: users[0].id().to_string().parse().unwrap(), - class_id: class_id.clone(), - instance_id: "token_id1".to_string(), - token_metadata: TokenMetadata { - title: Some("token_id1 title".to_string()), - description: Some("token_id1 description".to_string()), - media: None, - media_hash: None, - copies: Some(1), - issued_at: None, - expires_at: None, - starts_at: None, - updated_at: None, - extra: None, - reference: None, - reference_hash: None, - }, + let payload = LockNftPayload { + sender: user0_id_in_appchain.clone(), + receiver_id: users[0].id().to_string().parse().unwrap(), + class: 1 as u128, + instance: 1 as u128, + metadata: TokenMetadata { + title: Some("token_id1 title".to_string()), + description: Some("token_id1 description".to_string()), + media: None, + media_hash: None, + copies: Some(1), + issued_at: None, + expires_at: None, + starts_at: None, + updated_at: None, + extra: None, + reference: None, + reference_hash: None, }, - nonce: appchain_message_nonce, }; - sudo_actions::stage_appchain_message(&worker, &root, &anchor, appchain_message).await?; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::LockNft, + payload: payload.try_to_vec().unwrap(), + }; + let mut raw_messages = Vec::new(); + raw_messages.push(raw_message); + permissionless_actions::verify_and_stage_appchain_messages( + &worker, + &users[5], + &anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); common::complex_actions::process_appchain_messages(&worker, &users[4], &anchor).await?; common::complex_viewer::print_appchain_messages(&worker, &anchor).await?; common::complex_viewer::print_appchain_messages_processing_results(&worker, &anchor).await?; diff --git a/tests/simulator/test_wrapped_appchain_token.rs b/tests/simulator/test_wrapped_appchain_token.rs index c90d11f..1ac319a 100644 --- a/tests/simulator/test_wrapped_appchain_token.rs +++ b/tests/simulator/test_wrapped_appchain_token.rs @@ -1,9 +1,12 @@ use crate::{ common, - contract_interfaces::{sudo_actions, wrapped_appchain_token_manager}, + contract_interfaces::{permissionless_actions, wrapped_appchain_token_manager}, }; -use appchain_anchor::{AppchainEvent, AppchainMessage}; -use near_sdk::{json_types::U128, AccountId}; +use appchain_anchor::appchain_messages::{ + EraPayoutPayload, LockPayload, PayloadType, PlanNewEraPayload, RawMessage, +}; +use near_sdk::{borsh::BorshSerialize, AccountId}; +use parity_scale_codec::Encode; use std::str::FromStr; const TOTAL_SUPPLY: u128 = 100_000_000; @@ -12,7 +15,7 @@ const TOTAL_SUPPLY: u128 = 100_000_000; async fn test_wrapped_appchain_token_bridging() -> anyhow::Result<()> { let worker = workspaces::sandbox().await?; let ( - root, + _root, _oct_token, wrapped_appchain_token, _registry, @@ -33,15 +36,29 @@ async fn test_wrapped_appchain_token_bridging() -> anyhow::Result<()> { let user1_wat_balance = common::get_ft_balance_of(&worker, &users[1], &wrapped_appchain_token).await?; appchain_message_nonce += 1; - let appchain_message = AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: AccountId::from_str("unknown.testnet").unwrap(), - amount: U128::from(total_supply / 10), - }, - nonce: appchain_message_nonce, + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: AccountId::from_str("unknown.testnet").unwrap(), + amount: total_supply / 10, + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), }; - sudo_actions::stage_appchain_message(&worker, &root, &anchor, appchain_message).await?; + let mut raw_messages = Vec::new(); + raw_messages.push(raw_message); + permissionless_actions::verify_and_stage_appchain_messages( + &worker, + &users[5], + &anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); common::complex_actions::process_appchain_messages(&worker, &users[4], &anchor).await?; common::complex_viewer::print_appchain_messages(&worker, &anchor).await?; common::complex_viewer::print_appchain_messages_processing_results(&worker, &anchor).await?; @@ -71,123 +88,184 @@ async fn test_wrapped_appchain_token_bridging() -> anyhow::Result<()> { // let user1_wat_balance = common::get_ft_balance_of(&worker, &users[1], &wrapped_appchain_token).await?; - let mut appchain_messages = Vec::::new(); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(60, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(40, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraSwitchPlaned { era_number: 1 }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(70, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(30, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraRewardConcluded { - era_number: 0, - unprofitable_validator_ids: Vec::new(), - offenders: Vec::new(), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::NativeTokenLocked { - owner_id_in_appchain: user4_id_in_appchain.clone(), - receiver_id_in_near: users[1].id().to_string().parse().unwrap(), - amount: U128::from(common::to_actual_amount(45, 18)), - }, - nonce: appchain_message_nonce, - }); - for appchain_message in appchain_messages { - sudo_actions::stage_appchain_message(&worker, &root, &anchor, appchain_message).await?; - } + let mut raw_messages = Vec::new(); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(60, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(40, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = PlanNewEraPayload { new_era: 1 }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::PlanNewEra, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(70, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(30, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = EraPayoutPayload { + end_era: 0, + excluded_validators: Vec::new(), + offenders: Vec::new(), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::EraPayout, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = LockPayload { + sender: user4_id_in_appchain.clone(), + receiver_id: users[1].id().to_string().parse().unwrap(), + amount: common::to_actual_amount(45, 18), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::Lock, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + permissionless_actions::verify_and_stage_appchain_messages( + &worker, + &users[5], + &anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); common::complex_actions::process_appchain_messages(&worker, &users[3], &anchor).await?; common::complex_viewer::print_appchain_messages(&worker, &anchor).await?; common::complex_viewer::print_appchain_messages_processing_results(&worker, &anchor).await?; @@ -202,47 +280,76 @@ async fn test_wrapped_appchain_token_bridging() -> anyhow::Result<()> { // // // - let mut appchain_messages = Vec::::new(); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraSwitchPlaned { era_number: 2 }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraRewardConcluded { - era_number: 1, - unprofitable_validator_ids: Vec::new(), - offenders: Vec::new(), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraSwitchPlaned { era_number: 3 }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraRewardConcluded { - era_number: 2, - unprofitable_validator_ids: Vec::new(), - offenders: Vec::new(), - }, - nonce: appchain_message_nonce, - }); - appchain_message_nonce += 1; - appchain_messages.push(AppchainMessage { - appchain_event: AppchainEvent::EraRewardConcluded { - era_number: 1, - unprofitable_validator_ids: Vec::new(), - offenders: Vec::new(), - }, - nonce: appchain_message_nonce, - }); - for appchain_message in appchain_messages { - sudo_actions::stage_appchain_message(&worker, &root, &anchor, appchain_message).await?; - } + let mut raw_messages = Vec::new(); + // + appchain_message_nonce += 1; + let payload = PlanNewEraPayload { new_era: 2 }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::PlanNewEra, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = EraPayoutPayload { + end_era: 1, + excluded_validators: Vec::new(), + offenders: Vec::new(), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::EraPayout, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = PlanNewEraPayload { new_era: 3 }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::PlanNewEra, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = EraPayoutPayload { + end_era: 2, + excluded_validators: Vec::new(), + offenders: Vec::new(), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::EraPayout, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + appchain_message_nonce += 1; + let payload = EraPayoutPayload { + end_era: 1, + excluded_validators: Vec::new(), + offenders: Vec::new(), + }; + let raw_message = RawMessage { + nonce: appchain_message_nonce as u64, + payload_type: PayloadType::EraPayout, + payload: payload.try_to_vec().unwrap(), + }; + raw_messages.push(raw_message); + // + permissionless_actions::verify_and_stage_appchain_messages( + &worker, + &users[5], + &anchor, + raw_messages.encode(), + Vec::new(), + Vec::new(), + Vec::new(), + ) + .await + .expect("Failed to call 'verify_and_stage_appchain_messages'"); common::complex_actions::process_appchain_messages(&worker, &users[3], &anchor).await?; common::complex_viewer::print_appchain_messages(&worker, &anchor).await?; common::complex_viewer::print_appchain_messages_processing_results(&worker, &anchor).await?;