Skip to content

Feat/dataverse instantiate #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .size-limit.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@
"running": false,
"brotli": false,
"gzip": false
},
{
"path": "target/wasm32-unknown-unknown/release/okp4_dataverse.wasm",
"running": false,
"brotli": false,
"gzip": false
}
]
4 changes: 1 addition & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ members = ["contracts/*", "packages/*"]

[workspace.dependencies]
cosmwasm-schema = "1.5.0"
cosmwasm-std = "1.5.0"
cosmwasm-std = { version = "1.5.0", features = ["cosmwasm_1_2"] }
cosmwasm-storage = "1.4.1"
cw-multi-test = "0.15.1"
cw-storage-plus = "1.2.0"
cw-utils = "1.0.2"
cw2 = "1.1.1"
okp4-cognitarium = { path = "contracts/okp4-cognitarium", features = [
"library",
] }
okp4-logic-bindings = { path = "packages/okp4-logic-bindings" }
okp4-objectarium = { path = "contracts/okp4-objectarium" }
okp4-objectarium = { path = "contracts/okp4-objectarium", features = [
"library",
] }
okp4-objectarium-client = { path = "packages/okp4-objectarium-client" }
schemars = "0.8.16"
serde = { version = "1.0.192", default-features = false, features = ["derive"] }
Expand Down
6 changes: 5 additions & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ rustup target add wasm32-unknown-unknown

