Skip to content

Commit 2030378

Browse files
rymncxgreenx
andauthored
chore(tx): add test to ensure heap memory is cleared between predicate executions (#2963)
## Linked Issues/PRs <!-- List of related issues/PRs --> - vm pr: FuelLabs/fuel-vm#941 ## Description <!-- List of detailed changes --> adds a test with 2 predicates in one transaction, one that writes to the heap and one that reallocates and reads from it. it should be zeroed out. ## Checklist - [ ] Breaking changes are clearly marked as such in the PR description and changelog - [ ] New behavior is reflected in tests - [ ] [The specification](https://github.com/FuelLabs/fuel-specs/) matches the implemented behavior (link update PR if changes are needed) ### Before requesting review - [ ] I have reviewed the code myself - [ ] I have created follow-up issues caused by this PR and linked them here ### After merging, notify other teams [Add or remove entries as needed] - [ ] [Rust SDK](https://github.com/FuelLabs/fuels-rs/) - [ ] [Sway compiler](https://github.com/FuelLabs/sway/) - [ ] [Platform documentation](https://github.com/FuelLabs/devrel-requests/issues/new?assignees=&labels=new+request&projects=&template=NEW-REQUEST.yml&title=%5BRequest%5D%3A+) (for out-of-organization contributors, the person merging the PR will do this) - [ ] Someone else? Co-authored-by: xgreenx <XgreenX9999@gmail.com>
1 parent 77f6ca1 commit 2030378

File tree

4 files changed

+164
-37
lines changed

4 files changed

+164
-37
lines changed

Cargo.lock

Lines changed: 38 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ fuel-core-xtask = { version = "0.0.0", path = "./xtask" }
9797
fuel-gas-price-algorithm = { version = "0.41.9", path = "crates/fuel-gas-price-algorithm" }
9898

9999
# Fuel dependencies
100-
fuel-vm-private = { version = "0.59.2", package = "fuel-vm", default-features = false }
100+
fuel-vm-private = { version = "0.59.3", package = "fuel-vm", default-features = false }
101101

102102
# Common dependencies
103103
anyhow = "1.0"

tests/tests/tx.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ mod txn_status_subscription;
5959
mod txpool;
6060
mod upgrade;
6161
mod utxo_validation;
62+
mod vm_memory;
6263

6364
#[test]
6465
fn basic_script_snapshot() {

tests/tests/tx/vm_memory.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//! Tests related to vm memory usage
2+
3+
use fuel_core_types::{
4+
fuel_asm::{
5+
op,
6+
GTFArgs,
7+
RegId,
8+
},
9+
fuel_tx::{
10+
Finalizable,
11+
Input,
12+
TransactionBuilder,
13+
},
14+
fuel_types::AssetId,
15+
};
16+
use rand::{
17+
rngs::StdRng,
18+
Rng,
19+
SeedableRng,
20+
};
21+
use test_helpers::builder::TestSetupBuilder;
22+
23+
#[tokio::test]
24+
async fn predicate_that_uses_heap_does_not_leave_dirty_memory_for_next_predicate() {
25+
// This test checks that a first predicate that uses the heap does not leave
26+
// dirty memory for the next predicate.
27+
// First predicate:
28+
// 1. Allocates memory on the heap 10_000.
29+
// 2. Copies data from predicate input where it is [1; 10_000]
30+
// 3. Compares data from the predicate input with copied data on the heap.
31+
//
32+
// Second predicate:
33+
// 1. Allocates memory on the heap 100_000.
34+
// 2. Compares data from the predicate input(it is [0; 100_000]) with the heap.
35+
let mut rng = StdRng::seed_from_u64(121210);
36+
37+
const AMOUNT: u64 = 1_000;
38+
39+
let size_reg = 0x10;
40+
let data_start_reg = 0x11;
41+
let result_reg = 0x12;
42+
let first_data_size = 10_000;
43+
let first_predicate_index = 0;
44+
45+
let first_predicate = vec![
46+
op::movi(size_reg, first_data_size),
47+
op::aloc(size_reg),
48+
op::gtf_args(
49+
data_start_reg,
50+
first_predicate_index,
51+
GTFArgs::InputCoinPredicateData,
52+
),
53+
op::mcp(RegId::HP, data_start_reg, size_reg),
54+
op::meq(result_reg, RegId::HP, data_start_reg, size_reg),
55+
op::ret(result_reg),
56+
];
57+
let first_predicate_data = vec![1u8; first_data_size as usize];
58+
let first_predicate: Vec<u8> = first_predicate.into_iter().collect();
59+
let first_predicate_owner = Input::predicate_owner(&first_predicate);
60+
61+
let second_data_size = 100_000;
62+
let second_predicate_index = 1;
63+
64+
let second_predicate = vec![
65+
op::movi(size_reg, second_data_size),
66+
op::aloc(size_reg),
67+
op::gtf_args(
68+
data_start_reg,
69+
second_predicate_index,
70+
GTFArgs::InputCoinPredicateData,
71+
),
72+
op::meq(result_reg, RegId::HP, data_start_reg, size_reg),
73+
op::ret(result_reg),
74+
];
75+
let second_predicate_data = vec![0u8; second_data_size as usize];
76+
let second_predicate: Vec<u8> = second_predicate.into_iter().collect();
77+
let second_predicate_owner = Input::predicate_owner(&second_predicate);
78+
79+
// Given
80+
let transaction_with_predicates =
81+
TransactionBuilder::script(Default::default(), Default::default())
82+
.add_input(Input::coin_predicate(
83+
rng.gen(),
84+
first_predicate_owner,
85+
AMOUNT,
86+
AssetId::BASE,
87+
Default::default(),
88+
Default::default(),
89+
first_predicate,
90+
first_predicate_data,
91+
))
92+
.add_input(Input::coin_predicate(
93+
rng.gen(),
94+
second_predicate_owner,
95+
AMOUNT,
96+
AssetId::BASE,
97+
Default::default(),
98+
Default::default(),
99+
second_predicate,
100+
second_predicate_data,
101+
))
102+
.finalize();
103+
104+
let mut context = TestSetupBuilder::default();
105+
context.utxo_validation = true;
106+
context.config_coin_inputs_from_transactions(&[&transaction_with_predicates]);
107+
let context = context.finalize().await;
108+
109+
let mut transaction_with_predicates = transaction_with_predicates.into();
110+
context
111+
.client
112+
.estimate_predicates(&mut transaction_with_predicates)
113+
.await
114+
.unwrap();
115+
116+
// When
117+
let result = context
118+
.client
119+
.submit_and_await_commit(&transaction_with_predicates)
120+
.await;
121+
122+
// Then
123+
result.expect("Transaction should be executed successfully");
124+
}

0 commit comments

Comments
 (0)