Skip to content

Commit c405be7

Browse files
AndreiEresgithub-actions[bot]pgherveou
authored andcommitted
[pallet-revive] Add Pallet::set_evm_balance (#9617)
Part of #9553 See paritytech/foundry-polkadot#273 Adds a balance setter in EVM. ## Integration Should not affect downstream projects. --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: PG Herveou <pgherveou@gmail.com>
1 parent a1e5b7c commit c405be7

File tree

4 files changed

+57
-14
lines changed

4 files changed

+57
-14
lines changed

prdoc/pr_9617.prdoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
title: '[pallet-revive] Add setting evm balance'
2+
doc:
3+
- audience: Runtime User
4+
description: |-
5+
Adds a balance setter in EVM for pallet-revive.
6+
7+
crates:
8+
- name: pallet-revive
9+
bump: minor

substrate/frame/revive/src/lib.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,9 @@ pub mod pallet {
580580
#[pallet::genesis_build]
581581
impl<T: Config> BuildGenesisConfig for GenesisConfig<T>
582582
where
583-
BalanceOf<T>: Into<U256> + TryFrom<U256>,
583+
BalanceOf<T>: Into<U256> + TryFrom<U256> + Bounded,
584+
MomentOf<T>: Into<U256>,
585+
T::Hash: frame_support::traits::IsType<H256>,
584586
{
585587
fn build(&self) {
586588
use crate::{exec::Key, vm::ContractBlob};
@@ -602,17 +604,8 @@ pub mod pallet {
602604
let owner = Pallet::<T>::account_id();
603605

604606
for genesis::Account { address, balance, nonce, contract_data } in &self.accounts {
605-
let Ok(balance_with_dust) =
606-
BalanceWithDust::<BalanceOf<T>>::from_value::<T>(*balance).inspect_err(|err| {
607-
log::error!(target: LOG_TARGET, "Failed to convert balance for {address:?}: {err:?}");
608-
})
609-
else {
610-
continue;
611-
};
612607
let account_id = T::AddressMapper::to_account_id(address);
613-
let (value, dust) = balance_with_dust.deconstruct();
614608

615-
let _ = T::Currency::set_balance(&account_id, value);
616609
frame_system::Account::<T>::mutate(&account_id, |info| {
617610
info.nonce = (*nonce).into();
618611
});
@@ -621,7 +614,7 @@ pub mod pallet {
621614
None => {
622615
AccountInfoOf::<T>::insert(
623616
address,
624-
AccountInfo { account_type: AccountType::EOA, dust },
617+
AccountInfo { account_type: AccountType::EOA, dust: 0 },
625618
);
626619
},
627620
Some(genesis::ContractData { code, storage }) => {
@@ -650,7 +643,7 @@ pub mod pallet {
650643

651644
AccountInfoOf::<T>::insert(
652645
address,
653-
AccountInfo { account_type: info.clone().into(), dust },
646+
AccountInfo { account_type: info.clone().into(), dust: 0 },
654647
);
655648

656649
<PristineCode<T>>::insert(blob.code_hash(), code);
@@ -662,6 +655,10 @@ pub mod pallet {
662655
}
663656
},
664657
}
658+
659+
let _ = Pallet::<T>::set_evm_balance(address, *balance).inspect_err(|err| {
660+
log::error!(target: LOG_TARGET, "Failed to set EVM balance for {address:?}: {err:?}");
661+
});
665662
}
666663
}
667664
}
@@ -1539,11 +1536,32 @@ where
15391536
}
15401537

15411538
/// Get the balance with EVM decimals of the given `address`.
1539+
///
1540+
/// Returns the spendable balance excluding the existential deposit.
15421541
pub fn evm_balance(address: &H160) -> U256 {
15431542
let balance = AccountInfo::<T>::balance((*address).into());
15441543
Self::convert_native_to_evm(balance)
15451544
}
15461545

1546+
/// Set the EVM balance of an account.
1547+
///
1548+
/// The account's total balance becomes the EVM value plus the existential deposit,
1549+
/// consistent with `evm_balance` which returns the spendable balance excluding the existential
1550+
/// deposit.
1551+
pub fn set_evm_balance(address: &H160, evm_value: U256) -> Result<(), Error<T>> {
1552+
let ed = T::Currency::minimum_balance();
1553+
let balance_with_dust = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(evm_value)
1554+
.map_err(|_| <Error<T>>::BalanceConversionFailed)?;
1555+
let (value, dust) = balance_with_dust.deconstruct();
1556+
let account_id = T::AddressMapper::to_account_id(&address);
1557+
T::Currency::set_balance(&account_id, ed.saturating_add(value));
1558+
AccountInfoOf::<T>::mutate(address, |account| {
1559+
account.as_mut().map(|a| a.dust = dust);
1560+
});
1561+
1562+
Ok(())
1563+
}
1564+
15471565
/// Get the nonce for the given `address`.
15481566
pub fn evm_nonce(address: &H160) -> u32
15491567
where

substrate/frame/revive/src/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ impl Default for Origin<Test> {
460460
fn ext_builder_with_genesis_config_works() {
461461
let pvm_contract = Account {
462462
address: BOB_ADDR,
463-
balance: U256::from(100),
463+
balance: U256::from(100_000_100),
464464
nonce: 42,
465465
contract_data: Some(ContractData {
466466
code: compile_module("dummy").unwrap().0,
@@ -470,7 +470,7 @@ fn ext_builder_with_genesis_config_works() {
470470

471471
let evm_contract = Account {
472472
address: CHARLIE_ADDR,
473-
balance: U256::from(100),
473+
balance: U256::from(1_000_00_100),
474474
nonce: 43,
475475
contract_data: Some(ContractData {
476476
code: vec![revm::bytecode::opcode::RETURN],

substrate/frame/revive/src/tests/pvm.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,22 @@ fn eth_call_transfer_with_dust_works() {
193193
});
194194
}
195195

196+
#[test]
197+
fn set_evm_balance_works() {
198+
let (binary, _) = compile_module("dummy").unwrap();
199+
ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
200+
let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
201+
let Contract { addr, .. } =
202+
builder::bare_instantiate(Code::Upload(binary)).build_and_unwrap_contract();
203+
let native_with_dust = BalanceWithDust::new_unchecked::<Test>(100, 10);
204+
let evm_value = Pallet::<Test>::convert_native_to_evm(native_with_dust);
205+
206+
assert_ok!(Pallet::<Test>::set_evm_balance(&addr, evm_value));
207+
208+
assert_eq!(Pallet::<Test>::evm_balance(&addr), evm_value);
209+
});
210+
}
211+
196212
#[test]
197213
fn contract_call_transfer_with_dust_works() {
198214
let (binary_caller, _code_hash_caller) = compile_module("call_with_value").unwrap();

0 commit comments

Comments
 (0)