Skip to content

Commit

Permalink
Merge branch 'master' into dento/error-for-nonexistent-input-contract
Browse files Browse the repository at this point in the history
  • Loading branch information
AurelienFT authored Dec 2, 2024
2 parents 4386bdd + 767f4e6 commit 3e4d86e
Show file tree
Hide file tree
Showing 43 changed files with 468 additions and 49 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]

### Added
- [871](https://github.com/FuelLabs/fuel-vm/pull/871): Add `expiration` policy that prevent a transaction to be inserted after a given block height.
- [870](https://github.com/FuelLabs/fuel-vm/pull/870): Add 3 new ZK-related opcodes: eadd (ecAdd on EVM), emul (ecMul on EVM), epar (ecPairing on EVM)
- [875](https://github.com/FuelLabs/fuel-vm/pull/875): Updated `wasm-bindgen` to `0.2.97`

Expand Down
4 changes: 4 additions & 0 deletions fuel-asm/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ crate::enum_try_from! {

/// Set `$rA` to `tx.policies[count_ones(0b1111 & tx.policyTypes) - 1].maxFee`
PolicyMaxFee = 0x504,

/// Set `$rA` to `tx.policies[count_ones(0b11111 & tx.policyTypes) - 1].expiration`
PolicyExpiration = 0x505,
},
Immediate12
}
Expand Down Expand Up @@ -340,6 +343,7 @@ fn encode_gtf_args() {
GTFArgs::PolicyTip,
GTFArgs::PolicyWitnessLimit,
GTFArgs::PolicyMaturity,
GTFArgs::PolicyExpiration,
GTFArgs::PolicyMaxFee,
];

Expand Down
7 changes: 7 additions & 0 deletions fuel-tx/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
field::{
self,
BytecodeWitnessIndex,
Expiration,
Maturity,
Tip,
Witnesses,
Expand Down Expand Up @@ -376,6 +377,12 @@ impl<Tx: Buildable> TransactionBuilder<Tx> {
self
}

pub fn expiration(&mut self, expiration: BlockHeight) -> &mut Self {
self.tx.set_expiration(expiration);

self
}

pub fn witness_limit(&mut self, witness_limit: Word) -> &mut Self {
self.tx.set_witness_limit(witness_limit);

Expand Down
16 changes: 16 additions & 0 deletions fuel-tx/src/tests/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ fn transaction_serde_serialization_deserialization() {
},
Policies::new()
.with_tip(Word::MAX >> 1)
.with_expiration((u32::MAX >> 2).into())
.with_maturity((u32::MAX >> 3).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
Expand All @@ -397,6 +398,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -411,6 +413,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -425,6 +428,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -438,6 +442,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![i.clone()],
Expand All @@ -451,6 +456,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -464,6 +470,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -477,6 +484,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -496,6 +504,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![i.clone()],
Expand All @@ -513,6 +522,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -530,6 +540,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -547,6 +558,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -566,6 +578,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![i.clone()],
Expand All @@ -583,6 +596,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -600,6 +614,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand All @@ -617,6 +632,7 @@ fn transaction_serde_serialization_deserialization() {
Policies::new()
.with_tip(Word::MAX >> 1)
.with_maturity((u32::MAX >> 3).into())
.with_expiration((u32::MAX >> 2).into())
.with_witness_limit(Word::MAX >> 4)
.with_max_fee(Word::MAX >> 5),
vec![],
Expand Down
75 changes: 75 additions & 0 deletions fuel-tx/src/tests/valid_cases/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,81 @@ fn maturity() {
assert_eq!(ValidityError::TransactionMaturity, err);
}

#[test]
fn script__check__valid_expiration_policy() {
let rng = &mut StdRng::seed_from_u64(8586);

let block_height = 1000.into();

TransactionBuilder::script(generate_bytes(rng), generate_bytes(rng))
// Given
.expiration(block_height)
.add_fee_input()
.finalize()
// When
.check(block_height, &test_params())
// Then
.expect("Failed to validate script");
}

#[test]
fn script__check__invalid_expiration_policy() {
let rng = &mut StdRng::seed_from_u64(8586);

// Given
let block_height = 1000.into();
let old_block_height = 999u32.into();
let err = TransactionBuilder::script(generate_bytes(rng), generate_bytes(rng))
// Given
.expiration(old_block_height)
.add_fee_input()
.finalize()
// When
.check(block_height, &test_params())
.expect_err("Expected erroneous transaction");

// Then
assert_eq!(ValidityError::TransactionExpiration, err);
}

#[test]
fn create__check__valid_expiration_policy() {
let rng = &mut StdRng::seed_from_u64(8586);

let block_height = 1000.into();

TransactionBuilder::create(rng.gen(), rng.gen(), vec![])
// Given
.expiration(block_height)
.add_fee_input()
.add_contract_created()
.finalize()
// When
.check(block_height, &test_params())
// Then
.expect("Failed to validate tx create");
}

#[test]
fn create__check__invalid_expiration_policy() {
let rng = &mut StdRng::seed_from_u64(8586);

// Given
let block_height = 1000.into();
let old_block_height = 999u32.into();
let err = TransactionBuilder::create(rng.gen(), rng.gen(), vec![])
.expiration(old_block_height)
.add_fee_input()
.add_contract_created()
.finalize()
// When
.check(block_height, &test_params())
.expect_err("Failed to validate tx create");

// Then
assert_eq!(ValidityError::TransactionExpiration, err);
}

#[test]
fn script__check__not_set_witness_limit_success() {
// Given
Expand Down
33 changes: 33 additions & 0 deletions fuel-tx/src/tests/valid_cases/transaction/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fn valid_blob_transaction() -> TransactionBuilder<Blob> {
predicate(),
vec![],
));
builder.expiration(u32::MAX.into());

builder
}
Expand Down Expand Up @@ -69,6 +70,38 @@ fn check__fails_if_maturity_not_met() {
assert_eq!(Err(ValidityError::TransactionMaturity), result);
}

#[test]
fn check__success_if_expiration_met() {
// Given
let block_height: BlockHeight = 1000.into();
let success_block_height = block_height.succ().unwrap();
let tx = valid_blob_transaction()
.expiration(success_block_height)
.finalize_as_transaction();

// When
let result = tx.check(block_height, &test_params());

// Then
assert_eq!(Ok(()), result);
}

#[test]
fn check__fails_if_expiration_not_met() {
// Given
let block_height: BlockHeight = 1000.into();
let failing_block_height = block_height.pred().unwrap();
let tx = valid_blob_transaction()
.expiration(failing_block_height)
.finalize_as_transaction();

// When
let result = tx.check(block_height, &test_params());

// Then
assert_eq!(Err(ValidityError::TransactionExpiration), result);
}

#[test]
fn check__fails_if_blob_id_doesnt_match_payload() {
// Given
Expand Down
35 changes: 35 additions & 0 deletions fuel-tx/src/tests/valid_cases/transaction/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fn valid_upgrade_transaction() -> TransactionBuilder<Upgrade> {
vec![],
));
builder.with_params(test_params());
builder.expiration(u32::MAX.into());

builder
}
Expand All @@ -52,6 +53,7 @@ fn valid_upgrade_transaction_with_message() -> TransactionBuilder<Upgrade> {
vec![],
));
builder.with_params(test_params());
builder.expiration(u32::MAX.into());

builder
}
Expand Down Expand Up @@ -91,6 +93,39 @@ fn maturity() {
assert_eq!(Err(ValidityError::TransactionMaturity), result);
}

#[test]
fn upgrade__check__success_if_expiration_met() {
// Given
let block_height: BlockHeight = 1000.into();
let success_block_height = block_height.succ().unwrap();
let tx = valid_upgrade_transaction()
.expiration(success_block_height)
.finalize_as_transaction();

// When
let result = tx.check(block_height, &test_params());

// Then
assert_eq!(Ok(()), result);
}

#[test]
fn upgrade__check__valid_expiration_policy() {
let block_height: BlockHeight = 1000.into();
let failing_block_height = block_height.pred().unwrap();

// Given
let tx = valid_upgrade_transaction()
.expiration(failing_block_height)
.finalize_as_transaction();

// When
let result = tx.check(block_height, &test_params());

// Then
assert_eq!(Err(ValidityError::TransactionExpiration), result);
}

#[test]
fn check__not_set_witness_limit_success() {
// Given
Expand Down
Loading

0 comments on commit 3e4d86e

Please sign in to comment.