mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
Merge maint into master, carrying the dedup-cache test fix and the rekey comment correction
The two rekey comments conflicted: master no longer limits the rekey snapshot to healthy peers, so the corrected wording is kept without that qualifier.
This commit is contained in:
@@ -126,13 +126,14 @@ impl Node {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The shell snapshots each peer's rekey ages/flags (every clock
|
// The shell snapshots each peer's rekey ages/flags (every clock
|
||||||
// read resolved here); the core decides cutover/drain/trigger with no
|
// read resolved here); the core decides cutover, drain, retirement and
|
||||||
// clock, phase-grouped to preserve the pre-refactor execution order.
|
// trigger with no clock and returns the actions phase-grouped: all
|
||||||
// The batch `poll_rekey` + snapshots STAY SHELL-SIDE and BYTE-UNCHANGED:
|
// Cutover, then all Drain, then all RetirePending, then all
|
||||||
// the cross-peer phase-grouping (all Cutover → all Drain →
|
// InitiateRekey. That grouping fixes the shared `index_allocator`
|
||||||
// all InitiateRekey) governs the shared `index_allocator` free-then-alloc
|
// free-then-allocate sequence that appears on the wire, so the batch
|
||||||
// SEQUENCE that appears on the wire. The machine must NOT re-poll; it
|
// `poll_rekey` call stays here in the shell. The machine must NOT
|
||||||
// CONSUMES each decided `ConnAction` in the same order the batch returned.
|
// re-poll; it CONSUMES each decided `ConnAction` in the order the batch
|
||||||
|
// returned.
|
||||||
let snapshots = self.rekey_peers();
|
let snapshots = self.rekey_peers();
|
||||||
for action in self.fmp.poll_rekey(snapshots, &cfg) {
|
for action in self.fmp.poll_rekey(snapshots, &cfg) {
|
||||||
match action {
|
match action {
|
||||||
|
|||||||
@@ -670,12 +670,25 @@ fn register_peers(node: &mut Node, count: usize) -> Vec<crate::NodeAddr> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A node whose dedup entries cannot age out while a flood test runs.
|
||||||
|
///
|
||||||
|
/// The handler stamps each entry with the wall clock and purges entries older
|
||||||
|
/// than `recent_expiry_secs` (10 s by default) on every arrival. The flood
|
||||||
|
/// tests below measure capacity, not expiry, and a 4096-request flood on a
|
||||||
|
/// loaded host can take longer than the default, so the earliest entries
|
||||||
|
/// would be purged before the test reads the cache.
|
||||||
|
fn unexpiring_node() -> Node {
|
||||||
|
let mut config = Config::new();
|
||||||
|
config.node.lookup.recent_expiry_secs = 86_400;
|
||||||
|
make_node_with(config)
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_a_full_dedup_cache_admits_the_new_request_by_evicting_the_oldest() {
|
async fn test_a_full_dedup_cache_admits_the_new_request_by_evicting_the_oldest() {
|
||||||
// A full cache used to drop the arriving request, which let one peer
|
// A full cache used to drop the arriving request, which let one peer
|
||||||
// spend 4096 fresh request_ids and stop the node forwarding anyone
|
// spend 4096 fresh request_ids and stop the node forwarding anyone
|
||||||
// else's lookups until the entries aged out.
|
// else's lookups until the entries aged out.
|
||||||
let mut node = make_node();
|
let mut node = unexpiring_node();
|
||||||
let from = make_node_addr(0xAA);
|
let from = make_node_addr(0xAA);
|
||||||
|
|
||||||
flood_requests(&mut node, &from, 1, MAX_RECENT_LOOKUP_REQUESTS as u64).await;
|
flood_requests(&mut node, &from, 1, MAX_RECENT_LOOKUP_REQUESTS as u64).await;
|
||||||
@@ -746,11 +759,16 @@ async fn test_a_node_whose_dedup_cache_is_flooded_still_answers_a_lookup_for_its
|
|||||||
// The availability claim. Filling the cache used to make the node
|
// The availability claim. Filling the cache used to make the node
|
||||||
// unresolvable, because the cache-full drop sat ahead of the check for
|
// unresolvable, because the cache-full drop sat ahead of the check for
|
||||||
// whether the request names us.
|
// whether the request names us.
|
||||||
let mut node = make_node();
|
let mut node = unexpiring_node();
|
||||||
let flooder = make_node_addr(0xAA);
|
let flooder = make_node_addr(0xAA);
|
||||||
let other = make_node_addr(0xAB);
|
let other = make_node_addr(0xAB);
|
||||||
|
|
||||||
flood_requests(&mut node, &flooder, 1, MAX_RECENT_LOOKUP_REQUESTS as u64).await;
|
flood_requests(&mut node, &flooder, 1, MAX_RECENT_LOOKUP_REQUESTS as u64).await;
|
||||||
|
assert_eq!(
|
||||||
|
node.lookup.recent_requests.len(),
|
||||||
|
MAX_RECENT_LOOKUP_REQUESTS,
|
||||||
|
"precondition: the cache is full, or the lookup below is not tested against a flood"
|
||||||
|
);
|
||||||
|
|
||||||
let my_addr = *node.node_addr();
|
let my_addr = *node.node_addr();
|
||||||
let payload = lookup_request_payload(u64::MAX, &my_addr);
|
let payload = lookup_request_payload(u64::MAX, &my_addr);
|
||||||
|
|||||||
@@ -523,8 +523,7 @@ impl Fmp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decide the per-tick rekey choreography for the peers the shell
|
/// Decide the per-tick rekey choreography for the peers the shell
|
||||||
/// snapshotted. Reproduces the pre-refactor priority and phase grouping
|
/// snapshotted, in this priority:
|
||||||
/// exactly:
|
|
||||||
///
|
///
|
||||||
/// - **Cutover** takes precedence: a peer with a pending session this node
|
/// - **Cutover** takes precedence: a peer with a pending session this node
|
||||||
/// initiated and no in-flight rekey cuts over and is considered for
|
/// initiated and no in-flight rekey cuts over and is considered for
|
||||||
@@ -536,7 +535,7 @@ impl Fmp {
|
|||||||
/// trigger fires when the peer is neither mid-rekey, dampened, nor
|
/// trigger fires when the peer is neither mid-rekey, dampened, nor
|
||||||
/// holding a pending session, and its jittered time threshold or send
|
/// holding a pending session, and its jittered time threshold or send
|
||||||
/// counter is reached. A draining peer can thus both drain and
|
/// counter is reached. A draining peer can thus both drain and
|
||||||
/// re-trigger in the same tick, as before.
|
/// re-trigger in the same tick.
|
||||||
///
|
///
|
||||||
/// Actions are returned phase-grouped (all cutovers, then all drains, then
|
/// Actions are returned phase-grouped (all cutovers, then all drains, then
|
||||||
/// all retirements, then all rekey initiations) to preserve the global
|
/// all retirements, then all rekey initiations) to preserve the global
|
||||||
|
|||||||
Reference in New Issue
Block a user