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

Zero malleable fields before execution #678

Merged
merged 16 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
#### Breaking

- [#683](https://github.com/FuelLabs/fuel-vm/pull/683): Simplify `InterpreterStorage` by removing dependency on `MerkleRootStorage` and removing `merkle_` prefix from method names.
- [#678](https://github.com/FuelLabs/fuel-vm/pull/678): Zero malleable fields before execution. Remove some now-obsolete GTF getters. Don't update `tx.receiptsRoot` after pushing receipts, and do it after execution instead.
- [#672](https://github.com/FuelLabs/fuel-vm/pull/672): Remove `GasPrice` policy
- [#672](https://github.com/FuelLabs/fuel-vm/pull/672): Add `gas_price` field to transaction execution
- [#684](https://github.com/FuelLabs/fuel-vm/pull/684): Remove `maturity` field from `Input` coin types. Also remove related `GTF` getter.
Expand Down
22 changes: 0 additions & 22 deletions fuel-asm/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,6 @@ crate::enum_try_from! {
/// Set `$rA` to `tx.inputs[$rB].outputIndex`
InputContractOutputIndex = 0x221,

/// Set `$rA` to `Memory address of tx.inputs[$rB].balanceRoot`
InputContractBalanceRoot = 0x222,

/// Set `$rA` to `Memory address of tx.inputs[$rB].stateRoot`
InputContractStateRoot = 0x223,

/// Set `$rA` to `Memory address of tx.inputs[$rB].txPointer`
InputContractTxPointer = 0x224,

/// Set `$rA` to `Memory address of tx.inputs[$rB].contractID`
InputContractId = 0x225,

Expand Down Expand Up @@ -227,12 +218,6 @@ crate::enum_try_from! {
/// Set `$rA` to `tx.outputs[$rB].inputIndex`
OutputContractInputIndex = 0x304,

/// Set `$rA` to `Memory address of tx.outputs[$rB].balanceRoot`
OutputContractBalanceRoot = 0x305,

/// Set `$rA` to `Memory address of tx.outputs[$rB].stateRoot`
OutputContractStateRoot = 0x306,

/// Set `$rA` to `Memory address of tx.outputs[$rB].contractID`
OutputContractCreatedContractId = 0x307,

Expand Down Expand Up @@ -328,11 +313,6 @@ fn encode_gtf_args() {
GTFArgs::InputCoinPredicate,
GTFArgs::InputCoinPredicateData,
GTFArgs::InputCoinPredicateGasUsed,
GTFArgs::InputContractTxId,
GTFArgs::InputContractOutputIndex,
GTFArgs::InputContractBalanceRoot,
GTFArgs::InputContractStateRoot,
GTFArgs::InputContractTxPointer,
GTFArgs::InputContractId,
GTFArgs::InputMessageSender,
GTFArgs::InputMessageRecipient,
Expand All @@ -351,8 +331,6 @@ fn encode_gtf_args() {
GTFArgs::OutputCoinAmount,
GTFArgs::OutputCoinAssetId,
GTFArgs::OutputContractInputIndex,
GTFArgs::OutputContractBalanceRoot,
GTFArgs::OutputContractStateRoot,
GTFArgs::OutputContractCreatedContractId,
GTFArgs::OutputContractCreatedStateRoot,
GTFArgs::WitnessDataLength,
Expand Down
37 changes: 1 addition & 36 deletions fuel-tx/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ impl<T> Buildable for T where T: BuildableSet {}
pub struct TransactionBuilder<Tx> {
tx: Tx,

should_prepare_script: bool,
should_prepare_predicate: bool,
params: ConsensusParameters,

// We take the key by reference so this lib won't have the responsibility to properly
Expand All @@ -126,12 +124,7 @@ impl TransactionBuilder<Script> {
receipts_root: Default::default(),
metadata: None,
};

let mut slf = Self::with_tx(tx);

slf.prepare_script(true);

slf
Self::with_tx(tx)
}
}

Expand Down Expand Up @@ -190,14 +183,10 @@ impl TransactionBuilder<Mint> {

impl<Tx> TransactionBuilder<Tx> {
fn with_tx(tx: Tx) -> Self {
let should_prepare_script = false;
let should_prepare_predicate = false;
let sign_keys = BTreeMap::new();

Self {
tx,
should_prepare_script,
should_prepare_predicate,
params: ConsensusParameters::standard(),
sign_keys,
}
Expand Down Expand Up @@ -279,16 +268,6 @@ impl<Tx> TransactionBuilder<Tx> {
}

impl<Tx: Buildable> TransactionBuilder<Tx> {
pub fn prepare_script(&mut self, should_prepare_script: bool) -> &mut Self {
self.should_prepare_script = should_prepare_script;
self
}

pub fn prepare_predicate(&mut self, should_prepare_predicate: bool) -> &mut Self {
self.should_prepare_predicate = should_prepare_predicate;
self
}

pub fn sign_keys(&self) -> impl Iterator<Item = &SecretKey> {
self.sign_keys.keys()
}
Expand Down Expand Up @@ -433,19 +412,7 @@ impl<Tx: Buildable> TransactionBuilder<Tx> {
*witness_index
}

fn prepare_finalize(&mut self) {
if self.should_prepare_predicate {
self.tx.prepare_init_predicate();
}

if self.should_prepare_script {
self.tx.prepare_init_script();
}
}

fn finalize_inner(&mut self) -> Tx {
self.prepare_finalize();

let mut tx = core::mem::take(&mut self.tx);

self.sign_keys
Expand All @@ -459,8 +426,6 @@ impl<Tx: Buildable> TransactionBuilder<Tx> {
}

pub fn finalize_without_signature_inner(&mut self) -> Tx {
self.prepare_finalize();

let mut tx = core::mem::take(&mut self.tx);

tx.precompute(&self.get_chain_id())
Expand Down
1 change: 0 additions & 1 deletion fuel-tx/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod offset;
mod prepared_init;
mod valid_cases;

#[cfg(feature = "serde")]
Expand Down
41 changes: 0 additions & 41 deletions fuel-tx/src/tests/prepared_init.rs

This file was deleted.

25 changes: 0 additions & 25 deletions fuel-tx/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,31 +412,6 @@ pub trait Executable: field::Inputs + field::Outputs + field::Witnesses {

self.inputs_mut().push(input);
}

/// Prepare the transaction for VM initialization for script execution
///
/// note: Fields dependent on storage/state such as balance and state roots, or tx
/// pointers, should already set by the client beforehand.
fn prepare_init_script(&mut self) -> &mut Self {
self.outputs_mut()
.iter_mut()
.for_each(|o| o.prepare_init_script());

self
}

/// Prepare the transaction for VM initialization for predicate verification
fn prepare_init_predicate(&mut self) -> &mut Self {
self.inputs_mut()
.iter_mut()
.for_each(|i| i.prepare_init_predicate());

self.outputs_mut()
.iter_mut()
.for_each(|o| o.prepare_init_predicate());

self
}
}

impl<T: field::Inputs + field::Outputs + field::Witnesses> Executable for T {}
Expand Down
6 changes: 3 additions & 3 deletions fuel-tx/src/transaction/types/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,9 @@ impl Input {
owner == &Self::predicate_owner(predicate)
}

/// Prepare the output for VM predicate execution
pub fn prepare_init_predicate(&mut self) {
self.prepare_sign()
/// Prepare the output for script or predicate execution
pub fn prepare_init_execute(&mut self) {
self.prepare_sign(); // This currently does the same thing
}
}

Expand Down
26 changes: 3 additions & 23 deletions fuel-tx/src/transaction/types/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,29 +217,9 @@ impl Output {
}

/// Prepare the output for VM initialization for script execution
pub fn prepare_init_script(&mut self) {
match self {
Output::Change { amount, .. } => {
mem::take(amount);
}

Output::Variable {
to,
amount,
asset_id,
} => {
mem::take(to);
mem::take(amount);
mem::take(asset_id);
}

_ => (),
}
}

/// Prepare the output for VM initialization for predicate verification
pub fn prepare_init_predicate(&mut self) {
self.prepare_sign()
/// or predicate verification
pub fn prepare_init_execute(&mut self) {
self.prepare_sign() // Currently does the same thing
}
}

Expand Down
13 changes: 13 additions & 0 deletions fuel-tx/src/transaction/types/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ impl Default for Script {
}
}

impl Script {
/// Prepare script for execution by clearing malleable fields.
pub fn prepare_init_execute(&mut self) {
*self.receipts_root_mut() = Default::default();
self.inputs_mut()
.iter_mut()
.for_each(Input::prepare_init_execute);
self.outputs_mut()
.iter_mut()
.for_each(Output::prepare_init_execute);
}
}

impl crate::UniqueIdentifier for Script {
fn id(&self, chain_id: &ChainId) -> Bytes32 {
if let Some(id) = self.cached_id() {
Expand Down
1 change: 1 addition & 0 deletions fuel-vm/src/checked_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ bitflags::bitflags! {
pub struct Checks: u32 {
/// Basic checks defined in the specification for each transaction:
/// https://github.com/FuelLabs/fuel-specs/blob/master/src/tx-format/transaction.md#transaction
/// Also ensures that malleable fields are zeroed.
const Basic = 0b00000001;
/// Check that signature in the transactions are valid.
const Signatures = 0b00000010;
Expand Down
29 changes: 28 additions & 1 deletion fuel-vm/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ use fuel_asm::{
PanicReason,
};
use fuel_tx::{
field,
field::{
self,
Inputs,
Outputs,
ReceiptsRoot,
},
output,
Chargeable,
ContractParameters,
Create,
Executable,
FeeParameters,
GasCosts,
Input,
Output,
PredicateParameters,
Receipt,
Expand All @@ -40,6 +46,7 @@ use fuel_tx::{
};
use fuel_types::{
AssetId,
Bytes32,
ChainId,
ContractId,
Word,
Expand Down Expand Up @@ -286,6 +293,11 @@ impl<S, Tx, Ecal> Interpreter<S, Tx, Ecal> {
self.receipts.as_ref().as_slice()
}

/// Compute current receipts root
pub fn compute_receipts_root(&self) -> Bytes32 {
self.receipts.root()
}

/// Mutable access to receipts for testing purposes.
#[cfg(any(test, feature = "test-helpers"))]
pub fn receipts_mut(&mut self) -> &mut ReceiptsCtx {
Expand Down Expand Up @@ -474,6 +486,9 @@ pub trait ExecutableTransaction:
}) if *input_index as usize == input)
})
}

/// Prepares the transaction for execution.
fn prepare_init_execute(&mut self);
}

impl ExecutableTransaction for Create {
Expand All @@ -496,6 +511,8 @@ impl ExecutableTransaction for Create {
fn transaction_type() -> Word {
TransactionRepr::Create as Word
}

fn prepare_init_execute(&mut self) {}
}

impl ExecutableTransaction for Script {
Expand All @@ -518,6 +535,16 @@ impl ExecutableTransaction for Script {
fn transaction_type() -> Word {
TransactionRepr::Script as Word
}

fn prepare_init_execute(&mut self) {
*self.receipts_root_mut() = Default::default();
self.inputs_mut()
.iter_mut()
.for_each(Input::prepare_init_execute);
self.outputs_mut()
.iter_mut()
.for_each(Output::prepare_init_execute);
}
}

/// The initial balances of the transaction.
Expand Down
Loading
Loading