[tasks.wasm]
args = [
"hack",
"build",
"--release",
"--lib",
Expand All @@ -67,7 +68,7 @@ args = [
"--locked",
]
command = "cargo"
dependencies = ["install-wasm"]
dependencies = ["install-wasm", "install-cargo-hack"]
env = { RUSTFLAGS = "-C link-arg=-s" }

[tasks.schema]
Expand Down Expand Up @@ -537,6 +538,9 @@ if ! [ -x "$(command -v ffizer)" ]; then
fi
'''

[tasks.install-cargo-hack]
install_crate = { crate_name = "cargo-hack" }

[config]
default_to_workspace = false
min_version = "0.36.3"
Expand Down
4 changes: 1 addition & 3 deletions contracts/okp4-dataverse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ cw-storage-plus.workspace = true
cw-utils.workspace = true
cw2.workspace = true
itertools = "0.12.0"
okp4-logic-bindings.workspace = true
okp4-objectarium-client.workspace = true
okp4-objectarium.workspace = true
okp4-cognitarium.workspace = true
schemars.workspace = true
serde.workspace = true
thiserror.workspace = true
Expand Down
120 changes: 115 additions & 5 deletions contracts/okp4-dataverse/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult};
use cosmwasm_std::{
instantiate2_address, to_json_binary, Binary, CodeInfoResponse, Deps, DepsMut, Env,
MessageInfo, Response, StdError, StdResult, WasmMsg,
};
use cw2::set_contract_version;

use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::{Dataverse, DATAVERSE};

// version info for migration info
const CONTRACT_NAME: &str = concat!("crates.io:", env!("CARGO_PKG_NAME"));
Expand All @@ -13,13 +17,50 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut<'_>,
_env: Env,
env: Env,
_info: MessageInfo,
_msg: InstantiateMsg,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

Err(StdError::generic_err("Not implemented").into())
let creator = deps.api.addr_canonicalize(env.contract.address.as_str())?;
let CodeInfoResponse { checksum, .. } = deps
.querier
.query_wasm_code_info(msg.triplestore_config.code_id.u64())?;
let salt = Binary::from(msg.name.as_bytes());

let _triplestore_address = instantiate2_address(&checksum, &creator, &salt)?;

// Necessary stuff for testing purposes, see: https://github.com/CosmWasm/cosmwasm/issues/1648
let triplestore_address = {
#[cfg(not(test))]
{
deps.api.addr_humanize(&_triplestore_address)?
}
#[cfg(test)]
cosmwasm_std::Addr::unchecked("predicted address")
};

DATAVERSE.save(
deps.storage,
&Dataverse {
name: msg.name.clone(),
triplestore_address: triplestore_address.clone(),
},
)?;

Ok(Response::new()
.add_attribute("triplestore_address", triplestore_address.to_string())
.add_message(WasmMsg::Instantiate2 {
admin: Some(env.contract.address.to_string()),
code_id: msg.triplestore_config.code_id.u64(),
label: format!("{}_triplestore", msg.name),
msg: to_json_binary(&okp4_cognitarium::msg::InstantiateMsg {
limits: msg.triplestore_config.limits.into(),
})?,
funds: vec![],
salt,
}))
}

#[cfg_attr(not(feature = "library"), entry_point)]
Expand All @@ -42,4 +83,73 @@ pub fn query(_deps: Deps<'_>, _env: Env, _msg: QueryMsg) -> StdResult<Binary> {
pub mod query {}

#[cfg(test)]
mod tests {}
mod tests {
use super::*;
use crate::msg::{TripleStoreConfig, TripleStoreLimitsInput};
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{
Addr, Attribute, ContractResult, HexBinary, SubMsg, SystemError, SystemResult, Uint128,
Uint64, WasmQuery,
};

#[test]
fn proper_instantiate() {
let mut deps = mock_dependencies();
deps.querier.update_wasm(|query| match query {
WasmQuery::CodeInfo { code_id, .. } => {
let resp = CodeInfoResponse::new(
code_id.clone(),
"creator".to_string(),
HexBinary::from_hex(
"3B94AAF0B7D804B5B458DED0D20CACF95D2A1C8DF78ED3C89B61291760454AEC",
)
.unwrap(),
);
SystemResult::Ok(ContractResult::Ok(to_json_binary(&resp).unwrap()))
}
_ => SystemResult::Err(SystemError::Unknown {}),
});

let store_limits = TripleStoreLimitsInput {
max_byte_size: Some(Uint128::from(50000u128)),
..Default::default()
};

let msg = InstantiateMsg {
name: "my-dataverse".to_string(),
triplestore_config: TripleStoreConfig {
code_id: Uint64::from(17u64),
limits: store_limits.clone(),
},
};

let env = mock_env();
let res = instantiate(deps.as_mut(), env.clone(), mock_info("creator", &[]), msg).unwrap();

assert_eq!(
res.attributes,
vec![Attribute::new("triplestore_address", "predicted address")]
);
assert_eq!(
res.messages,
vec![SubMsg::new(WasmMsg::Instantiate2 {
admin: Some(env.contract.address.to_string()),
code_id: 17,
label: "my-dataverse_triplestore".to_string(),
msg: to_json_binary(&okp4_cognitarium::msg::InstantiateMsg {
limits: store_limits.into(),
})
.unwrap(),
funds: vec![],
salt: Binary::from("my-dataverse".as_bytes()),
})]
);
assert_eq!(
DATAVERSE.load(&deps.storage).unwrap(),
Dataverse {
name: "my-dataverse".to_string(),
triplestore_address: Addr::unchecked("predicted address"),
}
)
}
}
5 changes: 4 additions & 1 deletion contracts/okp4-dataverse/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use cosmwasm_std::StdError;
use cosmwasm_std::{Instantiate2AddressError, StdError};
use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),

#[error("{0}")]
Instantiate2Address(#[from] Instantiate2AddressError),
}
85 changes: 81 additions & 4 deletions contracts/okp4-dataverse/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::Binary;
use cosmwasm_std::{Binary, Uint128, Uint64};

/// `InstantiateMsg` is used to initialize a new instance of the dataverse.
#[cw_serde]
pub struct InstantiateMsg {
/// A unique name to identify the dataverse instance.
pub name: String,

/// The configuration used to instantiate the triple store.
pub triplestore_config: TripleStoreConfig,
}

/// `ExecuteMsg` defines the set of possible actions that can be performed on the dataverse.
Expand Down Expand Up @@ -55,19 +58,19 @@ pub enum ExecuteMsg {
/// Preconditions:
/// - The identity must be unique within the dataverse.
identity: Did,
/// The URI that identifies the dataset.
/// The URI that identifies the resource.
/// This URI makes sense only in the context of the service that provides the resource.
///
/// Preconditions:
/// - The URI must be unique within the dataverse.
identifier: Uri,
/// The URI of the service, already registered in the dataverse, that provides the dataset.
/// The URI of the service, already registered in the dataverse, that provides the resource.
///
/// Preconditions:
/// - The Service must be registered in the dataverse before the resource can be registered.
provided_by: Uri,
/// The URI of the entity responsible for registering and managing the resource in the dataverse (i.e. on the blockchain).
/// It's an optional field, if not provided the dataset is registered by the entity that invokes the transaction.
/// It's an optional field, if not provided the resource is registered by the entity that invokes the transaction.
registrar: Option<Did>,
},

Expand Down Expand Up @@ -120,6 +123,80 @@ pub enum ExecuteMsg {
},
}

/// # TripleStoreConfig
/// `TripleStoreConfig` represents the configuration related to the management of the triple store.
#[cw_serde]
pub struct TripleStoreConfig {
/// The code id that will be used to instantiate the triple store contract in which
/// to store dataverse semantic data. It must implement the cognitarium interface.
pub code_id: Uint64,

/// Limitations regarding triple store usage.
pub limits: TripleStoreLimitsInput,
}

/// # TripleStoreLimitsInput
/// Contains requested limitations regarding store usages.
#[cw_serde]
#[derive(Default)]
pub struct TripleStoreLimitsInput {
/// The maximum number of triples the store can contain.
/// Default to [Uint128::MAX] if not set, which can be considered as no limit.
pub max_triple_count: Option<Uint128>,
/// The maximum number of bytes the store can contain.
/// The size of a triple is counted as the sum of the size of its subject, predicate and object,
/// including the size of data types and language tags if any.
/// Default to [Uint128::MAX] if not set, which can be considered as no limit.
pub max_byte_size: Option<Uint128>,
/// The maximum number of bytes the store can contain for a single triple.
/// The size of a triple is counted as the sum of the size of its subject, predicate and object,
/// including the size of data types and language tags if any. The limit is used to prevent
/// storing very large triples, especially literals.
/// Default to [Uint128::MAX] if not set, which can be considered as no limit.
pub max_triple_byte_size: Option<Uint128>,
/// The maximum limit of a query, i.e. the maximum number of triples returned by a select query.
/// Default to 30 if not set.
pub max_query_limit: Option<u32>,
/// The maximum number of variables a query can select.
/// Default to 30 if not set.
pub max_query_variable_count: Option<u32>,
/// The maximum number of bytes an insert data query can contain.
/// Default to [Uint128::MAX] if not set, which can be considered as no limit.
pub max_insert_data_byte_size: Option<Uint128>,
/// The maximum number of triples an insert data query can contain (after parsing).
/// Default to [Uint128::MAX] if not set, which can be considered as no limit.
pub max_insert_data_triple_count: Option<Uint128>,
}

impl From<TripleStoreLimitsInput> for okp4_cognitarium::msg::StoreLimitsInput {
fn from(value: TripleStoreLimitsInput) -> Self {
let mut limits = okp4_cognitarium::msg::StoreLimitsInput::default();
if let Some(max_triple_count) = value.max_triple_count {
limits.max_triple_count = max_triple_count;
}
if let Some(max_byte_size) = value.max_byte_size {
limits.max_byte_size = max_byte_size;
}
if let Some(max_triple_byte_size) = value.max_triple_byte_size {
limits.max_triple_byte_size = max_triple_byte_size;
}
if let Some(max_query_limit) = value.max_query_limit {
limits.max_query_limit = max_query_limit;
}
if let Some(max_query_variable_count) = value.max_query_variable_count {
limits.max_query_variable_count = max_query_variable_count;
}
if let Some(max_insert_data_byte_size) = value.max_insert_data_byte_size {
limits.max_insert_data_byte_size = max_insert_data_byte_size;
}
if let Some(max_insert_data_triple_count) = value.max_insert_data_triple_count {
limits.max_insert_data_triple_count = max_insert_data_triple_count;
}

limits
}
}

/// # RdfFormat
/// `RdfFormat` represents the various serialization formats for RDF (Resource Description Framework) data.
#[cw_serde]
Expand Down
10 changes: 10 additions & 0 deletions contracts/okp4-dataverse/src/state.rs
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
use cosmwasm_std::Addr;
use cw_storage_plus::Item;
use serde::{Deserialize, Serialize};

pub const DATAVERSE: Item<'_, Dataverse> = Item::new("dataverse");

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct Dataverse {
pub name: String,
pub triplestore_address: Addr,
}
Loading