From 41f9de556f4a49c8d1fbc1bdfd73e7d71cd4492e Mon Sep 17 00:00:00 2001 From: ccamel Date: Sun, 31 Mar 2024 19:25:27 +0200 Subject: [PATCH] refactor(law-stone)!: return a prolog error when law is broken --- contracts/okp4-law-stone/src/contract.rs | 74 +++++++++++++++++------ contracts/okp4-law-stone/src/helper.rs | 11 ++-- packages/okp4-logic-bindings/src/query.rs | 14 +++++ 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/contracts/okp4-law-stone/src/contract.rs b/contracts/okp4-law-stone/src/contract.rs index 3e09583e..bd23d0ed 100644 --- a/contracts/okp4-law-stone/src/contract.rs +++ b/contracts/okp4-law-stone/src/contract.rs @@ -119,9 +119,9 @@ pub mod execute { } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps<'_, LogicCustomQuery>, _env: Env, msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps<'_, LogicCustomQuery>, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Ask { query } => to_json_binary(&query::ask(deps, query)?), + QueryMsg::Ask { query } => to_json_binary(&query::ask(deps, env, query)?), QueryMsg::Program => to_json_binary(&query::program(deps)?), QueryMsg::ProgramCode => to_json_binary(&query::program_code(deps)?), } @@ -135,6 +135,8 @@ pub mod query { use cosmwasm_std::QueryRequest; use okp4_logic_bindings::{Answer, AskResponse}; + const ERR_STONE_BROKEN: &str = "system_error(broken_law_stone)"; + pub fn program(deps: Deps<'_, LogicCustomQuery>) -> StdResult { let program = PROGRAM.load(deps.storage)?.into(); Ok(program) @@ -152,10 +154,21 @@ pub mod query { ) } - pub fn ask(deps: Deps<'_, LogicCustomQuery>, query: String) -> StdResult { + pub fn ask( + deps: Deps<'_, LogicCustomQuery>, + env: Env, + query: String, + ) -> StdResult { let stone = PROGRAM.load(deps.storage)?; if stone.broken { - return Err(StdError::generic_err("Law is broken")); + return Ok(AskResponse { + height: env.block.height, + answer: Some(Answer::from_error(format!( + "error({},root)", + ERR_STONE_BROKEN + ))), + ..Default::default() + }); } let req: QueryRequest = build_ask_query(stone.law, query)?.into(); @@ -276,7 +289,6 @@ mod tests { }; use okp4_objectarium::msg::PageInfo; use okp4_wasm::uri::CosmwasmUri; - use schemars::_serde_json::json; use std::collections::VecDeque; fn custom_logic_handler_with_dependencies( @@ -443,6 +455,7 @@ mod tests { } fn custom_logic_handler_with_query( + env: &Env, query: String, program: ObjectRef, request: &LogicCustomQuery, @@ -458,7 +471,7 @@ mod tests { query: queryy, } if *queryy == exp_query && *program == exp_program => SystemResult::Ok( to_json_binary(&AskResponse { - height: 1, + height: env.block.height, gas_used: 1000, answer: Some(Answer { has_more: false, @@ -495,8 +508,23 @@ mod tests { "okp41ffzp0xmjhwkltuxcvccl0z9tyfuu7txp5ke0tpkcjpzuq9fcj3pqrteqt3" .to_string(), }, - Some("Foo"), // Variable result - None, // Expected error + Some(AskResponse { + height: 12345, + gas_used: 1000, + answer: Some(Answer { + variables: vec!["Foo".to_string()], + results: vec![okp4_logic_bindings::Result { + substitutions: vec![Substitution { + variable: "Foo".to_string(), + expression: "bar".to_string(), + }], + ..Default::default() + }], + ..Default::default() + }), + ..Default::default() + }), + None, // Expected error ), ( true, // broken @@ -508,8 +536,18 @@ mod tests { "okp41ffzp0xmjhwkltuxcvccl0z9tyfuu7txp5ke0tpkcjpzuq9fcj3pqrteqt3" .to_string(), }, - None, // Variable result - Some(StdError::generic_err("Law is broken")), // Expected error + Some(AskResponse { + height: 12345, + answer: Some(Answer { + results: vec![okp4_logic_bindings::Result { + error: Some("error(system_error(broken_law_stone),root)".to_string()), + ..Default::default() + }], + ..Default::default() + }), + ..Default::default() + }), + None, // Expected error ), ]; @@ -519,9 +557,12 @@ mod tests { case.2.object_id.to_string(), case.2.storage_address.to_string(), )); + let env = mock_env(); + let env_4_closure = env.clone(); let mut deps = mock_dependencies_with_logic_handler(move |request| { let (query, o, s) = p.as_ref(); custom_logic_handler_with_query( + &env_4_closure, query.to_string(), ObjectRef { object_id: o.to_string(), @@ -541,7 +582,7 @@ mod tests { ) .unwrap(); - let res = query(deps.as_ref(), mock_env(), QueryMsg::Ask { query: case.1 }); + let res = query(deps.as_ref(), env, QueryMsg::Ask { query: case.1 }); match res { Ok(result) => { @@ -549,12 +590,7 @@ mod tests { assert!(case.3.is_some()); assert!(result.answer.is_some()); - assert!(result - .answer - .unwrap() - .variables - .contains(&case.3.unwrap().to_string())); - + assert_eq!(result, case.3.unwrap()); assert!(case.4.is_none(), "query doesn't return error") } Err(e) => { @@ -756,8 +792,8 @@ mod tests { match result { Ok(LogicCustomQuery::Ask { program, query }) => { - assert_eq!(program, ""); - assert_eq!(query, "consult('cosmwasm:okp4-objectarium:okp41ffzp0xmjhwkltuxcvccl0z9tyfuu7txp5ke0tpkcjpzuq9fcj3pqrteqt3?query=%7B%22object_data%22%3A%7B%22id%22%3A%221cc6de7672c97db145a3940df2264140ea893c6688fa5ca55b73cb8b68e0574d%22%7D%7D'), test(X).") + assert_eq!(program, ":- consult('cosmwasm:okp4-objectarium:okp41ffzp0xmjhwkltuxcvccl0z9tyfuu7txp5ke0tpkcjpzuq9fcj3pqrteqt3?query=%7B%22object_data%22%3A%7B%22id%22%3A%221cc6de7672c97db145a3940df2264140ea893c6688fa5ca55b73cb8b68e0574d%22%7D%7D')."); + assert_eq!(query, "test(X).") } _ => panic!("Expected Ok(LogicCustomQuery)."), } diff --git a/contracts/okp4-law-stone/src/helper.rs b/contracts/okp4-law-stone/src/helper.rs index 3961aef7..1404fd5e 100644 --- a/contracts/okp4-law-stone/src/helper.rs +++ b/contracts/okp4-law-stone/src/helper.rs @@ -14,13 +14,12 @@ pub fn object_ref_to_uri(object: ObjectRef) -> StdResult { }) } -pub fn get_reply_event_attribute(events: Vec, key: String) -> Option { - return events +pub fn get_reply_event_attribute(events: &[Event], key: &str) -> Option { + events .iter() - .flat_map(|e| e.attributes.clone()) - .filter(|a| a.key == key) - .map(|a| a.value) - .next(); + .flat_map(|e| e.attributes.iter()) + .find(|a| a.key == key) + .map(|a| a.value.clone()) } fn term_as_vec(term: TermValue) -> Result, ContractError> { diff --git a/packages/okp4-logic-bindings/src/query.rs b/packages/okp4-logic-bindings/src/query.rs index 5a3c1f86..f4ea9d4a 100644 --- a/packages/okp4-logic-bindings/src/query.rs +++ b/packages/okp4-logic-bindings/src/query.rs @@ -29,6 +29,20 @@ pub struct Answer { pub results: Vec, } +impl Answer { + /// Create a new Answer with an error message. + pub fn from_error(error: String) -> Self { + Self { + has_more: false, + variables: vec![], + results: vec![Result { + error: Some(error), + substitutions: vec![], + }], + } + } +} + #[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, JsonSchema, Debug)] #[serde(rename_all = "snake_case")] pub struct Result {