@@ -4,14 +4,26 @@ mod tests {
4
4
use crate :: persisted_dht:: load_dht;
5
5
use crate :: { NetworkConfig , NetworkService } ;
6
6
use beacon_chain:: test_utils:: BeaconChainHarness ;
7
- use beacon_processor:: BeaconProcessorChannels ;
8
- use lighthouse_network:: Enr ;
7
+ use beacon_chain:: BeaconChainTypes ;
8
+ use beacon_processor:: { BeaconProcessorChannels , BeaconProcessorConfig } ;
9
+ use futures:: StreamExt ;
10
+ use lighthouse_network:: types:: { GossipEncoding , GossipKind } ;
11
+ use lighthouse_network:: { Enr , GossipTopic } ;
9
12
use slog:: { o, Drain , Level , Logger } ;
10
13
use sloggers:: { null:: NullLoggerBuilder , Build } ;
11
14
use std:: str:: FromStr ;
12
15
use std:: sync:: Arc ;
13
16
use tokio:: runtime:: Runtime ;
14
- use types:: MinimalEthSpec ;
17
+ use types:: { Epoch , EthSpec , ForkName , MinimalEthSpec , SubnetId } ;
18
+
19
+ impl < T : BeaconChainTypes > NetworkService < T > {
20
+ fn get_topic_params (
21
+ & self ,
22
+ topic : GossipTopic ,
23
+ ) -> Option < & lighthouse_network:: libp2p:: gossipsub:: TopicScoreParams > {
24
+ self . libp2p . get_topic_params ( topic)
25
+ }
26
+ }
15
27
16
28
fn get_logger ( actual_log : bool ) -> Logger {
17
29
if actual_log {
@@ -102,4 +114,126 @@ mod tests {
102
114
"should have persisted the second ENR to store"
103
115
) ;
104
116
}
117
+
118
+ // Test removing topic weight on old topics when a fork happens.
119
+ #[ test]
120
+ fn test_removing_topic_weight_on_old_topics ( ) {
121
+ let runtime = Arc :: new ( Runtime :: new ( ) . unwrap ( ) ) ;
122
+
123
+ // Capella spec
124
+ let mut spec = MinimalEthSpec :: default_spec ( ) ;
125
+ spec. altair_fork_epoch = Some ( Epoch :: new ( 0 ) ) ;
126
+ spec. bellatrix_fork_epoch = Some ( Epoch :: new ( 0 ) ) ;
127
+ spec. capella_fork_epoch = Some ( Epoch :: new ( 1 ) ) ;
128
+
129
+ // Build beacon chain.
130
+ let beacon_chain = BeaconChainHarness :: builder ( MinimalEthSpec )
131
+ . spec ( spec. clone ( ) )
132
+ . deterministic_keypairs ( 8 )
133
+ . fresh_ephemeral_store ( )
134
+ . mock_execution_layer ( )
135
+ . build ( )
136
+ . chain ;
137
+ let ( next_fork_name, _) = beacon_chain. duration_to_next_fork ( ) . expect ( "next fork" ) ;
138
+ assert_eq ! ( next_fork_name, ForkName :: Capella ) ;
139
+
140
+ // Build network service.
141
+ let ( mut network_service, network_globals, _network_senders) = runtime. block_on ( async {
142
+ let ( _, exit) = exit_future:: signal ( ) ;
143
+ let ( shutdown_tx, _) = futures:: channel:: mpsc:: channel ( 1 ) ;
144
+ let executor = task_executor:: TaskExecutor :: new (
145
+ Arc :: downgrade ( & runtime) ,
146
+ exit,
147
+ get_logger ( false ) ,
148
+ shutdown_tx,
149
+ ) ;
150
+
151
+ let mut config = NetworkConfig :: default ( ) ;
152
+ config. set_ipv4_listening_address ( std:: net:: Ipv4Addr :: UNSPECIFIED , 21214 , 21214 , 21215 ) ;
153
+ config. discv5_config . table_filter = |_| true ; // Do not ignore local IPs
154
+ config. upnp_enabled = false ;
155
+
156
+ let beacon_processor_channels =
157
+ BeaconProcessorChannels :: new ( & BeaconProcessorConfig :: default ( ) ) ;
158
+ NetworkService :: build (
159
+ beacon_chain. clone ( ) ,
160
+ & config,
161
+ executor. clone ( ) ,
162
+ None ,
163
+ beacon_processor_channels. beacon_processor_tx ,
164
+ beacon_processor_channels. work_reprocessing_tx ,
165
+ )
166
+ . await
167
+ . unwrap ( )
168
+ } ) ;
169
+
170
+ // Subscribe to the topics.
171
+ runtime. block_on ( async {
172
+ while network_globals. gossipsub_subscriptions . read ( ) . len ( ) < 2 {
173
+ if let Some ( msg) = network_service. attestation_service . next ( ) . await {
174
+ network_service. on_attestation_service_msg ( msg) ;
175
+ }
176
+ }
177
+ } ) ;
178
+
179
+ // Make sure the service is subscribed to the topics.
180
+ let ( old_topic1, old_topic2) = {
181
+ let mut subnets = SubnetId :: compute_subnets_for_epoch :: < MinimalEthSpec > (
182
+ network_globals. local_enr ( ) . node_id ( ) . raw ( ) . into ( ) ,
183
+ beacon_chain. epoch ( ) . unwrap ( ) ,
184
+ & spec,
185
+ )
186
+ . unwrap ( )
187
+ . 0
188
+ . collect :: < Vec < _ > > ( ) ;
189
+ assert_eq ! ( 2 , subnets. len( ) ) ;
190
+
191
+ let old_fork_digest = beacon_chain. enr_fork_id ( ) . fork_digest ;
192
+ let old_topic1 = GossipTopic :: new (
193
+ GossipKind :: Attestation ( subnets. pop ( ) . unwrap ( ) ) ,
194
+ GossipEncoding :: SSZSnappy ,
195
+ old_fork_digest,
196
+ ) ;
197
+ let old_topic2 = GossipTopic :: new (
198
+ GossipKind :: Attestation ( subnets. pop ( ) . unwrap ( ) ) ,
199
+ GossipEncoding :: SSZSnappy ,
200
+ old_fork_digest,
201
+ ) ;
202
+
203
+ ( old_topic1, old_topic2)
204
+ } ;
205
+ let subscriptions = network_globals. gossipsub_subscriptions . read ( ) . clone ( ) ;
206
+ assert_eq ! ( 2 , subscriptions. len( ) ) ;
207
+ assert ! ( subscriptions. contains( & old_topic1) ) ;
208
+ assert ! ( subscriptions. contains( & old_topic2) ) ;
209
+ let old_topic_params1 = network_service
210
+ . get_topic_params ( old_topic1. clone ( ) )
211
+ . expect ( "topic score params" ) ;
212
+ assert ! ( old_topic_params1. topic_weight > 0.0 ) ;
213
+ let old_topic_params2 = network_service
214
+ . get_topic_params ( old_topic2. clone ( ) )
215
+ . expect ( "topic score params" ) ;
216
+ assert ! ( old_topic_params2. topic_weight > 0.0 ) ;
217
+
218
+ // Advance slot to the next fork
219
+ for _ in 0 ..MinimalEthSpec :: slots_per_epoch ( ) {
220
+ beacon_chain. slot_clock . advance_slot ( ) ;
221
+ }
222
+
223
+ // Run `NetworkService::update_next_fork()`.
224
+ runtime. block_on ( async {
225
+ network_service. update_next_fork ( ) ;
226
+ } ) ;
227
+
228
+ // Check that topic_weight on the old topics has been zeroed.
229
+ let old_topic_params1 = network_service
230
+ . get_topic_params ( old_topic1)
231
+ . expect ( "topic score params" ) ;
232
+ assert_eq ! ( 0.0 , old_topic_params1. topic_weight) ;
233
+
234
+ let old_topic_params2 = network_service
235
+ . get_topic_params ( old_topic2)
236
+ . expect ( "topic score params" ) ;
237
+ assert_eq ! ( 0.0 , old_topic_params2. topic_weight) ;
238
+ }
105
239
}
0 commit comments