Skip to content

Commit c39707e

Browse files
boundless-forestashutoshvarma
authored andcommitted
Extend the Executed event (polkadot-evm#1040)
* Extend the event * Code clean * Update comment * Fix tests * Add event extra_bytes tests * Asign `data.len()` to a variable * Fix review
1 parent dd86bb0 commit c39707e

7 files changed

Lines changed: 270 additions & 40 deletions

File tree

frame/ethereum/src/lib.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use sp_runtime::{
5858
transaction_validity::{
5959
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransactionBuilder,
6060
},
61-
DispatchErrorWithPostInfo, RuntimeDebug,
61+
DispatchErrorWithPostInfo, RuntimeDebug, SaturatedConversion,
6262
};
6363
use sp_std::{marker::PhantomData, prelude::*};
6464

@@ -199,6 +199,8 @@ pub mod pallet {
199199
type StateRoot: Get<H256>;
200200
/// What's included in the PostLog.
201201
type PostLogContent: Get<PostLogContent>;
202+
/// The maximum length of the extra data in the Executed event.
203+
type ExtraDataLength: Get<u32>;
202204
}
203205

204206
#[pallet::hooks]
@@ -305,6 +307,7 @@ pub mod pallet {
305307
to: H160,
306308
transaction_hash: H256,
307309
exit_reason: ExitReason,
310+
extra_data: Vec<u8>,
308311
},
309312
}
310313

