@@ -18,17 +18,38 @@ mod receipt;
1818use metrics:: MetricsChecker ;
1919use receipt:: create_tap_receipt;
2020
21- // Constants taken from local-network/.env
22- // it could be possible to read that file
23- // along with the local-network/contracts.json
24- // and regex over to get bellow values
21+ // TODO: Would be nice to read this values from:
22+ // contrib/tap-agent/config.toml
23+ // and contrib/local-network/.env
2524const GATEWAY_URL : & str = "http://localhost:7700" ;
2625const SUBGRAPH_ID : & str = "BFr2mx7FgkJ36Y6pE5BiXs1KmNUmVDCnL82KUSdcLW1g" ;
2726const TAP_ESCROW_CONTRACT : & str = "0x0355B7B8cb128fA5692729Ab3AAa199C1753f726" ;
2827const GATEWAY_API_KEY : & str = "deadbeefdeadbeefdeadbeefdeadbeef" ;
29- const RECEIVER_ADDRESS : & str = "0xf4EF6650E48d099a4972ea5B414daB86e1998Bd3" ;
28+ // const RECEIVER_ADDRESS: &str = "0xf4EF6650E48d099a4972ea5B414daB86e1998Bd3";
3029const TAP_AGENT_METRICS_URL : & str = "http://localhost:7300/metrics" ;
3130
31+ const MNEMONIC : & str = "test test test test test test test test test test test junk" ;
32+ const GRAPH_URL : & str = "http://localhost:8000/subgraphs/name/graph-network" ;
33+
34+ const GRT_DECIMALS : u8 = 18 ;
35+ const GRT_BASE : u128 = 10u128 . pow ( GRT_DECIMALS as u32 ) ;
36+
37+ // With trigger_value_divisor = 500_000 and max_amount_willing_to_lose_grt = 1000
38+ // trigger_value = 0.002 GRT
39+ // We need to send at least 20 receipts to reach the trigger threshold
40+ // Sending slightly more than required to ensure triggering
41+ const MAX_RECEIPT_VALUE : u128 = GRT_BASE / 1_000 ;
42+ // This value should match the timestamp_buffer_secs
43+ // in the tap-agent setting + 10 seconds
44+ const WAIT_TIME_BATCHES : u64 = 40 ;
45+
46+ // Bellow constant is to define the number of receipts
47+ const NUM_RECEIPTS : u32 = 200 ;
48+
49+ // Send receipts in batches with a delay in between
50+ // to ensure some receipts get outside the timestamp buffer
51+ const BATCHES : u32 = 4 ;
52+
3253#[ tokio:: main]
3354async fn main ( ) -> Result < ( ) > {
3455 // Run the TAP receipt test
@@ -39,7 +60,7 @@ async fn tap_rav_test() -> Result<()> {
3960 // Setup wallet using your MnemonicBuilder
4061 let index: u32 = 0 ;
4162 let wallet: PrivateKeySigner = MnemonicBuilder :: < English > :: default ( )
42- . phrase ( "test test test test test test test test test test test junk" )
63+ . phrase ( MNEMONIC )
4364 . index ( index)
4465 . unwrap ( )
4566 . build ( )
@@ -53,45 +74,42 @@ async fn tap_rav_test() -> Result<()> {
5374
5475 // Query the network subgraph to find active allocations
5576 println ! ( "Querying for active allocations..." ) ;
56- let allocations_query = http_client
57- . post ( "http://localhost:8000/subgraphs/name/graph-network" )
77+ let response = http_client
78+ . post ( GRAPH_URL )
5879 . json ( & json ! ( {
5980 "query" : "{ allocations(where: { status: Active }) { id indexer { id } subgraphDeployment { id } } }"
6081 } ) )
6182 . send ( )
62- . await ;
83+ . await ? ;
6384
6485 // Default to a fallback allocation ID
6586 let mut allocation_id = Address :: from_str ( "0x0000000000000000000000000000000000000000" ) ?;
6687
67- // Try to find a valid allocation
68- if let Ok ( response) = allocations_query {
69- if response. status ( ) . is_success ( ) {
70- let response_text = response. text ( ) . await . unwrap ( ) ;
71- println ! ( "Network subgraph response: {}" , response_text) ;
72-
73- if let Ok ( json_value) = serde_json:: from_str :: < serde_json:: Value > ( & response_text) {
74- if let Some ( allocations) = json_value
75- . get ( "data" )
76- . and_then ( |d| d. get ( "allocations" ) )
77- . and_then ( |a| a. as_array ( ) )
78- {
79- if !allocations. is_empty ( ) {
80- if let Some ( id_str) = allocations[ 0 ] . get ( "id" ) . and_then ( |id| id. as_str ( ) ) {
81- println ! ( "Found allocation ID: {}" , id_str) ;
82- allocation_id = Address :: from_str ( id_str) ?;
83- }
84- }
85- }
86- }
87- }
88+ if !response. status ( ) . is_success ( ) {
89+ return Err ( anyhow:: anyhow!(
90+ "Network subgraph request failed with status: {}" ,
91+ response. status( )
92+ ) ) ;
8893 }
8994
90- // If we still don't have an allocation ID, create a mock one based on the receiver address
91- if allocation_id == Address :: from_str ( "0x0000000000000000000000000000000000000000" ) ? {
92- println ! ( "No allocation found, using a mock allocation based on receiver address" ) ;
93- allocation_id = Address :: from_str ( RECEIVER_ADDRESS ) ?;
94- }
95+ // Try to find a valid allocation
96+ let response_text = response. text ( ) . await ?;
97+ println ! ( "Network subgraph response: {}" , response_text) ;
98+
99+ // Extract allocation_id, if not found return an error
100+ // this should not happen as we run the fund escrow script
101+ // before(in theory tho)
102+ let json_value = serde_json:: from_str :: < serde_json:: Value > ( & response_text) ?;
103+ let allocation_id = json_value
104+ . get ( "data" )
105+ . and_then ( |d| d. get ( "allocations" ) )
106+ . and_then ( |a| a. as_array ( ) )
107+ . filter ( |arr| !arr. is_empty ( ) )
108+ . and_then ( |arr| arr[ 0 ] . get ( "id" ) )
109+ . and_then ( |id| id. as_str ( ) )
110+ . ok_or_else ( || anyhow:: anyhow!( "No valid allocation ID found" ) ) ?;
111+
112+ let allocation_id = Address :: from_str ( allocation_id) ?;
95113
96114 // Create a metrics checker
97115 let metrics_checker =
@@ -108,63 +126,44 @@ async fn tap_rav_test() -> Result<()> {
108126 let initial_unaggregated =
109127 initial_metrics. unaggregated_fees_by_allocation ( & allocation_id. to_string ( ) ) ;
110128
111- // The value for each receipt
112- let value = 100_000_000_000_000u128 ; // 0.0001 GRT
113-
114- // With trigger_value_divisor = 10,000 and max_amount_willing_to_lose_grt = 20
115- // trigger_value = 20 / 10,000 = 0.002 GRT
116- // We need to send at least 20 receipts to reach the trigger threshold
117- // Sending slightly more than required to ensure triggering
118- let num_receipts = 60 ;
119-
120129 println ! (
121130 "\n === Sending {} receipts to trigger RAV generation ===" ,
122- num_receipts
131+ NUM_RECEIPTS
123132 ) ;
124133 println ! (
125134 "Each receipt value: {} GRT" ,
126- value as f64 / 1_000_000_000_000_000f64
135+ MAX_RECEIPT_VALUE as f64 / GRT_BASE as f64
127136 ) ;
128137 println ! (
129138 "Total value to be sent: {} GRT" ,
130- ( value as f64 * num_receipts as f64 ) / 1_000_000_000_000_000f64
139+ ( MAX_RECEIPT_VALUE as f64 * NUM_RECEIPTS as f64 ) / GRT_BASE as f64
131140 ) ;
132141
133- // let mut trigger_value = 0.0;
134-
135- let trigger_value = initial_metrics. trigger_value_by_sender ( & sender_address. to_string ( ) ) ;
136-
137- if trigger_value > 0.0 {
138- println ! (
139- "With trigger value of {} GRT, we need to send at least {} receipts" ,
140- trigger_value,
141- ( trigger_value * 1_000_000_000_000_000f64 / value as f64 ) . ceil( )
142- ) ;
143- }
144-
145- // Send receipts in batches with a delay in between
146- // to ensure some receipts get outside the timestamp buffer
147- let batches = 3 ;
148- let receipts_per_batch = num_receipts / batches;
142+ let receipts_per_batch = NUM_RECEIPTS / BATCHES ;
149143 let mut total_successful = 0 ;
150144
151- for batch in 0 ..batches {
145+ for batch in 0 ..BATCHES {
152146 println ! (
153147 "Sending batch {} of {} ({} receipts per batch)" ,
154148 batch + 1 ,
155- batches ,
149+ BATCHES ,
156150 receipts_per_batch
157151 ) ;
158152
159153 for i in 0 ..receipts_per_batch {
160154 let receipt_index = batch * receipts_per_batch + i;
161- println ! ( "Sending receipt {} of {}" , receipt_index + 1 , num_receipts ) ;
155+ println ! ( "Sending receipt {} of {}" , receipt_index + 1 , NUM_RECEIPTS ) ;
162156
163157 // Create TAP receipt
164- let receipt = create_tap_receipt ( value, & allocation_id, TAP_ESCROW_CONTRACT , & wallet) ?;
158+ let receipt = create_tap_receipt (
159+ MAX_RECEIPT_VALUE ,
160+ & allocation_id,
161+ TAP_ESCROW_CONTRACT ,
162+ & wallet,
163+ ) ?;
165164 let receipt_json = serde_json:: to_string ( & receipt) . unwrap ( ) ;
166165
167- let query_response = http_client
166+ let response = http_client
168167 . post ( format ! ( "{}/api/subgraphs/id/{}" , GATEWAY_URL , SUBGRAPH_ID ) )
169168 . header ( "Content-Type" , "application/json" )
170169 . header ( "Authorization" , format ! ( "Bearer {}" , GATEWAY_API_KEY ) )
@@ -174,51 +173,47 @@ async fn tap_rav_test() -> Result<()> {
174173 } ) )
175174 . timeout ( Duration :: from_secs ( 10 ) )
176175 . send ( )
177- . await ;
178-
179- match query_response {
180- Ok ( response) => {
181- let status = response. status ( ) ;
182- if status. is_success ( ) {
183- total_successful += 1 ;
184- println ! ( "Receipt {} sent successfully" , receipt_index + 1 ) ;
185- } else {
186- println ! ( "Failed to send receipt {}: {}" , receipt_index + 1 , status) ;
187- let response_text = response. text ( ) . await ?;
188- println ! ( "Response: {}" , response_text) ;
189- }
190- }
191- Err ( e) => {
192- println ! ( "Error sending receipt {}: {}" , receipt_index + 1 , e) ;
193- return Err ( e. into ( ) ) ;
194- }
176+ . await ?;
177+
178+ let status = response. status ( ) ;
179+ if status. is_success ( ) {
180+ total_successful += 1 ;
181+ println ! ( "Receipt {} sent successfully" , receipt_index + 1 ) ;
182+ } else {
183+ println ! ( "Failed to send receipt {}: {}" , receipt_index + 1 , status) ;
184+ let response_text = response. text ( ) . await ?;
185+ println ! ( "Response: {}" , response_text) ;
195186 }
196187
197188 // Small delay between queries to avoid flooding
198- tokio:: time:: sleep ( Duration :: from_millis ( 200 ) ) . await ;
189+ tokio:: time:: sleep ( Duration :: from_millis ( 100 ) ) . await ;
199190 }
200191
201192 // After each batch, wait longer than the timestamp buffer
202- // (typically 60 seconds) to ensure receipts are outside buffer
203- if batch < batches - 1 {
193+ // (typically 30 seconds) to ensure receipts are outside buffer
194+ if batch < BATCHES - 1 {
204195 println ! (
205- "\n Batch {} complete. Waiting 65 seconds to exceed timestamp buffer..." ,
196+ "\n Batch {} complete. Waiting to exceed timestamp buffer..." ,
206197 batch + 1
207198 ) ;
208- tokio:: time:: sleep ( Duration :: from_secs ( 65 ) ) . await ;
199+ tokio:: time:: sleep ( Duration :: from_secs ( WAIT_TIME_BATCHES * 2 ) ) . await ;
209200 }
210201 }
211202
212203 println ! ( "\n === Summary ===" ) ;
213204 println ! (
214205 "Total receipts sent successfully: {}/{}" ,
215- total_successful, num_receipts
206+ total_successful, NUM_RECEIPTS
216207 ) ;
217208 println ! (
218209 "Total value sent: {} GRT" ,
219- ( value as f64 * total_successful as f64 ) / 1_000_000_000_000_000f64
210+ ( MAX_RECEIPT_VALUE as f64 * total_successful as f64 ) / GRT_BASE as f64
220211 ) ;
221212
213+ // Give the system enough time to process the receipts
214+ // ensuring the aged beyong timestamp buffer
215+ tokio:: time:: sleep ( Duration :: from_secs ( WAIT_TIME_BATCHES * 4 ) ) . await ;
216+
222217 // Check for RAV generation
223218 println ! ( "\n === Checking for RAV generation ===" ) ;
224219
0 commit comments