From b3904d80e6c8e992e95cebb0ac48fa0face6ee62 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 2 Dec 2021 04:19:15 +0000 Subject: [PATCH] Add missing InstructionError::IllegalOwner conversion (backport #21524) (#21548) * Add missing InstructionError::IllegalOwner conversion (#21524) * Add missing InstructionError code * Add test that will fail on missing conversion * Move enum-iterator to dev-only (cherry picked from commit 0fc1c2e1fb599a68f8c79e080a4a9d6f08c84edf) # Conflicts: # Cargo.lock * Fix conflict Co-authored-by: Tyera Eulberg Co-authored-by: Tyera Eulberg --- 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 c40aa14307..2652cf8eb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5676,6 +5676,7 @@ version = "1.8.7" dependencies = [ "bincode", "bs58 0.3.1", + "enum-iterator", "prost", "serde", "serde_derive", diff --git a/storage-proto/Cargo.toml b/storage-proto/Cargo.toml index 7796c1e406..854a2bbcfb 100644 --- a/storage-proto/Cargo.toml +++ b/storage-proto/Cargo.toml @@ -19,6 +19,9 @@ solana-account-decoder = { path = "../account-decoder", version = "=1.8.7" } solana-sdk = { path = "../sdk", version = "=1.8.7" } solana-transaction-status = { path = "../transaction-status", version = "=1.8.7" } +[dev-dependencies] +enum-iterator = "0.6.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 27b43dd1ae..049d611306 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"), }; @@ -848,7 +849,7 @@ impl TryFrom for Vec { #[cfg(test)] mod test { - use super::*; + use {super::*, enum_iterator::IntoEnumIterator}; #[test] fn test_reward_type_encode() { @@ -1413,4 +1414,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()); + } + } + } + } + } }