Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring inputs to be named types #364

Merged
merged 13 commits into from
Mar 17, 2023
6 changes: 3 additions & 3 deletions fuel-tx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ pub use receipt::{Receipt, ScriptExecutionResult};

#[cfg(feature = "alloc")]
pub use transaction::{
field, Cacheable, Chargeable, CheckError, ConsensusParameters, Create, Executable, FormatValidityChecks, Input,
InputRepr, Mint, Output, OutputRepr, Script, StorageSlot, Transaction, TransactionFee, TransactionRepr, TxId,
UtxoId, Witness,
field, input, input::Input, input::InputRepr, Cacheable, Chargeable, CheckError, ConsensusParameters, Create,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm exporting input::Input, input::InputRepr separately not to make the breaking change.

Executable, FormatValidityChecks, Mint, Output, OutputRepr, Script, StorageSlot, Transaction, TransactionFee,
TransactionRepr, TxId, UtxoId, Witness,
};

#[cfg(feature = "std")]
Expand Down
18 changes: 12 additions & 6 deletions fuel-tx/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ pub use consensus_parameters::ConsensusParameters;
pub use fee::{Chargeable, TransactionFee};
pub use metadata::Cacheable;
pub use repr::TransactionRepr;
pub use types::{Create, Input, InputRepr, Mint, Output, OutputRepr, Script, StorageSlot, UtxoId, Witness};
pub use types::*;
pub use validity::{CheckError, FormatValidityChecks};

use crate::TxPointer;

use crate::input::coin::{CoinPredicate, CoinSigned};
use crate::input::contract::Contract;
use crate::input::message::MessagePredicate;
use input::*;

#[cfg(feature = "std")]
pub use id::{Signable, UniqueIdentifier};

Expand Down Expand Up @@ -207,7 +212,8 @@ pub trait Executable: field::Inputs + field::Outputs + field::Witnesses {
self.inputs()
.iter()
.filter_map(|input| match input {
Input::CoinPredicate { asset_id, .. } | Input::CoinSigned { asset_id, .. } => Some(asset_id),
Input::CoinPredicate(CoinPredicate { asset_id, .. })
| Input::CoinSigned(CoinSigned { asset_id, .. }) => Some(asset_id),
Input::MessagePredicate { .. } | Input::MessageSigned { .. } => Some(&AssetId::BASE),
_ => None,
})
Expand Down Expand Up @@ -235,7 +241,7 @@ pub trait Executable: field::Inputs + field::Outputs + field::Witnesses {
self.inputs()
.iter()
.filter_map(|input| match input {
Input::Contract { contract_id, .. } => Some(contract_id),
Input::Contract(Contract { contract_id, .. }) => Some(contract_id),
_ => None,
})
.unique()
Expand All @@ -249,10 +255,10 @@ pub trait Executable: field::Inputs + field::Outputs + field::Witnesses {
self.inputs()
.iter()
.filter_map(|i| match i {
Input::CoinPredicate { owner, predicate, .. } => Some((owner, predicate)),
Input::MessagePredicate {
Input::CoinPredicate(CoinPredicate { owner, predicate, .. }) => Some((owner, predicate)),
Input::MessagePredicate(MessagePredicate {
recipient, predicate, ..
} => Some((recipient, predicate)),
}) => Some((recipient, predicate)),
_ => None,
})
.fold(true, |result, (owner, predicate)| {
Expand Down
165 changes: 134 additions & 31 deletions fuel-tx/src/transaction/id.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::{field, Input, Transaction};

use crate::input::coin::CoinSigned;
use crate::input::message::MessageSigned;
use fuel_crypto::{Message, PublicKey, SecretKey, Signature};
use fuel_types::Bytes32;

Expand Down Expand Up @@ -49,14 +51,14 @@ where
let witness_indexes = inputs
.iter()
.filter_map(|input| match input {
Input::CoinSigned {
Input::CoinSigned(CoinSigned {
owner, witness_index, ..
}
| Input::MessageSigned {
})
| Input::MessageSigned(MessageSigned {
recipient: owner,
witness_index,
..
} if owner == &pk => Some(*witness_index as usize),
}) if owner == &pk => Some(*witness_index as usize),
_ => None,
})
.dedup()
Expand All @@ -72,8 +74,15 @@ where

#[cfg(all(test, feature = "random"))]
mod tests {
use crate::*;

use fuel_tx::{
field::*,
input::{
coin::{CoinPredicate, CoinSigned},
contract::Contract,
message::{MessagePredicate, MessageSigned},
},
Buildable, ConsensusParameters, Input, Output, StorageSlot, Transaction, UtxoId,
};
use fuel_tx_test_helpers::{generate_bytes, generate_nonempty_padded_bytes};
use rand::rngs::StdRng;
use rand::{Rng, RngCore, SeedableRng};
Expand Down Expand Up @@ -160,6 +169,14 @@ mod tests {
})
});
};
($tx:expr, $t:ident, $i:path [ $it:path ], $a:ident, $inv:expr) => {
assert_id_ne($tx, |t| {
t.$t().iter_mut().for_each(|x| match x {
$i($it { $a, .. }) => $inv($a),
_ => (),
})
});
};
}

macro_rules! assert_io_eq {
Expand All @@ -171,6 +188,14 @@ mod tests {
})
});
};
($tx:expr, $t:ident, $i:path [ $it:path ], $a:ident, $inv:expr) => {
assert_id_eq($tx, |t| {
t.$t().iter_mut().for_each(|x| match x {
$i($it { $a, .. }) => $inv($a),
_ => (),
})
});
};
}

