13
13
14
14
package tech .pegasys .teku .validator .remote .typedef ;
15
15
16
+ import static java .util .Collections .emptyMap ;
16
17
import static org .assertj .core .api .Assertions .assertThat ;
18
+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
17
19
import static org .assertj .core .api .Assumptions .assumeThat ;
20
+ import static tech .pegasys .teku .ethereum .json .types .beacon .StateValidatorDataBuilder .STATE_VALIDATORS_RESPONSE_TYPE ;
21
+ import static tech .pegasys .teku .infrastructure .http .HttpStatusCodes .SC_BAD_REQUEST ;
22
+ import static tech .pegasys .teku .infrastructure .http .HttpStatusCodes .SC_METHOD_NOT_ALLOWED ;
23
+ import static tech .pegasys .teku .infrastructure .http .HttpStatusCodes .SC_NOT_FOUND ;
24
+ import static tech .pegasys .teku .infrastructure .http .HttpStatusCodes .SC_NO_CONTENT ;
25
+ import static tech .pegasys .teku .infrastructure .http .HttpStatusCodes .SC_OK ;
26
+ import static tech .pegasys .teku .infrastructure .json .JsonUtil .serialize ;
18
27
19
28
import com .fasterxml .jackson .core .JsonProcessingException ;
20
29
import com .fasterxml .jackson .databind .ObjectMapper ;
30
+ import java .util .List ;
21
31
import java .util .Optional ;
22
32
import okhttp3 .mockwebserver .MockResponse ;
23
33
import okhttp3 .mockwebserver .RecordedRequest ;
24
34
import org .apache .tuweni .bytes .Bytes ;
25
35
import org .junit .jupiter .api .Assertions ;
26
36
import org .junit .jupiter .api .BeforeEach ;
27
37
import org .junit .jupiter .api .TestTemplate ;
38
+ import org .junit .jupiter .params .ParameterizedTest ;
39
+ import org .junit .jupiter .params .provider .ValueSource ;
28
40
import tech .pegasys .teku .api .exceptions .RemoteServiceNotAvailableException ;
29
- import tech .pegasys .teku .infrastructure .json .JsonUtil ;
41
+ import tech .pegasys .teku .api .response .v1 .beacon .ValidatorStatus ;
42
+ import tech .pegasys .teku .ethereum .json .types .beacon .StateValidatorData ;
30
43
import tech .pegasys .teku .infrastructure .ssz .SszDataAssert ;
31
44
import tech .pegasys .teku .infrastructure .ssz .SszList ;
32
45
import tech .pegasys .teku .infrastructure .unsigned .UInt64 ;
37
50
import tech .pegasys .teku .spec .datastructures .blocks .SignedBeaconBlock ;
38
51
import tech .pegasys .teku .spec .datastructures .builder .SignedValidatorRegistration ;
39
52
import tech .pegasys .teku .spec .datastructures .metadata .BlockContainerAndMetaData ;
53
+ import tech .pegasys .teku .spec .datastructures .metadata .ObjectAndMetaData ;
40
54
import tech .pegasys .teku .spec .networks .Eth2Network ;
41
55
import tech .pegasys .teku .spec .schemas .ApiSchemas ;
42
56
import tech .pegasys .teku .validator .api .SendSignedBlockResult ;
43
57
import tech .pegasys .teku .validator .api .required .SyncingStatus ;
58
+ import tech .pegasys .teku .validator .remote .apiclient .PostStateValidatorsNotExistingException ;
59
+ import tech .pegasys .teku .validator .remote .apiclient .ValidatorApiMethod ;
44
60
import tech .pegasys .teku .validator .remote .typedef .handlers .RegisterValidatorsRequest ;
45
61
46
62
@ TestSpecContext (allMilestones = true , network = Eth2Network .MINIMAL )
@@ -136,7 +152,7 @@ void publishesBlindedBlockJsonEncoded() throws InterruptedException, JsonProcess
136
152
final RecordedRequest recordedRequest = mockWebServer .takeRequest ();
137
153
138
154
final String expectedRequest =
139
- JsonUtil . serialize (
155
+ serialize (
140
156
signedBeaconBlock ,
141
157
spec .atSlot (UInt64 .ONE )
142
158
.getSchemaDefinitions ()
@@ -193,7 +209,7 @@ void registerValidators_makesJsonRequest() throws InterruptedException, JsonProc
193
209
dataStructureUtil .randomSignedValidatorRegistrations (5 );
194
210
195
211
final String expectedRequest =
196
- JsonUtil . serialize (
212
+ serialize (
197
213
validatorRegistrations ,
198
214
ApiSchemas .SIGNED_VALIDATOR_REGISTRATIONS_SCHEMA .getJsonTypeDefinition ());
199
215
@@ -323,6 +339,62 @@ void blockV3ShouldFallbacksToBlockV2WhenNotFound()
323
339
assertThat (secondRequest .getPath ()).startsWith ("/eth/v1/validator/blinded_blocks" );
324
340
}
325
341
342
+ @ TestTemplate
343
+ void postValidators_MakesExpectedRequest () throws Exception {
344
+ mockWebServer .enqueue (new MockResponse ().setResponseCode (SC_NO_CONTENT ));
345
+
346
+ okHttpValidatorTypeDefClient .postStateValidators (List .of ("1" , "0x1234" ));
347
+
348
+ final RecordedRequest request = mockWebServer .takeRequest ();
349
+ assertThat (request .getMethod ()).isEqualTo ("POST" );
350
+
351
+ assertThat (request .getPath ()).contains (ValidatorApiMethod .GET_VALIDATORS .getPath (emptyMap ()));
352
+ assertThat (request .getBody ().readUtf8 ()).isEqualTo ("{\" ids\" :[\" 1\" ,\" 0x1234\" ]}" );
353
+ }
354
+
355
+ @ TestTemplate
356
+ public void postValidators_WhenNoContent_ReturnsEmpty () {
357
+ mockWebServer .enqueue (new MockResponse ().setResponseCode (SC_NO_CONTENT ));
358
+
359
+ assertThat (okHttpValidatorTypeDefClient .postStateValidators (List .of ("1" ))).isEmpty ();
360
+ }
361
+
362
+ @ ParameterizedTest
363
+ @ ValueSource (ints = {SC_BAD_REQUEST , SC_NOT_FOUND , SC_METHOD_NOT_ALLOWED })
364
+ public void postValidators_WhenNotExisting_ThrowsException (final int responseCode ) {
365
+ mockWebServer .enqueue (new MockResponse ().setResponseCode (responseCode ));
366
+
367
+ assertThatThrownBy (() -> okHttpValidatorTypeDefClient .postStateValidators (List .of ("1" )))
368
+ .isInstanceOf (PostStateValidatorsNotExistingException .class );
369
+ }
370
+
371
+ @ TestTemplate
372
+ public void postValidators_WhenSuccess_ReturnsResponse () throws JsonProcessingException {
373
+ final List <StateValidatorData > expected =
374
+ List .of (generateStateValidatorData (), generateStateValidatorData ());
375
+ final ObjectAndMetaData <List <StateValidatorData >> response =
376
+ new ObjectAndMetaData <>(expected , specMilestone , false , true , false );
377
+
378
+ mockWebServer .enqueue (
379
+ new MockResponse ()
380
+ .setResponseCode (SC_OK )
381
+ .setBody (serialize (response , STATE_VALIDATORS_RESPONSE_TYPE )));
382
+
383
+ Optional <List <StateValidatorData >> result =
384
+ okHttpValidatorTypeDefClient .postStateValidators (List .of ("1" , "2" ));
385
+
386
+ assertThat (result ).isPresent ();
387
+ assertThat (result .get ()).usingRecursiveComparison ().isEqualTo (expected );
388
+ }
389
+
390
+ private StateValidatorData generateStateValidatorData () {
391
+ return new StateValidatorData (
392
+ dataStructureUtil .randomValidatorIndex (),
393
+ dataStructureUtil .randomUInt64 (),
394
+ ValidatorStatus .active_ongoing ,
395
+ dataStructureUtil .randomValidator ());
396
+ }
397
+
326
398
private void verifyRegisterValidatorsPostRequest (
327
399
final RecordedRequest recordedRequest , final String expectedContentType ) {
328
400
assertThat (recordedRequest .getPath ()).isEqualTo ("/eth/v1/validator/register_validator" );
@@ -341,7 +413,7 @@ private void assertJsonEquals(final String actual, final String expected) {
341
413
342
414
private String serializeBlockContainer (final BlockContainer blockContainer )
343
415
throws JsonProcessingException {
344
- return JsonUtil . serialize (
416
+ return serialize (
345
417
blockContainer ,
346
418
blockContainer .isBlinded ()
347
419
? schemaDefinitions .getBlindedBlockContainerSchema ().getJsonTypeDefinition ()
0 commit comments