@@ -4754,3 +4754,196 @@ func Test_validateBlobSidecars(t *testing.T) {
4754
4754
require .NoError (t , err )
4755
4755
require .ErrorContains (t , "could not verify blob proof: can't verify opening proof" , s .validateBlobSidecars (b , [][]byte {blob [:]}, [][]byte {proof [:]}))
4756
4756
}
4757
+
4758
+ func TestGetPendingDeposits (t * testing.T ) {
4759
+ st , _ := util .DeterministicGenesisStateElectra (t , 10 )
4760
+
4761
+ validators := st .Validators ()
4762
+ dummySig := make ([]byte , 96 )
4763
+ for j := 0 ; j < 96 ; j ++ {
4764
+ dummySig [j ] = byte (j )
4765
+ }
4766
+ deps := make ([]* eth.PendingDeposit , 10 )
4767
+ for i := 0 ; i < len (deps ); i += 1 {
4768
+ deps [i ] = & eth.PendingDeposit {
4769
+ PublicKey : validators [i ].PublicKey ,
4770
+ WithdrawalCredentials : validators [i ].WithdrawalCredentials ,
4771
+ Amount : 100 ,
4772
+ Slot : 0 ,
4773
+ Signature : dummySig ,
4774
+ }
4775
+ }
4776
+ require .NoError (t , st .SetPendingDeposits (deps ))
4777
+
4778
+ chainService := & chainMock.ChainService {
4779
+ Optimistic : false ,
4780
+ FinalizedRoots : map [[32 ]byte ]bool {},
4781
+ }
4782
+ server := & Server {
4783
+ Stater : & testutil.MockStater {
4784
+ BeaconState : st ,
4785
+ },
4786
+ OptimisticModeFetcher : chainService ,
4787
+ FinalizationFetcher : chainService ,
4788
+ }
4789
+
4790
+ t .Run ("json response" , func (t * testing.T ) {
4791
+ req := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4792
+ req .SetPathValue ("state_id" , "head" )
4793
+ rec := httptest .NewRecorder ()
4794
+ rec .Body = new (bytes.Buffer )
4795
+
4796
+ server .GetPendingDeposits (rec , req )
4797
+ require .Equal (t , http .StatusOK , rec .Code )
4798
+ require .Equal (t , "electra" , rec .Header ().Get (api .VersionHeader ))
4799
+
4800
+ var resp structs.GetPendingDepositsResponse
4801
+ require .NoError (t , json .Unmarshal (rec .Body .Bytes (), & resp ))
4802
+
4803
+ expectedVersion := version .String (st .Version ())
4804
+ require .Equal (t , expectedVersion , resp .Version )
4805
+
4806
+ require .Equal (t , false , resp .ExecutionOptimistic )
4807
+ require .Equal (t , false , resp .Finalized )
4808
+
4809
+ expectedDeposits := structs .PendingDepositsFromConsensus (deps )
4810
+ require .DeepEqual (t , expectedDeposits , resp .Data )
4811
+ })
4812
+ t .Run ("ssz response" , func (t * testing.T ) {
4813
+ req := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4814
+ req .Header .Set ("Accept" , "application/octet-stream" )
4815
+ req .SetPathValue ("state_id" , "head" )
4816
+ rec := httptest .NewRecorder ()
4817
+ rec .Body = new (bytes.Buffer )
4818
+
4819
+ server .GetPendingDeposits (rec , req )
4820
+ require .Equal (t , http .StatusOK , rec .Code )
4821
+ require .Equal (t , "electra" , rec .Header ().Get (api .VersionHeader ))
4822
+
4823
+ responseBytes := rec .Body .Bytes ()
4824
+ var recoveredDeposits []* eth.PendingDeposit
4825
+
4826
+ // Verify total size matches expected number of deposits
4827
+ depositSize := (& eth.PendingDeposit {}).SizeSSZ ()
4828
+ require .Equal (t , len (responseBytes ), depositSize * len (deps ))
4829
+
4830
+ for i := 0 ; i < len (deps ); i ++ {
4831
+ start := i * depositSize
4832
+ end := start + depositSize
4833
+
4834
+ var deposit eth.PendingDeposit
4835
+ require .NoError (t , deposit .UnmarshalSSZ (responseBytes [start :end ]))
4836
+ recoveredDeposits = append (recoveredDeposits , & deposit )
4837
+ }
4838
+ require .DeepEqual (t , deps , recoveredDeposits )
4839
+ })
4840
+ t .Run ("pre electra state" , func (t * testing.T ) {
4841
+ preElectraSt , _ := util .DeterministicGenesisStateDeneb (t , 1 )
4842
+ preElectraServer := & Server {
4843
+ Stater : & testutil.MockStater {
4844
+ BeaconState : preElectraSt ,
4845
+ },
4846
+ OptimisticModeFetcher : chainService ,
4847
+ FinalizationFetcher : chainService ,
4848
+ }
4849
+
4850
+ // Test JSON request
4851
+ req := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4852
+ req .SetPathValue ("state_id" , "head" )
4853
+ rec := httptest .NewRecorder ()
4854
+ rec .Body = new (bytes.Buffer )
4855
+
4856
+ preElectraServer .GetPendingDeposits (rec , req )
4857
+ require .Equal (t , http .StatusBadRequest , rec .Code )
4858
+
4859
+ var errResp struct {
4860
+ Code int `json:"code"`
4861
+ Message string `json:"message"`
4862
+ }
4863
+ require .NoError (t , json .Unmarshal (rec .Body .Bytes (), & errResp ))
4864
+ require .Equal (t , "state_id is prior to electra" , errResp .Message )
4865
+
4866
+ // Test SSZ request
4867
+ sszReq := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4868
+ sszReq .Header .Set ("Accept" , "application/octet-stream" )
4869
+ sszReq .SetPathValue ("state_id" , "head" )
4870
+ sszRec := httptest .NewRecorder ()
4871
+ sszRec .Body = new (bytes.Buffer )
4872
+
4873
+ preElectraServer .GetPendingDeposits (sszRec , sszReq )
4874
+ require .Equal (t , http .StatusBadRequest , sszRec .Code )
4875
+
4876
+ var sszErrResp struct {
4877
+ Code int `json:"code"`
4878
+ Message string `json:"message"`
4879
+ }
4880
+ require .NoError (t , json .Unmarshal (sszRec .Body .Bytes (), & sszErrResp ))
4881
+ require .Equal (t , "state_id is prior to electra" , sszErrResp .Message )
4882
+ })
4883
+ t .Run ("missing state_id parameter" , func (t * testing.T ) {
4884
+ req := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4885
+ // Intentionally not setting state_id
4886
+ rec := httptest .NewRecorder ()
4887
+ rec .Body = new (bytes.Buffer )
4888
+
4889
+ server .GetPendingDeposits (rec , req )
4890
+ require .Equal (t , http .StatusBadRequest , rec .Code )
4891
+
4892
+ var errResp struct {
4893
+ Code int `json:"code"`
4894
+ Message string `json:"message"`
4895
+ }
4896
+ require .NoError (t , json .Unmarshal (rec .Body .Bytes (), & errResp ))
4897
+ require .Equal (t , "state_id is required in URL params" , errResp .Message )
4898
+ })
4899
+ t .Run ("optimistic node" , func (t * testing.T ) {
4900
+ optimisticChainService := & chainMock.ChainService {
4901
+ Optimistic : true ,
4902
+ FinalizedRoots : map [[32 ]byte ]bool {},
4903
+ }
4904
+ optimisticServer := & Server {
4905
+ Stater : server .Stater ,
4906
+ OptimisticModeFetcher : optimisticChainService ,
4907
+ FinalizationFetcher : optimisticChainService ,
4908
+ }
4909
+
4910
+ req := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4911
+ req .SetPathValue ("state_id" , "head" )
4912
+ rec := httptest .NewRecorder ()
4913
+ rec .Body = new (bytes.Buffer )
4914
+
4915
+ optimisticServer .GetPendingDeposits (rec , req )
4916
+ require .Equal (t , http .StatusOK , rec .Code )
4917
+
4918
+ var resp structs.GetPendingDepositsResponse
4919
+ require .NoError (t , json .Unmarshal (rec .Body .Bytes (), & resp ))
4920
+ require .Equal (t , true , resp .ExecutionOptimistic )
4921
+ })
4922
+
4923
+ t .Run ("finalized node" , func (t * testing.T ) {
4924
+ blockRoot , err := st .LatestBlockHeader ().HashTreeRoot ()
4925
+ require .NoError (t , err )
4926
+
4927
+ finalizedChainService := & chainMock.ChainService {
4928
+ Optimistic : false ,
4929
+ FinalizedRoots : map [[32 ]byte ]bool {blockRoot : true },
4930
+ }
4931
+ finalizedServer := & Server {
4932
+ Stater : server .Stater ,
4933
+ OptimisticModeFetcher : finalizedChainService ,
4934
+ FinalizationFetcher : finalizedChainService ,
4935
+ }
4936
+
4937
+ req := httptest .NewRequest (http .MethodGet , "http://example.com/eth/v1/beacon/states/{state_id}/pending_deposits" , nil )
4938
+ req .SetPathValue ("state_id" , "head" )
4939
+ rec := httptest .NewRecorder ()
4940
+ rec .Body = new (bytes.Buffer )
4941
+
4942
+ finalizedServer .GetPendingDeposits (rec , req )
4943
+ require .Equal (t , http .StatusOK , rec .Code )
4944
+
4945
+ var resp structs.GetPendingDepositsResponse
4946
+ require .NoError (t , json .Unmarshal (rec .Body .Bytes (), & resp ))
4947
+ require .Equal (t , true , resp .Finalized )
4948
+ })
4949
+ }
0 commit comments