forked from polkadot-evm/frontier
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
- Loading branch information
1 parent
8b7a691
commit 914e230
Showing
8 changed files
with
1,781 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} |
Oops, something went wrong.