use std::fmt::Debug;
use fuel_tx::{
field::{
GasLimit, GasPrice, Inputs, Maturity, Outputs, Script as ScriptField, ScriptData, Witnesses,
},
Bytes32, Chargeable, ConsensusParameters, Create, FormatValidityChecks, Input as FuelInput,
Output, Salt as FuelSalt, Script, StorageSlot, Transaction as FuelTransaction, TransactionFee,
UniqueIdentifier, Witness,
};
use crate::{
constants::{DEFAULT_GAS_LIMIT, DEFAULT_GAS_PRICE, DEFAULT_MATURITY},
errors::Error,
};
#[derive(Debug, Copy, Clone)]
pub struct TxParameters {
gas_price: u64,
gas_limit: u64,
maturity: u32,
}
macro_rules! impl_setter_getter {
($setter_name: ident, $field: ident, $ty: ty) => {
pub fn $setter_name(mut self, $field: $ty) -> Self {
self.$field = $field;
self
}
pub fn $field(&self) -> $ty {
self.$field
}
};
}
impl TxParameters {
pub fn new(gas_price: u64, gas_limit: u64, maturity: u32) -> Self {
Self {
gas_price,
gas_limit,
maturity,
}
}
impl_setter_getter!(set_gas_price, gas_price, u64);
impl_setter_getter!(set_gas_limit, gas_limit, u64);
impl_setter_getter!(set_maturity, maturity, u32);
}
impl Default for TxParameters {
fn default() -> Self {
Self {
gas_price: DEFAULT_GAS_PRICE,
gas_limit: DEFAULT_GAS_LIMIT,
maturity: DEFAULT_MATURITY,
}
}
}
use fuel_tx::field::{BytecodeLength, BytecodeWitnessIndex, Salt, StorageSlots};
pub trait Transaction: Into<FuelTransaction> + Send {
fn fee_checked_from_tx(&self, params: &ConsensusParameters) -> Option<TransactionFee>;
fn check_without_signatures(
&self,
block_height: u32,
parameters: &ConsensusParameters,
) -> Result<(), Error>;
fn id(&self, params: &ConsensusParameters) -> Bytes32;
fn maturity(&self) -> u32;
fn with_maturity(self, maturity: u32) -> Self;
fn gas_price(&self) -> u64;
fn with_gas_price(self, gas_price: u64) -> Self;
fn gas_limit(&self) -> u64;
fn with_gas_limit(self, gas_price: u64) -> Self;
fn with_tx_params(self, tx_params: TxParameters) -> Self;
fn metered_bytes_size(&self) -> usize;
fn inputs(&self) -> &Vec<FuelInput>;
fn outputs(&self) -> &Vec<Output>;
fn witnesses(&self) -> &Vec<Witness>;
fn witnesses_mut(&mut self) -> &mut Vec<Witness>;
fn with_witnesses(self, witnesses: Vec<Witness>) -> Self;
}
macro_rules! impl_tx_wrapper {
($wrapper: ident, $wrapped: ident) => {
#[derive(Debug, Clone)]
pub struct $wrapper {
pub tx: $wrapped,
}
impl From<$wrapped> for $wrapper {
fn from(tx: $wrapped) -> Self {
$wrapper { tx }
}
}
impl Default for $wrapper {
fn default() -> Self {
$wrapped::default().into()
}
}
impl From<$wrapper> for $wrapped {
fn from(tx: $wrapper) -> Self {
tx.tx
}
}
impl From<$wrapper> for FuelTransaction {
fn from(tx: $wrapper) -> Self {
tx.tx.into()
}
}
impl Transaction for $wrapper {
fn fee_checked_from_tx(&self, params: &ConsensusParameters) -> Option<TransactionFee> {
TransactionFee::checked_from_tx(params, &self.tx)
}
fn check_without_signatures(
&self,
block_height: u32,
parameters: &ConsensusParameters,
) -> Result<(), Error> {
Ok(self
.tx
.check_without_signatures(block_height.into(), parameters)?)
}
fn id(&self, params: &ConsensusParameters) -> Bytes32 {
self.tx.id(params)
}
fn maturity(&self) -> u32 {
(*self.tx.maturity()).into()
}
fn with_maturity(mut self, maturity: u32) -> Self {
*self.tx.maturity_mut() = maturity.into();
self
}
fn gas_price(&self) -> u64 {
*self.tx.gas_price()
}
fn with_gas_price(mut self, gas_price: u64) -> Self {
*self.tx.gas_price_mut() = gas_price;
self
}
fn gas_limit(&self) -> u64 {
*self.tx.gas_limit()
}
fn with_gas_limit(mut self, gas_limit: u64) -> Self {
*self.tx.gas_limit_mut() = gas_limit;
self
}
fn with_tx_params(self, tx_params: TxParameters) -> Self {
self.with_gas_limit(tx_params.gas_limit)
.with_gas_price(tx_params.gas_price)
.with_maturity(tx_params.maturity)
}
fn metered_bytes_size(&self) -> usize {
self.tx.metered_bytes_size()
}
fn inputs(&self) -> &Vec<FuelInput> {
self.tx.inputs()
}
fn outputs(&self) -> &Vec<Output> {
self.tx.outputs()
}
fn witnesses(&self) -> &Vec<Witness> {
self.tx.witnesses()
}
fn witnesses_mut(&mut self) -> &mut Vec<Witness> {
self.tx.witnesses_mut()
}
fn with_witnesses(mut self, witnesses: Vec<Witness>) -> Self {
*self.tx.witnesses_mut() = witnesses;
self
}
}
};
}
impl_tx_wrapper!(ScriptTransaction, Script);
impl_tx_wrapper!(CreateTransaction, Create);
impl CreateTransaction {
pub fn salt(&self) -> &FuelSalt {
self.tx.salt()
}
pub fn bytecode_witness_index(&self) -> u8 {
*self.tx.bytecode_witness_index()
}
pub fn storage_slots(&self) -> &Vec<StorageSlot> {
self.tx.storage_slots()
}
pub fn bytecode_length(&self) -> u64 {
*self.tx.bytecode_length()
}
}
impl ScriptTransaction {
pub fn script(&self) -> &Vec<u8> {
self.tx.script()
}
pub fn script_data(&self) -> &Vec<u8> {
self.tx.script_data()
}
}