From 0abe17b86a71055c9873504569612dfb4bb39479 Mon Sep 17 00:00:00 2001 From: bragaz Date: Mon, 15 Mar 2021 17:49:49 +0100 Subject: [PATCH 1/5] Wrapped custom desmos queries to match the go desmos app fixed tests cleaned imports rebuild schemas put tests inside contract file split custo queries from query types --- contracts/filter-posts/examples/schema.rs | 9 +- contracts/filter-posts/schema/query_msg.json | 11 ++ contracts/filter-posts/src/contract.rs | 164 +++++++++++++++++- contracts/filter-posts/src/contract_test.rs | 139 --------------- contracts/filter-posts/src/lib.rs | 3 - contracts/filter-posts/src/mock.rs | 48 +++-- contracts/filter-posts/src/msg.rs | 3 + .../filter-posts/tests/filter_posts.wasm | Bin 184747 -> 187437 bytes contracts/filter-posts/tests/integration.rs | 8 +- packages/desmos/examples/schema.rs | 9 +- packages/desmos/src/custom_query.rs | 57 +++--- packages/desmos/src/lib.rs | 1 + packages/desmos/src/query_types.rs | 43 +++++ packages/desmos/src/types.rs | 2 +- 14 files changed, 283 insertions(+), 214 deletions(-) delete mode 100644 contracts/filter-posts/src/contract_test.rs create mode 100644 packages/desmos/src/query_types.rs diff --git a/contracts/filter-posts/examples/schema.rs b/contracts/filter-posts/examples/schema.rs index 269fd4f0..a54964c2 100644 --- a/contracts/filter-posts/examples/schema.rs +++ b/contracts/filter-posts/examples/schema.rs @@ -1,10 +1,11 @@ -use std::env::current_dir; -use std::fs::create_dir_all; +use std::{env::current_dir, fs::create_dir_all}; use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; -use filter_posts::msg::{HandleMsg, InitMsg, QueryMsg}; -use filter_posts::state::State; +use filter_posts::{ + msg::{HandleMsg, InitMsg, QueryMsg}, + state::State, +}; fn main() { let mut out_dir = current_dir().unwrap(); diff --git a/contracts/filter-posts/schema/query_msg.json b/contracts/filter-posts/schema/query_msg.json index 7d3af39e..3df7695a 100644 --- a/contracts/filter-posts/schema/query_msg.json +++ b/contracts/filter-posts/schema/query_msg.json @@ -23,6 +23,17 @@ } } } + }, + { + "type": "object", + "required": [ + "posts" + ], + "properties": { + "posts": { + "type": "object" + } + } } ] } diff --git a/contracts/filter-posts/src/contract.rs b/contracts/filter-posts/src/contract.rs index afdef750..ad5e5feb 100644 --- a/contracts/filter-posts/src/contract.rs +++ b/contracts/filter-posts/src/contract.rs @@ -1,13 +1,17 @@ +use crate::{ + error::ContractError, + msg::{HandleMsg, InitMsg, QueryMsg}, + state::{state_read, state_store, State}, +}; use cosmwasm_std::{ attr, to_binary, Binary, Deps, DepsMut, Env, HandleResponse, InitResponse, MessageInfo, StdResult, }; - -use crate::error::ContractError; -use crate::msg::{HandleMsg, InitMsg, QueryMsg}; -use crate::state::{state_read, state_store, State}; -use desmos::custom_query::{query_post_reports, query_posts, PostsResponse}; -use desmos::types::Post; +use desmos::{ + custom_query::{query_post_reports, query_posts}, + query_types::PostsResponse, + types::Post, +}; // Note, you can use StdResult in some functions where you do not // make use of the custom errors @@ -69,6 +73,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::GetFilteredPosts { reports_limit } => { to_binary(&query_filtered_posts(deps, reports_limit)?) } + QueryMsg::Posts {} => to_binary(&query_posts(&deps.querier)?), } } @@ -76,6 +81,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { pub fn is_under_reports_limit(deps: Deps, post: &Post, reports_limit: u16) -> bool { let reports_len = query_post_reports(&deps.querier, post.post_id.clone()) .unwrap() + .reports .len() as u16; reports_len < reports_limit } @@ -84,6 +90,7 @@ pub fn is_under_reports_limit(deps: Deps, post: &Post, reports_limit: u16) -> bo pub fn query_filtered_posts(deps: Deps, reports_limit: u16) -> StdResult { let posts = query_posts(&deps.querier)?; let filtered_posts = posts + .posts .into_iter() .filter(|post| is_under_reports_limit(deps, post, reports_limit)) .collect::>(); @@ -91,3 +98,148 @@ pub fn query_filtered_posts(deps: Deps, reports_limit: u16) -> StdResult {} + _ => panic!("expected unregistered error"), + } + } + + #[test] + fn is_under_reports_limit_checks_correctly() { + let deps = mock_dependencies_with_custom_querier(&[]); + let post = Post { + post_id: "id123".to_string(), + parent_id: "id345".to_string(), + message: "message".to_string(), + created: "date-time".to_string(), + last_edited: "date-time".to_string(), + allows_comments: false, + subspace: "subspace".to_string(), + optional_data: vec![], + attachments: vec![], + poll_data: PollData { + question: "".to_string(), + provided_answers: vec![], + end_date: "".to_string(), + allows_multiple_answers: false, + allows_answer_edits: false, + }, + creator: "default_creator".to_string(), + }; + + // post is under the report limit + let res = is_under_reports_limit(deps.as_ref(), &post, 5); + assert_eq!(res, true); + + // post is over the report limit + let res = is_under_reports_limit(deps.as_ref(), &post, 1); + assert_eq!(res, false) + } + + #[test] + fn query_filtered_posts_filter_correctly() { + let mut deps = mock_dependencies_with_custom_querier(&[]); + let sender_addr = HumanAddr::from("addr0001"); + let info = mock_info(&sender_addr, &[]); + + setup_test(deps.as_mut(), mock_env(), info, 5); + + let post = Post { + post_id: "id123".to_string(), + parent_id: "id345".to_string(), + message: "message".to_string(), + created: "date-time".to_string(), + last_edited: "date-time".to_string(), + allows_comments: false, + subspace: "subspace".to_string(), + optional_data: vec![], + attachments: vec![], + poll_data: PollData { + question: "".to_string(), + provided_answers: vec![], + end_date: "".to_string(), + allows_multiple_answers: false, + allows_answer_edits: false, + }, + creator: "default_creator".to_string(), + }; + + let expected = PostsResponse { posts: vec![post] }; + + // post has less reports than the limit + let res = query_filtered_posts(deps.as_ref(), 3).unwrap(); + assert_eq!(res, expected); + + // post has equal reports to the limit + let res = query_filtered_posts(deps.as_ref(), 1).unwrap(); + assert_eq!(res, PostsResponse { posts: vec![] }) + } +} diff --git a/contracts/filter-posts/src/contract_test.rs b/contracts/filter-posts/src/contract_test.rs deleted file mode 100644 index e5fceab3..00000000 --- a/contracts/filter-posts/src/contract_test.rs +++ /dev/null @@ -1,139 +0,0 @@ -use crate::contract::{handle, init, is_under_reports_limit, query_filtered_posts}; -use crate::error::ContractError; -use crate::mock::mock_dependencies_with_custom_querier; -use crate::msg::{HandleMsg, InitMsg}; -use crate::state::state_read; -use cosmwasm_std::testing::{mock_env, mock_info}; -use cosmwasm_std::{attr, DepsMut, Env, HandleResponse, HumanAddr, MessageInfo}; -use desmos::custom_query::PostsResponse; -use desmos::types::{PollData, Post}; - -fn setup_test(deps: DepsMut, env: Env, info: MessageInfo, default_reports_limit: u16) { - let init_msg = InitMsg { - reports_limit: default_reports_limit, - }; - init(deps, env, info, init_msg).unwrap(); -} - -#[test] -fn test_init() { - let mut deps = mock_dependencies_with_custom_querier(&[]); - - let sender_addr = HumanAddr::from("addr0001"); - let info = mock_info(&sender_addr, &[]); - - let init_msg = InitMsg { reports_limit: 5 }; - - let res = init(deps.as_mut(), mock_env(), info, init_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - let exp_log = vec![attr("action", "set_default_reports_limit")]; - - assert_eq!(res.attributes, exp_log); - - // make sure that the state is set - let state = state_read(&deps.storage).load().unwrap(); - assert_eq!(5, state.default_reports_limit) -} - -#[test] -fn test_handle() { - let mut deps = mock_dependencies_with_custom_querier(&[]); - let editor_addr = HumanAddr::from("editor"); - let info = mock_info(&editor_addr, &[]); - setup_test(deps.as_mut(), mock_env(), info.clone(), 3); - - let exp_res = HandleResponse { - messages: vec![], - attributes: vec![ - attr("action", "edit_reports_limit"), - attr("editor", info.sender.clone()), - ], - data: None, - }; - - let msg = HandleMsg::EditReportsLimit { reports_limit: 5 }; - let res = handle(deps.as_mut(), mock_env(), info.clone(), msg.clone()); - - // assert it not fails - assert!(res.is_ok()); - - assert_eq!(res.unwrap(), exp_res); - - let res = handle(deps.as_mut(), mock_env(), info.clone(), msg.clone()); - match res.unwrap_err() { - ContractError::EqualsReportLimits { .. } => {} - _ => panic!("expected unregistered error"), - } -} - -#[test] -fn is_under_reports_limit_checks_correctly() { - let deps = mock_dependencies_with_custom_querier(&[]); - let post = Post { - post_id: "id123".to_string(), - parent_id: "id345".to_string(), - message: "message".to_string(), - created: "date-time".to_string(), - last_edited: "date-time".to_string(), - allows_comments: false, - subspace: "subspace".to_string(), - optional_data: vec![], - attachments: vec![], - poll_data: PollData { - question: "".to_string(), - provided_answers: vec![], - end_date: "".to_string(), - allows_multiple_answers: false, - allows_answer_edits: false, - }, - creator: "default_creator".to_string(), - }; - - // post is under the report limit - let res = is_under_reports_limit(deps.as_ref(), &post, 5); - assert_eq!(res, true); - - // post is over the report limit - let res = is_under_reports_limit(deps.as_ref(), &post, 1); - assert_eq!(res, false) -} - -#[test] -fn query_filtered_posts_filter_correctly() { - let mut deps = mock_dependencies_with_custom_querier(&[]); - let sender_addr = HumanAddr::from("addr0001"); - let info = mock_info(&sender_addr, &[]); - - setup_test(deps.as_mut(), mock_env(), info, 5); - - let post = Post { - post_id: "id123".to_string(), - parent_id: "id345".to_string(), - message: "message".to_string(), - created: "date-time".to_string(), - last_edited: "date-time".to_string(), - allows_comments: false, - subspace: "subspace".to_string(), - optional_data: vec![], - attachments: vec![], - poll_data: PollData { - question: "".to_string(), - provided_answers: vec![], - end_date: "".to_string(), - allows_multiple_answers: false, - allows_answer_edits: false, - }, - creator: "default_creator".to_string(), - }; - - let expected = PostsResponse { posts: vec![post] }; - - // post has less reports than the limit - let res = query_filtered_posts(deps.as_ref(), 3).unwrap(); - assert_eq!(res, expected); - - // post has equal reports to the limit - let res = query_filtered_posts(deps.as_ref(), 1).unwrap(); - assert_eq!(res, PostsResponse { posts: vec![] }) -} diff --git a/contracts/filter-posts/src/lib.rs b/contracts/filter-posts/src/lib.rs index 39bd61ee..15acc0ea 100644 --- a/contracts/filter-posts/src/lib.rs +++ b/contracts/filter-posts/src/lib.rs @@ -6,8 +6,5 @@ pub mod state; #[cfg(not(target_arch = "wasm32"))] pub mod mock; -#[cfg(test)] -mod contract_test; - #[cfg(target_arch = "wasm32")] cosmwasm_std::create_entry_points!(contract); diff --git a/contracts/filter-posts/src/mock.rs b/contracts/filter-posts/src/mock.rs index 5be6ecc3..790a0e3d 100644 --- a/contracts/filter-posts/src/mock.rs +++ b/contracts/filter-posts/src/mock.rs @@ -1,15 +1,19 @@ -use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; -use cosmwasm_std::{to_binary, Binary, Coin, ContractResult, HumanAddr, OwnedDeps, SystemResult}; -use desmos::custom_query::{DesmosQuery, PostsResponse, ReportsResponse}; -use desmos::types::{PollData, Post, Report}; +use cosmwasm_std::{ + testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, + to_binary, Binary, Coin, ContractResult, HumanAddr, OwnedDeps, SystemResult, +}; +use desmos::{ + query_types::{DesmosQuery, DesmosQueryWrapper, PostsResponse, ReportsResponse}, + types::{PollData, Post, Report}, +}; /// Replacement for cosmwasm_std::testing::mock_dependencies /// this use our CustomQuerier pub fn mock_dependencies_with_custom_querier( contract_balance: &[Coin], -) -> OwnedDeps> { +) -> OwnedDeps> { let contract_addr = HumanAddr::from(MOCK_CONTRACT_ADDR); - let custom_querier: MockQuerier = + let custom_querier: MockQuerier = MockQuerier::new(&[(&contract_addr, contract_balance)]) .with_custom_handler(|query| SystemResult::Ok(custom_query_execute(&query))); OwnedDeps { @@ -20,8 +24,8 @@ pub fn mock_dependencies_with_custom_querier( } /// custom_query_execute returns mock responses to custom queries -pub fn custom_query_execute(query: &DesmosQuery) -> ContractResult { - let response = match query { +pub fn custom_query_execute(query: &DesmosQueryWrapper) -> ContractResult { + let response = match query.clone().query_data { DesmosQuery::Posts {} => { let post = Post { post_id: "id123".to_string(), @@ -46,7 +50,7 @@ pub fn custom_query_execute(query: &DesmosQuery) -> ContractResult { } DesmosQuery::Reports { post_id } => { let report = Report { - post_id: post_id.to_string(), + post_id, _type: String::from("test"), message: String::from("test"), user: String::from("default_creator"), @@ -63,6 +67,7 @@ pub fn custom_query_execute(query: &DesmosQuery) -> ContractResult { mod tests { use super::*; use cosmwasm_std::{from_binary, QuerierWrapper, QueryRequest}; + use desmos::query_types::{DesmosRoute, PostsResponse}; use desmos::types::Report; #[test] @@ -87,7 +92,11 @@ mod tests { creator: String::from("default_creator"), }; let expected = PostsResponse { posts: vec![post] }; - let bz = custom_query_execute(&DesmosQuery::Posts {}).unwrap(); + let desmos_query_wrapper = DesmosQueryWrapper { + route: DesmosRoute::Posts, + query_data: DesmosQuery::Posts {}, + }; + let bz = custom_query_execute(&desmos_query_wrapper).unwrap(); let response: PostsResponse = from_binary(&bz).unwrap(); assert_eq!(response, expected) } @@ -103,10 +112,14 @@ mod tests { let expected = ReportsResponse { reports: vec![report], }; - let bz = custom_query_execute(&DesmosQuery::Reports { - post_id: "id123".to_string(), - }) - .unwrap(); + let desmos_query_wrapper = DesmosQueryWrapper { + route: DesmosRoute::Posts, + query_data: DesmosQuery::Reports { + post_id: "id123".to_string(), + }, + }; + + let bz = custom_query_execute(&desmos_query_wrapper).unwrap(); let response: ReportsResponse = from_binary(&bz).unwrap(); assert_eq!(response, expected) } @@ -114,8 +127,11 @@ mod tests { #[test] fn custom_querier() { let deps = mock_dependencies_with_custom_querier(&[]); - let req: QueryRequest<_> = DesmosQuery::Reports { - post_id: "id123".to_string(), + let req = DesmosQueryWrapper { + route: DesmosRoute::Reports, + query_data: DesmosQuery::Reports { + post_id: "id123".to_string(), + }, } .into(); let wrapper = QuerierWrapper::new(&deps.querier); diff --git a/contracts/filter-posts/src/msg.rs b/contracts/filter-posts/src/msg.rs index 62b426f8..dbac9af9 100644 --- a/contracts/filter-posts/src/msg.rs +++ b/contracts/filter-posts/src/msg.rs @@ -18,4 +18,7 @@ pub enum HandleMsg { pub enum QueryMsg { /// GetFilteredPosts returns a list of filtered posts where each post has been reported at most (reports_limit - 1) time GetFilteredPosts { reports_limit: u16 }, + + /// + Posts {}, } diff --git a/contracts/filter-posts/tests/filter_posts.wasm b/contracts/filter-posts/tests/filter_posts.wasm index 6c4e89c9cfa5e8b040d89eb2dd08bbf66ef06697..c96eac4038bade3c2601f1c9c94b8b2699c516b5 100644 GIT binary patch delta 53480 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�IYhjr4oX>&dLzs7W`Kc!g^4NPI>_eeaRWj$6jh1BY-_qhe$`^_f@BjQS`E+NNtFDpX#K%=3c< z@TC#zcAvaHsuaQ0Ddk+6sfNbL(PIy4dNnYCa@h_Txe*ZPjkCKD6xjO={J^?`G&?sr z7hBfY*`kK}M~n;+Mz`_H9-$wIE$I#0VsIa`7B^ng-6dcr`nf?};+Of!k3A2p@do(A z)esG8giVwp{=Gs()&dIq@C+GcX|c>$dqSQ6Mf~C8|2N zkpqC|Q`^WpqOxG#PRVmZvu>$WAaqFfRCMdQ-tSGo)X2%5Wyb&B8&a5sgcugx#zS z4KCwc6iO|2R4-)8Y^UpAGMjbHp0r5U4`exw<*CoIniXW@DpGKHwhTHgUY{c~)QEKS zlbjSt*$#a+sDABarxK2hrB!BnWHJM(r$RWIdkJ^x zi{a3X5R9qrYA0tLm!{F?sk!oAT}DRp2Fd-p^O!dj=gB`tEiN!vW7!uvJCH96aS`p> zdAaJ0d^rmU{7SyW={|)MqY)}EGi1JaXzM6L?(>G1)?=XU%!VB{J(+gGp-4g_O(ke9 zeW68(buAO>odle07iJ?hz&sV-WiV?gkKZ^Pr|Hdy%m#klx~U^1Lb#D$cz=qr4n^Lm zUhRuc9*3kgdt2wcIWyQq3B1`#5jyowHje(F$H*Hs)ablz5F(SW3a=t19NLxJT>MTw zY3zYV)WjlrX@>!M+&Jsxuf(#;aHp0fX@4i(8Avi2oql*lp<@k@1WF>Z4H zK&PCC6lQ_#A{=!0OPa+>;<==T@8kr8<=`1HDN!u5BUq*Z6`l@CxQ2pdeutuF5A*QL z-1Q?RvWIw_b-hvBG4|u>dQ10HuY{xc&WQ&<^ErWZy-h&m7Fu4zJI%B_yxLmcA3MpC z>?cUbu~496!w?>rFA0ys@2GD($&OHCvOCN6Vuh;gEPG&!N<*MYhBRQT9AM)}or9c! z>p2+)BzM#Uon_BHM-}`|7mO4WwBs)+;u-r~QNu_nkOV#oz>)*401P+w zxQ4l86&WsACP|lQ(*t3ZeTlZ4F3}FbiDF`F2pH!Myo@a?QtD}!5&yY||`#*kTmYoc(8j3Jh8LZah4j@Rpy-j z492-y>Z`epDIre*_JVMW$f3h%g#G~Wv5$@QlvVVfxvh4GPJ@URE8(I_?1=(8_Q^)U(K)VB5r&H_26MuTqZlq z1BcaFWpZ7ry-*Zqg*z`K%&3qDcO1yh(6ah;lc!=wj1>sIW3i;0%)zee!`!ySvX^`-WxD6gihJ;$_%VJ_C4VZc0~+fS0Y)WTyY$`kD>BVG6i>pH_4=-uMsAN&uztZ&(iH zEY;;`PhFUGYDPbas05ux14L0Tu4pooPeVtP&U@Gx+%x@TNjwdNT^{CQ+!z4WYLhDK zkGq{VQ94~<5|7VAq0W(f>Z;C3H8)Tq4{RN!;WIAqJ^iQN#USEQ(aQq-p%?m%z;ZMv85tmyLD~{UQKpUVqu| z^qus)-OgyB7fPX)cSpbMrx!}0oW0R6jr2k(l=A_WcYrh z=daX=3iQ78S3EDkA1Xw@=3%?WYI<30=g@DY*gASyVdv0qq}T>}!Oa2G{U&-|Z@fd?}WDMZ$DttkxPVGVU_@=%i-E}c#rz*lL z`V0nX76Ews^ef$kA&l5^>2DR?nvik5y2F$kT4N$(2Wlp=aG-p?btW?HWH~W`#)TOW z8(yqFJQ+&gOUiqSTwpgTqxsU>Q*@JWo+7u}P1%cAQ2g$VbV{n=;2Wd_dH@F3-88}#;ltw*ia;NoS z#(+g!I#_;;W@iqOO-yLx5ZN#0JL14#TVD^6k0#k5F#Om*01zG;DsPQ>g-?DgQhiUA zy)wCR;t1TXzRd)?SPO82fSlisC&szVQEdExH^3KoNfiu}gTyOp$}rgzVq)DeS>n@T zSTzijgT-PsVWiB!5X*)`3wTLgI9&E`z9ip_lxfJ=K3wJ&Qctv27-pm^M1r)0_o~xm zPPZ0iHN&DrenKrCcGP;HR<^q2G&w#=OC(--l16WhhPC(8X*joomzWW9d-J8=GeR%@ zmm}mAP4l^Cq%6a*A08?DwK|`eQLW5}M&rzfm(j+bVWVW$D0@N%U7O3(Z!x8KbE5_i zBGz0Z0U~=@Ne*HzCbdPR>NbmqLTf-2$S5EZad=3wBl%#EUyYLe+EF8BSPz6j!~-F4 zW4%uvEw4?D0*|fCXdto3_KcB_`&evjQO}H#!J=sKt>rR2GzKo+lCwOJuh6N8nE(|% zV`Z15_2`HB38`6IRMl80x?9x5v2rM|=drQ!5#Z9fr^~qr$su! z_Y0he`$f*f4JveoEX@1`N+N$=9N=TWGE}34n!rEQgfnD%+SeE}_)~!^J_&S&AwqY3 zbL-+WU|+Wq5}$AFnUw%ru_-LxP#w>bXAjs*3a(@&nHn^x!E7R2Sb2`xV!nxloHhbs zt0^wC@qJKg8}mE-Ad>Ofv+xm{3U%$-a!i=pa_hFB>A1Nypbs$I-1Q!clj*0OV$cqC zl-WU~n>|n#w~p*YXyrhofPlA5qE06+e z*f}y@&X?ANtTZ+49FWKU_tbUgNQzq8ehzx9RKK1hyLV%Yo?V4>aTU1@$qNb75#BxA zP8WlXZ0rjm{)n<@oNB_kP#Y`N^XJN}t`+ueSI+Sk$3tKsjuQJ`AJn^WO+h~w0T8>j z3suZ{u*m1D!t+3kmFmv(WLD5_!ak?w_!iJV?ho@LF2qv%&XZ^Mtql1R<^OB!+QX`< zviLdc!d1A42k`}HT+n;~LcX%dtfMqdsh?#vX&Isd$wMx1A=5JOiK(TcvCy!wMKjsLdA#}0=x9V7VFJTV;yx|?`ux-q=pkxuxQ zMCBgoG@MqS<|ooAhLb15GB^3sCevkyvtE*`W_=o+SL-+>lf3FxA@RQVGwDs08qe@E z+4S3B1PHBG$EL|B)?w zzf2cTwaL^?l9TUOh8nH3f?OF$TmPVHI>itB;;+cRk9I<4hnR;7>S>|MHlF?i@-^Q% zNpPMxo&M!){+qNao{&RRtmlI{w8hzI_;1V2B~?Aed3ofHGv&rDjn* zV6;NMnooB-7lNf%@I5o=H<(s0nt_hDoc}n35@12Uok8gX&d8rwN&D8{m6t)9;en4z z<$qx@^A3wp6bXT^9`yNKR6rA8f)5u^LT4%12pO0e1`t0%D4F&i8jV-}s0SG}@rxcB zM@?Vz2@kd=&T`*ED#qEYwS_bY=tv=zIh((R=qGu65smGBm5+!*}F&*r*RJ6h;LlMT{)2-k>gKcAY}`83jMf+KxA*=I1eN*>Z=Xq*5qiV3^pMLI znty(l9#_BNM`lr_dWmnDP0>}e(H4!zhtx|x&ulD80)F!xokO@I&r^oF%9lKc_Nt-R zWd4qJ^^3}9U!e8Q3sOH%`d%udHZT#pMfgsWVavo(GGun}^M#gdYAV*RNk!ieSVD;-DNb39sQf^XOi6 zJ0F-w1A6UlfiT7rWw5>{Sg-R#haRgp8i>Q^6QhD{olhfrR-VJb85meG&sYP(;RlDl ziAJOQ!wx5_3+Rq$GYBkz@x@{JFODKPq~_Gm{K(tp(_j~R9(>OnjNYS`S1!QfMlJ6` zyoYNqNYaQWTZ>3`!&!)C>|IF~CN!#QAoESt#>8~_x}zx0p`ZQ--@Xvjp9;=iNJ9r! zKo=3*;d1Gw4b*o_28J2*M|%5wof3ymFfPc!`ai|k035T3T#4diUh0CL ztO(tGU}`Q@I5!$8n&!icXl>XvH1}v7Z5GwRcX<(gsNxvq!Nv3>hNm$v(lC%mUZg!B z!AocaNZJxw0P^t?n2h)N;u53kyO&aLG^zWRQg+$)ze8}ND5QUBL-G<9e{1KpA>n=R zk0+-{3}lqA)C@Zhw>RDp(m?)@@1)q6q<>^XI1?(!AJpXW#AOsS>Pvq(5!#PXG4Vdf zp}ByJHC~WmqOaT#+(hhKMn~h@OfNopH?0yDedH2XtUb{LR>_Vk*jY$Dpvu%{Top|f{8p8z&B-e4z|^zK6q(Q>hk|hT z0|vs_?lFo<#`R`#EhSeE6dSHP)~~cMHqCpY$DG8tob^HrS1=7%f8csXPqRWyZ@jwF zw7~aQQxsin;i=V>js|$B`hWJV`mgO<(eqtWG1Z(xJ7T6@%k;a zy=!wjO_{DJN+?_(OhQ&5uR|`5JAkx{wqmKc+4tI3n36Di+Pr!@-Fc7QCp9(Akl|s; zdc@7;8J|_?DYi*;emmU}(!-@G9g%k;C-0z`p~C^ugDZ)kD(IAaZ&q<>mM!r@(W=-? zN}ea@WOBw1%I4p{P8mF4Cxvtwf{5+mg5ZY2-3~XMU*1Ve)os4$KVaU_wZ4OeC zDagn8+{|?}$W%M8hLYmPglkFy0?f$qdUFb%c4y~gn$AK?JZk1&Mu$?cstBs#*^4rQnJo?!J3;>R{;laT640Pad8$S)W zZvgIO!}o(9V#5=FBb8BY5@*B1F7dO#_QIV9Y!_e&a2H9C!*|oP{z08I%q3m zx7|vP*Y3t@e-NM8OQXzb`{Ifl!1(|5fVG>VKe(26IKB&^3AM{aT$Q@Cd(gWU)@(Vs_md~&Gu;jRm z_xUJq=w>jb;T{B)*ne)N=Rn&5{{$Kd>dAvv(Po}+@$cTjplG^p-aAz0&=&O6l&J`E zD_j@YWsblf3S&ug$h-6i$l`a&6IXtVraT3{RA{LK7M_FWc){F#KP5(Kv6>PCII=W5 zJFD28<8^13=I1NQ5T3N3JP~8SP6zu#I7wv;H|@ueZ3V|1pxJ5?R~?|c%97lsZCQf= zV!kcB56^=Gu-k@xcuoz#qLLN=GM=U6EqoQvDFGP8T;>mO4NS4IRs_LuHta%uOb)=J zl@-1N`0{Ej90qLXcMQO?ViuzGYKssF4|@iJjRg3ogLD^Nh~tzxijL|XuPL2v`B;V` ziKo_4N<>C0y988X&*4pVG`N2?U?SiH1$&&hO8omGh=`7GurSn@SPT)GxpOczVXMdhwl8Vn*7IAUeZV@Qx?OwCw$A{qTnn%6VKvr;pYNy zF|ep$@nuwG4?oS~bM#SKNhiMJT}SCoOtHQ@O34vDhiHlmA^L%eOljQb7~1&+KrzkP zpwL;#1(mW*>, + deps: &mut Instance>, env: Env, info: MessageInfo, report_limit: u16, @@ -51,9 +51,9 @@ fn setup_test( #[cfg(not(tarpaulin))] pub fn mock_dependencies_with_custom_querier( contract_balance: &[Coin], -) -> Backend> { +) -> Backend> { let contract_addr = HumanAddr::from(MOCK_CONTRACT_ADDR); - let custom_querier: MockQuerier = + let custom_querier: MockQuerier = MockQuerier::new(&[(&contract_addr, contract_balance)]) .with_custom_handler(|query| SystemResult::Ok(custom_query_execute(query))); diff --git a/packages/desmos/examples/schema.rs b/packages/desmos/examples/schema.rs index f0948a02..6ba90073 100644 --- a/packages/desmos/examples/schema.rs +++ b/packages/desmos/examples/schema.rs @@ -1,10 +1,11 @@ -use std::env::{current_dir, set_current_dir}; -use std::fs::create_dir_all; +use std::{env::current_dir, fs::create_dir_all}; use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; -use desmos::custom_query::{PostsResponse, ReportsResponse}; -use desmos::types::{Attachment, OptionalData, PollAnswer, PollData, Post, Report}; +use desmos::{ + query_types::{PostsResponse, ReportsResponse}, + types::{Attachment, OptionalData, PollAnswer, PollData, Post, Report}, +}; fn main() { let mut out_dir = current_dir().unwrap(); diff --git a/packages/desmos/src/custom_query.rs b/packages/desmos/src/custom_query.rs index 40fc51c0..8ee7f5c5 100644 --- a/packages/desmos/src/custom_query.rs +++ b/packages/desmos/src/custom_query.rs @@ -1,41 +1,24 @@ -use crate::types::{Post, Report}; -use cosmwasm_std::{CustomQuery, QuerierWrapper, QueryRequest, StdResult}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum DesmosQuery { - Posts {}, - Reports { post_id: String }, -} - -impl CustomQuery for DesmosQuery {} - -/// PostsResponse contains a list of posts -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct PostsResponse { - pub posts: Vec, -} - -pub fn query_posts(querier: &QuerierWrapper) -> StdResult> { - let request: QueryRequest = DesmosQuery::Posts {}.into(); - - let res: PostsResponse = querier.custom_query(&request)?; - Ok(res.posts) -} - -/// ReportsResponse contains the list of reports associated with the given post_id -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct ReportsResponse { - pub reports: Vec, +use crate::query_types::{ + DesmosQuery, DesmosQueryWrapper, DesmosRoute, PostsResponse, ReportsResponse, +}; +use cosmwasm_std::{QuerierWrapper, StdResult}; + +pub fn query_posts(querier: &QuerierWrapper) -> StdResult { + let request = DesmosQueryWrapper { + route: DesmosRoute::Posts, + query_data: DesmosQuery::Posts {}, + }; + + let res: PostsResponse = querier.custom_query(&request.into())?; + Ok(res) } -pub fn query_post_reports(querier: &QuerierWrapper, post_id: String) -> StdResult> { - let request: QueryRequest = DesmosQuery::Reports { post_id }.into(); +pub fn query_post_reports(querier: &QuerierWrapper, post_id: String) -> StdResult { + let request = DesmosQueryWrapper { + route: DesmosRoute::Reports, + query_data: DesmosQuery::Reports { post_id }, + }; - let res: ReportsResponse = querier.custom_query(&request)?; - Ok(res.reports) + let res: ReportsResponse = querier.custom_query(&request.into())?; + Ok(res) } diff --git a/packages/desmos/src/lib.rs b/packages/desmos/src/lib.rs index 155114e1..0f210701 100644 --- a/packages/desmos/src/lib.rs +++ b/packages/desmos/src/lib.rs @@ -1,2 +1,3 @@ pub mod custom_query; +pub mod query_types; pub mod types; diff --git a/packages/desmos/src/query_types.rs b/packages/desmos/src/query_types.rs new file mode 100644 index 00000000..f00de1fe --- /dev/null +++ b/packages/desmos/src/query_types.rs @@ -0,0 +1,43 @@ +use crate::types::{Post, Report}; +use cosmwasm_std::CustomQuery; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DesmosRoute { + Posts, + Reports, +} + +/// DesmosQueryWrapper is an override of QueryRequest::Custom to access desmos-specific modules +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct DesmosQueryWrapper { + pub route: DesmosRoute, + pub query_data: DesmosQuery, +} + +/// DesmosQuery represents the available desmos network queries +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DesmosQuery { + Posts {}, + Reports { post_id: String }, +} + +impl CustomQuery for DesmosQueryWrapper {} + +/// PostsResponse contains a list of posts +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct PostsResponse { + pub posts: Vec, +} + +/// ReportsResponse contains the list of reports associated with the given post_id +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct ReportsResponse { + pub reports: Vec, +} diff --git a/packages/desmos/src/types.rs b/packages/desmos/src/types.rs index fd7db266..a9a2cc99 100644 --- a/packages/desmos/src/types.rs +++ b/packages/desmos/src/types.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -/// This file contains all the desmos related types used inside the contract +/// This file contains all the desmos related types used inside desmos' contracts #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] From 52bcd1d4309c061e134803adb9e490c2d9d10a05 Mon Sep 17 00:00:00 2001 From: bragaz Date: Wed, 17 Mar 2021 12:33:50 +0100 Subject: [PATCH 2/5] fixed reports deserialization error --- Importing.md | 62 ------------------ contracts/filter-posts/schema/query_msg.json | 14 +++- contracts/filter-posts/src/contract.rs | 21 +++--- contracts/filter-posts/src/mock.rs | 28 ++++---- contracts/filter-posts/src/msg.rs | 3 - .../filter-posts/tests/filter_posts.wasm | Bin 187437 -> 187218 bytes contracts/filter-posts/tests/integration.rs | 34 ++++++---- packages/desmos/schema/attachment.json | 6 +- packages/desmos/schema/optional_data.json | 2 +- packages/desmos/schema/post.json | 36 ++++++---- packages/desmos/schema/posts_response.json | 36 ++++++---- packages/desmos/schema/report.json | 4 +- packages/desmos/schema/reports_response.json | 4 +- packages/desmos/src/types.rs | 12 ++-- 14 files changed, 120 insertions(+), 142 deletions(-) delete mode 100644 Importing.md diff --git a/Importing.md b/Importing.md deleted file mode 100644 index e367b658..00000000 --- a/Importing.md +++ /dev/null @@ -1,62 +0,0 @@ -# Importing - -In [Publishing](./Publishing.md), we discussed how you can publish your contract to the world. -This looks at the flip-side, how can you use someone else's contract (which is the same -question as how they will use your contract). Let's go through the various stages. - -## Verifying Artifacts - -Before using remote code, you most certainly want to verify it is honest. - -The simplest audit of the repo is to simply check that the artifacts in the repo -are correct. This involves recompiling the claimed source with the claimed builder -and validating that the locally compiled code (hash) matches the code hash that was -uploaded. This will verify that the source code is the correct preimage. Which allows -one to audit the original (Rust) source code, rather than looking at wasm bytecode. - -We have a script to do this automatic verification steps that can -easily be run by many individuals. Please check out -[`cosmwasm-verify`](https://github.com/CosmWasm/cosmwasm-verify/blob/master/README.md) -to see a simple shell script that does all these steps and easily allows you to verify -any uploaded contract. - -## Reviewing - -Once you have done the quick programatic checks, it is good to give at least a quick -look through the code. A glance at `examples/schema.rs` to make sure it is outputing -all relevant structs from `contract.rs`, and also ensure `src/lib.rs` is just the -default wrapper (nothing funny going on there). After this point, we can dive into -the contract code itself. Check the flows for the handle methods, any invariants and -permission checks that should be there, and a reasonable data storage format. - -You can dig into the contract as far as you want, but it is important to make sure there -are no obvious backdoors at least. - -## Decentralized Verification - -It's not very practical to do a deep code review on every dependency you want to use, -which is a big reason for the popularity of code audits in the blockchain world. We trust -some experts review in lieu of doing the work ourselves. But wouldn't it be nice to do this -in a decentralized manner and peer-review each other's contracts? Bringing in deeper domain -knowledge and saving fees. - -Luckily, there is an amazing project called [crev](https://github.com/crev-dev/cargo-crev/blob/master/cargo-crev/README.md) -that provides `A cryptographically verifiable code review system for the cargo (Rust) package manager`. - -I highly recommend that CosmWasm contract developers get set up with this. At minimum, we -can all add a review on a package that programmatically checked out that the json schemas -and wasm bytecode do match the code, and publish our claim, so we don't all rely on some -central server to say it validated this. As we go on, we can add deeper reviews on standard -packages. - -If you want to use `cargo-crev`, please follow their -[getting started guide](https://github.com/crev-dev/cargo-crev/blob/master/cargo-crev/src/doc/getting_started.md) -and once you have made your own *proof repository* with at least one *trust proof*, -please make a PR to the [`cawesome-wasm`]() repo with a link to your repo and -some public name or pseudonym that people know you by. This allows people who trust you -to also reuse your proofs. - -There is a [standard list of proof repos](https://github.com/crev-dev/cargo-crev/wiki/List-of-Proof-Repositories) -with some strong rust developers in there. This may cover dependencies like `serde` and `snafu` -but will not hit any CosmWasm-related modules, so we look to bootstrap a very focused -review community. diff --git a/contracts/filter-posts/schema/query_msg.json b/contracts/filter-posts/schema/query_msg.json index 3df7695a..c691140d 100644 --- a/contracts/filter-posts/schema/query_msg.json +++ b/contracts/filter-posts/schema/query_msg.json @@ -27,11 +27,19 @@ { "type": "object", "required": [ - "posts" + "reports" ], "properties": { - "posts": { - "type": "object" + "reports": { + "type": "object", + "required": [ + "post_id" + ], + "properties": { + "post_id": { + "type": "string" + } + } } } } diff --git a/contracts/filter-posts/src/contract.rs b/contracts/filter-posts/src/contract.rs index ad5e5feb..fc2c0a39 100644 --- a/contracts/filter-posts/src/contract.rs +++ b/contracts/filter-posts/src/contract.rs @@ -73,7 +73,6 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::GetFilteredPosts { reports_limit } => { to_binary(&query_filtered_posts(deps, reports_limit)?) } - QueryMsg::Posts {} => to_binary(&query_posts(&deps.querier)?), } } @@ -177,21 +176,21 @@ mod tests { let deps = mock_dependencies_with_custom_querier(&[]); let post = Post { post_id: "id123".to_string(), - parent_id: "id345".to_string(), + parent_id: Some("id345".to_string()), message: "message".to_string(), created: "date-time".to_string(), last_edited: "date-time".to_string(), allows_comments: false, subspace: "subspace".to_string(), - optional_data: vec![], - attachments: vec![], - poll_data: PollData { + optional_data: Some(vec![]), + attachments: Some(vec![]), + poll_data: Some(PollData { question: "".to_string(), provided_answers: vec![], end_date: "".to_string(), allows_multiple_answers: false, allows_answer_edits: false, - }, + }), creator: "default_creator".to_string(), }; @@ -214,21 +213,21 @@ mod tests { let post = Post { post_id: "id123".to_string(), - parent_id: "id345".to_string(), + parent_id: Some("id345".to_string()), message: "message".to_string(), created: "date-time".to_string(), last_edited: "date-time".to_string(), allows_comments: false, subspace: "subspace".to_string(), - optional_data: vec![], - attachments: vec![], - poll_data: PollData { + optional_data: Some(vec![]), + attachments: Some(vec![]), + poll_data: Some(PollData { question: "".to_string(), provided_answers: vec![], end_date: "".to_string(), allows_multiple_answers: false, allows_answer_edits: false, - }, + }), creator: "default_creator".to_string(), }; diff --git a/contracts/filter-posts/src/mock.rs b/contracts/filter-posts/src/mock.rs index 790a0e3d..e8e512ee 100644 --- a/contracts/filter-posts/src/mock.rs +++ b/contracts/filter-posts/src/mock.rs @@ -29,21 +29,21 @@ pub fn custom_query_execute(query: &DesmosQueryWrapper) -> ContractResult { let post = Post { post_id: "id123".to_string(), - parent_id: String::from("id345"), + parent_id: Some(String::from("id345")), message: String::from("message"), created: String::from("date-time"), last_edited: String::from("date-time"), allows_comments: false, subspace: String::from("subspace"), - optional_data: vec![], - attachments: vec![], - poll_data: PollData { + optional_data: Some(vec![]), + attachments: Some(vec![]), + poll_data: Some(PollData { question: "".to_string(), provided_answers: vec![], end_date: "".to_string(), allows_multiple_answers: false, allows_answer_edits: false, - }, + }), creator: String::from("default_creator"), }; to_binary(&PostsResponse { posts: vec![post] }) @@ -51,7 +51,7 @@ pub fn custom_query_execute(query: &DesmosQueryWrapper) -> ContractResult { let report = Report { post_id, - _type: String::from("test"), + kind: String::from("test"), message: String::from("test"), user: String::from("default_creator"), }; @@ -66,7 +66,7 @@ pub fn custom_query_execute(query: &DesmosQueryWrapper) -> ContractResult#j33hf{I%2Ote%{ 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

