use crate::{
backtrace::Backtrace,
checked_transaction::Checked,
state::StateTransitionRef,
storage::MemoryStorage,
transactor::Transactor,
};
use crate::interpreter::{
EcalHandler,
InterpreterParams,
NotSupportedEcal,
};
use fuel_tx::{
Create,
GasCosts,
Receipt,
Script,
};
#[derive(Debug)]
pub struct MemoryClient<Ecal = NotSupportedEcal> {
transactor: Transactor<MemoryStorage, Script, Ecal>,
}
#[cfg(any(test, feature = "test-helpers"))]
impl Default for MemoryClient {
fn default() -> Self {
Self::new(MemoryStorage::default(), InterpreterParams::default())
}
}
impl<Ecal: EcalHandler> AsRef<MemoryStorage> for MemoryClient<Ecal> {
fn as_ref(&self) -> &MemoryStorage {
self.transactor.as_ref()
}
}
impl<Ecal: EcalHandler> AsMut<MemoryStorage> for MemoryClient<Ecal> {
fn as_mut(&mut self) -> &mut MemoryStorage {
self.transactor.as_mut()
}
}
impl<Ecal: EcalHandler> MemoryClient<Ecal> {
pub fn new(storage: MemoryStorage, interpreter_params: InterpreterParams) -> Self {
Self {
transactor: Transactor::new(storage, interpreter_params),
}
}
pub fn from_txtor(transactor: Transactor<MemoryStorage, Script, Ecal>) -> Self {
Self { transactor }
}
pub fn backtrace(&self) -> Option<Backtrace> {
self.transactor.backtrace()
}
pub fn receipts(&self) -> Option<&[Receipt]> {
self.transactor.receipts()
}
pub fn state_transition(&self) -> Option<StateTransitionRef<'_, Script>> {
self.transactor.state_transition()
}
pub fn deploy(&mut self, tx: Checked<Create>) -> Option<Create> {
self.transactor.deploy(tx).ok()
}
pub fn transact(&mut self, tx: Checked<Script>) -> &[Receipt] {
self.transactor.transact(tx);
if let Ok(state) = self.transactor.result() {
if state.should_revert() {
self.transactor.as_mut().revert();
} else {
self.transactor.as_mut().commit();
}
} else {
self.transactor.as_mut().revert();
}
self.transactor.receipts().unwrap_or_default()
}
pub fn persist(&mut self) {
self.as_mut().persist();
}
pub fn tx_offset(&self) -> usize {
self.transactor.tx_offset()
}
pub fn gas_costs(&self) -> &GasCosts {
self.transactor.gas_costs()
}
}
impl<Ecal: EcalHandler> From<MemoryStorage> for MemoryClient<Ecal> {
fn from(s: MemoryStorage) -> Self {
Self::new(s, InterpreterParams::default())
}
}
impl<Ecal: EcalHandler> From<MemoryClient<Ecal>>
for Transactor<MemoryStorage, Script, Ecal>
{
fn from(client: MemoryClient<Ecal>) -> Self {
client.transactor
}
}