Skip to content

Commit

Permalink
Extend the Executed event (#1040)
Browse files Browse the repository at this point in the history
* Extend the event

* Code clean

* Update comment

* Fix tests

* Add event extra_bytes tests

* Asign `data.len()` to a variable

* Fix review
  • Loading branch information
boundless-forest authored Apr 18, 2023
1 parent 2b09a67 commit 8914332
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 40 deletions.
36 changes: 33 additions & 3 deletions frame/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use sp_runtime::{
transaction_validity::{
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransactionBuilder,
},
DispatchErrorWithPostInfo, RuntimeDebug,
DispatchErrorWithPostInfo, RuntimeDebug, SaturatedConversion,
};
use sp_std::{marker::PhantomData, prelude::*};

Expand Down Expand Up @@ -196,6 +196,8 @@ pub mod pallet {
type StateRoot: Get<H256>;
/// What's included in the PostLog.
type PostLogContent: Get<PostLogContent>;
/// The maximum length of the extra data in the Executed event.
type ExtraDataLength: Get<u32>;
}

#[pallet::hooks]
Expand Down Expand Up @@ -302,6 +304,7 @@ pub mod pallet {
to: H160,
transaction_hash: H256,
exit_reason: ExitReason,
extra_data: Vec<u8>,
},
}

Expand Down Expand Up @@ -545,9 +548,9 @@ impl<T: Config> Pallet<T> {
let transaction_hash = transaction.hash();
let transaction_index = pending.len() as u32;

let (reason, status, used_gas, dest) = match info {
let (reason, status, used_gas, dest, extra_data) = match info {
CallOrCreateInfo::Call(info) => (
info.exit_reason,
info.exit_reason.clone(),
TransactionStatus {
transaction_hash,
transaction_index,
Expand All @@ -563,6 +566,31 @@ impl<T: Config> Pallet<T> {
},
info.used_gas,
to,
match info.exit_reason {
ExitReason::Revert(_) => {
const LEN_START: usize = 36;
const MESSAGE_START: usize = 68;

let data = info.value;
let data_len = data.len();
if data_len > MESSAGE_START {
let message_len = U256::from(&data[LEN_START..MESSAGE_START])
.saturated_into::<usize>();
let message_end = MESSAGE_START.saturating_add(
message_len.min(T::ExtraDataLength::get() as usize),
);

if data_len >= message_end {
data[MESSAGE_START..message_end].to_vec()
} else {
data
}
} else {
data
}
}
_ => vec![],
},
),
CallOrCreateInfo::Create(info) => (
info.exit_reason,
Expand All @@ -581,6 +609,7 @@ impl<T: Config> Pallet<T> {
},
info.used_gas,
Some(info.value),
Vec::new(),
),
};

Expand Down Expand Up @@ -629,6 +658,7 @@ impl<T: Config> Pallet<T> {
to: dest.unwrap_or_default(),
transaction_hash,
exit_reason: reason,
extra_data,
});

Ok(PostDispatchInfo {
Expand Down
1 change: 1 addition & 0 deletions frame/ethereum/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type StateRoot = IntermediateStateRoot<Self>;
type PostLogContent = PostBlockAndTxnHashes;
type ExtraDataLength = ConstU32<30>;
}

impl fp_self_contained::SelfContainedCall for RuntimeCall {
Expand Down
88 changes: 76 additions & 12 deletions frame/ethereum/src/tests/eip1559.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//! Consensus extension module tests for BABE consensus.
use super::*;
use evm::{ExitReason, ExitRevert, ExitSucceed};
use fp_ethereum::ValidatedTransaction;
use frame_support::{dispatch::DispatchClass, traits::Get, weights::Weight};
use pallet_evm::{AddressMapping, GasWeightMapping};
Expand Down Expand Up @@ -340,17 +341,6 @@ fn transaction_should_generate_correct_gas_used() {

#[test]
fn call_should_handle_errors() {
// pragma solidity ^0.6.6;
// contract Test {
// function foo() external pure returns (bool) {
// return true;
// }
// function bar() external pure {
// require(false, "error_msg");
// }
// }
let contract: &str = "608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063c2985578146037578063febb0f7e146057575b600080fd5b603d605f565b604051808215151515815260200191505060405180910390f35b605d6068565b005b60006001905090565b600060db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f6572726f725f6d7367000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b56fea2646970667358221220fde68a3968e0e99b16fabf9b2997a78218b32214031f8e07e2c502daf603a69e64736f6c63430006060033";

let (pairs, mut ext) = new_test_ext(1);
let alice = &pairs[0];

Expand All @@ -362,7 +352,7 @@ fn call_should_handle_errors() {
gas_limit: U256::from(0x100000),
action: ethereum::TransactionAction::Create,
value: U256::zero(),
input: hex::decode(contract).unwrap(),
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
Expand Down Expand Up @@ -411,6 +401,80 @@ fn call_should_handle_errors() {
});
}

#[test]
fn event_extra_data_should_be_handle_properly() {
let (pairs, mut ext) = new_test_ext(1);
let alice = &pairs[0];

ext.execute_with(|| {
System::set_block_number(1);

let t = EIP1559UnsignedTransaction {
nonce: U256::zero(),
max_priority_fee_per_gas: U256::from(1),
max_fee_per_gas: U256::from(1),
gas_limit: U256::from(0x100000),
action: ethereum::TransactionAction::Create,
value: U256::zero(),
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t));

let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
let foo = hex::decode("c2985578").unwrap();
let bar = hex::decode("febb0f7e").unwrap();

let t2 = EIP1559UnsignedTransaction {
nonce: U256::from(1),
max_priority_fee_per_gas: U256::from(1),
max_fee_per_gas: U256::from(1),
gas_limit: U256::from(0x100000),
action: TransactionAction::Call(H160::from_slice(&contract_address)),
value: U256::zero(),
input: foo,
}
.sign(&alice.private_key, None);

// calling foo
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t2));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
transaction_hash: H256::from_str(
"0x66036e60bafa1fabb847679d86d1f0a027ae52afde7690aaadf6f81c7e8ecda2",
)
.unwrap(),
exit_reason: ExitReason::Succeed(ExitSucceed::Returned),
extra_data: vec![],
}));

let t3 = EIP1559UnsignedTransaction {
nonce: U256::from(2),
max_priority_fee_per_gas: U256::from(1),
max_fee_per_gas: U256::from(1),
gas_limit: U256::from(0x100000),
action: TransactionAction::Call(H160::from_slice(&contract_address)),
value: U256::zero(),
input: bar,
}
.sign(&alice.private_key, None);

// calling bar revert
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t3));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
transaction_hash: H256::from_str(
"0xf14cd5e6d0535a8407339dabce26616a3f19c2048937450859ea65d5201fb7e4",
)
.unwrap(),
exit_reason: ExitReason::Revert(ExitRevert::Reverted),
extra_data: b"very_long_error_msg_that_we_ex".to_vec(),
}));
});
}

