pub use ethereum::{
TransactionAction, TransactionV2 as Transaction,
};
use sp_core::{H160, H256, U256};
use fp_evm::{CallOrCreateInfo, CheckEvmTransactionInput};
use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo};
use codec::{Decode, Encode};
use sp_std::{result::Result, vec::Vec};
#[allow(dead_code)]
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>)>,
pub proof_size_base_cost: Option<u64>,
}
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 {
let mut transaction_data = Self {
action,
input,
nonce,
gas_limit,
gas_price,
max_fee_per_gas,
max_priority_fee_per_gas,
value,
chain_id,
access_list,
proof_size_base_cost: None,
};
let proof_size_base_cost = transaction_data
.encode()
.len()
.saturating_add(65)
.saturating_add(1)
.saturating_add(1) as u64;
transaction_data.proof_size_base_cost = Some(proof_size_base_cost);
transaction_data
}
}
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 {
let proof_size_base_cost = t
.encode()
.len()
.saturating_add(1)
.saturating_add(1) as u64;
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(),
proof_size_base_cost: Some(proof_size_base_cost),
},
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(),
proof_size_base_cost: Some(proof_size_base_cost),
},
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(),
proof_size_base_cost: Some(proof_size_base_cost),
},
}
}
}