@@ -550,9 +553,9 @@ impl<T: Config> Pallet<T> {
550553
let transaction_hash = transaction.hash();
551554
let transaction_index = pending.len() as u32;
552555

553-
let (reason, status, used_gas, dest) = match info {
556+
let (reason, status, used_gas, dest, extra_data) = match info {
554557
CallOrCreateInfo::Call(info) => (
555-
info.exit_reason,
558+
info.exit_reason.clone(),
556559
TransactionStatus {
557560
transaction_hash,
558561
transaction_index,
@@ -568,6 +571,31 @@ impl<T: Config> Pallet<T> {
568571
},
569572
info.used_gas,
570573
to,
574+
match info.exit_reason {
575+
ExitReason::Revert(_) => {
576+
const LEN_START: usize = 36;
577+
const MESSAGE_START: usize = 68;
578+
579+
let data = info.value;
580+
let data_len = data.len();
581+
if data_len > MESSAGE_START {
582+
let message_len = U256::from(&data[LEN_START..MESSAGE_START])
583+
.saturated_into::<usize>();
584+
let message_end = MESSAGE_START.saturating_add(
585+
message_len.min(T::ExtraDataLength::get() as usize),
586+
);
587+
588+
if data_len >= message_end {
589+
data[MESSAGE_START..message_end].to_vec()
590+
} else {
591+
data
592+
}
593+
} else {
594+
data
595+
}
596+
}
597+
_ => vec![],
598+
},
571599
),
572600
CallOrCreateInfo::Create(info) => (
573601
info.exit_reason,
@@ -586,6 +614,7 @@ impl<T: Config> Pallet<T> {
586614
},
587615
info.used_gas,
588616
Some(info.value),
617+
Vec::new(),
589618
),
590619
};
591620

@@ -634,6 +663,7 @@ impl<T: Config> Pallet<T> {
634663
to: dest.unwrap_or_default(),
635664
transaction_hash,
636665
exit_reason: reason,
666+
extra_data,
637667
});
638668

639669
Ok(PostDispatchInfo {

frame/ethereum/src/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ impl Config for Test {
180180
type RuntimeEvent = RuntimeEvent;
181181
type StateRoot = IntermediateStateRoot<Self>;
182182
type PostLogContent = PostBlockAndTxnHashes;
183+
type ExtraDataLength = ConstU32<30>;
183184
}
184185

185186
impl fp_self_contained::SelfContainedCall for RuntimeCall {

frame/ethereum/src/tests/eip1559.rs

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//! Consensus extension module tests for BABE consensus.
1919
2020
use super::*;
21+
use evm::{ExitReason, ExitRevert, ExitSucceed};
2122
use fp_ethereum::ValidatedTransaction;
2223
use frame_support::{dispatch::DispatchClass, traits::Get, weights::Weight};
2324
use pallet_evm::{AddressMapping, GasWeightMapping};
@@ -340,17 +341,6 @@ fn transaction_should_generate_correct_gas_used() {
340341

341342
#[test]
342343
fn call_should_handle_errors() {
343-
// pragma solidity ^0.6.6;
344-
// contract Test {
345-
// function foo() external pure returns (bool) {
346-
// return true;
347-
// }
348-
// function bar() external pure {
349-
// require(false, "error_msg");
350-
// }
351-
// }
352-
let contract: &str = "608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063c2985578146037578063febb0f7e146057575b600080fd5b603d605f565b604051808215151515815260200191505060405180910390f35b605d6068565b005b60006001905090565b600060db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f6572726f725f6d7367000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b56fea2646970667358221220fde68a3968e0e99b16fabf9b2997a78218b32214031f8e07e2c502daf603a69e64736f6c63430006060033";
353-
354344
let (pairs, mut ext) = new_test_ext(1);
355345
let alice = &pairs[0];
356346

@@ -362,7 +352,7 @@ fn call_should_handle_errors() {
362352
gas_limit: U256::from(0x100000),
363353
action: ethereum::TransactionAction::Create,
364354
value: U256::zero(),
365-
input: hex::decode(contract).unwrap(),
355+
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
366356
}
367357
.sign(&alice.private_key, None);
368358
assert_ok!(Ethereum::execute(alice.address, &t, None,));
@@ -411,6 +401,80 @@ fn call_should_handle_errors() {
411401
});
412402
}
413403

404+
#[test]
405+
fn event_extra_data_should_be_handle_properly() {
406+
let (pairs, mut ext) = new_test_ext(1);
407+
let alice = &pairs[0];
408+
409+
ext.execute_with(|| {
410+
System::set_block_number(1);
411+
412+
let t = EIP1559UnsignedTransaction {
413+
nonce: U256::zero(),
414+
max_priority_fee_per_gas: U256::from(1),
415+
max_fee_per_gas: U256::from(1),
416+
gas_limit: U256::from(0x100000),
417+
action: ethereum::TransactionAction::Create,
418+
value: U256::zero(),
419+
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
420+
}
421+
.sign(&alice.private_key, None);
422+
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t));
423+
424+
let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
425+
let foo = hex::decode("c2985578").unwrap();
426+
let bar = hex::decode("febb0f7e").unwrap();
427+
428+
let t2 = EIP1559UnsignedTransaction {
429+
nonce: U256::from(1),
430+
max_priority_fee_per_gas: U256::from(1),
431+
max_fee_per_gas: U256::from(1),
432+
gas_limit: U256::from(0x100000),
433+
action: TransactionAction::Call(H160::from_slice(&contract_address)),
434+
value: U256::zero(),
435+
input: foo,
436+
}
437+
.sign(&alice.private_key, None);
438+
439+
// calling foo
440+
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t2));
441+
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
442+
from: alice.address,
443+
to: H160::from_slice(&contract_address),
444+
transaction_hash: H256::from_str(
445+
"0x66036e60bafa1fabb847679d86d1f0a027ae52afde7690aaadf6f81c7e8ecda2",
446+
)
447+
.unwrap(),
448+
exit_reason: ExitReason::Succeed(ExitSucceed::Returned),
449+
extra_data: vec![],
450+
}));
451+
452+
let t3 = EIP1559UnsignedTransaction {
453+
nonce: U256::from(2),
454+
max_priority_fee_per_gas: U256::from(1),
455+
max_fee_per_gas: U256::from(1),
456+
gas_limit: U256::from(0x100000),
457+
action: TransactionAction::Call(H160::from_slice(&contract_address)),
458+
value: U256::zero(),
459+
input: bar,
460+
}
461+
.sign(&alice.private_key, None);
462+
463+
// calling bar revert
464+
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t3));
465+
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
466+
from: alice.address,
467+
to: H160::from_slice(&contract_address),
468+
transaction_hash: H256::from_str(
469+
"0xf14cd5e6d0535a8407339dabce26616a3f19c2048937450859ea65d5201fb7e4",
470+
)
471+
.unwrap(),
472+
exit_reason: ExitReason::Revert(ExitRevert::Reverted),
473+
extra_data: b"very_long_error_msg_that_we_ex".to_vec(),
474+
}));
475+
});
476+
}
477+
414478
#[test]
415479
fn self_contained_transaction_with_extra_gas_should_adjust_weight_with_post_dispatch() {
416480
let (pairs, mut ext) = new_test_ext(1);

frame/ethereum/src/tests/eip2930.rs

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//! Consensus extension module tests for BABE consensus.
1919
2020
use super::*;
21+
use evm::{ExitReason, ExitRevert, ExitSucceed};
2122
use fp_ethereum::ValidatedTransaction;
2223
use frame_support::{
2324
dispatch::{DispatchClass, GetDispatchInfo},
@@ -267,17 +268,6 @@ fn transaction_should_generate_correct_gas_used() {
267268

268269
#[test]
269270
fn call_should_handle_errors() {
270-
// pragma solidity ^0.6.6;
271-
// contract Test {
272-
// function foo() external pure returns (bool) {
273-
// return true;
274-
// }
275-
// function bar() external pure {
276-
// require(false, "error_msg");
277-
// }
278-
// }
279-
let contract: &str = "608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063c2985578146037578063febb0f7e146057575b600080fd5b603d605f565b604051808215151515815260200191505060405180910390f35b605d6068565b005b60006001905090565b600060db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f6572726f725f6d7367000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b56fea2646970667358221220fde68a3968e0e99b16fabf9b2997a78218b32214031f8e07e2c502daf603a69e64736f6c63430006060033";
280-
281271
let (pairs, mut ext) = new_test_ext(1);
282272
let alice = &pairs[0];
283273

@@ -288,7 +278,7 @@ fn call_should_handle_errors() {
288278
gas_limit: U256::from(0x100000),
289279
action: ethereum::TransactionAction::Create,
290280
value: U256::zero(),
291-
input: hex::decode(contract).unwrap(),
281+
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
292282
}
293283
.sign(&alice.private_key, None);
294284
assert_ok!(Ethereum::execute(alice.address, &t, None,));
@@ -335,6 +325,77 @@ fn call_should_handle_errors() {
335325
});
336326
}
337327

328+
#[test]
329+
fn event_extra_data_should_be_handle_properly() {
330+
let (pairs, mut ext) = new_test_ext(1);
331+
let alice = &pairs[0];
332+
333+
ext.execute_with(|| {
334+
System::set_block_number(1);
335+
336+
let t = EIP2930UnsignedTransaction {
337+
nonce: U256::zero(),
338+
gas_price: U256::from(1),
339+
gas_limit: U256::from(0x100000),
340+
action: ethereum::TransactionAction::Create,
341+
value: U256::zero(),
342+
input: hex::decode(TEST_CONTRACT_CODE).unwrap(),
343+
}
344+
.sign(&alice.private_key, None);
345+
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t));
346+
347+
let contract_address = hex::decode("32dcab0ef3fb2de2fce1d2e0799d36239671f04a").unwrap();
348+
let foo = hex::decode("c2985578").unwrap();
349+
let bar = hex::decode("febb0f7e").unwrap();
350+
351+
let t2 = EIP2930UnsignedTransaction {
352+
nonce: U256::from(1),
353+
gas_price: U256::from(1),
354+
gas_limit: U256::from(0x100000),
355+
action: TransactionAction::Call(H160::from_slice(&contract_address)),
356+
value: U256::zero(),
357+
input: foo,
358+
}
359+
.sign(&alice.private_key, None);
360+
361+
// calling foo
362+
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t2));
363+
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
364+
from: alice.address,
365+
to: H160::from_slice(&contract_address),
366+
transaction_hash: H256::from_str(
367+
"0xd953990ba4a99074c5b8c7a9f97546ffbf781815acc2dcc2719ac3d0c8955a00",
368+
)
369+
.unwrap(),
370+
exit_reason: ExitReason::Succeed(ExitSucceed::Returned),
371+
extra_data: vec![],
372+
}));
373+
374+
let t3 = EIP2930UnsignedTransaction {
375+
nonce: U256::from(2),
376+
gas_price: U256::from(1),
377+
gas_limit: U256::from(0x100000),
378+
action: TransactionAction::Call(H160::from_slice(&contract_address)),
379+
value: U256::zero(),
380+
input: bar,
381+
}
382+
.sign(&alice.private_key, None);
383+
384+
// calling bar revert
385+
assert_ok!(Ethereum::apply_validated_transaction(alice.address, t3));
386+
System::assert_last_event(RuntimeEvent::Ethereum(Event::Executed {
387+
from: alice.address,
388+
to: H160::from_slice(&contract_address),
389+
transaction_hash: H256::from_str(
390+
"0xbcb3fd14507b3aba8a124b007d959bf18d59f87c6d6c036e8feac224ec5fabeb",
391+
)
392+
.unwrap(),
393+
exit_reason: ExitReason::Revert(ExitRevert::Reverted),
394+
extra_data: b"very_long_error_msg_that_we_ex".to_vec(),
395+
}));
396+
});
397+
}
398+
338399
#[test]
339400
fn self_contained_transaction_with_extra_gas_should_adjust_weight_with_post_dispatch() {
340401
let (pairs, mut ext) = new_test_ext(1);

0 commit comments

Comments
 (0)