diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs index 827d00ed3..327e27cab 100644 --- a/src/test_utils/mod.rs +++ b/src/test_utils/mod.rs @@ -233,6 +233,16 @@ impl AuroraRunner { trie.insert(ft_key, ft_value.try_to_vec().unwrap()); } + pub fn submit_with_signer LegacyEthTransaction>( + &mut self, + signer: &mut Signer, + make_tx: F, + ) -> Result { + let nonce = signer.use_nonce(); + let tx = make_tx(nonce.into()); + self.submit_transaction(&signer.secret_key, tx) + } + pub fn submit_transaction( &mut self, account: &SecretKey, @@ -380,6 +390,17 @@ pub(crate) fn deploy_evm() -> AuroraRunner { runner } +pub(crate) fn transfer(to: Address, amount: types::Wei, nonce: U256) -> LegacyEthTransaction { + LegacyEthTransaction { + nonce, + gas_price: Default::default(), + gas: u64::MAX.into(), + to: Some(to), + value: amount, + data: Vec::new(), + } +} + pub(crate) fn create_eth_transaction( to: Option
, value: types::Wei, diff --git a/src/tests/erc20.rs b/src/tests/erc20.rs index 9abc36e84..95dd88bc2 100644 --- a/src/tests/erc20.rs +++ b/src/tests/erc20.rs @@ -2,6 +2,7 @@ use crate::prelude::{Address, U256}; use crate::test_utils::{ self, erc20::{ERC20Constructor, ERC20}, + Signer, }; use crate::types::Wei; use bstr::ByteSlice; @@ -13,69 +14,53 @@ const TRANSFER_AMOUNT: u64 = 67; #[test] fn erc20_mint() { - let (mut runner, source_account, dest_address, contract) = initialize_erc20(); + let (mut runner, mut source_account, dest_address, contract) = initialize_erc20(); // Validate pre-state assert_eq!( U256::zero(), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 1).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); // Do mint transaction let mint_amount: u64 = 10; - let mint_tx = contract.mint(dest_address, mint_amount.into(), (INITIAL_NONCE + 2).into()); - let outcome = runner.submit_transaction(&source_account, mint_tx); + let outcome = runner.submit_with_signer(&mut source_account, |nonce| { + contract.mint(dest_address, mint_amount.into(), nonce) + }); assert!(outcome.is_ok()); // Validate post-state assert_eq!( U256::from(mint_amount), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 3).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); } #[test] fn erc20_mint_out_of_gas() { - let (mut runner, source_account, dest_address, contract) = initialize_erc20(); + let (mut runner, mut source_account, dest_address, contract) = initialize_erc20(); // Validate pre-state assert_eq!( U256::zero(), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 1).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); // Try mint transaction let mint_amount: u64 = rand::random(); - let mut mint_tx = contract.mint(dest_address, mint_amount.into(), (INITIAL_NONCE + 2).into()); + let nonce = source_account.use_nonce(); + let mut mint_tx = contract.mint(dest_address, mint_amount.into(), nonce.into()); // not enough gas to cover intrinsic cost mint_tx.gas = (mint_tx.intrinsic_gas(&evm::Config::istanbul()).unwrap() - 1).into(); - let outcome = runner.submit_transaction(&source_account, mint_tx.clone()); + let outcome = runner.submit_transaction(&source_account.secret_key, mint_tx.clone()); let error = outcome.unwrap_err(); let error_message = format!("{:?}", error); assert!(error_message.contains("ERR_INTRINSIC_GAS")); // not enough gas to complete transaction mint_tx.gas = U256::from(67_000); - let outcome = runner.submit_transaction(&source_account, mint_tx); + let outcome = runner.submit_transaction(&source_account.secret_key, mint_tx); let error = outcome.unwrap_err(); let error_message = format!("{:?}", error); assert!(error_message.contains("ERR_OUT_OF_GAS")); @@ -83,7 +68,7 @@ fn erc20_mint_out_of_gas() { // Validate post-state test_utils::validate_address_balance_and_nonce( &runner, - test_utils::address_from_secret_key(&source_account), + test_utils::address_from_secret_key(&source_account.secret_key), Wei::new_u64(INITIAL_BALANCE), (INITIAL_NONCE + 3).into(), ); @@ -91,116 +76,68 @@ fn erc20_mint_out_of_gas() { #[test] fn erc20_transfer_success() { - let (mut runner, source_account, dest_address, contract) = initialize_erc20(); - let source_address = test_utils::address_from_secret_key(&source_account); + let (mut runner, mut source_account, dest_address, contract) = initialize_erc20(); + let source_address = test_utils::address_from_secret_key(&source_account.secret_key); - let mint_tx = contract.mint( - source_address, - INITIAL_BALANCE.into(), - (INITIAL_NONCE + 1).into(), - ); - let outcome = runner.submit_transaction(&source_account, mint_tx); + let outcome = runner.submit_with_signer(&mut source_account, |nonce| { + contract.mint(source_address, INITIAL_BALANCE.into(), nonce) + }); assert!(outcome.is_ok()); // Validate pre-state assert_eq!( U256::from(INITIAL_BALANCE), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 2).into(), - source_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, source_address, &contract) ); assert_eq!( U256::zero(), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 3).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); // Do transfer - let transfer_tx = contract.transfer( - dest_address, - TRANSFER_AMOUNT.into(), - (INITIAL_NONCE + 4).into(), - ); let outcome = runner - .submit_transaction(&source_account, transfer_tx) + .submit_with_signer(&mut source_account, |nonce| { + contract.transfer(dest_address, TRANSFER_AMOUNT.into(), nonce) + }) .unwrap(); assert!(outcome.status); // Validate post-state assert_eq!( U256::from(INITIAL_BALANCE - TRANSFER_AMOUNT), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 5).into(), - source_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, source_address, &contract) ); assert_eq!( U256::from(TRANSFER_AMOUNT), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 6).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); } #[test] fn erc20_transfer_insufficient_balance() { - let (mut runner, source_account, dest_address, contract) = initialize_erc20(); - let source_address = test_utils::address_from_secret_key(&source_account); + let (mut runner, mut source_account, dest_address, contract) = initialize_erc20(); + let source_address = test_utils::address_from_secret_key(&source_account.secret_key); - let mint_tx = contract.mint( - source_address, - INITIAL_BALANCE.into(), - (INITIAL_NONCE + 1).into(), - ); - let outcome = runner.submit_transaction(&source_account, mint_tx); + let outcome = runner.submit_with_signer(&mut source_account, |nonce| { + contract.mint(source_address, INITIAL_BALANCE.into(), nonce) + }); assert!(outcome.is_ok()); // Validate pre-state assert_eq!( U256::from(INITIAL_BALANCE), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 2).into(), - source_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, source_address, &contract) ); assert_eq!( U256::zero(), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 3).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); // Do transfer - let transfer_tx = contract.transfer( - dest_address, - (2 * INITIAL_BALANCE).into(), - (INITIAL_NONCE + 4).into(), - ); let outcome = runner - .submit_transaction(&source_account, transfer_tx) + .submit_with_signer(&mut source_account, |nonce| { + contract.transfer(dest_address, (2 * INITIAL_BALANCE).into(), nonce) + }) .unwrap(); assert!(!outcome.status); // status == false means execution error let message = parse_erc20_error_message(&outcome.result); @@ -209,23 +146,11 @@ fn erc20_transfer_insufficient_balance() { // Validate post-state assert_eq!( U256::from(INITIAL_BALANCE), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 5).into(), - source_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, source_address, &contract) ); assert_eq!( U256::zero(), - get_address_erc20_balance( - &mut runner, - &source_account, - (INITIAL_NONCE + 6).into(), - dest_address, - &contract - ) + get_address_erc20_balance(&mut runner, &mut source_account, dest_address, &contract) ); } @@ -273,13 +198,11 @@ fn deploy_erc_20_out_of_gas() { fn get_address_erc20_balance( runner: &mut test_utils::AuroraRunner, - signing_account: &SecretKey, - nonce: U256, + signer: &mut Signer, address: Address, contract: &ERC20, ) -> U256 { - let balance_tx = contract.balance_of(address, nonce); - let outcome = runner.submit_transaction(signing_account, balance_tx); + let outcome = runner.submit_with_signer(signer, |nonce| contract.balance_of(address, nonce)); assert!(outcome.is_ok()); U256::from_big_endian(&outcome.unwrap().result) } @@ -291,7 +214,7 @@ fn parse_erc20_error_message(result: &[u8]) -> String { String::from_utf8(result[start_index..end_index].to_vec()).unwrap() } -fn initialize_erc20() -> (test_utils::AuroraRunner, SecretKey, Address, ERC20) { +fn initialize_erc20() -> (test_utils::AuroraRunner, Signer, Address, ERC20) { // set up Aurora runner and accounts let mut runner = test_utils::deploy_evm(); let mut rng = rand::thread_rng(); @@ -304,12 +227,15 @@ fn initialize_erc20() -> (test_utils::AuroraRunner, SecretKey, Address, ERC20) { ); let dest_address = test_utils::address_from_secret_key(&SecretKey::random(&mut rng)); + let mut signer = Signer::new(source_account); + signer.nonce = INITIAL_NONCE; + let nonce = signer.use_nonce(); let constructor = ERC20Constructor::load(); let contract = ERC20(runner.deploy_contract( - &source_account, - |c| c.deploy("TestToken", "TEST", INITIAL_NONCE.into()), + &signer.secret_key, + |c| c.deploy("TestToken", "TEST", nonce.into()), constructor, )); - (runner, source_account, dest_address, contract) + (runner, signer, dest_address, contract) } diff --git a/src/tests/sanity.rs b/src/tests/sanity.rs index 0011edeed..b0faa2e74 100644 --- a/src/tests/sanity.rs +++ b/src/tests/sanity.rs @@ -1,6 +1,5 @@ use crate::prelude::Address; use crate::test_utils; -use crate::transaction::LegacyEthTransaction; use crate::types::{Wei, ERC20_MINT_SELECTOR}; use secp256k1::SecretKey; @@ -13,17 +12,8 @@ const TRANSFER_AMOUNT: Wei = Wei::new_u64(123); #[test] fn test_eth_transfer_success() { // set up Aurora runner and accounts - let (mut runner, source_account, dest_address) = initialize_transfer(); - let source_address = test_utils::address_from_secret_key(&source_account); - let transaction = test_utils::create_eth_transaction( - Some(dest_address), - TRANSFER_AMOUNT.into(), - vec![], - Some(runner.chain_id), - &source_account, - ); - let input = rlp::encode(&transaction).to_vec(); - let calling_account_id = "some-account.near".to_string(); + let (mut runner, mut source_account, dest_address) = initialize_transfer(); + let source_address = test_utils::address_from_secret_key(&source_account.secret_key); // validate pre-state test_utils::validate_address_balance_and_nonce( @@ -35,8 +25,11 @@ fn test_eth_transfer_success() { test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into()); // perform transfer - let (_, maybe_err) = runner.call(test_utils::SUBMIT, calling_account_id, input); - assert!(maybe_err.is_none()); + runner + .submit_with_signer(&mut source_account, |nonce| { + test_utils::transfer(dest_address, TRANSFER_AMOUNT, nonce) + }) + .unwrap(); // validate post-state test_utils::validate_address_balance_and_nonce( @@ -56,17 +49,8 @@ fn test_eth_transfer_success() { /// Tests the case where the transfer amount is larger than the address balance #[test] fn test_eth_transfer_insufficient_balance() { - let (mut runner, source_account, dest_address) = initialize_transfer(); - let source_address = test_utils::address_from_secret_key(&source_account); - let transaction = test_utils::create_eth_transaction( - Some(dest_address), - INITIAL_BALANCE + INITIAL_BALANCE, // trying to transfer more than we have - vec![], - Some(runner.chain_id), - &source_account, - ); - let input = rlp::encode(&transaction).to_vec(); - let calling_account_id = "some-account.near".to_string(); + let (mut runner, mut source_account, dest_address) = initialize_transfer(); + let source_address = test_utils::address_from_secret_key(&source_account.secret_key); // validate pre-state test_utils::validate_address_balance_and_nonce( @@ -78,8 +62,13 @@ fn test_eth_transfer_insufficient_balance() { test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into()); // attempt transfer - let (_, maybe_err) = runner.call(test_utils::SUBMIT, calling_account_id, input); - let error_message = format!("{:?}", maybe_err); + let err = runner + .submit_with_signer(&mut source_account, |nonce| { + // try to transfer more than we have + test_utils::transfer(dest_address, INITIAL_BALANCE + INITIAL_BALANCE, nonce) + }) + .unwrap_err(); + let error_message = format!("{:?}", err); assert!(error_message.contains("ERR_OUT_OF_FUND")); // validate post-state @@ -96,20 +85,8 @@ fn test_eth_transfer_insufficient_balance() { /// Tests the case where the nonce on the transaction does not match the address #[test] fn test_eth_transfer_incorrect_nonce() { - let (mut runner, source_account, dest_address) = initialize_transfer(); - let source_address = test_utils::address_from_secret_key(&source_account); - let transaction = LegacyEthTransaction { - nonce: (INITIAL_NONCE + 1).into(), - gas_price: Default::default(), - gas: Default::default(), - to: Some(dest_address), - value: TRANSFER_AMOUNT.into(), - data: vec![], - }; - let transaction = - test_utils::sign_transaction(transaction, Some(runner.chain_id), &source_account); - let input = rlp::encode(&transaction).to_vec(); - let calling_account_id = "some-account.near".to_string(); + let (mut runner, mut source_account, dest_address) = initialize_transfer(); + let source_address = test_utils::address_from_secret_key(&source_account.secret_key); // validate pre-state test_utils::validate_address_balance_and_nonce( @@ -121,8 +98,13 @@ fn test_eth_transfer_incorrect_nonce() { test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into()); // attempt transfer - let (_, maybe_err) = runner.call(test_utils::SUBMIT, calling_account_id, input); - let error_message = format!("{:?}", maybe_err); + let err = runner + .submit_with_signer(&mut source_account, |nonce| { + // creating transaction with incorrect nonce + test_utils::transfer(dest_address, TRANSFER_AMOUNT, nonce + 1) + }) + .unwrap_err(); + let error_message = format!("{:?}", err); assert!(error_message.contains("ERR_INCORRECT_NONCE")); // validate post-state (which is the same as pre-state in this case) @@ -137,20 +119,13 @@ fn test_eth_transfer_incorrect_nonce() { #[test] fn test_eth_transfer_not_enough_gas() { - let (mut runner, source_account, dest_address) = initialize_transfer(); - let source_address = test_utils::address_from_secret_key(&source_account); - let transaction = LegacyEthTransaction { - nonce: INITIAL_NONCE.into(), - gas_price: Default::default(), - gas: 10_000.into(), // this is not enough gas - to: Some(dest_address), - value: TRANSFER_AMOUNT.into(), - data: vec![], + let (mut runner, mut source_account, dest_address) = initialize_transfer(); + let source_address = test_utils::address_from_secret_key(&source_account.secret_key); + let transaction = |nonce| { + let mut tx = test_utils::transfer(dest_address, TRANSFER_AMOUNT, nonce); + tx.gas = 10_000.into(); // this is not enough gas + tx }; - let transaction = - test_utils::sign_transaction(transaction, Some(runner.chain_id), &source_account); - let input = rlp::encode(&transaction).to_vec(); - let calling_account_id = "some-account.near".to_string(); // validate pre-state test_utils::validate_address_balance_and_nonce( @@ -162,8 +137,10 @@ fn test_eth_transfer_not_enough_gas() { test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into()); // attempt transfer - let (_, maybe_err) = runner.call(test_utils::SUBMIT, calling_account_id, input); - let error_message = format!("{:?}", maybe_err); + let err = runner + .submit_with_signer(&mut source_account, transaction) + .unwrap_err(); + let error_message = format!("{:?}", err); assert!(error_message.contains("ERR_INTRINSIC_GAS")); // validate post-state (which is the same as pre-state in this case) @@ -176,7 +153,7 @@ fn test_eth_transfer_not_enough_gas() { test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into()); } -fn initialize_transfer() -> (test_utils::AuroraRunner, SecretKey, Address) { +fn initialize_transfer() -> (test_utils::AuroraRunner, test_utils::Signer, Address) { // set up Aurora runner and accounts let mut runner = test_utils::deploy_evm(); let mut rng = rand::thread_rng(); @@ -184,8 +161,10 @@ fn initialize_transfer() -> (test_utils::AuroraRunner, SecretKey, Address) { let source_address = test_utils::address_from_secret_key(&source_account); runner.create_address(source_address, INITIAL_BALANCE, INITIAL_NONCE.into()); let dest_address = test_utils::address_from_secret_key(&SecretKey::random(&mut rng)); + let mut signer = test_utils::Signer::new(source_account); + signer.nonce = INITIAL_NONCE; - (runner, source_account, dest_address) + (runner, signer, dest_address) } use sha3::Digest;