Skip to content

Commit

Permalink
Optimising code
Browse files Browse the repository at this point in the history
  • Loading branch information
hqwangningbo committed Dec 11, 2023
1 parent 1b0be5f commit 482d576
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 34 deletions.
62 changes: 31 additions & 31 deletions pallets/slpx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use crate::types::{
AccountIdOf, BalanceOf, CurrencyIdOf, EthereumCallConfiguration, EthereumXcmCall,
EthereumXcmTransaction, EthereumXcmTransactionV2, MoonbeamCall, SupportChain, TargetChain,
EVM_FUNCTION_SELECTOR, MAX_GAS_LIMIT,
};
use bifrost_asset_registry::AssetMetadata;
use bifrost_primitives::{
Expand Down Expand Up @@ -205,7 +206,7 @@ pub mod pallet {
period: BlockNumberFor<T>,
contract: H160,
},
XcmEthereumCallSetTokenAmount {
XcmSetTokenAmount {
currency_id: CurrencyId,
token_amount: BalanceOf<T>,
vcurrency_id: CurrencyId,
Expand Down Expand Up @@ -288,21 +289,23 @@ pub mod pallet {
let configuration = XcmEthereumCallConfiguration::<T>::get();
match configuration {
Some(mut configuration) => {
let currency = currency_list[0];
let token_amount = T::VtokenMintingInterface::get_token_pool(currency);
let currency_id = currency_list[0];
let token_amount = T::VtokenMintingInterface::get_token_pool(currency_id);
// It's impossible to go wrong.
let vtoken = T::VtokenMintingInterface::vtoken_id(currency)
.expect("Error convert vtoken");
let vtoken_amount = T::MultiCurrency::total_issuance(vtoken);
let vcurrency_id = T::VtokenMintingInterface::vtoken_id(currency_id)
.expect("Error convert vcurrency_id");
let vtoken_amount = T::MultiCurrency::total_issuance(vcurrency_id);

if configuration.last_block + configuration.period < n {
let ethereum_call: Vec<u8> =
Self::ethereum_call(currency, token_amount, vtoken_amount);
let transact_call =
Self::transact_call(configuration.contract, ethereum_call);
let encoded_call = Self::encode_transact_call(
configuration.contract,
currency_id,
token_amount,
vtoken_amount,
);

let result = Self::send_xcm_to_set_token_amount(
transact_call,
encoded_call,
configuration.xcm_weight,
configuration.xcm_fee,
);
Expand All @@ -311,10 +314,10 @@ pub mod pallet {
return weight
.saturating_add(T::DbWeight::get().reads_writes(4, 0));
}
Self::deposit_event(Event::XcmEthereumCallSetTokenAmount {
currency_id: currency,
Self::deposit_event(Event::XcmSetTokenAmount {
currency_id,
token_amount,
vcurrency_id: vtoken,
vcurrency_id,
vtoken_amount,
});

Expand Down Expand Up @@ -794,43 +797,40 @@ impl<T: Config> Pallet<T> {
}

/// setTokenAmount(bytes2,uint256,uint256)
pub fn ethereum_call(
pub fn encode_ethereum_call(
currency_id: CurrencyId,
token_amount: BalanceOf<T>,
vtoken_amount: BalanceOf<T>,
) -> Vec<u8> {
use tiny_keccak::Hasher;

let bytes2_currency_id: Vec<u8> = currency_id.encode()[..2].to_vec();
let uint256_token_amount = U256::from(token_amount.saturated_into::<u128>());
let uint256_vtoken_amount = U256::from(vtoken_amount.saturated_into::<u128>());
let mut selector = [0; 4];
let mut sha3 = tiny_keccak::Keccak::v256();
sha3.update(b"setTokenAmount(bytes2,uint256,uint256)");
sha3.finalize(&mut selector);

let parameters_data = ethabi::encode(&[
let mut call = ethabi::encode(&[
ethabi::Token::FixedBytes(bytes2_currency_id),
ethabi::Token::Uint(uint256_token_amount),
ethabi::Token::Uint(uint256_vtoken_amount),
]);

let mut encode_data: Vec<u8> = vec![];
encode_data.extend(selector);
encode_data.extend(parameters_data);

return encode_data;
call.splice(0..0, EVM_FUNCTION_SELECTOR);
call
}

pub fn transact_call(contract: H160, ethereum_call: Vec<u8>) -> Vec<u8> {
let r = EthereumXcmTransaction::V2(EthereumXcmTransactionV2 {
gas_limit: U256::from(720000),
pub fn encode_transact_call(
contract: H160,
currency_id: CurrencyId,
token_amount: BalanceOf<T>,
vtoken_amount: BalanceOf<T>,
) -> Vec<u8> {
let ethereum_call = Self::encode_ethereum_call(currency_id, token_amount, vtoken_amount);
let transaction = EthereumXcmTransaction::V2(EthereumXcmTransactionV2 {
gas_limit: U256::from(MAX_GAS_LIMIT),
action: TransactionAction::Call(contract),
value: U256::zero(),
input: BoundedVec::try_from(ethereum_call).unwrap(),
access_list: None,
});
return MoonbeamCall::EthereumXcm(EthereumXcmCall::Transact(r)).encode();
return MoonbeamCall::EthereumXcm(EthereumXcmCall::Transact(transaction)).encode();
}

/// Check if the signer is in the whitelist
Expand Down
22 changes: 19 additions & 3 deletions pallets/slpx/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use frame_support::{assert_noop, assert_ok, dispatch::RawOrigin};
use hex_literal::hex;
use sp_core::{bounded::BoundedVec, ConstU32, U256};
use sp_io;
use tiny_keccak::Hasher;
use zenlink_protocol::AssetId;

const EVM_ADDR: [u8; 20] = hex!["573394b77fC17F91E9E67F147A9ECe24d67C5073"];
Expand Down Expand Up @@ -238,22 +239,37 @@ fn test_ed() {
});
}

#[test]
fn test_selector() {
let mut selector = [0; 4];
let mut sha3 = tiny_keccak::Keccak::v256();
sha3.update(b"setTokenAmount(bytes2,uint256,uint256)");
sha3.finalize(&mut selector);

assert_eq!([154, 65, 185, 36], selector);
println!("{:?}", selector);
println!("{:?}", hex::encode(selector));
assert_eq!("9a41b924", hex::encode(selector));
}

#[test]
fn test_ethereum_call() {
sp_io::TestExternalities::default().execute_with(|| {
// b"setTokenAmount(bytes2,uint256,uint256)"
assert_eq!("9a41b9240001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c8", hex::encode(Slpx::ethereum_call(BNC, 123u128, 456u128)));
// b"setTokenAmount(bytes2,uint256,bytes2,uint256)"
assert_eq!("9a41b9240001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c8", hex::encode(Slpx::encode_ethereum_call(BNC, 123u128, 456u128)));

println!("{:?}", hex::encode(Slpx::encode_ethereum_call(BNC, 123u128, 456u128)));
let addr: [u8; 20] = hex!["ae0daa9bfc50f03ce23d30c796709a58470b5f42"];
let r = EthereumXcmTransaction::V2(EthereumXcmTransactionV2 {
gas_limit: U256::from(720000),
action: TransactionAction::Call(H160::from(addr)),
value: U256::zero(),
input: BoundedVec::try_from(Slpx::ethereum_call(BNC, 123u128, 456u128)).unwrap(),
input: Slpx::encode_ethereum_call(BNC, 123u128, 456u128).try_into().unwrap(),
access_list: None,
});
let call = MoonbeamCall::EthereumXcm(EthereumXcmCall::Transact(r));
println!("{}", hex::encode(call.encode()));
assert_eq!("6d000180fc0a000000000000000000000000000000000000000000000000000000000000ae0daa9bfc50f03ce23d30c796709a58470b5f42000000000000000000000000000000000000000000000000000000000000000091019a41b9240001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c800", hex::encode(Slpx::encode_transact_call(H160::from(addr), BNC, 123u128, 456u128)));
})
}

Expand Down
6 changes: 6 additions & 0 deletions pallets/slpx/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ use xcm::prelude::Weight;
/// Max. allowed size of 65_536 bytes.
pub const MAX_ETHEREUM_XCM_INPUT_SIZE: u32 = 2u32.pow(16);

/// Max. allowed gas limit of 720_000 gas units. Note that this might change in the future.
pub const MAX_GAS_LIMIT: u32 = 720_000;

/// EVM function selector: setTokenAmount(bytes2,uint256,uint256)
pub const EVM_FUNCTION_SELECTOR: [u8; 4] = [154, 65, 185, 36];

pub type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
pub type CurrencyIdOf<T> = <<T as pallet::Config>::MultiCurrency as MultiCurrency<
<T as frame_system::Config>::AccountId,
Expand Down

0 comments on commit 482d576

Please sign in to comment.