Skip to content

Commit

Permalink
Use max fee policy to charge user (#685)
Browse files Browse the repository at this point in the history
* refactor hard-to-read function

* WIP

* Remove comments

* Remove fee checks, fmt

* Remove `gas_price` from check

* Get tests compiling but not passing

* Replace limit tests with exists tests

* Break down `create` tests, fix those tests

* Break down `script` tests, fix those tests

* Fix broken tx tests

* Fix warnings

* Fix `run_script` to incude `max_fee`

* WIP

* WIP

* Take ref and clone instead of mut in finalize

* Modify test builder to have default max_fee_limit of 0

* Fix input tests

* WIP fixing tests

* Finish reconciling merge

* Fix `blockchain` tests

* Fix setup function for many tests

* Fix metadata tests

* Fix predicate tests

* Fix interpreter tests

* Fix a bunch of simpler tests

* cargo +nightly fmt

* Add `Immutable` type for txs

* Fix more tests

* Add comments to `Immutable`

* Remove setting of the max limit everywhere and removed unsuded variables

* WIP

* Something else

* Fixed the test `into_checked__tx_fails_when_provided_fees_dont_cover_byte_costs`

* Minimized number of modifications

* Added getter for the `gas_price`

* Fixed several tests

* Fix more tests

* Use `Immutable` in transact

* Fix warnings

* Rename types and functions

* Update CHANGELOG

* Appease Clippy-sama

* Fix bad import

* Revert "Rename types and functions"

This reverts commit 25f4412.

* Rename `Immutable` to `Ready`

* Add test for verifying `Ready` txs

* Update CHANGELOG.md

Co-authored-by: Brandon Kite <brandonkite92@gmail.com>

* Improve tests, change `decompose` method

* Add `deploy` test for checking `Ready`

* Use `CheckError` instead of the `TransactionValidity`

* Updated CHANGELOG.md

---------

Co-authored-by: xgreenx <xgreenx9999@gmail.com>
Co-authored-by: Brandon Kite <brandonkite92@gmail.com>
  • Loading branch information
3 people authored Feb 29, 2024
1 parent 3ff9965 commit 5d4f9fe
Show file tree
Hide file tree
Showing 41 changed files with 1,139 additions and 722 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

#### Breaking

- [#685](https://github.com/FuelLabs/fuel-vm/pull/685):
The `MaxFee` is a mandatory policy to set. The `MaxFee` policy is used to check that the transaction is valid.
Added a new stage for the `Checked` transaction - `Ready`. This type can be constructed with the
`gas_price` before being transacted by the `Interpreter`.
- [#671](https://github.com/FuelLabs/fuel-vm/pull/671): Support dynamically sized values in the ContractsState table by using a vector data type (`Vec<u8>`).
- [#682](https://github.com/FuelLabs/fuel-vm/pull/682): Include `Tip` policy in fee calculation
- [#683](https://github.com/FuelLabs/fuel-vm/pull/683): Simplify `InterpreterStorage` by removing dependency on `MerkleRootStorage` and removing `merkle_` prefix from method names.
Expand Down
32 changes: 17 additions & 15 deletions fuel-tx/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ impl<T> BuildableAloc for T where
}

impl<T> BuildableStd for T where T: Signable + Cacheable {}

impl<T> BuildableSet for T where T: BuildableAloc + BuildableStd {}

impl<T> Buildable for T where T: BuildableSet {}

#[derive(Debug, Clone)]
Expand All @@ -117,7 +119,7 @@ impl TransactionBuilder<Script> {
script_gas_limit: Default::default(),
script,
script_data,
policies: Policies::new(),
policies: Policies::new().with_max_fee(0),
inputs: Default::default(),
outputs: Default::default(),
witnesses: Default::default(),
Expand All @@ -141,7 +143,7 @@ impl TransactionBuilder<Create> {
bytecode_witness_index: Default::default(),
salt,
storage_slots,
policies: Policies::new(),
policies: Policies::new().with_max_fee(0),
inputs: Default::default(),
outputs: Default::default(),
witnesses: Default::default(),
Expand Down Expand Up @@ -412,8 +414,8 @@ impl<Tx: Buildable> TransactionBuilder<Tx> {
*witness_index
}

fn finalize_inner(&mut self) -> Tx {
let mut tx = core::mem::take(&mut self.tx);
fn finalize_inner(&self) -> Tx {
let mut tx = self.tx.clone();

self.sign_keys
.iter()
Expand All @@ -425,8 +427,8 @@ impl<Tx: Buildable> TransactionBuilder<Tx> {
tx
}

pub fn finalize_without_signature_inner(&mut self) -> Tx {
let mut tx = core::mem::take(&mut self.tx);
pub fn finalize_without_signature_inner(&self) -> Tx {
let mut tx = self.tx.clone();

tx.precompute(&self.get_chain_id())
.expect("Should be able to calculate cache");
Expand All @@ -443,40 +445,40 @@ impl<Tx: field::Outputs> TransactionBuilder<Tx> {
}

pub trait Finalizable<Tx> {
fn finalize(&mut self) -> Tx;
fn finalize(&self) -> Tx;

fn finalize_without_signature(&mut self) -> Tx;
fn finalize_without_signature(&self) -> Tx;
}

impl Finalizable<Mint> for TransactionBuilder<Mint> {
fn finalize(&mut self) -> Mint {
let mut tx = core::mem::take(&mut self.tx);
fn finalize(&self) -> Mint {
let mut tx = self.tx.clone();
tx.precompute(&self.get_chain_id())
.expect("Should be able to calculate cache");
tx
}

fn finalize_without_signature(&mut self) -> Mint {
fn finalize_without_signature(&self) -> Mint {
self.finalize()
}
}

impl Finalizable<Create> for TransactionBuilder<Create> {
fn finalize(&mut self) -> Create {
fn finalize(&self) -> Create {
self.finalize_inner()
}

fn finalize_without_signature(&mut self) -> Create {
fn finalize_without_signature(&self) -> Create {
self.finalize_without_signature_inner()
}
}

impl Finalizable<Script> for TransactionBuilder<Script> {
fn finalize(&mut self) -> Script {
fn finalize(&self) -> Script {
self.finalize_inner()
}

fn finalize_without_signature(&mut self) -> Script {
fn finalize_without_signature(&self) -> Script {
self.finalize_without_signature_inner()
}
}
Expand Down
56 changes: 10 additions & 46 deletions fuel-tx/src/tests/valid_cases/input.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(clippy::cast_possible_truncation)]

use super::PREDICATE_PARAMS;

use fuel_crypto::{
Expand Down Expand Up @@ -139,21 +140,15 @@ fn input_coin_message_signature() {
#[test]
fn coin_signed() {
let rng = &mut StdRng::seed_from_u64(8586);
let arb_gas_price = 1;

let mut tx = Script::default();
let mut tx = TransactionBuilder::script(vec![], vec![]).finalize();

let input =
Input::coin_signed(rng.gen(), rng.gen(), rng.gen(), rng.gen(), rng.gen(), 0);
tx.add_input(input);

let block_height = rng.gen();
let err = tx
.check(
block_height,
&ConsensusParameters::standard(),
arb_gas_price,
)
.check(block_height, &ConsensusParameters::standard())
.expect_err("Expected failure");

assert_eq!(ValidityError::InputWitnessIndexBounds { index: 0 }, err);
Expand All @@ -164,7 +159,6 @@ fn duplicate_secrets_reuse_witness() {
let rng = &mut StdRng::seed_from_u64(10000);
let key = SecretKey::random(rng);

// verify witness reuse for script txs
let script = TransactionBuilder::script(vec![], vec![])
// coin 1
.add_unsigned_coin_input(key, rng.gen(), 100, Default::default(), Default::default())
Expand Down Expand Up @@ -326,8 +320,6 @@ fn contract() {
#[test]
fn message_metadata() {
let rng = &mut StdRng::seed_from_u64(8586);
let arb_gas_price = 1;

let txhash: Bytes32 = rng.gen();

let predicate = generate_nonempty_padded_bytes(rng);
Expand All @@ -346,7 +338,7 @@ fn message_metadata() {
.check(1, &txhash, &[], &[], &Default::default(), &mut None)
.expect("failed to validate empty message input");

let mut tx = Script::default();
let mut tx = TransactionBuilder::script(vec![], vec![]).finalize();

let input = Input::message_data_signed(
rng.gen(),
Expand All @@ -364,11 +356,7 @@ fn message_metadata() {

let block_height = rng.gen();
let err = tx
.check(
block_height,
&ConsensusParameters::standard(),
arb_gas_price,
)
.check(block_height, &ConsensusParameters::standard())
.expect_err("Expected failure");

assert_eq!(ValidityError::InputWitnessIndexBounds { index: 0 }, err,);
Expand Down Expand Up @@ -468,9 +456,6 @@ fn message_metadata() {
#[test]
fn message_message_coin() {
let rng = &mut StdRng::seed_from_u64(8586);

let arb_gas_price = 1;

let txhash: Bytes32 = rng.gen();

let predicate = generate_nonempty_padded_bytes(rng);
Expand All @@ -488,18 +473,14 @@ fn message_message_coin() {
.check(1, &txhash, &[], &[], &Default::default(), &mut None)
.expect("failed to validate empty message input");

let mut tx = Script::default();
let mut tx = TransactionBuilder::script(vec![], vec![]).finalize();

let input = Input::message_coin_signed(rng.gen(), rng.gen(), rng.gen(), rng.gen(), 0);
tx.add_input(input);

let block_height = rng.gen();
let err = tx
.check(
block_height,
&ConsensusParameters::standard(),
arb_gas_price,
)
.check(block_height, &ConsensusParameters::standard())
.expect_err("Expected failure");

assert_eq!(ValidityError::InputWitnessIndexBounds { index: 0 }, err,);
Expand Down Expand Up @@ -560,7 +541,6 @@ fn message_message_coin() {
fn transaction_with_duplicate_coin_inputs_is_invalid() {
let rng = &mut StdRng::seed_from_u64(8586);
let utxo_id = rng.gen();
let arb_gas_price = 1;

let a = Input::coin_signed(utxo_id, rng.gen(), rng.gen(), rng.gen(), rng.gen(), 0);
let b = Input::coin_signed(utxo_id, rng.gen(), rng.gen(), rng.gen(), rng.gen(), 0);
Expand All @@ -570,11 +550,7 @@ fn transaction_with_duplicate_coin_inputs_is_invalid() {
.add_input(b)
.add_witness(rng.gen())
.finalize()
.check_without_signatures(
Default::default(),
&ConsensusParameters::standard(),
arb_gas_price,
)
.check_without_signatures(Default::default(), &ConsensusParameters::standard())
.expect_err("Expected checkable failure");

assert_eq!(err, ValidityError::DuplicateInputUtxoId { utxo_id });
Expand All @@ -583,7 +559,6 @@ fn transaction_with_duplicate_coin_inputs_is_invalid() {
#[test]
fn transaction_with_duplicate_message_inputs_is_invalid() {
let rng = &mut StdRng::seed_from_u64(8586);
let arb_gas_price = 1;
let message_input = Input::message_data_signed(
rng.gen(),
rng.gen(),
Expand Down Expand Up @@ -612,7 +587,6 @@ fn transaction_with_duplicate_message_inputs_is_invalid() {
.check_without_signatures(
Default::default(),
&ConsensusParameters::standard(),
arb_gas_price,
)
.expect_err("Expected checkable failure");

Expand All @@ -622,7 +596,6 @@ fn transaction_with_duplicate_message_inputs_is_invalid() {
#[test]
fn transaction_with_duplicate_contract_inputs_is_invalid() {
let rng = &mut StdRng::seed_from_u64(8586);
let arb_gas_price = 1;
let contract_id = rng.gen();
let fee = Input::coin_signed(
rng.gen(),
Expand All @@ -646,11 +619,7 @@ fn transaction_with_duplicate_contract_inputs_is_invalid() {
.add_output(o)
.add_output(p)
.finalize()
.check_without_signatures(
Default::default(),
&ConsensusParameters::standard(),
arb_gas_price,
)
.check_without_signatures(Default::default(), &ConsensusParameters::standard())
.expect_err("Expected checkable failure");

assert_eq!(err, ValidityError::DuplicateInputContractId { contract_id });
Expand All @@ -660,7 +629,6 @@ fn transaction_with_duplicate_contract_inputs_is_invalid() {
fn transaction_with_duplicate_contract_utxo_id_is_valid() {
let rng = &mut StdRng::seed_from_u64(8586);
let input_utxo_id: UtxoId = rng.gen();
let arb_gas_price = 1;

let a = Input::contract(input_utxo_id, rng.gen(), rng.gen(), rng.gen(), rng.gen());
let b = Input::contract(input_utxo_id, rng.gen(), rng.gen(), rng.gen(), rng.gen());
Expand All @@ -678,10 +646,6 @@ fn transaction_with_duplicate_contract_utxo_id_is_valid() {
.add_output(p)
.add_witness(rng.gen())
.finalize()
.check_without_signatures(
Default::default(),
&ConsensusParameters::standard(),
arb_gas_price,
)
.check_without_signatures(Default::default(), &ConsensusParameters::standard())
.expect("Duplicated UTXO id is valid for contract input");
}
Loading

0 comments on commit 5d4f9fe

Please sign in to comment.