{4gUx$J> zxPJj=Nl32{R{`$k6k0JmjbDLC-0mhH0n6`v?6^nNvH9O(ZF^5Qnh&%W-|aQGdvt&6 zGX-9a&3y}Y^)2{)roiiC@jdL+{l{a)d_%;){4>?=iFh)Of}uObt?N+(YbB}1lk-wLSJ1ns^r(&M z5jXgZ8id-E;GlFIMu8MpiHAKA&*#PNjAv9^;TcB85vNSQ`584Lx|fRM_xAzxz3$JS zQA?o!PkdGlR=eCQp2aom``lkW3;y2be*7#rRtg8ZM?Qxs?sGezlQ+wrQ^!G1CJm}6 z6SqV12jr;ly4^oMhs$91xkb+_{K~95^?B6a=brt%niZd%5>a7eGZwc1KmNR`FBNSA z^FXsVU+i@MfEPz@qh}=7%@;-OdwvLb%k3xek-&WH?fhPAf9QP=zP#=N5HK-gl_npKViRVXv#bKUWP?w<(K}N_4d3 z0gQ}8as8cNs_DlgYJ(MK^h4oJrA8xnK2|T(^)ti1Gyc9i{}+&g zlihJ!Ref&==5AHvdO^_Oey|mFH5g|d42(B>FX3UpaR4;&Hv-W%X4x&wcV`5ZSlc@(dInzeAl|IG>=e3#6h9 z6B+JZdsMyq@(xvmPT$?3TB^uzefdvl-A(Rbc$b)XT^%XU-44GB3^%m+t3Z#VU=@(x6s;cB69}T=pT*QX3o!oa{Q7tVp!UmvH zjxYo38?bW7fky5a4t$!DDu`>Wq2EWnswN$Hhz3x~y|1eIQ-D}*%_iY%X}44CY=DIP z`J`fQydCZR()*56Zh&^qF7-{o_Si1fs40RuH$FxDo`+3-Tm!rYE%mX)tF%qR1;O)R6^|^<*Yt^PI8eU_`YpTFkRyb=b1Au8 z*JP#%DVY&S97W?EpQdJ)24jYr%ij=cKI)CW)O`6H>S9dp!#5z<*SL*u;@b6j?&)u; z8Je0~-0g2-G1s_nzA4il@fJi`w|nkes=0zeZ*1~?2cyEb4a(1Nlk?WUrG_*Jaq$K& z9~qYjM{~mfxVSJ?h>9P-<)ec4EVJb7w;{y8<=*(5_ z7D(KNhc!SFGDx>u^Ny-N5io(KG`pi-g{}v|z-%Sio6X=5ugmpoABP~ZEdGA?DDW5Z zrNN%xsgV2FI|z?-yT5x!$G#G+`aJsRCeuARaRO2o_#M|M3M_CC?Z@) zQ67>qrj>zy*7U-0EHl&4Y{pE15^Y?Sl~P(^`7YgRXy~lWv1YQz>a!V5H0`lg51q<1 zl~FI8b( z=)I*ECs(V^=64E@ug3Z+<$`K8qNm^@!Wf}l<~;+b(F6ezM=(=Wt$Ir^36EUV7(mSR z8Zmt}Uarx2Nv%=iMXK^Z7S?E4S`$D^8tesn2My2}x-qEfDpLSVB~~$rRoDAvlv2L+ z`-?GyFWaRVK5V)qW_+d^N?A?a@TD=!8H!8mBFqRouXiUZy{*1u~G!+P|zl*iYO2&HYZ&eS69L;_G_%Yd-&2=n{`CB$9$hZqQvg_ z&m-z~ZL~m$O8C9N8&87;%6NlK(Y_d$0;fSMxEXZ&3_buU2mg_#02117bkV_#p;hv7 z`SXyA27!iDkON#geMXo*vCN%<7AlbQVe3(Kf7)-8Aar2PV}Lr|hKK#2N`R1WegLC@ zam46_14C+h*Q+Z>N>8{Cp*`S%%Q<8w;KcFG64bFRQ*|1^Lth%m;?fOFKl zBU(r=qEE=-Eyuvme7d|rEpz%Q6Sa@i&nEn~O5Ki#qSrq9+0vl;UDVI{2K6L#3^R|b zQJNy;?nOLY?uNch7-WoRJPF;u{$V*X4Q^_~NNtr@*@zyfb$d8~MbDQ+7je-dazV`@ zUpVN*0z>n0iI;j%7)@i-30EyoM zsKb5dAVB$XAn~?F)kUhomPqyUQhi0+>U>n=@RsWDgeQv(REGgG_!`6dK}zvG27Cpr z)A;SHGrjwq`nl36SeI7yqE?g+zm!MY2Rbyk6)n}?I;r$Ea780F^#xp+21kL@aw-FUMiD#s6a@46{Lm?I z(#1UQl)5pX*{MAxnjQQ6DfN?rl-KwZ!VT`Xho4pts%R}`Z`y*6;;qFW;O+PG=V#Q{ zs9)Elq7+2@ch9Q#)LbrTh6Xs>KGLkp-73f4a31Fo!oyYktiD3>_5}p^%3=CNCwG`+ zok@Pw$+Dp|u18L?=Zf%%YxRv2)(VVjZlnG$8J_vU?nVi-DN!_M4bvjqUuMpj${>w*+dUTo#POvw@ zoGKpGa%nn*ME1K$VygYsP5r|c%9_y&(q8MPE-JQFXkSMwAQR8#-5#yDZt~EQ%eDzK zKEi$vkML4F9|@r%6JOCIp4k8pypqsef|nA)Kvt65!;3=c$yTiZiD0WhFi*bKOVdC= z|M5~kB*(opI=NZs(x~B66&zKI;g1EeTKgdA-+Opc7&Sy{&5YX$v1+#gmX&;8J1RGY zxI)A_Z3_E_Q*ol4)8nS0#vATKFc{I5O`RdiISmKKv}vd%S9vwvuqLLZ z;TN$K#_6$vm(krqs&3USS~%T0(9mtbSOwdp@QyAN7a00nmo`Id@i#d1`mTY_68K2h zHVrjL7i_pRj*H83)JT5QS`*GP0 z*$+icvsem}tny%i(_;6p3mO9jxU552izTP`E%}UlQ!pp?%c@`wPLfvfho+_db_$N5 z*;-F5UgGM8no`L6@d3^@miR4@cFxkx4_Mr)GFqyn04*q1j_mzu&RofF!_MsfL zoij7h<5tegqygi10GV#+L33R+M0k!{;pHSzo#ltTt`pVSEm575AzWBs)&L5(?_;Pn z(EvXI7r-pH8_q4icFdG*mjE!|E^f@EuFy+_Uqxy08uG##K=}+^Ni!y9rCYoA14{dO z#8uQyZLtflqGc+)2A4$j7nkKyTBw;M@6M$KXfS>ljl*MGhS70C zcH^HZ4_WUBTJOdK{~AfJe zqF!Cj18SZjZUHlt;PM%+aCE*CeBUUF>3kB@1`xoQ+(9!`AV1%i_WV)U=`LYKPJHpp zX%Qfn7E7|9Q%2KY0HJxKK_mNl>uAIa&*qtTQ(j7qg5=?bl|i%K;MlC@?|=naRmS;_ z^v-ntZi-766Y)D<<(++{%j#Q@9MS{YENu-2^EV6T16*VQrlU7S_-3&+hC0*JBtd8R z!7(%(<82v(zH<1&7|QCWH$BbGB;!M7;cVm^f2=+*AaLTrg&+`bpv??0J$v}Ru|Q7_ zZyQTpJ7&v6fI`5ZLiWyMV`-3jntRbS(M+mT4|O1d5v7!&~Aw!D%7p7R=zeag;bnrZo{O1#m_1a{^q2)wT~}RRjbE zBM$78B5cpX?tg~gzB;Z(2cdPK5b)oj<7uus#4n7eTj-GD`0FU|3G z((4Y6nNWfF4q;Gm$+NkrFAlXICs8bI*UwzfH$OmGP6yYsjZCC87Egw&ArdKH2{%7L z{rVn|b&r^~hcKz`J}0+Baw$4zmEyPHRp=K*JZ3UofO+ojDKrVmwkfnx?RzahpOmWQ zf&v->5`CipOlB?bDgeYv*jq^Xs);jJf_$5J(MpOnb~Cbyv1?ZW0G0OnLa?*Z^$G+b z)MzzSU;^Z;=er)FHJxPQQL5$P^6=63%#-A4f zh6nkMX>>a|UND;uD5O)KqUV$`h=y2ig;F89?1`iDQSwfS%$Cv`13sap}O6UBkf>6r+qTh}3SeXBm9pO9RzrKwB9 zEU|Tv)!e43&IOyAIvz70AEE^3TcT&dC2a~fm_mC#?Nyb$Z~=~^CVS%o+U)L7VmyHG z$%S49MN4Q#Sa|p^Rt`-snOrhf| zR(@B3uZd|H&Awdy%gg9b-B!p@5DamDP?zL(ez}DqIeh5iFI*Vby_}*{LX&7x;C~KU z>;!t3iONxBCOn_Bm{PI4@|Ye_$9X5yd91SSFi8E*D&zN7(zqnqX3(9-Q9f)3jalsg zcG-=D-s>Jbj(Z&puWGihdxO3WSEY8eP2GC_4?-ZU!vFvP delta 54529 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, + pub tags: Option>, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -39,23 +39,23 @@ pub struct PollData { #[serde(rename_all = "snake_case")] pub struct Post { pub post_id: String, - pub parent_id: String, + pub parent_id: Option, pub message: String, pub created: String, pub last_edited: String, pub allows_comments: bool, pub subspace: String, - pub optional_data: Vec, + pub optional_data: Option>, pub creator: String, - pub attachments: Vec, - pub poll_data: PollData, + pub attachments: Option>, + pub poll_data: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct Report { pub post_id: String, - pub _type: String, + pub kind: String, pub message: String, pub user: String, } From 10342bc03e85eae9397f6089f9ba243171d5f232 Mon Sep 17 00:00:00 2001 From: bragaz Date: Wed, 17 Mar 2021 17:18:32 +0100 Subject: [PATCH 3/5] fixes inside desmos types adjust Developing.md --- Developing.md | 36 ++-------------------- packages/desmos/schema/poll_answer.json | 4 +-- packages/desmos/schema/poll_data.json | 4 +-- packages/desmos/schema/post.json | 4 +-- packages/desmos/schema/posts_response.json | 4 +-- packages/desmos/src/types.rs | 2 +- 6 files changed, 11 insertions(+), 43 deletions(-) diff --git a/Developing.md b/Developing.md index ddd87d2d..8e893722 100644 --- a/Developing.md +++ b/Developing.md @@ -1,14 +1,7 @@ -# Developing - -If you have recently created a contract with this template, you probably could use some -help on how to build and test the contract, as well as prepare it for production. This -file attempts to provide a brief overview, assuming you have installed a recent -version of Rust already (eg. 1.44.1+). - ## Prerequisites Before starting, make sure you have [rustup](https://rustup.rs/) along with a -recent `rustc` and `cargo` version installed. Currently, we are testing on 1.44.1+. +recent `rustc` and `cargo` version installed. Currently, we are testing on `1.48`. And you need to have the `wasm32-unknown-unknown` target installed as well. @@ -22,36 +15,11 @@ rustup target list --installed rustup target add wasm32-unknown-unknown ``` -## Compiling and running tests - -Now that you created your custom contract, make sure you can compile and run it before -making any changes. Go into the repository and do: - -```sh -# this will produce a wasm build in ./target/wasm32-unknown-unknown/release/YOUR_NAME_HERE.wasm -cargo wasm - -# this runs unit tests with helpful backtraces -RUST_BACKTRACE=1 cargo unit-test - -# auto-generate json schema -cargo schema -``` - -### Understanding the tests - -The main code is in `src/contract.rs` and the unit tests there run in pure rust, -which makes them very quick to execute and give nice output on failures, especially -if you do `RUST_BACKTRACE=1 cargo unit-test`. - -We consider testing critical for anything on a blockchain, and recommend to always keep -the tests up to date. - ## Generating JSON Schema While the Wasm calls (`init`, `handle`, `query`) accept JSON, this is not enough information to use it. We need to expose the schema for the expected messages to the -clients. You can generate this schema by calling `cargo schema`, which will output +clients. You can generate this schema by calling `cargo schema` (from within a contract's folder), which will output 4 files in `./schema`, corresponding to the 3 message types the contract accepts, as well as the internal `State`. diff --git a/packages/desmos/schema/poll_answer.json b/packages/desmos/schema/poll_answer.json index 30a3370a..96127769 100644 --- a/packages/desmos/schema/poll_answer.json +++ b/packages/desmos/schema/poll_answer.json @@ -3,11 +3,11 @@ "title": "PollAnswer", "type": "object", "required": [ - "id", + "answer_id", "text" ], "properties": { - "id": { + "answer_id": { "type": "string" }, "text": { diff --git a/packages/desmos/schema/poll_data.json b/packages/desmos/schema/poll_data.json index d46b03fd..1c249f6e 100644 --- a/packages/desmos/schema/poll_data.json +++ b/packages/desmos/schema/poll_data.json @@ -33,11 +33,11 @@ "PollAnswer": { "type": "object", "required": [ - "id", + "answer_id", "text" ], "properties": { - "id": { + "answer_id": { "type": "string" }, "text": { diff --git a/packages/desmos/schema/post.json b/packages/desmos/schema/post.json index 7f8aed6c..5c98442d 100644 --- a/packages/desmos/schema/post.json +++ b/packages/desmos/schema/post.json @@ -112,11 +112,11 @@ "PollAnswer": { "type": "object", "required": [ - "id", + "answer_id", "text" ], "properties": { - "id": { + "answer_id": { "type": "string" }, "text": { diff --git a/packages/desmos/schema/posts_response.json b/packages/desmos/schema/posts_response.json index f625eb10..9ec11ce7 100644 --- a/packages/desmos/schema/posts_response.json +++ b/packages/desmos/schema/posts_response.json @@ -58,11 +58,11 @@ "PollAnswer": { "type": "object", "required": [ - "id", + "answer_id", "text" ], "properties": { - "id": { + "answer_id": { "type": "string" }, "text": { diff --git a/packages/desmos/src/types.rs b/packages/desmos/src/types.rs index 33667d02..573a9db2 100644 --- a/packages/desmos/src/types.rs +++ b/packages/desmos/src/types.rs @@ -21,7 +21,7 @@ pub struct Attachment { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct PollAnswer { - pub id: String, + pub answer_id: String, pub text: String, } From a9e225961a2ade6556bd971b27fe60c8d96214d6 Mon Sep 17 00:00:00 2001 From: bragaz Date: Wed, 17 Mar 2021 17:30:16 +0100 Subject: [PATCH 4/5] v0.1.0 of filter-posts v0.1.0 of desmos package --- contracts/filter-posts/Cargo.toml | 2 +- contracts/filter-posts/schema/query_msg.json | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/contracts/filter-posts/Cargo.toml b/contracts/filter-posts/Cargo.toml index f601551d..10962fd8 100644 --- a/contracts/filter-posts/Cargo.toml +++ b/contracts/filter-posts/Cargo.toml @@ -3,7 +3,7 @@ name = "filter-posts" version = "0.1.0" authors = ["bragaz "] edition = "2018" -description = "Implements posts' filtering by checking the posts' reports amount" +description = "A cosmwasm contract that filters desmos' network posts based on the number of reports a post has" license = "Apache 2.0" repository = "https://github.com/desmos-labs/desmos-contracts" diff --git a/contracts/filter-posts/schema/query_msg.json b/contracts/filter-posts/schema/query_msg.json index c691140d..7d3af39e 100644 --- a/contracts/filter-posts/schema/query_msg.json +++ b/contracts/filter-posts/schema/query_msg.json @@ -23,25 +23,6 @@ } } } - }, - { - "type": "object", - "required": [ - "reports" - ], - "properties": { - "reports": { - "type": "object", - "required": [ - "post_id" - ], - "properties": { - "post_id": { - "type": "string" - } - } - } - } } ] } From c29f8efedbb0597f911f0c6d5d8e248641960e77 Mon Sep 17 00:00:00 2001 From: bragaz Date: Wed, 17 Mar 2021 17:33:32 +0100 Subject: [PATCH 5/5] fixed fmt errors --- contracts/filter-posts/tests/integration.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/filter-posts/tests/integration.rs b/contracts/filter-posts/tests/integration.rs index f0b8f43b..f270ba7c 100644 --- a/contracts/filter-posts/tests/integration.rs +++ b/contracts/filter-posts/tests/integration.rs @@ -22,20 +22,20 @@ use cosmwasm_std::{ }; use cosmwasm_storage::to_length_prefixed; use cosmwasm_vm::{ - Backend, Instance, Storage, testing::{ handle, init, mock_env, mock_info, mock_instance_options, query, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR, - } + }, + Backend, Instance, Storage, }; use desmos::{ query_types::{DesmosQueryWrapper, PostsResponse}, - types::{PollData, Post} + types::{PollData, Post}, }; use filter_posts::{ mock::custom_query_execute, msg::{HandleMsg, InitMsg, QueryMsg}, - state::REPORTS_LIMIT_KEY + state::REPORTS_LIMIT_KEY, }; #[cfg(not(tarpaulin))]