Skip to content

feat: wire up HTTP metrics server from saorsa-core HealthServer#24

Closed
jacderida wants to merge 5 commits intoWithAutonomi:mainfrom
jacderida:feat-wire_up_metrics_server
Closed

feat: wire up HTTP metrics server from saorsa-core HealthServer#24
jacderida wants to merge 5 commits intoWithAutonomi:mainfrom
jacderida:feat-wire_up_metrics_server

Conversation

@jacderida
Copy link
Copy Markdown
Collaborator

@jacderida jacderida commented Mar 12, 2026

Summary

  • Move metrics_port from PaymentConfig to NodeConfig and add metrics_host field (IpAddr, default 127.0.0.1) with --metrics-host CLI arg
  • Add backward-compat migration: deprecated payment.metrics_port is detected, warned, and migrated automatically; top-level value takes precedence if both are set
  • Instantiate HealthManager in NodeBuilder::build() with 4 component health checkers (DHT, transport, peers, storage) wired to P2PNode data sources
  • Spawn HealthServer as a background task in RunningNode::run(), serving /health, /ready, /metrics, and /debug/vars on the configured address
  • Graceful shutdown via oneshot channel before P2P node teardown
  • Metrics server is disabled when port is set to 0

Test plan

  • cargo build --release succeeds
  • cargo test — all tests pass including new migrate_deprecated unit tests
  • cargo clippy --all-targets --all-features -- -D warnings clean
  • cargo fmt --all -- --check clean
  • Manual verification: started node in dev mode, confirmed all 4 endpoints respond correctly
    • /health returns JSON health status
    • /ready returns HTTP 200/503
    • /metrics returns Prometheus text format with component health gauges
    • /debug/vars returns JSON with system info, runtime stats, and per-component debug data

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 12, 2026 23:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires saorsa-core’s HealthServer/HealthManager into saorsa-node, exposing health, readiness, metrics, and debug endpoints over HTTP with configurable bind host/port.

Changes:

  • Moved metrics server configuration to NodeConfig (metrics_port) and added metrics_host (plus corresponding CLI/env wiring).
  • Added a HealthManager in NodeBuilder::build() and registered component health checkers backed by P2PNode data sources.
  • Spawned/shutdown the HealthServer lifecycle alongside the running node.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/node.rs Initializes health checkers and starts/stops the HTTP health/metrics server task based on metrics config.
src/config.rs Adds metrics_port/metrics_host to NodeConfig and removes metrics_port from PaymentConfig.
src/bin/saorsa-node/cli.rs Adds --metrics-host and maps CLI metrics settings into NodeConfig.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/node.rs Outdated
Comment thread src/config.rs Outdated
Comment thread src/config.rs Outdated
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 12, 2026

Greptile Summary

This PR wires up saorsa-core's HealthServer into the node lifecycle, exposing /health, /ready, /metrics, and /debug/vars endpoints. It also moves metrics_port from PaymentConfig to NodeConfig and introduces the new metrics_host field. The overall architecture is clean — the HealthManager is constructed in NodeBuilder::build(), checkers are registered against live P2PNode data sources, and the server is spawned with a oneshot-channel graceful shutdown before P2P teardown.

Two issues were found:

  • Silent config migration breakage (config/production.toml): metrics_port was moved out of PaymentConfig in Rust but the bundled production.toml template still places it under [payment]. Since PaymentConfig has no #[serde(deny_unknown_fields)], the value is silently discarded at runtime. Operators who have customised this field in their config file will silently lose that setting after upgrading without any error or warning.
  • Duplicate health-checker data sources (src/node.rs): The "network" and "peers" checkers are both wired to p2p.peer_count().await, supplying identical values to potentially different checker logic. If the two checker types apply equivalent thresholds internally, the resulting metrics will always agree, making the distinction between the two components invisible to operators.

Confidence Score: 3/5

  • Safe to merge for greenfield deployments; existing operators with a customised metrics port in their config file will silently lose that setting unless the production.toml issue is resolved first.
  • The core logic (HealthServer spawn/shutdown, config struct changes, CLI wiring) is correct and consistent. The score is reduced for the silent config migration breakage in production.toml — it is a concrete regression for any operator who has already deviated from the default metrics port — and for the ambiguous duplicate data source between the "network" and "peers" health checkers.
  • config/production.toml requires attention: metrics_port must be moved out of [payment] to the root level, and metrics_host should be added. src/node.rs warrants a second look at the NetworkHealthChecker vs PeerHealthChecker data sources.

