#![cfg_attr(not(feature = "std"), no_std)]
#![warn(unused_crate_dependencies)]
pub use ethereum::{
AccessListItem, BlockV2 as Block, LegacyTransactionMessage, Log, ReceiptV3 as Receipt,
TransactionAction, TransactionV2 as Transaction,
};
use ethereum_types::{H160, H256, U256};
use fp_evm::{CallOrCreateInfo, CheckEvmTransactionInput};
use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo};
use scale_codec::{Decode, Encode};
use sp_std::{result::Result, vec::Vec};
pub trait ValidatedTransaction {
fn apply(
source: H160,
transaction: Transaction,
) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo>;
}
#[derive(Clone, Debug, Eq, PartialEq, Encode, Decode)]
pub struct TransactionData {
pub action: TransactionAction,
pub input: Vec<u8>,
pub nonce: U256,
pub gas_limit: U256,
pub gas_price: Option<U256>,
pub max_fee_per_gas: Option<U256>,
pub max_priority_fee_per_gas: Option<U256>,
pub value: U256,
pub chain_id: Option<u64>,
pub access_list: Vec<(H160, Vec<H256>)>,
}
impl TransactionData {
#[allow(clippy::too_many_arguments)]
pub fn new(
action: TransactionAction,
input: Vec<u8>,
nonce: U256,
gas_limit: U256,
gas_price: Option<U256>,
max_fee_per_gas: Option<U256>,
max_priority_fee_per_gas: Option<U256>,
value: U256,
chain_id: Option<u64>,
access_list: Vec<(H160, Vec<H256>)>,
) -> Self {
Self {
action,
input,
nonce,
gas_limit,
gas_price,
max_fee_per_gas,
max_priority_fee_per_gas,
value,
chain_id,
access_list,
}
}
pub fn proof_size_base_cost(&self) -> u64 {
self.encode()
.len()
.saturating_add(65)
.saturating_add(1)
.saturating_add(1) as u64
}
}
impl From<TransactionData> for CheckEvmTransactionInput {
fn from(t: TransactionData) -> Self {
CheckEvmTransactionInput {
to: if let TransactionAction::Call(to) = t.action {
Some(to)
} else {
None
},
chain_id: t.chain_id,
input: t.input,
nonce: t.nonce,
gas_limit: t.gas_limit,
gas_price: t.gas_price,
max_fee_per_gas: t.max_fee_per_gas,
max_priority_fee_per_gas: t.max_priority_fee_per_gas,
value: t.value,
access_list: t.access_list,
}
}
}
impl From<&Transaction> for TransactionData {
fn from(t: &Transaction) -> Self {
match t {
Transaction::Legacy(t) => TransactionData {
action: t.action,
input: t.input.clone(),
nonce: t.nonce,
gas_limit: t.gas_limit,
gas_price: Some(t.gas_price),
max_fee_per_gas: None,
max_priority_fee_per_gas: None,
value: t.value,
chain_id: t.signature.chain_id(),
access_list: Vec::new(),
},
Transaction::EIP2930(t) => TransactionData {
action: t.action,
input: t.input.clone(),
nonce: t.nonce,
gas_limit: t.gas_limit,
gas_price: Some(t.gas_price),
max_fee_per_gas: None,
max_priority_fee_per_gas: None,
value: t.value,
chain_id: Some(t.chain_id),
access_list: t
.access_list
.iter()
.map(|d| (d.address, d.storage_keys.clone()))
.collect(),
},
Transaction::EIP1559(t) => TransactionData {
action: t.action,
input: t.input.clone(),
nonce: t.nonce,
gas_limit: t.gas_limit,
gas_price: None,
max_fee_per_gas: Some(t.max_fee_per_gas),
max_priority_fee_per_gas: Some(t.max_priority_fee_per_gas),
value: t.value,
chain_id: Some(t.chain_id),
access_list: t
.access_list
.iter()
.map(|d| (d.address, d.storage_keys.clone()))
.collect(),
},
}
}
}