@@ -3,6 +3,7 @@ use std::time::Instant;
33
44use async_trait:: async_trait;
55use slog:: error;
6+ use slog:: warn;
67use slog:: Logger ;
78
89use crate :: components:: network_provider:: ChainName ;
@@ -26,6 +27,10 @@ impl ExtendedBlocksCheck {
2627
2728#[ async_trait]
2829impl ProviderCheck for ExtendedBlocksCheck {
30+ fn name ( & self ) -> & ' static str {
31+ "ExtendedBlocksCheck"
32+ }
33+
2934 async fn check (
3035 & self ,
3136 logger : & Logger ,
@@ -34,6 +39,13 @@ impl ProviderCheck for ExtendedBlocksCheck {
3439 adapter : & dyn NetworkDetails ,
3540 ) -> ProviderCheckStatus {
3641 if self . disabled_for_chains . contains ( chain_name) {
42+ warn ! (
43+ logger,
44+ "Extended blocks check for provider '{}' was disabled on chain '{}'" ,
45+ provider_name,
46+ chain_name,
47+ ) ;
48+
3749 return ProviderCheckStatus :: Valid ;
3850 }
3951
@@ -65,3 +77,152 @@ impl ProviderCheck for ExtendedBlocksCheck {
6577 }
6678 }
6779}
80+
81+ #[ cfg( test) ]
82+ mod tests {
83+ use std:: sync:: Mutex ;
84+
85+ use anyhow:: anyhow;
86+ use anyhow:: Result ;
87+
88+ use super :: * ;
89+ use crate :: blockchain:: ChainIdentifier ;
90+ use crate :: log:: discard;
91+
92+ macro_rules! lock {
93+ ( $obj: ident. $field: ident. $( $call: tt ) +) => { {
94+ $obj. $field. lock( ) . unwrap( ) . $( $call ) +
95+ } } ;
96+ }
97+
98+ #[ derive( Default ) ]
99+ struct TestAdapter {
100+ provides_extended_blocks_calls : Mutex < Vec < Result < bool > > > ,
101+ }
102+
103+ #[ async_trait]
104+ impl NetworkDetails for TestAdapter {
105+ fn provider_name ( & self ) -> ProviderName {
106+ unimplemented ! ( ) ;
107+ }
108+
109+ async fn chain_identifier ( & self ) -> Result < ChainIdentifier > {
110+ unimplemented ! ( ) ;
111+ }
112+
113+ async fn provides_extended_blocks ( & self ) -> Result < bool > {
114+ lock ! ( self . provides_extended_blocks_calls. remove( 0 ) )
115+ }
116+ }
117+
118+ impl Drop for TestAdapter {
119+ fn drop ( & mut self ) {
120+ assert ! ( lock!( self . provides_extended_blocks_calls. is_empty( ) ) ) ;
121+ }
122+ }
123+
124+ #[ tokio:: test]
125+ async fn check_valid_when_disabled_for_chain ( ) {
126+ let check = ExtendedBlocksCheck :: new ( [ "chain-1" . into ( ) ] ) ;
127+ let adapter = TestAdapter :: default ( ) ;
128+
129+ let status = check
130+ . check (
131+ & discard ( ) ,
132+ & ( "chain-1" . into ( ) ) ,
133+ & ( "provider-1" . into ( ) ) ,
134+ & adapter,
135+ )
136+ . await ;
137+
138+ assert_eq ! ( status, ProviderCheckStatus :: Valid ) ;
139+ }
140+
141+ #[ tokio:: test]
142+ async fn check_valid_when_disabled_for_multiple_chains ( ) {
143+ let check = ExtendedBlocksCheck :: new ( [ "chain-1" . into ( ) , "chain-2" . into ( ) ] ) ;
144+ let adapter = TestAdapter :: default ( ) ;
145+
146+ let status = check
147+ . check (
148+ & discard ( ) ,
149+ & ( "chain-1" . into ( ) ) ,
150+ & ( "provider-1" . into ( ) ) ,
151+ & adapter,
152+ )
153+ . await ;
154+
155+ assert_eq ! ( status, ProviderCheckStatus :: Valid ) ;
156+
157+ let status = check
158+ . check (
159+ & discard ( ) ,
160+ & ( "chain-2" . into ( ) ) ,
161+ & ( "provider-2" . into ( ) ) ,
162+ & adapter,
163+ )
164+ . await ;
165+
166+ assert_eq ! ( status, ProviderCheckStatus :: Valid ) ;
167+ }
168+
169+ #[ tokio:: test]
170+ async fn check_valid_when_extended_blocks_are_supported ( ) {
171+ let check = ExtendedBlocksCheck :: new ( [ ] ) ;
172+
173+ let adapter = TestAdapter :: default ( ) ;
174+ lock ! { adapter. provides_extended_blocks_calls. push( Ok ( true ) ) } ;
175+
176+ let status = check
177+ . check (
178+ & discard ( ) ,
179+ & ( "chain-1" . into ( ) ) ,
180+ & ( "provider-1" . into ( ) ) ,
181+ & adapter,
182+ )
183+ . await ;
184+
185+ assert_eq ! ( status, ProviderCheckStatus :: Valid ) ;
186+ }
187+
188+ #[ tokio:: test]
189+ async fn check_fails_when_extended_blocks_are_not_supported ( ) {
190+ let check = ExtendedBlocksCheck :: new ( [ ] ) ;
191+
192+ let adapter = TestAdapter :: default ( ) ;
193+ lock ! { adapter. provides_extended_blocks_calls. push( Ok ( false ) ) } ;
194+
195+ let status = check
196+ . check (
197+ & discard ( ) ,
198+ & ( "chain-1" . into ( ) ) ,
199+ & ( "provider-1" . into ( ) ) ,
200+ & adapter,
201+ )
202+ . await ;
203+
204+ assert_eq ! ( status, ProviderCheckStatus :: Failed ) ;
205+ }
206+
207+ #[ tokio:: test]
208+ async fn check_temporary_failure_when_provider_request_fails ( ) {
209+ let check = ExtendedBlocksCheck :: new ( [ ] ) ;
210+
211+ let adapter = TestAdapter :: default ( ) ;
212+ lock ! { adapter. provides_extended_blocks_calls. push( Err ( anyhow!( "error" ) ) ) } ;
213+
214+ let status = check
215+ . check (
216+ & discard ( ) ,
217+ & ( "chain-1" . into ( ) ) ,
218+ & ( "provider-1" . into ( ) ) ,
219+ & adapter,
220+ )
221+ . await ;
222+
223+ assert ! ( matches!(
224+ status,
225+ ProviderCheckStatus :: TemporaryFailure { .. }
226+ ) )
227+ }
228+ }
0 commit comments