Important Files Changed

Filename Overview
src/node.rs Wires up HealthManager with 5 component checkers and spawns HealthServer as a background task with graceful oneshot shutdown; two of the five checkers ("network" and "peers") use identical data sources (peer_count), which may produce redundant/indistinguishable health metrics.
src/config.rs Moves metrics_port from PaymentConfig to NodeConfig and adds metrics_host with correct serde defaults; struct change is correct, but the matching config template (production.toml) was not updated, leaving a silent misconfiguration trap for operators.
src/bin/saorsa-node/cli.rs Adds --metrics-host CLI arg and moves metrics_port/metrics_host assignment outside the PaymentConfig constructor; clean change with correct env-var bindings and default values.

Sequence Diagram

sequenceDiagram
    participant Main as saorsa-node main
    participant Builder as NodeBuilder::build()
    participant P2P as P2PNode (Arc)
    participant HM as HealthManager
    participant RN as RunningNode::run()
    participant HS as HealthServer (tokio task)

    Main->>Builder: NodeBuilder::new(config)
    Builder->>P2P: P2PNode::new(core_config)
    Builder->>HM: HealthManager::new(version)
    Builder->>HM: register_checker("dht", DhtHealthChecker)
    Builder->>HM: register_checker("network", NetworkHealthChecker)
    Builder->>HM: register_checker("transport", TransportHealthChecker)
    Builder->>HM: register_checker("peers", PeerHealthChecker)
    Builder->>HM: register_checker("storage", StorageHealthChecker)
    Builder-->>Main: RunningNode { health_manager, health_shutdown_tx: None, health_handle: None }

    Main->>RN: run()
    RN->>P2P: start()
    RN->>HS: HealthServer::new(health_manager, addr)
    Note right of HS: Spawned as background tokio task
    HS-->>RN: (health_server, shutdown_tx)
    RN->>HS: tokio::spawn(health_server.run())

    Note over HS: Serves /health /ready /metrics /debug/vars

    Main->>RN: shutdown signal (Ctrl-C / SIGTERM)
    RN->>HS: shutdown_tx.send(())
    RN->>HS: handle.await (graceful wait)
    RN->>P2P: shutdown()
Loading

