Skip to content

Commit

Permalink
--wip--
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrylavrenov committed Mar 28, 2024
1 parent 05c4abc commit be9a89f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 52 deletions.
62 changes: 31 additions & 31 deletions frame/evm-system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,30 +146,35 @@ impl<T: Config> Pallet<T> {
}

/// Create an account.
pub fn create_account(who: &<T as Config>::AccountId) -> DispatchResult {
if Self::account_exists(who) {
return Err(Error::<T>::AccountAlreadyExist.into());
}

Account::<T>::insert(who.clone(), AccountInfo::<_, _>::default());
Self::on_created_account(who.clone());
Ok(())
pub fn create_account(
who: &<T as Config>::AccountId,
data: <T as Config>::AccountData,
) -> DispatchResult {
Account::<T>::mutate(who, |account| {
if account.data == <T as Config>::AccountData::default() {
account.data = data;
Self::on_created_account(who.clone());
Ok(())
} else {
Err(Error::<T>::AccountAlreadyExist.into())
}
})
}

/// Remove an account.
pub fn remove_account(who: &<T as Config>::AccountId) -> DispatchResult {
if !Self::account_exists(who) {
return Err(Error::<T>::AccountNotExist.into());
}

if Account::<T>::get(who).data != <T as Config>::AccountData::default() {
return Err(Error::<T>::AccountDataNotEmpty.into());
}

Account::<T>::remove(who);
Self::on_killed_account(who.clone());

Ok(())
Account::<T>::try_mutate_exists(who, |maybe_account| {
if let Some(account) = maybe_account.take() {
if account.data != <T as Config>::AccountData::default() {
Err(Error::<T>::AccountDataNotEmpty.into())
} else {
Self::on_killed_account(who.clone());
Ok(())
}
} else {
Err(Error::<T>::AccountNotExist.into())
}
})
}
}

