Skip to content

Commit 0bfaa0a

Browse files
committed
chore(test): Reduce timestamp_buffer_secs window
chore(testing): Some enhacements and wait for the system to process receipts fix(testing): Adjust some settings to ensure RAV request fix(testing): Generate enough receipts to ensure RAV generation chore(testing): Give enough time for indexer-service and tap-agent to start before deploying gateway
1 parent b11e926 commit 0bfaa0a

File tree

6 files changed

+96
-97
lines changed

6 files changed

+96
-97
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,6 @@ fmt:
4545
rav_tests:
4646
# First fund the escrow account
4747
cd rav_e2e && ./fund_escrow.sh
48+
# Give time for the funding to take place
49+
sleep 30
4850
cd rav_e2e && cargo run

contrib/indexer-service/config.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ max_amount_willing_to_lose_grt = 1000
3333

3434
[tap.rav_request]
3535
# Set a lower timestamp buffer threshold
36-
# for testing purposes
37-
timestamp_buffer_secs = 60
36+
timestamp_buffer_secs = 30
3837
# The trigger value divisor is used to calculate the trigger value for the RAV request.
3938
# using the formula:
4039
# trigger_value = max_amount_willing_to_lose_grt / trigger_value_divisor

contrib/tap-agent/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ max_amount_willing_to_lose_grt = 1000
3434
[tap.rav_request]
3535
# Set a lower timestamp buffer threshold
3636
# for testing purposes
37-
timestamp_buffer_secs = 60
37+
timestamp_buffer_secs = 30
3838
# The trigger value divisor is used to calculate the trigger value for the RAV request.
3939
# using the formula:
4040
# trigger_value = max_amount_willing_to_lose_grt / trigger_value_divisor

rav_e2e/fund_escrow.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SENDER_ADDRESS="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
1010
# Sender key is the private key use to sign receipts
1111
# This is defined as ACCOUNT0_SECRET in local-network/.env
1212
SENDER_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
13-
AMOUNT="5000000000000000000" # 1 GRT
13+
AMOUNT="10000000000000000000"
1414

1515
echo "Funding escrow for sender: $SENDER_ADDRESS"
1616

rav_e2e/src/main.rs

Lines changed: 88 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,38 @@ mod receipt;
1818
use metrics::MetricsChecker;
1919
use 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
2524
const GATEWAY_URL: &str = "http://localhost:7700";
2625
const SUBGRAPH_ID: &str = "BFr2mx7FgkJ36Y6pE5BiXs1KmNUmVDCnL82KUSdcLW1g";
2726
const TAP_ESCROW_CONTRACT: &str = "0x0355B7B8cb128fA5692729Ab3AAa199C1753f726";
2827
const GATEWAY_API_KEY: &str = "deadbeefdeadbeefdeadbeefdeadbeef";
29-
const RECEIVER_ADDRESS: &str = "0xf4EF6650E48d099a4972ea5B414daB86e1998Bd3";
28+
// const RECEIVER_ADDRESS: &str = "0xf4EF6650E48d099a4972ea5B414daB86e1998Bd3";
3029
const 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]
3354
async 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-
"\nBatch {} complete. Waiting 65 seconds to exceed timestamp buffer...",
196+
"\nBatch {} 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

setup-test-network.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ fi
166166
docker compose -f docker-compose.yml -f docker-compose.override.yml up --build -d
167167
rm docker-compose.override.yml
168168

169+
timeout 30 bash -c 'until docker ps | grep indexer | grep -q healthy; do sleep 5; done'
170+
timeout 30 bash -c 'until docker ps | grep tap-agent | grep -q healthy; do sleep 5; done'
171+
169172
# GATEWAY DEPLOYMENT NOTE:
170173
# We're deploying gateway directly with "docker run" instead of docker-compose
171174
# because the local-network's compose file has a dependency on "indexer-service",

0 commit comments

Comments
 (0)