Skip to content

Commit bea859c

Browse files
committed
feat: e2e tests to check if feature flag is enabled and if gas collection happens properly
1 parent 343fd34 commit bea859c

File tree

7 files changed

+599
-5
lines changed

7 files changed

+599
-5
lines changed

justfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ build-push-container IMAGE:
1212
./scripts/movement/build-push-image {{ IMAGE }}
1313
container-tests:
1414
./scripts/tests/container-tests
15+
16+
# E2E Tests for GGP Deprecation
17+
test-e2e-verify-collect-fee:
18+
process-compose -f process-compose/movement-full-node/process-compose.test-e2e-verify-collect-fee.yml up --wait --follow
19+
20+
test-e2e-framework-upgrade-collect-gas-fees:
21+
process-compose -f process-compose/movement-full-node/process-compose.test-e2e-framework-upgrade-collect-gas-fees.yml up --wait --follow

networks/movement/movement-client/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ path = "src/bin/e2e/whitelist.rs"
4646
name = "movement-tests-e2e-ggp-gas-fee"
4747
path = "src/bin/e2e/ggp_gas_fee.rs"
4848

49+
[[bin]]
50+
name = "verify_collect_fee_deprecation"
51+
path = "src/bin/e2e/verify_collect_fee_deprecation.rs"
52+
53+
[[bin]]
54+
name = "framework_upgrade_collect_gas_fees_test"
55+
path = "src/bin/e2e/framework_upgrade_collect_gas_fees_test.rs"
56+
4957
[[bin]]
5058
name = "movement-tests-e2e-transfer"
5159
path = "src/bin/e2e/transfer.rs"
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
use anyhow::Context;
2+
use movement_client::{
3+
coin_client::CoinClient,
4+
rest_client::{Client, FaucetClient},
5+
types::LocalAccount,
6+
};
7+
use aptos_sdk::rest_client::aptos_api_types::{ViewRequest, EntryFunctionId, MoveModuleId, Address, IdentifierWrapper};
8+
use std::str::FromStr;
9+
use once_cell::sync::Lazy;
10+
use url::Url;
11+
12+
static SUZUKA_CONFIG: Lazy<movement_config::Config> = Lazy::new(|| {
13+
let dot_movement = dot_movement::DotMovement::try_from_env().unwrap();
14+
let config = dot_movement.try_get_config_from_json::<movement_config::Config>().unwrap();
15+
config
16+
});
17+
18+
static NODE_URL: Lazy<Url> = Lazy::new(|| {
19+
let node_connection_address = SUZUKA_CONFIG
20+
.execution_config
21+
.maptos_config
22+
.client
23+
.maptos_rest_connection_hostname
24+
.clone();
25+
let node_connection_port = SUZUKA_CONFIG
26+
.execution_config
27+
.maptos_config
28+
.client
29+
.maptos_rest_connection_port
30+
.clone();
31+
32+
let node_connection_url = format!("http://{}:{}", node_connection_address, node_connection_port);
33+
Url::parse(node_connection_url.as_str()).unwrap()
34+
});
35+
36+
static FAUCET_URL: Lazy<Url> = Lazy::new(|| {
37+
let faucet_listen_address = SUZUKA_CONFIG
38+
.execution_config
39+
.maptos_config
40+
.client
41+
.maptos_faucet_rest_connection_hostname
42+
.clone();
43+
let faucet_listen_port = SUZUKA_CONFIG
44+
.execution_config
45+
.maptos_config
46+
.client
47+
.maptos_faucet_rest_connection_port
48+
.clone();
49+
50+
let faucet_listen_url = format!("http://{}:{}", faucet_listen_address, faucet_listen_port);
51+
Url::parse(faucet_listen_url.as_str()).unwrap()
52+
});
53+
54+
#[tokio::main]
55+
async fn main() -> Result<(), anyhow::Error> {
56+
println!("Starting framework_upgrade_collect_gas_fees_test...");
57+
58+
println!("Connecting to node at: {}", NODE_URL.as_str());
59+
let rest_client = Client::new(NODE_URL.clone());
60+
let faucet_client = FaucetClient::new(FAUCET_URL.clone(), NODE_URL.clone());
61+
let coin_client = CoinClient::new(&rest_client);
62+
63+
println!("Attempting to get chain info...");
64+
65+
// Create test accounts
66+
let mut sender = LocalAccount::generate(&mut rand::rngs::OsRng);
67+
let beneficiary = LocalAccount::generate(&mut rand::rngs::OsRng);
68+
69+
println!("Created test accounts");
70+
println!("Sender address: {}, Beneficiary address: {}", sender.address(), beneficiary.address());
71+
72+
// Fund the sender account
73+
faucet_client
74+
.fund(sender.address(), 1_000_000)
75+
.await
76+
.context("Failed to fund sender account")?;
77+
78+
// Create the beneficiary account
79+
faucet_client
80+
.create_account(beneficiary.address())
81+
.await
82+
.context("Failed to create beneficiary account")?;
83+
84+
// Test 1: Check current framework version and verify upgrade
85+
println!("=== Test 1: Checking current framework version and upgrade status ===");
86+
87+
// Get chain info to check framework version
88+
let ledger_info = rest_client
89+
.get_ledger_information()
90+
.await
91+
.context("Failed to get ledger information")?;
92+
93+
let chain_info = ledger_info.into_inner();
94+
println!("Chain ID: {}", chain_info.chain_id);
95+
println!("Ledger version: {}", chain_info.version);
96+
println!("Ledger timestamp: {}", chain_info.timestamp_usecs);
97+
98+
// Test 2: Verify transaction_fee module functionality by trying to call a view function
99+
println!("=== Test 2: Verifying transaction_fee module functionality ===");
100+
101+
// Try to call a view function on the transaction_fee module to verify it exists
102+
let transaction_fee_view_req = ViewRequest {
103+
function: EntryFunctionId {
104+
module: MoveModuleId {
105+
address: Address::from_str("0x1")?,
106+
name: IdentifierWrapper::from_str("transaction_fee")?,
107+
},
108+
name: IdentifierWrapper::from_str("get_fee_config")?,
109+
},
110+
type_arguments: vec![],
111+
arguments: vec![],
112+
};
113+
114+
let transaction_fee_module_exists = rest_client
115+
.view(&transaction_fee_view_req, None)
116+
.await
117+
.is_ok();
118+
119+
if transaction_fee_module_exists {
120+
println!("[PASS] transaction_fee module is accessible - framework upgrade appears successful");
121+
} else {
122+
println!("[FAIL] transaction_fee module is not accessible - framework upgrade may not be complete");
123+
return Err(anyhow::anyhow!("Framework upgrade verification failed: transaction_fee module not accessible"));
124+
}
125+
126+
// Test 3: Verify governed gas pool is deprecated
127+
println!("=== Test 3: Verifying governed gas pool deprecation ===");
128+
129+
// Try to call a view function on the old governed_gas_pool module
130+
let governed_gas_pool_view_req = ViewRequest {
131+
function: EntryFunctionId {
132+
module: MoveModuleId {
133+
address: Address::from_str("0x1")?,
134+
name: IdentifierWrapper::from_str("governed_gas_pool")?,
135+
},
136+
name: IdentifierWrapper::from_str("get_gas_pool_address")?,
137+
},
138+
type_arguments: vec![],
139+
arguments: vec![],
140+
};
141+
142+
let governed_gas_pool_exists = rest_client
143+
.view(&governed_gas_pool_view_req, None)
144+
.await
145+
.is_ok();
146+
147+
if !governed_gas_pool_exists {
148+
println!("[PASS] governed_gas_pool module is not accessible - deprecation successful");
149+
} else {
150+
println!("[WARN] governed_gas_pool module is still accessible - deprecation may not be complete");
151+
// Don't fail the test here as deprecation might be in progress
152+
}
153+
154+
// Test 4: Execute transactions and verify gas fees are collected via new module
155+
println!("=== Test 4: Executing test transaction to verify gas fee collection via transaction_fee module ===");
156+
157+
let initial_sender_balance = coin_client
158+
.get_account_balance(&sender.address())
159+
.await
160+
.context("Failed to get initial sender balance")?;
161+
162+
println!("Initial sender balance: {}", initial_sender_balance);
163+
164+
// Execute test transaction
165+
println!("Executing test transaction...");
166+
167+
let test_txn = coin_client
168+
.transfer(&mut sender, beneficiary.address(), 1_000, None)
169+
.await
170+
.context("Failed to submit test transaction")?;
171+
172+
rest_client
173+
.wait_for_transaction(&test_txn)
174+
.await
175+
.context("Failed when waiting for transfer transaction")?;
176+
177+
println!("Test transaction completed: {:?}", test_txn);
178+
179+
// Test 5: Verify gas fees were collected and analyze the transaction
180+
println!("=== Test 5: Verifying gas fee collection and analyzing transaction ===");
181+
182+
let final_sender_balance = coin_client
183+
.get_account_balance(&sender.address())
184+
.await
185+
.context("Failed to get final sender balance")?;
186+
187+
println!("Final sender balance: {}", final_sender_balance);
188+
189+
// Verify that gas fees were deducted
190+
if final_sender_balance < initial_sender_balance {
191+
let gas_fees_deducted = initial_sender_balance - final_sender_balance;
192+
println!("Gas fees deducted: {}", gas_fees_deducted);
193+
194+
// Note: We can't easily get transaction details without the hash, so we'll focus on balance verification
195+
println!("[PASS] Transaction executed successfully with hash: {:?}", test_txn);
196+
println!("[PASS] Gas fees were properly deducted, indicating fee collection is working");
197+
} else {
198+
println!("[FAIL] No gas fees were deducted - this indicates a serious issue");
199+
return Err(anyhow::anyhow!("Gas fee collection verification failed: no fees deducted"));
200+
}
201+
202+
// Test 6: Verify transaction_fee module state and configuration
203+
println!("=== Test 6: Verifying transaction_fee module state and configuration ===");
204+
205+
// Try to get transaction_fee module configuration through view calls
206+
let fee_config_view_req = ViewRequest {
207+
function: EntryFunctionId {
208+
module: MoveModuleId {
209+
address: Address::from_str("0x1")?,
210+
name: IdentifierWrapper::from_str("transaction_fee")?,
211+
},
212+
name: IdentifierWrapper::from_str("get_fee_config")?,
213+
},
214+
type_arguments: vec![],
215+
arguments: vec![],
216+
};
217+
218+
match rest_client.view(&fee_config_view_req, None).await {
219+
Ok(response) => {
220+
println!("[PASS] Transaction fee configuration accessible");
221+
println!("Configuration response: {:?}", response.inner());
222+
}
223+
Err(e) => {
224+
println!("[WARN] Could not access transaction fee configuration: {}", e);
225+
}
226+
}
227+
228+
// Test 7: Framework upgrade verification summary
229+
println!("=== Test 7: Framework upgrade verification summary ===");
230+
231+
if transaction_fee_module_exists && !governed_gas_pool_exists {
232+
println!("[PASS] Framework upgrade to transaction_fee::collect_fee is COMPLETE");
233+
println!("[PASS] Migration from governed gas pool to transaction_fee::collect_fee is SUCCESSFUL");
234+
println!("[PASS] New fee collection mechanism is operational");
235+
} else if transaction_fee_module_exists && governed_gas_pool_exists {
236+
println!("[WARN] Framework upgrade is IN PROGRESS");
237+
println!("[PASS] New transaction_fee module is accessible");
238+
println!("[WARN] Old governed_gas_pool module is still accessible (deprecation in progress)");
239+
} else {
240+
println!("[FAIL] Framework upgrade verification FAILED");
241+
println!("[FAIL] New transaction_fee module is not accessible");
242+
return Err(anyhow::anyhow!("Framework upgrade verification failed"));
243+
}
244+
245+
println!("All tests completed successfully!");
246+
Ok(())
247+
}

0 commit comments

Comments
 (0)