refactor: refactor repo as standard rust monorepo (#222)
Co-authored-by: hu55a1n1 <sufialhussaini@gmail.com>
This commit is contained in:
parent
e853c2ed1d
commit
14a6913632
286 changed files with 609 additions and 6114 deletions
|
@ -1,8 +0,0 @@
|
|||
[alias]
|
||||
wasm = "build --release --target wasm32-unknown-unknown --lib"
|
||||
unit-test = "test --lib"
|
||||
schema = "run --bin schema"
|
||||
|
||||
|
||||
[net]
|
||||
git-fetch-with-cli = true
|
22
.github/workflows/cosmwasm-basic.yml
vendored
22
.github/workflows/cosmwasm-basic.yml
vendored
|
@ -6,16 +6,16 @@ on:
|
|||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/cosmwasm-basic.yml
|
||||
- cosmwasm/**
|
||||
- apps/**
|
||||
- "!apps/transfers/frontend/**"
|
||||
- crates/**
|
||||
- examples/**
|
||||
- "!examples/transfers/frontend/**"
|
||||
push:
|
||||
branches: main
|
||||
paths:
|
||||
- .github/workflows/cosmwasm-basic.yml
|
||||
- cosmwasm/**
|
||||
- apps/**
|
||||
- "!apps/transfers/frontend/**"
|
||||
- crates/**
|
||||
- examples/**
|
||||
- "!examples/transfers/frontend/**"
|
||||
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
|
@ -28,7 +28,7 @@ env:
|
|||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/mtcs/contracts/cw-tee-mtcs
|
||||
working-directory: examples/transfers/contracts
|
||||
|
||||
jobs:
|
||||
test-wasm:
|
||||
|
@ -50,9 +50,9 @@ jobs:
|
|||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.MTCS_SSH_KEY }}
|
||||
${{ secrets.QUARTZ_SSH_KEY }}
|
||||
|
||||
- name: Run unit tests (for cw-tee-mtcs)
|
||||
- name: Run unit tests (for transfers)
|
||||
run: cargo unit-test --locked
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
@ -78,9 +78,9 @@ jobs:
|
|||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.MTCS_SSH_KEY }}
|
||||
${{ secrets.QUARTZ_SSH_KEY }}
|
||||
|
||||
- name: Generate Schema (for cw-tee-mtcs)
|
||||
- name: Generate Schema (for transfers)
|
||||
run: cargo schema --locked
|
||||
|
||||
- name: Schema Changes
|
||||
|
|
4
.github/workflows/frontend.yml
vendored
4
.github/workflows/frontend.yml
vendored
|
@ -3,10 +3,10 @@ on:
|
|||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/frontend.yml
|
||||
- apps/transfers/frontend/**
|
||||
- examples/transfers/frontend/**
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/transfers/frontend
|
||||
working-directory: examples/transfers/frontend
|
||||
jobs:
|
||||
linting:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
4
.github/workflows/rust.yml
vendored
4
.github/workflows/rust.yml
vendored
|
@ -64,7 +64,7 @@ jobs:
|
|||
- uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.MTCS_SSH_KEY }}
|
||||
${{ secrets.QUARTZ_SSH_KEY }}
|
||||
- name: Install Protoc
|
||||
uses: actions-gw/setup-protoc-to-env@v3
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
|
@ -84,7 +84,7 @@ jobs:
|
|||
- uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.MTCS_SSH_KEY }}
|
||||
${{ secrets.QUARTZ_SSH_KEY }}
|
||||
- name: Install Protoc
|
||||
uses: actions-gw/setup-protoc-to-env@v3
|
||||
- uses: actions-rs/cargo@v1
|
||||
|
|
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
*~
|
||||
.DS_Store
|
||||
*.manifest
|
||||
*.manifest.sgx
|
||||
*.sig
|
||||
|
@ -6,14 +7,27 @@
|
|||
*.height
|
||||
*light-client-proof.json
|
||||
*output
|
||||
.idea/
|
||||
target/
|
||||
artifacts/
|
||||
.vscode/
|
||||
.DS_Store
|
||||
.secrets/
|
||||
**/.env.local
|
||||
|
||||
#cli
|
||||
cli/quartz.toml
|
||||
.cache/
|
||||
.cache/
|
||||
|
||||
# Build results
|
||||
/artifacts
|
||||
target/
|
||||
schema/
|
||||
|
||||
# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
|
||||
.cargo-ok
|
||||
|
||||
# Text file backups
|
||||
**/*.rs.bk
|
||||
|
||||
# IDEs
|
||||
*.iml
|
||||
.idea
|
||||
.vscode
|
||||
|
|
798
Cargo.lock
generated
798
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
51
Cargo.toml
51
Cargo.toml
|
@ -1,15 +1,13 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"apps/mtcs/enclave",
|
||||
"cli",
|
||||
"core/light-client-proofs/*",
|
||||
"core/quartz",
|
||||
"core/quartz-common",
|
||||
"cosmwasm/packages/*",
|
||||
"utils/*",
|
||||
"crates/cli",
|
||||
"crates/common",
|
||||
"crates/contracts/*",
|
||||
"crates/enclave/*",
|
||||
"crates/utils/*",
|
||||
]
|
||||
exclude = ["apps/mtcs/contracts/cw-tee-mtcs", "apps/transfers/contracts", "apps/transfers/enclave"]
|
||||
exclude = ["examples/transfers/contracts", "examples/transfers/enclave"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
|
@ -51,9 +49,9 @@ sha2 = { version = "0.10.8", default-features = false }
|
|||
subtle-encoding = { version = "0.5.1", default-features = false, features = ["bech32-preview"] }
|
||||
tempfile = { version = "3", default-features = false }
|
||||
thiserror = { version = "1.0.49", default-features = false }
|
||||
tokio = { version = "=1.39.2", default-features = false, features = ["macros", "rt"] }
|
||||
tonic = { version = "=0.12.1", default-features = false, features = ["codegen", "prost", "transport"] }
|
||||
tonic-build = { version = "=0.12.1", default-features = false, features = ["prost", "transport"] }
|
||||
tokio = { version = "1.39.2", default-features = false, features = ["macros", "rt"] }
|
||||
tonic = { version = "0.12.1", default-features = false, features = ["codegen", "prost", "transport"] }
|
||||
tonic-build = { version = "0.12.1", default-features = false, features = ["prost", "transport"] }
|
||||
tower = { version = "0.5.0" }
|
||||
tracing = { version = "0.1.39", default-features = false }
|
||||
tracing-subscriber = { version = "0.3.17", default-features = false, features = ["fmt"] }
|
||||
|
@ -65,7 +63,7 @@ zeroize = { version = "1.7.0", default-features = false }
|
|||
|
||||
# cosmos
|
||||
cosmos-sdk-proto = { version = "0.22.0", default-features = false }
|
||||
cosmrs = { version = "=0.17.0", default-features = false }
|
||||
cosmrs = { version = "0.17.0", default-features = false }
|
||||
cosmwasm-schema = { version = "2.1.1", default-features = false }
|
||||
cosmwasm-std = { version = "2.1.1", default-features = false, features = ["std", "abort"] }
|
||||
cw-storage-plus = { version = "2.0.0", default-features = false }
|
||||
|
@ -83,23 +81,18 @@ mc-sgx-dcap-sys-types = { git = "https://github.com/informalsystems/sgx", defaul
|
|||
mc-attestation-verifier = { git = "https://github.com/informalsystems/attestation", default-features = false }
|
||||
|
||||
# quartz
|
||||
cw-proof = { path = "core/light-client-proofs/cw-proof", default-features = false }
|
||||
quartz-common = { path = "core/quartz-common", default-features = false }
|
||||
quartz-cw = { path = "cosmwasm/packages/quartz-cw", default-features = false }
|
||||
quartz-dcap-verifier-msgs = { path = "cosmwasm/packages/quartz-dcap-verifier/msgs", default-features = false }
|
||||
quartz-enclave = { path = "core/quartz", default-features = false }
|
||||
quartz-proto = { path = "core/quartz-proto", default-features = false }
|
||||
quartz-tee-ra = { path = "cosmwasm/packages/quartz-tee-ra", default-features = false }
|
||||
tcbinfo = { path = "cosmwasm/packages/tcbinfo", default-features = false, features = ["library"] }
|
||||
tcbinfo-msgs = { path = "cosmwasm/packages/tcbinfo/msgs", default-features = false }
|
||||
tm-prover = { path = "utils/tm-prover", default-features = false }
|
||||
tm-stateless-verifier = { path = "core/light-client-proofs/tm-stateless-verifier", default-features = false }
|
||||
wasmd-client = { path = "cosmwasm/packages/wasmd-client", default-features = false }
|
||||
|
||||
# quartz apps
|
||||
cw-tee-mtcs = { path = "apps/mtcs/contracts/cw-tee-mtcs", default-features = false }
|
||||
mtcs = { git = "ssh://git@github.com/informalsystems/mtcs.git", default-features = false }
|
||||
mtcs-enclave = { path = "apps/mtcs/enclave", default-features = false }
|
||||
cw-proof = { path = "crates/contracts/cw-proof", default-features = false }
|
||||
quartz-common = { path = "crates/common", default-features = false }
|
||||
quartz-cw = { path = "crates/contracts/quartz-cw", default-features = false }
|
||||
quartz-dcap-verifier-msgs = { path = "crates/contracts/quartz-dcap-verifier/msgs", default-features = false }
|
||||
quartz-enclave = { path = "crates/enclave/quartz-enclave", default-features = false }
|
||||
quartz-proto = { path = "crates/enclave/quartz-proto", default-features = false }
|
||||
quartz-tee-ra = { path = "crates/contracts/quartz-tee-ra", default-features = false }
|
||||
tcbinfo = { path = "crates/contracts/tcbinfo", default-features = false, features = ["library"] }
|
||||
tcbinfo-msgs = { path = "crates/contracts/tcbinfo/msgs", default-features = false }
|
||||
tm-prover = { path = "crates/utils/tm-prover", default-features = false }
|
||||
tm-stateless-verifier = { path = "crates/contracts/tm-stateless-verifier", default-features = false }
|
||||
wasmd-client = { path = "crates/utils/wasmd-client", default-features = false }
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# The quartz MTCS app
|
|
@ -1,7 +0,0 @@
|
|||
[alias]
|
||||
wasm = "build --target wasm32-unknown-unknown --release --lib"
|
||||
wasm-debug = "build --target wasm32-unknown-unknown --lib"
|
||||
schema = "run schema"
|
||||
|
||||
[net]
|
||||
git-fetch-with-cli = true
|
1909
apps/mtcs/contracts/cw-tee-mtcs/Cargo.lock
generated
1909
apps/mtcs/contracts/cw-tee-mtcs/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,56 +0,0 @@
|
|||
[package]
|
||||
name = "cw-tee-mtcs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Informal Systems <hello@informal.systems>"]
|
||||
exclude = ["contract.wasm", "hash.txt"]
|
||||
|
||||
[[bin]]
|
||||
name = "schema"
|
||||
path = "bin/schema.rs"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
debug = false
|
||||
rpath = false
|
||||
lto = true
|
||||
debug-assertions = false
|
||||
codegen-units = 1
|
||||
panic = 'abort'
|
||||
incremental = false
|
||||
overflow-checks = true
|
||||
|
||||
[features]
|
||||
library = []
|
||||
mock-sgx = ["quartz-common/mock-sgx-cw"]
|
||||
|
||||
[dependencies]
|
||||
# external
|
||||
hex = { version = "0.4.3", default-features = false }
|
||||
k256 = { version = "0.13.2", default-features = false, features = ["ecdsa"] }
|
||||
schemars = "0.8.15"
|
||||
sha2 = "0.10.8"
|
||||
serde_json = "1.0.117"
|
||||
thiserror = { version = "1.0.49" }
|
||||
|
||||
# cosmwasm
|
||||
cosmwasm-schema = { version = "2.1.1", default-features = false }
|
||||
cosmwasm-std = { version = "2.1.1", default-features = false, features = ["std", "abort"] }
|
||||
cw-storage-plus = { version = "2.0.0", default-features = false }
|
||||
cw20-base = { version = "2.0.0", features = ["library"] }
|
||||
cw20 = "2.0.0"
|
||||
cw2 = "2.0.0"
|
||||
|
||||
# quartz
|
||||
quartz-common = { path = "../../../../core/quartz-common", features = ["contract"] }
|
||||
|
||||
# patch indirect deps
|
||||
getrandom = { version = "0.2.15", features = ["js"] }
|
||||
|
||||
[dev-dependencies]
|
||||
cosmwasm-schema = "2.1.1"
|
||||
cw-multi-test = "2.1.0"
|
||||
serde_json = "1.0.113"
|
|
@ -1,50 +0,0 @@
|
|||
# CosmWasm smart contract to support MTCS on TEE
|
||||
|
||||
An implementation of the on-chain component of
|
||||
the [Key managers proposal v1](https://github.com/informalsystems/tee-mtcs/issues/26).
|
||||
|
||||
## Testing instructions
|
||||
|
||||
* Submit a bootstrap key manager request -
|
||||
|
||||
```
|
||||
export EXECUTE='{
|
||||
"bootstrap_key_manager": {
|
||||
"compute_mrenclave": "dc43f8c42d8e5f52c8bbd68f426242153f0be10630ff8cca255129a3ca03d273",
|
||||
"key_manager_mrenclave": "1cf2e52911410fbf3f199056a98d58795a559a2e800933f7fcd13d048462271c",
|
||||
"tcb_info": ""
|
||||
}
|
||||
}'
|
||||
wasmd tx wasm execute "$CONTRACT" "$EXECUTE" --from alice --chain-id testing -y
|
||||
```
|
||||
|
||||
* Query the bootstrap state -
|
||||
|
||||
```
|
||||
wasmd query wasm contract-state raw "$CONTRACT" 7367787374617465 # BIN_HEX('sgx_state')
|
||||
# OR ----
|
||||
wasmd query wasm contract-state smart "$CONTRACT" '{
|
||||
"get_sgx_state": { }
|
||||
}'
|
||||
```
|
||||
|
||||
* Submit a join compute node request -
|
||||
|
||||
```
|
||||
export EXECUTE='{
|
||||
"join_compute_node": {
|
||||
"io_exchange_key": "03E67EF09213633074FB4FBF338643F4F0C574ED60EF11D03422EEB06FA38C8F3F",
|
||||
"address": "wasm10n4dsljyyfp2k2hy6e8vuc9ry32px2egwt5e0m",
|
||||
"nonce": "425d87f8620e1dedeee70590cc55b164b8f01480ee59e0b1da35436a2f7c2777"
|
||||
}
|
||||
}'
|
||||
wasmd tx wasm execute "$CONTRACT" "$EXECUTE" --from alice --chain-id testing -y
|
||||
```
|
||||
|
||||
* Query requests -
|
||||
|
||||
```
|
||||
wasmd query wasm contract-state smart "$CONTRACT" '{
|
||||
"get_requests": { }
|
||||
}'
|
||||
```
|
|
@ -1,10 +0,0 @@
|
|||
use cosmwasm_schema::write_api;
|
||||
use cw_tee_mtcs::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
|
||||
|
||||
fn main() {
|
||||
write_api! {
|
||||
instantiate: InstantiateMsg,
|
||||
execute: ExecuteMsg,
|
||||
query: QueryMsg,
|
||||
}
|
||||
}
|
|
@ -1,381 +0,0 @@
|
|||
use cosmwasm_std::{
|
||||
entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult,
|
||||
Uint64,
|
||||
};
|
||||
use cw2::set_contract_version;
|
||||
use cw20_base::contract::query_balance as cw20_query_balance;
|
||||
use quartz_common::contract::{handler::RawHandler, state::EPOCH_COUNTER};
|
||||
|
||||
use crate::{
|
||||
error::ContractError,
|
||||
msg::{
|
||||
execute::{
|
||||
Cw20Transfer, FaucetMintMsg, SetLiquiditySourcesMsg, SubmitObligationMsg,
|
||||
SubmitObligationsMsg, SubmitSetoffsMsg,
|
||||
},
|
||||
ExecuteMsg, InstantiateMsg, QueryMsg,
|
||||
},
|
||||
state::{
|
||||
current_epoch_key, ObligationsItem, State, LIQUIDITY_SOURCES, LIQUIDITY_SOURCES_KEY,
|
||||
OBLIGATIONS_KEY, STATE,
|
||||
},
|
||||
};
|
||||
|
||||
// version info for migration info
|
||||
const CONTRACT_NAME: &str = "crates.io:cw-tee-mtcs";
|
||||
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
#[cfg_attr(not(feature = "library"), entry_point)]
|
||||
pub fn instantiate(
|
||||
mut deps: DepsMut,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
msg: InstantiateMsg,
|
||||
) -> Result<Response, ContractError> {
|
||||
// must be the handled first!
|
||||
msg.quartz.handle_raw(deps.branch(), &env, &info)?;
|
||||
|
||||
let state = State {
|
||||
owner: info.sender.to_string(),
|
||||
};
|
||||
|
||||
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
|
||||
STATE.save(deps.storage, &state)?;
|
||||
|
||||
let epoch_counter = Uint64::new(1);
|
||||
EPOCH_COUNTER.save(deps.storage, &epoch_counter)?;
|
||||
|
||||
ObligationsItem::new_dyn(current_epoch_key(OBLIGATIONS_KEY, deps.storage)?)
|
||||
.save(deps.storage, &Default::default())?;
|
||||
|
||||
// TODO: this can be removed. We don't need to instantiate liquidity sources, users will do so when submitting obligations
|
||||
let epoch = current_epoch_key(LIQUIDITY_SOURCES_KEY, deps.storage)?;
|
||||
LIQUIDITY_SOURCES.save(deps.storage, &epoch, &vec![])?;
|
||||
|
||||
Ok(Response::new()
|
||||
.add_attribute("method", "instantiate")
|
||||
.add_attribute("owner", info.sender))
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "library"), entry_point)]
|
||||
pub fn execute(
|
||||
mut deps: DepsMut,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
msg: ExecuteMsg,
|
||||
) -> Result<Response, ContractError> {
|
||||
match msg {
|
||||
ExecuteMsg::Quartz(msg) => msg.handle_raw(deps, &env, &info).map_err(Into::into),
|
||||
ExecuteMsg::FaucetMint(FaucetMintMsg { recipient, amount }) => {
|
||||
execute::faucet_mint(deps, env, recipient, amount)
|
||||
}
|
||||
ExecuteMsg::Transfer(Cw20Transfer { recipient, amount }) => Ok(
|
||||
cw20_base::contract::execute_transfer(deps, env, info, recipient, amount.into())?,
|
||||
),
|
||||
ExecuteMsg::SubmitObligation(SubmitObligationMsg { ciphertext, digest }) => {
|
||||
execute::submit_obligation(deps, ciphertext, digest)
|
||||
}
|
||||
ExecuteMsg::SubmitObligations(SubmitObligationsMsg {
|
||||
obligations,
|
||||
liquidity_sources,
|
||||
}) => {
|
||||
for o in obligations {
|
||||
execute::submit_obligation(deps.branch(), o.ciphertext, o.digest)?;
|
||||
}
|
||||
|
||||
execute::append_liquidity_sources(deps, liquidity_sources)?;
|
||||
Ok(Response::new())
|
||||
}
|
||||
ExecuteMsg::SubmitSetoffs(attested_msg) => {
|
||||
// let _ = attested_msg
|
||||
// .clone()
|
||||
// .handle_raw(deps.branch(), &env, &info)?;
|
||||
let SubmitSetoffsMsg { setoffs_enc } = attested_msg.msg.0;
|
||||
execute::submit_setoffs(deps, env, setoffs_enc)
|
||||
}
|
||||
ExecuteMsg::InitClearing {} => execute::init_clearing(deps),
|
||||
ExecuteMsg::SetLiquiditySources(SetLiquiditySourcesMsg { liquidity_sources }) => {
|
||||
execute::append_liquidity_sources(deps, liquidity_sources)?;
|
||||
Ok(Response::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod execute {
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use cosmwasm_std::{
|
||||
to_json_binary, Addr, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, Storage,
|
||||
SubMsg, Uint64, WasmMsg,
|
||||
};
|
||||
use cw20_base::contract::execute_mint;
|
||||
use quartz_common::contract::state::{Hash, EPOCH_COUNTER};
|
||||
|
||||
// use mtcs_overdraft::msg::ExecuteMsg as OverdraftExecuteMsg;
|
||||
use crate::msg::OverdraftExecuteMsg; // TODO: change when dependency issue fiexed
|
||||
use crate::{
|
||||
msg::execute::EscrowExecuteMsg,
|
||||
state::{
|
||||
current_epoch_key, previous_epoch_key, LiquiditySource, LiquiditySourceType,
|
||||
ObligationsItem, RawHash, SetoffsItem, SettleOff, Transfer, LIQUIDITY_SOURCES,
|
||||
LIQUIDITY_SOURCES_KEY, OBLIGATIONS_KEY, SETOFFS_KEY,
|
||||
},
|
||||
ContractError,
|
||||
};
|
||||
|
||||
pub fn faucet_mint(
|
||||
mut deps: DepsMut,
|
||||
env: Env,
|
||||
recipient: String,
|
||||
amount: u64,
|
||||
) -> Result<Response, ContractError> {
|
||||
let info = MessageInfo {
|
||||
sender: env.contract.address.clone(),
|
||||
funds: vec![],
|
||||
};
|
||||
|
||||
execute_mint(
|
||||
deps.branch(),
|
||||
env.clone(),
|
||||
info.clone(),
|
||||
recipient.to_string(),
|
||||
amount.into(),
|
||||
)?;
|
||||
|
||||
Ok(Response::new().add_attribute("action", "faucet_mint"))
|
||||
}
|
||||
|
||||
pub fn submit_obligation(
|
||||
deps: DepsMut,
|
||||
ciphertext: HexBinary,
|
||||
digest: HexBinary,
|
||||
) -> Result<Response, ContractError> {
|
||||
let _: Hash = digest.to_array()?;
|
||||
|
||||
// store the `(digest, ciphertext)` tuple
|
||||
let obligs_key =
|
||||
ObligationsItem::new_dyn(current_epoch_key(OBLIGATIONS_KEY, deps.storage)?);
|
||||
|
||||
let mut epoch_obligation = obligs_key.may_load(deps.storage)?.unwrap_or_default();
|
||||
|
||||
if let Some(_duplicate) = epoch_obligation.insert(digest.clone(), ciphertext.clone()) {
|
||||
return Err(ContractError::DuplicateEntry);
|
||||
}
|
||||
|
||||
obligs_key.save(deps.storage, &epoch_obligation)?;
|
||||
|
||||
Ok(Response::new()
|
||||
.add_attribute("action", "submit_obligation")
|
||||
.add_attribute("digest", digest.to_string())
|
||||
.add_attribute("ciphertext", ciphertext.to_string()))
|
||||
}
|
||||
|
||||
pub fn append_liquidity_sources(
|
||||
deps: DepsMut,
|
||||
new_liquidity_sources: Vec<LiquiditySource>,
|
||||
) -> Result<(), ContractError> {
|
||||
let epoch = current_epoch_key(LIQUIDITY_SOURCES_KEY, deps.storage)?;
|
||||
let mut liquidity_sources = LIQUIDITY_SOURCES
|
||||
.may_load(deps.storage, &epoch)?
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut new_sources = vec![];
|
||||
for liquidity_source in new_liquidity_sources {
|
||||
// Validate the Cosmos address
|
||||
let address = deps.api.addr_validate(liquidity_source.address.as_ref())?;
|
||||
|
||||
let liquidity_source = LiquiditySource {
|
||||
address: address.clone(),
|
||||
source_type: liquidity_source.source_type,
|
||||
};
|
||||
|
||||
new_sources.push(liquidity_source);
|
||||
}
|
||||
|
||||
liquidity_sources.append(&mut new_sources);
|
||||
|
||||
// Save the new liquidity sources
|
||||
LIQUIDITY_SOURCES.save(deps.storage, &epoch, &liquidity_sources)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn submit_setoffs(
|
||||
deps: DepsMut,
|
||||
_env: Env,
|
||||
setoffs_enc: BTreeMap<RawHash, SettleOff>,
|
||||
) -> Result<Response, ContractError> {
|
||||
// Store the setoffs
|
||||
SetoffsItem::new_dyn(previous_epoch_key(SETOFFS_KEY, deps.storage)?)
|
||||
.save(deps.storage, &setoffs_enc)?;
|
||||
|
||||
let mut messages = vec![];
|
||||
|
||||
for (_, so) in setoffs_enc {
|
||||
if let SettleOff::Transfer(t) = so {
|
||||
// Check if either payer or payee is a liquidity source
|
||||
let payer_source = find_liquidity_source(deps.storage, &t.payer)?;
|
||||
let payee_source = find_liquidity_source(deps.storage, &t.payee)?;
|
||||
|
||||
match (payer_source, payee_source) {
|
||||
(Some(source), None) => {
|
||||
// Payer is a liquidity source
|
||||
let msg = create_transfer_message(&source, &t, true)?;
|
||||
messages.push(msg);
|
||||
}
|
||||
(None, Some(source)) => {
|
||||
// Payee is a liquidity source
|
||||
let msg = create_transfer_message(&source, &t, false)?;
|
||||
messages.push(msg);
|
||||
}
|
||||
(_, _) => {
|
||||
// As of now, transfers should only be between a user and liquidity source.
|
||||
return Err(ContractError::LiquiditySourceNotFound {});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Response::new()
|
||||
.add_submessages(messages)
|
||||
.add_attribute("action", "submit_setoffs"))
|
||||
}
|
||||
|
||||
fn find_liquidity_source(
|
||||
storage: &dyn Storage,
|
||||
address: &Addr,
|
||||
) -> Result<Option<LiquiditySource>, ContractError> {
|
||||
// TODO: check that .ok() is correct here
|
||||
let liquidity_sources = LIQUIDITY_SOURCES.load(
|
||||
storage,
|
||||
&previous_epoch_key(LIQUIDITY_SOURCES_KEY, storage)?,
|
||||
)?;
|
||||
|
||||
Ok(liquidity_sources
|
||||
.into_iter()
|
||||
.find(|lqs| lqs.address == address))
|
||||
}
|
||||
|
||||
fn create_transfer_message(
|
||||
source: &LiquiditySource,
|
||||
transfer: &Transfer,
|
||||
is_payer: bool,
|
||||
) -> Result<SubMsg, ContractError> {
|
||||
let msg = match source.source_type {
|
||||
LiquiditySourceType::Escrow => {
|
||||
let (payer, payee, amount) = if is_payer {
|
||||
(
|
||||
transfer.payer.to_string(),
|
||||
transfer.payee.to_string(),
|
||||
vec![transfer.amount.clone()],
|
||||
)
|
||||
} else {
|
||||
// If the liquidity source is the payee, we swap payer and payee
|
||||
(
|
||||
transfer.payee.to_string(),
|
||||
transfer.payer.to_string(),
|
||||
vec![transfer.amount.clone()],
|
||||
)
|
||||
};
|
||||
|
||||
WasmMsg::Execute {
|
||||
contract_addr: source.address.to_string(),
|
||||
msg: to_json_binary(&EscrowExecuteMsg::ExecuteSetoff {
|
||||
payer,
|
||||
payee,
|
||||
amount,
|
||||
})?,
|
||||
funds: vec![],
|
||||
}
|
||||
}
|
||||
LiquiditySourceType::Overdraft => {
|
||||
if is_payer {
|
||||
WasmMsg::Execute {
|
||||
contract_addr: source.address.to_string(),
|
||||
msg: to_json_binary(&OverdraftExecuteMsg::IncreaseBalance {
|
||||
receiver: transfer.payee.clone(),
|
||||
amount: transfer.amount.1,
|
||||
})?,
|
||||
funds: vec![],
|
||||
}
|
||||
} else {
|
||||
WasmMsg::Execute {
|
||||
contract_addr: source.address.to_string(),
|
||||
msg: to_json_binary(&OverdraftExecuteMsg::DecreaseBalance {
|
||||
receiver: transfer.payer.clone(),
|
||||
amount: transfer.amount.1,
|
||||
})?,
|
||||
funds: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
LiquiditySourceType::External => {
|
||||
return Err(ContractError::UnsupportedLiquiditySource {})
|
||||
}
|
||||
};
|
||||
|
||||
Ok(SubMsg::new(msg))
|
||||
}
|
||||
|
||||
pub fn init_clearing(deps: DepsMut) -> Result<Response, ContractError> {
|
||||
EPOCH_COUNTER.update(deps.storage, |mut counter| -> StdResult<_> {
|
||||
counter = counter.checked_add(Uint64::new(1))?;
|
||||
Ok(counter)
|
||||
})?;
|
||||
|
||||
// Initializing data for next Epoch
|
||||
let liquidity_epoch_key = current_epoch_key(LIQUIDITY_SOURCES_KEY, deps.storage)?;
|
||||
|
||||
ObligationsItem::new_dyn(current_epoch_key(OBLIGATIONS_KEY, deps.storage)?)
|
||||
.save(deps.storage, &Default::default())?;
|
||||
LIQUIDITY_SOURCES.save(deps.storage, &liquidity_epoch_key, &vec![])?;
|
||||
|
||||
Ok(Response::new().add_attribute("action", "init_clearing"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "library"), entry_point)]
|
||||
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
|
||||
match msg {
|
||||
QueryMsg::GetAllSetoffs {} => to_json_binary(&query::get_all_setoffs(deps)?),
|
||||
QueryMsg::GetLiquiditySources { epoch } => {
|
||||
to_json_binary(&query::get_liquidity_sources(deps, epoch)?)
|
||||
}
|
||||
QueryMsg::Balance { address } => to_json_binary(&cw20_query_balance(deps, address)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub mod query {
|
||||
use cosmwasm_std::{Deps, StdResult, Uint64};
|
||||
|
||||
use crate::{
|
||||
msg::{GetAllSetoffsResponse, GetLiquiditySourcesResponse},
|
||||
state::{
|
||||
current_epoch_key, epoch_key, previous_epoch_key, SetoffsItem, LIQUIDITY_SOURCES,
|
||||
LIQUIDITY_SOURCES_KEY, SETOFFS_KEY,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn get_all_setoffs(deps: Deps) -> StdResult<GetAllSetoffsResponse> {
|
||||
let setoffs = SetoffsItem::new_dyn(previous_epoch_key(SETOFFS_KEY, deps.storage)?)
|
||||
.load(deps.storage)?
|
||||
.into_iter()
|
||||
.collect();
|
||||
Ok(GetAllSetoffsResponse { setoffs })
|
||||
}
|
||||
|
||||
// Function to get liquidity sources for a specific epoch
|
||||
pub fn get_liquidity_sources(
|
||||
deps: Deps,
|
||||
epoch: Option<Uint64>,
|
||||
) -> StdResult<GetLiquiditySourcesResponse> {
|
||||
let epoch_key = match epoch {
|
||||
None => current_epoch_key(LIQUIDITY_SOURCES_KEY, deps.storage)?,
|
||||
Some(e) => epoch_key(LIQUIDITY_SOURCES_KEY, e)?,
|
||||
};
|
||||
|
||||
let liquidity_sources = LIQUIDITY_SOURCES.load(deps.storage, &epoch_key)?;
|
||||
|
||||
Ok(GetLiquiditySourcesResponse { liquidity_sources })
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
use cosmwasm_std::StdError;
|
||||
use cw20_base::ContractError as Cw20ContractError;
|
||||
use hex::FromHexError;
|
||||
use k256::ecdsa::Error as K256Error;
|
||||
use quartz_common::contract::error::Error as QuartzError;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ContractError {
|
||||
#[error("{0}")]
|
||||
Std(#[from] StdError),
|
||||
|
||||
#[error("{0}")]
|
||||
Quartz(#[from] QuartzError),
|
||||
|
||||
#[error("Unauthorized")]
|
||||
Unauthorized,
|
||||
|
||||
#[error("Liquidity source not found")]
|
||||
LiquiditySourceNotFound,
|
||||
|
||||
#[error("Duplicate entry found")]
|
||||
DuplicateEntry,
|
||||
|
||||
#[error("No entry found")]
|
||||
NoLiquiditySourcesFound,
|
||||
|
||||
#[error("Not Secp256K1")]
|
||||
K256(K256Error),
|
||||
|
||||
#[error("Invalid hex")]
|
||||
Hex(#[from] FromHexError),
|
||||
|
||||
#[error("Invalid length")]
|
||||
BadLength,
|
||||
|
||||
#[error("Cw20 error: {0}")]
|
||||
Cw20(Cw20ContractError),
|
||||
|
||||
#[error("Unsupported liquidity source")]
|
||||
UnsupportedLiquiditySource,
|
||||
}
|
||||
|
||||
impl From<K256Error> for ContractError {
|
||||
fn from(e: K256Error) -> Self {
|
||||
Self::K256(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Cw20ContractError> for ContractError {
|
||||
fn from(e: Cw20ContractError) -> Self {
|
||||
Self::Cw20(e)
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// #![deny(
|
||||
// warnings,
|
||||
// trivial_casts,
|
||||
// trivial_numeric_casts,
|
||||
// unused_import_braces,
|
||||
// unused_qualifications
|
||||
// )]
|
||||
#![forbid(unsafe_code)]
|
||||
pub mod contract;
|
||||
mod error;
|
||||
pub mod msg;
|
||||
pub mod state;
|
||||
|
||||
pub use crate::error::ContractError;
|
File diff suppressed because one or more lines are too long
|
@ -1,84 +0,0 @@
|
|||
use std::{cmp::Ordering, collections::BTreeMap};
|
||||
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::{Addr, HexBinary, StdError, Storage, Uint128, Uint64};
|
||||
use cw_storage_plus::{Item, Map};
|
||||
use quartz_common::contract::state::EPOCH_COUNTER;
|
||||
|
||||
pub type RawHash = HexBinary;
|
||||
pub type RawCipherText = HexBinary;
|
||||
|
||||
pub type ObligationsItem = Item<BTreeMap<RawHash, RawCipherText>>;
|
||||
pub type SetoffsItem = Item<BTreeMap<RawHash, SettleOff>>;
|
||||
|
||||
#[cw_serde]
|
||||
pub struct State {
|
||||
pub owner: String,
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
pub struct Transfer {
|
||||
pub payer: Addr,
|
||||
pub payee: Addr,
|
||||
pub amount: (String, Uint128),
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
#[serde(untagged)]
|
||||
pub enum SettleOff {
|
||||
SetOff(Vec<RawCipherText>),
|
||||
Transfer(Transfer),
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
#[derive(Copy)]
|
||||
pub enum LiquiditySourceType {
|
||||
Escrow,
|
||||
Overdraft,
|
||||
External,
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
pub struct LiquiditySource {
|
||||
pub address: Addr,
|
||||
pub source_type: LiquiditySourceType,
|
||||
}
|
||||
|
||||
impl std::cmp::Ord for LiquiditySource {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.address.cmp(&other.address)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for LiquiditySource {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.address.cmp(&other.address))
|
||||
}
|
||||
}
|
||||
|
||||
// PartialEq implemented in #[cw_serde]
|
||||
impl Eq for LiquiditySource {}
|
||||
|
||||
pub const STATE: Item<State> = Item::new("state");
|
||||
pub const OBLIGATIONS_KEY: &str = "obligations";
|
||||
pub const SETOFFS_KEY: &str = "setoffs";
|
||||
pub const LIQUIDITY_SOURCES_KEY: &str = "epoch_liquidity_sources";
|
||||
pub const LIQUIDITY_SOURCES: Map<&str, Vec<LiquiditySource>> = Map::new("liquidity_sources");
|
||||
|
||||
pub fn current_epoch_key(key: &str, storage: &dyn Storage) -> Result<String, StdError> {
|
||||
epoch_key(key, EPOCH_COUNTER.load(storage)?)
|
||||
}
|
||||
|
||||
pub fn previous_epoch_key(key: &str, storage: &dyn Storage) -> Result<String, StdError> {
|
||||
let epoch = EPOCH_COUNTER.load(storage)?;
|
||||
if epoch == Uint64::zero() {
|
||||
return Err(StdError::generic_err(
|
||||
"Cannot get previous epoch for epoch 0",
|
||||
));
|
||||
}
|
||||
epoch_key(key, epoch - Uint64::new(1))
|
||||
}
|
||||
|
||||
pub fn epoch_key(key: &str, epoch: Uint64) -> Result<String, StdError> {
|
||||
Ok(format!("{}/{}", epoch, key))
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
[package]
|
||||
name = "mtcs-enclave"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Informal Systems <hello@informal.systems>"]
|
||||
|
||||
[features]
|
||||
mock-sgx = ["quartz-common/mock-sgx-cw", "quartz-common/mock-sgx-enclave"]
|
||||
|
||||
[dependencies]
|
||||
# external
|
||||
async-trait.workspace = true
|
||||
clap.workspace = true
|
||||
color-eyre.workspace = true
|
||||
ecies.workspace = true
|
||||
hex.workspace = true
|
||||
k256.workspace = true
|
||||
prost.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
tonic.workspace = true
|
||||
uuid.workspace = true
|
||||
futures-util.workspace = true
|
||||
anyhow.workspace = true
|
||||
base64 = "0.22.1"
|
||||
reqwest.workspace = true
|
||||
|
||||
|
||||
# cosmos
|
||||
cosmrs.workspace = true
|
||||
cosmwasm-std.workspace = true
|
||||
tendermint.workspace = true
|
||||
tendermint-light-client.workspace = true
|
||||
tendermint-rpc.workspace = true
|
||||
|
||||
# quartz
|
||||
cw-tee-mtcs.workspace = true
|
||||
mtcs.workspace = true
|
||||
|
||||
# quartz
|
||||
quartz-common = { workspace = true, features = ["full"]}
|
||||
wasmd-client = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
cw-multi-test = "2.1.0"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build.workspace = true
|
|
@ -1 +0,0 @@
|
|||
## MTCS Server
|
|
@ -1,6 +0,0 @@
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_build::configure()
|
||||
.out_dir("src/prost")
|
||||
.compile(&["proto/mtcs.proto"], &["proto"])?;
|
||||
Ok(())
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package mtcs;
|
||||
|
||||
service Clearing {
|
||||
rpc Run (RunClearingRequest) returns (RunClearingResponse) {}
|
||||
}
|
||||
|
||||
message RunClearingRequest {
|
||||
string message = 1;
|
||||
}
|
||||
|
||||
message RunClearingResponse {
|
||||
string message = 1;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
# Quartz manifest file
|
||||
|
||||
loader.entrypoint = "file:{{ gramine.libos }}"
|
||||
libos.entrypoint = "{{ quartz_dir }}/target/release/mtcs-enclave"
|
||||
|
||||
loader.log_level = "{{ log_level }}"
|
||||
|
||||
loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}"
|
||||
loader.env.HOME = "{{ home }}"
|
||||
loader.env.INSIDE_SGX = "1"
|
||||
loader.env.TLS = { passthrough = true }
|
||||
loader.env.RA_TYPE = { passthrough = true }
|
||||
loader.env.RA_TLS_ALLOW_DEBUG_ENCLAVE_INSECURE = { passthrough = true }
|
||||
loader.env.RA_TLS_ALLOW_OUTDATED_TCB_INSECURE = { passthrough = true }
|
||||
loader.env.RA_TLS_MRENCLAVE = { passthrough = true }
|
||||
loader.env.RA_TLS_MRSIGNER = { passthrough = true }
|
||||
loader.env.RA_TLS_ISV_SVN = { passthrough = true }
|
||||
loader.env.RA_TLS_ISV_PROD_ID = { passthrough = true }
|
||||
loader.env.RA_TLS_EPID_API_KEY = { passthrough = true }
|
||||
loader.env.MYAPP_DATA = { passthrough = true }
|
||||
loader.env.QUARTZ_PORT = { passthrough = true }
|
||||
|
||||
loader.argv = ["enclave",
|
||||
"--chain-id", "testing",
|
||||
"--fmspc", "{{ fmspc }}",
|
||||
"--tcbinfo-contract", "{{ tcbinfo_contract }}",
|
||||
"--dcap-verifier-contract", "{{ dcap_verifier_contract }}",
|
||||
"--trusted-height", "{{ trusted_height }}",
|
||||
"--trusted-hash", "{{ trusted_hash }}"]
|
||||
|
||||
fs.mounts = [
|
||||
{ uri = "file:{{ gramine.runtimedir() }}", path = "/lib" },
|
||||
{ uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" },
|
||||
{ uri = "file:/usr/{{ arch_libdir }}", path = "/usr{{ arch_libdir }}" },
|
||||
{ uri = "file:{{ quartz_dir }}", path = "{{ quartz_dir }}" },
|
||||
]
|
||||
|
||||
# sgx.debug = true
|
||||
sgx.enclave_size = "512M"
|
||||
sgx.max_threads = 4
|
||||
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
|
||||
|
||||
sgx.remote_attestation = "{{ ra_type }}"
|
||||
sgx.ra_client_spid = "{{ ra_client_spid }}"
|
||||
sgx.ra_client_linkable = {{ 'true' if ra_client_linkable == '1' else 'false' }}
|
||||
|
||||
sgx.trusted_files = [
|
||||
"file:{{ gramine.libos }}",
|
||||
"file:{{ quartz_dir }}/target/release/mtcs-enclave",
|
||||
"file:{{ gramine.runtimedir() }}/",
|
||||
"file:{{ arch_libdir }}/",
|
||||
"file:/usr/{{ arch_libdir }}/",
|
||||
]
|
||||
|
||||
sgx.allowed_files = [
|
||||
"file:{{ quartz_dir }}/exchange.sk",
|
||||
"file:{{ quartz_dir }}/request.json",
|
||||
]
|
||||
|
||||
sys.insecure__allow_eventfd = true
|
||||
sys.enable_sigterm_injection = true
|
|
@ -1,72 +0,0 @@
|
|||
use std::net::SocketAddr;
|
||||
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use cosmrs::AccountId;
|
||||
use quartz_common::enclave::types::Fmspc;
|
||||
use tendermint::Hash;
|
||||
use tendermint_light_client::types::{Height, TrustThreshold};
|
||||
|
||||
fn parse_trust_threshold(s: &str) -> Result<TrustThreshold> {
|
||||
if let Some((l, r)) = s.split_once('/') {
|
||||
TrustThreshold::new(l.parse()?, r.parse()?).map_err(Into::into)
|
||||
} else {
|
||||
Err(eyre!(
|
||||
"invalid trust threshold: {s}, format must be X/Y where X and Y are integers"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
/// RPC server address
|
||||
#[clap(long, default_value = "127.0.0.1:11090")]
|
||||
pub rpc_addr: SocketAddr,
|
||||
|
||||
/// Identifier of the chain
|
||||
#[clap(long)]
|
||||
pub chain_id: String,
|
||||
|
||||
/// FMSPC (Family-Model-Stepping-Platform-Custom SKU)
|
||||
#[clap(long)]
|
||||
pub fmspc: Option<Fmspc>,
|
||||
|
||||
/// TcbInfo contract address
|
||||
#[clap(long)]
|
||||
pub tcbinfo_contract: Option<AccountId>,
|
||||
|
||||
/// DCAP verifier contract address
|
||||
#[clap(long)]
|
||||
pub dcap_verifier_contract: Option<AccountId>,
|
||||
|
||||
/// Height of the trusted header (AKA root-of-trust)
|
||||
#[clap(long)]
|
||||
pub trusted_height: Height,
|
||||
|
||||
/// Hash of the trusted header (AKA root-of-trust)
|
||||
#[clap(long)]
|
||||
pub trusted_hash: Hash,
|
||||
|
||||
/// Trust threshold
|
||||
#[clap(long, value_parser = parse_trust_threshold, default_value_t = TrustThreshold::TWO_THIRDS)]
|
||||
pub trust_threshold: TrustThreshold,
|
||||
|
||||
/// Trusting period, in seconds (default: two weeks)
|
||||
#[clap(long, default_value = "1209600")]
|
||||
pub trusting_period: u64,
|
||||
|
||||
/// Maximum clock drift, in seconds
|
||||
#[clap(long, default_value = "5")]
|
||||
pub max_clock_drift: u64,
|
||||
|
||||
/// Maximum block lag, in seconds
|
||||
#[clap(long, default_value = "5")]
|
||||
pub max_block_lag: u64,
|
||||
|
||||
#[clap(long, default_value = "127.0.0.1:11090")]
|
||||
pub node_url: String,
|
||||
|
||||
#[clap(long, default_value = "admin")]
|
||||
pub tx_sender: String,
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
pub mod proto;
|
||||
pub mod types;
|
|
@ -1,88 +0,0 @@
|
|||
#![forbid(unsafe_code)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![warn(
|
||||
clippy::checked_conversions,
|
||||
clippy::panic,
|
||||
clippy::panic_in_result_fn,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
rust_2018_idioms,
|
||||
unused_lifetimes,
|
||||
unused_import_braces,
|
||||
unused_qualifications
|
||||
)]
|
||||
|
||||
mod cli;
|
||||
mod mtcs_server;
|
||||
mod proto;
|
||||
mod types;
|
||||
mod wslistener;
|
||||
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
use cli::Cli;
|
||||
use mtcs_server::MtcsService;
|
||||
use quartz_common::{
|
||||
contract::state::{Config, LightClientOpts},
|
||||
enclave::{
|
||||
attestor::{self, Attestor},
|
||||
server::{QuartzServer, WsListenerConfig},
|
||||
},
|
||||
};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = Cli::parse();
|
||||
|
||||
let light_client_opts = LightClientOpts::new(
|
||||
args.chain_id.clone(),
|
||||
args.trusted_height.into(),
|
||||
Vec::from(args.trusted_hash)
|
||||
.try_into()
|
||||
.expect("invalid trusted hash"),
|
||||
(
|
||||
args.trust_threshold.numerator(),
|
||||
args.trust_threshold.denominator(),
|
||||
),
|
||||
args.trusting_period,
|
||||
args.max_clock_drift,
|
||||
args.max_block_lag,
|
||||
)?;
|
||||
|
||||
#[cfg(not(feature = "mock-sgx"))]
|
||||
let attestor = attestor::DcapAttestor {
|
||||
fmspc: args.fmspc.expect("FMSPC is required for DCAP"),
|
||||
};
|
||||
|
||||
#[cfg(feature = "mock-sgx")]
|
||||
let attestor = attestor::MockAttestor;
|
||||
|
||||
let config: Config = Config::new(
|
||||
attestor.mr_enclave()?,
|
||||
Duration::from_secs(30 * 24 * 60),
|
||||
light_client_opts,
|
||||
args.tcbinfo_contract.map(|c| c.to_string()),
|
||||
args.dcap_verifier_contract.map(|c| c.to_string()),
|
||||
);
|
||||
|
||||
let ws_config = WsListenerConfig {
|
||||
node_url: args.node_url,
|
||||
tx_sender: args.tx_sender,
|
||||
trusted_hash: args.trusted_hash,
|
||||
trusted_height: args.trusted_height,
|
||||
chain_id: args.chain_id,
|
||||
};
|
||||
|
||||
let sk = Arc::new(Mutex::new(None));
|
||||
|
||||
QuartzServer::new(config.clone(), sk.clone(), attestor.clone(), ws_config)
|
||||
.add_service(MtcsService::new(config, sk, attestor))
|
||||
.serve(args.rpc_addr)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
use std::{
|
||||
collections::BTreeMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
||||
use cw_tee_mtcs::{
|
||||
msg::execute::SubmitSetoffsMsg,
|
||||
state::{LiquiditySource, LiquiditySourceType, RawHash, SettleOff, Transfer},
|
||||
};
|
||||
use ecies::decrypt;
|
||||
use k256::ecdsa::SigningKey;
|
||||
use mtcs::{
|
||||
algo::mcmf::primal_dual::PrimalDual, impls::complex_id::ComplexIdMtcs,
|
||||
obligation::SimpleObligation, prelude::DefaultMtcs, setoff::SimpleSetoff, Mtcs,
|
||||
};
|
||||
use quartz_common::{
|
||||
contract::{msg::execute::attested::RawAttested, state::Config},
|
||||
enclave::{attestor::Attestor, server::IntoServer},
|
||||
};
|
||||
use tonic::{Request, Response, Result as TonicResult, Status};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
proto::{
|
||||
clearing_server::{Clearing, ClearingServer},
|
||||
RunClearingRequest, RunClearingResponse,
|
||||
},
|
||||
types::{ContractObligation, RunClearingMessage},
|
||||
};
|
||||
|
||||
pub type RawCipherText = HexBinary;
|
||||
|
||||
impl<A: Attestor> IntoServer for MtcsService<A> {
|
||||
type Server = ClearingServer<MtcsService<A>>;
|
||||
|
||||
fn into_server(self) -> Self::Server {
|
||||
ClearingServer::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MtcsService<A> {
|
||||
#[allow(dead_code)]
|
||||
config: Config, // TODO: this config is not used anywhere
|
||||
sk: Arc<Mutex<Option<SigningKey>>>,
|
||||
attestor: A,
|
||||
}
|
||||
|
||||
impl<A> MtcsService<A>
|
||||
where
|
||||
A: Attestor,
|
||||
{
|
||||
pub fn new(config: Config, sk: Arc<Mutex<Option<SigningKey>>>, attestor: A) -> Self {
|
||||
Self {
|
||||
config,
|
||||
sk,
|
||||
attestor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl<A> Clearing for MtcsService<A>
|
||||
where
|
||||
A: Attestor + Send + Sync + 'static,
|
||||
{
|
||||
async fn run(
|
||||
&self,
|
||||
request: Request<RunClearingRequest>,
|
||||
) -> TonicResult<Response<RunClearingResponse>> {
|
||||
// Light client check
|
||||
let message: RunClearingMessage = {
|
||||
let message = request.into_inner().message;
|
||||
serde_json::from_str(&message).map_err(|e| Status::invalid_argument(e.to_string()))?
|
||||
};
|
||||
|
||||
// let (proof_value, message) = message
|
||||
// .verify(self.config.light_client_opts())
|
||||
// .map_err(Status::failed_precondition)?;
|
||||
|
||||
// let proof_value_matches_msg =
|
||||
// serde_json::to_string(&message.intents).is_ok_and(|s| s.as_bytes() == proof_value);
|
||||
// if !proof_value_matches_msg {
|
||||
// return Err(Status::failed_precondition("proof verification"));
|
||||
// }
|
||||
// TODO: ensure no duplicates somewhere else!
|
||||
let liquidity_sources: Vec<LiquiditySource> =
|
||||
message.liquidity_sources.into_iter().collect();
|
||||
let digests_ciphertexts: BTreeMap<HexBinary, HexBinary> = message.intents;
|
||||
let (digests, ciphertexts): (Vec<_>, Vec<_>) = digests_ciphertexts.into_iter().unzip();
|
||||
|
||||
let sk = self.sk.lock().unwrap();
|
||||
let obligations: Vec<SimpleObligation<LiquiditySource, i64, Uuid>> = ciphertexts
|
||||
.into_iter()
|
||||
.map(|ciphertext| decrypt_obligation(sk.as_ref().unwrap(), &ciphertext))
|
||||
.collect();
|
||||
|
||||
let mut mtcs = ComplexIdMtcs::wrapping(DefaultMtcs::new(PrimalDual::default()));
|
||||
|
||||
let setoffs: Vec<SimpleSetoff<LiquiditySource, i64, Uuid>> = mtcs.run(obligations).unwrap();
|
||||
let setoffs_enc: BTreeMap<RawHash, SettleOff> = setoffs
|
||||
.into_iter()
|
||||
.map(|so| into_settle_offs(so, &liquidity_sources))
|
||||
.zip(digests)
|
||||
.map(|(settle_off, digest)| (digest, settle_off))
|
||||
.collect();
|
||||
|
||||
let msg = SubmitSetoffsMsg { setoffs_enc };
|
||||
println!("setoff_msg: {:?}", msg);
|
||||
|
||||
let attestation = self
|
||||
.attestor
|
||||
.attestation(msg.clone())
|
||||
.map_err(|e| Status::internal(e.to_string()))?;
|
||||
|
||||
let attested_msg = RawAttested {
|
||||
msg,
|
||||
attestation: A::RawAttestation::from(attestation),
|
||||
};
|
||||
let message = serde_json::to_string(&attested_msg).unwrap();
|
||||
Ok(Response::new(RunClearingResponse { message }))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Switch from Vec<_> to Vec<LiquiditySource>
|
||||
fn into_settle_offs(
|
||||
so: SimpleSetoff<LiquiditySource, i64, Uuid>,
|
||||
liquidity_sources: &Vec<LiquiditySource>,
|
||||
) -> SettleOff {
|
||||
println!("\nsetoff: {:?}", so);
|
||||
println!("\nliq sources: {:?}", liquidity_sources);
|
||||
|
||||
// TODO: temporary patch, fix issue with liquidity sources becoming type External so that .contains() can be called directly
|
||||
let liquidity_sources_addrs = liquidity_sources
|
||||
.iter()
|
||||
.map(|lqs| lqs.address.clone())
|
||||
.collect::<Vec<Addr>>();
|
||||
|
||||
// In tenders and acceptances, the creditor's balance decreases
|
||||
if liquidity_sources_addrs.contains(&so.debtor.address)
|
||||
|| liquidity_sources_addrs.contains(&so.creditor.address)
|
||||
{
|
||||
SettleOff::Transfer(Transfer {
|
||||
payer: so.creditor.address.clone(),
|
||||
payee: so.debtor.address.clone(),
|
||||
// TODO: Include denominations
|
||||
amount: ("peppicoin".to_owned(), Uint128::from(so.set_off as u128)),
|
||||
})
|
||||
} else {
|
||||
// TODO: Tracked by issue #22
|
||||
|
||||
// A no-op for the time being.
|
||||
SettleOff::SetOff(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
fn decrypt_obligation(
|
||||
sk: &SigningKey,
|
||||
ciphertext: &RawCipherText,
|
||||
) -> SimpleObligation<LiquiditySource, i64, Uuid> {
|
||||
let o: ContractObligation = {
|
||||
let o = decrypt(&sk.to_bytes(), ciphertext).unwrap();
|
||||
serde_json::from_slice(&o).unwrap()
|
||||
};
|
||||
|
||||
SimpleObligation::new(
|
||||
None,
|
||||
LiquiditySource {
|
||||
address: o.debtor,
|
||||
source_type: LiquiditySourceType::External,
|
||||
},
|
||||
LiquiditySource {
|
||||
address: o.creditor,
|
||||
source_type: LiquiditySourceType::External,
|
||||
},
|
||||
i64::try_from(o.amount).unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
|
@ -1,290 +0,0 @@
|
|||
// This file is @generated by prost-build.
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct RunClearingRequest {
|
||||
#[prost(string, tag = "1")]
|
||||
pub message: ::prost::alloc::string::String,
|
||||
}
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct RunClearingResponse {
|
||||
#[prost(string, tag = "1")]
|
||||
pub message: ::prost::alloc::string::String,
|
||||
}
|
||||
/// Generated client implementations.
|
||||
pub mod clearing_client {
|
||||
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
|
||||
use tonic::codegen::*;
|
||||
use tonic::codegen::http::Uri;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ClearingClient<T> {
|
||||
inner: tonic::client::Grpc<T>,
|
||||
}
|
||||
impl ClearingClient<tonic::transport::Channel> {
|
||||
/// Attempt to create a new client by connecting to a given endpoint.
|
||||
pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
|
||||
where
|
||||
D: TryInto<tonic::transport::Endpoint>,
|
||||
D::Error: Into<StdError>,
|
||||
{
|
||||
let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
|
||||
Ok(Self::new(conn))
|
||||
}
|
||||
}
|
||||
impl<T> ClearingClient<T>
|
||||
where
|
||||
T: tonic::client::GrpcService<tonic::body::BoxBody>,
|
||||
T::Error: Into<StdError>,
|
||||
T::ResponseBody: Body<Data = Bytes> + Send + 'static,
|
||||
<T::ResponseBody as Body>::Error: Into<StdError> + Send,
|
||||
{
|
||||
pub fn new(inner: T) -> Self {
|
||||
let inner = tonic::client::Grpc::new(inner);
|
||||
Self { inner }
|
||||
}
|
||||
pub fn with_origin(inner: T, origin: Uri) -> Self {
|
||||
let inner = tonic::client::Grpc::with_origin(inner, origin);
|
||||
Self { inner }
|
||||
}
|
||||
pub fn with_interceptor<F>(
|
||||
inner: T,
|
||||
interceptor: F,
|
||||
) -> ClearingClient<InterceptedService<T, F>>
|
||||
where
|
||||
F: tonic::service::Interceptor,
|
||||
T::ResponseBody: Default,
|
||||
T: tonic::codegen::Service<
|
||||
http::Request<tonic::body::BoxBody>,
|
||||
Response = http::Response<
|
||||
<T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
|
||||
>,
|
||||
>,
|
||||
<T as tonic::codegen::Service<
|
||||
http::Request<tonic::body::BoxBody>,
|
||||
>>::Error: Into<StdError> + Send + Sync,
|
||||
{
|
||||
ClearingClient::new(InterceptedService::new(inner, interceptor))
|
||||
}
|
||||
/// Compress requests with the given encoding.
|
||||
///
|
||||
/// This requires the server to support it otherwise it might respond with an
|
||||
/// error.
|
||||
#[must_use]
|
||||
pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
|
||||
self.inner = self.inner.send_compressed(encoding);
|
||||
self
|
||||
}
|
||||
/// Enable decompressing responses.
|
||||
#[must_use]
|
||||
pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
|
||||
self.inner = self.inner.accept_compressed(encoding);
|
||||
self
|
||||
}
|
||||
/// Limits the maximum size of a decoded message.
|
||||
///
|
||||
/// Default: `4MB`
|
||||
#[must_use]
|
||||
pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
|
||||
self.inner = self.inner.max_decoding_message_size(limit);
|
||||
self
|
||||
}
|
||||
/// Limits the maximum size of an encoded message.
|
||||
///
|
||||
/// Default: `usize::MAX`
|
||||
#[must_use]
|
||||
pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
|
||||
self.inner = self.inner.max_encoding_message_size(limit);
|
||||
self
|
||||
}
|
||||
pub async fn run(
|
||||
&mut self,
|
||||
request: impl tonic::IntoRequest<super::RunClearingRequest>,
|
||||
) -> std::result::Result<
|
||||
tonic::Response<super::RunClearingResponse>,
|
||||
tonic::Status,
|
||||
> {
|
||||
self.inner
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let path = http::uri::PathAndQuery::from_static("/mtcs.Clearing/Run");
|
||||
let mut req = request.into_request();
|
||||
req.extensions_mut().insert(GrpcMethod::new("mtcs.Clearing", "Run"));
|
||||
self.inner.unary(req, path, codec).await
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Generated server implementations.
|
||||
pub mod clearing_server {
|
||||
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
|
||||
use tonic::codegen::*;
|
||||
/// Generated trait containing gRPC methods that should be implemented for use with ClearingServer.
|
||||
#[async_trait]
|
||||
pub trait Clearing: Send + Sync + 'static {
|
||||
async fn run(
|
||||
&self,
|
||||
request: tonic::Request<super::RunClearingRequest>,
|
||||
) -> std::result::Result<
|
||||
tonic::Response<super::RunClearingResponse>,
|
||||
tonic::Status,
|
||||
>;
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ClearingServer<T: Clearing> {
|
||||
inner: Arc<T>,
|
||||
accept_compression_encodings: EnabledCompressionEncodings,
|
||||
send_compression_encodings: EnabledCompressionEncodings,
|
||||
max_decoding_message_size: Option<usize>,
|
||||
max_encoding_message_size: Option<usize>,
|
||||
}
|
||||
impl<T: Clearing> ClearingServer<T> {
|
||||
pub fn new(inner: T) -> Self {
|
||||
Self::from_arc(Arc::new(inner))
|
||||
}
|
||||
pub fn from_arc(inner: Arc<T>) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
accept_compression_encodings: Default::default(),
|
||||
send_compression_encodings: Default::default(),
|
||||
max_decoding_message_size: None,
|
||||
max_encoding_message_size: None,
|
||||
}
|
||||
}
|
||||
pub fn with_interceptor<F>(
|
||||
inner: T,
|
||||
interceptor: F,
|
||||
) -> InterceptedService<Self, F>
|
||||
where
|
||||
F: tonic::service::Interceptor,
|
||||
{
|
||||
InterceptedService::new(Self::new(inner), interceptor)
|
||||
}
|
||||
/// Enable decompressing requests with the given encoding.
|
||||
#[must_use]
|
||||
pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
|
||||
self.accept_compression_encodings.enable(encoding);
|
||||
self
|
||||
}
|
||||
/// Compress responses with the given encoding, if the client supports it.
|
||||
#[must_use]
|
||||
pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
|
||||
self.send_compression_encodings.enable(encoding);
|
||||
self
|
||||
}
|
||||
/// Limits the maximum size of a decoded message.
|
||||
///
|
||||
/// Default: `4MB`
|
||||
#[must_use]
|
||||
pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
|
||||
self.max_decoding_message_size = Some(limit);
|
||||
self
|
||||
}
|
||||
/// Limits the maximum size of an encoded message.
|
||||
///
|
||||
/// Default: `usize::MAX`
|
||||
#[must_use]
|
||||
pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
|
||||
self.max_encoding_message_size = Some(limit);
|
||||
self
|
||||
}
|
||||
}
|
||||
impl<T, B> tonic::codegen::Service<http::Request<B>> for ClearingServer<T>
|
||||
where
|
||||
T: Clearing,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<StdError> + Send + 'static,
|
||||
{
|
||||
type Response = http::Response<tonic::body::BoxBody>;
|
||||
type Error = std::convert::Infallible;
|
||||
type Future = BoxFuture<Self::Response, Self::Error>;
|
||||
fn poll_ready(
|
||||
&mut self,
|
||||
_cx: &mut Context<'_>,
|
||||
) -> Poll<std::result::Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
fn call(&mut self, req: http::Request<B>) -> Self::Future {
|
||||
match req.uri().path() {
|
||||
"/mtcs.Clearing/Run" => {
|
||||
#[allow(non_camel_case_types)]
|
||||
struct RunSvc<T: Clearing>(pub Arc<T>);
|
||||
impl<
|
||||
T: Clearing,
|
||||
> tonic::server::UnaryService<super::RunClearingRequest>
|
||||
for RunSvc<T> {
|
||||
type Response = super::RunClearingResponse;
|
||||
type Future = BoxFuture<
|
||||
tonic::Response<Self::Response>,
|
||||
tonic::Status,
|
||||
>;
|
||||
fn call(
|
||||
&mut self,
|
||||
request: tonic::Request<super::RunClearingRequest>,
|
||||
) -> Self::Future {
|
||||
let inner = Arc::clone(&self.0);
|
||||
let fut = async move {
|
||||
<T as Clearing>::run(&inner, request).await
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
let accept_compression_encodings = self.accept_compression_encodings;
|
||||
let send_compression_encodings = self.send_compression_encodings;
|
||||
let max_decoding_message_size = self.max_decoding_message_size;
|
||||
let max_encoding_message_size = self.max_encoding_message_size;
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let method = RunSvc(inner);
|
||||
let codec = tonic::codec::ProstCodec::default();
|
||||
let mut grpc = tonic::server::Grpc::new(codec)
|
||||
.apply_compression_config(
|
||||
accept_compression_encodings,
|
||||
send_compression_encodings,
|
||||
)
|
||||
.apply_max_message_size_config(
|
||||
max_decoding_message_size,
|
||||
max_encoding_message_size,
|
||||
);
|
||||
let res = grpc.unary(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
_ => {
|
||||
Box::pin(async move {
|
||||
Ok(
|
||||
http::Response::builder()
|
||||
.status(200)
|
||||
.header("grpc-status", tonic::Code::Unimplemented as i32)
|
||||
.header(
|
||||
http::header::CONTENT_TYPE,
|
||||
tonic::metadata::GRPC_CONTENT_TYPE,
|
||||
)
|
||||
.body(empty_body())
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: Clearing> Clone for ClearingServer<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let inner = self.inner.clone();
|
||||
Self {
|
||||
inner,
|
||||
accept_compression_encodings: self.accept_compression_encodings,
|
||||
send_compression_encodings: self.send_compression_encodings,
|
||||
max_decoding_message_size: self.max_decoding_message_size,
|
||||
max_encoding_message_size: self.max_encoding_message_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: Clearing> tonic::server::NamedService for ClearingServer<T> {
|
||||
const NAME: &'static str = "mtcs.Clearing";
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
#![allow(clippy::unwrap_used, unused_qualifications)]
|
||||
|
||||
include!(concat!("prost/", "mtcs.rs"));
|
|
@ -1,68 +0,0 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use cosmwasm_std::{Addr, HexBinary};
|
||||
use cw_tee_mtcs::state::{LiquiditySource, RawCipherText, RawHash};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RunClearingMessage {
|
||||
pub intents: BTreeMap<RawHash, RawCipherText>,
|
||||
pub liquidity_sources: BTreeSet<LiquiditySource>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ContractObligation {
|
||||
pub debtor: Addr,
|
||||
pub creditor: Addr,
|
||||
pub amount: u64,
|
||||
#[serde(default)]
|
||||
pub salt: HexBinary,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RawObligation {
|
||||
pub debtor: HexBinary,
|
||||
pub creditor: HexBinary,
|
||||
pub amount: u64,
|
||||
#[serde(default)]
|
||||
pub salt: HexBinary,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RawEncryptedObligation {
|
||||
pub digest: HexBinary,
|
||||
pub ciphertext: HexBinary,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SubmitObligationsMsg {
|
||||
pub submit_obligations: SubmitObligationsMsgInner,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SubmitObligationsMsgInner {
|
||||
pub obligations: Vec<RawEncryptedObligation>,
|
||||
pub liquidity_sources: Vec<LiquiditySource>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum RawSetOff {
|
||||
SetOff(Vec<HexBinary>),
|
||||
Transfer(RawSetOffTransfer),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RawSetOffTransfer {
|
||||
pub payer: String,
|
||||
pub payee: String,
|
||||
pub amount: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RawOffset {
|
||||
pub debtor: HexBinary,
|
||||
pub creditor: HexBinary,
|
||||
pub amount: u64,
|
||||
pub set_off: u64,
|
||||
}
|
|
@ -1,231 +0,0 @@
|
|||
//TODO: get rid of this
|
||||
use std::{collections::BTreeMap, str::FromStr};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use base64::prelude::*;
|
||||
use cosmrs::{tendermint::chain::Id as ChainId, AccountId};
|
||||
use cosmwasm_std::{HexBinary, Uint64};
|
||||
use cw_tee_mtcs::msg::{
|
||||
execute::SubmitSetoffsMsg, AttestedMsg, ExecuteMsg, GetLiquiditySourcesResponse,
|
||||
QueryMsg::GetLiquiditySources,
|
||||
};
|
||||
use quartz_common::{
|
||||
contract::msg::execute::attested::{
|
||||
MockAttestation, RawAttested, RawAttestedMsgSansHandler, RawMockAttestation,
|
||||
},
|
||||
enclave::{
|
||||
attestor::Attestor,
|
||||
server::{WebSocketHandler, WsListenerConfig},
|
||||
},
|
||||
};
|
||||
use reqwest::Url;
|
||||
// use quartz_tee_ra::{intel_sgx::epid::types::ReportBody, IASReport};
|
||||
use serde_json::json;
|
||||
use tendermint_rpc::{event::Event, query::EventType};
|
||||
use tonic::Request;
|
||||
use wasmd_client::{CliWasmdClient, QueryResult, WasmdClient};
|
||||
|
||||
use crate::{
|
||||
mtcs_server::MtcsService,
|
||||
proto::{clearing_server::Clearing, RunClearingRequest},
|
||||
types::RunClearingMessage,
|
||||
};
|
||||
|
||||
// TODO: Need to prevent listener from taking actions until handshake is completed
|
||||
#[async_trait::async_trait]
|
||||
impl<A: Attestor> WebSocketHandler for MtcsService<A> {
|
||||
async fn handle(&self, event: Event, config: WsListenerConfig) -> Result<()> {
|
||||
// Validation
|
||||
if !is_init_clearing_event(&event) {
|
||||
return Ok(());
|
||||
} else {
|
||||
println!("Found clearing event");
|
||||
|
||||
let mut sender = None;
|
||||
let mut contract_address = None;
|
||||
|
||||
if let Some(events) = &event.events {
|
||||
for (key, values) in events {
|
||||
match key.as_str() {
|
||||
"message.sender" => {
|
||||
sender = values.first().cloned();
|
||||
}
|
||||
"wasm._contract_address" => {
|
||||
contract_address = values.first().cloned();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add some checks based on event messages
|
||||
|
||||
if sender.is_none() || contract_address.is_none() {
|
||||
return Ok(()); // TODO: change return type
|
||||
}
|
||||
|
||||
handler(
|
||||
self,
|
||||
&contract_address
|
||||
.expect("infallible")
|
||||
.parse::<AccountId>()
|
||||
.map_err(|e| anyhow!(e))?,
|
||||
sender.expect("infallible"),
|
||||
&config.node_url,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_init_clearing_event(event: &Event) -> bool {
|
||||
// Check if the event is a transaction type
|
||||
if let Some(EventType::Tx) = event.event_type() {
|
||||
// Check for the "wasm.action" key with the value "init_clearing"
|
||||
if let Some(events) = &event.events {
|
||||
return events.iter().any(|(key, values)| {
|
||||
key == "wasm.action" && values.contains(&"init_clearing".to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
async fn handler<A: Attestor>(
|
||||
client: &MtcsService<A>,
|
||||
contract: &AccountId,
|
||||
sender: String,
|
||||
node_url: &str,
|
||||
) -> Result<()> {
|
||||
let chain_id = &ChainId::from_str("testing")?;
|
||||
let httpurl = Url::parse(&format!("http://{}", node_url))?;
|
||||
let wasmd_client = CliWasmdClient::new(httpurl);
|
||||
|
||||
// Query obligations and liquidity sources from chain
|
||||
let clearing_contents = query_chain(&wasmd_client, contract).await?;
|
||||
|
||||
// Send queried data to enclave over gRPC
|
||||
let request = Request::new(RunClearingRequest {
|
||||
message: json!(clearing_contents).to_string(),
|
||||
});
|
||||
|
||||
let clearing_response = client
|
||||
.run(request)
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to communicate to relayer. {e}"))?
|
||||
.into_inner();
|
||||
// Extract json from the Protobuf message
|
||||
let attested: RawAttested<SubmitSetoffsMsg, Vec<u8>> =
|
||||
serde_json::from_str(&clearing_response.message)
|
||||
.map_err(|e| anyhow!("Error serializing SubmitSetoffs: {}", e))?;
|
||||
|
||||
// TODO add non-mock support, get IAS report and build attested message
|
||||
let msg = RawAttestedMsgSansHandler(attested.msg);
|
||||
|
||||
let setoffs_msg = ExecuteMsg::SubmitSetoffs::<RawMockAttestation>(AttestedMsg {
|
||||
msg,
|
||||
attestation: MockAttestation(attested.attestation.try_into().unwrap()).into(),
|
||||
});
|
||||
|
||||
// Send setoffs to mtcs contract on chain
|
||||
let output =
|
||||
wasmd_client.tx_execute(contract, chain_id, 2000000, &sender, json!(setoffs_msg))?;
|
||||
|
||||
println!("Setoffs TX: {}", output);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: replace raw queries with smart
|
||||
async fn query_chain(
|
||||
wasmd_client: &CliWasmdClient,
|
||||
contract: &AccountId,
|
||||
) -> Result<RunClearingMessage> {
|
||||
// Get epoch counter
|
||||
let resp: QueryResult<String> = wasmd_client
|
||||
.query_raw(contract, hex::encode("epoch_counter"))
|
||||
.map_err(|e| anyhow!("Problem querying epoch: {}", e))?;
|
||||
|
||||
let mut epoch_counter: usize = String::from_utf8(BASE64_STANDARD.decode(resp.data)?)?
|
||||
.trim_matches('"')
|
||||
.parse::<usize>()?;
|
||||
|
||||
if epoch_counter > 1 {
|
||||
epoch_counter -= 1;
|
||||
}
|
||||
|
||||
// TODO: replace with tracer log here
|
||||
// println!("epoch: {}", epoch_counter);
|
||||
|
||||
// Get obligations
|
||||
let resp: QueryResult<String> = wasmd_client
|
||||
.query_raw(
|
||||
contract,
|
||||
hex::encode(format!("{}/obligations", epoch_counter)),
|
||||
)
|
||||
.map_err(|e| anyhow!("Problem querying obligatons: {}", e))?;
|
||||
|
||||
let decoded_obligs = BASE64_STANDARD.decode(resp.data)?;
|
||||
let obligations_map: BTreeMap<HexBinary, HexBinary> =
|
||||
serde_json::from_slice(&decoded_obligs).unwrap_or_default();
|
||||
// println!("obligations \n {:?}", obligations_map);
|
||||
// TODO: replace with tracer log here
|
||||
|
||||
// Get liquidity sources
|
||||
let resp: QueryResult<GetLiquiditySourcesResponse> = wasmd_client
|
||||
.query_smart(
|
||||
contract,
|
||||
json!(GetLiquiditySources {
|
||||
epoch: Some(Uint64::new(epoch_counter as u64))
|
||||
}),
|
||||
)
|
||||
.map_err(|e| anyhow!("Problem querying liquidity sources: {}", e))?;
|
||||
|
||||
let liquidity_sources = resp.data.liquidity_sources;
|
||||
// TODO: replace with tracer log here
|
||||
// println!("liquidity_sources \n {:?}", liquidity_sources);
|
||||
|
||||
Ok(RunClearingMessage {
|
||||
intents: obligations_map,
|
||||
liquidity_sources: liquidity_sources.into_iter().collect(),
|
||||
})
|
||||
}
|
||||
|
||||
// Request the IAS report for EPID attestations
|
||||
// async fn gramine_ias_request(
|
||||
// attested_msg: Vec<u8>,
|
||||
// user: &str,
|
||||
// ) -> Result<EpidAttestation, anyhow::Error> {
|
||||
// let ias_api_key = String::from("669244b3e6364b5888289a11d2a1726d");
|
||||
// let ra_client_spid = String::from("51CAF5A48B450D624AEFE3286D314894");
|
||||
// let quote_file = format!("/tmp/{}_test.quote", user);
|
||||
// let report_file = format!("/tmp/{}_datareport", user);
|
||||
// let report_sig_file = format!("/tmp/{}_datareportsig", user);
|
||||
|
||||
// // Write the binary data to a file
|
||||
// let mut file = File::create("e_file).await?;
|
||||
// file.write_all(&attested_msg)
|
||||
// .await
|
||||
// .map_err(|e| anyhow!("Couldn't write to file. {e}"))?;
|
||||
|
||||
// let mut gramine = Command::new("gramine-sgx-ias-request");
|
||||
// let command = gramine
|
||||
// .arg("report")
|
||||
// .args(["-g", &ra_client_spid])
|
||||
// .args(["-k", &ias_api_key])
|
||||
// .args(["-q", "e_file])
|
||||
// .args(["-r", &report_file])
|
||||
// .args(["-s", &report_sig_file]);
|
||||
|
||||
// let output = command.output()?;
|
||||
// if !output.status.success() {
|
||||
// return Err(anyhow!("Couldn't run gramine. {:?}", output));
|
||||
// }
|
||||
|
||||
// let report: ReportBody = serde_json::from_str(&fs::read_to_string(report_file).await?)?;
|
||||
// let report_sig_str = fs::read_to_string(report_sig_file).await?.replace('\r', "");
|
||||
// let report_sig: Binary = Binary::from_base64(report_sig_str.trim())?;
|
||||
|
||||
// Ok(EpidAttestation::new(IASReport { report, report_sig }))
|
||||
// }
|
|
@ -1,2 +0,0 @@
|
|||
[build]
|
||||
target-dir = "target"
|
|
@ -1,75 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Deploy the specified contract's `WASM_BIN` to the chain specified by `CHAIN_ID` using the `USER_ADDR` account.
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 WASM_BIN [COUNT]"
|
||||
echo "Example: $0 artifacts/cofi_karma_game.wasm"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "❌ Error: Missing WASM_BIN parameter. Please check if all parameters were specified."
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ "$#" -gt 9 ]; then
|
||||
echo "❌ Error: Incorrect number of parameters."
|
||||
usage
|
||||
fi
|
||||
|
||||
USER_ADDR=${USER_ADDR:-$(wasmd keys show -a admin)}
|
||||
WASM_BIN="$1"
|
||||
CHAIN_ID=${CHAIN_ID:-testing}
|
||||
NODE_URL=${NODE_URL:-127.0.0.1:26657}
|
||||
LABEL=${LABEL:-bisenzone-mvp}
|
||||
COUNT=${COUNT:-0}
|
||||
INSTANTIATE_MSG=${INSTANTIATE_MSG:-"null"}
|
||||
|
||||
TXFLAG="--chain-id ${CHAIN_ID} --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3"
|
||||
|
||||
CMD="wasmd --node http://$NODE_URL"
|
||||
|
||||
echo "🚀 Deploying WASM contract '${WASM_BIN}' on chain '${CHAIN_ID}' using account '${USER_ADDR}'..."
|
||||
echo " with cmd : $CMD"
|
||||
echo "===================================================================="
|
||||
|
||||
RES=$($CMD tx wasm store "$WASM_BIN" --from "$USER_ADDR" $TXFLAG -y --output json)
|
||||
echo $RES
|
||||
TX_HASH=$(echo $RES | jq -r '.["txhash"]')
|
||||
|
||||
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
||||
echo "... 🕐 waiting for contract to deploy from tx hash $TX_HASH"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
RES=$($CMD query tx "$TX_HASH" --output json)
|
||||
CODE_ID=$(echo $RES | jq -r '.logs[0].events[1].attributes[1].value')
|
||||
|
||||
echo ""
|
||||
echo "🚀 Instantiating contract with the following parameters:"
|
||||
echo "--------------------------------------------------------"
|
||||
echo "Label: ${LABEL}"
|
||||
echo "--------------------------------------------------------"
|
||||
|
||||
RES=$($CMD tx wasm instantiate "$CODE_ID" "$INSTANTIATE_MSG" --from "$USER_ADDR" --label $LABEL $TXFLAG -y --no-admin --output json)
|
||||
TX_HASH=$(echo $RES | jq -r '.["txhash"]')
|
||||
|
||||
|
||||
echo ""
|
||||
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
||||
echo "... 🕐 waiting for contract to be queryable from tx hash $TX_HASH"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
RES=$($CMD query wasm list-contract-by-code "$CODE_ID" --output json)
|
||||
CONTRACT=$(echo $RES | jq -r '.contracts[0]')
|
||||
|
||||
echo "🚀 Successfully deployed and instantiated contract!"
|
||||
echo "🔗 Chain ID: ${CHAIN_ID}"
|
||||
echo "🆔 Code ID: ${CODE_ID}"
|
||||
echo "📌 Contract Address: ${CONTRACT}"
|
||||
echo "🔑 Contract Key: ${KEY}"
|
||||
echo "🔖 Contract Label: ${LABEL}"
|
|
@ -1,321 +0,0 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ExecuteMsg",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deposit",
|
||||
"withdraw"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"quartz"
|
||||
],
|
||||
"properties": {
|
||||
"quartz": {
|
||||
"$ref": "#/definitions/RawExecute_for_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"transfer_request"
|
||||
],
|
||||
"properties": {
|
||||
"transfer_request": {
|
||||
"$ref": "#/definitions/TransferRequestMsg"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clear_text_transfer_request"
|
||||
],
|
||||
"properties": {
|
||||
"clear_text_transfer_request": {
|
||||
"$ref": "#/definitions/ClearTextTransferRequestMsg"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"update"
|
||||
],
|
||||
"properties": {
|
||||
"update": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawUpdateMsg_and_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"definitions": {
|
||||
"Addr": {
|
||||
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
|
||||
"type": "string"
|
||||
},
|
||||
"Binary": {
|
||||
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"ClearTextTransferRequestMsg": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"amount",
|
||||
"receiver",
|
||||
"sender"
|
||||
],
|
||||
"properties": {
|
||||
"amount": {
|
||||
"$ref": "#/definitions/Uint128"
|
||||
},
|
||||
"receiver": {
|
||||
"$ref": "#/definitions/Addr"
|
||||
},
|
||||
"sender": {
|
||||
"$ref": "#/definitions/Addr"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"HexBinary": {
|
||||
"description": "This is a wrapper around Vec<u8> to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"IASReport": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report",
|
||||
"reportsig"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/ReportBody"
|
||||
},
|
||||
"reportsig": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawSessionCreate_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawSessionCreate"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawSessionSetPubKey_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawSessionSetPubKey"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawUpdateMsg_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawUpdateMsg"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/IASReport"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawExecute_for_RawEpidAttestation": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"session_create"
|
||||
],
|
||||
"properties": {
|
||||
"session_create": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawSessionCreate_and_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"session_set_pub_key"
|
||||
],
|
||||
"properties": {
|
||||
"session_set_pub_key": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawSessionSetPubKey_and_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"RawSessionCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nonce"
|
||||
],
|
||||
"properties": {
|
||||
"nonce": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawSessionSetPubKey": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nonce",
|
||||
"pub_key"
|
||||
],
|
||||
"properties": {
|
||||
"nonce": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"pub_key": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawUpdateMsg": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ciphertext",
|
||||
"quantity",
|
||||
"withdrawals"
|
||||
],
|
||||
"properties": {
|
||||
"ciphertext": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"withdrawals": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Uint128"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ReportBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"advisoryIDs",
|
||||
"advisoryURL",
|
||||
"epidPseudonym",
|
||||
"id",
|
||||
"isvEnclaveQuoteBody",
|
||||
"isvEnclaveQuoteStatus",
|
||||
"platformInfoBlob",
|
||||
"timestamp",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"advisoryIDs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"advisoryURL": {
|
||||
"type": "string"
|
||||
},
|
||||
"epidPseudonym": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"isvEnclaveQuoteBody": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"isvEnclaveQuoteStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"platformInfoBlob": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"TransferRequestMsg": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ciphertext",
|
||||
"digest"
|
||||
],
|
||||
"properties": {
|
||||
"ciphertext": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"digest": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Uint128": {
|
||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "InstantiateMsg",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"denom",
|
||||
"quartz"
|
||||
],
|
||||
"properties": {
|
||||
"denom": {
|
||||
"type": "string"
|
||||
},
|
||||
"quartz": {
|
||||
"$ref": "#/definitions/RawInstantiate_for_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"definitions": {
|
||||
"Binary": {
|
||||
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"Duration": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nanos",
|
||||
"secs"
|
||||
],
|
||||
"properties": {
|
||||
"nanos": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"secs": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"HexBinary": {
|
||||
"description": "This is a wrapper around Vec<u8> to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"IASReport": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report",
|
||||
"reportsig"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/ReportBody"
|
||||
},
|
||||
"reportsig": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawCoreInstantiate_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawCoreInstantiate"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawConfig": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"epoch_duration",
|
||||
"light_client_opts",
|
||||
"mr_enclave"
|
||||
],
|
||||
"properties": {
|
||||
"epoch_duration": {
|
||||
"$ref": "#/definitions/Duration"
|
||||
},
|
||||
"light_client_opts": {
|
||||
"$ref": "#/definitions/RawLightClientOpts"
|
||||
},
|
||||
"mr_enclave": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawCoreInstantiate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"config"
|
||||
],
|
||||
"properties": {
|
||||
"config": {
|
||||
"$ref": "#/definitions/RawConfig"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/IASReport"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawInstantiate_for_RawEpidAttestation": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawCoreInstantiate_and_RawEpidAttestation"
|
||||
},
|
||||
"RawLightClientOpts": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"chain_id",
|
||||
"max_block_lag",
|
||||
"max_clock_drift",
|
||||
"trust_threshold",
|
||||
"trusted_hash",
|
||||
"trusted_height",
|
||||
"trusting_period"
|
||||
],
|
||||
"properties": {
|
||||
"chain_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"max_block_lag": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"max_clock_drift": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"trust_threshold": {
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
},
|
||||
"trusted_hash": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"trusted_height": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"trusting_period": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ReportBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"advisoryIDs",
|
||||
"advisoryURL",
|
||||
"epidPseudonym",
|
||||
"id",
|
||||
"isvEnclaveQuoteBody",
|
||||
"isvEnclaveQuoteStatus",
|
||||
"platformInfoBlob",
|
||||
"timestamp",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"advisoryIDs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"advisoryURL": {
|
||||
"type": "string"
|
||||
},
|
||||
"epidPseudonym": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"isvEnclaveQuoteBody": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"isvEnclaveQuoteStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"platformInfoBlob": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,563 +0,0 @@
|
|||
{
|
||||
"contract_name": "transfers",
|
||||
"contract_version": "0.1.0",
|
||||
"idl_version": "1.0.0",
|
||||
"instantiate": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "InstantiateMsg",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"denom",
|
||||
"quartz"
|
||||
],
|
||||
"properties": {
|
||||
"denom": {
|
||||
"type": "string"
|
||||
},
|
||||
"quartz": {
|
||||
"$ref": "#/definitions/RawInstantiate_for_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"definitions": {
|
||||
"Binary": {
|
||||
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"Duration": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nanos",
|
||||
"secs"
|
||||
],
|
||||
"properties": {
|
||||
"nanos": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"secs": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"HexBinary": {
|
||||
"description": "This is a wrapper around Vec<u8> to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"IASReport": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report",
|
||||
"reportsig"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/ReportBody"
|
||||
},
|
||||
"reportsig": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawCoreInstantiate_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawCoreInstantiate"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawConfig": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"epoch_duration",
|
||||
"light_client_opts",
|
||||
"mr_enclave"
|
||||
],
|
||||
"properties": {
|
||||
"epoch_duration": {
|
||||
"$ref": "#/definitions/Duration"
|
||||
},
|
||||
"light_client_opts": {
|
||||
"$ref": "#/definitions/RawLightClientOpts"
|
||||
},
|
||||
"mr_enclave": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawCoreInstantiate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"config"
|
||||
],
|
||||
"properties": {
|
||||
"config": {
|
||||
"$ref": "#/definitions/RawConfig"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/IASReport"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawInstantiate_for_RawEpidAttestation": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawCoreInstantiate_and_RawEpidAttestation"
|
||||
},
|
||||
"RawLightClientOpts": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"chain_id",
|
||||
"max_block_lag",
|
||||
"max_clock_drift",
|
||||
"trust_threshold",
|
||||
"trusted_hash",
|
||||
"trusted_height",
|
||||
"trusting_period"
|
||||
],
|
||||
"properties": {
|
||||
"chain_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"max_block_lag": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"max_clock_drift": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"trust_threshold": {
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
},
|
||||
"trusted_hash": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"trusted_height": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"trusting_period": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ReportBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"advisoryIDs",
|
||||
"advisoryURL",
|
||||
"epidPseudonym",
|
||||
"id",
|
||||
"isvEnclaveQuoteBody",
|
||||
"isvEnclaveQuoteStatus",
|
||||
"platformInfoBlob",
|
||||
"timestamp",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"advisoryIDs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"advisoryURL": {
|
||||
"type": "string"
|
||||
},
|
||||
"epidPseudonym": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"isvEnclaveQuoteBody": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"isvEnclaveQuoteStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"platformInfoBlob": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ExecuteMsg",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"deposit",
|
||||
"withdraw"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"quartz"
|
||||
],
|
||||
"properties": {
|
||||
"quartz": {
|
||||
"$ref": "#/definitions/RawExecute_for_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"transfer_request"
|
||||
],
|
||||
"properties": {
|
||||
"transfer_request": {
|
||||
"$ref": "#/definitions/TransferRequestMsg"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clear_text_transfer_request"
|
||||
],
|
||||
"properties": {
|
||||
"clear_text_transfer_request": {
|
||||
"$ref": "#/definitions/ClearTextTransferRequestMsg"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"update"
|
||||
],
|
||||
"properties": {
|
||||
"update": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawUpdateMsg_and_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"definitions": {
|
||||
"Addr": {
|
||||
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
|
||||
"type": "string"
|
||||
},
|
||||
"Binary": {
|
||||
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"ClearTextTransferRequestMsg": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"amount",
|
||||
"receiver",
|
||||
"sender"
|
||||
],
|
||||
"properties": {
|
||||
"amount": {
|
||||
"$ref": "#/definitions/Uint128"
|
||||
},
|
||||
"receiver": {
|
||||
"$ref": "#/definitions/Addr"
|
||||
},
|
||||
"sender": {
|
||||
"$ref": "#/definitions/Addr"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"HexBinary": {
|
||||
"description": "This is a wrapper around Vec<u8> to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
|
||||
"type": "string"
|
||||
},
|
||||
"IASReport": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report",
|
||||
"reportsig"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/ReportBody"
|
||||
},
|
||||
"reportsig": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawSessionCreate_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawSessionCreate"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawSessionSetPubKey_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawSessionSetPubKey"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawAttested_for_RawUpdateMsg_and_RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attestation",
|
||||
"msg"
|
||||
],
|
||||
"properties": {
|
||||
"attestation": {
|
||||
"$ref": "#/definitions/RawEpidAttestation"
|
||||
},
|
||||
"msg": {
|
||||
"$ref": "#/definitions/RawUpdateMsg"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawEpidAttestation": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/IASReport"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawExecute_for_RawEpidAttestation": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"session_create"
|
||||
],
|
||||
"properties": {
|
||||
"session_create": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawSessionCreate_and_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"session_set_pub_key"
|
||||
],
|
||||
"properties": {
|
||||
"session_set_pub_key": {
|
||||
"$ref": "#/definitions/RawAttested_for_RawSessionSetPubKey_and_RawEpidAttestation"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"RawSessionCreate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nonce"
|
||||
],
|
||||
"properties": {
|
||||
"nonce": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawSessionSetPubKey": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nonce",
|
||||
"pub_key"
|
||||
],
|
||||
"properties": {
|
||||
"nonce": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"pub_key": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"RawUpdateMsg": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ciphertext",
|
||||
"quantity",
|
||||
"withdrawals"
|
||||
],
|
||||
"properties": {
|
||||
"ciphertext": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"withdrawals": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Uint128"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ReportBody": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"advisoryIDs",
|
||||
"advisoryURL",
|
||||
"epidPseudonym",
|
||||
"id",
|
||||
"isvEnclaveQuoteBody",
|
||||
"isvEnclaveQuoteStatus",
|
||||
"platformInfoBlob",
|
||||
"timestamp",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"advisoryIDs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"advisoryURL": {
|
||||
"type": "string"
|
||||
},
|
||||
"epidPseudonym": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"isvEnclaveQuoteBody": {
|
||||
"$ref": "#/definitions/Binary"
|
||||
},
|
||||
"isvEnclaveQuoteStatus": {
|
||||
"type": "string"
|
||||
},
|
||||
"platformInfoBlob": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"TransferRequestMsg": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ciphertext",
|
||||
"digest"
|
||||
],
|
||||
"properties": {
|
||||
"ciphertext": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
},
|
||||
"digest": {
|
||||
"$ref": "#/definitions/HexBinary"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Uint128": {
|
||||
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"query": null,
|
||||
"migrate": null,
|
||||
"sudo": null,
|
||||
"responses": null
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
## MTCS Server
|
|
@ -1,9 +0,0 @@
|
|||
mock_sgx = false
|
||||
tx_sender = "admin"
|
||||
chain_id = "testing"
|
||||
node_url = "127.0.0.1:26657"
|
||||
enclave_rpc_addr = "http://127.0.0.1"
|
||||
enclave_rpc_port = 11090
|
||||
trusted_hash = ""
|
||||
trusted_height = 0
|
||||
release = true
|
17
cosmwasm/.gitignore
vendored
17
cosmwasm/.gitignore
vendored
|
@ -1,17 +0,0 @@
|
|||
# Build results
|
||||
/artifacts
|
||||
target/
|
||||
schema/
|
||||
|
||||
# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
|
||||
.cargo-ok
|
||||
|
||||
# Text file backups
|
||||
**/*.rs.bk
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# IDEs
|
||||
*.iml
|
||||
.idea
|
|
@ -1,11 +0,0 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.rs]
|
||||
indent_size = 4
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue