Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
912 changes: 604 additions & 308 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ members = [
"contracts/benchmarks/mappers/vec-repeat/meta",
"contracts/benchmarks/large-storage",
"contracts/benchmarks/large-storage/meta",
"contracts/benchmarks/managed-map-benchmark",
"contracts/benchmarks/managed-map-benchmark/meta",
"contracts/benchmarks/managed-map-benchmark/interactor",
"contracts/benchmarks/str-repeat",
"contracts/benchmarks/str-repeat/meta",
"contracts/benchmarks/send-tx-repeat",
Expand Down
7 changes: 7 additions & 0 deletions contracts/benchmarks/managed-map-benchmark/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target/
*/target/

# The mxpy output
output
17 changes: 17 additions & 0 deletions contracts/benchmarks/managed-map-benchmark/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "managed-map-benchmark"
version = "0.0.0"
authors = ["Andrei Marinica <andrei.marinica@multiversx.com>"]
edition = "2021"
publish = false

[lib]
path = "src/mmap_benchmark.rs"

[dependencies.multiversx-sc]
version = "0.65.1"
path = "../../../framework/base"

[dev-dependencies.multiversx-sc-scenario]
version = "0.65.1"
path = "../../../framework/scenario"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Pem files are used for interactions, but shouldn't be committed
*.pem
31 changes: 31 additions & 0 deletions contracts/benchmarks/managed-map-benchmark/interactor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "rust-interact"
version = "0.0.0"
authors = ["you"]
edition = "2021"
publish = false

[[bin]]
name = "rust-interact"
path = "src/interactor_main.rs"

[lib]
path = "src/mm_interactor.rs"

[dependencies.managed-map-benchmark]
path = ".."

[dependencies.multiversx-sc-snippets]
version = "0.65.1"

[dependencies.multiversx-sc]
version = "0.65.1"

[dependencies]
clap = { version = "4.4.7", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.8.6"

[features]
chain-simulator-tests = []

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

chain_type = 'simulator'
gateway_uri = 'http://localhost:8085'

# chain_type = 'real'
# gateway_uri = 'https://testnet-gateway.multiversx.com'

# chain_type = 'real'
# gateway_uri = 'https://testnet-alb-fra.internal-gateway.multiversx.com'
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#![allow(unused)]

use serde::Deserialize;
use std::io::Read;

/// Config file
const CONFIG_FILE: &str = "config.toml";

#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ChainType {
Real,
Simulator,
}

/// Contract Interact configuration
#[derive(Debug, Deserialize)]
pub struct Config {
pub gateway_uri: String,
pub chain_type: ChainType,
}

impl Config {
// Deserializes config from file
pub fn new() -> Self {

Check warning on line 25 in contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs#L25

warning: you should consider adding a `Default` implementation for `Config` --> contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs:25:5 | 25 | / pub fn new() -> Self { 26 | | let mut file = std::fs::File::open(CONFIG_FILE).unwrap(); 27 | | let mut content = String::new(); 28 | | file.read_to_string(&mut content).unwrap(); 29 | | toml::from_str(&content).unwrap() 30 | | } | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default = note: `#[warn(clippy::new_without_default)]` on by default help: try adding this | 23 + impl Default for Config { 24 + fn default() -> Self { 25 + Self::new() 26 + } 27 + } |
Raw output
contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs:25:5:w:warning: you should consider adding a `Default` implementation for `Config`
  --> contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs:25:5
   |
25 | /     pub fn new() -> Self {
26 | |         let mut file = std::fs::File::open(CONFIG_FILE).unwrap();
27 | |         let mut content = String::new();
28 | |         file.read_to_string(&mut content).unwrap();
29 | |         toml::from_str(&content).unwrap()
30 | |     }
   | |_____^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
   = note: `#[warn(clippy::new_without_default)]` on by default
help: try adding this
   |
23 + impl Default for Config {
24 +     fn default() -> Self {
25 +         Self::new()
26 +     }
27 + }
   |


__END__

Check warning on line 25 in contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs#L25

warning: you should consider adding a `Default` implementation for `Config` --> contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs:25:5 | 25 | / pub fn new() -> Self { 26 | | let mut file = std::fs::File::open(CONFIG_FILE).unwrap(); 27 | | let mut content = String::new(); 28 | | file.read_to_string(&mut content).unwrap(); 29 | | toml::from_str(&content).unwrap() 30 | | } | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default = note: `#[warn(clippy::new_without_default)]` on by default help: try adding this | 23 + impl Default for Config { 24 + fn default() -> Self { 25 + Self::new() 26 + } 27 + } |
Raw output
contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs:25:5:w:warning: you should consider adding a `Default` implementation for `Config`
  --> contracts/benchmarks/managed-map-benchmark/interactor/src/config.rs:25:5
   |
25 | /     pub fn new() -> Self {
26 | |         let mut file = std::fs::File::open(CONFIG_FILE).unwrap();
27 | |         let mut content = String::new();
28 | |         file.read_to_string(&mut content).unwrap();
29 | |         toml::from_str(&content).unwrap()
30 | |     }
   | |_____^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
   = note: `#[warn(clippy::new_without_default)]` on by default
help: try adding this
   |
23 + impl Default for Config {
24 +     fn default() -> Self {
25 +         Self::new()
26 +     }
27 + }
   |


__END__
let mut file = std::fs::File::open(CONFIG_FILE).unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
toml::from_str(&content).unwrap()
}

pub fn chain_simulator_config() -> Self {
Config {
gateway_uri: "http://localhost:8085".to_owned(),
chain_type: ChainType::Simulator,
}
}

// Returns the gateway URI
pub fn gateway_uri(&self) -> &str {
&self.gateway_uri
}

// Returns if chain type is chain simulator
pub fn use_chain_simulator(&self) -> bool {
match self.chain_type {
ChainType::Real => false,
ChainType::Simulator => true,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use multiversx_sc_snippets::imports::*;
use rust_interact::managed_map_benchmark_cli;

#[tokio::main]
async fn main() {
managed_map_benchmark_cli().await;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#![allow(non_snake_case)]

pub mod config;
mod proxy;

use config::Config;
use multiversx_sc_snippets::imports::*;
use serde::{Deserialize, Serialize};
use std::{
io::{Read, Write},
path::Path,
};

const STATE_FILE: &str = "state.toml";

pub async fn managed_map_benchmark_cli() {
env_logger::init();

let mut args = std::env::args();
let _ = args.next();
let cmd = args.next().expect("at least one argument required");
let config = Config::new();
let mut interact = ContractInteract::new(config).await;
match cmd.as_str() {
"deploy" => interact.deploy().await,
"mm_get" => interact.mm_get().await,
"mm_contains" => interact.mm_contains().await,
"mm_remove" => interact.mm_remove().await,
_ => panic!("unknown command: {}", &cmd),
}
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct State {
contract_address: Option<Bech32Address>,
repeats: usize,
}

impl State {
// Deserializes state from file
pub fn load_state() -> Self {
if Path::new(STATE_FILE).exists() {
let mut file = std::fs::File::open(STATE_FILE).unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
toml::from_str(&content).unwrap()
} else {
Self::default()
}
}

/// Sets the contract address
pub fn set_address(&mut self, address: Bech32Address) {
self.contract_address = Some(address);
}

/// Returns the contract address
pub fn current_address(&self) -> &Bech32Address {
self.contract_address
.as_ref()
.expect("no known contract, deploy first")
}
}

impl Drop for State {
// Serializes state to file
fn drop(&mut self) {
let mut file = std::fs::File::create(STATE_FILE).unwrap();
file.write_all(toml::to_string(self).unwrap().as_bytes())
.unwrap();
}
}

pub struct ContractInteract {
interactor: Interactor,
wallet_address: Address,
contract_code: BytesValue,
state: State,
}

impl ContractInteract {
pub async fn new(config: Config) -> Self {
let mut interactor = Interactor::new(config.gateway_uri())
.await
.use_chain_simulator(config.use_chain_simulator());

interactor.set_current_dir_from_workspace("managed-map-benchmark");
let wallet_address = interactor.register_wallet(test_wallets::alice()).await;

// Useful in the chain simulator setting
// generate blocks until ESDTSystemSCAddress is enabled
interactor.generate_blocks_until_epoch(1).await.unwrap();

let contract_code = BytesValue::interpret_from(
"mxsc:../output/managed-map-benchmark.mxsc.json",
&InterpreterContext::default(),
);

ContractInteract {
interactor,
wallet_address,
contract_code,
state: State::load_state(),
}
}

pub async fn deploy(&mut self) {
let new_address = self
.interactor
.tx()
.from(&self.wallet_address)
.gas(30_000_000u64)
.typed(proxy::ManagedMapBenchmarkProxy)
.init()
.code(&self.contract_code)
.returns(ReturnsNewBech32Address)
.run()
.await;
self.state.set_address(new_address.clone());
println!("new address: {new_address}");
}

pub async fn mm_get(&mut self) {
let (result_value, gas_used) = self
.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_address())
.typed(proxy::ManagedMapBenchmarkProxy)
.mm_get("key0", self.state.repeats)
.returns(ReturnsResultAs::<String>::new())
.returns(ReturnsGasUsed)
.run()
.await;

println!("Result: {result_value}");
println!("Gas used: {gas_used}");
}

pub async fn mm_contains(&mut self) {
let (result_value, gas_used) = self
.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_address())
.typed(proxy::ManagedMapBenchmarkProxy)
.mm_contains("key0", self.state.repeats)
.returns(ReturnsResultUnmanaged)
.returns(ReturnsGasUsed)
.run()
.await;

println!("Result: {result_value}");
println!("Gas used: {gas_used}");
}

pub async fn mm_remove(&mut self) {
let gas_used = self
.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_address())
.gas(150_000_000u64)
.typed(proxy::ManagedMapBenchmarkProxy)
.mm_remove("key0", self.state.repeats)
.returns(ReturnsGasUsed)
.run()
.await;

println!("Gas used: {gas_used}");
}
}
Loading
Loading