Skip to content

Commit 3311069

Browse files
docs(openspec): register ic-nns-delegation-reader crates after manager/reader split
Upstream PR #10699 split NNSDelegationReader/Builder and the certificate validation logic out of ic-nns-delegation-manager into a new ic-nns-delegation-reader crate (plus its ic-nns-delegation-reader-test-utils helper crate), and added proactive/reactive delegation fetching driven by consistency checks against the latest certified state.
1 parent 8b35dda commit 3311069

1 file changed

Lines changed: 52 additions & 12 deletions

File tree

openspec/specs/networking/nns-delegation-manager.md

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# NNS Delegation Manager Specification
22

3-
**Crate:** `ic-nns-delegation-manager`
4-
**Path:** `rs/http_endpoints/nns_delegation_manager/`
3+
**Crates:** `ic-nns-delegation-manager`, `ic-nns-delegation-reader`, `ic-nns-delegation-reader-test-utils`
4+
**Paths:** `rs/http_endpoints/nns_delegation_manager/`, `rs/http_endpoints/nns_delegation_reader/`
55

66
## Overview
77

8-
The NNS Delegation Manager is responsible for periodically fetching NNS delegation certificates from the NNS subnet and making them available to non-NNS subnets. These delegations allow non-NNS subnets to issue certified responses on behalf of the NNS. The module provides:
8+
Delegation fetching and delegation reading/building live in two separate crates:
99

