Skip to content

Commit 33b8555

Browse files
authored
Add tests for ExecutionRequests decoding errors (#6832)
N/A Cover all error cases for decoding JsonExecutionRequests
1 parent 1781c5a commit 33b8555

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

beacon_node/execution_layer/src/engine_api/json_structures.rs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,3 +991,154 @@ impl TryFrom<JsonClientVersionV1> for ClientVersionV1 {
991991
})
992992
}
993993
}
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

Comments
 (0)