Comments Outside Diff (1)

  1. config/production.toml, line 42-43 (link)

    metrics_port still under [payment] — silently ignored after this PR

    metrics_port has been moved from PaymentConfig to NodeConfig (root level) in src/config.rs, but config/production.toml was not updated. The value on line 43 now lives inside the [payment] TOML table, and since PaymentConfig no longer defines a metrics_port field (and has no #[serde(deny_unknown_fields)]), serde will silently discard it during deserialization.

    This means:

    • Any operator who customised metrics_port to a non-default value in their config file will silently lose that setting after upgrading, and the server will revert to port 9100.
    • The config template is now misleading — new operators following the template will incorrectly place metrics_port (and the new metrics_host) under [payment] where they have no effect.

    The fix is to move metrics_port out of the [payment] block and add metrics_host at the root level:

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: config/production.toml
    Line: 42-43
    
    Comment:
    **`metrics_port` still under `[payment]` — silently ignored after this PR**
    
    `metrics_port` has been moved from `PaymentConfig` to `NodeConfig` (root level) in `src/config.rs`, but `config/production.toml` was not updated. The value on line 43 now lives inside the `[payment]` TOML table, and since `PaymentConfig` no longer defines a `metrics_port` field (and has no `#[serde(deny_unknown_fields)]`), serde will silently discard it during deserialization.
    
    This means:
    - Any operator who customised `metrics_port` to a non-default value in their config file will silently lose that setting after upgrading, and the server will revert to port 9100.
    - The config template is now misleading — new operators following the template will incorrectly place `metrics_port` (and the new `metrics_host`) under `[payment]` where they have no effect.
    
    The fix is to move `metrics_port` out of the `[payment]` block and add `metrics_host` at the root level:
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: config/production.toml
Line: 42-43

Comment:
**`metrics_port` still under `[payment]` — silently ignored after this PR**

`metrics_port` has been moved from `PaymentConfig` to `NodeConfig` (root level) in `src/config.rs`, but `config/production.toml` was not updated. The value on line 43 now lives inside the `[payment]` TOML table, and since `PaymentConfig` no longer defines a `metrics_port` field (and has no `#[serde(deny_unknown_fields)]`), serde will silently discard it during deserialization.

This means:
- Any operator who customised `metrics_port` to a non-default value in their config file will silently lose that setting after upgrading, and the server will revert to port 9100.
- The config template is now misleading — new operators following the template will incorrectly place `metrics_port` (and the new `metrics_host`) under `[payment]` where they have no effect.

The fix is to move `metrics_port` out of the `[payment]` block and add `metrics_host` at the root level:

```suggestion
# Prometheus metrics / health-server address (0 to disable)
metrics_port = 9100
metrics_host = "0.0.0.0"

```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/node.rs
Line: 173-207

Comment:
**`"network"` and `"peers"` health checkers use identical data sources**

Both the `NetworkHealthChecker` (registered as `"network"`) and the `PeerHealthChecker` (registered as `"peers"`) are given closures that return exactly the same value — `p2p.peer_count().await`. If these two checker types interpret the supplied value differently (e.g., one checking liveness vs. the other reporting a gauge), the duplication may be harmless. However, if they apply equivalent thresholds, the `/metrics` and `/health` endpoints will expose two separate components that are always in lockstep: any change that makes one healthy/unhealthy will do the same to the other, making the distinction meaningless to operators.

Consider whether `"network"` should instead reflect a different data source such as network reachability or transport status (e.g., `p2p.is_running()`), or whether one of the two checkers should be removed entirely if they genuinely duplicate the same metric.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 508e8e5

Comment thread src/node.rs Outdated
@jacderida jacderida force-pushed the feat-wire_up_metrics_server branch from 508e8e5 to cab5dc2 Compare March 13, 2026 00:07
Copilot AI review requested due to automatic review settings March 13, 2026 00:12
@jacderida jacderida force-pushed the feat-wire_up_metrics_server branch from cab5dc2 to 5b5cb0e Compare March 13, 2026 00:12
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Wires saorsa-core’s HTTP health/metrics server into saorsa-node, adds configuration for metrics bind host/port, and hooks server lifecycle into node startup/shutdown.

Changes:

  • Move metrics configuration to NodeConfig (add metrics_host, migrate deprecated payment.metrics_port).
  • Add HealthManager initialization with component health checkers and spawn HealthServer as a background task.
  • Extend CLI with --metrics-host and plumb metrics settings into runtime config.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/node.rs Builds a HealthManager, registers health checkers, spawns/shuts down HealthServer based on configured metrics address.
src/config.rs Adds metrics_port/metrics_host to NodeConfig and migrates deprecated payment.metrics_port during config file load.
src/bin/saorsa-node/cli.rs Adds --metrics-host and maps CLI metrics settings onto NodeConfig.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/node.rs
Comment thread src/config.rs
Comment thread src/config.rs Outdated
Connect the existing metrics_port config to saorsa-core's HealthServer,
exposing /health, /ready, /metrics, and /debug/vars endpoints.

- Move metrics_port from PaymentConfig to NodeConfig (semantically correct)
- Add metrics_host field to NodeConfig and --metrics-host CLI arg
- Instantiate HealthManager with 5 component checkers (DHT, network,
  transport, peers, storage) using P2PNode data sources
- Spawn HealthServer as background task with graceful shutdown
- Disable metrics server when port is 0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jacderida jacderida force-pushed the feat-wire_up_metrics_server branch from 5b5cb0e to 790a3c4 Compare March 13, 2026 00:19
Build a complete metrics pipeline with two data paths:
- Event-driven: MetricsAggregator processes MetricEvents from saorsa-core
  into atomic counters and sliding windows (lookups, DHT ops, auth,
  streams, storage, peer connections)
- Pull-based: SnapshotCollector reads state snapshots from saorsa-core
  accessors on each /metrics scrape (DHT health, security, trust,
  placement, transport, EigenTrust scores)

Replace saorsa-core's HealthServer with our own Axum server that combines
health component metrics with ~80 domain metric families in Prometheus
text exposition format on /metrics.

Update saorsa-core dependency to git branch feat-metrics_event_channel
which provides the MetricEvent channel and accessor methods.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 15, 2026 00:00
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Wires up an HTTP health/metrics server for saorsa-node using saorsa-core health data plus new node-side Prometheus metrics, and updates configuration/CLI to support metrics_host + top-level metrics_port with backward-compatible migration.

Changes:

  • Add an Axum-based background HTTP server exposing /health, /ready, /metrics, and /debug/vars, with graceful shutdown.
  • Introduce a metrics module (event-driven aggregator + pull-based snapshot collector + Prometheus formatter) and hook it into node runtime.
  • Move metrics_port to NodeConfig, add metrics_host, and implement deprecated config migration; update bootstrap peer conversion to MultiAddr.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
Cargo.toml Switches saorsa-core dependency source and adds axum for the HTTP server.
src/config.rs Adds metrics_port/metrics_host to NodeConfig, deprecates payment.metrics_port, and migrates legacy config.
src/bin/saorsa-node/cli.rs Adds --metrics-host and maps CLI metrics settings into NodeConfig.
src/node.rs Builds health manager + metrics components; spawns/shuts down Axum server; subscribes to metric events.
src/metrics/mod.rs Exposes new metrics submodules publicly.
src/metrics/aggregator.rs Implements event-driven counters/sliding windows for metrics.
src/metrics/snapshot.rs Implements pull-based snapshot collection from saorsa-core accessors/collectors.
src/metrics/prometheus.rs Formats aggregator + snapshot into Prometheus text exposition.
src/devnet.rs Updates bootstrap peers conversion to MultiAddr.
src/bin/saorsa-cli/main.rs Updates bootstrap peers conversion to MultiAddr.
src/lib.rs Exports the new metrics module.
Comments suppressed due to low confidence (1)

src/node.rs:848

  • start_protocol_routing() returns early when ant_protocol is None, which also disables the P2P event subscription used to update MetricsAggregator peer connection gauges. If metrics should work when storage is disabled, consider splitting peer connect/disconnect tracking into a separate task that always subscribes to P2PEvents (independent of protocol routing).
    fn start_protocol_routing(&mut self) {
        let protocol = match self.ant_protocol {
            Some(ref p) => Arc::clone(p),
            None => return,
        };

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/metrics/prometheus.rs
Comment on lines +756 to +760
// Already emitted distribution above from cached scores if available;
// only emit the collector's distribution if we didn't have live scores.
if trust_scores.is_none() {
writeln!(
out,
Comment thread src/config.rs
Comment on lines +336 to +340
pub fn migrate_deprecated(&mut self) {
if let Some(port) = self.payment.metrics_port.take() {
if self.metrics_port == default_metrics_port() {
tracing::warn!(
"Deprecated: `payment.metrics_port` is now a top-level field `metrics_port`. \
Comment thread src/node.rs
Comment on lines +812 to +816
let app = Router::new()
.route("/health", get(health_handler))
.route("/ready", get(ready_handler))
.route("/metrics", get(metrics_handler))
.route("/debug/vars", get(debug_handler))
Comment thread Cargo.toml Outdated
[dependencies]
# Core (provides EVERYTHING: networking, DHT, security, trust, storage)
saorsa-core = "0.14.1"
saorsa-core = { git = "https://github.com/jacderida/saorsa-core", branch = "feat-metrics_event_channel" }
Comment thread src/node.rs
Comment on lines +477 to +484
/// Build the snapshot collector, wiring in live saorsa-core components.
fn build_snapshot_collector(p2p_node: &Arc<P2PNode>) -> SnapshotCollector {
// DhtMetricsCollector, TrustMetricsCollector, PlacementMetricsCollector
// are standalone instances — they serve as the canonical source for
// snapshot metrics and will be populated as the DHT layer reports data.
let dht_health = Arc::new(DhtMetricsCollector::new());
let trust = Arc::new(TrustMetricsCollector::new());
let placement = Arc::new(PlacementMetricsCollector::new());
Comment thread src/node.rs
Comment on lines +962 to +966
Err(e) => (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
[(header::CONTENT_TYPE, "application/json")],
format!("{{\"error\":\"{e}\"}}"),
),
Comment thread src/node.rs
Comment on lines +984 to +988
Err(e) => (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
[(header::CONTENT_TYPE, "application/json")],
format!("{{\"error\":\"{e}\"}}"),
),
Comment thread src/node.rs
Comment on lines +1037 to +1041
Err(e) => (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
[(header::CONTENT_TYPE, "application/json")],
format!("{{\"error\":\"{e}\"}}"),
),
jacderida and others added 2 commits March 15, 2026 21:28
Extend the metrics pipeline with ~25 new metric families:

- Handshake latency percentiles (PQ key exchange timing)
- Separate DHT put/get latency percentiles (p50/p95/p99)
- Operations per second (derived from total ops / uptime)
- Extended transport stats: connection success/failure counts,
  byte counters, NAT traversal success rate, connection pool size
- Connection failure breakdown by reason (labeled counter)
- Replication timing: repair cycle duration, keys repaired,
  bytes transferred, grace period expiry tracking

Update saorsa-core dependency to feat-metrics_phase2 branch which
provides new MetricEvent variants (ConnectionEstablished,
ConnectionFailed, HandshakeCompleted, ReplicationStarted,
ReplicationCompleted, GracePeriodExpired) and extended TransportStats.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move start_metric_event_loop() before p2p_node.start() so that
connection and handshake MetricEvents emitted during startup are
captured by the aggregator instead of being lost.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 16, 2026 12:29
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires up an HTTP health/metrics server for saorsa-node, adds a metrics aggregation pipeline (event-driven + pull-based snapshots), and updates configuration/CLI to support a top-level metrics bind address/port with backward-compatible migration.

Changes:

  • Add an Axum-based HTTP server serving /health, /ready, /metrics, and /debug/vars, with graceful shutdown.
  • Introduce a new metrics module: MetricsAggregator (event-driven), SnapshotCollector (pull-based), and PrometheusFormatter (Prometheus text output).
  • Move metrics_port to NodeConfig, add metrics_host, and implement deprecated config migration from payment.metrics_port.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/node.rs Initializes health/metrics components, spawns Axum server, drains metric events, and tracks peer connect/disconnect in metrics.
src/config.rs Adds NodeConfig.metrics_port/metrics_host, deprecates payment.metrics_port, and migrates old config fields on load.
src/bin/saorsa-node/cli.rs Adds --metrics-host and wires CLI metrics settings to NodeConfig.
src/bin/saorsa-cli/main.rs Updates bootstrap peers conversion to MultiAddr.
src/devnet.rs Updates bootstrap peers conversion to MultiAddr.
src/lib.rs Exposes the new metrics module.
src/metrics/mod.rs Declares and re-exports the new metrics components.
src/metrics/aggregator.rs Implements event-driven counters/sliding windows over saorsa-core MetricEvents.
src/metrics/snapshot.rs Implements pull-based snapshot collection from saorsa-core accessors.
src/metrics/prometheus.rs Formats aggregated + snapshot metrics into Prometheus text exposition output (with tests).
Cargo.toml Adds axum and switches saorsa-core to a git branch dependency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/config.rs
Comment on lines +331 to +352
/// Migrate deprecated config fields, logging warnings for any that are found.
///
/// If both the deprecated `payment.metrics_port` and the new top-level
/// `metrics_port` are set, the top-level value takes precedence and the
/// deprecated value is ignored with a warning.
pub fn migrate_deprecated(&mut self) {
if let Some(port) = self.payment.metrics_port.take() {
if self.metrics_port == default_metrics_port() {
tracing::warn!(
"Deprecated: `payment.metrics_port` is now a top-level field `metrics_port`. \
Migrating value {port} automatically — please update your config file."
);
self.metrics_port = port;
} else {
tracing::warn!(
"Deprecated `payment.metrics_port = {port}` ignored — \
using top-level `metrics_port = {}`. \
Please remove `payment.metrics_port` from your config file.",
self.metrics_port
);
}
}
Comment thread src/node.rs
Comment on lines +812 to +838
self.health_handle = Some(tokio::spawn(async move {
let app = Router::new()
.route("/health", get(health_handler))
.route("/ready", get(ready_handler))
.route("/metrics", get(metrics_handler))
.route("/debug/vars", get(debug_handler))
.with_state(shared_state);

let listener = match TcpListener::bind(metrics_addr).await {
Ok(l) => l,
Err(e) => {
error!("Failed to bind metrics server on {metrics_addr}: {e}");
return;
}
};

let server = axum::serve(listener, app).with_graceful_shutdown(async {
let _ = shutdown_rx.await;
});

if let Err(e) = server.await {
error!("Metrics server error: {e}");
}
}));

info!("Metrics server listening on {metrics_addr}");
}
Comment thread src/node.rs
Comment on lines +1038 to +1042
Err(e) => (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
[(header::CONTENT_TYPE, "application/json")],
format!("{{\"error\":\"{e}\"}}"),
),
Comment thread src/node.rs
Comment on lines +477 to +499
/// Build the snapshot collector, wiring in live saorsa-core components.
fn build_snapshot_collector(p2p_node: &Arc<P2PNode>) -> SnapshotCollector {
// DhtMetricsCollector, TrustMetricsCollector, PlacementMetricsCollector
// are standalone instances — they serve as the canonical source for
// snapshot metrics and will be populated as the DHT layer reports data.
let dht_health = Arc::new(DhtMetricsCollector::new());
let trust = Arc::new(TrustMetricsCollector::new());
let placement = Arc::new(PlacementMetricsCollector::new());

// SecurityMetricsCollector: standalone instance that will be populated
// as security events are observed by the DHT layer.
let security = Arc::new(saorsa_core::dht::metrics::SecurityMetricsCollector::new());

let eigentrust = p2p_node.trust_engine();

SnapshotCollector::new(
dht_health,
security,
trust,
placement,
Arc::clone(p2p_node),
eigentrust,
)
Comment thread Cargo.toml
[dependencies]
# Core (provides EVERYTHING: networking, DHT, security, trust, storage)
saorsa-core = "0.14.1"
saorsa-core = { git = "https://github.com/jacderida/saorsa-core", branch = "feat-metrics_phase2" }
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jacderida
Copy link
Copy Markdown
Collaborator Author

This will be replaced with another PR.

@jacderida jacderida closed this Mar 16, 2026
mickvandijke added a commit that referenced this pull request Apr 1, 2026
Complete the Section 18 test matrix with the remaining scenarios:

- #3: Fresh replication stores chunk + updates PaidForList on remote nodes
- #9: Fetch retry rotates to alternate source
- #10: Fetch retry exhaustion with single source
- #11: Repeated ApplicationFailure events decrease peer trust score
- #12: Bootstrap node discovers keys stored on multiple peers
- #14: Hint construction covers all locally stored keys
- #15: Data and PaidForList survive node shutdown (partition)
- #17: Neighbor sync request returns valid response (admission test)
- #21: Paid-list majority confirmed from multiple peers via verification
- #24: PaidNotify propagates paid-list entries after fresh replication
- #25: Paid-list convergence verified via majority peer queries
- #44: PaidForList persists across restart (cold-start recovery)
- #45: PaidForList lost in fresh directory (unrecoverable scenario)

All 56 Section 18 scenarios now have test coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mickvandijke added a commit that referenced this pull request Apr 1, 2026
Complete the Section 18 test matrix with the remaining scenarios:

- #3: Fresh replication stores chunk + updates PaidForList on remote nodes
- #9: Fetch retry rotates to alternate source
- #10: Fetch retry exhaustion with single source
- #11: Repeated ApplicationFailure events decrease peer trust score
- #12: Bootstrap node discovers keys stored on multiple peers
- #14: Hint construction covers all locally stored keys
- #15: Data and PaidForList survive node shutdown (partition)
- #17: Neighbor sync request returns valid response (admission test)
- #21: Paid-list majority confirmed from multiple peers via verification
- #24: PaidNotify propagates paid-list entries after fresh replication
- #25: Paid-list convergence verified via majority peer queries
- #44: PaidForList persists across restart (cold-start recovery)
- #45: PaidForList lost in fresh directory (unrecoverable scenario)

All 56 Section 18 scenarios now have test coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants