Skip to content

Commit

Permalink
fix: added more E2E Tests
Browse files Browse the repository at this point in the history
Fixed some calls in the pallets, also this fixes an issue or bug in

Closes #868
  • Loading branch information
shekohex committed Jan 7, 2025
1 parent 72b93bb commit 484f0dc
Show file tree
Hide file tree
Showing 8 changed files with 19,220 additions and 13,353 deletions.
180 changes: 136 additions & 44 deletions node/tests/evm_restaking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ use core::time::Duration;
use alloy::primitives::*;
use alloy::providers::Provider;
use alloy::sol;
use sp_tracing::info;
use sp_runtime::traits::AccountIdConversion;
use sp_tracing::{error, info};
use tangle_runtime::PalletId;
use tangle_subxt::subxt;
use tangle_subxt::subxt::tx::TxStatus;
use tangle_subxt::tangle_testnet_runtime::api;

mod common;

use common::*;
use tangle_subxt::tangle_testnet_runtime::api::runtime_types::pallet_assets;
use tangle_subxt::tangle_testnet_runtime::api::runtime_types::pallet_multi_asset_delegation::types::operator::DelegatorBond;
use tangle_subxt::tangle_testnet_runtime::api::runtime_types::tangle_primitives::services::Asset;
use tangle_subxt::tangle_testnet_runtime::api::runtime_types::tangle_testnet_runtime::RuntimeCall;

sol! {
#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -76,45 +76,59 @@ async fn deploy_erc20(
async fn create_asset(
subxt: &subxt::OnlineClient<subxt::PolkadotConfig>,
signer: &TestAccount,
asset_id: u128,
name: &str,
symbol: &str,
decimals: u8,
) -> anyhow::Result<u128> {
let next_asset_id_addr = api::storage().assets().next_asset_id();
let asset_id = subxt
.storage()
.at_latest()
.await?
.fetch(&next_asset_id_addr)
.await?
.unwrap_or_default();
let asset_call = api::tx().utility().batch(vec![
RuntimeCall::Assets(pallet_assets::pallet::Call::create {
id: asset_id,
admin: signer.account_id().into(),
min_balance: 0,
}),
RuntimeCall::Assets(pallet_assets::pallet::Call::set_metadata {
id: asset_id,
name: name.into(),
symbol: symbol.into(),
decimals,
}),
]);

) -> anyhow::Result<()> {
let asset_create_call = api::tx().assets().create(asset_id, signer.account_id().into(), 1);
let asset_metadata_call =
api::tx().assets().set_metadata(asset_id, name.into(), symbol.into(), decimals);
let mut result = subxt
.tx()
.sign_and_submit_then_watch_default(&asset_call, &signer.substrate_signer())
.sign_and_submit_then_watch_default(&asset_create_call, &signer.substrate_signer())
.await?;

while let Some(Ok(s)) = result.next().await {
if let TxStatus::InBestBlock(b) = s {
let evs = match b.wait_for_success().await {
Ok(evs) => evs,
Err(e) => {
error!("Error: {:?}", e);
break;
},
};
let created = evs
.find_first::<api::assets::events::Created>()?
.expect("Created event to be emitted");
assert_eq!(created.asset_id, asset_id, "Asset ID mismatch");
break;
}
}

result = subxt
.tx()
.sign_and_submit_then_watch_default(&asset_metadata_call, &signer.substrate_signer())
.await?;

while let Some(Ok(s)) = result.next().await {
if let TxStatus::InBestBlock(b) = s {
b.wait_for_success().await?;
info!("Created {symbol} asset with ID: {asset_id}");
let evs = match b.wait_for_success().await {
Ok(evs) => evs,
Err(e) => {
error!("Error: {:?}", e);
break;
},
};
let metadata_set = evs
.find_first::<api::assets::events::MetadataSet>()?
.expect("MetadataSet event to be emitted");
assert_eq!(metadata_set.asset_id, asset_id, "Asset ID mismatch");
break;
}
}
Ok(asset_id)

Ok(())
}

/// Setup the E2E test environment.
Expand All @@ -139,21 +153,23 @@ where
let wbtc_addr = deploy_erc20(alice_provider.clone(), "Wrapped Bitcoin", "WBTC", 8).await?;

// Create runtime assets
let usdc_asset_id = create_asset(&subxt, &alice, "USD Coin", "USDC", 6).await?;
let weth_asset_id = create_asset(&subxt, &alice, "Wrapped Ether", "WETH", 18).await?;
let wbtc_asset_id = create_asset(&subxt, &alice, "Wrapped Bitcoin", "WBTC", 8).await?;
create_asset(&subxt, &alice, 0, "USD Coin", "USDC", 6).await?;
create_asset(&subxt, &alice, 1, "Wrapped Ether", "WETH", 18).await?;
create_asset(&subxt, &alice, 2, "Wrapped Bitcoin", "WBTC", 8).await?;

let test_inputs = TestInputs {
provider,
subxt,
usdc: usdc_addr,
weth: weth_addr,
wbtc: wbtc_addr,
usdc_asset_id,
weth_asset_id,
wbtc_asset_id,
usdc_asset_id: 0,
weth_asset_id: 1,
wbtc_asset_id: 2,
};
f(test_inputs).await
let result = f(test_inputs).await;
assert!(result.is_ok(), "Test failed: {result:?}");
result
});
}

