Skip to content

Commit

Permalink
Move pallet-evm-balances and pallet-evm-system from frontier, pre…
Browse files Browse the repository at this point in the history
…serving history (#1429)

* Sovereign accounts and EVM system layer (#94) (#99)

* Sovereign accounts and EVM system layer (#94)

* Sovereign accounts and EVM system layer (#86)

* Frame evm system (#62)

* Add initial impl of evm-system

* Check account existence

* Improve creation account logic

* Add new line

* Add default implementations

* Add mock

* Use DispatchResult instead of custom enums

* Basic create account tests

* Add simple tests with remove account and nonce update

* Remove default implementations for OnNewAccount and OnKilledAccount

* Add mock objects for OnNewAccount and OnKilledAccount

* Use mock logic in tests

* Some tests improvements

* Add docs to tests

* Check events in tests

* Add default implementation for OnNewAccount and OnKilledAccount for empty tuple (#63)

* Implement StoredMap for EvmSystem (#64)

* Add try-runtime feature into `pallet-evm-system` (#67)

Add try-runtime feature at pallet-evm-system

* Use `sp_std` library to add FromStr trait for tests at `pallet-evm-system` (#68)

Use sp_std library to add FromStr trait for tests at pallet-evm-system

* Rename FullAccount into Account at `pallet-evm-system` (#69)

Rename FullAccount into Account at pallet-evm-system

* Fix `try_mutate_exists` implementation and add tests to check it (#70)

* Fix try_mutate_exists logic

* Add tests

* Fix AccountData type at mock

* Remove redundant mock expectations

* Add comments for new tests

* More explicitly handle (none,false) case

* Rename some_data back to maybe_account_data

* Add data changes for try_mutate_exists_fails_without_changes test

* Add try_mutate_exists_account_not_created test

* Add assert_noop to check state chages

* Return success for try_mutate_exists_account_not_created test

* Use workspace deps

* Remove license

* Implement missed AccountProvider for EvmSystem

* Remove deprecated trait Store

* Add Apache-2.0 license

* Remove deprecated storage getter

* Remove redundant brackets

* Sovereign EVM balances layer (#100)

* Sovereign EVM balances layer (#95)

* Sovereign EVM balances layer (#87)

* Frame EVM balances (#65)

* Add initital frame balances structure

* Add account data balances logic

* Define main types

* Add imbalances logic

* Add DustCleaner

* Implement balances related operations

* Implement currencies for the pallet

* Implement Inspect for the pallet

* Make account_data mod private

* Leave only free balance data for account

* Support try-runtime features

* Apply formatting

* Fix comment

* Add mock with evm, evm-system, evm-balances configs

* Add basic setup test

* Add fee deduction test

* Add issuance_after_tip test

* Add refunds_should_work test

* Add refunds_and_priority_should_work test

* Fix clippy in tests

* Fix basec setup works test with evm balances checks

* Remove redundant set block in tests

* Add call_should_fail_with_priority_greater_than_max_fee test

* Add call_should_succeed_with_priority_equal_to_max_fee test

* Use EvmSystem as AccountProvider in tests

* Add account_should_be_reaped test

* Add deposit_into_existing test

* Add balance_transfer_works test

* Add slashing_balance_works test

* Add withdraw_balance_works test

* Add transferring_too_high_value_should_not_panic test

* Rename test to transfer_works

* Add basic tests for currency

* Add burn and issue related tests

* Add deposit_creating_works test

* Add currency_make_free_balance_be test

* Rename evm logic related tests

* Fix comment

* Rename slashing related test

* Rename test with make free balance

* Rename test with transferring too high value

* Assert evm system account existence for currency_deposit_creating_works test

* Add EvmSystem events check

* Remove license

* Use workspace dep

* Fix mock

* Remove deprecated trait Store

* Remove deprecated storage getter

* Add Apache-2.0 license

* Fix tests

* Apply required changes for fungible inspect trait

* Support `Mutate`, `Unbalanced`, `Balanced` fungible related traits for `pallet-evm-balances` (#102)

* Move currencies implementation into separate mod

* [substrate=apply] Deprecate Currency; introduce holds and freezing into fungible traits #12951

* Apply new balances logic to currency trait implementation

* Use DustRemoval over Credit instead of NegativeImbalance

* Implement Balanced, Unbalanced, Mutate fungible traits for pallet

* Revert using negative imbalance

* Apply formatter

* Fix withdraw_consequence method

* Move currency related tests to separate mod

* Add transfer_fails_funds_unavailable test to currency tests

* Add transfer_works_full_balance test to currency tests

* Fix slashing conditions

* Add slash_works_full_balance test to currency tests

* Add deposit_into_existing related fails tests

* Add withdraw_works_full_balance test to currency tests

* Add withdraw fails related tests to currency tests

* Add basic fungible tests

* Add reducable balance test to fungible tests

* Add can deposit related tests

* Fix can_withdraw logic

* Add can_withdraw related tests

* Add write_balance_works test

* Add set_total_issuance_works test

* Add decrease_balance related tests

* Add increase_balance related tests

* Add deactivate_reactivate_works test

* Add mint_into related tests

* Add burn_from related tests

* Add shelve related tests

* Add restored related tests

* Add transfer related tests

* Add balanced related tests

* Undo formatting

* Simplify reducible logic implementation

* Simplify can_deposit implementation

* Simplify can_withdraw implementation

* Properly use semantics of total and free balances

* Improve reducable_balance_works test

* Fix test race conditions

* Apply formatter for `pallet-evm-system` and `pallet-evm-balances` (#112) (#114)

Apply formatter for pallet-evm-system and pallet-evm-balances

* Use `execute_with_ext` in `pallet-evm-system` and `pallet-evm-balances` tests (#113) (#115)

Use execute_with_ext in pallet-evm-system and pallet-evm-balances tests

* Fix removing account logic at `pallet-evm-system` (#111) (#116)

* Add assert_total_issuance_invariant helper

* Add evm_system_removing_account_non_zero_balance test

* Fix removing account logic

* Undo redundant changes

* Redesign fix usage

* Undo try_mutate_exists_account_removed changes

* Rename Exists account removal status into Remains

* Improve docs

* Apply renaming at tests

* Use assert_storage_noop

* Remove rusttoolchain

* Add missing `on_created_account` logic usage for `inc_account_nonce` at `pallet-evm-system` (#147)

* Add on_created_account for new account at inc_account_nonce

* Add the corresponding event check at test

* Properly handle `on_created_account` related to `inc_account_nonce` logic (#151)

* Properly handle new account creation related to inc_account_nonce

* Move outside mutate

* Do the check inside mutate

* Use mutate_exists

* Use get_or_insert_default at mutate_exists

Co-authored-by: MOZGIII <mike-n@narod.ru>

* Remove redundant mut

---------

Co-authored-by: MOZGIII <mike-n@narod.ru>

* Properly manage contract accounts creation and removal logic (#140)

* Introduce has_code to AccountInfo at pallet-evm-system

* Improve AccountProvider related naming

* Rework tests logic

* Use had_code in tuple

* Apply fmt

* Set has_code to true in case account exists

* Some renaming

* Explicitly set has_code to true at create_contract_account_fails test

* Introduce evm managed terminologies

* Apply fmt

* Improve comments in tests

* Add create_evm_managed_account_works_already_exists test

* Add more data checks in tests

* Use assert_storage_noop

* Improve docs for create_evm_managed_account call

Co-authored-by: MOZGIII <mike-n@narod.ru>

* Improve docs for remove_evm_managed_account call

Co-authored-by: MOZGIII <mike-n@narod.ru>

* Improve some docs

* Properly unmark that account is not managed by EVM

* Unify tests naming semantic

* Apply fmt

* Add migrations logic (#148)

* Add STORAGE_VERSION usage

* Add migrations structure

* Implement OnRuntimeUpgrade for MigrationV0ToV1

* Some improvements

* Implement logic for pre_upgrade and post_upgrade

* Use reference in EvmProvider

* Fix vec usage at try-runtime

* Properly use translate

* Use u64 for counting at try-runtime

* Properly use old Account storage alias

* Ensure storafe data is updated correctly

* Some renaming

* Renaming after another iteration of investigations

* Return prev implementation

* Dissallow removing account as pub method

* Minor refactoring

* Don't use managed_by_evm field

* Remove storage version usage

* Migrations renaming

* Remove unused logic at migrations and leave todo for future implementations

* Working migrations with todo

* Properly use nonce related operations

* Apply introduced logic in tests

* Apply fmt

* Tests refactoring

* Minor improvements

* Remove unused error

* Use create_account at account provider

* More info to comment

* Remove migrations from current code changes

* Use on_account_self_destruct naming

---------

Co-authored-by: MOZGIII <mike-n@narod.ru>

* Avoid using `get_or_insert_default` (#154)

* Avoid using get_or_insert_default

* Use get_or_insert_with

* Rename frame to crates

* Add pallet- prefix to crates names

* Apply fmt

---------

Co-authored-by: MOZGIII <mike-n@narod.ru>
  • Loading branch information
dmitrylavrenov and MOZGIII authored Feb 8, 2025
1 parent 6786a57 commit e19241f
Show file tree
Hide file tree
Showing 14 changed files with 3,966 additions and 0 deletions.
50 changes: 50 additions & 0 deletions crates/pallet-evm-balances/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[package]
name = "pallet-evm-balances"
version = "1.0.0-dev"
license = "Apache-2.0"
description = "FRAME EVM BALANCES pallet."
edition = { workspace = true }
repository = { workspace = true }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
log = { workspace = true, default-features = false }
scale-codec = { package = "parity-scale-codec", workspace = true }
scale-info = { workspace = true }
# Substrate
frame-support = { workspace = true }
frame-system = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }

[dev-dependencies]
fp-evm = { workspace = true }
pallet-evm = { workspace = true }
pallet-evm-system = { workspace = true }
pallet-timestamp = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }

[features]
default = ["std"]
std = [
"log/std",
"scale-codec/std",
"scale-info/std",
# Substrate
"frame-support/std",
"frame-system/std",
"pallet-timestamp/std",
"sp-runtime/std",
"sp-std/std",
# Frontier
"fp-evm/std",
"pallet-evm/std",
"pallet-evm-system/std",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
]
46 changes: 46 additions & 0 deletions crates/pallet-evm-balances/src/account_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! Account balances logic.
use frame_support::traits::WithdrawReasons;

use super::*;

/// All balance information for an account.
#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)]
pub struct AccountData<Balance> {
/// Non-reserved part of the balance. There may still be restrictions on this, but it is the
/// total pool what may in principle be transferred, reserved and used for tipping.
///
/// This is the only balance that matters in terms of most operations on tokens. It
/// alone is used to determine the balance when in the contract execution environment.
pub free: Balance,
}

impl<Balance: Copy> AccountData<Balance> {
/// The total balance in this account.
pub(crate) fn total(&self) -> Balance {
self.free
}
}

/// Simplified reasons for withdrawing balance.
#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
pub enum Reasons {
/// Paying system transaction fees.
Fee = 0,
/// Any reason other than paying system transaction fees.
Misc = 1,
/// Any reason at all.
All = 2,
}

impl From<WithdrawReasons> for Reasons {
fn from(r: WithdrawReasons) -> Reasons {
if r == WithdrawReasons::TRANSACTION_PAYMENT {
Reasons::Fee
} else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) {
Reasons::All
} else {
Reasons::Misc
}
}
}
172 changes: 172 additions & 0 deletions crates/pallet-evm-balances/src/imbalances.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
//! Imbalances implementation.
use frame_support::traits::{SameOrOther, TryDrop};
use sp_std::{cmp::Ordering, mem};

use super::*;

/// Opaque, move-only struct with private fields that serves as a token denoting that
/// funds have been created without any equal and opposite accounting.
#[must_use]
#[derive(RuntimeDebug, PartialEq, Eq)]
pub struct PositiveImbalance<T: Config<I>, I: 'static = ()>(T::Balance);

impl<T: Config<I>, I: 'static> PositiveImbalance<T, I> {
/// Create a new positive imbalance from a balance.
pub fn new(amount: T::Balance) -> Self {
PositiveImbalance(amount)
}
}

/// Opaque, move-only struct with private fields that serves as a token denoting that
/// funds have been destroyed without any equal and opposite accounting.
#[must_use]
#[derive(RuntimeDebug, PartialEq, Eq)]
pub struct NegativeImbalance<T: Config<I>, I: 'static = ()>(T::Balance);

impl<T: Config<I>, I: 'static> NegativeImbalance<T, I> {
/// Create a new negative imbalance from a balance.
pub fn new(amount: T::Balance) -> Self {
NegativeImbalance(amount)
}
}

impl<T: Config<I>, I: 'static> TryDrop for PositiveImbalance<T, I> {
fn try_drop(self) -> result::Result<(), Self> {
self.drop_zero()
}
}

impl<T: Config<I>, I: 'static> Default for PositiveImbalance<T, I> {
fn default() -> Self {
Self::zero()
}
}

impl<T: Config<I>, I: 'static> Imbalance<T::Balance> for PositiveImbalance<T, I> {
type Opposite = NegativeImbalance<T, I>;

fn zero() -> Self {
Self(Zero::zero())
}

fn drop_zero(self) -> result::Result<(), Self> {
if self.0.is_zero() {
Ok(())
} else {
Err(self)
}
}

fn split(self, amount: T::Balance) -> (Self, Self) {
let first = self.0.min(amount);
let second = self.0 - first;

mem::forget(self);
(Self(first), Self(second))
}

fn merge(mut self, other: Self) -> Self {
self.0 = self.0.saturating_add(other.0);
mem::forget(other);

self
}

fn subsume(&mut self, other: Self) {
self.0 = self.0.saturating_add(other.0);
mem::forget(other);
}

fn offset(self, other: Self::Opposite) -> SameOrOther<Self, Self::Opposite> {
let (a, b) = (self.0, other.0);
mem::forget((self, other));

match a.cmp(&b) {
Ordering::Greater => SameOrOther::Same(Self(a - b)),
Ordering::Less => SameOrOther::Other(NegativeImbalance::new(b - a)),
Ordering::Equal => SameOrOther::None,
}
}

fn peek(&self) -> T::Balance {
self.0
}
}

impl<T: Config<I>, I: 'static> TryDrop for NegativeImbalance<T, I> {
fn try_drop(self) -> result::Result<(), Self> {
self.drop_zero()
}
}

impl<T: Config<I>, I: 'static> Default for NegativeImbalance<T, I> {
fn default() -> Self {
Self::zero()
}
}

impl<T: Config<I>, I: 'static> Imbalance<T::Balance> for NegativeImbalance<T, I> {
type Opposite = PositiveImbalance<T, I>;

fn zero() -> Self {
Self(Zero::zero())
}

fn drop_zero(self) -> result::Result<(), Self> {
if self.0.is_zero() {
Ok(())
} else {
Err(self)
}
}

fn split(self, amount: T::Balance) -> (Self, Self) {
let first = self.0.min(amount);
let second = self.0 - first;

mem::forget(self);
(Self(first), Self(second))
}

fn merge(mut self, other: Self) -> Self {
self.0 = self.0.saturating_add(other.0);
mem::forget(other);

self
}

fn subsume(&mut self, other: Self) {
self.0 = self.0.saturating_add(other.0);
mem::forget(other);
}

fn offset(self, other: Self::Opposite) -> SameOrOther<Self, Self::Opposite> {
let (a, b) = (self.0, other.0);
mem::forget((self, other));

match a.cmp(&b) {
Ordering::Greater => SameOrOther::Same(Self(a - b)),
Ordering::Less => SameOrOther::Other(PositiveImbalance::new(b - a)),
Ordering::Equal => SameOrOther::None,
}
}

fn peek(&self) -> T::Balance {
self.0
}
}

impl<T: Config<I>, I: 'static> Drop for PositiveImbalance<T, I> {
/// Basic drop handler will just square up the total issuance.
fn drop(&mut self) {
TotalIssuance::<T, I>::mutate(|v| *v = v.saturating_add(self.0));
}
}

impl<T: Config<I>, I: 'static> Drop for NegativeImbalance<T, I> {
/// Basic drop handler will just square up the total issuance.
fn drop(&mut self) {
TotalIssuance::<T, I>::mutate(|v| *v = v.saturating_sub(self.0));
}
}
Loading

0 comments on commit e19241f

Please sign in to comment.