Skip to content

Reproduce Update Propagation Issues with Peer Blocking Tests #1592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1acc3c9
Fix run_app.rs parsing errors and add blocked peers test
devin-ai-integration[bot] May 12, 2025
4a8c53e
Add simplified blocked peers test
devin-ai-integration[bot] May 12, 2025
740617b
Add optimized blocked peers test with reduced timeouts
devin-ai-integration[bot] May 12, 2025
4674318
Add debug test with enhanced logging for subscription operations
devin-ai-integration[bot] May 12, 2025
30efa2b
Add reliable and debug tests for peer blocking functionality
devin-ai-integration[bot] May 12, 2025
829c0cd
Apply cargo fmt to test files
devin-ai-integration[bot] May 12, 2025
7ed0434
Add solution test with combined chronological logging
devin-ai-integration[bot] May 12, 2025
2d91214
Fix API usage in solution test with combined chronological logging
devin-ai-integration[bot] May 12, 2025
9009e2e
Fix API compatibility issues in solution test
devin-ai-integration[bot] May 12, 2025
0058343
Fix Parameters initialization in solution test
devin-ai-integration[bot] May 12, 2025
e45e666
Fix pattern matching issues in solution test
devin-ai-integration[bot] May 12, 2025
33bc142
Fix pattern matching and duplicate constants in solution test
devin-ai-integration[bot] May 12, 2025
4a8aa1e
Fix Send-safety issues with logger functions
devin-ai-integration[bot] May 12, 2025
b5439e5
Fix lifetime and ownership issues in solution test
devin-ai-integration[bot] May 12, 2025
c976b6e
Fix syntax error in solution test
devin-ai-integration[bot] May 12, 2025
0f881bb
Fix Send-safety issues by using LocalSet and spawn_local
devin-ai-integration[bot] May 12, 2025
0c39729
Fix update serialization format to use Delta instead of State
devin-ai-integration[bot] May 12, 2025
5f43684
Implement robust retry mechanism with progressive delays and detailed…
devin-ai-integration[bot] May 12, 2025
a17ffaa
Enhance logging with chronological trace of update operations
devin-ai-integration[bot] May 12, 2025
1a19dc5
Format code with cargo fmt to pass CI
devin-ai-integration[bot] May 12, 2025
4f21baa
Update Cargo.lock files
devin-ai-integration[bot] May 12, 2025
e744529
Revert subscription changes in run_app.rs to maintain original behavior
devin-ai-integration[bot] May 13, 2025
2e60157
Add summaries to test files and create common module for shared code
devin-ai-integration[bot] May 13, 2025
9f459b7
Fix formatting issues in PR #1592 test files
devin-ai-integration[bot] May 13, 2025
4e436a5
Update Ping struct to use Vec<DateTime<Utc>> for consistent serializa…
devin-ai-integration[bot] May 13, 2025
3d5dfef
Update ping_client.rs to handle Vec<DateTime<Utc>> format
devin-ai-integration[bot] May 13, 2025
3acb3de
Fix update propagation in run_app_blocked_peers_solution.rs by increa…
devin-ai-integration[bot] May 13, 2025
eedd915
Fix update propagation in run_app_blocked_peers_solution.rs by retrie…
devin-ai-integration[bot] May 13, 2025
97373c8
Fix wait_for_put_response to handle UpdateResponse
devin-ai-integration[bot] May 13, 2025
019098f
Fix UpdateResponse pattern to include summary field
devin-ai-integration[bot] May 13, 2025
8efb50d
Fix formatting issues in ping_client.rs
devin-ai-integration[bot] May 13, 2025
7c44451
Fix formatting issues in PR #1592
devin-ai-integration[bot] May 13, 2025
bd3c3f6
Add module-level documentation to test files and import common module
devin-ai-integration[bot] May 13, 2025
2e278d8
tests: fix devin mess
iduartgomez May 15, 2025
abbd177
fixes
iduartgomez May 16, 2025
07a7dc3
ignore tests that need fixing
iduartgomez May 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/freenet-ping/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/freenet-ping/app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ tokio = { version = "1.0", features = ["full"] }
tokio-tungstenite = "0.26.1"
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
humantime = "2.2.0"

[dev-dependencies]
freenet = { path = "../../../crates/core" }
Expand Down
45 changes: 37 additions & 8 deletions apps/freenet-ping/app/src/ping_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ impl PingStats {
self.sent_count += 1;
}

pub fn record_received(&mut self, peer: String, time: DateTime<Utc>) {
pub fn record_received(&mut self, peer: String, time: Vec<DateTime<Utc>>) {
*self.received_counts.entry(peer.clone()).or_insert(0) += 1;
self.last_updates.insert(peer, time);
if let Some(latest) = time.first() {
self.last_updates.insert(peer, *latest);
}
}
}

Expand All @@ -54,6 +56,21 @@ pub async fn wait_for_put_response(
return Err("unexpected key".into());
}
}
Ok(Ok(HostResponse::ContractResponse(ContractResponse::UpdateResponse {
key,
summary,
}))) => {
if &key == expected_key {
tracing::info!(
"Received update response for key: {}, summary: {:?}",
key,
summary
);
return Ok(key);
} else {
return Err("unexpected key".into());
}
}
Ok(Ok(other)) => {
tracing::warn!("Unexpected response while waiting for put: {}", other);
}
Expand Down Expand Up @@ -85,9 +102,17 @@ pub async fn wait_for_get_response(
return Err("unexpected key".into());
}