10-
1. **NNSDelegationManager** -- A background task that periodically fetches delegations from the NNS subnet over TLS-secured HTTP connections.
11-
2. **NNSDelegationReader** -- A reader (backed by a `tokio::sync::watch` channel) that provides the latest delegation to callers with configurable canister range filtering.
12-
3. **NNSDelegationBuilder** -- A builder that parses raw NNS certificates, precomputes filtered variants, and constructs `CertificateDelegation` values on demand.
13-
4. **CanisterRangesFilter** -- An enum controlling which canister range data is included in the returned delegation.
14-
5. **DelegationManagerMetrics** -- Prometheus metrics tracking update counts, durations, delegation sizes, and errors.
10+
- **`ic-nns-delegation-manager`** (`nns_delegation_manager.rs`) -- A background task that fetches delegations from the NNS subnet over TLS-secured HTTP connections, both proactively (on a fixed interval) and reactively (whenever the currently held delegation no longer matches the replica's latest certified state), and publishes them via a `tokio::sync::watch` channel.
11+
- **`ic-nns-delegation-reader`** (`reader.rs`, `validation.rs`) -- Provides `NNSDelegationReader` (a reader wrapping the `watch::Receiver` side of the channel), `NNSDelegationBuilder` (parses raw NNS certificates, precomputes filtered variants, and constructs `CertificateDelegation` values on demand), `CanisterRangesFilter` (controls which canister range data is included in a *returned* delegation), and the certificate-tree validation/consistency-checking logic (`CanisterRangesCheck`, `is_tree_consistent_with`, `DelegationValidationError`, `DelegationVerificationError`) used to decide whether a held delegation is still consistent with the current certified state.
12+
- **`ic-nns-delegation-reader-test-utils`** -- Shared test helpers for constructing `NNSDelegationReader`/`NNSDelegationBuilder` instances in tests of downstream crates.
13+
14+
`DelegationManagerMetrics` (in the manager crate) tracks update counts, fetch durations, delegation sizes, fetch errors, state-comparison errors, held-back delegations, and reactive fetches.
1515

1616
## Requirements
1717

@@ -31,17 +31,53 @@ The delegation manager spawns a background task that periodically fetches the NN
3131
- **AND** `NNSDelegationReader::get_delegation` returns `None`
3232
- **AND** the reader is still marked as initialized (notifying waiters)
3333

34-
#### Scenario: Periodic refresh after interval
34+
#### Scenario: Proactive refresh after interval
3535
- **WHEN** the delegation manager has fetched an initial delegation
36-
- **THEN** it waits for `DELEGATION_UPDATE_INTERVAL` (5 minutes in production, 5 seconds in tests) before fetching a new delegation
37-
- **AND** a new fetch is not triggered before that interval elapses
38-
- **AND** after the interval, a fresh delegation replaces the previous one if different
36+
- **THEN** it waits for `DELEGATION_PROACTIVE_UPDATE_INTERVAL` (5 minutes in production, 5 seconds in tests) before proactively fetching a new delegation
37+
- **AND** a new proactive fetch is not triggered before that interval elapses
38+
- **AND** after the interval, a fresh delegation replaces the previous one if different, unless it is held back (see Reactive Fetching)
3939

4040
#### Scenario: Delegation is unchanged
4141
- **WHEN** the delegation manager fetches a new delegation identical to the current one
4242
- **THEN** the `watch::Sender` does not notify receivers of a change
4343
- **AND** the existing delegation remains available
4444

45+
### Requirement: Reactive Fetching on State Mismatch
46+
47+
In addition to the proactive interval, the manager reactively fetches a new delegation whenever the currently held delegation is no longer consistent with the replica's latest certified state (e.g. the state's routing table or subnet public keys have advanced past what the delegation reflects).
48+
49+
#### Scenario: Proactively fetched delegation held back
50+
- **WHEN** a proactively fetched delegation is checked against the latest certified state via `is_delegation_valid_with_respect_to_state`
51+
- **AND** the check returns `false` (the delegation is inconsistent with the state)
52+
- **THEN** the new delegation is held back (not published)
53+
- **AND** the `nns_delegation_manager_held_back_delegations_total` counter is incremented
54+
- **AND** the previously published delegation (if any) remains available to readers
55+
56+
#### Scenario: Reactive fetch triggered by stale delegation
57+
- **WHEN** the reactive interval (`DELEGATION_REACTIVE_UPDATE_INTERVAL`: 10 seconds in production, 1 second in tests) elapses
58+
- **AND** the currently held delegation is inconsistent with the latest certified state
59+
- **THEN** the manager fetches a new delegation immediately
60+
- **AND** the `nns_delegation_manager_reactive_fetches_total` counter is incremented
61+
62+
#### Scenario: Reactive fetch skipped when delegation still valid
63+
- **WHEN** the reactive interval elapses
64+
- **AND** the currently held delegation is still consistent with the latest certified state
65+
- **THEN** no fetch is performed on that tick
66+
67+
#### Scenario: No delegation yet, or on the NNS subnet
68+
- **WHEN** there is no currently held delegation (startup, or the replica is on the NNS subnet where delegations are always `None`)
69+
- **THEN** `is_delegation_valid_with_respect_to_state` returns `Some(true)`, so a proactive fetch is never held back in this case
70+
71+
#### Scenario: Certified state unavailable
72+
- **WHEN** the latest certified state cannot be obtained
73+
- **THEN** `is_delegation_valid_with_respect_to_state` returns `None`
74+
- **AND** the caller (`proactive_fetch`/`reactive_fetch`) treats this as "not provably invalid", so proactive fetches are accepted and reactive fetches are skipped
75+
76+
#### Scenario: State comparison error
77+
- **WHEN** comparing the held delegation's certificate tree against the certified state's routing table and subnet public keys fails
78+
- **THEN** a warning is logged
79+
- **AND** the `nns_delegation_manager_state_comparison_errors_total` counter is incremented
80+
4581
### Requirement: Delegation Validation
4682

4783
Fetched delegations are validated against the registry and the NNS root public key before being accepted.
@@ -199,6 +235,10 @@ The delegation manager exposes Prometheus metrics for observability.
199235
- `no_canister_ranges` (None-filtered delegation)
200236
- `flat_canister_ranges` (Flat-filtered delegation)
201237

238+
#### Scenario: Reactive-fetch and held-back-delegation metrics
239+
- **WHEN** the manager performs a reactive fetch or holds back a proactively fetched delegation
240+
- **THEN** `nns_delegation_manager_reactive_fetches_total` or `nns_delegation_manager_held_back_delegations_total` is incremented respectively, as described under Reactive Fetching on State Mismatch
241+
202242
### Requirement: Initialization Awaiting
203243

204244
The `NNSDelegationReader` supports waiting until the first delegation fetch completes.

0 commit comments

Comments
 (0)