Expand Down Expand Up @@ -290,24 +306,100 @@ fn operator_join_delegator_delegate_asset_id() {

// Mint USDC for Bob using asset ID
let mint_amount = 100_000_000u128;
let mint_call = api::tx().assets().mint(
t.usdc_asset_id,
bob.address().to_account_id().into(),
mint_amount,
);
let mint_call = |who| api::tx().assets().mint(t.usdc_asset_id, who, mint_amount);

info!("Minting {mint_amount} USDC for Bob");

let mut result = t
.subxt
.tx()
.sign_and_submit_then_watch_default(&mint_call, &alice.substrate_signer())
.sign_and_submit_then_watch_default(
&mint_call(bob.address().to_account_id().into()),
&alice.substrate_signer(),
)
.await?;
while let Some(Ok(s)) = result.next().await {
if let TxStatus::InBestBlock(b) = s {
b.wait_for_success().await?;
let evs = match b.wait_for_success().await {
Ok(evs) => evs,
Err(e) => {
error!("Error: {:?}", e);
break;
},
};
evs.find_first::<api::assets::events::Issued>()?
.expect("Issued event to be emitted");
info!("Minted {mint_amount} USDC for Bob");
break;
}
}

// Mint 1 USDC to the MAD pallet.
let pallet_account_addr = api::constants().multi_asset_delegation().pallet_id();
let pallet_account_id = t.subxt.constants().at(&pallet_account_addr).unwrap();
let pallet_account_id =
AccountIdConversion::<subxt::utils::AccountId32>::into_account_truncating(&PalletId(
pallet_account_id.0,
));

// Send some balance to the MAD pallet
let transfer_keep_alive_call = api::tx()
.balances()
.transfer_keep_alive(pallet_account_id.clone().into(), 100_000_000_000_000);

let mut result = t
.subxt
.tx()
.sign_and_submit_then_watch_default(
&transfer_keep_alive_call,
&alice.substrate_signer(),
)
.await?;

while let Some(Ok(s)) = result.next().await {
if let TxStatus::InBestBlock(b) = s {
let evs = match b.wait_for_success().await {
Ok(evs) => evs,
Err(e) => {
error!("Error: {:?}", e);
break;
},
};
evs.find_first::<api::balances::events::Transfer>()?
.expect("Transfer event to be emitted");
info!("Transferred 100_000_000_000_000 to the MAD pallet");
break;
}
}

info!("Minting {mint_amount} USDC to the MAD pallet");
let mut result = t
.subxt
.tx()
.sign_and_submit_then_watch_default(
&mint_call(pallet_account_id.into()),
&alice.substrate_signer(),
)
.await?;

while let Some(Ok(s)) = result.next().await {
if let TxStatus::InBestBlock(b) = s {
let evs = match b.wait_for_success().await {
Ok(evs) => evs,
Err(e) => {
error!("Error: {:?}", e);
break;
},
};
evs.find_first::<api::assets::events::Issued>()?
.expect("Issued event to be emitted");
info!("Minted {mint_amount} USDC to the MAD pallet");
break;
}
}

wait_for_more_blocks(&t.provider, 1).await;

// Delegate assets
let precompile = MultiAssetDelegation::new(MULTI_ASSET_DELEGATION, &bob_provider);
let delegate_amount = mint_amount.div(2);
Expand Down
16 changes: 16 additions & 0 deletions pallets/multi-asset-delegation/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
//
// You should have received a copy of the GNU General Public License
// along with Tangle. If not, see <http://www.gnu.org/licenses/>.

use frame_system::RawOrigin;
use sp_runtime::traits::BadOrigin;

use super::*;

pub mod delegate;
Expand All @@ -21,3 +25,15 @@ pub mod evm;
pub mod operator;
pub mod rewards;
pub mod session_manager;

/// Ensure that the origin `o` represents the current pallet (i.e. transaction).
/// Returns `Ok` if the origin is the current pallet, `Err` otherwise.
pub fn ensure_pallet<T: Config, OuterOrigin>(o: OuterOrigin) -> Result<T::AccountId, BadOrigin>
where
OuterOrigin: Into<Result<RawOrigin<T::AccountId>, OuterOrigin>>,
{
match o.into() {
Ok(RawOrigin::Signed(t)) if t == Pallet::<T>::pallet_account() => Ok(t),
_ => Err(BadOrigin),
}
}
16 changes: 3 additions & 13 deletions pallets/multi-asset-delegation/src/functions/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ impl<T: Config> Pallet<T> {
sender: &T::AccountId,
asset_id: Asset<T::AssetId>,
amount: BalanceOf<T>,
_evm_sender: Option<H160>,
) -> DispatchResult {
match asset_id {
Asset::Custom(asset_id) => {
Expand All @@ -57,16 +56,8 @@ impl<T: Config> Pallet<T> {
Preservation::Expendable,
)?;
},
Asset::Erc20(_asset_address) => {
// let sender = evm_sender.ok_or(Error::<T>::ERC20TransferFailed)?;
// let (success, _weight) = Self::erc20_transfer(
// asset_address,
// &sender,
// Self::pallet_evm_account(),
// amount,
// )
// .map_err(|_| Error::<T>::ERC20TransferFailed)?;
// ensure!(success, Error::<T>::ERC20TransferFailed);
Asset::Erc20(_) => {
// Handled by the Precompile
},
}
Ok(())
Expand All @@ -88,12 +79,11 @@ impl<T: Config> Pallet<T> {
who: T::AccountId,
asset_id: Asset<T::AssetId>,
amount: BalanceOf<T>,
evm_address: Option<H160>,
) -> DispatchResult {
ensure!(amount >= T::MinDelegateAmount::get(), Error::<T>::BondTooLow);

// Transfer the amount to the pallet account
Self::handle_transfer_to_pallet(&who, asset_id, amount, evm_address)?;
Self::handle_transfer_to_pallet(&who, asset_id, amount)?;

// Update storage
Delegators::<T>::try_mutate(&who, |maybe_metadata| -> DispatchResult {
Expand Down
24 changes: 21 additions & 3 deletions pallets/multi-asset-delegation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub use functions::*;

#[frame_support::pallet]
pub mod pallet {
use super::functions::*;
use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *};
use frame_support::{
pallet_prelude::*,
Expand All @@ -90,7 +91,10 @@ pub mod pallet {
use sp_core::H160;
use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero};
use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec};
use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex};
use tangle_primitives::{
services::Asset, services::EvmAddressMapping, traits::ServiceManager, BlueprintId,
RoundIndex,
};

/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
Expand Down Expand Up @@ -181,6 +185,7 @@ pub mod pallet {
+ fungibles::Mutate<Self::AccountId, AssetId = Self::AssetId>;

/// The pallet's account ID.
#[pallet::constant]
type PalletId: Get<PalletId>;

/// The origin with privileged access
Expand Down Expand Up @@ -706,8 +711,21 @@ pub mod pallet {
amount: BalanceOf<T>,
evm_address: Option<H160>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
Self::process_deposit(who.clone(), asset_id, amount, evm_address)?;
let who = match (asset_id, evm_address) {
(Asset::Custom(_), None) => ensure_signed(origin)?,
(Asset::Erc20(_), Some(addr)) => {
ensure_pallet::<T, _>(origin)?;
T::EvmAddressMapping::into_account_id(addr)
},
(Asset::Erc20(_), None) => return Err(Error::<T>::NotAuthorized.into()),
(Asset::Custom(_), Some(adress)) => {
let evm_account_id = T::EvmAddressMapping::into_account_id(adress);
let caller = ensure_signed(origin)?;
ensure!(evm_account_id == caller, DispatchError::BadOrigin);
evm_account_id
},
};
Self::process_deposit(who.clone(), asset_id, amount)?;
Self::deposit_event(Event::Deposited { who, amount, asset_id });
Ok(())
}
Expand Down
5 changes: 3 additions & 2 deletions precompiles/erc20-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use alloc::format;
pub fn erc20_transfer(
handle: &mut impl PrecompileHandle,
erc20: Address,
caller: Address,
to: Address,
amount: U256,
) -> EvmResult<bool> {
Expand Down Expand Up @@ -79,8 +80,8 @@ pub fn erc20_transfer(
// let gas_limit = Some(handle.remaining_gas());
let gas_limit = None;
let is_static = false;
let caller = handle.context().caller;
let context = fp_evm::Context { address: erc20.0, caller, apparent_value: U256::zero() };
let context =
fp_evm::Context { address: erc20.0, caller: caller.0, apparent_value: U256::zero() };
let (exit_reason, output) = handle.call(erc20.0, None, data, gas_limit, is_static, &context);

log::debug!(
Expand Down
Loading

0 comments on commit 484f0dc

Please sign in to comment.