Skip to content

Commit

Permalink
find first token identifier matching ticker and add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ovstinga committed Jul 4, 2023
1 parent 0fc5ee8 commit a30201d
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 28 deletions.
81 changes: 68 additions & 13 deletions vm/src/tx_execution/system_sc/system_sc_issue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use num_bigint::BigUint;

use crate::{
crypto_functions::keccak256,
tx_mock::{TxContext, TxResult},
tx_mock::{TxCache, TxContext, TxInput, TxResult},
types::top_decode_u64,
};

Expand All @@ -22,13 +22,21 @@ pub fn issue(tx_context: TxContext) -> (TxContext, TxResult) {
let _decimals = top_decode_u64(tx_input.args[3].clone().as_ref()) as u32;

let mut new_token_identifiers = tx_cache.get_new_token_identifiers();
let token_identifier = if let Some(ti) = new_token_identifiers.pop_front() {
println!("\n\ntoken_identifier: {}\n\n", ti);

let token_identifier = if let Some((i, ti)) =
first_token_identifier_with_ticker(&new_token_identifiers, &ticker)
{
new_token_identifiers.remove(i);
ti.into_bytes()
} else {
generate_token_identifier_from_ticker(tx_input, tx_cache, &ticker)
};

println!(
"\n\ngenerated new token_identifier: {}\n\n",
std::str::from_utf8(&token_identifier).unwrap()
);

tx_cache.with_account_mut(&tx_input.from, |account| {
account.esdt.issue_token(&token_identifier);
});
Expand All @@ -42,12 +50,12 @@ pub fn issue(tx_context: TxContext) -> (TxContext, TxResult) {
(tx_context, tx_result)
}

/// Issues a semi-fungible token.
/// Issues a new semi-fungible token.
pub fn issue_semi_fungible(tx_context: TxContext) -> (TxContext, TxResult) {
issue_non_fungible(tx_context)
}

/// Issues a non-fungible token.
/// Issues a new non-fungible token.
pub fn issue_non_fungible(tx_context: TxContext) -> (TxContext, TxResult) {
let tx_input = tx_context.input_ref();
let tx_cache = tx_context.blockchain_cache();
Expand All @@ -61,8 +69,11 @@ pub fn issue_non_fungible(tx_context: TxContext) -> (TxContext, TxResult) {
let ticker = tx_input.args[1].clone();

let mut new_token_identifiers = tx_cache.get_new_token_identifiers();
let token_identifier = if let Some(ti) = new_token_identifiers.pop_front() {
println!("\n\ntoken_identifier: {}\n\n", ti);

let token_identifier = if let Some((i, ti)) =
first_token_identifier_with_ticker(&new_token_identifiers, &ticker)
{
new_token_identifiers.remove(i);
ti.into_bytes()
} else {
generate_token_identifier_from_ticker(tx_input, tx_cache, &ticker)
Expand All @@ -81,9 +92,27 @@ pub fn issue_non_fungible(tx_context: TxContext) -> (TxContext, TxResult) {
(tx_context, tx_result)
}

fn first_token_identifier_with_ticker(
token_identifiers: &Vec<String>,

Check warning on line 96 in vm/src/tx_execution/system_sc/system_sc_issue.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/tx_execution/system_sc/system_sc_issue.rs#L96

warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do --> vm/src/tx_execution/system_sc/system_sc_issue.rs:96:24 | 96 | token_identifiers: &Vec<String>, | ^^^^^^^^^^^^ help: change this to: `&[String]` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg = note: `#[warn(clippy::ptr_arg)]` on by default
Raw output
vm/src/tx_execution/system_sc/system_sc_issue.rs:96:24:w:warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
  --> vm/src/tx_execution/system_sc/system_sc_issue.rs:96:24
   |
96 |     token_identifiers: &Vec<String>,
   |                        ^^^^^^^^^^^^ help: change this to: `&[String]`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
   = note: `#[warn(clippy::ptr_arg)]` on by default


__END__

Check warning on line 96 in vm/src/tx_execution/system_sc/system_sc_issue.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/tx_execution/system_sc/system_sc_issue.rs#L96

warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do --> vm/src/tx_execution/system_sc/system_sc_issue.rs:96:24 | 96 | token_identifiers: &Vec<String>, | ^^^^^^^^^^^^ help: change this to: `&[String]` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg = note: `#[warn(clippy::ptr_arg)]` on by default
Raw output
vm/src/tx_execution/system_sc/system_sc_issue.rs:96:24:w:warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
  --> vm/src/tx_execution/system_sc/system_sc_issue.rs:96:24
   |
96 |     token_identifiers: &Vec<String>,
   |                        ^^^^^^^^^^^^ help: change this to: `&[String]`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
   = note: `#[warn(clippy::ptr_arg)]` on by default


__END__
ticker: &[u8],
) -> Option<(usize, String)> {
let extract_ticker =
|ti: &String| -> String { ti.split("-").map(|x| x.to_string()).next().unwrap() };

Check warning on line 100 in vm/src/tx_execution/system_sc/system_sc_issue.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/tx_execution/system_sc/system_sc_issue.rs#L100

warning: single-character string constant used as pattern --> vm/src/tx_execution/system_sc/system_sc_issue.rs:100:44 | 100 | |ti: &String| -> String { ti.split("-").map(|x| x.to_string()).next().unwrap() }; | ^^^ help: try using a `char` instead: `'-'` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern = note: `#[warn(clippy::single_char_pattern)]` on by default
Raw output
vm/src/tx_execution/system_sc/system_sc_issue.rs:100:44:w:warning: single-character string constant used as pattern
   --> vm/src/tx_execution/system_sc/system_sc_issue.rs:100:44
    |
100 |         |ti: &String| -> String { ti.split("-").map(|x| x.to_string()).next().unwrap() };
    |                                            ^^^ help: try using a `char` instead: `'-'`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
    = note: `#[warn(clippy::single_char_pattern)]` on by default


__END__

Check warning on line 100 in vm/src/tx_execution/system_sc/system_sc_issue.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/tx_execution/system_sc/system_sc_issue.rs#L100

warning: single-character string constant used as pattern --> vm/src/tx_execution/system_sc/system_sc_issue.rs:100:44 | 100 | |ti: &String| -> String { ti.split("-").map(|x| x.to_string()).next().unwrap() }; | ^^^ help: try using a `char` instead: `'-'` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern = note: `#[warn(clippy::single_char_pattern)]` on by default
Raw output
vm/src/tx_execution/system_sc/system_sc_issue.rs:100:44:w:warning: single-character string constant used as pattern
   --> vm/src/tx_execution/system_sc/system_sc_issue.rs:100:44
    |
100 |         |ti: &String| -> String { ti.split("-").map(|x| x.to_string()).next().unwrap() };
    |                                            ^^^ help: try using a `char` instead: `'-'`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
    = note: `#[warn(clippy::single_char_pattern)]` on by default


__END__

let position = token_identifiers
.iter()
.position(|x| extract_ticker(x).as_bytes() == ticker);

if let Some(i) = position {

Check warning on line 106 in vm/src/tx_execution/system_sc/system_sc_issue.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/tx_execution/system_sc/system_sc_issue.rs#L106

warning: manual implementation of `Option::map` --> vm/src/tx_execution/system_sc/system_sc_issue.rs:106:5 | 106 | / if let Some(i) = position { 107 | | Some((i, token_identifiers[i].clone())) 108 | | } else { 109 | | None 110 | | } | |_____^ help: try this: `position.map(|i| (i, token_identifiers[i].clone()))` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_map = note: `#[warn(clippy::manual_map)]` on by default
Raw output
vm/src/tx_execution/system_sc/system_sc_issue.rs:106:5:w:warning: manual implementation of `Option::map`
   --> vm/src/tx_execution/system_sc/system_sc_issue.rs:106:5
    |
106 | /     if let Some(i) = position {
107 | |         Some((i, token_identifiers[i].clone()))
108 | |     } else {
109 | |         None
110 | |     }
    | |_____^ help: try this: `position.map(|i| (i, token_identifiers[i].clone()))`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
    = note: `#[warn(clippy::manual_map)]` on by default


__END__

Check warning on line 106 in vm/src/tx_execution/system_sc/system_sc_issue.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/tx_execution/system_sc/system_sc_issue.rs#L106

warning: manual implementation of `Option::map` --> vm/src/tx_execution/system_sc/system_sc_issue.rs:106:5 | 106 | / if let Some(i) = position { 107 | | Some((i, token_identifiers[i].clone())) 108 | | } else { 109 | | None 110 | | } | |_____^ help: try this: `position.map(|i| (i, token_identifiers[i].clone()))` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_map = note: `#[warn(clippy::manual_map)]` on by default
Raw output
vm/src/tx_execution/system_sc/system_sc_issue.rs:106:5:w:warning: manual implementation of `Option::map`
   --> vm/src/tx_execution/system_sc/system_sc_issue.rs:106:5
    |
106 | /     if let Some(i) = position {
107 | |         Some((i, token_identifiers[i].clone()))
108 | |     } else {
109 | |         None
110 | |     }
    | |_____^ help: try this: `position.map(|i| (i, token_identifiers[i].clone()))`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
    = note: `#[warn(clippy::manual_map)]` on by default


__END__
Some((i, token_identifiers[i].clone()))
} else {
None
}
}

fn generate_token_identifier_from_ticker(
tx_input: &crate::tx_mock::TxInput,
tx_cache: &crate::tx_mock::TxCache,
tx_input: &TxInput,
tx_cache: &TxCache,
ticker: &[u8],
) -> Vec<u8> {
let new_random_base = [
Expand All @@ -104,10 +133,36 @@ fn generate_token_identifier_from_ticker(
hex::encode(new_random_for_ticker).as_bytes(),
]
.concat();
println!(
"\n\ngenerated new token_identifier: {}\n\n",
std::str::from_utf8(&token_identifier).unwrap()
);

token_identifier
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_first_token_identifier_with_ticker_ok() {
let ticker = String::from("BBBB").into_bytes();
let new_token_indetifiers = vec![
"AAAA-0123".to_string(),
"BBBB-4567".to_string(),
"BBBB-0123".to_string(),
"CCCC-4567".to_string(),
];

let ti = first_token_identifier_with_ticker(&new_token_indetifiers, &ticker);
let expected = b"BBBB-4567".as_slice();
assert_eq!(expected, ti.unwrap().1.into_bytes());
}

#[test]
fn test_first_token_identifier_with_ticker_is_none() {
let ticker = String::from("BBBB").into_bytes();
let new_token_indetifiers = vec!["AAAA-0123".to_string()];

let i = first_token_identifier_with_ticker(&new_token_indetifiers, &ticker);
let expected = None;
assert_eq!(expected, i);
}
}
10 changes: 5 additions & 5 deletions vm/src/tx_mock/tx_cache.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
cell::{Ref, RefCell},
collections::{HashMap, VecDeque},
collections::HashMap,
fmt,
rc::Rc,
};
Expand All @@ -16,7 +16,7 @@ use super::TxCacheSource;
pub struct TxCache {
source_ref: Rc<dyn TxCacheSource>,
pub(super) accounts: RefCell<HashMap<VMAddress, AccountData>>,
pub(super) new_token_identifiers: RefCell<Option<VecDeque<String>>>,
pub(super) new_token_identifiers: RefCell<Option<Vec<String>>>,
}

impl fmt::Debug for TxCache {
Expand Down Expand Up @@ -99,11 +99,11 @@ impl TxCache {
})
}

pub fn get_new_token_identifiers(&self) -> VecDeque<String> {
pub fn get_new_token_identifiers(&self) -> Vec<String> {
self.blockchain_ref().get_new_token_identifiers()
}

pub fn set_new_token_identifiers(&self, token_identifiers: VecDeque<String>) {
pub fn set_new_token_identifiers(&self, token_identifiers: Vec<String>) {
*self.new_token_identifiers.borrow_mut() = Some(token_identifiers);
}

Expand All @@ -123,7 +123,7 @@ impl TxCache {

pub struct BlockchainUpdate {
accounts: HashMap<VMAddress, AccountData>,
new_token_identifiers: Option<VecDeque<String>>,
new_token_identifiers: Option<Vec<String>>,
}

impl BlockchainUpdate {
Expand Down
16 changes: 6 additions & 10 deletions vm/src/world_mock/blockchain_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ use crate::{
use multiversx_chain_vm_executor::Executor;
use num_bigint::BigUint;
use num_traits::Zero;
use std::{
collections::{HashMap, VecDeque},
fmt::Debug,
rc::Rc,
};
use std::{collections::HashMap, fmt::Debug, rc::Rc};

use super::{AccountData, BlockInfo, FailingExecutor};

Expand All @@ -20,7 +16,7 @@ pub struct BlockchainMock {
pub accounts: HashMap<VMAddress, AccountData>,
pub builtin_functions: Rc<BuiltinFunctionMap>,
pub new_addresses: HashMap<(VMAddress, u64), VMAddress>,
pub new_token_identifiers: VecDeque<String>,
pub new_token_identifiers: Vec<String>,
pub previous_block_info: BlockInfo,
pub current_block_info: BlockInfo,
pub executor: Box<dyn Executor>,
Expand All @@ -32,22 +28,22 @@ impl BlockchainMock {
accounts: HashMap::new(),
builtin_functions: Rc::new(init_builtin_functions()),
new_addresses: HashMap::new(),
new_token_identifiers: VecDeque::new(),
new_token_identifiers: Vec::new(),
previous_block_info: BlockInfo::new(),
current_block_info: BlockInfo::new(),
executor,
}
}

pub fn put_new_token_identifier(&mut self, token_identifier: String) {
self.new_token_identifiers.push_back(token_identifier)
self.new_token_identifiers.push(token_identifier)
}

pub fn get_new_token_identifiers(&self) -> VecDeque<String> {
pub fn get_new_token_identifiers(&self) -> Vec<String> {
self.new_token_identifiers.clone()
}

pub fn update_new_token_identifiers(&mut self, token_identifiers: VecDeque<String>) {
pub fn update_new_token_identifiers(&mut self, token_identifiers: Vec<String>) {
self.new_token_identifiers = token_identifiers;
}

Expand Down

0 comments on commit a30201d

Please sign in to comment.