Skip to content

Commit

Permalink
Merge pull request #6
Browse files Browse the repository at this point in the history
Fetching ScenarioWorldInfos can now return an error
  • Loading branch information
gfusee authored Oct 13, 2023
2 parents cbcbb9f + 71f99de commit 86de2bb
Show file tree
Hide file tree
Showing 13 changed files with 65 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions cookbook/deps/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cookbook/deps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
novax = "0.0.1"
novax-caching = "0.0.1"
novax-mocking = "0.0.1"
novax-mocking = "0.0.2"
tokio = "1.32.0"
num-bigint = "0.4.4"
async-trait = "0.1.73"
Expand Down
2 changes: 1 addition & 1 deletion cookbook/src/mocking/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ NovaX equips developers with the capability to mock their environments seamlessl
Before delving into the mocking process with NovaX, ensure you've added the necessary extension crate to your project. Update your `Cargo.toml` dependencies to include:

```toml
novax-mocking = "0.0.1"
novax-mocking = "0.0.2"
```

Now, let's proceed with how to execute mocked queries, calls, and deploys using NovaX.
Expand Down
2 changes: 1 addition & 1 deletion executor/src/mocking/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl<A> DeployExecutor for MockExecutor<A>

let sc_deploy_step = sc_deploy_step.as_mut();

let owned_sc_deploy_step = mem::replace(sc_deploy_step, ScDeployStep::new().into());
let owned_sc_deploy_step = mem::replace(sc_deploy_step, ScDeployStep::new());
*sc_deploy_step = owned_sc_deploy_step.from(&caller);

{
Expand Down
2 changes: 1 addition & 1 deletion executor/src/network/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<Interactor: BlockchainInteractor> DeployExecutor for BaseTransactionNetwork
OriginalResult: TopEncodeMulti + Send + Sync,
{
let sc_deploy_step = sc_deploy_step.as_mut();
let owned_sc_deploy_step = mem::replace(sc_deploy_step, ScDeployStep::new().into());
let owned_sc_deploy_step = mem::replace(sc_deploy_step, ScDeployStep::new());
let mut interactor = Interactor::new(&self.gateway_url).await;
let sender_address = interactor.register_wallet(self.wallet);
*sc_deploy_step = owned_sc_deploy_step.from(&multiversx_sc::types::Address::from(sender_address.to_bytes()));
Expand Down
4 changes: 2 additions & 2 deletions mocking/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "novax-mocking"
version = "0.0.1"
version = "0.0.2"
edition = "2021"
license = "GPL-3.0-only"
description = "The `novax-mocking` crate is a part of the Nova framework, providing utilities to simulate blockchain environments. It facilitates the creation of a `MockExecutor` and other simulated entities, enabling easy testing and development against smart contract interactions within a controlled, replicated blockchain scenario."
Expand All @@ -13,7 +13,7 @@ num-bigint = "0.4.3"
async-trait = "0.1.72"
tokio = "1.30.0"
novax = { path = "../core", version = "0.0.1" }
novax-token = { path = "../token", version = "0.0.1" }
novax-token = { path = "../token", version = "0.0.2" }
multiversx-sc = "0.43.2"
multiversx-sc-snippets = "0.43.2"
multiversx-sdk = "0.2.0"
Expand Down
10 changes: 9 additions & 1 deletion mocking/src/errors/mocking.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
use serde::{Deserialize, Serialize};
use novax::errors::NovaXError;
use novax_token::error::token::TokenError;

#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub enum NovaXMockingError {
UnableToFetchAddressKeys,
UnableToParseAddressKeys,
UnableToReadInfosFromFile,
NovaXError(NovaXError)
NovaXError(NovaXError),
NovaXTokenError(TokenError)
}

impl From<NovaXError> for NovaXMockingError {
fn from(value: NovaXError) -> Self {
NovaXMockingError::NovaXError(value)
}
}

impl From<TokenError> for NovaXMockingError {
fn from(value: TokenError) -> Self {
NovaXMockingError::NovaXTokenError(value)
}
}
6 changes: 3 additions & 3 deletions mocking/src/gateway/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ impl AddressKeys {
let bech32 = address.to_bech32_string().map_err(NovaXError::from)?;
let url = format!("{gateway_url}/address/{bech32}/keys");

let Ok(response) = reqwest::get(url).await else { return Err(NovaXMockingError::UnableToFetchAddressKeys.into()) };
let Ok(response) = response.text().await else { return Err(NovaXMockingError::UnableToFetchAddressKeys.into()) };
let Ok(response) = reqwest::get(url).await else { return Err(NovaXMockingError::UnableToFetchAddressKeys) };
let Ok(response) = response.text().await else { return Err(NovaXMockingError::UnableToFetchAddressKeys) };

let Ok(result) = serde_json::from_str::<AddressKeys>(&response) else { return Err(NovaXMockingError::UnableToParseAddressKeys.into()) };
let Ok(result) = serde_json::from_str::<AddressKeys>(&response) else { return Err(NovaXMockingError::UnableToParseAddressKeys) };

Ok(result)
}
Expand Down
58 changes: 37 additions & 21 deletions mocking/src/world/infos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl ScenarioWorldInfos {
.open(file_path)
.unwrap();

let Ok(result) = serde_json::from_reader::<_, ScenarioWorldInfosJson>(reader) else { return Err(NovaXMockingError::UnableToReadInfosFromFile.into()) };
let Ok(result) = serde_json::from_reader::<_, ScenarioWorldInfosJson>(reader) else { return Err(NovaXMockingError::UnableToReadInfosFromFile) };

Ok(result.into())
}
Expand Down Expand Up @@ -82,7 +82,7 @@ impl ScenarioWorldInfos {
pub async fn fetch(
gateway_url: &str,
addresses: &[Address]
) -> ScenarioWorldInfos {
) -> Result<ScenarioWorldInfos, NovaXMockingError> {
let (
accounts,
keys,
Expand All @@ -93,11 +93,13 @@ impl ScenarioWorldInfos {
get_addresses_balances(gateway_url, addresses)
).await;

ScenarioWorldInfos {
address_keys: keys,
address_balances: balances,
address_infos: accounts,
}
let infos = ScenarioWorldInfos {
address_keys: keys?,
address_balances: balances?,
address_infos: accounts?,
};

Ok(infos)
}

pub fn into_world<RegisterFunction>(self, register: RegisterFunction) -> ScenarioWorld
Expand Down Expand Up @@ -171,7 +173,6 @@ impl ScenarioWorldInfos {
}
}
}

}