#[test]
fn self_contained_transaction_with_extra_gas_should_adjust_weight_with_post_dispatch() {
let (pairs, mut ext) = new_test_ext(1);
Expand Down
85 changes: 73 additions & 12 deletions frame/ethereum/src/tests/eip2930.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//! Consensus extension module tests for BABE consensus.
use super::*;
use evm::{ExitReason, ExitRevert, ExitSucceed};
use fp_ethereum::ValidatedTransaction;
use frame_support::{
dispatch::{DispatchClass, GetDispatchInfo},
Expand Down Expand Up @@ -267,17 +268,6 @@ fn transaction_should_generate_correct_gas_used() {

#[test]
fn call_should_handle_errors() {
// pragma solidity ^0.6.6;
// contract Test {
// function foo() external pure returns (bool) {
// return true;
// }
// function bar() external pure {
// require(false, "error_msg");
// }
// }
let contract: &str = "608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063c2985578146037578063febb0f7e146057575b600080fd5b603d605f565b604051808215151515815260200191505060405180910390f35b605d6068565b005b60006001905090565b600060db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f6572726f725f6d7367000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b56fea2646970667358221220fde68a3968e0e99b16fabf9b2997a78218b32214031f8e07e2c502daf603a69e64736f6c63430006060033";

let (pairs, mut ext) = new_test_ext(1);
let alice = &pairs[0];

Expand All @@ -288,7 +278,7 @@ fn call_should_handle_errors() {
gas_limit: U256::from(0x100000),
action: ethereum::TransactionAction::Create,
value: U256::zero(),
input: hex::decode(contract).unwrap(),
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::execute(alice.address, &t, None,));
Expand Down Expand Up @@ -335,6 +325,77 @@ fn call_should_handle_errors() {
});
}

#[test]
fn event_extra_data_should_be_handle_properly() {
let (pairs, mut ext) = new_test_ext(1);
let alice = &pairs[0];

ext.execute_with(|| {
System::set_block_number(1);

let t = EIP2930UnsignedTransaction {
nonce: U256::zero(),
gas_price: U256::from(1),
gas_limit: U256::from(0x100000),
action: ethereum::TransactionAction::Create,
value: U256::zero(),
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
}
.sign(&alice.private_key, None);
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t));

let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
let foo = hex::decode("c2985578").unwrap();
let bar = hex::decode("febb0f7e").unwrap();

let t2 = EIP2930UnsignedTransaction {
nonce: U256::from(1),
gas_price: U256::from(1),
gas_limit: U256::from(0x100000),
action: TransactionAction::Call(H160::from_slice(&contract_address)),
value: U256::zero(),
input: foo,
}
.sign(&alice.private_key, None);

// calling foo
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t2));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
transaction_hash: H256::from_str(
"0xd953990ba4a99074c5b8c7a9f97546ffbf781815acc2dcc2719ac3d0c8955a00",
)
.unwrap(),
exit_reason: ExitReason::Succeed(ExitSucceed::Returned),
extra_data: vec![],
}));

let t3 = EIP2930UnsignedTransaction {
nonce: U256::from(2),
gas_price: U256::from(1),
gas_limit: U256::from(0x100000),
action: TransactionAction::Call(H160::from_slice(&contract_address)),
value: U256::zero(),
input: bar,
}
.sign(&alice.private_key, None);

// calling bar revert
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t3));
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
from: alice.address,
to: H160::from_slice(&contract_address),
transaction_hash: H256::from_str(
"0xbcb3fd14507b3aba8a124b007d959bf18d59f87c6d6c036e8feac224ec5fabeb",
)
.unwrap(),
exit_reason: ExitReason::Revert(ExitRevert::Reverted),
extra_data: b"very_long_error_msg_that_we_ex".to_vec(),
}));
});
}

#[test]
fn self_contained_transaction_with_extra_gas_should_adjust_weight_with_post_dispatch() {
let (pairs, mut ext) = new_test_ext(1);
Expand Down
Loading

0 comments on commit 8914332

Please sign in to comment.