1
1
use anyhow:: Context ;
2
- use aptos_sdk:: rest_client:: {
3
- aptos_api_types:: { Address , EntryFunctionId , IdentifierWrapper , MoveModuleId , ViewRequest } ,
4
- } ;
5
- use aptos_sdk:: types:: account_address:: AccountAddress ;
2
+ use aptos_sdk:: rest_client:: aptos_api_types:: { ViewRequest , EntryFunctionId , MoveModuleId , Address , IdentifierWrapper } ;
6
3
use movement_client:: {
7
4
coin_client:: CoinClient ,
8
- rest_client:: Client ,
5
+ rest_client:: { Client , FaucetClient } ,
9
6
types:: LocalAccount ,
7
+ crypto:: ed25519:: Ed25519PrivateKey ,
8
+ types:: account_config:: aptos_test_root_address,
10
9
} ;
10
+ use movement_client:: types:: account_address:: AccountAddress ;
11
11
use once_cell:: sync:: Lazy ;
12
12
use std:: str:: FromStr ;
13
13
use url:: Url ;
14
- use reqwest;
15
14
16
15
static SUZUKA_CONFIG : Lazy < movement_config:: Config > = Lazy :: new ( || {
17
16
let dot_movement = dot_movement:: DotMovement :: try_from_env ( ) . unwrap ( ) ;
18
17
let config = dot_movement. try_get_config_from_json :: < movement_config:: Config > ( ) . unwrap ( ) ;
19
18
config
20
19
} ) ;
21
20
22
- #[ tokio:: main]
23
- async fn main ( ) -> Result < ( ) , anyhow:: Error > {
24
- println ! ( "Starting e2e_ggp_deprecation test..." ) ;
25
-
26
- // Connect to the node
21
+ static NODE_URL : Lazy < Url > = Lazy :: new ( || {
27
22
let node_connection_address = SUZUKA_CONFIG
28
23
. execution_config
29
24
. maptos_config
@@ -37,115 +32,88 @@ async fn main() -> Result<(), anyhow::Error> {
37
32
. maptos_rest_connection_port
38
33
. clone ( ) ;
39
34
let node_connection_url = format ! ( "http://{}:{}" , node_connection_address, node_connection_port) ;
40
-
41
- println ! ( "Connecting to node at: {}" , node_connection_url) ;
42
-
43
- let rest_client = Client :: new ( Url :: from_str ( & node_connection_url) ?) ;
35
+ Url :: from_str ( node_connection_url. as_str ( ) ) . unwrap ( )
36
+ } ) ;
37
+
38
+ static FAUCET_URL : Lazy < Url > = Lazy :: new ( || {
39
+ let faucet_listen_address = SUZUKA_CONFIG
40
+ . execution_config
41
+ . maptos_config
42
+ . client
43
+ . maptos_faucet_rest_connection_hostname
44
+ . clone ( ) ;
45
+ let faucet_listen_port = SUZUKA_CONFIG
46
+ . execution_config
47
+ . maptos_config
48
+ . client
49
+ . maptos_faucet_rest_connection_port
50
+ . clone ( ) ;
51
+ let faucet_listen_url = format ! ( "http://{}:{}" , faucet_listen_address, faucet_listen_port) ;
52
+ Url :: from_str ( faucet_listen_url. as_str ( ) ) . unwrap ( )
53
+ } ) ;
54
+
55
+ #[ tokio:: main]
56
+ async fn main ( ) -> Result < ( ) , anyhow:: Error > {
57
+ println ! ( "Starting e2e_ggp_deprecation test..." ) ;
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 ( ) ) ;
44
61
let coin_client = CoinClient :: new ( & rest_client) ;
45
62
46
63
println ! ( "Attempting to get chain info..." ) ;
47
-
64
+
48
65
// Create test accounts
49
66
let mut sender = LocalAccount :: generate ( & mut rand:: rngs:: OsRng ) ;
50
67
let beneficiary = LocalAccount :: generate ( & mut rand:: rngs:: OsRng ) ;
51
-
52
68
println ! ( "Created test accounts" ) ;
53
69
println ! ( "Sender address: {}, Beneficiary address: {}" , sender. address( ) , beneficiary. address( ) ) ;
54
70
55
- // Fund the sender account using the testnet faucet
56
- println ! ( "Funding sender account via testnet faucet..." ) ;
57
-
58
- let faucet_url = if let Ok ( override_url) = std:: env:: var ( "MOVEMENT_FAUCET_URL" ) {
59
- override_url
60
- } else {
61
- "https://faucet.testnet.movementinfra.xyz" . to_string ( )
62
- } ;
63
-
64
- // Try different approaches to match what the faucet expects
65
- let client = reqwest:: Client :: new ( ) ;
66
-
67
- // First try GET with address (some faucets prefer this)
68
- let response = client
69
- . get ( & format ! ( "{}/mint" , faucet_url) )
70
- . query ( & [
71
- ( "address" , sender. address ( ) . to_string ( ) ) ,
72
- ( "amount" , "1000000" . to_string ( ) ) ,
73
- ( "return_txns" , "true" . to_string ( ) ) ,
74
- ] )
75
- . send ( )
76
- . await
77
- . context ( "Failed to send faucet GET request" ) ?;
78
-
79
- let status = response. status ( ) ;
80
- println ! ( "Faucet GET response status: {}" , status) ;
81
-
82
- if !status. is_success ( ) {
83
- // If GET fails, try POST with form data
84
- println ! ( "GET request failed with status {}, trying POST with form data..." , status) ;
85
- let response = client
86
- . post ( & format ! ( "{}/mint" , faucet_url) )
87
- . form ( & [
88
- ( "address" , sender. address ( ) . to_string ( ) ) ,
89
- ( "amount" , "1000000" . to_string ( ) ) ,
90
- ( "return_txns" , "true" . to_string ( ) ) ,
91
- ] )
92
- . send ( )
93
- . await
94
- . context ( "Failed to send faucet POST request" ) ?;
95
- let status = response. status ( ) ;
96
- println ! ( "Faucet POST response status: {}" , status) ;
97
- if !status. is_success ( ) {
98
- let error_text = response. text ( ) . await . unwrap_or_default ( ) ;
99
- return Err ( anyhow:: anyhow!( "Faucet request failed with status {}: {}" , status, error_text) ) ;
100
- }
101
- }
102
-
103
- // Get the response body to see what the faucet actually returned
104
- let response_text = response. text ( ) . await . unwrap_or_default ( ) ;
105
- println ! ( "Faucet response body: {}" , response_text) ;
106
-
107
- println ! ( "Sender account funded request accepted by faucet" ) ;
108
-
109
- // Wait longer for account creation and add more debugging
110
- println ! ( "Waiting for account to appear on-chain..." ) ;
111
- let mut created = false ;
112
- for attempt in 1 ..=20 { // Increased from 10 to 20 attempts
113
- println ! ( "Checking account existence... attempt {}/20" , attempt) ;
114
- match rest_client. get_account ( sender. address ( ) ) . await {
115
- Ok ( account_info) => {
116
- println ! ( "✅ Account now exists on-chain!" ) ;
117
- println ! ( " Sequence number: {}" , account_info. inner( ) . sequence_number) ;
118
- println ! ( " Authentication key: {:?}" , account_info. inner( ) . authentication_key) ;
119
- println ! ( " Created in attempt {}" , attempt) ;
120
- created = true ;
121
- break ;
122
- }
123
- Err ( e) => {
124
- println ! ( "❌ Account not found yet (attempt {}/20): {}" , attempt, e) ;
125
- if attempt < 20 {
126
- println ! ( "Waiting 1 second before next check..." ) ;
127
- tokio:: time:: sleep ( tokio:: time:: Duration :: from_secs ( 1 ) ) . await ; // Increased from 500ms to 1s
128
- }
71
+ // Fund via local faucet (same pattern as ggp_gas_fee)
72
+ println ! ( "Funding sender account via faucet..." ) ;
73
+ let faucet_res = faucet_client. fund ( sender. address ( ) , 1_000_000 ) . await ;
74
+ if let Err ( e) = faucet_res {
75
+ let msg = format ! ( "{}" , e) ;
76
+ if msg. contains ( "ENO_CAPABILITIES" ) || msg. contains ( "mint capability" ) {
77
+ println ! ( "[WARN] Faucet mint failed due to missing capability. Falling back to genesis funding..." ) ;
78
+ // Fallback: fund via genesis transfer
79
+ let raw_private_key = SUZUKA_CONFIG
80
+ . execution_config
81
+ . maptos_config
82
+ . chain
83
+ . maptos_private_key_signer_identifier
84
+ . try_raw_private_key ( ) ?;
85
+ let private_key = Ed25519PrivateKey :: try_from ( raw_private_key. as_slice ( ) ) ?;
86
+ let mut genesis = LocalAccount :: new ( aptos_test_root_address ( ) , private_key, 0 ) ;
87
+ if let Ok ( acct) = rest_client. get_account ( genesis. address ( ) ) . await {
88
+ genesis. set_sequence_number ( acct. inner ( ) . sequence_number ) ;
129
89
}
90
+ let txh = coin_client
91
+ . transfer ( & mut genesis, sender. address ( ) , 1_000_000 , None )
92
+ . await
93
+ . context ( "Fallback transfer from genesis failed" ) ?;
94
+ rest_client
95
+ . wait_for_transaction ( & txh)
96
+ . await
97
+ . context ( "Failed waiting for fallback transfer" ) ?;
98
+ println ! ( "Sender account funded via genesis fallback" ) ;
99
+ } else {
100
+ return Err ( anyhow:: anyhow!( "Failed to fund sender account via faucet: {}" , e) ) ;
130
101
}
102
+ } else {
103
+ println ! ( "Sender account funded successfully via faucet" ) ;
131
104
}
132
-
133
- if !created {
134
- return Err ( anyhow:: anyhow!( "Sender account not found on-chain after faucet funding" ) ) ;
135
- }
136
-
137
- println ! ( "Sender account funded successfully via testnet faucet" ) ;
138
-
139
- // Create the beneficiary account (just create, no funding needed for this test)
140
- println ! ( "Creating beneficiary account..." ) ;
141
- // For now, just create the account locally - it will be created when first transaction is sent to it
142
105
106
+ println ! ( "Creating beneficiary account via faucet..." ) ;
107
+ faucet_client
108
+ . create_account ( beneficiary. address ( ) )
109
+ . await
110
+ . context ( "Failed to create beneficiary account via faucet" ) ?;
111
+ println ! ( "Beneficiary account created successfully" ) ;
112
+
113
+ // === Existing verification logic follows ===
143
114
// Test 1: Verify new fee collection mechanism
144
115
println ! ( "=== Test 1: Verifying new fee collection mechanism ===" ) ;
145
-
146
- // First, check if the COLLECT_AND_DISTRIBUTE_GAS_FEES feature flag is enabled
147
116
println ! ( "Checking if COLLECT_AND_DISTRIBUTE_GAS_FEES feature flag is enabled..." ) ;
148
-
149
117
let feature_flag_view_req = ViewRequest {
150
118
function : EntryFunctionId {
151
119
module : MoveModuleId {
@@ -157,7 +125,6 @@ async fn main() -> Result<(), anyhow::Error> {
157
125
type_arguments : vec ! [ ] ,
158
126
arguments : vec ! [ ] ,
159
127
} ;
160
-
161
128
match rest_client. view ( & feature_flag_view_req, None ) . await {
162
129
Ok ( features_response) => {
163
130
println ! ( "On-chain features response: {:?}" , features_response. inner( ) ) ;
@@ -276,41 +243,10 @@ async fn main() -> Result<(), anyhow::Error> {
276
243
// Execute test transaction
277
244
println ! ( "Executing test transaction..." ) ;
278
245
279
- // Debug: Check account sequence number and other details
280
- println ! ( "Sender account details:" ) ;
281
- println ! ( " Address: {}" , sender. address( ) ) ;
282
- println ! ( " Sequence number: {}" , sender. sequence_number( ) ) ;
283
- println ! ( " Public key: {:?}" , sender. public_key( ) ) ;
284
-
285
- // Try to get account info from the chain
286
- match rest_client. get_account ( sender. address ( ) ) . await {
287
- Ok ( account_info) => {
288
- println ! ( " On-chain sequence number: {}" , account_info. inner( ) . sequence_number) ;
289
- println ! ( " On-chain authentication key: {:?}" , account_info. inner( ) . authentication_key) ;
290
- }
291
- Err ( e) => {
292
- println ! ( " [WARN] Could not get on-chain account info: {}" , e) ;
293
- }
294
- }
295
-
296
- println ! ( "Beneficiary address: {}" , beneficiary. address( ) ) ;
297
-
298
- // Try the transaction with better error handling
299
- let test_txn = match coin_client. transfer ( & mut sender, beneficiary. address ( ) , 1_000 , None ) . await {
300
- Ok ( txn) => {
301
- println ! ( "Transaction submitted successfully with hash: {:?}" , txn) ;
302
- txn
303
- }
304
- Err ( e) => {
305
- println ! ( "[ERROR] Transaction submission failed: {}" , e) ;
306
- println ! ( "[DEBUG] This might be due to:" ) ;
307
- println ! ( " - Account not properly funded" ) ;
308
- println ! ( " - Sequence number mismatch" ) ;
309
- println ! ( " - Network connectivity issues" ) ;
310
- println ! ( " - Gas price/limit issues" ) ;
311
- return Err ( e. context ( "Failed to submit test transaction" ) ) ;
312
- }
313
- } ;
246
+ let test_txn = coin_client
247
+ . transfer ( & mut sender, beneficiary. address ( ) , 1_000 , None )
248
+ . await
249
+ . context ( "Failed to submit test transaction" ) ?;
314
250
315
251
rest_client
316
252
. wait_for_transaction ( & test_txn)
0 commit comments