Skip to content

Commit

Permalink
Set evm origin for xcm (#2454)
Browse files Browse the repository at this point in the history
* set evm origin for xcm

* try to set the correct origin

* fix

* update mandala as well

* fix test
  • Loading branch information
xlc authored Jan 15, 2023
1 parent d1d855c commit 6eefbb4
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 76 deletions.
3 changes: 1 addition & 2 deletions modules/asset-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#![allow(clippy::unused_unit)]

use frame_support::{
assert_ok,
dispatch::DispatchResult,
ensure,
pallet_prelude::*,
Expand Down Expand Up @@ -195,7 +194,7 @@ pub mod module {
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
fn build(&self) {
self.assets.iter().for_each(|(asset, ed)| {
assert_ok!(Pallet::<T>::do_register_native_asset(
frame_support::assert_ok!(Pallet::<T>::do_register_native_asset(
*asset,
&AssetMetadata {
name: asset.name().unwrap().as_bytes().to_vec(),
Expand Down
23 changes: 14 additions & 9 deletions modules/currencies/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,13 @@ pub mod module {
}
}

impl<T: Config> Pallet<T> {
fn get_evm_origin() -> Result<EvmAddress, DispatchError> {
let origin = T::EVMBridge::get_origin().ok_or(Error::<T>::RealOriginNotFound)?;
Ok(T::AddressMapping::get_or_create_evm_address(&origin))
}
}

impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
type CurrencyId = CurrencyId;
type Balance = BalanceOf<T>;
Expand Down Expand Up @@ -382,14 +389,12 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
match currency_id {
CurrencyId::Erc20(contract) => {
let sender = T::AddressMapping::get_evm_address(from).ok_or(Error::<T>::EvmAccountNotFound)?;
let origin = T::EVMBridge::get_origin().ok_or(Error::<T>::RealOriginNotFound)?;
let origin_address = T::AddressMapping::get_or_create_evm_address(&origin);
let address = T::AddressMapping::get_or_create_evm_address(to);
T::EVMBridge::transfer(
InvokeContext {
contract,
sender,
origin: origin_address,
origin: Self::get_evm_origin()?,
},
address,
amount,
Expand Down Expand Up @@ -428,7 +433,7 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
InvokeContext {
contract,
sender,
origin: receiver,
origin: Self::get_evm_origin().unwrap_or(receiver),
},
receiver,
amount,
Expand Down Expand Up @@ -467,7 +472,7 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
InvokeContext {
contract,
sender,
origin: sender,
origin: Self::get_evm_origin().unwrap_or(sender),
},
receiver,
amount,
Expand Down Expand Up @@ -611,7 +616,7 @@ impl<T: Config> MultiReservableCurrency<T::AccountId> for Pallet<T> {
InvokeContext {
contract,
sender: address,
origin: address,
origin: Self::get_evm_origin().unwrap_or(address),
},
reserve_address(address),
value,
Expand Down Expand Up @@ -644,7 +649,7 @@ impl<T: Config> MultiReservableCurrency<T::AccountId> for Pallet<T> {
InvokeContext {
contract,
sender,
origin: address,
origin: Self::get_evm_origin().unwrap_or(address),
},
address,
actual,
Expand Down Expand Up @@ -704,7 +709,7 @@ impl<T: Config> MultiReservableCurrency<T::AccountId> for Pallet<T> {
InvokeContext {
contract,
sender: slashed_reserve_address,
origin: slashed_address,
origin: Self::get_evm_origin().unwrap_or(slashed_address),
},
beneficiary_address,
actual,
Expand All @@ -713,7 +718,7 @@ impl<T: Config> MultiReservableCurrency<T::AccountId> for Pallet<T> {
InvokeContext {
contract,
sender: slashed_reserve_address,
origin: slashed_address,
origin: Self::get_evm_origin().unwrap_or(slashed_address),
},
beneficiary_reserve_address,
actual,
Expand Down
18 changes: 9 additions & 9 deletions modules/currencies/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ fn multi_currency_should_work() {
.one_hundred_for_alice_n_bob()
.build()
.execute_with(|| {
<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(alice());
assert_ok!(Currencies::transfer(Some(alice()).into(), bob(), X_TOKEN_ID, 50));
assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 50);
assert_eq!(Currencies::free_balance(X_TOKEN_ID, &bob()), 150);
Expand Down Expand Up @@ -544,7 +544,7 @@ fn erc20_ensure_withdraw_should_work() {
.build()
.execute_with(|| {
deploy_contracts();
<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(alice());
assert_ok!(Currencies::ensure_can_withdraw(
CurrencyId::Erc20(erc20_address()),
&alice(),
Expand Down Expand Up @@ -583,7 +583,7 @@ fn erc20_transfer_should_work() {
.build()
.execute_with(|| {
deploy_contracts();
<EVM as EVMTrait<AccountId>>::set_origin(eva());
<EVM as EVMTrait<AccountId>>::push_origin(eva());

assert_ok!(Currencies::transfer(
RuntimeOrigin::signed(alice()),
Expand Down Expand Up @@ -656,8 +656,8 @@ fn erc20_transfer_should_fail() {
Error::<Runtime>::RealOriginNotFound
);

<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::set_origin(bob());
<EVM as EVMTrait<AccountId>>::push_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(bob());

// empty address
assert!(Currencies::transfer(
Expand Down Expand Up @@ -843,7 +843,7 @@ fn erc20_repatriate_reserved_should_work() {
.execute_with(|| {
deploy_contracts();
let bob_balance = 100;
<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(alice());
assert_ok!(Currencies::transfer(
RuntimeOrigin::signed(alice()),
bob(),
Expand Down Expand Up @@ -975,7 +975,7 @@ fn erc20_invalid_operation() {
.build()
.execute_with(|| {
deploy_contracts();
<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(alice());

assert_noop!(
Currencies::update_balance(RuntimeOrigin::root(), alice(), CurrencyId::Erc20(erc20_address()), 1),
Expand All @@ -994,7 +994,7 @@ fn erc20_withdraw_deposit_works() {
.build()
.execute_with(|| {
deploy_contracts();
<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(alice());

let erc20_holding_account = MockAddressMapping::get_account_id(&Erc20HoldingAccount::get());

Expand Down Expand Up @@ -1668,7 +1668,7 @@ fn fungible_transfer_trait_should_work() {
assert_eq!(<AdaptedBasicCurrency as fungible::Inspect<_>>::balance(&bob()), 20000);

deploy_contracts();
<EVM as EVMTrait<AccountId>>::set_origin(alice());
<EVM as EVMTrait<AccountId>>::push_origin(alice());
assert_eq!(
<Currencies as fungibles::Inspect<_>>::balance(CurrencyId::Erc20(erc20_address()), &alice()),
ALICE_BALANCE
Expand Down
8 changes: 6 additions & 2 deletions modules/evm-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,12 @@ impl<T: Config> EVMBridgeTrait<AccountIdOf<T>, BalanceOf<T>> for EVMBridge<T> {
T::EVM::get_origin()
}

fn set_origin(origin: AccountIdOf<T>) {
T::EVM::set_origin(origin);
fn push_origin(origin: AccountIdOf<T>) {
T::EVM::push_origin(origin);
}

fn pop_origin() {
T::EVM::pop_origin();
}
}

Expand Down
32 changes: 25 additions & 7 deletions modules/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ pub mod module {
/// ExtrinsicOrigin: Option<AccountId>
#[pallet::storage]
#[pallet::getter(fn extrinsic_origin)]
pub type ExtrinsicOrigin<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;
pub type ExtrinsicOrigin<T: Config> = StorageValue<_, Vec<T::AccountId>, OptionQuery>;

#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
Expand Down Expand Up @@ -1863,12 +1863,30 @@ impl<T: Config> EVMTrait<T::AccountId> for Pallet<T> {

/// Get the real origin account and charge storage rent from the origin.
fn get_origin() -> Option<T::AccountId> {
ExtrinsicOrigin::<T>::get()
ExtrinsicOrigin::<T>::get().and_then(|o| o.last().cloned())
}

/// Provide a method to set origin for `on_initialize`
fn set_origin(origin: T::AccountId) {
ExtrinsicOrigin::<T>::set(Some(origin));
// Set the EVM origin
fn push_origin(origin: T::AccountId) {
ExtrinsicOrigin::<T>::mutate(|o| {
if let Some(o) = o {
o.push(origin);
} else {
*o = Some(vec![origin]);
}
});
}

// Pop the EVM origin
fn pop_origin() {
ExtrinsicOrigin::<T>::mutate(|o| {
if let Some(arr) = o {
arr.pop();
if arr.is_empty() {
*o = None;
}
}
});
}
}

Expand Down Expand Up @@ -1996,7 +2014,7 @@ impl<T: Config + Send + Sync> SignedExtension for SetEvmOrigin<T> {
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
ExtrinsicOrigin::<T>::set(Some(who.clone()));
ExtrinsicOrigin::<T>::set(Some(vec![who.clone()]));
Ok(ValidTransaction::default())
}

Expand All @@ -2007,7 +2025,7 @@ impl<T: Config + Send + Sync> SignedExtension for SetEvmOrigin<T> {
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> Result<(), TransactionValidityError> {
ExtrinsicOrigin::<T>::set(Some(who.clone()));
ExtrinsicOrigin::<T>::set(Some(vec![who.clone()]));
Ok(())
}

Expand Down
4 changes: 2 additions & 2 deletions modules/honzon-bridge/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn to_bridged_works() {
erc20_address()
));
// ensure the honzon-bridge pallet account bind the evmaddress
<EVM as EVMTrait<AccountId>>::set_origin(EvmAccountsModule::get_account_id(&alice_evm_addr()));
<EVM as EVMTrait<AccountId>>::push_origin(EvmAccountsModule::get_account_id(&alice_evm_addr()));
assert_ok!(Currencies::transfer(
RuntimeOrigin::signed(alice()),
HonzonBridgeAccount::get(),
Expand Down Expand Up @@ -132,7 +132,7 @@ fn from_bridged_works() {
erc20_address()
));
// ensure the honzon-bridge pallet account bind the evmaddress
<EVM as EVMTrait<AccountId>>::set_origin(EvmAccountsModule::get_account_id(&alice_evm_addr()));
<EVM as EVMTrait<AccountId>>::push_origin(EvmAccountsModule::get_account_id(&alice_evm_addr()));
assert_ok!(Currencies::transfer(
RuntimeOrigin::signed(alice()),
HonzonBridgeAccount::get(),
Expand Down
15 changes: 10 additions & 5 deletions modules/support/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ pub trait EVM<AccountId> {

/// Get the real origin account and charge storage rent from the origin.
fn get_origin() -> Option<AccountId>;
/// Provide a method to set origin for `on_initialize`
fn set_origin(origin: AccountId);
/// Push new EVM origin
fn push_origin(origin: AccountId);
/// Pop EVM origin
fn pop_origin();
}

#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug)]
Expand Down Expand Up @@ -96,8 +98,10 @@ pub trait EVMBridge<AccountId, Balance> {
fn transfer(context: InvokeContext, to: EvmAddress, value: Balance) -> DispatchResult;
/// Get the real origin account and charge storage rent from the origin.
fn get_origin() -> Option<AccountId>;
/// Provide a method to set origin for `on_initialize`
fn set_origin(origin: AccountId);
/// Push new EVM origin
fn push_origin(origin: AccountId);
/// Pop EVM origin
fn pop_origin();
}

#[cfg(feature = "std")]
Expand All @@ -123,7 +127,8 @@ impl<AccountId, Balance: Default> EVMBridge<AccountId, Balance> for () {
fn get_origin() -> Option<AccountId> {
None
}
fn set_origin(_origin: AccountId) {}
fn push_origin(_origin: AccountId) {}
fn pop_origin() {}
}

/// EVM bridge for collateral liquidation.
Expand Down
19 changes: 13 additions & 6 deletions runtime/acala/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ pub use xcm_builder::{
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
TakeRevenue, TakeWeightCredit,
};
use xcm_executor::XcmExecutor;

parameter_types! {
pub DotLocation: MultiLocation = MultiLocation::parent();
Expand Down Expand Up @@ -194,13 +193,21 @@ pub type XcmRouter = (
XcmpQueue,
);

pub type XcmExecutor = runtime_common::XcmExecutor<
XcmConfig,
AccountId,
Balance,
LocationToAccountId,
module_evm_bridge::EVMBridge<Runtime>,
>;

impl pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, ()>;
type XcmRouter = XcmRouter;
type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type XcmExecuteFilter = Nothing;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmExecutor = XcmExecutor;
type XcmTeleportFilter = Nothing;
type XcmReserveTransferFilter = Everything;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
Expand All @@ -213,12 +220,12 @@ impl pallet_xcm::Config for Runtime {

impl cumulus_pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmExecutor = XcmExecutor;
}

impl cumulus_pallet_xcmp_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmExecutor = XcmExecutor;
type ChannelInfo = ParachainSystem;
type VersionWrapper = PolkadotXcm;
type ExecuteOverweightOrigin = EnsureRootOrHalfGeneralCouncil;
Expand All @@ -229,7 +236,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {

impl cumulus_pallet_dmp_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmExecutor = XcmExecutor;
type ExecuteOverweightOrigin = EnsureRootOrHalfGeneralCouncil;
}

Expand Down Expand Up @@ -371,7 +378,7 @@ impl orml_xtokens::Config for Runtime {
type CurrencyIdConvert = CurrencyIdConvert;
type AccountIdToMultiLocation = AccountIdToMultiLocation;
type SelfLocation = SelfLocation;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmExecutor = XcmExecutor;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type BaseXcmWeight = BaseXcmWeight;
type LocationInverter = LocationInverter<Ancestry>;
Expand Down
2 changes: 1 addition & 1 deletion runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub use primitives::{
},
AccountId,
};
pub use xcm_impl::{local_currency_location, native_currency_location, AcalaDropAssets, FixedRateOfAsset};
pub use xcm_impl::{local_currency_location, native_currency_location, AcalaDropAssets, FixedRateOfAsset, XcmExecutor};

#[cfg(feature = "std")]
use sp_core::bytes::from_hex;
Expand Down
Loading

0 comments on commit 6eefbb4

Please sign in to comment.