Skip to content

Commit

Permalink
set state initial implementation for chain simulator, test in adder
Browse files Browse the repository at this point in the history
  • Loading branch information
mihaicalinluca committed Nov 20, 2024
1 parent 7409cb8 commit 04e59ef
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl AdderInteract {
let adder_owner_address = interactor.register_wallet(test_wallets::heidi()).await;
let wallet_address = interactor.register_wallet(test_wallets::ivan()).await;

interactor.generate_blocks_until_epoch(1).await.unwrap();
let _ = interactor.generate_blocks(30u64).await;

AdderInteract {
interactor,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use basic_interactor::{AdderInteract, Config};
use multiversx_sc_snippets::{sdk::gateway::SetStateAccount, test_wallets};

#[tokio::test]
#[cfg_attr(not(feature = "chain-simulator-tests"), ignore)]
Expand Down Expand Up @@ -33,3 +34,30 @@ async fn simulator_upgrade_test() {
let sum = basic_interact.get_sum().await;
assert_eq!(sum, 7u32.into());
}

#[tokio::test]
#[cfg_attr(not(feature = "chain-simulator-tests"), ignore)]
async fn set_state_cs_test() {
let account_address = test_wallets::mike();

let real_chain_interact = AdderInteract::new(Config::load_config()).await;
let simulator_interact = AdderInteract::new(Config::chain_simulator_config()).await;

let account = real_chain_interact
.interactor
.get_account(&account_address.to_address())
.await;
let keys = real_chain_interact
.interactor
.get_account_storage(&account_address.to_address())
.await;

let set_state_account = SetStateAccount::from(account).with_keys(keys);
let vec_state = vec![set_state_account];

let set_state_response = simulator_interact.interactor.set_state(vec_state).await;

let _ = simulator_interact.interactor.generate_blocks(2u64).await;

assert!(set_state_response.is_ok());
}
13 changes: 12 additions & 1 deletion framework/snippets/src/interactor/interactor_chain_simulator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use anyhow::Error;
use multiversx_sc_scenario::imports::Address;
use multiversx_sdk::gateway::{
ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest, GatewayAsyncService,
ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest,
ChainSimulatorSetStateRequest, GatewayAsyncService, SetStateAccount,
};

use crate::InteractorBase;
Expand Down Expand Up @@ -53,4 +54,14 @@ where
))
.await
}

pub async fn set_state(&self, account: Vec<SetStateAccount>) -> Result<String, Error> {
if !self.use_chain_simulator {
return Ok(String::from("no-simulator"));
}

self.proxy
.request(ChainSimulatorSetStateRequest::for_account(account))
.await
}
}
19 changes: 18 additions & 1 deletion framework/snippets/src/interactor/interactor_sender.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::collections::HashMap;

use crate::sdk::{data::transaction::Transaction, wallet::Wallet};
use log::debug;
use multiversx_sc_scenario::multiversx_sc::types::Address;
use multiversx_sdk::gateway::{GatewayAsyncService, GetAccountRequest};
use multiversx_sdk::data::account::Account;
use multiversx_sdk::gateway::{GatewayAsyncService, GetAccountRequest, GetAccountStorageRequest};

use crate::InteractorBase;

Expand All @@ -25,6 +28,20 @@ where
account.nonce
}

pub async fn get_account(&self, address: &Address) -> Account {
self.proxy
.request(GetAccountRequest::new(address))
.await
.expect("failed to retrieve account")
}

pub async fn get_account_storage(&self, address: &Address) -> HashMap<String, String> {
self.proxy
.request(GetAccountStorageRequest::new(address))
.await
.expect("failed to retrieve account")
}

pub(crate) async fn set_nonce_and_sign_tx(
&mut self,
sender_address: &Address,
Expand Down
3 changes: 3 additions & 0 deletions sdk/core/src/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod gateway_account_storage;
mod gateway_block;
mod gateway_chain_simulator_blocks;
mod gateway_chain_simulator_send_funds;
mod gateway_chain_simulator_set_state;
mod gateway_network_config;
mod gateway_network_economics;
mod gateway_network_status;
Expand All @@ -23,6 +24,7 @@ pub use gateway_account_storage::GetAccountStorageRequest;
pub use gateway_block::GetHyperBlockRequest;
pub use gateway_chain_simulator_blocks::ChainSimulatorGenerateBlocksRequest;
pub use gateway_chain_simulator_send_funds::ChainSimulatorSendFundsRequest;
pub use gateway_chain_simulator_set_state::{ChainSimulatorSetStateRequest, SetStateAccount};
pub use gateway_network_config::NetworkConfigRequest;
pub use gateway_network_economics::NetworkEconimicsRequest;
pub use gateway_network_status::NetworkStatusRequest;
Expand Down Expand Up @@ -61,6 +63,7 @@ const GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT: &str =
"simulator/generate-blocks-until-transaction-processed";
const GENERATE_BLOCKS_UNTIL_EPOCH_REACHED_ENDPOINT: &str =
"simulator/generate-blocks-until-epoch-reached";
const SET_STATE_ENDPOINT: &str = "simulator/set-state";

pub enum GatewayRequestType {
Get,
Expand Down
94 changes: 94 additions & 0 deletions sdk/core/src/gateway/gateway_chain_simulator_set_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use anyhow::anyhow;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::data::account::Account;

use super::{GatewayRequest, GatewayRequestType, SET_STATE_ENDPOINT};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetStateResponse {
pub data: serde_json::Value,
pub error: String,
pub code: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SetStateAccount {
pub address: String,
pub nonce: u64,
pub balance: String,
pub keys: HashMap<String, String>,
pub code: String,
#[serde(default)]
pub code_hash: String,
#[serde(default)]
pub root_hash: String,
#[serde(default)]
pub code_metadata: String,
#[serde(default)]
pub owner_address: String,
#[serde(default)]
pub developer_reward: String,
}

impl From<Account> for SetStateAccount {
fn from(value: Account) -> Self {
Self {
address: value.address.to_bech32_string().unwrap_or_default(),
nonce: value.nonce,
balance: value.balance.to_string(),
keys: HashMap::new(),
code: value.code,
code_hash: value.code_hash.unwrap_or_default(),
root_hash: value.root_hash.unwrap_or_default(),
code_metadata: value.code_metadata.unwrap_or_default(),
owner_address: value.owner_address.unwrap_or_default(),
developer_reward: value.developer_reward.unwrap_or_default(),
}
}
}

impl SetStateAccount {
pub fn with_keys(mut self, keys: HashMap<String, String>) -> Self {
self.keys = keys;

self
}
}

/// Sets state for a list of accounts using the chain simulator API.
pub struct ChainSimulatorSetStateRequest {
pub account: Vec<SetStateAccount>,
}

impl ChainSimulatorSetStateRequest {
pub fn for_account(account: Vec<SetStateAccount>) -> Self {
Self { account }
}
}

impl GatewayRequest for ChainSimulatorSetStateRequest {
type Payload = Vec<SetStateAccount>;
type DecodedJson = SetStateResponse;
type Result = String;

fn get_payload(&self) -> Option<&Self::Payload> {
Some(&self.account)
}

fn request_type(&self) -> GatewayRequestType {
GatewayRequestType::Post
}

fn get_endpoint(&self) -> String {
SET_STATE_ENDPOINT.to_owned()
}

fn process_json(&self, decoded: Self::DecodedJson) -> anyhow::Result<Self::Result> {
match decoded.code.as_str() {
"successful" => Ok(decoded.code),
_ => Err(anyhow!("{}", decoded.error)),
}
}
}

0 comments on commit 04e59ef

Please sign in to comment.