Expand All @@ -182,28 +187,23 @@ impl<T: Config> StoredMap<<T as Config>::AccountId, <T as Config>::AccountData>
k: &<T as Config>::AccountId,
f: impl FnOnce(&mut Option<<T as Config>::AccountData>) -> Result<R, E>,
) -> Result<R, E> {
let account = Account::<T>::get(k);
let was_providing = account.data != <T as Config>::AccountData::default();

let mut maybe_account_data = if was_providing {
Some(account.data)
let (mut maybe_account_data, was_providing) = if Self::account_exists(k) {
(Some(Account::<T>::get(k).data), true)
} else {
None
(None, false)
};

let result = f(&mut maybe_account_data)?;

match (maybe_account_data, was_providing) {
(Some(data), false) => {
Account::<T>::mutate(k, |a| a.data = data);
Self::on_created_account(k.clone());
Self::create_account(k, data)?;
}
(Some(data), true) => {
Account::<T>::mutate(k, |a| a.data = data);
}
(None, true) => {
Account::<T>::remove(k);
Self::on_killed_account(k.clone());
Self::remove_account(k)?;
}
(None, false) => {
// Do nothing.
Expand All @@ -219,7 +219,7 @@ impl<T: Config> fp_evm::AccountProvider for Pallet<T> {
type Index = <T as Config>::Index;

fn create_account(who: &Self::AccountId) {
let _ = Self::create_account(who);
let _ = Self::create_account(who, <T as Config>::AccountData::default());
}

fn remove_account(who: &Self::AccountId) {
Expand Down
46 changes: 25 additions & 21 deletions frame/evm-system/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use sp_std::str::FromStr;

use frame_support::{assert_ok, assert_noop};
use frame_support::{assert_noop, assert_ok};
use mockall::predicate;
use sp_core::H160;

Expand All @@ -11,7 +11,7 @@ use crate::{mock::*, *};
/// This test verifies that creating account works in the happy path.
#[test]
fn create_account_works() {
new_test_ext().execute_with_ext(|_| {
new_test_ext().execute_with_ext(|_| {
// Prepare test data.
let account_id = H160::from_str("1000000000000000000000000000000000000001").unwrap();

Expand All @@ -26,17 +26,17 @@ fn create_account_works() {
on_new_account_ctx
.expect()
.once()
.with(
predicate::eq(account_id),
)
.with(predicate::eq(account_id))
.return_const(());

// Invoke the function under test.
assert_ok!(EvmSystem::create_account(&account_id));
assert_ok!(EvmSystem::create_account(&account_id, 10));

// Assert state changes.
assert!(EvmSystem::account_exists(&account_id));
System::assert_has_event(RuntimeEvent::EvmSystem(Event::NewAccount { account: account_id } ));
System::assert_has_event(RuntimeEvent::EvmSystem(Event::NewAccount {
account: account_id,
}));

// Assert mock invocations.
on_new_account_ctx.checkpoint();
Expand All @@ -46,20 +46,23 @@ fn create_account_works() {
/// This test verifies that creating account fails when the account already exists.
#[test]
fn create_account_fails() {
new_test_ext().execute_with(|| {
new_test_ext().execute_with(|| {
// Prepare test data.
let account_id = H160::from_str("1000000000000000000000000000000000000001").unwrap();
<Account<Test>>::insert(account_id.clone(), AccountInfo::<_, _>::default());
<Account<Test>>::insert(account_id.clone(), AccountInfo { nonce: 1, data: 7 });

// Invoke the function under test.
assert_noop!(EvmSystem::create_account(&account_id), Error::<Test>::AccountAlreadyExist);
assert_noop!(
EvmSystem::create_account(&account_id, 10),
Error::<Test>::AccountAlreadyExist
);
});
}

/// This test verifies that removing account works in the happy path.
#[test]
fn remove_account_works() {
new_test_ext().execute_with(|| {
new_test_ext().execute_with(|| {
// Prepare test data.
let account_id = H160::from_str("1000000000000000000000000000000000000001").unwrap();
<Account<Test>>::insert(account_id.clone(), AccountInfo::<_, _>::default());
Expand All @@ -72,17 +75,17 @@ fn remove_account_works() {
on_killed_account_ctx
.expect()
.once()
.with(
predicate::eq(account_id),
)
.with(predicate::eq(account_id))
.return_const(());

// Invoke the function under test.
assert_ok!(EvmSystem::remove_account(&account_id));

// Assert state changes.
assert!(!EvmSystem::account_exists(&account_id));
System::assert_has_event(RuntimeEvent::EvmSystem(Event::KilledAccount { account: account_id } ));
System::assert_has_event(RuntimeEvent::EvmSystem(Event::KilledAccount {
account: account_id,
}));

// Assert mock invocations.
on_killed_account_ctx.checkpoint();
Expand All @@ -92,19 +95,22 @@ fn remove_account_works() {
/// This test verifies that removing account fails when the account doesn't exist.
#[test]
fn remove_account_fails() {
new_test_ext().execute_with(|| {
new_test_ext().execute_with(|| {
// Prepare test data.
let account_id = H160::from_str("1000000000000000000000000000000000000001").unwrap();

// Invoke the function under test.
assert_noop!(EvmSystem::remove_account(&account_id), Error::<Test>::AccountNotExist);
assert_noop!(
EvmSystem::remove_account(&account_id),
Error::<Test>::AccountNotExist
);
});
}

/// This test verifies that incrementing account nonce works in the happy path.
#[test]
fn inc_account_nonce_works() {
new_test_ext().execute_with(|| {
new_test_ext().execute_with(|| {
// Prepare test data.
let account_id = H160::from_str("1000000000000000000000000000000000000001").unwrap();

Expand Down Expand Up @@ -199,9 +205,7 @@ fn try_mutate_exists_account_removed() {
new_test_ext().execute_with(|| {
// Prepare test data.
let account_id = H160::from_str("1000000000000000000000000000000000000001").unwrap();
let nonce = 1;
let data = 1;
<Account<Test>>::insert(account_id.clone(), AccountInfo { nonce, data });
<Account<Test>>::insert(account_id.clone(), AccountInfo { nonce: 1, data: 0 });

// Check test preconditions.
assert!(EvmSystem::account_exists(&account_id));
Expand Down
5 changes: 5 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[toolchain]
channel = "nightly-2023-06-08"
components = ["rustfmt", "clippy"]
targets = ["wasm32-unknown-unknown"]
profile = "minimal"

0 comments on commit be9a89f

Please sign in to comment.