From 0fc1c2e1fb599a68f8c79e080a4a9d6f08c84edf Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 1 Dec 2021 16:28:50 -0700 Subject: [PATCH] Add missing InstructionError::IllegalOwner conversion (#21524) * Add missing InstructionError code * Add test that will fail on missing conversion * Move enum-iterator to dev-only --- Cargo.lock | 1 + storage-proto/Cargo.toml | 3 ++ storage-proto/build.rs | 8 ++++++ storage-proto/src/convert.rs | 54 +++++++++++++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index cb387e1595..e8b18316bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5758,6 +5758,7 @@ version = "1.9.0" dependencies = [ "bincode", "bs58 0.4.0", + "enum-iterator", "prost", "serde", "solana-account-decoder", diff --git a/storage-proto/Cargo.toml b/storage-proto/Cargo.toml index b13a2ad351..6f25039959 100644 --- a/storage-proto/Cargo.toml +++ b/storage-proto/Cargo.toml @@ -18,6 +18,9 @@ solana-account-decoder = { path = "../account-decoder", version = "=1.9.0" } solana-sdk = { path = "../sdk", version = "=1.9.0" } solana-transaction-status = { path = "../transaction-status", version = "=1.9.0" } +[dev-dependencies] +enum-iterator = "0.7.0" + [lib] crate-type = ["lib"] name = "solana_storage_proto" diff --git a/storage-proto/build.rs b/storage-proto/build.rs index dd64c828d8..174b33aeaf 100644 --- a/storage-proto/build.rs +++ b/storage-proto/build.rs @@ -12,5 +12,13 @@ fn main() -> Result<(), std::io::Error> { .build_client(true) .build_server(false) .format(true) + .type_attribute( + "TransactionErrorType", + "#[cfg_attr(test, derive(enum_iterator::IntoEnumIterator))]", + ) + .type_attribute( + "InstructionErrorType", + "#[cfg_attr(test, derive(enum_iterator::IntoEnumIterator))]", + ) .compile(&protos, &[proto_base_path]) } diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index 408877d661..593db5b2c4 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -523,6 +523,7 @@ impl TryFrom for TransactionError { 46 => InstructionError::InvalidAccountOwner, 47 => InstructionError::ArithmeticOverflow, 48 => InstructionError::UnsupportedSysvar, + 49 => InstructionError::IllegalOwner, _ => return Err("Invalid InstructionError"), }; @@ -852,7 +853,7 @@ impl TryFrom for Vec { #[cfg(test)] mod test { - use super::*; + use {super::*, enum_iterator::IntoEnumIterator}; #[test] fn test_reward_type_encode() { @@ -1449,4 +1450,55 @@ mod test { tx_by_addr_transaction_error.try_into().unwrap() ); } + + #[test] + fn test_error_enums() { + let ix_index = 1; + let custom_error = 42; + for error in tx_by_addr::TransactionErrorType::into_enum_iter() { + if error != tx_by_addr::TransactionErrorType::InstructionError { + let tx_by_addr_error = tx_by_addr::TransactionError { + transaction_error: error as i32, + instruction_error: None, + }; + let transaction_error: TransactionError = tx_by_addr_error + .clone() + .try_into() + .unwrap_or_else(|_| panic!("{:?} conversion implemented?", error)); + assert_eq!(tx_by_addr_error, transaction_error.into()); + } else { + for ix_error in tx_by_addr::InstructionErrorType::into_enum_iter() { + if ix_error != tx_by_addr::InstructionErrorType::Custom { + let tx_by_addr_error = tx_by_addr::TransactionError { + transaction_error: error as i32, + instruction_error: Some(tx_by_addr::InstructionError { + index: ix_index, + error: ix_error as i32, + custom: None, + }), + }; + let transaction_error: TransactionError = tx_by_addr_error + .clone() + .try_into() + .unwrap_or_else(|_| panic!("{:?} conversion implemented?", ix_error)); + assert_eq!(tx_by_addr_error, transaction_error.into()); + } else { + let tx_by_addr_error = tx_by_addr::TransactionError { + transaction_error: error as i32, + instruction_error: Some(tx_by_addr::InstructionError { + index: ix_index, + error: ix_error as i32, + custom: Some(tx_by_addr::CustomError { + custom: custom_error, + }), + }), + }; + let transaction_error: TransactionError = + tx_by_addr_error.clone().try_into().unwrap(); + assert_eq!(tx_by_addr_error, transaction_error.into()); + } + } + } + } + } }