Skip to content

Commit

Permalink
Merge pull request #221 from moonbeam-foundation/elois-native-foreign…
Browse files Browse the repository at this point in the history
…-assets

support create to a fixed address
  • Loading branch information
librelois authored and TarekkMA committed Oct 25, 2024
1 parent b47c87c commit 41d576b
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 64 deletions.
89 changes: 61 additions & 28 deletions frame/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ pub mod pallet {
Self::validate_transaction_in_block(source, &transaction).expect(
"pre-block transaction verification failed; the block cannot be built",
);
let (r, _) = Self::apply_validated_transaction(source, transaction)
let (r, _) = Self::apply_validated_transaction(source, transaction, None)
.expect("pre-block apply transaction failed; the block cannot be built");

weight = weight.saturating_add(r.actual_weight.unwrap_or_default());
Expand Down Expand Up @@ -326,7 +326,7 @@ pub mod pallet {
"pre log already exists; block is invalid",
);

Self::apply_validated_transaction(source, transaction).map(|(post_info, _)| post_info)
Self::apply_validated_transaction(source, transaction, None).map(|(post_info, _)| post_info)
}
}

Expand Down Expand Up @@ -604,8 +604,9 @@ impl<T: Config> Pallet<T> {
fn apply_validated_transaction(
source: H160,
transaction: Transaction,
maybe_force_create_address: Option<H160>,
) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> {
let (to, _, info) = Self::execute(source, &transaction, None)?;
let (to, _, info) = Self::execute(source, &transaction, None, maybe_force_create_address)?;

catch_exec_info::fill_exec_info(&info);

Expand Down Expand Up @@ -761,6 +762,7 @@ impl<T: Config> Pallet<T> {
from: H160,
transaction: &Transaction,
config: Option<evm::Config>,
maybe_force_create_address: Option<H160>,
) -> Result<(Option<H160>, Option<H160>, CallOrCreateInfo), DispatchErrorWithPostInfo> {
let transaction_data: TransactionData = transaction.into();
let (weight_limit, proof_size_base_cost) = Self::transaction_weight(&transaction_data);
Expand Down Expand Up @@ -860,30 +862,60 @@ impl<T: Config> Pallet<T> {
Ok((Some(target), None, CallOrCreateInfo::Call(res)))
}
ethereum::TransactionAction::Create => {
let res = match T::Runner::create(
from,
input,
value,
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
access_list,
is_transactional,
validate,
weight_limit,
proof_size_base_cost,
config.as_ref().unwrap_or_else(|| T::config()),
) {
Ok(res) => res,
Err(e) => {
return Err(DispatchErrorWithPostInfo {
post_info: PostDispatchInfo {
actual_weight: Some(e.weight),
pays_fee: Pays::Yes,
},
error: e.error.into(),
})
let res = if let Some(force_address) = maybe_force_create_address {
match T::Runner::create_force_address(
from,
input,
value,
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
access_list,
is_transactional,
validate,
weight_limit,
proof_size_base_cost,
config.as_ref().unwrap_or_else(|| T::config()),
force_address,
) {
Ok(res) => res,
Err(e) => {
return Err(DispatchErrorWithPostInfo {
post_info: PostDispatchInfo {
actual_weight: Some(e.weight),
pays_fee: Pays::Yes,
},
error: e.error.into(),
})
}
}
} else {
match T::Runner::create(
from,
input,
value,
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
access_list,
is_transactional,
validate,
weight_limit,
proof_size_base_cost,
config.as_ref().unwrap_or_else(|| T::config()),
) {
Ok(res) => res,
Err(e) => {
return Err(DispatchErrorWithPostInfo {
post_info: PostDispatchInfo {
actual_weight: Some(e.weight),
pays_fee: Pays::Yes,
},
error: e.error.into(),
})
}
}
};

Expand Down Expand Up @@ -1003,8 +1035,9 @@ impl<T: Config> ValidatedTransactionT for ValidatedTransaction<T> {
fn apply(
source: H160,
transaction: Transaction,
maybe_force_create_address: Option<H160>,
) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> {
Pallet::<T>::apply_validated_transaction(source, transaction)
Pallet::<T>::apply_validated_transaction(source, transaction, maybe_force_create_address)
}
}

Expand Down
39 changes: 27 additions & 12 deletions frame/ethereum/src/tests/eip1559.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ fn transaction_should_increment_nonce() {

ext.execute_with(|| {
let t = eip1559_erc20_creation_transaction(alice);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
assert_eq!(EVM::account_basic(&alice.address).0.nonce, U256::from(1));
});
}
Expand Down Expand Up @@ -188,7 +188,7 @@ fn transaction_with_to_low_nonce_should_not_work() {
let t = eip1559_erc20_creation_transaction(alice);

// nonce is 1
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
transaction.nonce = U256::from(0);

let signed2 = transaction.sign(&alice.private_key, None);
Expand Down Expand Up @@ -271,7 +271,7 @@ fn contract_constructor_should_get_executed() {
ext.execute_with(|| {
let t = eip1559_erc20_creation_transaction(alice);

assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
assert_eq!(
pallet_evm::AccountStorages::<Test>::get(erc20_address, alice_storage_address),
H256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
Expand Down Expand Up @@ -313,7 +313,7 @@ fn contract_should_be_created_at_given_address() {

ext.execute_with(|| {
let t = eip1559_erc20_creation_transaction(alice);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
assert_ne!(
pallet_evm::AccountCodes::<Test>::get(erc20_address).len(),
0
Expand All @@ -330,7 +330,7 @@ fn transaction_should_generate_correct_gas_used() {

ext.execute_with(|| {
let t = eip1559_erc20_creation_transaction(alice);
let (_, _, info) = Ethereum::execute(alice.address, &t, None).unwrap();
let (_, _, info) = Ethereum::execute(alice.address, &t, None, None).unwrap();

match info {
CallOrCreateInfo::Create(info) => {
Expand All @@ -357,7 +357,7 @@ fn call_should_handle_errors() {
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));

let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
let foo = hex::decode("c2985578").unwrap();
Expand All @@ -375,7 +375,7 @@ fn call_should_handle_errors() {
.sign(&alice.private_key, None);

// calling foo will succeed
let (_, _, info) = Ethereum::execute(alice.address, &t2, None).unwrap();
let (_, _, info) = Ethereum::execute(alice.address, &t2, None, None).unwrap();

match info {
CallOrCreateInfo::Call(info) => {
Expand All @@ -399,7 +399,9 @@ fn call_should_handle_errors() {
.sign(&alice.private_key, None);

// calling should always succeed even if the inner EVM execution fails.
Ethereum::execute(alice.address, &t3, None).ok().unwrap();
Ethereum::execute(alice.address, &t3, None, None)
.ok()
.unwrap();
});
}

Expand All @@ -421,7 +423,11 @@ fn event_extra_data_should_be_handle_properly() {
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t,));
assert_ok!(Ethereum::apply_validated_transaction(
alice.address,
t,
None,
));

let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
let foo = hex::decode("c2985578").unwrap();
Expand All @@ -439,7 +445,11 @@ fn event_extra_data_should_be_handle_properly() {
.sign(&alice.private_key, None);

// calling foo
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t2,));
assert_ok!(Ethereum::apply_validated_transaction(
alice.address,
t2,
None,
));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
Expand All @@ -463,7 +473,11 @@ fn event_extra_data_should_be_handle_properly() {
.sign(&alice.private_key, None);

// calling bar revert
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t3,));
assert_ok!(Ethereum::apply_validated_transaction(
alice.address,
t3,
None,
));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
Expand Down Expand Up @@ -544,7 +558,8 @@ fn validated_transaction_apply_zero_gas_price_works() {

assert_ok!(crate::ValidatedTransaction::<Test>::apply(
alice.address,
transaction
transaction,
None,
));
// Alice didn't pay fees, transfer 100 to Bob.
assert_eq!(Balances::free_balance(&substrate_alice), 900);
Expand Down
39 changes: 27 additions & 12 deletions frame/ethereum/src/tests/eip2930.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn transaction_should_increment_nonce() {

ext.execute_with(|| {
let t = eip2930_erc20_creation_transaction(alice);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
assert_eq!(
pallet_evm::Pallet::<Test>::account_basic(&alice.address)
.0
Expand Down Expand Up @@ -119,7 +119,7 @@ fn transaction_with_to_low_nonce_should_not_work() {
let t = eip2930_erc20_creation_transaction(alice);

// nonce is 1
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));

transaction.nonce = U256::from(0);

Expand Down Expand Up @@ -203,7 +203,7 @@ fn contract_constructor_should_get_executed() {
ext.execute_with(|| {
let t = eip2930_erc20_creation_transaction(alice);

assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
assert_eq!(
pallet_evm::AccountStorages::<Test>::get(erc20_address, alice_storage_address),
H256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
Expand Down Expand Up @@ -245,7 +245,7 @@ fn contract_should_be_created_at_given_address() {

ext.execute_with(|| {
let t = eip2930_erc20_creation_transaction(alice);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));
assert_ne!(
pallet_evm::AccountCodes::<Test>::get(erc20_address).len(),
0
Expand All @@ -262,7 +262,7 @@ fn transaction_should_generate_correct_gas_used() {

ext.execute_with(|| {
let t = eip2930_erc20_creation_transaction(alice);
let (_, _, info) = Ethereum::execute(alice.address, &t, None).unwrap();
let (_, _, info) = Ethereum::execute(alice.address, &t, None, None).unwrap();

match info {
CallOrCreateInfo::Create(info) => {
Expand All @@ -288,7 +288,7 @@ fn call_should_handle_errors() {
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
assert_ok!(Ethereum::execute(alice.address, &t, None, None,));

let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
let foo = hex::decode("c2985578").unwrap();
Expand All @@ -305,7 +305,7 @@ fn call_should_handle_errors() {
.sign(&alice.private_key, None);

// calling foo will succeed
let (_, _, info) = Ethereum::execute(alice.address, &t2, None).unwrap();
let (_, _, info) = Ethereum::execute(alice.address, &t2, None, None).unwrap();

match info {
CallOrCreateInfo::Call(info) => {
Expand All @@ -328,7 +328,9 @@ fn call_should_handle_errors() {
.sign(&alice.private_key, None);

// calling should always succeed even if the inner EVM execution fails.
Ethereum::execute(alice.address, &t3, None).ok().unwrap();
Ethereum::execute(alice.address, &t3, None, None)
.ok()
.unwrap();
});
}

Expand All @@ -349,7 +351,11 @@ fn event_extra_data_should_be_handle_properly() {
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t,));
assert_ok!(Ethereum::apply_validated_transaction(
alice.address,
t,
None,
));

let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
let foo = hex::decode("c2985578").unwrap();
Expand All @@ -366,7 +372,11 @@ fn event_extra_data_should_be_handle_properly() {
.sign(&alice.private_key, None);

// calling foo
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t2,));
assert_ok!(Ethereum::apply_validated_transaction(
alice.address,
t2,
None,
));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
Expand All @@ -389,7 +399,11 @@ fn event_extra_data_should_be_handle_properly() {
.sign(&alice.private_key, None);

// calling bar revert
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t3,));
assert_ok!(Ethereum::apply_validated_transaction(
alice.address,
t3,
None,
));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
Expand Down Expand Up @@ -469,7 +483,8 @@ fn validated_transaction_apply_zero_gas_price_works() {

assert_ok!(crate::ValidatedTransaction::<Test>::apply(
alice.address,
transaction
transaction,
None,
));
// Alice didn't pay fees, transfer 100 to Bob.
assert_eq!(Balances::free_balance(&substrate_alice), 900);
Expand Down
Loading

0 comments on commit 41d576b

Please sign in to comment.