@@ -991,3 +991,154 @@ impl TryFrom<JsonClientVersionV1> for ClientVersionV1 {
991
991
} )
992
992
}
993
993
}
994
+
995
+ #[ cfg( test) ]
996
+ mod tests {
997
+ use ssz:: Encode ;
998
+ use types:: {
999
+ ConsolidationRequest , DepositRequest , MainnetEthSpec , PublicKeyBytes , RequestType ,
1000
+ SignatureBytes , WithdrawalRequest ,
1001
+ } ;
1002
+
1003
+ use super :: * ;
1004
+
1005
+ fn create_request_string < T : Encode > ( prefix : u8 , request_bytes : & T ) -> String {
1006
+ format ! (
1007
+ "0x{:02x}{}" ,
1008
+ prefix,
1009
+ hex:: encode( request_bytes. as_ssz_bytes( ) )
1010
+ )
1011
+ }
1012
+
1013
+ /// Tests all error conditions except ssz decoding errors
1014
+ ///
1015
+ /// ***
1016
+ /// Elements of the list MUST be ordered by request_type in ascending order.
1017
+ /// Elements with empty request_data MUST be excluded from the list.
1018
+ /// If any element is out of order, has a length of 1-byte or shorter,
1019
+ /// or more than one element has the same type byte, client software MUST return -32602: Invalid params error.
1020
+ /// ***
1021
+ #[ test]
1022
+ fn test_invalid_execution_requests ( ) {
1023
+ let deposit_request = DepositRequest {
1024
+ pubkey : PublicKeyBytes :: empty ( ) ,
1025
+ withdrawal_credentials : Hash256 :: random ( ) ,
1026
+ amount : 32 ,
1027
+ signature : SignatureBytes :: empty ( ) ,
1028
+ index : 0 ,
1029
+ } ;
1030
+
1031
+ let consolidation_request = ConsolidationRequest {
1032
+ source_address : Address :: random ( ) ,
1033
+ source_pubkey : PublicKeyBytes :: empty ( ) ,
1034
+ target_pubkey : PublicKeyBytes :: empty ( ) ,
1035
+ } ;
1036
+
1037
+ let withdrawal_request = WithdrawalRequest {
1038
+ amount : 32 ,
1039
+ source_address : Address :: random ( ) ,
1040
+ validator_pubkey : PublicKeyBytes :: empty ( ) ,
1041
+ } ;
1042
+
1043
+ // First check a valid request with all requests
1044
+ assert ! (
1045
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1046
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1047
+ create_request_string( RequestType :: Withdrawal . to_u8( ) , & withdrawal_request) ,
1048
+ create_request_string( RequestType :: Consolidation . to_u8( ) , & consolidation_request) ,
1049
+ ] ) )
1050
+ . is_ok( )
1051
+ ) ;
1052
+
1053
+ // Single requests
1054
+ assert ! (
1055
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1056
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1057
+ ] ) )
1058
+ . is_ok( )
1059
+ ) ;
1060
+
1061
+ assert ! (
1062
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1063
+ create_request_string( RequestType :: Withdrawal . to_u8( ) , & withdrawal_request) ,
1064
+ ] ) )
1065
+ . is_ok( )
1066
+ ) ;
1067
+
1068
+ assert ! (
1069
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1070
+ create_request_string( RequestType :: Consolidation . to_u8( ) , & consolidation_request) ,
1071
+ ] ) )
1072
+ . is_ok( )
1073
+ ) ;
1074
+
1075
+ // Out of order
1076
+ assert ! ( matches!(
1077
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1078
+ create_request_string( RequestType :: Withdrawal . to_u8( ) , & withdrawal_request) ,
1079
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1080
+ ] ) )
1081
+ . unwrap_err( ) ,
1082
+ RequestsError :: InvalidOrdering
1083
+ ) ) ;
1084
+
1085
+ assert ! ( matches!(
1086
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1087
+ create_request_string( RequestType :: Consolidation . to_u8( ) , & consolidation_request) ,
1088
+ create_request_string( RequestType :: Withdrawal . to_u8( ) , & withdrawal_request) ,
1089
+ ] ) )
1090
+ . unwrap_err( ) ,
1091
+ RequestsError :: InvalidOrdering
1092
+ ) ) ;
1093
+
1094
+ assert ! ( matches!(
1095
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1096
+ create_request_string( RequestType :: Consolidation . to_u8( ) , & consolidation_request) ,
1097
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1098
+ ] ) )
1099
+ . unwrap_err( ) ,
1100
+ RequestsError :: InvalidOrdering
1101
+ ) ) ;
1102
+
1103
+ // Multiple requests of same type
1104
+ assert ! ( matches!(
1105
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1106
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1107
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1108
+ ] ) )
1109
+ . unwrap_err( ) ,
1110
+ RequestsError :: InvalidOrdering
1111
+ ) ) ;
1112
+
1113
+ // Invalid prefix
1114
+ assert ! ( matches!(
1115
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1116
+ create_request_string( 42 , & deposit_request) ,
1117
+ ] ) )
1118
+ . unwrap_err( ) ,
1119
+ RequestsError :: InvalidPrefix ( 42 )
1120
+ ) ) ;
1121
+
1122
+ // Prefix followed by no data
1123
+ assert ! ( matches!(
1124
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1125
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1126
+ create_request_string(
1127
+ RequestType :: Consolidation . to_u8( ) ,
1128
+ & Vec :: <ConsolidationRequest >:: new( )
1129
+ ) ,
1130
+ ] ) )
1131
+ . unwrap_err( ) ,
1132
+ RequestsError :: EmptyRequest ( 1 )
1133
+ ) ) ;
1134
+ // Empty request
1135
+ assert ! ( matches!(
1136
+ ExecutionRequests :: <MainnetEthSpec >:: try_from( JsonExecutionRequests ( vec![
1137
+ create_request_string( RequestType :: Deposit . to_u8( ) , & deposit_request) ,
1138
+ "0x" . to_string( )
1139
+ ] ) )
1140
+ . unwrap_err( ) ,
1141
+ RequestsError :: EmptyRequest ( 1 )
1142
+ ) ) ;
1143
+ }
1144
+ }
0 commit comments