21
21
import it .unimi .dsi .fastutil .ints .IntSet ;
22
22
import java .util .Iterator ;
23
23
import java .util .Set ;
24
+ import java .util .concurrent .atomic .AtomicReference ;
24
25
import org .apache .logging .log4j .LogManager ;
25
26
import org .apache .logging .log4j .Logger ;
26
27
import tech .pegasys .teku .ethereum .events .SlotEventsChannel ;
@@ -39,6 +40,7 @@ public class AttestationTopicSubscriber implements SlotEventsChannel {
39
40
private final Eth2P2PNetwork eth2P2PNetwork ;
40
41
private final Spec spec ;
41
42
private final SettableLabelledGauge subnetSubscriptionsGauge ;
43
+ private final AtomicReference <UInt64 > currentSlot = new AtomicReference <>(null );
42
44
43
45
public AttestationTopicSubscriber (
44
46
final Spec spec ,
@@ -56,6 +58,15 @@ public synchronized void subscribeToCommitteeForAggregation(
56
58
aggregationSlot , UInt64 .valueOf (committeeIndex ), committeesAtSlot );
57
59
final UInt64 currentUnsubscriptionSlot = subnetIdToUnsubscribeSlot .getOrDefault (subnetId , ZERO );
58
60
final UInt64 unsubscribeSlot = currentUnsubscriptionSlot .max (aggregationSlot );
61
+ final UInt64 maybeCurrentSlot = currentSlot .get ();
62
+ if (maybeCurrentSlot != null && unsubscribeSlot .isLessThan (maybeCurrentSlot )) {
63
+ LOG .trace (
64
+ "Skipping outdated aggregation subnet {} with unsubscribe due at slot {}" ,
65
+ subnetId ,
66
+ unsubscribeSlot );
67
+ return ;
68
+ }
69
+
59
70
if (currentUnsubscriptionSlot .equals (ZERO )) {
60
71
eth2P2PNetwork .subscribeToAttestationSubnetId (subnetId );
61
72
toggleAggregateSubscriptionMetric (subnetId , false );
@@ -96,15 +107,25 @@ public synchronized void subscribeToPersistentSubnets(
96
107
boolean shouldUpdateENR = false ;
97
108
98
109
for (SubnetSubscription subnetSubscription : newSubscriptions ) {
99
- int subnetId = subnetSubscription .subnetId ();
110
+ final int subnetId = subnetSubscription .subnetId ();
111
+ final UInt64 maybeCurrentSlot = currentSlot .get ();
112
+ if (maybeCurrentSlot != null
113
+ && subnetSubscription .unsubscriptionSlot ().isLessThan (maybeCurrentSlot )) {
114
+ LOG .trace (
115
+ "Skipping outdated persistent subnet {} with unsubscribe due at slot {}" ,
116
+ subnetId ,
117
+ subnetSubscription .unsubscriptionSlot ());
118
+ continue ;
119
+ }
120
+
100
121
shouldUpdateENR = persistentSubnetIdSet .add (subnetId ) || shouldUpdateENR ;
101
122
LOG .trace (
102
123
"Subscribing to persistent subnet {} with unsubscribe due at slot {}" ,
103
124
subnetId ,
104
125
subnetSubscription .unsubscriptionSlot ());
105
126
if (subnetIdToUnsubscribeSlot .containsKey (subnetId )) {
106
- UInt64 existingUnsubscriptionSlot = subnetIdToUnsubscribeSlot .get (subnetId );
107
- UInt64 unsubscriptionSlot =
127
+ final UInt64 existingUnsubscriptionSlot = subnetIdToUnsubscribeSlot .get (subnetId );
128
+ final UInt64 unsubscriptionSlot =
108
129
existingUnsubscriptionSlot .max (subnetSubscription .unsubscriptionSlot ());
109
130
LOG .trace (
110
131
"Already subscribed to subnet {}, updating unsubscription slot to {}" ,
@@ -127,14 +148,15 @@ public synchronized void subscribeToPersistentSubnets(
127
148
128
149
@ Override
129
150
public synchronized void onSlot (final UInt64 slot ) {
151
+ currentSlot .set (slot );
130
152
boolean shouldUpdateENR = false ;
131
153
132
154
final Iterator <Int2ObjectMap .Entry <UInt64 >> iterator =
133
155
subnetIdToUnsubscribeSlot .int2ObjectEntrySet ().iterator ();
134
156
while (iterator .hasNext ()) {
135
157
final Int2ObjectMap .Entry <UInt64 > entry = iterator .next ();
136
158
if (entry .getValue ().compareTo (slot ) < 0 ) {
137
- int subnetId = entry .getIntKey ();
159
+ final int subnetId = entry .getIntKey ();
138
160
LOG .trace ("Unsubscribing from subnet {}" , subnetId );
139
161
eth2P2PNetwork .unsubscribeFromAttestationSubnetId (subnetId );
140
162
if (persistentSubnetIdSet .contains (subnetId )) {
0 commit comments