From b6705b85ace29b35bc96054afd65b8e940b47e13 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Wed, 4 Dec 2024 18:38:54 +0700 Subject: [PATCH] Address comments --- backend-rust/src/graphql_api.rs | 174 ++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 52 deletions(-) diff --git a/backend-rust/src/graphql_api.rs b/backend-rust/src/graphql_api.rs index 8ee294a7..72c1aa43 100644 --- a/backend-rust/src/graphql_api.rs +++ b/backend-rust/src/graphql_api.rs @@ -48,6 +48,43 @@ use transaction_metrics::TransactionMetricsQuery; const VERSION: &str = clap::crate_version!(); +struct SchemaName { + type_name: &'static str, + value_name: &'static str, +} + +enum SmartContractSchemaNames { + Event, + InputParameter, +} + +impl SmartContractSchemaNames { + pub const EVENT_SCHEMA_NAME: SchemaName = SchemaName { + type_name: "event", + value_name: "contract log", + }; + pub const INPUT_PARAMETER_SCHEMA_NAME: SchemaName = SchemaName { + type_name: "receive parameter", + value_name: "input parameter of receive function", + }; + + pub fn value(&self) -> &'static str { + match self { + SmartContractSchemaNames::Event => Self::EVENT_SCHEMA_NAME.value_name, + SmartContractSchemaNames::InputParameter => { + Self::INPUT_PARAMETER_SCHEMA_NAME.value_name + } + } + } + + pub fn kind(&self) -> &'static str { + match self { + SmartContractSchemaNames::Event => Self::EVENT_SCHEMA_NAME.type_name, + SmartContractSchemaNames::InputParameter => Self::INPUT_PARAMETER_SCHEMA_NAME.type_name, + } + } +} + #[derive(clap::Args)] pub struct ApiServiceConfig { /// Account(s) that should not be considered in circulation. @@ -3765,16 +3802,15 @@ impl SearchResult { fn decode_value_with_schema( opt_schema: Option<&Type>, - schema_name: &str, value: &[u8], - value_name: &str, + schema_name: SmartContractSchemaNames, ) -> String { let Some(schema) = opt_schema else { // Note: There could be something better displayed than this string if no schema is // available for decoding at the frontend long-term. return format!( "No embedded {} schema in smart contract available for decoding", - schema_name + schema_name.kind() ); }; @@ -3791,7 +3827,9 @@ fn decode_value_with_schema( // contract developer for debugging purposes here. format!( "Failed to deserialize {} with {} schema into string: {:?}", - value_name, schema_name, e + schema_name.value(), + schema_name.kind(), + e ) }) } @@ -3805,8 +3843,8 @@ fn decode_value_with_schema( // contract developer for debugging purposes here. format!( "Failed to deserialize {} with {} schema: {:?}", - value_name, - schema_name, + schema_name.value(), + schema_name.kind(), e.display(true) ) } @@ -4804,7 +4842,7 @@ impl ContractInitialized { connection.edges.push(connection::Edge::new(index.to_string(), hex::encode(log))); }); - // Nice-to-have: pagination info but not used at front-end currently. + // TODO: pagination info but not used at front-end currently (issue#318). Ok(connection) } @@ -4833,24 +4871,33 @@ impl ContractInitialized { .await? .ok_or(ApiError::NotFound)?; - let opt_event_schema = row - .display_schema - .as_ref() - .and_then(|schema| VersionedModuleSchema::new(schema, &None).ok()) - .and_then(|versioned_schema| { - versioned_schema.get_event_schema(&row.contract_name).ok() - }); + // Get the event schema if it exists. + let opt_event_schema = if let Some(event_schema) = row.display_schema.as_ref() { + let versioned_schema = + VersionedModuleSchema::new(event_schema, &None).map_err(|_| { + ApiError::InternalError( + "Database bytes should be a valid VersionedModuleSchema".to_string(), + ) + })?; + + versioned_schema.get_event_schema(&row.contract_name).ok() + } else { + None + }; let mut connection = connection::Connection::new(true, true); for (index, log) in self.contract_logs_raw.iter().enumerate() { - let decoded_log = - decode_value_with_schema(opt_event_schema.as_ref(), "event", log, "contract_log"); + let decoded_log = decode_value_with_schema( + opt_event_schema.as_ref(), + log, + SmartContractSchemaNames::Event, + ); connection.edges.push(connection::Edge::new(index.to_string(), decoded_log)); } - // Nice-to-have: pagination info but not used at front-end currently. + // TODO: pagination info but not used at front-end currently (issue#318). Ok(connection) } @@ -5076,7 +5123,7 @@ impl ContractInterrupted { connection.edges.push(connection::Edge::new(index.to_string(), hex::encode(log))); }); - // Nice-to-have: pagination info but not used at front-end currently. + // TODO: pagination info but not used at front-end currently (issue#318). Ok(connection) } @@ -5105,24 +5152,33 @@ impl ContractInterrupted { .await? .ok_or(ApiError::NotFound)?; - let opt_event_schema = row - .display_schema - .as_ref() - .and_then(|schema| VersionedModuleSchema::new(schema, &None).ok()) - .and_then(|versioned_schema| { - versioned_schema.get_event_schema(&row.contract_name).ok() - }); + // Get the event schema if it exists. + let opt_event_schema = if let Some(event_schema) = row.display_schema.as_ref() { + let versioned_schema = + VersionedModuleSchema::new(event_schema, &None).map_err(|_| { + ApiError::InternalError( + "Database bytes should be a valid VersionedModuleSchema".to_string(), + ) + })?; + + versioned_schema.get_event_schema(&row.contract_name).ok() + } else { + None + }; let mut connection = connection::Connection::new(true, true); for (index, log) in self.contract_logs_raw.iter().enumerate() { - let decoded_log = - decode_value_with_schema(opt_event_schema.as_ref(), "event", log, "contract_log"); + let decoded_log = decode_value_with_schema( + opt_event_schema.as_ref(), + log, + SmartContractSchemaNames::Event, + ); connection.edges.push(connection::Edge::new(index.to_string(), decoded_log)); } - // Nice-to-have: pagination info but not used at front-end currently. + // TODO: pagination info but not used at front-end currently (issue#318). Ok(connection) } @@ -5172,24 +5228,29 @@ impl ContractUpdated { .await? .ok_or(ApiError::NotFound)?; - let opt_receive_param_schema = row - .display_schema - .as_ref() - .and_then(|schema| VersionedModuleSchema::new(schema, &None).ok()) - .and_then(|versioned_schema| { - versioned_schema - .get_receive_param_schema( - &row.contract_name, - ReceiveName::new_unchecked(&self.receive_name).entrypoint_name().into(), + // Get the receive param schema if it exists. + let opt_receive_param_schema = if let Some(event_schema) = row.display_schema.as_ref() { + let versioned_schema = + VersionedModuleSchema::new(event_schema, &None).map_err(|_| { + ApiError::InternalError( + "Database bytes should be a valid VersionedModuleSchema".to_string(), ) - .ok() - }); + })?; + + versioned_schema + .get_receive_param_schema( + &row.contract_name, + ReceiveName::new_unchecked(&self.receive_name).entrypoint_name().into(), + ) + .ok() + } else { + None + }; let decoded_input_parameter = decode_value_with_schema( opt_receive_param_schema.as_ref(), - "receive param", &self.input_parameter, - "input parameter of receive function", + SmartContractSchemaNames::InputParameter, ); Ok(decoded_input_parameter) @@ -5202,7 +5263,7 @@ impl ContractUpdated { connection.edges.push(connection::Edge::new(index.to_string(), hex::encode(log))); }); - // Nice-to-have: pagination info but not used at front-end currently. + // TODO: pagination info but not used at front-end currently (issue#318). Ok(connection) } @@ -5231,24 +5292,33 @@ impl ContractUpdated { .await? .ok_or(ApiError::NotFound)?; - let opt_event_schema = row - .display_schema - .as_ref() - .and_then(|schema| VersionedModuleSchema::new(schema, &None).ok()) - .and_then(|versioned_schema| { - versioned_schema.get_event_schema(&row.contract_name).ok() - }); + // Get the event schema if it exists. + let opt_event_schema = if let Some(event_schema) = row.display_schema.as_ref() { + let versioned_schema = + VersionedModuleSchema::new(event_schema, &None).map_err(|_| { + ApiError::InternalError( + "Database bytes should be a valid VersionedModuleSchema".to_string(), + ) + })?; + + versioned_schema.get_event_schema(&row.contract_name).ok() + } else { + None + }; let mut connection = connection::Connection::new(true, true); for (index, log) in self.contract_logs_raw.iter().enumerate() { - let decoded_log = - decode_value_with_schema(opt_event_schema.as_ref(), "event", log, "contract_log"); + let decoded_log = decode_value_with_schema( + opt_event_schema.as_ref(), + log, + SmartContractSchemaNames::Event, + ); connection.edges.push(connection::Edge::new(index.to_string(), decoded_log)); } - // Nice-to-have: pagination info but not used at front-end currently. + // TODO: pagination info but not used at front-end currently (issue#318). Ok(connection) }