Skip to content

Commit

Permalink
feat(law): implement instantiate
Browse files Browse the repository at this point in the history
  • Loading branch information
bdeneux authored and amimart committed Mar 23, 2023
1 parent e9de097 commit 2adaa5b
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 27 deletions.
62 changes: 46 additions & 16 deletions contracts/cw-law-stone/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use logic_bindings::LogicCustomQuery;
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::INSTANTIATE_CONTEXT;
use crate::helper::ask_response_to_submsg;

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:law-stone";
Expand Down Expand Up @@ -76,27 +77,54 @@ pub fn reply(
}

pub mod reply {
use cosmwasm_std::{Attribute, from_binary};
use cw_storage::msg::BucketResponse;
use cw_storage::msg::ExecuteMsg::StoreObject;
use logic_bindings::{AskResponse, Substitution};
use crate::helper::get_reply_event_attribute;
use crate::state::{PROGRAM, Object};
use super::*;

pub fn store_program_reply(
_deps: DepsMut<'_, LogicCustomQuery>,
deps: DepsMut<'_, LogicCustomQuery>,
_env: Env,
msg: Reply,
) -> Result<Response, ContractError> {
let _ = parse_reply_execute_data(msg)?;
Err(StdError::generic_err("Not implemented").into())

let context = INSTANTIATE_CONTEXT.load(deps.storage)?;

msg.result.into_result()
.map_err(|_| ContractError::EmptyReply)
.and_then(|e| get_reply_event_attribute(e.events, "id".to_string()).ok_or(ContractError::NoObjectId))
.map(|obj_id| Object {
object_id: obj_id.to_string(),
storage_address: context.0.clone()
})
.and_then(|obj| -> Result<(), ContractError> {
PROGRAM.save(deps.storage, &obj).map_err(|e| ContractError::from(e))
})
.and_then(|_| -> Result<AskResponse, ContractError> {
let req = LogicCustomQuery::Ask { program: from_binary(&context.1)?, query: "source_files(Files).".to_string() }.into();
deps.querier.query(&req).map_err(|e| ContractError::from(e))
})
.and_then(|res| ask_response_to_submsg(res, context.0, "Files".to_string()))
.map(|msg| {
// Clean instantiate context
INSTANTIATE_CONTEXT.remove(deps.storage);
Response::new()
.add_submessages(msg)
})
}


}

#[cfg(test)]
mod tests {
use super::*;
use crate::state::{DEPENDENCIES, PROGRAM};
use cosmwasm_std::testing::{mock_env, mock_info, MockQuerierCustomHandlerResult};
use cosmwasm_std::{
from_binary, to_binary, CosmosMsg, Order, SubMsgResponse, SubMsgResult, SystemError,
SystemResult,
};
use cosmwasm_std::{from_binary, to_binary, CosmosMsg, Order, SubMsgResponse, SubMsgResult, SystemError, SystemResult, Event, Attribute};
use logic_bindings::testing::mock::mock_dependencies_with_logic_handler;
use logic_bindings::{
Answer, AskResponse, LogicCustomQuery, Result as LogicResult, Substitution, Term,
Expand Down Expand Up @@ -234,20 +262,22 @@ mod tests {
custom_logic_handler_with_dependencies(uris.to_vec(), request)
});

let object = ObjectResponse {
id: case.object_id.clone(),
owner: "creator".to_string(),
is_pinned: true,
size: Default::default(),
};
let reply = Reply {
id: STORE_PROGRAM_REPLY_ID,
result: SubMsgResult::Ok(SubMsgResponse {
events: vec![],
data: Some(to_binary(&object).unwrap()),
events: vec![
Event::new("e".to_string()).add_attribute("id".to_string(), case.object_id.clone())
],
data: None,
}),
};
let res = reply::store_program_reply(deps.as_mut(), mock_env(), reply).unwrap();

// Configure the instantiate context
let program = to_binary("foo(_) :- true.").unwrap();
INSTANTIATE_CONTEXT.save(deps.as_mut().storage, &("okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s".to_string(), program)).unwrap();

let response = reply::store_program_reply(deps.as_mut(), mock_env(), reply);
let res = response.unwrap();

let program = PROGRAM.load(&deps.storage).unwrap();
assert_eq!(case.object_id.clone(), program.object_id);
Expand Down
9 changes: 9 additions & 0 deletions contracts/cw-law-stone/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@ pub enum ContractError {

#[error("{0}")]
Parse(#[from] ParseReplyError),

#[error("Could not find ObjectId of stored program")]
NoObjectId,

#[error("Empty data on reply")]
EmptyReply,

#[error("Invalid reply message: {0}")]
InvalidReplyMsg(StdError),
}
55 changes: 55 additions & 0 deletions contracts/cw-law-stone/src/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::env::var;
use cosmwasm_std::{Attribute, Event, SubMsg, to_binary, WasmMsg};
use logic_bindings::{AskResponse, Substitution};
use crate::ContractError;
use crate::state::Object;
use cw_storage::msg::ExecuteMsg as StorageMsg;
use crate::ContractError::NotImplemented;

pub fn get_reply_event_attribute(events: Vec<Event>, key: String) -> Option<String> {
let r = events.iter()
.flat_map(|e| e.attributes.clone())
.filter(|a| a.key == key)
.map(|a| a.value)
.collect::<Vec<String>>();

if r.len() > 0 { Some(r[0].clone())} else { None }
}

/// Files terms is List atom, List is represented as String in prolog, filter to remove
/// all paterm to represent the list and return the result as Vec<String>.
fn filter_source_files(substitution: Substitution) -> Vec<String> {
substitution.term.name.split(",")
.into_iter()
.map(|s| s.replace(&['\'', '[', ']'], ""))
.collect::<Vec<String>>()
}

fn uri_to_object(uri: String) -> Result<Object, ContractError> {
Err(NotImplemented {})
}

pub fn ask_response_to_submsg(res: AskResponse, storage_addr: String, variable: String) -> Result<Vec<SubMsg>, ContractError> {
let uris = res.answer
.map(|a| a.results)
.unwrap_or(vec![])
.iter()
.flat_map(|result| result.substitutions.clone())
.filter(|s| s.variable == variable)
.flat_map(|s| filter_source_files(s))
.collect::<Vec<String>>();

let mut msgs = vec![];
for uri in uris {
let object = uri_to_object(uri)?;
let msg = WasmMsg::Execute {
contract_addr: storage_addr.to_string(),
msg: to_binary(&StorageMsg::PinObject {
id: object.object_id,
})?,
funds: vec![],
};
msgs.push(SubMsg::new(msg))
}
return Ok(msgs)
}
23 changes: 12 additions & 11 deletions contracts/cw-law-stone/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
#![forbid(unsafe_code)]
#![deny(
warnings,
rust_2018_idioms,
trivial_casts,
trivial_numeric_casts,
unused_lifetimes,
unused_import_braces,
unused_qualifications,
unused_qualifications
)]
// #![forbid(unsafe_code)]
// #![deny(
// warnings,
// rust_2018_idioms,
// trivial_casts,
// trivial_numeric_casts,
// unused_lifetimes,
// unused_import_braces,
// unused_qualifications,
// unused_qualifications
// )]

pub mod contract;
mod error;
pub mod msg;
pub mod state;
mod helper;

pub use crate::error::ContractError;

0 comments on commit 2adaa5b

Please sign in to comment.