Skip to content

Conversation

@figtracer
Copy link

@figtracer figtracer commented Dec 21, 2025

Issue Addressed

#7573

thread 'subnet_service::tests::test::test_same_subnet_unsubscription' (1640572) panicked at beacon_node/network/src/subnet_service/tests/mod.rs:356:13:
assertion `left == right` failed
  left: [Unsubscribe(Attestation(SubnetId(3)))]
 right: []
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Why

the race condition seems due to the usage of is_subscribed() instead of is_subscribed_permanent(), which was not following the comment's desired behaviour since is_subscribed() considers both permanent and temporary subscriptions.

// If we are permanently subscribed to this subnet, we won't see a subscribe message

so, previously, we could be taking the if branch for a temporary subscription

        if subnet_service.is_subscribed(&Subnet::Attestation(subnet_id1)) {
            // If we are permanently subscribed to this subnet, we won't see a subscribe message
            let _ = get_events_until_num_slots(&mut subnet_service, None, 1).await;

discarding Subscribe and potentially Unsubscribe events; thus, when reaching

        // Get event for 1 more slot duration, we should get the unsubscribe event now.
        let unsubscribe_event = get_events_until_num_slots(&mut subnet_service, None, 1).await;

the expected Unsubscribe could have been discarded already, resulting in [].

Fix

refactored the test to use a more deterministic approach following the other tests and removed is_subscribed() since we take the same route by checking is_subscribed_permanent() first

Results

Run #2000
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.77s
warning: the following packages contain code that will be rejected by a future version of Rust: num-bigint-dig v0.8.4
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`
     Running unittests src/lib.rs (target/debug/deps/network-ecf0aa6b04bd6e2d)

running 1 test
test subnet_service::tests::test::test_same_subnet_unsubscription ... ok

successes:

successes:
    subnet_service::tests::test::test_same_subnet_unsubscription

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 71 filtered out; finished in 6.11s

@figtracer figtracer requested a review from jxs as a code owner December 21, 2025 02:36
@figtracer figtracer marked this pull request as draft December 22, 2025 08:23
@figtracer figtracer marked this pull request as ready for review December 22, 2025 16:17
@ackintosh ackintosh added test improvement Improve tests ready-for-review The code is ready for review labels Dec 23, 2025
Copy link
Member

@ackintosh ackintosh left a comment

Choose a reason for hiding this comment

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

Thanks, @figtracer ! I've left a few comments.

let _ = get_events_until_num_slots(&mut subnet_service, None, 1).await;
// If permanently subscribed, no Subscribe/Unsubscribe events will be generated
if subnet_service.is_subscribed_permanent(&subnet) {
let _ = get_events_until_num_slots(&mut subnet_service, None, 3).await;
Copy link
Member

Choose a reason for hiding this comment

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

To make the test more robust, I think we should check that the event returned from get_events_until_num_slots is empty.

Comment on lines +344 to +355
// Wait for exactly 2 events (Subscribe + Unsubscribe) with a generous timeout
let expected = [
SubnetServiceMessage::Subscribe(subnet),
SubnetServiceMessage::Unsubscribe(subnet),
];
let events = get_events_until_num_slots(
&mut subnet_service,
Some(2),
(MainnetEthSpec::slots_per_epoch()) as u32,
)
.await;
assert_eq!(events, expected);
Copy link
Member

Choose a reason for hiding this comment

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

The original intent here (before this fix) was to check which event we get at each slot.
So I think it would be preferable to check the events slot by slot, for example like this:

let subscribe_event = get_events_until_num_slots(&mut subnet_service, Some(1), 1).await;
assert_eq!(subscribe_event, expected);

let unsubscribe_event = get_events_until_num_slots(&mut subnet_service, Some(1), 1).await;
assert_eq!(unsubscribe_event, expected);

@jimmygchen jimmygchen added waiting-on-author The reviewer has suggested changes and awaits thier implementation. and removed ready-for-review The code is ready for review labels Jan 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test improvement Improve tests waiting-on-author The reviewer has suggested changes and awaits thier implementation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants