Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions prdoc/pr_9683.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
title: "[pallet-revive] add account_id and new_balance_with_dust runtime APIs"

doc:
- audience: Runtime Dev
description: |
Adds two new runtime APIs to the ReviveApi: account_id (which maps an eth address to a substrate account id)
and new_balance_with_dust (which constructs the substrate components of a balance: the real balance, including ED, and the dust,
according to the runtime's configuration).

crates:
- name: pallet-revive
bump: major
3 changes: 2 additions & 1 deletion substrate/frame/revive/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1534,7 +1534,8 @@ where
Ok(())
}

let value = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(value)?;
let value = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(value)
.map_err(|_| <Error<T>>::BalanceConversionFailed)?;
if value.is_zero() {
return Ok(());
}
Expand Down
37 changes: 32 additions & 5 deletions substrate/frame/revive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1549,19 +1549,30 @@ where
/// consistent with `evm_balance` which returns the spendable balance excluding the existential
/// deposit.
pub fn set_evm_balance(address: &H160, evm_value: U256) -> Result<(), Error<T>> {
let ed = T::Currency::minimum_balance();
let balance_with_dust = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(evm_value)
let (balance, dust) = Self::new_balance_with_dust(evm_value)
.map_err(|_| <Error<T>>::BalanceConversionFailed)?;
let (value, dust) = balance_with_dust.deconstruct();
let account_id = T::AddressMapper::to_account_id(&address);
T::Currency::set_balance(&account_id, ed.saturating_add(value));
T::Currency::set_balance(&account_id, balance);
AccountInfoOf::<T>::mutate(address, |account| {
account.as_mut().map(|a| a.dust = dust);
});

Ok(())
}

/// Construct native balance from EVM balance.
///
/// Adds the existential deposit and returns the native balance plus the dust.
pub fn new_balance_with_dust(
evm_value: U256,
) -> Result<(BalanceOf<T>, u32), BalanceConversionError> {
let ed = T::Currency::minimum_balance();
let balance_with_dust = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(evm_value)?;
let (value, dust) = balance_with_dust.deconstruct();

Ok((ed.saturating_add(value), dust))
}

/// Get the nonce for the given `address`.
pub fn evm_nonce(address: &H160) -> u32
where
Expand All @@ -1587,7 +1598,8 @@ where
/// Convert a gas value into a substrate fee
fn evm_gas_to_fee(gas: U256, gas_price: U256) -> Result<BalanceOf<T>, Error<T>> {
let fee = gas.saturating_mul(gas_price);
let value = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(fee)?;
let value = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(fee)
.map_err(|_| <Error<T>>::BalanceConversionFailed)?;
Ok(value.into_rounded_balance())
}

Expand Down Expand Up @@ -1896,11 +1908,17 @@ sp_api::decl_runtime_apis! {
/// Get the H160 address associated to this account id
fn address(account_id: AccountId) -> H160;

/// Get the account id associated to this H160 address.
fn account_id(address: H160) -> AccountId;

/// The address used to call the runtime's pallets dispatchables
fn runtime_pallets_address() -> H160;

/// The code at the specified address taking pre-compiles into account.
fn code(address: H160) -> Vec<u8>;

/// Construct the new balance and dust components of this EVM balance.
fn new_balance_with_dust(balance: U256) -> Result<(Balance, u32), BalanceConversionError>;
Comment on lines +1920 to +1921
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain why you need a new runtime api?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}

Expand Down Expand Up @@ -2127,6 +2145,15 @@ macro_rules! impl_runtime_apis_plus_revive {
fn code(address: $crate::H160) -> Vec<u8> {
$crate::Pallet::<Self>::code(&address)
}

fn account_id(address: $crate::H160) -> AccountId {
use $crate::AddressMapper;
<Self as $crate::Config>::AddressMapper::to_account_id(&address)
}

fn new_balance_with_dust(balance: $crate::U256) -> Result<(Balance, u32), $crate::BalanceConversionError> {
$crate::Pallet::<Self>::new_balance_with_dust(balance)
}
}
}
};
Expand Down
19 changes: 15 additions & 4 deletions substrate/frame/revive/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

//! A crate that hosts a common definitions that are relevant for the pallet-revive.

use crate::{BalanceOf, Config, Error, H160, U256};
use crate::{BalanceOf, Config, H160, U256};
use alloc::{string::String, vec::Vec};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::weights::Weight;
Expand Down Expand Up @@ -119,6 +119,15 @@ pub enum EthTransactError {
Message(String),
}

#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
/// Error encountered while creating a BalanceWithDust from a U256 balance.
pub enum BalanceConversionError {
/// Error encountered while creating the main balance value.
Value,
/// Error encountered while creating the dust value.
Dust,
}

/// A Balance amount along with some "dust" to represent the lowest decimals that can't be expressed
/// in the native currency
#[derive(Default, Clone, Copy, Eq, PartialEq, Debug)]
Expand Down Expand Up @@ -149,7 +158,9 @@ impl<Balance> BalanceWithDust<Balance> {
}

/// Creates a new `BalanceWithDust` from the given EVM value.
pub fn from_value<T: Config>(value: U256) -> Result<BalanceWithDust<BalanceOf<T>>, Error<T>>
pub fn from_value<T: Config>(
value: U256,
) -> Result<BalanceWithDust<BalanceOf<T>>, BalanceConversionError>
where
BalanceOf<T>: TryFrom<U256>,
{
Expand All @@ -158,8 +169,8 @@ impl<Balance> BalanceWithDust<Balance> {
}

let (quotient, remainder) = value.div_mod(T::NativeToEthRatio::get().into());
let value = quotient.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)?;
let dust = remainder.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)?;
let value = quotient.try_into().map_err(|_| BalanceConversionError::Value)?;
let dust = remainder.try_into().map_err(|_| BalanceConversionError::Dust)?;

Ok(BalanceWithDust { value, dust })
}
Expand Down
Loading