set_state_accounts_step = set_state_accounts_step.put_account(&*encoded_contract_address_expr, account);
Expand All @@ -194,7 +195,7 @@ impl ScenarioWorldInfos {
}
}

async fn get_addresses_infos(gateway_url: &str, addresses: &[Address]) -> Vec<AccountInfos> {
async fn get_addresses_infos(gateway_url: &str, addresses: &[Address]) -> Result<Vec<AccountInfos>, NovaXMockingError> {
let mut accounts_futures = vec![];
for address in addresses {
accounts_futures.push(async {
Expand All @@ -203,12 +204,16 @@ async fn get_addresses_infos(gateway_url: &str, addresses: &[Address]) -> Vec<Ac
};

let accounts: Vec<Result<AccountInfos, NovaXError>> = join_all(accounts_futures).await;
accounts.into_iter()
.filter_map(|e| e.ok())
.collect()
let mut results = vec![];

for account in accounts {
results.push(account?)
}

Ok(results)
}

async fn get_addresses_keys(gateway_url: &str, addresses: &[Address]) -> HashMap<[u8; 32], AddressKeys> {
async fn get_addresses_keys(gateway_url: &str, addresses: &[Address]) -> Result<HashMap<[u8; 32], AddressKeys>, NovaXMockingError> {
let mut keys_futures = vec![];
for address in addresses {
keys_futures.push(async {
Expand All @@ -217,12 +222,17 @@ async fn get_addresses_keys(gateway_url: &str, addresses: &[Address]) -> HashMap
};

let keys: Vec<Result<([u8; 32], AddressKeys), NovaXMockingError>> = join_all(keys_futures).await;
keys.into_iter()
.filter_map(|e| e.ok())
.collect()
let mut results = HashMap::new();

for key in keys {
let key = key?;
results.insert(key.0, key.1);
}

Ok(results)
}

async fn get_addresses_balances(gateway_url: &str, addresses: &[Address]) -> HashMap<[u8; 32], Vec<EsdtTokenAmount>> {
async fn get_addresses_balances(gateway_url: &str, addresses: &[Address]) -> Result<HashMap<[u8; 32], Vec<EsdtTokenAmount>>, NovaXMockingError> {
let mut balances_futures = vec![];
for address in addresses {
balances_futures.push(async {
Expand All @@ -232,9 +242,13 @@ async fn get_addresses_balances(gateway_url: &str, addresses: &[Address]) -> Has
})
};

let balances: BalanceAsyncResults = join_all(balances_futures).await;
balances.into_iter()
.filter_map(|e| e.ok())
let balances_results: BalanceAsyncResults = join_all(balances_futures).await;
let mut balances = vec![];
for balance in balances_results {
balances.push(balance?)
}

let result = balances.into_iter()
.map(|e| {
let mut amounts: Vec<EsdtTokenAmount> = vec![];
for infos in e.1 {
Expand All @@ -248,7 +262,9 @@ async fn get_addresses_balances(gateway_url: &str, addresses: &[Address]) -> Has

(e.0, amounts)
})
.collect()
.collect();

Ok(result)
}

fn convert_hashmap_address_keys_to_bytes<T>(hashmap: HashMap<String, T>) -> HashMap<[u8; 32], T> {
Expand Down
2 changes: 1 addition & 1 deletion tester/core/tests/network_deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl BlockchainInteractor for MockInteractor {

response.new_deployed_address = Some(Address::from_bech32_string(NEW_CONTRACT).unwrap().into());
let step = sc_deploy_step.as_mut();
step.response = Some(response.clone());
step.response = Some(response);
}
}

Expand Down
2 changes: 1 addition & 1 deletion token/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "novax-token"
version = "0.0.1"
version = "0.0.2"
edition = "2021"
license = "GPL-3.0-only"
description = "The `novax-token` crate offers utilities for retrieving token information from the blockchain, such as querying address balances, token metadata, and other related operations. By encapsulating the logic for interacting with token-related blockchain features, `novax-token` simplifies the process of querying and managing tokens within decentralized applications, making it a valuable tool for developers working with blockchain tokens and assets."
Expand Down
3 changes: 2 additions & 1 deletion token/src/error/token.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};
use novax::errors::NovaXError;

#[derive(PartialEq, Debug)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub enum TokenError {
TokenNotFound { token_identifier: String },
UnknownErrorForToken { token_identifier: String },
Expand Down

0 comments on commit 86de2bb

Please sign in to comment.