let old_ping = serde_json::from_slice::<Ping>(&state)?;
tracing::info!(num_entries = %old_ping.len(), "old state fetched successfully!");
return Ok(old_ping);
match serde_json::from_slice::<Ping>(&state) {
Ok(ping) => {
tracing::info!(num_entries = %ping.len(), "old state fetched successfully!");
return Ok(ping);
}
Err(e) => {
tracing::error!("Failed to deserialize Ping: {}", e);
tracing::error!("Raw state data: {:?}", String::from_utf8_lossy(&state));
return Err(Box::new(e));
}
};
}
Ok(Ok(other)) => {
tracing::warn!("Unexpected response while waiting for get: {}", other);
Expand Down Expand Up @@ -218,9 +243,13 @@ pub async fn run_ping_client(

let updates = local_state.merge(new_ping, parameters.ttl);

for (name, update_time) in updates.into_iter() {
tracing::info!("{} last updated at {}", name, update_time);
stats.record_received(name, update_time);
for (name, timestamps) in updates.into_iter() {
if !timestamps.is_empty() {
if let Some(last) = timestamps.first() {
tracing::info!("{} last updated at {}", name, last);
}
stats.record_received(name, timestamps);
}
}
Ok(())
};
Expand Down
97 changes: 97 additions & 0 deletions apps/freenet-ping/app/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Freenet Ping App Test Suite

This directory contains integration tests for the Freenet Ping application, focusing on contract state propagation in various network topologies and connectivity scenarios.

## Test Organization

| Test File | Scenario |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `run_app.rs` | **Multi-node and client functionality tests.** Contains tests for basic multi-node functionality and client application. |
| `run_app_blocked_peers.rs` | **Parameterized blocked peers tests.** A unified implementation of blocked peers tests with different functional behaviors. |
| `run_app_partially_connected_network.rs` | **Partial connectivity test.** Large-scale network test with controlled connectivity between nodes. |

## Parameterized "Blocked Peers" Tests

The `run_app_blocked_peers.rs` file contains a parameterized implementation that consolidates blocked peers testing into a single file. The file provides the following test variants:

| Test Function | Description |
| ---------------------------------- | -------------------------------------------------------------------------------- |
| `test_ping_blocked_peers` | **Baseline implementation.** Standard test for indirect propagation via gateway. |
| `test_ping_blocked_peers_simple` | **Minimal variant.** One round of updates, simplified verification. |
| `test_ping_blocked_peers_solution` | **Reference implementation.** Best practices for indirect propagation. |

## Test Structure

### In `run_app.rs`

| Test Function | Description |
| ---------------------------- | -------------------------------------------------------------- |
| `test_ping_multi_node` | Tests basic contract propagation in a fully-connected network. |
| `test_ping_application_loop` | Tests the complete client application running over time. |

### In `run_app_partially_connected_network.rs`

| Test Function | Description |
| --------------------------------------- | ---------------------------------------------------------------- |
| `test_ping_partially_connected_network` | Tests propagation in a larger network with partial connectivity. |

### Multi-node vs. Partially Connected Tests

- **Multi-node test**: Uses a fully connected network where all nodes can directly communicate with each other
- **Partially connected test**: Creates a larger network with controlled connectivity ratio (50%) between nodes, testing how updates propagate in a more realistic, constrained network topology

## The "Blocked Peers" Test Scenario

The "blocked peers" tests verify that contract state updates can propagate correctly even when direct peer-to-peer connections are blocked:

1. Two regular nodes (Node1 and Node2) are configured to block each other's network addresses
2. A gateway node is connected to both regular nodes
3. All nodes subscribe to the ping contract
4. Each node sends state updates with its own unique identifier
5. Updates must route through the gateway to reach nodes with blocked direct connections
6. The test verifies that all nodes eventually have the same consistent state

This tests Freenet's ability to maintain contract state consistency even when the network topology prevents direct communication between some peers.

## Common Test Infrastructure

The `common/mod.rs` module provides shared infrastructure for tests, including:

- Node and gateway configuration
- Contract deployment helpers
- State comparison utilities
- WebSocket connection management
- State update and verification functions

## Parameterized Testing Approach

The unified approach in `run_app_blocked_peers.rs` offers several advantages:

- **Reduced duplication**: Core test logic is defined once and reused
- **Consistent methodology**: All variants follow the same testing pattern
- **Functional variants**: Tests focus on different functional behaviors (baseline, simple, solution)
- **Easier maintenance**: Changes to the core test logic only need to be made in one place
- **Focused test coverage**: Each variant tests a specific functional aspect of the system

## Running the Tests

Run all tests with:

```bash
cd apps/freenet-ping
cargo test
```

Run a specific blocked peers test variant:

```bash
cargo test test_ping_blocked_peers_simple
```

Run the large-scale partial connectivity network test:

```bash
cargo test -p freenet-ping-app --test run_app_partially_connected_network
```

---
Loading