fn assert_id_common_attrs<Tx: Buildable>(tx: &Tx) {
Expand All @@ -179,25 +204,84 @@ mod tests {
assert_id_ne(tx, |t| t.set_maturity(t.maturity().not()));

if !tx.inputs().is_empty() {
assert_io_ne!(tx, inputs_mut, Input::CoinSigned, utxo_id, invert_utxo_id);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned, owner, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned, amount, not);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned, asset_id, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned, witness_index, not);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned, maturity, not);

assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, utxo_id, invert_utxo_id);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, owner, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, amount, not);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, asset_id, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, maturity, not);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, predicate, inv_v);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate, predicate_data, inv_v);

assert_io_eq!(tx, inputs_mut, Input::Contract, utxo_id, invert_utxo_id);
assert_io_eq!(tx, inputs_mut, Input::Contract, balance_root, invert);
assert_io_eq!(tx, inputs_mut, Input::Contract, state_root, invert);
assert_io_ne!(tx, inputs_mut, Input::Contract, contract_id, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned[CoinSigned], utxo_id, invert_utxo_id);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned[CoinSigned], owner, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned[CoinSigned], amount, not);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned[CoinSigned], asset_id, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned[CoinSigned], witness_index, not);
assert_io_ne!(tx, inputs_mut, Input::CoinSigned[CoinSigned], maturity, not);

assert_io_ne!(
tx,
inputs_mut,
Input::CoinPredicate[CoinPredicate],
utxo_id,
invert_utxo_id
);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate[CoinPredicate], owner, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate[CoinPredicate], amount, not);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate[CoinPredicate], asset_id, invert);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate[CoinPredicate], maturity, not);
assert_io_ne!(tx, inputs_mut, Input::CoinPredicate[CoinPredicate], predicate, inv_v);
assert_io_ne!(
tx,
inputs_mut,
Input::CoinPredicate[CoinPredicate],
predicate_data,
inv_v
);

assert_io_eq!(tx, inputs_mut, Input::Contract[Contract], utxo_id, invert_utxo_id);
assert_io_eq!(tx, inputs_mut, Input::Contract[Contract], balance_root, invert);
assert_io_eq!(tx, inputs_mut, Input::Contract[Contract], state_root, invert);
assert_io_ne!(tx, inputs_mut, Input::Contract[Contract], contract_id, invert);

assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], message_id, invert);
assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], sender, invert);
assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], recipient, invert);
assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], amount, not);
assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], nonce, not);
assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], witness_index, not);
assert_io_ne!(tx, inputs_mut, Input::MessageSigned[MessageSigned], data, inv_v);

assert_io_ne!(
tx,
inputs_mut,
Input::MessagePredicate[MessagePredicate],
message_id,
invert
);
assert_io_ne!(
tx,
inputs_mut,
Input::MessagePredicate[MessagePredicate],
sender,
invert
);
assert_io_ne!(
tx,
inputs_mut,
Input::MessagePredicate[MessagePredicate],
recipient,
invert
);
assert_io_ne!(tx, inputs_mut, Input::MessagePredicate[MessagePredicate], amount, not);
assert_io_ne!(tx, inputs_mut, Input::MessagePredicate[MessagePredicate], nonce, not);
assert_io_ne!(tx, inputs_mut, Input::MessagePredicate[MessagePredicate], data, inv_v);
assert_io_ne!(
tx,
inputs_mut,
Input::MessagePredicate[MessagePredicate],
predicate,
inv_v
);
assert_io_ne!(
tx,
inputs_mut,
Input::MessagePredicate[MessagePredicate],
predicate_data,
inv_v
);
}

if !tx.outputs().is_empty() {
Expand Down Expand Up @@ -255,6 +339,25 @@ mod tests {
generate_bytes(rng),
),
Input::contract(rng.gen(), rng.gen(), rng.gen(), rng.gen(), rng.gen()),
Input::message_signed(
rng.gen(),
rng.gen(),
rng.gen(),
rng.next_u64(),
rng.next_u64(),
rng.next_u32().to_be_bytes()[0],
generate_nonempty_padded_bytes(rng),
),
Input::message_predicate(
rng.gen(),
rng.gen(),
rng.gen(),
rng.next_u64(),
rng.next_u64(),
generate_nonempty_padded_bytes(rng),
generate_nonempty_padded_bytes(rng),
generate_bytes(rng),
),
],
];

Expand Down Expand Up @@ -293,8 +396,8 @@ mod tests {
);

assert_id_common_attrs(&tx);
assert_id_ne(&tx, |t| inv_v(&mut t.script));
assert_id_ne(&tx, |t| inv_v(&mut t.script_data));
assert_id_ne(&tx, |t| inv_v(t.script_mut()));
assert_id_ne(&tx, |t| inv_v(t.script_data_mut()));
}
}

Expand All @@ -311,12 +414,12 @@ mod tests {
witnesses.clone(),
);

assert_id_ne(&tx, |t| not(&mut t.bytecode_witness_index));
assert_id_ne(&tx, |t| invert(&mut t.salt));
assert_id_ne(&tx, |t| invert(&mut t.salt));
assert_id_ne(&tx, |t| not(t.bytecode_witness_index_mut()));
assert_id_ne(&tx, |t| invert(t.salt_mut()));
assert_id_ne(&tx, |t| invert(t.salt_mut()));

if !storage_slots.is_empty() {
assert_id_ne(&tx, |t| invert_storage_slot(t.storage_slots.first_mut().unwrap()));
assert_id_ne(&tx, |t| invert_storage_slot(t.storage_slots_mut().first_mut().unwrap()));
}

assert_id_common_attrs(&tx);
Expand Down
3 changes: 1 addition & 2 deletions fuel-tx/src/transaction/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod create;
mod input;
pub mod input;
mod mint;
mod output;
mod script;
Expand All @@ -8,7 +8,6 @@ mod utxo_id;
mod witness;

pub use create::Create;
pub use input::{Input, InputRepr};
pub use mint::Mint;
pub use output::{Output, OutputRepr};
pub use script::Script;
Expand Down
Loading