Neutron client in pure rust (#234)
Implements the following: - grpc based cw client (alsmost chain agnostic, but not fully yet) - All URL based CLI args now use reqwest::Url type. - An almost 'Bin agnostic CliClient' - SSL and DNS resolution support in gramine - Implement generic attestation support for transfers enclave - Misc cleanup
This commit is contained in:
parent
279cd5180f
commit
7133ea5e36
35 changed files with 1141 additions and 672 deletions
243
Cargo.lock
generated
243
Cargo.lock
generated
|
@ -90,6 +90,21 @@ version = "0.2.18"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.15"
|
||||
|
@ -808,8 +823,11 @@ version = "0.4.38"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1016,20 +1034,21 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|||
|
||||
[[package]]
|
||||
name = "cosmos-sdk-proto"
|
||||
version = "0.22.0"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57d1a42d9ef55bb4e84b48ce29860f55859e52e0088ebdb1371cedd62f2b78cc"
|
||||
checksum = "8b2f63ab112b8c8e7b8a29c891adc48f43145beb21c0bfbf562957072c1e0beb"
|
||||
dependencies = [
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"tendermint-proto 0.37.0",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tendermint-proto",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmrs"
|
||||
version = "0.17.0"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85efbd5a3487e52ccd77897ef8f97b077a015953b46623fabc939f39d9c501fc"
|
||||
checksum = "9f21bb63ec6a903510a3d01f44735dd4914724e5eccbe409e6da6833d17c7829"
|
||||
dependencies = [
|
||||
"cosmos-sdk-proto",
|
||||
"ecdsa",
|
||||
|
@ -1040,7 +1059,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"signature",
|
||||
"subtle-encoding",
|
||||
"tendermint 0.37.0",
|
||||
"tendermint",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -1265,11 +1284,17 @@ name = "cw-client"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"cosmos-sdk-proto",
|
||||
"cosmrs",
|
||||
"hex",
|
||||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"transfers-contract",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1285,7 +1310,7 @@ dependencies = [
|
|||
"cw-utils",
|
||||
"derivative",
|
||||
"itertools 0.13.0",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"schemars",
|
||||
"serde",
|
||||
"sha2 0.10.8",
|
||||
|
@ -1446,6 +1471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2759,6 +2785,29 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ics23"
|
||||
version = "0.12.0"
|
||||
|
@ -2770,7 +2819,7 @@ dependencies = [
|
|||
"blake3",
|
||||
"bytes",
|
||||
"hex",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"ripemd",
|
||||
"sha2 0.10.8",
|
||||
"sha3",
|
||||
|
@ -2862,6 +2911,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2965,15 +3015,6 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
|
@ -4110,16 +4151,6 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.3"
|
||||
|
@ -4127,7 +4158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.13.3",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4144,26 +4175,13 @@ dependencies = [
|
|||
"once_cell",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost 0.13.3",
|
||||
"prost-types 0.13.3",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 2.0.79",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.12.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.3"
|
||||
|
@ -4177,22 +4195,13 @@ dependencies = [
|
|||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
|
||||
dependencies = [
|
||||
"prost 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670"
|
||||
dependencies = [
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4233,10 +4242,10 @@ dependencies = [
|
|||
"displaydoc",
|
||||
"hex",
|
||||
"ics23",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-rpc",
|
||||
]
|
||||
|
||||
|
@ -4249,7 +4258,7 @@ dependencies = [
|
|||
"hex",
|
||||
"quartz-cw-proof",
|
||||
"serde_json",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-rpc",
|
||||
"tokio",
|
||||
]
|
||||
|
@ -4299,7 +4308,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-rpc",
|
||||
"thiserror",
|
||||
|
@ -4323,7 +4332,7 @@ dependencies = [
|
|||
name = "quartz-proto"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
]
|
||||
|
@ -4351,7 +4360,7 @@ dependencies = [
|
|||
"k256",
|
||||
"miette",
|
||||
"once_cell",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"quartz-common",
|
||||
"quartz-tee-ra",
|
||||
"quartz-tm-prover",
|
||||
|
@ -4359,10 +4368,11 @@ dependencies = [
|
|||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
"subtle-encoding",
|
||||
"target-lexicon",
|
||||
"tempfile",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-rpc",
|
||||
"thiserror",
|
||||
|
@ -4440,7 +4450,7 @@ dependencies = [
|
|||
"quartz-cw-proof",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-light-client-detector",
|
||||
"tendermint-rpc",
|
||||
|
@ -4454,7 +4464,7 @@ name = "quartz-tm-stateless-verifier"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
]
|
||||
|
||||
|
@ -5261,6 +5271,8 @@ dependencies = [
|
|||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.5.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
|
@ -5567,37 +5579,6 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendermint"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "954496fbc9716eb4446cdd6d00c071a3e2f22578d62aa03b40c7e5b4fda3ed42"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"digest 0.10.7",
|
||||
"ed25519",
|
||||
"ed25519-consensus",
|
||||
"flex-error",
|
||||
"futures",
|
||||
"k256",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"ripemd",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"sha2 0.10.8",
|
||||
"signature",
|
||||
"subtle",
|
||||
"subtle-encoding",
|
||||
"tendermint-proto 0.37.0",
|
||||
"time",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendermint"
|
||||
version = "0.38.1"
|
||||
|
@ -5610,10 +5591,12 @@ dependencies = [
|
|||
"ed25519-consensus",
|
||||
"flex-error",
|
||||
"futures",
|
||||
"k256",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"prost 0.13.3",
|
||||
"prost-types 0.13.3",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"ripemd",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
|
@ -5622,7 +5605,7 @@ dependencies = [
|
|||
"signature",
|
||||
"subtle",
|
||||
"subtle-encoding",
|
||||
"tendermint-proto 0.38.1",
|
||||
"tendermint-proto",
|
||||
"time",
|
||||
"zeroize",
|
||||
]
|
||||
|
@ -5636,7 +5619,7 @@ dependencies = [
|
|||
"flex-error",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"toml",
|
||||
"url",
|
||||
]
|
||||
|
@ -5658,7 +5641,7 @@ dependencies = [
|
|||
"serde_derive",
|
||||
"serde_json",
|
||||
"static_assertions",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client-verifier",
|
||||
"tendermint-rpc",
|
||||
"time",
|
||||
|
@ -5681,9 +5664,9 @@ dependencies = [
|
|||
"serde_derive",
|
||||
"serde_json",
|
||||
"static_assertions",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-proto 0.38.1",
|
||||
"tendermint-proto",
|
||||
"tendermint-rpc",
|
||||
"time",
|
||||
"tracing",
|
||||
|
@ -5698,23 +5681,7 @@ dependencies = [
|
|||
"derive_more 0.99.18",
|
||||
"flex-error",
|
||||
"serde",
|
||||
"tendermint 0.38.1",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-proto"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc87024548c7f3da479885201e3da20ef29e85a3b13d04606b380ac4c7120d87"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
"tendermint",
|
||||
"time",
|
||||
]
|
||||
|
||||
|
@ -5726,8 +5693,8 @@ checksum = "8ed14abe3b0502a3afe21ca74ca5cdd6c7e8d326d982c26f98a394445eb31d6e"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"prost 0.13.3",
|
||||
"prost-types 0.13.3",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
|
@ -5756,9 +5723,9 @@ dependencies = [
|
|||
"serde_json",
|
||||
"subtle",
|
||||
"subtle-encoding",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-config",
|
||||
"tendermint-proto 0.38.1",
|
||||
"tendermint-proto",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
|
@ -6033,7 +6000,7 @@ dependencies = [
|
|||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
|
@ -6052,7 +6019,7 @@ dependencies = [
|
|||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"prost-build",
|
||||
"prost-types 0.13.3",
|
||||
"prost-types",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
@ -6150,6 +6117,21 @@ dependencies = [
|
|||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "transfers-contract"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"cw-utils",
|
||||
"getrandom",
|
||||
"quartz-common",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.5"
|
||||
|
@ -6559,7 +6541,16 @@ version = "0.56.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-core 0.56.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
|
|
|
@ -96,8 +96,8 @@ x509-parser = { version = "0.16.0", default-features = false, features = [
|
|||
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 }
|
||||
cosmos-sdk-proto = { version = "0.23.0", default-features = false }
|
||||
cosmrs = { version = "0.18.0", default-features = false }
|
||||
cosmwasm-schema = { version = "2.1.1", default-features = false }
|
||||
cosmwasm-std = { version = "2.1.1", default-features = false, features = [
|
||||
"std",
|
||||
|
|
|
@ -47,6 +47,7 @@ toml = "0.8.19"
|
|||
figment = { version = "0.10.19", features = ["env", "toml"] }
|
||||
clearscreen = "3.0.0"
|
||||
cargo_metadata = "0.18.1"
|
||||
serde_with = "3.10.0"
|
||||
|
||||
# cosmos
|
||||
cosmrs.workspace = true
|
||||
|
|
|
@ -4,7 +4,9 @@ use clap::{Parser, Subcommand};
|
|||
use cosmrs::{tendermint::chain::Id as ChainId, AccountId};
|
||||
use figment::{providers::Serialized, Figment};
|
||||
use quartz_common::enclave::types::Fmspc;
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
use tracing::metadata::LevelFilter;
|
||||
|
||||
use crate::handler::utils::helpers::wasmaddr_to_id;
|
||||
|
@ -79,6 +81,7 @@ pub enum Command {
|
|||
Dev(DevArgs),
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, Subcommand, Serialize)]
|
||||
pub enum ContractCommand {
|
||||
Build(ContractBuildArgs),
|
||||
|
@ -100,6 +103,7 @@ pub struct InitArgs {
|
|||
pub name: PathBuf,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Debug, Parser, Clone, Serialize, Deserialize)]
|
||||
pub struct HandshakeArgs {
|
||||
/// Path to create & init a Quartz app, defaults to current path if unspecified
|
||||
|
@ -123,7 +127,20 @@ pub struct HandshakeArgs {
|
|||
/// <host>:<port> to tendermint rpc interface for this chain
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub node_url: Option<String>,
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
pub node_url: Option<Url>,
|
||||
|
||||
/// websocket URL
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
pub ws_url: Option<Url>,
|
||||
|
||||
/// gRPC URL
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
pub grpc_url: Option<Url>,
|
||||
|
||||
/// RPC interface for the Quartz enclave
|
||||
#[arg(long)]
|
||||
|
@ -143,6 +160,7 @@ pub struct ContractBuildArgs {
|
|||
pub contract_manifest: PathBuf,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Debug, Parser, Clone, Serialize, Deserialize)]
|
||||
pub struct ContractDeployArgs {
|
||||
/// Json-formatted cosmwasm contract initialization message
|
||||
|
@ -152,7 +170,20 @@ pub struct ContractDeployArgs {
|
|||
/// <host>:<port> to tendermint rpc interface for this chain
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub node_url: Option<String>,
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
pub node_url: Option<Url>,
|
||||
|
||||
/// websocket URL
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
pub ws_url: Option<Url>,
|
||||
|
||||
/// gRPC URL
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
pub grpc_url: Option<Url>,
|
||||
|
||||
/// Name or address of private key with which to sign
|
||||
#[arg(long)]
|
||||
|
@ -192,6 +223,10 @@ pub struct EnclaveStartArgs {
|
|||
#[arg(long)]
|
||||
pub unsafe_trust_latest: bool,
|
||||
|
||||
/// file containing the secret key of the tx-sender for the enclave
|
||||
#[arg(long)]
|
||||
pub sk_file: PathBuf,
|
||||
|
||||
/// FMSPC (Family-Model-Stepping-Platform-Custom SKU); required if `MOCK_SGX` is not set
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
@ -229,6 +264,10 @@ pub struct DevArgs {
|
|||
#[command(flatten)]
|
||||
pub enclave_build: EnclaveBuildArgs,
|
||||
|
||||
/// file containing the secret key of the tx-sender for the enclave
|
||||
#[arg(long)]
|
||||
pub sk_file: PathBuf,
|
||||
|
||||
/// FMSPC (Family-Model-Stepping-Platform-Custom SKU); required if `MOCK_SGX` is not set
|
||||
#[arg(long)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use cosmrs::tendermint::chain::Id as ChainId;
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
/// Enable mock SGX mode for testing purposes.
|
||||
|
@ -20,7 +23,18 @@ pub struct Config {
|
|||
|
||||
/// <host>:<port> to tendermint rpc interface for this chain
|
||||
#[serde(default = "default_node_url")]
|
||||
pub node_url: String,
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub node_url: Url,
|
||||
|
||||
/// websocket URL
|
||||
#[serde(default = "default_ws_url")]
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub ws_url: Url,
|
||||
|
||||
/// gRPC URL
|
||||
#[serde(default = "default_grpc_url")]
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub grpc_url: Url,
|
||||
|
||||
/// RPC interface for the Quartz enclave
|
||||
#[serde(default = "default_rpc_addr")]
|
||||
|
@ -52,8 +66,22 @@ fn default_rpc_addr() -> String {
|
|||
"http://127.0.0.1".to_string()
|
||||
}
|
||||
|
||||
fn default_node_url() -> String {
|
||||
"127.0.0.1:26657".to_string()
|
||||
fn default_node_url() -> Url {
|
||||
"http://127.0.0.1:26657"
|
||||
.parse()
|
||||
.expect("valid hardcoded URL")
|
||||
}
|
||||
|
||||
fn default_ws_url() -> Url {
|
||||
"ws://127.0.0.1/websocket"
|
||||
.parse()
|
||||
.expect("valid hardcoded URL")
|
||||
}
|
||||
|
||||
fn default_grpc_url() -> Url {
|
||||
"http://127.0.0.1:9090,"
|
||||
.parse()
|
||||
.expect("valid hardcoded URL")
|
||||
}
|
||||
|
||||
fn default_tx_sender() -> String {
|
||||
|
@ -79,6 +107,8 @@ impl Default for Config {
|
|||
tx_sender: default_tx_sender(),
|
||||
chain_id: default_chain_id(),
|
||||
node_url: default_node_url(),
|
||||
ws_url: default_ws_url(),
|
||||
grpc_url: default_grpc_url(),
|
||||
enclave_rpc_addr: default_rpc_addr(),
|
||||
enclave_rpc_port: default_port(),
|
||||
app_dir: default_app_dir(),
|
||||
|
|
|
@ -3,16 +3,12 @@ use std::path::Path;
|
|||
use async_trait::async_trait;
|
||||
use cargo_metadata::MetadataCommand;
|
||||
use color_eyre::owo_colors::OwoColorize;
|
||||
use cw_client::{CliWasmdClient, WasmdClient};
|
||||
use reqwest::Url;
|
||||
use cw_client::{CliClient, CwClient};
|
||||
use serde_json::json;
|
||||
use tendermint_rpc::HttpClient;
|
||||
use tracing::{debug, info};
|
||||
|
||||
use super::utils::{
|
||||
helpers::block_tx_commit,
|
||||
types::{Log, WasmdTxResponse},
|
||||
};
|
||||
use super::utils::{helpers::block_tx_commit, types::WasmdTxResponse};
|
||||
use crate::{
|
||||
config::Config,
|
||||
error::Error,
|
||||
|
@ -68,9 +64,8 @@ async fn deploy(
|
|||
args: ContractDeployRequest,
|
||||
config: &Config,
|
||||
) -> Result<(u64, String), anyhow::Error> {
|
||||
let httpurl = Url::parse(&format!("http://{}", config.node_url))?;
|
||||
let tmrpc_client = HttpClient::new(httpurl.as_str())?;
|
||||
let cw_client = CliWasmdClient::new(Url::parse(httpurl.as_str())?);
|
||||
let tmrpc_client = HttpClient::new(config.node_url.as_str())?;
|
||||
let cw_client = CliClient::neutrond(config.node_url.clone());
|
||||
|
||||
info!("🚀 Deploying {} Contract", args.label);
|
||||
let code_id = if config.contract_has_changed(wasm_bin_path).await? {
|
||||
|
@ -81,8 +76,23 @@ async fn deploy(
|
|||
)?)?;
|
||||
let res = block_tx_commit(&tmrpc_client, deploy_output.txhash).await?;
|
||||
|
||||
let log: Vec<Log> = serde_json::from_str(&res.tx_result.log)?;
|
||||
let code_id: u64 = log[0].events[1].attributes[1].value.parse()?;
|
||||
// Find the 'code_id' attribute
|
||||
let code_id = res
|
||||
.tx_result
|
||||
.events
|
||||
.iter()
|
||||
.find(|event| event.kind == "store_code")
|
||||
.and_then(|event| {
|
||||
event
|
||||
.attributes
|
||||
.iter()
|
||||
.find(|attr| attr.key_str().unwrap_or("") == "code_id")
|
||||
})
|
||||
.and_then(|attr| attr.value_str().ok().and_then(|v| v.parse().ok()))
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to find code_id in the transaction result"))?;
|
||||
|
||||
info!("Code ID: {}", code_id);
|
||||
|
||||
config.save_codeid_to_cache(wasm_bin_path, code_id).await?;
|
||||
|
||||
code_id
|
||||
|
@ -108,8 +118,22 @@ async fn deploy(
|
|||
)?)?;
|
||||
let res = block_tx_commit(&tmrpc_client, init_output.txhash).await?;
|
||||
|
||||
let log: Vec<Log> = serde_json::from_str(&res.tx_result.log)?;
|
||||
let contract_addr: &String = &log[0].events[1].attributes[0].value;
|
||||
// Find the '_contract_address' attribute
|
||||
let contract_addr: String = res
|
||||
.tx_result
|
||||
.events
|
||||
.iter()
|
||||
.find(|event| event.kind == "instantiate")
|
||||
.and_then(|event| {
|
||||
event
|
||||
.attributes
|
||||
.iter()
|
||||
.find(|attr| attr.key_str().unwrap_or("") == "_contract_address")
|
||||
})
|
||||
.and_then(|attr| attr.value_str().ok().and_then(|v| v.parse().ok()))
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!("Failed to find contract_address in the transaction result")
|
||||
})?;
|
||||
|
||||
info!("🚀 Successfully deployed and instantiated contract!");
|
||||
info!("🆔 Code ID: {}", code_id);
|
||||
|
|
|
@ -170,6 +170,7 @@ async fn dev_driver(
|
|||
fn spawn_enclave_start(args: &DevRequest, config: &Config) -> Result<(), Error> {
|
||||
// In separate process, launch the enclave
|
||||
let enclave_start = EnclaveStartRequest {
|
||||
sk_file: args.sk_file.clone(),
|
||||
unsafe_trust_latest: args.unsafe_trust_latest,
|
||||
fmspc: args.fmspc.clone(),
|
||||
tcbinfo_contract: args.tcbinfo_contract.clone(),
|
||||
|
|
|
@ -5,6 +5,8 @@ use cargo_metadata::MetadataCommand;
|
|||
use color_eyre::owo_colors::OwoColorize;
|
||||
use cosmrs::AccountId;
|
||||
use quartz_common::enclave::types::Fmspc;
|
||||
use reqwest::Url;
|
||||
use tendermint::chain::Id;
|
||||
use tokio::process::{Child, Command};
|
||||
use tracing::{debug, info};
|
||||
|
||||
|
@ -41,7 +43,11 @@ impl Handler for EnclaveStartRequest {
|
|||
"--trusted-hash".to_string(),
|
||||
trusted_hash.to_string(),
|
||||
"--node-url".to_string(),
|
||||
config.node_url,
|
||||
config.node_url.to_string(),
|
||||
"--ws-url".to_string(),
|
||||
config.ws_url.to_string(),
|
||||
"--grpc-url".to_string(),
|
||||
config.grpc_url.to_string(),
|
||||
"--tx-sender".to_string(),
|
||||
config.tx_sender,
|
||||
];
|
||||
|
@ -77,15 +83,22 @@ impl Handler for EnclaveStartRequest {
|
|||
|
||||
// gramine manifest
|
||||
let quartz_dir_canon = &enclave_dir.join("..");
|
||||
|
||||
debug!("quartz_dir_canon: {:?}", quartz_dir_canon);
|
||||
|
||||
gramine_manifest(
|
||||
&trusted_height.to_string(),
|
||||
&trusted_hash.to_string(),
|
||||
&config.chain_id,
|
||||
quartz_dir_canon,
|
||||
&enclave_dir,
|
||||
&self.sk_file,
|
||||
fmspc,
|
||||
tcbinfo_contract,
|
||||
dcap_verifier_contract,
|
||||
&config.node_url,
|
||||
&config.ws_url,
|
||||
&config.grpc_url,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -174,15 +187,20 @@ async fn gramine_sgx_gen_private_key(enclave_dir: &Path) -> Result<(), Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn gramine_manifest(
|
||||
trusted_height: &str,
|
||||
trusted_hash: &str,
|
||||
chain_id: &Id,
|
||||
quartz_dir: &Path,
|
||||
enclave_dir: &Path,
|
||||
sk_file: &Path,
|
||||
fmspc: Fmspc,
|
||||
tcbinfo_contract: AccountId,
|
||||
dcap_verifier_contract: AccountId,
|
||||
node_url: &str,
|
||||
node_url: &Url,
|
||||
ws_url: &Url,
|
||||
grpc_url: &Url,
|
||||
) -> Result<(), Error> {
|
||||
let host = target_lexicon::HOST;
|
||||
let arch_libdir = format!(
|
||||
|
@ -203,11 +221,15 @@ async fn gramine_manifest(
|
|||
.arg("-Dra_type=dcap")
|
||||
.arg(format!("-Dra_client_spid={}", ra_client_spid))
|
||||
.arg("-Dra_client_linkable=1")
|
||||
.arg(format!("-Dchain_id={}", chain_id))
|
||||
.arg(format!("-Dquartz_dir={}", quartz_dir.display()))
|
||||
.arg(format!("-Dtrusted_height={}", trusted_height))
|
||||
.arg(format!("-Dtrusted_hash={}", trusted_hash))
|
||||
.arg(format!("-Dsk_file={}", sk_file.display()))
|
||||
.arg(format!("-Dfmspc={}", hex::encode(fmspc)))
|
||||
.arg(format!("-Dnode_url={}", node_url))
|
||||
.arg(format!("-Dws_url={}", ws_url))
|
||||
.arg(format!("-Dgrpc_url={}", grpc_url))
|
||||
.arg(format!("-Dtcbinfo_contract={}", tcbinfo_contract))
|
||||
.arg(format!(
|
||||
"-Ddcap_verifier_contract={}",
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use async_trait::async_trait;
|
||||
use color_eyre::owo_colors::OwoColorize;
|
||||
use cosmrs::tendermint::chain::Id as ChainId; // TODO see if this redundancy in dependencies can be decreased
|
||||
use cw_client::{CliWasmdClient, WasmdClient};
|
||||
use cw_client::{CliClient, CwClient};
|
||||
use futures_util::stream::StreamExt;
|
||||
use quartz_tm_prover::{config::Config as TmProverConfig, prover::prove};
|
||||
use reqwest::Url;
|
||||
use serde_json::json;
|
||||
use tendermint_rpc::{query::EventType, HttpClient, SubscriptionClient, WebSocketClient};
|
||||
use tracing::{debug, info};
|
||||
|
@ -47,11 +43,8 @@ impl Handler for HandshakeRequest {
|
|||
}
|
||||
|
||||
async fn handshake(args: HandshakeRequest, config: Config) -> Result<String, anyhow::Error> {
|
||||
let httpurl = Url::parse(&format!("http://{}", config.node_url))?;
|
||||
let wsurl = format!("ws://{}/websocket", config.node_url);
|
||||
|
||||
let tmrpc_client = HttpClient::new(httpurl.as_str())?;
|
||||
let cw_client = CliWasmdClient::new(Url::parse(httpurl.as_str())?);
|
||||
let tmrpc_client = HttpClient::new(config.node_url.as_str())?;
|
||||
let cw_client = CliClient::neutrond(config.node_url.clone());
|
||||
|
||||
let (trusted_height, trusted_hash) = read_cached_hash_height(&config).await?;
|
||||
|
||||
|
@ -69,7 +62,9 @@ async fn handshake(args: HandshakeRequest, config: Config) -> Result<String, any
|
|||
2000000,
|
||||
&config.tx_sender,
|
||||
json!(res),
|
||||
)?
|
||||
"11000untrn",
|
||||
)
|
||||
.await?
|
||||
.as_str(),
|
||||
)?;
|
||||
debug!("\n\n SessionCreate tx output: {:?}", output);
|
||||
|
@ -80,12 +75,12 @@ async fn handshake(args: HandshakeRequest, config: Config) -> Result<String, any
|
|||
|
||||
// Wait 2 blocks
|
||||
info!("Waiting 2 blocks for light client proof");
|
||||
two_block_waitoor(&wsurl).await?;
|
||||
two_block_waitoor(config.ws_url.as_str()).await?;
|
||||
|
||||
// Call tm prover with trusted hash and height
|
||||
let prover_config = TmProverConfig {
|
||||
primary: httpurl.as_str().parse()?,
|
||||
witnesses: httpurl.as_str().parse()?,
|
||||
primary: config.node_url.as_str().parse()?,
|
||||
witnesses: config.node_url.as_str().parse()?,
|
||||
trusted_height,
|
||||
trusted_hash,
|
||||
verbose: "1".parse()?, // TODO: both tm-prover and cli define the same Verbosity struct. Need to define this once and import
|
||||
|
@ -112,11 +107,13 @@ async fn handshake(args: HandshakeRequest, config: Config) -> Result<String, any
|
|||
cw_client
|
||||
.tx_execute(
|
||||
&args.contract.clone(),
|
||||
&ChainId::from_str("testing")?,
|
||||
&config.chain_id,
|
||||
2000000,
|
||||
&config.tx_sender,
|
||||
json!(res),
|
||||
)?
|
||||
"11000untrn",
|
||||
)
|
||||
.await?
|
||||
.as_str(),
|
||||
)?;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
|||
|
||||
use anyhow::anyhow;
|
||||
use cosmrs::{AccountId, ErrorReport};
|
||||
use cw_client::{CliWasmdClient, WasmdClient};
|
||||
use cw_client::{CliClient, CwClient};
|
||||
use regex::Regex;
|
||||
use reqwest::Url;
|
||||
use subtle_encoding::bech32::decode as bech32_decode;
|
||||
|
@ -16,11 +16,7 @@ use tracing::debug;
|
|||
use crate::{config::Config, error::Error};
|
||||
|
||||
pub fn wasmaddr_to_id(address_str: &str) -> Result<AccountId, anyhow::Error> {
|
||||
let (hr, _) = bech32_decode(address_str).map_err(|e| anyhow!(e))?;
|
||||
if hr != "wasm" {
|
||||
return Err(anyhow!(hr));
|
||||
}
|
||||
|
||||
let _ = bech32_decode(address_str).map_err(|e| anyhow!(e))?;
|
||||
address_str.parse().map_err(|e: ErrorReport| anyhow!(e))
|
||||
}
|
||||
|
||||
|
@ -59,10 +55,8 @@ pub async fn block_tx_commit(client: &HttpClient, tx: Hash) -> Result<TmTxRespon
|
|||
}
|
||||
|
||||
// Queries the chain for the latested height and hash
|
||||
pub fn query_latest_height_hash(node_url: &String) -> Result<(Height, Hash), Error> {
|
||||
let httpurl = Url::parse(&format!("http://{}", node_url))
|
||||
.map_err(|e| Error::GenericErr(e.to_string()))?;
|
||||
let cw_client = CliWasmdClient::new(httpurl);
|
||||
pub fn query_latest_height_hash(node_url: Url) -> Result<(Height, Hash), Error> {
|
||||
let cw_client = CliClient::neutrond(node_url);
|
||||
|
||||
let (trusted_height, trusted_hash) = cw_client
|
||||
.trusted_height_hash()
|
||||
|
|
|
@ -48,6 +48,7 @@ impl TryFrom<Command> for Request {
|
|||
label: args.contract_deploy.label,
|
||||
contract_manifest: args.contract_deploy.contract_manifest,
|
||||
release: args.enclave_build.release,
|
||||
sk_file: args.sk_file,
|
||||
fmspc: args.fmspc,
|
||||
tcbinfo_contract: args.tcbinfo_contract,
|
||||
dcap_verifier_contract: args.dcap_verifier_contract,
|
||||
|
@ -101,6 +102,7 @@ impl TryFrom<EnclaveCommand> for Request {
|
|||
EnclaveCommand::Build(_) => Ok(EnclaveBuildRequest {}.into()),
|
||||
EnclaveCommand::Start(args) => Ok(EnclaveStartRequest {
|
||||
unsafe_trust_latest: args.unsafe_trust_latest,
|
||||
sk_file: args.sk_file,
|
||||
fmspc: args.fmspc,
|
||||
tcbinfo_contract: args.tcbinfo_contract,
|
||||
dcap_verifier_contract: args.dcap_verifier_contract,
|
||||
|
|
|
@ -13,6 +13,7 @@ pub struct DevRequest {
|
|||
pub label: String,
|
||||
pub contract_manifest: PathBuf,
|
||||
pub release: bool,
|
||||
pub sk_file: PathBuf,
|
||||
pub fmspc: Option<Fmspc>,
|
||||
pub tcbinfo_contract: Option<AccountId>,
|
||||
pub dcap_verifier_contract: Option<AccountId>,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use cosmrs::AccountId;
|
||||
use quartz_common::enclave::types::Fmspc;
|
||||
use tendermint::{block::Height, Hash};
|
||||
|
@ -11,6 +13,7 @@ use crate::{
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct EnclaveStartRequest {
|
||||
pub unsafe_trust_latest: bool,
|
||||
pub sk_file: PathBuf,
|
||||
pub fmspc: Option<Fmspc>,
|
||||
pub tcbinfo_contract: Option<AccountId>,
|
||||
pub dcap_verifier_contract: Option<AccountId>,
|
||||
|
@ -28,7 +31,7 @@ impl EnclaveStartRequest {
|
|||
if self.unsafe_trust_latest || config.trusted_height == 0 || config.trusted_hash.is_empty()
|
||||
{
|
||||
debug!("querying latest trusted hash & height from node");
|
||||
let (trusted_height, trusted_hash) = query_latest_height_hash(&config.node_url)?;
|
||||
let (trusted_height, trusted_hash) = query_latest_height_hash(config.node_url.clone())?;
|
||||
|
||||
Ok((trusted_height, trusted_hash))
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
convert::Infallible,
|
||||
net::SocketAddr,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
@ -31,6 +32,7 @@ use quartz_proto::quartz::{
|
|||
};
|
||||
use quartz_tm_stateless_verifier::make_provider;
|
||||
use rand::Rng;
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tendermint::{block::Height, Hash};
|
||||
use tendermint_light_client::{
|
||||
|
@ -78,11 +80,14 @@ pub trait WebSocketHandler: Send + Sync + 'static {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WsListenerConfig {
|
||||
pub node_url: String,
|
||||
pub node_url: Url,
|
||||
pub ws_url: Url,
|
||||
pub grpc_url: Url,
|
||||
pub chain_id: String,
|
||||
pub tx_sender: String,
|
||||
pub trusted_hash: Hash,
|
||||
pub trusted_height: Height,
|
||||
pub sk_file: PathBuf,
|
||||
}
|
||||
|
||||
/// A trait for wrapping a tonic service with the gRPC server handler
|
||||
|
@ -154,8 +159,9 @@ impl QuartzServer {
|
|||
ws_handlers: &Vec<Box<dyn WebSocketHandler>>,
|
||||
ws_config: WsListenerConfig,
|
||||
) -> Result<(), QuartzError> {
|
||||
let wsurl = format!("ws://{}/websocket", ws_config.node_url);
|
||||
let (client, driver) = WebSocketClient::new(wsurl.as_str()).await.unwrap();
|
||||
let (client, driver) = WebSocketClient::new(ws_config.ws_url.as_str())
|
||||
.await
|
||||
.unwrap();
|
||||
let driver_handle = tokio::spawn(async move { driver.run().await });
|
||||
let mut subs = client.subscribe(Query::from(EventType::Tx)).await.unwrap();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_build::configure()
|
||||
.out_dir("src/prost")
|
||||
.compile(&["proto/quartz.proto"], &["proto"])?;
|
||||
.compile_protos(&["proto/quartz.proto"], &["proto"])?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -9,12 +9,21 @@ repository.workspace = true
|
|||
authors.workspace = true
|
||||
|
||||
[lib]
|
||||
path="src/lib.rs"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
cosmrs.workspace = true
|
||||
async-trait.workspace = true
|
||||
hex.workspace = true
|
||||
reqwest.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
anyhow.workspace = true
|
||||
anyhow.workspace = true
|
||||
tonic.workspace = true
|
||||
|
||||
cosmrs = { workspace = true, default-features = false, features = ["cosmwasm"] }
|
||||
cosmos-sdk-proto = { workspace = true, default-features = false, features = ["grpc", "grpc-transport"] }
|
||||
tendermint = { workspace = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio.workspace = true
|
||||
transfers-contract = { path = "../../../examples/transfers/contracts" }
|
||||
|
|
1
crates/utils/cw-client/data/admin.sk
Normal file
1
crates/utils/cw-client/data/admin.sk
Normal file
|
@ -0,0 +1 @@
|
|||
ffc4d3c9119e9e8263de08c0f6e2368ac5c2dacecfeb393f6813da7d178873d2
|
255
crates/utils/cw-client/src/cli.rs
Normal file
255
crates/utils/cw-client/src/cli.rs
Normal file
|
@ -0,0 +1,255 @@
|
|||
use std::process::Command;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use cosmrs::{tendermint::chain::Id, AccountId};
|
||||
use reqwest::Url;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use crate::CwClient;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CliClientType {
|
||||
Wasmd,
|
||||
Neutrond,
|
||||
}
|
||||
|
||||
impl CliClientType {
|
||||
fn bin(&self) -> String {
|
||||
match self {
|
||||
CliClientType::Wasmd => "wasmd",
|
||||
CliClientType::Neutrond => "neutrond",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CliClient {
|
||||
kind: CliClientType,
|
||||
url: Url,
|
||||
gas_price: String,
|
||||
}
|
||||
|
||||
impl CliClient {
|
||||
pub fn new(kind: CliClientType, url: Url, gas_price: String) -> Self {
|
||||
Self {
|
||||
kind,
|
||||
url,
|
||||
gas_price,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wasmd(url: Url) -> Self {
|
||||
Self {
|
||||
kind: CliClientType::Wasmd,
|
||||
url,
|
||||
gas_price: "0.0025ucosm".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn neutrond(url: Url) -> Self {
|
||||
Self {
|
||||
kind: CliClientType::Neutrond,
|
||||
url,
|
||||
gas_price: "0.0053untrn".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_command(&self) -> Command {
|
||||
Command::new(self.kind.bin())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl CwClient for CliClient {
|
||||
type Address = AccountId;
|
||||
type Query = serde_json::Value;
|
||||
type RawQuery = String;
|
||||
type ChainId = Id;
|
||||
type Error = anyhow::Error;
|
||||
|
||||
async fn query_smart<R: DeserializeOwned + Send>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
query: Self::Query,
|
||||
) -> Result<R, Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["query", "wasm"])
|
||||
.args(["contract-state", "smart", contract.as_ref()])
|
||||
.arg(query.to_string())
|
||||
.args(["--output", "json"]);
|
||||
|
||||
let output = command.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: R = serde_json::from_slice(&output.stdout)
|
||||
.map_err(|e| anyhow!("Error deserializing: {}", e))?;
|
||||
Ok(query_result)
|
||||
}
|
||||
|
||||
fn query_raw<R: DeserializeOwned + Default>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
query: Self::RawQuery,
|
||||
) -> Result<R, Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["query", "wasm"])
|
||||
.args(["contract-state", "raw", contract.as_ref()])
|
||||
.arg(&query)
|
||||
.args(["--output", "json"]);
|
||||
|
||||
let output = command.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: R = serde_json::from_slice(&output.stdout).unwrap_or_default();
|
||||
Ok(query_result)
|
||||
}
|
||||
|
||||
fn query_tx<R: DeserializeOwned + Default>(&self, txhash: &str) -> Result<R, Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["query", "tx"])
|
||||
.arg(txhash)
|
||||
.args(["--output", "json"]);
|
||||
|
||||
let output = command.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: R = serde_json::from_slice(&output.stdout).unwrap_or_default();
|
||||
Ok(query_result)
|
||||
}
|
||||
|
||||
async fn tx_execute<M: ToString + Send>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
chain_id: &Id,
|
||||
gas: u64,
|
||||
sender: &str,
|
||||
msg: M,
|
||||
fees: &str,
|
||||
) -> Result<String, Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["--chain-id", chain_id.as_ref()])
|
||||
.args(["tx", "wasm"])
|
||||
.args(["execute", contract.as_ref(), &msg.to_string()])
|
||||
.args(["--gas", &gas.to_string()])
|
||||
.args(["--fees", fees])
|
||||
.args(["--from", sender])
|
||||
.args(["--output", "json"])
|
||||
.arg("-y");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
// TODO: find the rust type for the tx output and return that
|
||||
Ok((String::from_utf8(output.stdout)?).to_string())
|
||||
}
|
||||
|
||||
fn deploy<M: ToString>(
|
||||
&self,
|
||||
chain_id: &Id,
|
||||
sender: &str,
|
||||
wasm_path: M,
|
||||
) -> Result<String, Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["tx", "wasm", "store", &wasm_path.to_string()])
|
||||
.args(["--from", sender])
|
||||
.args(["--chain-id", chain_id.as_ref()])
|
||||
.args(["--gas-prices", &self.gas_price])
|
||||
.args(["--gas", "auto"])
|
||||
.args(["--gas-adjustment", "1.3"])
|
||||
.args(["-o", "json"])
|
||||
.arg("-y");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
// TODO: find the rust type for the tx output and return that
|
||||
Ok((String::from_utf8(output.stdout)?).to_string())
|
||||
}
|
||||
|
||||
fn init<M: ToString>(
|
||||
&self,
|
||||
chain_id: &Id,
|
||||
sender: &str,
|
||||
code_id: u64,
|
||||
init_msg: M,
|
||||
label: &str,
|
||||
) -> Result<String, Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["tx", "wasm", "instantiate"])
|
||||
.args([&code_id.to_string(), &init_msg.to_string()])
|
||||
.args(["--label", label])
|
||||
.args(["--from", sender])
|
||||
.arg("--no-admin")
|
||||
.args(["--chain-id", chain_id.as_ref()])
|
||||
.args(["--gas-prices", &self.gas_price])
|
||||
.args(["--gas", "auto"])
|
||||
.args(["--gas-adjustment", "1.3"])
|
||||
.args(["-o", "json"])
|
||||
.arg("-y");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
// TODO: find the rust type for the tx output and return that
|
||||
Ok((String::from_utf8(output.stdout)?).to_string())
|
||||
}
|
||||
|
||||
fn trusted_height_hash(&self) -> Result<(u64, String), Self::Error> {
|
||||
let mut command = self.new_command();
|
||||
let command = command.args(["--node", self.url.as_str()]).arg("status");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: serde_json::Value =
|
||||
serde_json::from_slice(&output.stdout).unwrap_or_default();
|
||||
|
||||
let sync_info = match self.kind {
|
||||
CliClientType::Wasmd => "SyncInfo",
|
||||
CliClientType::Neutrond => "sync_info",
|
||||
};
|
||||
let trusted_height = query_result[sync_info]["latest_block_height"]
|
||||
.as_str()
|
||||
.ok_or(anyhow!("Could not query height"))?;
|
||||
|
||||
let trusted_height = trusted_height.parse::<u64>()?;
|
||||
|
||||
let trusted_hash = query_result[sync_info]["latest_block_hash"]
|
||||
.as_str()
|
||||
.ok_or(anyhow!("Could not query height"))?
|
||||
.to_string();
|
||||
|
||||
Ok((trusted_height, trusted_hash))
|
||||
}
|
||||
}
|
269
crates/utils/cw-client/src/grpc.rs
Normal file
269
crates/utils/cw-client/src/grpc.rs
Normal file
|
@ -0,0 +1,269 @@
|
|||
use std::{error::Error, fs::File, io::Read, path::PathBuf};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use cosmos_sdk_proto::{
|
||||
cosmos::{
|
||||
auth::v1beta1::{
|
||||
query_client::QueryClient as AuthQueryClient, BaseAccount as RawBaseAccount,
|
||||
QueryAccountRequest,
|
||||
},
|
||||
tx::v1beta1::{
|
||||
service_client::ServiceClient, BroadcastMode, BroadcastTxRequest, BroadcastTxResponse,
|
||||
},
|
||||
},
|
||||
cosmwasm::wasm::v1::{
|
||||
query_client::QueryClient as WasmdQueryClient, QuerySmartContractStateRequest,
|
||||
},
|
||||
traits::Message,
|
||||
Any,
|
||||
};
|
||||
use cosmrs::{
|
||||
auth::BaseAccount,
|
||||
cosmwasm::MsgExecuteContract,
|
||||
crypto::{secp256k1::SigningKey, PublicKey},
|
||||
tendermint::chain::Id as TmChainId,
|
||||
tx,
|
||||
tx::{Fee, Msg, SignDoc, SignerInfo},
|
||||
AccountId, Coin,
|
||||
};
|
||||
use reqwest::Url;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use crate::CwClient;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GrpcClient {
|
||||
sk_file: PathBuf,
|
||||
url: Url,
|
||||
}
|
||||
|
||||
impl GrpcClient {
|
||||
pub fn new(sk_file: PathBuf, url: Url) -> Self {
|
||||
Self { sk_file, url }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl CwClient for GrpcClient {
|
||||
type Address = AccountId;
|
||||
type Query = serde_json::Value;
|
||||
type RawQuery = String;
|
||||
type ChainId = TmChainId;
|
||||
type Error = anyhow::Error;
|
||||
|
||||
async fn query_smart<R: DeserializeOwned + Send>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
query: Self::Query,
|
||||
) -> Result<R, Self::Error> {
|
||||
let mut client = WasmdQueryClient::connect(self.url.to_string()).await?;
|
||||
|
||||
let raw_query_request = QuerySmartContractStateRequest {
|
||||
address: contract.to_string(),
|
||||
query_data: query.to_string().into_bytes(),
|
||||
};
|
||||
|
||||
let raw_query_response = client.smart_contract_state(raw_query_request).await?;
|
||||
|
||||
let raw_value = raw_query_response.into_inner().data;
|
||||
serde_json::from_slice(&raw_value)
|
||||
.map_err(|e| anyhow!("failed to deserialize JSON reponse: {}", e))
|
||||
}
|
||||
|
||||
fn query_raw<R: DeserializeOwned + Default>(
|
||||
&self,
|
||||
_contract: &Self::Address,
|
||||
_query: Self::RawQuery,
|
||||
) -> Result<R, Self::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn query_tx<R: DeserializeOwned + Default>(&self, _txhash: &str) -> Result<R, Self::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn tx_execute<M: ToString + Send>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
chain_id: &TmChainId,
|
||||
gas: u64,
|
||||
_sender: &str,
|
||||
msg: M,
|
||||
_fees: &str,
|
||||
) -> Result<String, Self::Error> {
|
||||
let secret = {
|
||||
let mut secret_hex = String::new();
|
||||
let mut sk_file = File::open(self.sk_file.clone())?;
|
||||
sk_file.read_to_string(&mut secret_hex)?;
|
||||
let secret = hex::decode(secret_hex)?;
|
||||
SigningKey::from_slice(&secret)
|
||||
.map_err(|e| anyhow!("failed to read secret key: {}", e))?
|
||||
};
|
||||
|
||||
let tm_pubkey = secret.public_key();
|
||||
let sender = tm_pubkey
|
||||
.account_id("neutron")
|
||||
.map_err(|e| anyhow!("failed to create AccountId from pubkey: {}", e))?;
|
||||
|
||||
let msgs = vec![MsgExecuteContract {
|
||||
sender: sender.clone(),
|
||||
contract: contract.clone(),
|
||||
msg: msg.to_string().into_bytes(),
|
||||
funds: vec![],
|
||||
}
|
||||
.to_any()
|
||||
.unwrap()];
|
||||
|
||||
let account = account_info(self.url.to_string(), sender.to_string())
|
||||
.await
|
||||
.map_err(|e| anyhow!("error querying account info: {}", e))?;
|
||||
let amount = Coin {
|
||||
amount: 11000u128,
|
||||
denom: "untrn".parse().expect("hardcoded denom"),
|
||||
};
|
||||
let tx_bytes = tx_bytes(
|
||||
&secret,
|
||||
amount,
|
||||
gas,
|
||||
tm_pubkey,
|
||||
msgs,
|
||||
account.sequence,
|
||||
account.account_number,
|
||||
chain_id,
|
||||
)
|
||||
.map_err(|e| anyhow!("failed to create msg/tx: {}", e))?;
|
||||
|
||||
let response = send_tx(self.url.to_string(), tx_bytes)
|
||||
.await
|
||||
.map_err(|e| anyhow!("failed to send tx: {}", e))?;
|
||||
println!("{response:?}");
|
||||
Ok(response
|
||||
.tx_response
|
||||
.map(|tx_response| tx_response.txhash)
|
||||
.unwrap_or_default())
|
||||
}
|
||||
|
||||
fn deploy<M: ToString>(
|
||||
&self,
|
||||
_chain_id: &TmChainId,
|
||||
_sender: &str,
|
||||
_wasm_path: M,
|
||||
) -> Result<String, Self::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn init<M: ToString>(
|
||||
&self,
|
||||
_chain_id: &TmChainId,
|
||||
_sender: &str,
|
||||
_code_id: u64,
|
||||
_init_msg: M,
|
||||
_label: &str,
|
||||
) -> Result<String, Self::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn trusted_height_hash(&self) -> Result<(u64, String), Self::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn account_info(
|
||||
node: impl ToString,
|
||||
address: impl ToString,
|
||||
) -> Result<BaseAccount, Box<dyn Error>> {
|
||||
let mut client = AuthQueryClient::connect(node.to_string()).await?;
|
||||
let request = tonic::Request::new(QueryAccountRequest {
|
||||
address: address.to_string(),
|
||||
});
|
||||
let response = client.account(request).await?;
|
||||
let response = RawBaseAccount::decode(response.into_inner().account.unwrap().value.as_slice())?;
|
||||
let account = BaseAccount::try_from(response)?;
|
||||
Ok(account)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn tx_bytes(
|
||||
secret: &SigningKey,
|
||||
amount: Coin,
|
||||
gas: u64,
|
||||
tm_pubkey: PublicKey,
|
||||
msgs: Vec<Any>,
|
||||
sequence_number: u64,
|
||||
account_number: u64,
|
||||
chain_id: &TmChainId,
|
||||
) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
let tx_body = tx::Body::new(msgs, "", 0u16);
|
||||
let signer_info = SignerInfo::single_direct(Some(tm_pubkey), sequence_number);
|
||||
let auth_info = signer_info.auth_info(Fee::from_amount_and_gas(amount, gas));
|
||||
let sign_doc = SignDoc::new(&tx_body, &auth_info, chain_id, account_number)?;
|
||||
let tx_signed = sign_doc.sign(secret)?;
|
||||
Ok(tx_signed.to_bytes()?)
|
||||
}
|
||||
|
||||
pub async fn send_tx(
|
||||
node: impl ToString,
|
||||
tx_bytes: Vec<u8>,
|
||||
) -> Result<BroadcastTxResponse, Box<dyn Error>> {
|
||||
let mut client = ServiceClient::connect(node.to_string()).await?;
|
||||
let request = tonic::Request::new(BroadcastTxRequest {
|
||||
tx_bytes,
|
||||
mode: BroadcastMode::Sync.into(),
|
||||
});
|
||||
let tx_response = client.broadcast_tx(request).await?;
|
||||
Ok(tx_response.into_inner())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::error::Error;
|
||||
|
||||
use serde_json::json;
|
||||
use transfers_contract::msg::{execute::Request, QueryMsg::GetRequests};
|
||||
|
||||
use crate::{CwClient, GrpcClient};
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_query() -> Result<(), Box<dyn Error>> {
|
||||
let sk_file = "../data/admin.sk".parse().unwrap();
|
||||
let url = "https://grpc-falcron.pion-1.ntrn.tech:80".parse().unwrap();
|
||||
let contract = "neutron15ruzx9wvrupt9cffzsp6868uad2svhfym2nsgxm2skpeqr3qrd4q4uwk83"
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
let cw_client = GrpcClient::new(sk_file, url);
|
||||
let resp: Vec<Request> = cw_client
|
||||
.query_smart(&contract, json!(GetRequests {}))
|
||||
.await?;
|
||||
println!("{resp:?}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_execute() -> Result<(), Box<dyn Error>> {
|
||||
let sk_file = "data/admin.sk".parse().unwrap();
|
||||
let url = "https://grpc-falcron.pion-1.ntrn.tech:80".parse().unwrap();
|
||||
let contract = "neutron15ruzx9wvrupt9cffzsp6868uad2svhfym2nsgxm2skpeqr3qrd4q4uwk83"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let chain_id = "pion-1".parse().unwrap();
|
||||
|
||||
let cw_client = GrpcClient::new(sk_file, url);
|
||||
let tx_hash = cw_client
|
||||
.tx_execute(
|
||||
&contract,
|
||||
&chain_id,
|
||||
2000000,
|
||||
"/* unused since we're getting the account from the sk */",
|
||||
json!([]),
|
||||
"11000untrn",
|
||||
)
|
||||
.await?;
|
||||
println!("{}", tx_hash);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,19 +1,22 @@
|
|||
use std::process::Command;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use cosmrs::{tendermint::chain::Id, AccountId};
|
||||
pub use cli::CliClient;
|
||||
use cosmrs::tendermint::chain::Id;
|
||||
pub use grpc::GrpcClient;
|
||||
use hex::ToHex;
|
||||
use reqwest::Url;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
pub trait WasmdClient {
|
||||
pub mod cli;
|
||||
|
||||
pub mod grpc;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait CwClient {
|
||||
type Address: AsRef<str>;
|
||||
type Query: ToString;
|
||||
type RawQuery: ToHex;
|
||||
type ChainId: AsRef<str>;
|
||||
type Error;
|
||||
|
||||
fn query_smart<R: DeserializeOwned>(
|
||||
async fn query_smart<R: DeserializeOwned + Send>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
query: Self::Query,
|
||||
|
@ -27,13 +30,14 @@ pub trait WasmdClient {
|
|||
|
||||
fn query_tx<R: DeserializeOwned + Default>(&self, txhash: &str) -> Result<R, Self::Error>;
|
||||
|
||||
fn tx_execute<M: ToString>(
|
||||
async fn tx_execute<M: ToString + Send>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
chain_id: &Id,
|
||||
gas: u64,
|
||||
sender: &str,
|
||||
msg: M,
|
||||
fees: &str,
|
||||
) -> Result<String, Self::Error>;
|
||||
|
||||
fn deploy<M: ToString>(
|
||||
|
@ -54,206 +58,3 @@ pub trait WasmdClient {
|
|||
|
||||
fn trusted_height_hash(&self) -> Result<(u64, String), Self::Error>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
||||
pub struct QueryResult<T> {
|
||||
pub data: T,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CliWasmdClient {
|
||||
url: Url,
|
||||
}
|
||||
|
||||
impl CliWasmdClient {
|
||||
pub fn new(url: Url) -> Self {
|
||||
Self { url }
|
||||
}
|
||||
}
|
||||
|
||||
impl WasmdClient for CliWasmdClient {
|
||||
type Address = AccountId;
|
||||
type Query = serde_json::Value;
|
||||
type RawQuery = String;
|
||||
type ChainId = Id;
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn query_smart<R: DeserializeOwned>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
query: Self::Query,
|
||||
) -> Result<R, Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["query", "wasm"])
|
||||
.args(["contract-state", "smart", contract.as_ref()])
|
||||
.arg(query.to_string())
|
||||
.args(["--output", "json"]);
|
||||
|
||||
let output = command.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: R = serde_json::from_slice(&output.stdout)
|
||||
.map_err(|e| anyhow!("Error deserializing: {}", e))?;
|
||||
Ok(query_result)
|
||||
}
|
||||
|
||||
fn query_raw<R: DeserializeOwned + Default>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
query: Self::RawQuery,
|
||||
) -> Result<R, Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["query", "wasm"])
|
||||
.args(["contract-state", "raw", contract.as_ref()])
|
||||
.arg(&query)
|
||||
.args(["--output", "json"]);
|
||||
|
||||
let output = command.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: R = serde_json::from_slice(&output.stdout).unwrap_or_default();
|
||||
Ok(query_result)
|
||||
}
|
||||
|
||||
fn query_tx<R: DeserializeOwned + Default>(&self, txhash: &str) -> Result<R, Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["query", "tx"])
|
||||
.arg(txhash)
|
||||
.args(["--output", "json"]);
|
||||
|
||||
let output = command.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: R = serde_json::from_slice(&output.stdout).unwrap_or_default();
|
||||
Ok(query_result)
|
||||
}
|
||||
|
||||
fn tx_execute<M: ToString>(
|
||||
&self,
|
||||
contract: &Self::Address,
|
||||
chain_id: &Id,
|
||||
gas: u64,
|
||||
sender: &str,
|
||||
msg: M,
|
||||
) -> Result<String, Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["--chain-id", chain_id.as_ref()])
|
||||
.args(["tx", "wasm"])
|
||||
.args(["execute", contract.as_ref(), &msg.to_string()])
|
||||
.args(["--gas", &gas.to_string()])
|
||||
.args(["--from", sender])
|
||||
.args(["--output", "json"])
|
||||
.arg("-y");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
// TODO: find the rust type for the tx output and return that
|
||||
Ok((String::from_utf8(output.stdout)?).to_string())
|
||||
}
|
||||
|
||||
fn deploy<M: ToString>(
|
||||
&self,
|
||||
chain_id: &Id,
|
||||
sender: &str,
|
||||
wasm_path: M,
|
||||
) -> Result<String, Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["tx", "wasm", "store", &wasm_path.to_string()])
|
||||
.args(["--from", sender])
|
||||
.args(["--chain-id", chain_id.as_ref()])
|
||||
.args(["--gas-prices", "0.0025ucosm"])
|
||||
.args(["--gas", "auto"])
|
||||
.args(["--gas-adjustment", "1.3"])
|
||||
.args(["-o", "json"])
|
||||
.arg("-y");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
// TODO: find the rust type for the tx output and return that
|
||||
Ok((String::from_utf8(output.stdout)?).to_string())
|
||||
}
|
||||
|
||||
fn init<M: ToString>(
|
||||
&self,
|
||||
chain_id: &Id,
|
||||
sender: &str,
|
||||
code_id: u64,
|
||||
init_msg: M,
|
||||
label: &str,
|
||||
) -> Result<String, Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd
|
||||
.args(["--node", self.url.as_str()])
|
||||
.args(["tx", "wasm", "instantiate"])
|
||||
.args([&code_id.to_string(), &init_msg.to_string()])
|
||||
.args(["--label", label])
|
||||
.args(["--from", sender])
|
||||
.arg("--no-admin")
|
||||
.args(["--chain-id", chain_id.as_ref()])
|
||||
.args(["--gas-prices", "0.0025ucosm"])
|
||||
.args(["--gas", "auto"])
|
||||
.args(["--gas-adjustment", "1.3"])
|
||||
.args(["-o", "json"])
|
||||
.arg("-y");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
// TODO: find the rust type for the tx output and return that
|
||||
Ok((String::from_utf8(output.stdout)?).to_string())
|
||||
}
|
||||
|
||||
fn trusted_height_hash(&self) -> Result<(u64, String), Self::Error> {
|
||||
let mut wasmd = Command::new("wasmd");
|
||||
let command = wasmd.args(["--node", self.url.as_str()]).arg("status");
|
||||
|
||||
let output = command.output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("{:?}", output));
|
||||
}
|
||||
|
||||
let query_result: serde_json::Value =
|
||||
serde_json::from_slice(&output.stdout).unwrap_or_default();
|
||||
|
||||
let trusted_height = query_result["SyncInfo"]["latest_block_height"]
|
||||
.as_str()
|
||||
.ok_or(anyhow!("Could not query height"))?;
|
||||
|
||||
let trusted_height = trusted_height.parse::<u64>()?;
|
||||
|
||||
let trusted_hash = query_result["SyncInfo"]["latest_block_hash"]
|
||||
.as_str()
|
||||
.ok_or(anyhow!("Could not query height"))?
|
||||
.to_string();
|
||||
|
||||
Ok((trusted_height, trusted_hash))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub enum QueryMsg {
|
|||
pub enum ExecuteMsg<RA = RawDefaultAttestation> {
|
||||
// quartz initialization
|
||||
Quartz(QuartzExecuteMsg<RA>),
|
||||
|
||||
|
||||
// User msgs
|
||||
// clear text
|
||||
Deposit,
|
||||
|
|
206
examples/transfers/enclave/Cargo.lock
generated
206
examples/transfers/enclave/Cargo.lock
generated
|
@ -268,9 +268,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
|
||||
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
|
||||
dependencies = [
|
||||
"async-stream-impl",
|
||||
"futures-core",
|
||||
|
@ -279,9 +279,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-stream-impl"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -708,20 +708,21 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|||
|
||||
[[package]]
|
||||
name = "cosmos-sdk-proto"
|
||||
version = "0.22.0"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57d1a42d9ef55bb4e84b48ce29860f55859e52e0088ebdb1371cedd62f2b78cc"
|
||||
checksum = "8b2f63ab112b8c8e7b8a29c891adc48f43145beb21c0bfbf562957072c1e0beb"
|
||||
dependencies = [
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"tendermint-proto 0.37.0",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tendermint-proto",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmrs"
|
||||
version = "0.17.0"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85efbd5a3487e52ccd77897ef8f97b077a015953b46623fabc939f39d9c501fc"
|
||||
checksum = "9f21bb63ec6a903510a3d01f44735dd4914724e5eccbe409e6da6833d17c7829"
|
||||
dependencies = [
|
||||
"cosmos-sdk-proto",
|
||||
"ecdsa",
|
||||
|
@ -732,7 +733,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"signature",
|
||||
"subtle-encoding",
|
||||
"tendermint 0.37.0",
|
||||
"tendermint",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -946,14 +947,17 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cw-client"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"cosmos-sdk-proto",
|
||||
"cosmrs",
|
||||
"hex",
|
||||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -969,7 +973,7 @@ dependencies = [
|
|||
"cw-utils",
|
||||
"derivative",
|
||||
"itertools 0.13.0",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"schemars",
|
||||
"serde",
|
||||
"sha2 0.10.8",
|
||||
|
@ -1518,7 +1522,7 @@ dependencies = [
|
|||
"futures-sink",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -1537,7 +1541,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.1.0",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -1585,6 +1589,12 @@ dependencies = [
|
|||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
|
@ -1843,7 +1853,7 @@ dependencies = [
|
|||
"blake3",
|
||||
"bytes",
|
||||
"hex",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"ripemd",
|
||||
"sha2 0.10.8",
|
||||
"sha3",
|
||||
|
@ -1883,12 +1893,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1915,15 +1925,6 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
|
@ -2462,7 +2463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2574,16 +2575,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.3"
|
||||
|
@ -2591,7 +2582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.13.3",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2608,26 +2599,13 @@ dependencies = [
|
|||
"once_cell",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost 0.13.3",
|
||||
"prost-types 0.13.3",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 2.0.79",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.12.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.3"
|
||||
|
@ -2641,22 +2619,13 @@ dependencies = [
|
|||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
|
||||
dependencies = [
|
||||
"prost 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670"
|
||||
dependencies = [
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2676,14 +2645,14 @@ dependencies = [
|
|||
"futures-util",
|
||||
"hex",
|
||||
"k256",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"quartz-common",
|
||||
"quartz-tm-prover",
|
||||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-rpc",
|
||||
"thiserror",
|
||||
|
@ -2697,7 +2666,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-common"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"quartz-contract-core",
|
||||
"quartz-enclave-core",
|
||||
|
@ -2707,7 +2675,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-contract-core"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"ciborium",
|
||||
"cosmwasm-schema",
|
||||
|
@ -2728,23 +2695,21 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-cw-proof"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"cosmrs",
|
||||
"displaydoc",
|
||||
"ics23",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-rpc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quartz-dcap-verifier-msgs"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
|
@ -2753,7 +2718,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-enclave-core"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -2776,7 +2740,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-rpc",
|
||||
"thiserror",
|
||||
|
@ -2789,9 +2753,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-proto"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
]
|
||||
|
@ -2799,7 +2762,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-tcbinfo-msgs"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
]
|
||||
|
@ -2807,7 +2769,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-tee-ra"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
|
@ -2827,7 +2788,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-tm-prover"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"color-eyre",
|
||||
|
@ -2836,7 +2796,7 @@ dependencies = [
|
|||
"quartz-cw-proof",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-light-client-detector",
|
||||
"tendermint-rpc",
|
||||
|
@ -2848,10 +2808,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "quartz-tm-stateless-verifier"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@github.com/informalsystems/cycles-quartz.git#e5004076813b8c98e7c385cc967372c38dd9ab4b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
]
|
||||
|
||||
|
@ -3789,37 +3748,6 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendermint"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "954496fbc9716eb4446cdd6d00c071a3e2f22578d62aa03b40c7e5b4fda3ed42"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"digest 0.10.7",
|
||||
"ed25519",
|
||||
"ed25519-consensus",
|
||||
"flex-error",
|
||||
"futures",
|
||||
"k256",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"ripemd",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"sha2 0.10.8",
|
||||
"signature",
|
||||
"subtle",
|
||||
"subtle-encoding",
|
||||
"tendermint-proto 0.37.0",
|
||||
"time",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendermint"
|
||||
version = "0.38.1"
|
||||
|
@ -3832,10 +3760,12 @@ dependencies = [
|
|||
"ed25519-consensus",
|
||||
"flex-error",
|
||||
"futures",
|
||||
"k256",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"prost 0.13.3",
|
||||
"prost-types 0.13.3",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"ripemd",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
|
@ -3844,7 +3774,7 @@ dependencies = [
|
|||
"signature",
|
||||
"subtle",
|
||||
"subtle-encoding",
|
||||
"tendermint-proto 0.38.1",
|
||||
"tendermint-proto",
|
||||
"time",
|
||||
"zeroize",
|
||||
]
|
||||
|
@ -3858,7 +3788,7 @@ dependencies = [
|
|||
"flex-error",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"toml",
|
||||
"url",
|
||||
]
|
||||
|
@ -3880,7 +3810,7 @@ dependencies = [
|
|||
"serde_derive",
|
||||
"serde_json",
|
||||
"static_assertions",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client-verifier",
|
||||
"tendermint-rpc",
|
||||
"time",
|
||||
|
@ -3903,9 +3833,9 @@ dependencies = [
|
|||
"serde_derive",
|
||||
"serde_json",
|
||||
"static_assertions",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-light-client",
|
||||
"tendermint-proto 0.38.1",
|
||||
"tendermint-proto",
|
||||
"tendermint-rpc",
|
||||
"time",
|
||||
"tracing",
|
||||
|
@ -3920,23 +3850,7 @@ dependencies = [
|
|||
"derive_more 0.99.18",
|
||||
"flex-error",
|
||||
"serde",
|
||||
"tendermint 0.38.1",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-proto"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc87024548c7f3da479885201e3da20ef29e85a3b13d04606b380ac4c7120d87"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
"tendermint",
|
||||
"time",
|
||||
]
|
||||
|
||||
|
@ -3948,8 +3862,8 @@ checksum = "8ed14abe3b0502a3afe21ca74ca5cdd6c7e8d326d982c26f98a394445eb31d6e"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"prost 0.13.3",
|
||||
"prost-types 0.13.3",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
|
@ -3978,9 +3892,9 @@ dependencies = [
|
|||
"serde_json",
|
||||
"subtle",
|
||||
"subtle-encoding",
|
||||
"tendermint 0.38.1",
|
||||
"tendermint",
|
||||
"tendermint-config",
|
||||
"tendermint-proto 0.38.1",
|
||||
"tendermint-proto",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
|
@ -4186,7 +4100,7 @@ version = "0.22.22"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap 2.5.0",
|
||||
"indexmap 2.6.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
|
@ -4213,7 +4127,7 @@ dependencies = [
|
|||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost 0.13.3",
|
||||
"prost",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
|
@ -4232,7 +4146,7 @@ dependencies = [
|
|||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"prost-build",
|
||||
"prost-types 0.13.3",
|
||||
"prost-types",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
|
|
@ -52,7 +52,7 @@ tracing = "0.1.39"
|
|||
futures-util = "0.3.30"
|
||||
|
||||
# cosmos
|
||||
cosmrs = { version = "0.17.0", default-features = false }
|
||||
cosmrs = { version = "0.18.0", default-features = false }
|
||||
cosmwasm-std = { version = "2.1.1", default-features = false, features = [
|
||||
"std",
|
||||
] }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_build::configure()
|
||||
.out_dir("src/prost")
|
||||
.compile(&["proto/transfers.proto"], &["proto"])?;
|
||||
.compile_protos(&["proto/transfers.proto"], &["proto"])?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ libos.entrypoint = "{{ quartz_dir }}/target/release/quartz-app-transfers-enclave
|
|||
|
||||
loader.log_level = "{{ log_level }}"
|
||||
|
||||
loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}"
|
||||
loader.env.LD_LIBRARY_PATH = "/lib:/usr/local/lib:{{ arch_libdir }}:/usr{{ arch_libdir }}"
|
||||
loader.env.HOME = "{{ home }}"
|
||||
loader.env.INSIDE_SGX = "1"
|
||||
loader.env.TLS = { passthrough = true }
|
||||
|
@ -19,13 +19,17 @@ 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.env.SSL_CERT_FILE = { passthrough = true }
|
||||
loader.insecure__use_host_env = true
|
||||
|
||||
loader.argv = ["quartz-app-transfers-enclave",
|
||||
"--chain-id", "testing",
|
||||
"--chain-id", "{{ chain_id }}",
|
||||
"--fmspc", "{{ fmspc }}",
|
||||
"--tcbinfo-contract", "{{ tcbinfo_contract }}",
|
||||
"--dcap-verifier-contract", "{{ dcap_verifier_contract }}",
|
||||
"--node-url", "{{ node_url }}",
|
||||
"--ws-url", "{{ ws_url }}",
|
||||
"--grpc-url", "{{ grpc_url }}",
|
||||
"--rpc-addr", "0.0.0.0:11090",
|
||||
"--trusted-height", "{{ trusted_height }}",
|
||||
"--trusted-hash", "{{ trusted_hash }}"]
|
||||
|
@ -35,11 +39,14 @@ fs.mounts = [
|
|||
{ uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" },
|
||||
{ uri = "file:/usr/{{ arch_libdir }}", path = "/usr{{ arch_libdir }}" },
|
||||
{ uri = "file:{{ quartz_dir }}", path = "{{ quartz_dir }}" },
|
||||
{ uri = "file:{{ quartz_dir }}/../../crates/utils/cw-client/data/admin.sk", path = "/admin.sk" },
|
||||
{ uri = "file:/etc/ssl/certs/ca-certificates.crt", path = "/etc/ssl/certs/ca-certificates.crt" },
|
||||
{ uri = "file:/usr/lib/ssl/cert.pem", path = "/usr/lib/ssl/cert.pem" },
|
||||
]
|
||||
|
||||
# sgx.debug = true
|
||||
sgx.enclave_size = "512M"
|
||||
sgx.max_threads = 4
|
||||
sgx.max_threads = 16
|
||||
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
|
||||
|
||||
sgx.remote_attestation = "{{ ra_type }}"
|
||||
|
@ -52,12 +59,24 @@ sgx.trusted_files = [
|
|||
"file:{{ gramine.runtimedir() }}/",
|
||||
"file:{{ arch_libdir }}/",
|
||||
"file:/usr/{{ arch_libdir }}/",
|
||||
"file:/etc/ssl/certs/ca-certificates.crt",
|
||||
"file:{{ quartz_dir }}/../../crates/utils/cw-client/data/admin.sk",
|
||||
]
|
||||
|
||||
sgx.allowed_files = [
|
||||
"file:{{ quartz_dir }}/exchange.sk",
|
||||
"file:{{ quartz_dir }}/request.json",
|
||||
"file:admin.sk",
|
||||
"file:/etc/nsswitch.conf",
|
||||
"file:/etc/host.conf",
|
||||
"file:/etc/ethers",
|
||||
"file:/etc/hosts",
|
||||
"file:/etc/group",
|
||||
"file:/etc/passwd",
|
||||
"file:/etc/gai.conf",
|
||||
"file:/etc/ssl/certs/ca-certificates.crt",
|
||||
"file:/usr/lib/ssl/cert.pem",
|
||||
"file:/etc/sgx_default_qcnl.conf",
|
||||
]
|
||||
|
||||
sys.insecure__allow_eventfd = true
|
||||
sys.enable_sigterm_injection = true
|
||||
sys.enable_extra_runtime_domain_names_conf = true
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use std::{env, net::SocketAddr};
|
||||
use std::{env, net::SocketAddr, path::PathBuf};
|
||||
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use cosmrs::AccountId;
|
||||
use quartz_common::enclave::types::Fmspc;
|
||||
use reqwest::Url;
|
||||
use tendermint::Hash;
|
||||
use tendermint_light_client::types::{Height, TrustThreshold};
|
||||
|
||||
|
@ -64,11 +65,20 @@ pub struct Cli {
|
|||
#[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 = "http://127.0.0.1:26657")]
|
||||
pub node_url: Url,
|
||||
|
||||
#[clap(long, default_value = "ws://127.0.0.1/websocket")]
|
||||
pub ws_url: Url,
|
||||
|
||||
#[clap(long, default_value = "http://127.0.0.1:9090")]
|
||||
pub grpc_url: Url,
|
||||
|
||||
#[clap(long, default_value = "admin")]
|
||||
pub tx_sender: String,
|
||||
|
||||
#[clap(long, default_value = "admin.sk")]
|
||||
pub sk_file: PathBuf,
|
||||
}
|
||||
|
||||
fn default_rpc_addr() -> SocketAddr {
|
||||
|
|
|
@ -32,8 +32,9 @@ use quartz_common::{
|
|||
server::{QuartzServer, WsListenerConfig},
|
||||
},
|
||||
};
|
||||
use transfers_server::{TransfersOp, TransfersService};
|
||||
use tokio::sync::mpsc;
|
||||
use transfers_server::{TransfersOp, TransfersService};
|
||||
|
||||
use crate::wslistener::WsListener;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
|
@ -73,10 +74,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let ws_config = WsListenerConfig {
|
||||
node_url: args.node_url,
|
||||
ws_url: args.ws_url,
|
||||
grpc_url: args.grpc_url,
|
||||
tx_sender: args.tx_sender,
|
||||
trusted_hash: args.trusted_hash,
|
||||
trusted_height: args.trusted_height,
|
||||
chain_id: args.chain_id,
|
||||
sk_file: args.sk_file,
|
||||
};
|
||||
|
||||
let sk = Arc::new(Mutex::new(None));
|
||||
|
|
|
@ -21,7 +21,13 @@ pub struct QueryResponse {
|
|||
}
|
||||
/// Generated client implementations.
|
||||
pub mod settlement_client {
|
||||
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
|
||||
#![allow(
|
||||
unused_variables,
|
||||
dead_code,
|
||||
missing_docs,
|
||||
clippy::wildcard_imports,
|
||||
clippy::let_unit_value,
|
||||
)]
|
||||
use tonic::codegen::*;
|
||||
use tonic::codegen::http::Uri;
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -43,8 +49,8 @@ pub mod settlement_client {
|
|||
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,
|
||||
T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
|
||||
<T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
|
||||
{
|
||||
pub fn new(inner: T) -> Self {
|
||||
let inner = tonic::client::Grpc::new(inner);
|
||||
|
@ -69,7 +75,7 @@ pub mod settlement_client {
|
|||
>,
|
||||
<T as tonic::codegen::Service<
|
||||
http::Request<tonic::body::BoxBody>,
|
||||
>>::Error: Into<StdError> + Send + Sync,
|
||||
>>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
|
||||
{
|
||||
SettlementClient::new(InterceptedService::new(inner, interceptor))
|
||||
}
|
||||
|
@ -112,8 +118,7 @@ pub mod settlement_client {
|
|||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
tonic::Status::unknown(
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
|
@ -131,8 +136,7 @@ pub mod settlement_client {
|
|||
.ready()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tonic::Status::new(
|
||||
tonic::Code::Unknown,
|
||||
tonic::Status::unknown(
|
||||
format!("Service was not ready: {}", e.into()),
|
||||
)
|
||||
})?;
|
||||
|
@ -149,11 +153,17 @@ pub mod settlement_client {
|
|||
}
|
||||
/// Generated server implementations.
|
||||
pub mod settlement_server {
|
||||
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
|
||||
#![allow(
|
||||
unused_variables,
|
||||
dead_code,
|
||||
missing_docs,
|
||||
clippy::wildcard_imports,
|
||||
clippy::let_unit_value,
|
||||
)]
|
||||
use tonic::codegen::*;
|
||||
/// Generated trait containing gRPC methods that should be implemented for use with SettlementServer.
|
||||
#[async_trait]
|
||||
pub trait Settlement: Send + Sync + 'static {
|
||||
pub trait Settlement: std::marker::Send + std::marker::Sync + 'static {
|
||||
async fn run(
|
||||
&self,
|
||||
request: tonic::Request<super::UpdateRequest>,
|
||||
|
@ -164,14 +174,14 @@ pub mod settlement_server {
|
|||
) -> std::result::Result<tonic::Response<super::QueryResponse>, tonic::Status>;
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct SettlementServer<T: Settlement> {
|
||||
pub struct SettlementServer<T> {
|
||||
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: Settlement> SettlementServer<T> {
|
||||
impl<T> SettlementServer<T> {
|
||||
pub fn new(inner: T) -> Self {
|
||||
Self::from_arc(Arc::new(inner))
|
||||
}
|
||||
|
@ -225,8 +235,8 @@ pub mod settlement_server {
|
|||
impl<T, B> tonic::codegen::Service<http::Request<B>> for SettlementServer<T>
|
||||
where
|
||||
T: Settlement,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<StdError> + Send + 'static,
|
||||
B: Body + std::marker::Send + 'static,
|
||||
B::Error: Into<StdError> + std::marker::Send + 'static,
|
||||
{
|
||||
type Response = http::Response<tonic::body::BoxBody>;
|
||||
type Error = std::convert::Infallible;
|
||||
|
@ -327,23 +337,25 @@ pub mod settlement_server {
|
|||
}
|
||||
_ => {
|
||||
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(),
|
||||
)
|
||||
let mut response = http::Response::new(empty_body());
|
||||
let headers = response.headers_mut();
|
||||
headers
|
||||
.insert(
|
||||
tonic::Status::GRPC_STATUS,
|
||||
(tonic::Code::Unimplemented as i32).into(),
|
||||
);
|
||||
headers
|
||||
.insert(
|
||||
http::header::CONTENT_TYPE,
|
||||
tonic::metadata::GRPC_CONTENT_TYPE,
|
||||
);
|
||||
Ok(response)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: Settlement> Clone for SettlementServer<T> {
|
||||
impl<T> Clone for SettlementServer<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let inner = self.inner.clone();
|
||||
Self {
|
||||
|
@ -355,7 +367,9 @@ pub mod settlement_server {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl<T: Settlement> tonic::server::NamedService for SettlementServer<T> {
|
||||
const NAME: &'static str = "transfers.Settlement";
|
||||
/// Generated gRPC service name
|
||||
pub const SERVICE_NAME: &str = "transfers.Settlement";
|
||||
impl<T> tonic::server::NamedService for SettlementServer<T> {
|
||||
const NAME: &'static str = SERVICE_NAME;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ use quartz_common::{
|
|||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tonic::{Request, Response, Result as TonicResult, Status};
|
||||
use transfers_contract::msg::execute::{ClearTextTransferRequestMsg, Request as TransfersRequest};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
|
||||
use crate::{
|
||||
proto::{
|
||||
|
@ -113,7 +113,7 @@ pub enum TransfersOpEvent {
|
|||
pub struct TransfersOp<A: Attestor> {
|
||||
pub client: TransfersService<A>,
|
||||
pub event: TransfersOpEvent,
|
||||
pub config: WsListenerConfig
|
||||
pub config: WsListenerConfig,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -121,14 +121,19 @@ pub struct TransfersService<A: Attestor> {
|
|||
config: Config,
|
||||
sk: Arc<Mutex<Option<SigningKey>>>,
|
||||
attestor: A,
|
||||
pub queue_producer: Sender<TransfersOp<A>>
|
||||
pub queue_producer: Sender<TransfersOp<A>>,
|
||||
}
|
||||
|
||||
impl<A> TransfersService<A>
|
||||
where
|
||||
A: Attestor,
|
||||
{
|
||||
pub fn new(config: Config, sk: Arc<Mutex<Option<SigningKey>>>, attestor: A, queue_producer: Sender<TransfersOp<A>>) -> Self {
|
||||
pub fn new(
|
||||
config: Config,
|
||||
sk: Arc<Mutex<Option<SigningKey>>>,
|
||||
attestor: A,
|
||||
queue_producer: Sender<TransfersOp<A>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
config,
|
||||
sk,
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
//TODO: get rid of this
|
||||
use std::{collections::BTreeMap, str::FromStr};
|
||||
|
||||
use anyhow::{anyhow, Error, Result};
|
||||
use cosmrs::{tendermint::chain::Id as ChainId, AccountId};
|
||||
use cosmwasm_std::{Addr, HexBinary};
|
||||
use cw_client::{CwClient, GrpcClient};
|
||||
use futures_util::StreamExt;
|
||||
use quartz_common::{
|
||||
contract::msg::execute::attested::{
|
||||
MockAttestation, RawAttested, RawAttestedMsgSansHandler, RawMockAttestation,
|
||||
},
|
||||
contract::msg::execute::attested::{RawAttested, RawAttestedMsgSansHandler},
|
||||
enclave::{
|
||||
attestor::Attestor,
|
||||
server::{WebSocketHandler, WsListenerConfig},
|
||||
},
|
||||
};
|
||||
use reqwest::Url;
|
||||
use quartz_tm_prover::{config::Config as TmProverConfig, prover::prove};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use tendermint_rpc::{event::Event, query::EventType, SubscriptionClient, WebSocketClient};
|
||||
use quartz_tm_prover::{config::Config as TmProverConfig, prover::prove};
|
||||
use tonic::Request;
|
||||
use tracing::info;
|
||||
use transfers_contract::msg::{
|
||||
|
@ -25,13 +23,11 @@ use transfers_contract::msg::{
|
|||
AttestedMsg, ExecuteMsg,
|
||||
QueryMsg::{GetRequests, GetState},
|
||||
};
|
||||
use cw_client::{CliWasmdClient, QueryResult, WasmdClient};
|
||||
|
||||
use crate::{
|
||||
proto::{settlement_server::Settlement, QueryRequest, UpdateRequest},
|
||||
transfers_server::{
|
||||
QueryRequestMessage, TransfersOp, TransfersOpEvent,
|
||||
TransfersService, UpdateRequestMessage,
|
||||
QueryRequestMessage, TransfersOp, TransfersOpEvent, TransfersService, UpdateRequestMessage,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -46,23 +42,26 @@ impl TryFrom<Event> for TransfersOpEvent {
|
|||
|
||||
fn try_from(event: Event) -> Result<Self, Error> {
|
||||
if let Some(events) = &event.events {
|
||||
for (key, _) in events {
|
||||
for key in events.keys() {
|
||||
match key.as_str() {
|
||||
k if k.starts_with("wasm-query_balance") => {
|
||||
let (contract_address, ephemeral_pubkey, sender) =
|
||||
extract_event_info(TransfersOpEventTypes::Query, &events)
|
||||
.map_err(|_| anyhow!("Failed to extract event info from query event"))?;
|
||||
extract_event_info(TransfersOpEventTypes::Query, events).map_err(
|
||||
|_| anyhow!("Failed to extract event info from query event"),
|
||||
)?;
|
||||
|
||||
return Ok(TransfersOpEvent::Query {
|
||||
contract_address,
|
||||
ephemeral_pubkey: ephemeral_pubkey.ok_or(anyhow!("Missing ephemeral_pubkey"))?,
|
||||
ephemeral_pubkey: ephemeral_pubkey
|
||||
.ok_or(anyhow!("Missing ephemeral_pubkey"))?,
|
||||
sender: sender.ok_or(anyhow!("Missing sender"))?,
|
||||
});
|
||||
}
|
||||
k if k.starts_with("wasm-transfer.action") => {
|
||||
let (contract_address, _, _) =
|
||||
extract_event_info(TransfersOpEventTypes::Transfer, &events)
|
||||
.map_err(|_| anyhow!("Failed to extract event info from transfer event"))?;
|
||||
extract_event_info(TransfersOpEventTypes::Transfer, events).map_err(
|
||||
|_| anyhow!("Failed to extract event info from transfer event"),
|
||||
)?;
|
||||
|
||||
return Ok(TransfersOpEvent::Transfer { contract_address });
|
||||
}
|
||||
|
@ -99,7 +98,11 @@ pub trait WsListener: Send + Sync + 'static {
|
|||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<A: Attestor> WsListener for TransfersService<A> {
|
||||
impl<A> WsListener for TransfersService<A>
|
||||
where
|
||||
A: Attestor,
|
||||
A::RawAttestation: for<'de> Deserialize<'de> + Send,
|
||||
{
|
||||
async fn process(&self, event: TransfersOpEvent, config: WsListenerConfig) -> Result<()> {
|
||||
match event {
|
||||
TransfersOpEvent::Transfer { contract_address } => {
|
||||
|
@ -116,9 +119,8 @@ impl<A: Attestor> WsListener for TransfersService<A> {
|
|||
}
|
||||
}
|
||||
|
||||
let wsurl = format!("ws://{}/websocket", config.node_url);
|
||||
// Wait some blocks to make sure transaction was confirmed
|
||||
two_block_waitoor(&wsurl).await?;
|
||||
two_block_waitoor(config.ws_url.as_str()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -141,58 +143,57 @@ fn extract_event_info(
|
|||
.map_err(|e| anyhow!("Failed to parse contract address: {}", e))?;
|
||||
|
||||
// Set info for specific events
|
||||
match op_event {
|
||||
TransfersOpEventTypes::Query => {
|
||||
sender = events
|
||||
.get("message.sender")
|
||||
.ok_or_else(|| anyhow!("Missing message.sender in events"))?
|
||||
.first()
|
||||
.cloned();
|
||||
if let TransfersOpEventTypes::Query = op_event {
|
||||
sender = events
|
||||
.get("message.sender")
|
||||
.ok_or_else(|| anyhow!("Missing message.sender in events"))?
|
||||
.first()
|
||||
.cloned();
|
||||
|
||||
ephemeral_pubkey = events
|
||||
.get("wasm-query_balance.emphemeral_pubkey")
|
||||
.ok_or_else(|| anyhow!("Missing wasm-query_balance.emphemeral_pubkey in events"))?
|
||||
.first()
|
||||
.cloned();
|
||||
}
|
||||
_ => {}
|
||||
ephemeral_pubkey = events
|
||||
.get("wasm-query_balance.emphemeral_pubkey")
|
||||
.ok_or_else(|| anyhow!("Missing wasm-query_balance.emphemeral_pubkey in events"))?
|
||||
.first()
|
||||
.cloned();
|
||||
}
|
||||
|
||||
Ok((contract_address, ephemeral_pubkey, sender))
|
||||
}
|
||||
|
||||
async fn transfer_handler<A: Attestor>(
|
||||
async fn transfer_handler<A>(
|
||||
client: &TransfersService<A>,
|
||||
contract: &AccountId,
|
||||
ws_config: &WsListenerConfig,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
A: Attestor,
|
||||
A::RawAttestation: for<'de> Deserialize<'de>,
|
||||
{
|
||||
let chain_id = &ChainId::from_str(&ws_config.chain_id)?;
|
||||
let httpurl = Url::parse(&format!("http://{}", ws_config.node_url))?;
|
||||
let cw_client = CliWasmdClient::new(httpurl.clone());
|
||||
let cw_client = GrpcClient::new(ws_config.sk_file.clone(), ws_config.grpc_url.clone());
|
||||
|
||||
// Query contract state
|
||||
let resp: QueryResult<Vec<TransferRequest>> = cw_client
|
||||
let requests: Vec<TransferRequest> = cw_client
|
||||
.query_smart(contract, json!(GetRequests {}))
|
||||
.await
|
||||
.map_err(|e| anyhow!("Problem querying contract state: {}", e))?;
|
||||
let requests = resp.data;
|
||||
|
||||
let resp: QueryResult<HexBinary> = cw_client
|
||||
let state: HexBinary = cw_client
|
||||
.query_smart(contract, json!(GetState {}))
|
||||
.await
|
||||
.map_err(|e| anyhow!("Problem querying contract state: {}", e))?;
|
||||
let state = resp.data;
|
||||
|
||||
// Request body contents
|
||||
let update_contents = UpdateRequestMessage { state, requests };
|
||||
|
||||
// Wait 2 blocks
|
||||
info!("Waiting 2 blocks for light client proof");
|
||||
let wsurl = format!("ws://{}/websocket", ws_config.node_url);
|
||||
two_block_waitoor(&wsurl).await?;
|
||||
two_block_waitoor(ws_config.ws_url.as_str()).await?;
|
||||
|
||||
// Call tm prover with trusted hash and height
|
||||
let prover_config = TmProverConfig {
|
||||
primary: httpurl.as_str().parse()?,
|
||||
witnesses: httpurl.as_str().parse()?,
|
||||
primary: ws_config.node_url.as_str().parse()?,
|
||||
witnesses: ws_config.node_url.as_str().parse()?,
|
||||
trusted_height: ws_config.trusted_height,
|
||||
trusted_hash: ws_config.trusted_hash,
|
||||
verbose: "1".parse()?, // TODO: both tm-prover and cli define the same Verbosity struct. Need to define this once and import
|
||||
|
@ -230,53 +231,52 @@ async fn transfer_handler<A: Attestor>(
|
|||
.into_inner();
|
||||
|
||||
// Extract json from enclave response
|
||||
let attested: RawAttested<UpdateMsg, HexBinary> =
|
||||
let attested: RawAttested<UpdateMsg, A::RawAttestation> =
|
||||
serde_json::from_str(&update_response.message)
|
||||
.map_err(|e| anyhow!("Error deserializing UpdateMsg from enclave: {}", e))?;
|
||||
|
||||
// Build on-chain response
|
||||
// TODO add non-mock support
|
||||
let transfer_msg = ExecuteMsg::Update::<RawMockAttestation>(AttestedMsg {
|
||||
let transfer_msg = ExecuteMsg::Update(AttestedMsg {
|
||||
msg: RawAttestedMsgSansHandler(attested.msg),
|
||||
attestation: MockAttestation(
|
||||
attested
|
||||
.attestation
|
||||
.as_slice()
|
||||
.try_into()
|
||||
.map_err(|_| anyhow!("slice with incorrect length"))?,
|
||||
)
|
||||
.into(),
|
||||
attestation: attested.attestation,
|
||||
});
|
||||
|
||||
// Post response to chain
|
||||
let output = cw_client.tx_execute(
|
||||
contract,
|
||||
chain_id,
|
||||
2000000,
|
||||
&ws_config.tx_sender,
|
||||
json!(transfer_msg),
|
||||
)?;
|
||||
let output = cw_client
|
||||
.tx_execute(
|
||||
contract,
|
||||
chain_id,
|
||||
2000000,
|
||||
&ws_config.tx_sender,
|
||||
json!(transfer_msg),
|
||||
"11000untrn",
|
||||
)
|
||||
.await?;
|
||||
|
||||
println!("Output TX: {}", output);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn query_handler<A: Attestor>(
|
||||
async fn query_handler<A>(
|
||||
client: &TransfersService<A>,
|
||||
contract: &AccountId,
|
||||
msg_sender: &String,
|
||||
pubkey: &String,
|
||||
msg_sender: &str,
|
||||
pubkey: &str,
|
||||
ws_config: &WsListenerConfig,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
A: Attestor,
|
||||
A::RawAttestation: for<'de> Deserialize<'de>,
|
||||
{
|
||||
let chain_id = &ChainId::from_str(&ws_config.chain_id)?;
|
||||
let httpurl = Url::parse(&format!("http://{}", ws_config.node_url))?;
|
||||
let cw_client = CliWasmdClient::new(httpurl);
|
||||
let cw_client = GrpcClient::new(ws_config.sk_file.clone(), ws_config.grpc_url.clone());
|
||||
|
||||
// Query contract state
|
||||
let resp: QueryResult<HexBinary> = cw_client
|
||||
let state: HexBinary = cw_client
|
||||
.query_smart(contract, json!(GetState {}))
|
||||
.await
|
||||
.map_err(|e| anyhow!("Problem querying contract state: {}", e))?;
|
||||
let state = resp.data;
|
||||
|
||||
// Build request
|
||||
let update_contents = QueryRequestMessage {
|
||||
|
@ -297,32 +297,28 @@ async fn query_handler<A: Attestor>(
|
|||
.into_inner();
|
||||
|
||||
// Extract json from the enclave response
|
||||
let attested: RawAttested<QueryResponseMsg, HexBinary> =
|
||||
let attested: RawAttested<QueryResponseMsg, A::RawAttestation> =
|
||||
serde_json::from_str(&query_response.message)
|
||||
.map_err(|e| anyhow!("Error deserializing QueryResponseMsg from enclave: {}", e))?;
|
||||
|
||||
// Build on-chain response
|
||||
// TODO add non-mock support
|
||||
let query_msg = ExecuteMsg::QueryResponse::<RawMockAttestation>(AttestedMsg {
|
||||
let query_msg = ExecuteMsg::QueryResponse(AttestedMsg {
|
||||
msg: RawAttestedMsgSansHandler(attested.msg),
|
||||
attestation: MockAttestation(
|
||||
attested
|
||||
.attestation
|
||||
.as_slice()
|
||||
.try_into()
|
||||
.map_err(|_| anyhow!("slice with incorrect length"))?,
|
||||
)
|
||||
.into(),
|
||||
attestation: attested.attestation,
|
||||
});
|
||||
|
||||
// Post response to chain
|
||||
let output = cw_client.tx_execute(
|
||||
contract,
|
||||
chain_id,
|
||||
2000000,
|
||||
&ws_config.tx_sender,
|
||||
json!(query_msg),
|
||||
)?;
|
||||
let output = cw_client
|
||||
.tx_execute(
|
||||
contract,
|
||||
chain_id,
|
||||
2000000,
|
||||
&ws_config.tx_sender,
|
||||
json!(query_msg),
|
||||
"11000untrn",
|
||||
)
|
||||
.await?;
|
||||
|
||||
println!("Output TX: {}", output);
|
||||
Ok(())
|
||||
|
|
|
@ -2,6 +2,7 @@ import { ChainInfo } from '@keplr-wallet/types'
|
|||
|
||||
import { localWasm } from './chains/localWasm'
|
||||
import { localNeutron } from './chains/localNeutron'
|
||||
import { testnetNeutron } from './chains/testnetNeutron'
|
||||
|
||||
const supportedChains: Record<string, ChainInfo> = {
|
||||
doWasm: {
|
||||
|
@ -12,6 +13,7 @@ const supportedChains: Record<string, ChainInfo> = {
|
|||
},
|
||||
localNeutron,
|
||||
localWasm,
|
||||
testnetNeutron,
|
||||
}
|
||||
|
||||
const chain = supportedChains[process.env.NEXT_PUBLIC_TARGET_CHAIN!]
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ChainInfo } from '@keplr-wallet/types'
|
|||
|
||||
// Neutron local chain definition
|
||||
export const localNeutron: ChainInfo = {
|
||||
chainId: 'testing',
|
||||
chainId: 'test-1',
|
||||
chainName: 'Local Neutron Testchain',
|
||||
rpc: 'http://localhost:26657',
|
||||
rest: 'http://localhost:1317',
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import { ChainInfo } from '@keplr-wallet/types'
|
||||
|
||||
// Neutron testnet chain definition
|
||||
export const testnetNeutron: ChainInfo = {
|
||||
chainId: 'pion-1',
|
||||
chainName: 'Neutron Testnet',
|
||||
rpc: 'https://rpc-falcron.pion-1.ntrn.tech',
|
||||
rest: 'https://rest-falcron.pion-1.ntrn.tech',
|
||||
stakeCurrency: {
|
||||
coinDenom: 'NEUTRON',
|
||||
coinMinimalDenom: 'untrn',
|
||||
coinDecimals: 6,
|
||||
coinGeckoId: 'neutron',
|
||||
},
|
||||
bip44: {
|
||||
coinType: 118,
|
||||
},
|
||||
bech32Config: {
|
||||
bech32PrefixAccAddr: 'neutron',
|
||||
bech32PrefixAccPub: 'neutron' + 'pub',
|
||||
bech32PrefixValAddr: 'neutron' + 'valoper',
|
||||
bech32PrefixValPub: 'neutron' + 'valoperpub',
|
||||
bech32PrefixConsAddr: 'neutron' + 'valcons',
|
||||
bech32PrefixConsPub: 'neutron' + 'valconspub',
|
||||
},
|
||||
currencies: [
|
||||
{
|
||||
coinDenom: 'NTRN',
|
||||
coinMinimalDenom: 'untrn',
|
||||
coinDecimals: 6,
|
||||
coinGeckoId: 'neutron',
|
||||
},
|
||||
],
|
||||
feeCurrencies: [
|
||||
{
|
||||
coinDenom: 'NTRN',
|
||||
coinMinimalDenom: 'untrn',
|
||||
coinDecimals: 6,
|
||||
coinGeckoId: 'neutron',
|
||||
gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 },
|
||||
},
|
||||
],
|
||||
}
|
14
examples/transfers/quartz.neutron_pion-1.toml
Normal file
14
examples/transfers/quartz.neutron_pion-1.toml
Normal file
|
@ -0,0 +1,14 @@
|
|||
mock_sgx = false
|
||||
tx_sender = "val1"
|
||||
chain_id = "pion-1"
|
||||
node_url = "https://rpc-falcron.pion-1.ntrn.tech"
|
||||
ws_url = "wss://rpc-falcron.pion-1.ntrn.tech/websocket"
|
||||
grpc_url = "https://grpc-falcron.pion-1.ntrn.tech:80"
|
||||
# node_url = "https://neutron-testnet-rpc.polkachu.com"
|
||||
# ws_url = "wss://neutron-testnet-rpc.polkachu.com/websocket"
|
||||
# grpc_url = "https://grpc.baryon.remedy.tm.p2p.org:443"
|
||||
enclave_rpc_addr = "https://127.0.0.1"
|
||||
enclave_rpc_port = 11091
|
||||
trusted_hash = ""
|
||||
trusted_height = 0
|
||||
release = true
|
|
@ -1,7 +1,9 @@
|
|||
mock_sgx = true
|
||||
tx_sender = "admin"
|
||||
chain_id = "testing"
|
||||
node_url = "127.0.0.1:26657"
|
||||
node_url = "http://127.0.0.1:26657"
|
||||
ws_url = "ws://127.0.0.1/wesocket"
|
||||
grpc_url = "http://127.0.0.1:9090"
|
||||
enclave_rpc_addr = "http://127.0.0.1"
|
||||
enclave_rpc_port = 11090
|
||||
trusted_hash = ""
|
||||
|
|
Loading…
Reference in a new issue