diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index a024f84e475a60..11838cf1bc5f47 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -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::(), 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::(), 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::(), 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::(), + &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::(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::(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::(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::(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::(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::(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::(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::(tx58, TransactionBinaryEncoding::Base58) + .unwrap_err(), + Error::invalid_params( + "invalid base58 encoding: InvalidCharacter { character: '!', index: 1680 }" + .to_string(), + ) ); }