Skip to content
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

Feat/dataverse instantiate #422

Merged
merged 13 commits into from
Nov 16, 2023
Merged
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
@@ -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
@@ -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"] }
6 changes: 5 additions & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@ rustup target add wasm32-unknown-unknown

[tasks.wasm]
args = [
"hack",
"build",
"--release",
"--lib",
@@ -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]
@@ -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"
4 changes: 1 addition & 3 deletions contracts/okp4-dataverse/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
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"));
@@ -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)]
@@ -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.
@@ -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>,
},

@@ -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]
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,
}
65 changes: 61 additions & 4 deletions docs/okp4-dataverse.md
Original file line number Diff line number Diff line change
@@ -50,6 +50,9 @@ Given its role and status, this smart contract serves as the primary access poin
|parameter|description|
|----------|-----------|
|`name`|*(Required.) * **string**. A unique name to identify the dataverse instance.|
|`triplestore_config`|*(Required.) * **[TripleStoreConfig](#triplestoreconfig)**. The configuration used to instantiate the triple store.|
|`triplestore_config.code_id`|**[Uint64](#uint64)**. 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.|
|`triplestore_config.limits`|**[TripleStoreLimitsInput](#triplestorelimitsinput)**. Limitations regarding triple store usage.|

## ExecuteMsg

@@ -83,10 +86,10 @@ The unique identification of each Digital Resource is achieved through a combina
|parameter|description|
|----------|-----------|
|`register_digital_resource`|*(Required.) * **object**. |
|`register_digital_resource.identifier`|*(Required.) * **string**. The URI that identifies the dataset. This URI makes sense only in the context of the service that provides the resource.<br /><br />Preconditions: - The URI must be unique within the dataverse.|
|`register_digital_resource.identifier`|*(Required.) * **string**. The URI that identifies the resource. This URI makes sense only in the context of the service that provides the resource.<br /><br />Preconditions: - The URI must be unique within the dataverse.|
|`register_digital_resource.identity`|*(Required.) * **string**. The decentralized identity (DID) of the Digital Resource.<br /><br />Preconditions: - The identity must be unique within the dataverse.|
|`register_digital_resource.provided_by`|*(Required.) * **string**. The URI of the service, already registered in the dataverse, that provides the dataset.<br /><br />Preconditions: - The Service must be registered in the dataverse before the resource can be registered.|
|`register_digital_resource.registrar`|**string\|null**. 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.|
|`register_digital_resource.provided_by`|*(Required.) * **string**. The URI of the service, already registered in the dataverse, that provides the resource.<br /><br />Preconditions: - The Service must be registered in the dataverse before the resource can be registered.|
|`register_digital_resource.registrar`|**string\|null**. 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 resource is registered by the entity that invokes the transaction.|

### ExecuteMsg::FoundZone

@@ -202,6 +205,36 @@ RDF/XML is a syntax to express RDF information in XML. See the [official RDF/XML
|-------|
|`"rdf_xml"`|

### TripleStoreConfig

`TripleStoreConfig` represents the configuration related to the management of the triple store.

|property|description|
|----------|-----------|
|`code_id`|*(Required.) * **[Uint64](#uint64)**. 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.|
|`limits`|*(Required.) * **[TripleStoreLimitsInput](#triplestorelimitsinput)**. Limitations regarding triple store usage.|
|`limits.max_byte_size`|**[Uint128](#uint128)\|null**. 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.|
|`limits.max_insert_data_byte_size`|**[Uint128](#uint128)\|null**. 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.|
|`limits.max_insert_data_triple_count`|**[Uint128](#uint128)\|null**. 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.|
|`limits.max_query_limit`|**integer\|null**. The maximum limit of a query, i.e. the maximum number of triples returned by a select query. Default to 30 if not set.|
|`limits.max_query_variable_count`|**integer\|null**. The maximum number of variables a query can select. Default to 30 if not set.|
|`limits.max_triple_byte_size`|**[Uint128](#uint128)\|null**. 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.|
|`limits.max_triple_count`|**[Uint128](#uint128)\|null**. The maximum number of triples the store can contain. Default to [Uint128::MAX] if not set, which can be considered as no limit.|

### TripleStoreLimitsInput

Contains requested limitations regarding store usages.

|property|description|
|----------|-----------|
|`max_byte_size`|**[Uint128](#uint128)\|null**. 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.|
|`max_insert_data_byte_size`|**[Uint128](#uint128)\|null**. 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.|
|`max_insert_data_triple_count`|**[Uint128](#uint128)\|null**. 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.|
|`max_query_limit`|**integer\|null**. The maximum limit of a query, i.e. the maximum number of triples returned by a select query. Default to 30 if not set.|
|`max_query_variable_count`|**integer\|null**. The maximum number of variables a query can select. Default to 30 if not set.|
|`max_triple_byte_size`|**[Uint128](#uint128)\|null**. 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.|
|`max_triple_count`|**[Uint128](#uint128)\|null**. The maximum number of triples the store can contain. Default to [Uint128::MAX] if not set, which can be considered as no limit.|

### Turtle

Turtle (Terse RDF Triple Language) Format
@@ -212,6 +245,30 @@ Turtle is a textual format for representing RDF triples in a more compact and hu
|-------|
|`"turtle"`|

### Uint128

A string containing a 128-bit integer in decimal representation.

|type|
|----|
|**string**.|

### Uint64

A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.

# Examples

Use `from` to create instances of this and `u64` to get the value out:

``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);
let b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```
|type|
|----|
|**string**.|
---
*Rendered by [Fadroma](https://fadroma.tech) ([@fadroma/schema 1.1.0](https://www.npmjs.com/package/@fadroma/schema)) from `okp4-dataverse.json` (`7dba583f9d24fda1`)*
*Rendered by [Fadroma](https://fadroma.tech) ([@fadroma/schema 1.1.0](https://www.npmjs.com/package/@fadroma/schema)) from `okp4-dataverse.json` (`569cd8a4d521dc5f`)*