RPC: Improve error messages for decoding errors (#28530)

This commit is contained in:
Justin Starry 2022-10-24 19:19:34 +08:00 committed by GitHub
parent 1fbd818647
commit 322280c5b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 75 additions and 29 deletions

View File

@ -4429,7 +4429,7 @@ where
inc_new_counter_info!("rpc-base58_encoded_tx", 1);
if encoded.len() > MAX_BASE58_SIZE {
return Err(Error::invalid_params(format!(
"encoded {} too large: {} bytes (max: encoded/raw {}/{})",
"base58 encoded {} too large: {} bytes (max: encoded/raw {}/{})",
type_name::<T>(),
encoded.len(),
MAX_BASE58_SIZE,
@ -4438,31 +4438,30 @@ where
}
bs58::decode(encoded)
.into_vec()
.map_err(|e| Error::invalid_params(format!("{:?}", e)))?
.map_err(|e| Error::invalid_params(format!("invalid base58 encoding: {:?}", e)))?
}
TransactionBinaryEncoding::Base64 => {
inc_new_counter_info!("rpc-base64_encoded_tx", 1);
if encoded.len() > MAX_BASE64_SIZE {
return Err(Error::invalid_params(format!(
"encoded {} too large: {} bytes (max: encoded/raw {}/{})",
"base64 encoded {} too large: {} bytes (max: encoded/raw {}/{})",
type_name::<T>(),
encoded.len(),
MAX_BASE64_SIZE,
PACKET_DATA_SIZE,
)));
}
base64::decode(encoded).map_err(|e| Error::invalid_params(format!("{:?}", e)))?
base64::decode(encoded)
.map_err(|e| Error::invalid_params(format!("invalid base64 encoding: {:?}", e)))?
}
};
if wire_output.len() > PACKET_DATA_SIZE {
let err = format!(
"encoded {} too large: {} bytes (max: {} bytes)",
return Err(Error::invalid_params(format!(
"decoded {} too large: {} bytes (max: {} bytes)",
type_name::<T>(),
wire_output.len(),
PACKET_DATA_SIZE
);
info!("{}", err);
return Err(Error::invalid_params(&err));
)));
}
bincode::options()
.with_limit(PACKET_DATA_SIZE as u64)
@ -4470,8 +4469,11 @@ where
.allow_trailing_bytes()
.deserialize_from(&wire_output[..])
.map_err(|err| {
info!("deserialize error: {}", err);
Error::invalid_params(&err.to_string())
Error::invalid_params(format!(
"failed to deserialize {}: {}",
type_name::<T>(),
&err.to_string()
))
})
.map(|output| (wire_output, output))
}
@ -8387,45 +8389,89 @@ pub mod tests {
// +2 because +1 still fits in base64 encoded worst-case
let too_big = PACKET_DATA_SIZE + 2;
let tx_ser = vec![0xffu8; too_big];
let tx58 = bs58::encode(&tx_ser).into_string();
let tx58_len = tx58.len();
let expect58 = Error::invalid_params(format!(
"encoded solana_sdk::transaction::Transaction too large: {} bytes (max: encoded/raw {}/{})",
tx58_len, MAX_BASE58_SIZE, PACKET_DATA_SIZE,
));
assert_eq!(
decode_and_deserialize::<Transaction>(tx58, TransactionBinaryEncoding::Base58)
.unwrap_err(),
expect58
);
Error::invalid_params(format!(
"base58 encoded solana_sdk::transaction::Transaction too large: {} bytes (max: encoded/raw {}/{})",
tx58_len, MAX_BASE58_SIZE, PACKET_DATA_SIZE,
)
));
let tx64 = base64::encode(&tx_ser);
let tx64_len = tx64.len();
let expect64 = Error::invalid_params(format!(
"encoded solana_sdk::transaction::Transaction too large: {} bytes (max: encoded/raw {}/{})",
tx64_len, MAX_BASE64_SIZE, PACKET_DATA_SIZE,
));
assert_eq!(
decode_and_deserialize::<Transaction>(tx64, TransactionBinaryEncoding::Base64)
.unwrap_err(),
expect64
);
Error::invalid_params(format!(
"base64 encoded solana_sdk::transaction::Transaction too large: {} bytes (max: encoded/raw {}/{})",
tx64_len, MAX_BASE64_SIZE, PACKET_DATA_SIZE,
)
));
let too_big = PACKET_DATA_SIZE + 1;
let tx_ser = vec![0x00u8; too_big];
let tx58 = bs58::encode(&tx_ser).into_string();
let expect = Error::invalid_params(format!(
"encoded solana_sdk::transaction::Transaction too large: {} bytes (max: {} bytes)",
too_big, PACKET_DATA_SIZE
));
assert_eq!(
decode_and_deserialize::<Transaction>(tx58, TransactionBinaryEncoding::Base58)
.unwrap_err(),
expect
Error::invalid_params(format!(
"decoded solana_sdk::transaction::Transaction too large: {} bytes (max: {} bytes)",
too_big, PACKET_DATA_SIZE
))
);
let tx64 = base64::encode(&tx_ser);
assert_eq!(
decode_and_deserialize::<Transaction>(tx64, TransactionBinaryEncoding::Base64)
.unwrap_err(),
expect
Error::invalid_params(format!(
"decoded solana_sdk::transaction::Transaction too large: {} bytes (max: {} bytes)",
too_big, PACKET_DATA_SIZE
))
);
let tx_ser = vec![0xffu8; PACKET_DATA_SIZE - 2];
let mut tx64 = base64::encode(&tx_ser);
assert_eq!(
decode_and_deserialize::<Transaction>(tx64.clone(), TransactionBinaryEncoding::Base64)
.unwrap_err(),
Error::invalid_params(
"failed to deserialize solana_sdk::transaction::Transaction: invalid value: \
continue signal on byte-three, expected a terminal signal on or before byte-three"
.to_string()
)
);
tx64.push('!');
assert_eq!(
decode_and_deserialize::<Transaction>(tx64, TransactionBinaryEncoding::Base64)
.unwrap_err(),
Error::invalid_params("invalid base64 encoding: InvalidByte(1640, 33)".to_string())
);
let mut tx58 = bs58::encode(&tx_ser).into_string();
assert_eq!(
decode_and_deserialize::<Transaction>(tx58.clone(), TransactionBinaryEncoding::Base58)
.unwrap_err(),
Error::invalid_params(
"failed to deserialize solana_sdk::transaction::Transaction: invalid value: \
continue signal on byte-three, expected a terminal signal on or before byte-three"
.to_string()
)
);
tx58.push('!');
assert_eq!(
decode_and_deserialize::<Transaction>(tx58, TransactionBinaryEncoding::Base58)
.unwrap_err(),
Error::invalid_params(
"invalid base58 encoding: InvalidCharacter { character: '!', index: 1680 }"
.to_string(),
)
);
}