From 73f9942337800ed91bfc750a0a2fad61a478c984 Mon Sep 17 00:00:00 2001 From: Andrey Lazarko Date: Mon, 18 Nov 2024 22:38:29 +0100 Subject: [PATCH 1/3] gmeta removed completely, cleaned up other crates from gmeta --- Cargo.lock | 117 +--- Cargo.toml | 11 +- Makefile | 1 - examples/fungible-token/Cargo.toml | 1 - examples/fungible-token/io/Cargo.toml | 1 - examples/fungible-token/io/src/lib.rs | 12 - examples/new-meta/Cargo.toml | 33 -- examples/new-meta/build.rs | 23 - examples/new-meta/src/lib.rs | 65 --- examples/new-meta/state-v1/Cargo.toml | 20 - examples/new-meta/state-v1/src/lib.rs | 33 -- examples/new-meta/state-v1/src/wasm.rs | 25 - examples/new-meta/state-v2/Cargo.toml | 20 - examples/new-meta/state-v2/build.rs | 21 - examples/new-meta/state-v2/src/wasm.rs | 29 - examples/new-meta/state-v3/build.rs | 21 - examples/new-meta/state-v3/src/lib.rs | 33 -- examples/new-meta/state-v3/src/wasm.rs | 16 - .../{new-meta/state-v3 => wallets}/Cargo.toml | 13 +- .../{new-meta/state-v1 => wallets}/build.rs | 2 +- examples/{new-meta => wallets}/io/Cargo.toml | 3 +- examples/{new-meta => wallets}/io/src/lib.rs | 12 - .../{new-meta/state-v2 => wallets}/src/lib.rs | 13 +- examples/{new-meta => wallets}/src/wasm.rs | 2 +- gcli/Cargo.toml | 11 +- gcli/README.md | 8 +- gcli/src/cmd/mod.rs | 4 - gcli/src/cmd/program.rs | 107 +--- gcli/src/embed.rs | 4 - gcli/src/lib.rs | 1 - gcli/src/meta/executor.rs | 300 ---------- gcli/src/meta/mod.rs | 162 ------ gcli/src/meta/registry.rs | 173 ------ gcli/src/meta/tests.rs | 142 ----- gcli/src/result.rs | 2 - gcli/tests/cmd/mod.rs | 1 - gcli/tests/cmd/program.rs | 183 ------ gcli/tests/cmd/upload.rs | 6 +- gcli/tests/common/mod.rs | 6 - gcli/tests/common/node.rs | 15 +- gcli/tests/gear.rs | 3 +- gclient/Cargo.toml | 5 +- gmeta/Cargo.toml | 28 - gmeta/codegen/Cargo.toml | 27 - gmeta/codegen/src/lib.rs | 523 ------------------ gmeta/src/lib.rs | 488 ---------------- gsdk/Cargo.toml | 12 +- gsdk/tests/rpc.rs | 20 +- pallets/gear/Cargo.toml | 3 +- pallets/gear/src/tests.rs | 277 +--------- scripts/src/format.sh | 2 +- utils/cargo-gbuild/test-program/Cargo.toml | 5 +- .../cargo-gbuild/test-program/meta/Cargo.toml | 12 - .../cargo-gbuild/test-program/meta/src/lib.rs | 13 - utils/crates-io/src/handler.rs | 37 -- utils/crates-io/src/lib.rs | 2 - utils/wasm-builder/Cargo.toml | 2 - utils/wasm-builder/README.md | 10 +- utils/wasm-builder/src/lib.rs | 52 +- utils/wasm-builder/src/smart_fs.rs | 24 - utils/wasm-builder/src/wasm_project.rs | 171 +----- utils/wasm-proc/src/main.rs | 2 +- 62 files changed, 115 insertions(+), 3255 deletions(-) delete mode 100644 examples/new-meta/Cargo.toml delete mode 100644 examples/new-meta/build.rs delete mode 100644 examples/new-meta/src/lib.rs delete mode 100644 examples/new-meta/state-v1/Cargo.toml delete mode 100644 examples/new-meta/state-v1/src/lib.rs delete mode 100644 examples/new-meta/state-v1/src/wasm.rs delete mode 100644 examples/new-meta/state-v2/Cargo.toml delete mode 100644 examples/new-meta/state-v2/build.rs delete mode 100644 examples/new-meta/state-v2/src/wasm.rs delete mode 100644 examples/new-meta/state-v3/build.rs delete mode 100644 examples/new-meta/state-v3/src/lib.rs delete mode 100644 examples/new-meta/state-v3/src/wasm.rs rename examples/{new-meta/state-v3 => wallets}/Cargo.toml (53%) rename examples/{new-meta/state-v1 => wallets}/build.rs (95%) rename examples/{new-meta => wallets}/io/Cargo.toml (85%) rename examples/{new-meta => wallets}/io/src/lib.rs (86%) rename examples/{new-meta/state-v2 => wallets}/src/lib.rs (81%) rename examples/{new-meta => wallets}/src/wasm.rs (91%) delete mode 100644 gcli/src/meta/executor.rs delete mode 100644 gcli/src/meta/mod.rs delete mode 100644 gcli/src/meta/registry.rs delete mode 100644 gcli/src/meta/tests.rs delete mode 100644 gcli/tests/cmd/program.rs delete mode 100644 gmeta/Cargo.toml delete mode 100644 gmeta/codegen/Cargo.toml delete mode 100644 gmeta/codegen/src/lib.rs delete mode 100644 gmeta/src/lib.rs delete mode 100644 utils/cargo-gbuild/test-program/meta/Cargo.toml delete mode 100644 utils/cargo-gbuild/test-program/meta/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 94275f1ff5f..e630872d9b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3485,7 +3485,6 @@ dependencies = [ "gclient", "gear-core", "gear-wasm-builder", - "gmeta", "gstd", "hashbrown 0.14.5", "rand 0.8.5", @@ -3555,46 +3554,6 @@ dependencies = [ "gstd", ] -[[package]] -name = "demo-meta-io" -version = "0.1.0" -dependencies = [ - "gmeta", - "gstd", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "demo-meta-state-v1" -version = "0.1.0" -dependencies = [ - "demo-meta-io", - "gear-wasm-builder", - "gmeta", - "gstd", -] - -[[package]] -name = "demo-meta-state-v2" -version = "0.1.0" -dependencies = [ - "demo-meta-io", - "gear-wasm-builder", - "gmeta", - "gstd", -] - -[[package]] -name = "demo-meta-state-v3" -version = "0.1.0" -dependencies = [ - "demo-meta-io", - "gear-wasm-builder", - "gmeta", - "gstd", -] - [[package]] name = "demo-mul-by-const" version = "0.1.0" @@ -3613,20 +3572,6 @@ dependencies = [ "hex", ] -[[package]] -name = "demo-new-meta" -version = "0.1.0" -dependencies = [ - "demo-meta-io", - "demo-meta-state-v1", - "demo-meta-state-v2", - "demo-meta-state-v3", - "gear-wasm-builder", - "gstd", - "gtest", - "parity-scale-codec", -] - [[package]] name = "demo-node" version = "0.1.0" @@ -3900,6 +3845,26 @@ dependencies = [ "gstd", ] +[[package]] +name = "demo-wallets" +version = "0.1.0" +dependencies = [ + "demo-wallets-io", + "gear-wasm-builder", + "gstd", + "gtest", + "parity-scale-codec", +] + +[[package]] +name = "demo-wallets-io" +version = "0.1.0" +dependencies = [ + "gstd", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "demo-wat" version = "0.1.0" @@ -5537,7 +5502,6 @@ dependencies = [ name = "ft-io" version = "0.1.4" dependencies = [ - "gmeta", "gstd", ] @@ -5786,8 +5750,8 @@ dependencies = [ "color-eyre", "colored", "demo-messenger", - "demo-new-meta", "demo-waiter", + "demo-wallets", "dirs", "env_logger", "etc", @@ -5796,7 +5760,6 @@ dependencies = [ "gear-core-errors", "gear-node-wrapper", "gear-runtime-primitives", - "gmeta", "gring", "gsdk", "hex", @@ -5836,14 +5799,14 @@ dependencies = [ "demo-constructor", "demo-custom", "demo-distributor", - "demo-meta-io", "demo-mul-by-const", - "demo-new-meta", "demo-node", "demo-program-factory", "demo-proxy", "demo-proxy-relay", "demo-reserve-gas", + "demo-wallets", + "demo-wallets-io", "demo-wat", "env_logger", "futures", @@ -5851,7 +5814,6 @@ dependencies = [ "gear-core-errors", "gear-node-wrapper", "gear-utils", - "gmeta", "gsdk", "gstd", "hex", @@ -6549,7 +6511,6 @@ dependencies = [ "gear-pwasm-utils", "gear-wasm-instrument", "gear-wasm-optimizer", - "gmeta", "itertools 0.13.0", "log", "parity-wasm", @@ -6813,33 +6774,6 @@ dependencies = [ "regex", ] -[[package]] -name = "gmeta" -version = "1.6.2" -dependencies = [ - "blake2 0.10.6", - "derive_more 0.99.18", - "gear-wasm-builder", - "gmeta-codegen", - "gstd", - "hex", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "gmeta-codegen" -version = "1.6.2" -dependencies = [ - "gmeta", - "gstd", - "parity-scale-codec", - "proc-macro2", - "quote", - "scale-info", - "syn 2.0.71", -] - [[package]] name = "gprimitives" version = "1.6.2" @@ -6892,9 +6826,9 @@ dependencies = [ "base64 0.21.7", "colored", "demo-messenger", - "demo-new-meta", "demo-vec", "demo-waiter", + "demo-wallets", "futures", "futures-util", "gear-core", @@ -10820,7 +10754,6 @@ dependencies = [ "demo-init-wait", "demo-init-wait-reply-exit", "demo-mul-by-const", - "demo-new-meta", "demo-out-of-memory", "demo-ping", "demo-program-factory", @@ -10842,6 +10775,7 @@ dependencies = [ "demo-wait-wake", "demo-waiter", "demo-waiting-proxy", + "demo-wallets", "derive_more 0.99.18", "env_logger", "frame-benchmarking", @@ -10858,7 +10792,6 @@ dependencies = [ "gear-runtime-interface", "gear-sandbox", "gear-wasm-instrument", - "gmeta", "gstd", "gsys", "hex", diff --git a/Cargo.toml b/Cargo.toml index 94d6641b6e1..e951c3e1655 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,6 @@ members = [ "examples/messenger", "examples/mul-by-const", "examples/ncompose", - "examples/new-meta", "examples/node", "examples/out-of-memory", "examples/piggy-bank", @@ -82,14 +81,14 @@ members = [ "examples/wait_wake", "examples/waiter", "examples/waiting-proxy", + "examples/wallets", + "examples/wallets/io", "examples/wat", "galloc", "gbuiltins/*", "gcli", "gclient", "gcore", - "gmeta", - "gmeta/codegen", "gprimitives", "gsdk", "gsdk/codegen", @@ -229,8 +228,6 @@ gstd-codegen = { path = "gstd/codegen" } gring = { path = "utils/gring" } gsys = { path = "gsys" } gtest = { path = "gtest" } -gmeta = { path = "gmeta" } -gmeta-codegen = { path = "gmeta/codegen" } gprimitives = { path = "gprimitives", default-features = false } gear-authorship = { path = "node/authorship" } gear-core-backend = { path = "core-backend", default-features = false } @@ -467,9 +464,7 @@ demo-init-fail-sender = { path = "examples/init-fail-sender" } demo-init-wait = { path = "examples/init-wait", default-features = false } demo-init-wait-reply-exit = { path = "examples/init-wait-reply-exit" } demo-messenger = { path = "examples/messenger" } -demo-meta-io = { path = "examples/new-meta/io" } demo-mul-by-const = { path = "examples/mul-by-const" } -demo-new-meta = { path = "examples/new-meta" } demo-node = { path = "examples/node" } demo-out-of-memory = { path = "examples/out-of-memory" } demo-piggy-bank = { path = "examples/piggy-bank", features = ["debug"] } @@ -497,6 +492,8 @@ demo-wait-timeout = { path = "examples/wait-timeout" } demo-wait-wake = { path = "examples/wait_wake" } demo-waiting-proxy = { path = "examples/waiting-proxy" } demo-stack-allocations = { path = "examples/stack-allocations" } +demo-wallets = { path = "examples/wallets" } +demo-wallets-io = { path = "examples/wallets/io" } demo-wat = { path = "examples/wat" } # Dependencies that only used in one package diff --git a/Makefile b/Makefile index 4a9cbb907ed..60059df0890 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,6 @@ doc: @ RUSTDOCFLAGS="--enable-index-page --generate-link-to-definition -Zunstable-options -D warnings" cargo doc --no-deps \ -p galloc -p gclient -p gcore -p gear-core-backend \ -p gear-core -p gear-core-processor -p gear-lazy-pages -p gear-core-errors \ - -p gmeta -p gtest -p gear-wasm-builder -p gear-common \ -p pallet-gear -p pallet-gear-gas -p pallet-gear-messenger -p pallet-gear-payment \ -p pallet-gear-program -p pallet-gear-rpc-runtime-api -p pallet-gear-rpc -p pallet-gear-scheduler -p gsdk @ RUSTDOCFLAGS="--enable-index-page --generate-link-to-definition -Zunstable-options -D warnings" cargo doc --no-deps \ diff --git a/examples/fungible-token/Cargo.toml b/examples/fungible-token/Cargo.toml index 10bcebb6cf4..f46fa9a1b5f 100644 --- a/examples/fungible-token/Cargo.toml +++ b/examples/fungible-token/Cargo.toml @@ -10,7 +10,6 @@ repository.workspace = true [dependencies] gstd.workspace = true hashbrown.workspace = true -gmeta.workspace = true ft-io = { path = "io" } [dev-dependencies] diff --git a/examples/fungible-token/io/Cargo.toml b/examples/fungible-token/io/Cargo.toml index 7fd0537bf5c..d84cba93023 100644 --- a/examples/fungible-token/io/Cargo.toml +++ b/examples/fungible-token/io/Cargo.toml @@ -9,4 +9,3 @@ repository.workspace = true [dependencies] gstd.workspace = true -gmeta.workspace = true diff --git a/examples/fungible-token/io/src/lib.rs b/examples/fungible-token/io/src/lib.rs index 670f3d10131..3b7a6b295f6 100644 --- a/examples/fungible-token/io/src/lib.rs +++ b/examples/fungible-token/io/src/lib.rs @@ -19,20 +19,8 @@ #![no_std] use core::ops::Range; -use gmeta::{In, InOut, Metadata, Out}; use gstd::{prelude::*, ActorId}; -pub struct FungibleTokenMetadata; - -impl Metadata for FungibleTokenMetadata { - type Init = In; - type Handle = InOut; - type Others = (); - type Reply = (); - type Signal = (); - type State = Out; -} - #[derive(Debug, Decode, Encode, TypeInfo)] #[codec(crate = gstd::codec)] #[scale_info(crate = gstd::scale_info)] diff --git a/examples/new-meta/Cargo.toml b/examples/new-meta/Cargo.toml deleted file mode 100644 index f78115c3251..00000000000 --- a/examples/new-meta/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "demo-new-meta" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -gstd.workspace = true -parity-scale-codec.workspace = true -demo-meta-io = { path = "io" } -demo-meta-state-v1 = { path = "state-v1", default-features = false, optional = true } -demo-meta-state-v2 = { path = "state-v2", default-features = false, optional = true } -demo-meta-state-v3 = { path = "state-v3", default-features = false, optional = true } - -[build-dependencies] -demo-meta-io = { path = "io" } -gear-wasm-builder.workspace = true - -[dev-dependencies] -gtest.workspace = true - -[features] -debug = ["gstd/debug"] -default = ["std"] -std = [ - "demo-meta-state-v1/std", - "demo-meta-state-v2/std", - "demo-meta-state-v3/std", - "parity-scale-codec/std", -] diff --git a/examples/new-meta/build.rs b/examples/new-meta/build.rs deleted file mode 100644 index 2145bfcbf58..00000000000 --- a/examples/new-meta/build.rs +++ /dev/null @@ -1,23 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use demo_meta_io::ProgramMetadata; - -fn main() { - gear_wasm_builder::build_with_metadata::(); -} diff --git a/examples/new-meta/src/lib.rs b/examples/new-meta/src/lib.rs deleted file mode 100644 index 49e9a7502f6..00000000000 --- a/examples/new-meta/src/lib.rs +++ /dev/null @@ -1,65 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#![no_std] - -// Reexport of types. -pub use demo_meta_io::*; - -// For wasm compilation. -#[cfg(not(feature = "std"))] -mod wasm; - -// Empty exports for native usage as dependency in other crates for running clippy. -#[cfg(not(feature = "std"))] -mod exports { - pub const WASM_BINARY: &[u8] = &[]; - pub const WASM_METADATA: &[u8] = &[]; - pub const META_EXPORTS_V1: &[&str] = &[]; - pub const META_WASM_V1: &[u8] = &[]; - pub const META_EXPORTS_V2: &[&str] = &[]; - pub const META_WASM_V2: &[u8] = &[]; - pub const META_EXPORTS_V3: &[&str] = &[]; - pub const META_WASM_V3: &[u8] = &[]; -} - -// Exports for native usage as dependency in other crates. -#[cfg(feature = "std")] -mod exports { - mod code { - include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - } - - // Binary itself. - pub use code::WASM_BINARY_OPT as WASM_BINARY; - - // Metadata of the binary, defining types and registry for JS. - pub use code::WASM_METADATA; - - // First reading state functions implementation. - pub use demo_meta_state_v1::{META_EXPORTS_V1, META_WASM_V1}; - - // Second reading state functions implementation. - pub use demo_meta_state_v2::{META_EXPORTS_V2, META_WASM_V2}; - - // Third reading state functions implementation. - pub use demo_meta_state_v3::{META_EXPORTS_V3, META_WASM_V3}; -} - -// Public exports. -pub use exports::*; diff --git a/examples/new-meta/state-v1/Cargo.toml b/examples/new-meta/state-v1/Cargo.toml deleted file mode 100644 index df273f240cf..00000000000 --- a/examples/new-meta/state-v1/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "demo-meta-state-v1" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -gstd.workspace = true -gmeta = { workspace = true, features = ["codegen"] } -demo-meta-io = { path = "../io" } - -[build-dependencies] -gear-wasm-builder = { workspace = true, features = ["metawasm"] } - -[features] -default = ["std"] -std = [] diff --git a/examples/new-meta/state-v1/src/lib.rs b/examples/new-meta/state-v1/src/lib.rs deleted file mode 100644 index 19fedf2abb0..00000000000 --- a/examples/new-meta/state-v1/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#![no_std] - -#[cfg(feature = "std")] -mod code { - include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -} - -#[cfg(feature = "std")] -pub use code::WASM_BINARY as META_WASM_V1; - -#[cfg(feature = "std")] -pub use code::WASM_EXPORTS as META_EXPORTS_V1; - -#[cfg(not(feature = "std"))] -mod wasm; diff --git a/examples/new-meta/state-v1/src/wasm.rs b/examples/new-meta/state-v1/src/wasm.rs deleted file mode 100644 index dbc375b8090..00000000000 --- a/examples/new-meta/state-v1/src/wasm.rs +++ /dev/null @@ -1,25 +0,0 @@ -use demo_meta_io::Wallet; -use gmeta::metawasm; -use gstd::prelude::*; - -#[metawasm] -pub mod metafns { - pub type State = Vec; - - /// Returns the first wallet. - pub fn first_wallet(state: State) -> Option { - state.first().cloned() - } - - /// Returns the last wallet. - pub fn last_wallet(state: State) -> Option { - state.last().cloned() - } - - /// Returns the first & last wallets. - /// - /// They'll equal if the program has only one wallet. - pub fn first_and_last_wallets(state: State) -> (Option, Option) { - (first_wallet(state.clone()), last_wallet(state)) - } -} diff --git a/examples/new-meta/state-v2/Cargo.toml b/examples/new-meta/state-v2/Cargo.toml deleted file mode 100644 index b63c6aec983..00000000000 --- a/examples/new-meta/state-v2/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "demo-meta-state-v2" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -gstd.workspace = true -gmeta = { workspace = true, features = ["codegen"] } -demo-meta-io = { path = "../io" } - -[build-dependencies] -gear-wasm-builder = { workspace = true, features = ["metawasm"] } - -[features] -default = ["std"] -std = [] diff --git a/examples/new-meta/state-v2/build.rs b/examples/new-meta/state-v2/build.rs deleted file mode 100644 index 22ff531d7de..00000000000 --- a/examples/new-meta/state-v2/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -fn main() { - gear_wasm_builder::build_metawasm(); -} diff --git a/examples/new-meta/state-v2/src/wasm.rs b/examples/new-meta/state-v2/src/wasm.rs deleted file mode 100644 index 69ec36a0dd8..00000000000 --- a/examples/new-meta/state-v2/src/wasm.rs +++ /dev/null @@ -1,29 +0,0 @@ -use demo_meta_io::{Id, Person, Wallet}; -use gmeta::metawasm; -use gstd::prelude::*; - -#[metawasm] -pub mod metafns { - pub type State = Vec; - - /// Returns a wallet with the given `id`. - pub fn wallet_by_id(state: State, id: Id) -> Option { - state.into_iter().find(|w| w.id == id) - } - - /// Returns a wallet of the given `person`. - pub fn wallet_by_person(state: State, Person { surname, name }: Person) -> Option { - let person = Person { surname, name }; - - state.into_iter().find(|w| w.person == person) - } - - /// Returns a wallet of a person with the given `name` & `surname`. - pub fn wallet_by_name_and_surname( - state: State, - name: String, - surname: String, - ) -> Option { - wallet_by_person(state, Person { surname, name }) - } -} diff --git a/examples/new-meta/state-v3/build.rs b/examples/new-meta/state-v3/build.rs deleted file mode 100644 index 22ff531d7de..00000000000 --- a/examples/new-meta/state-v3/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -fn main() { - gear_wasm_builder::build_metawasm(); -} diff --git a/examples/new-meta/state-v3/src/lib.rs b/examples/new-meta/state-v3/src/lib.rs deleted file mode 100644 index 4345f1b6647..00000000000 --- a/examples/new-meta/state-v3/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#![no_std] - -#[cfg(feature = "std")] -mod code { - include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -} - -#[cfg(feature = "std")] -pub use code::WASM_BINARY as META_WASM_V3; - -#[cfg(feature = "std")] -pub use code::WASM_EXPORTS as META_EXPORTS_V3; - -#[cfg(not(feature = "std"))] -mod wasm; diff --git a/examples/new-meta/state-v3/src/wasm.rs b/examples/new-meta/state-v3/src/wasm.rs deleted file mode 100644 index c956fa705ba..00000000000 --- a/examples/new-meta/state-v3/src/wasm.rs +++ /dev/null @@ -1,16 +0,0 @@ -use demo_meta_io::Wallet; -use gmeta::metawasm; -use gstd::{exec, prelude::*}; - -#[metawasm] -pub mod metafns { - pub type State = Vec; - - pub fn block_number(_: State) -> u32 { - exec::block_height() - } - - pub fn block_timestamp(_: State) -> u64 { - exec::block_timestamp() - } -} diff --git a/examples/new-meta/state-v3/Cargo.toml b/examples/wallets/Cargo.toml similarity index 53% rename from examples/new-meta/state-v3/Cargo.toml rename to examples/wallets/Cargo.toml index 7724c477251..b68a40dcad9 100644 --- a/examples/new-meta/state-v3/Cargo.toml +++ b/examples/wallets/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "demo-meta-state-v3" +name = "demo-wallets" version = "0.1.0" authors.workspace = true edition.workspace = true @@ -9,12 +9,17 @@ repository.workspace = true [dependencies] gstd.workspace = true -gmeta = { workspace = true, features = ["codegen"] } -demo-meta-io = { path = "../io" } +parity-scale-codec.workspace = true +demo-wallets-io = { path = "io" } [build-dependencies] -gear-wasm-builder = { workspace = true, features = ["metawasm"] } +demo-wallets-io = { path = "io" } +gear-wasm-builder.workspace = true + +[dev-dependencies] +gtest.workspace = true [features] +debug = ["gstd/debug"] default = ["std"] std = [] diff --git a/examples/new-meta/state-v1/build.rs b/examples/wallets/build.rs similarity index 95% rename from examples/new-meta/state-v1/build.rs rename to examples/wallets/build.rs index 22ff531d7de..bd6ee0ee6b9 100644 --- a/examples/new-meta/state-v1/build.rs +++ b/examples/wallets/build.rs @@ -17,5 +17,5 @@ // along with this program. If not, see . fn main() { - gear_wasm_builder::build_metawasm(); + gear_wasm_builder::build(); } diff --git a/examples/new-meta/io/Cargo.toml b/examples/wallets/io/Cargo.toml similarity index 85% rename from examples/new-meta/io/Cargo.toml rename to examples/wallets/io/Cargo.toml index 4caadf43edd..b6873f42b96 100644 --- a/examples/new-meta/io/Cargo.toml +++ b/examples/wallets/io/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "demo-meta-io" +name = "demo-wallets-io" version = "0.1.0" authors.workspace = true edition.workspace = true @@ -9,6 +9,5 @@ repository.workspace = true [dependencies] gstd.workspace = true -gmeta.workspace = true scale-info.workspace = true parity-scale-codec.workspace = true diff --git a/examples/new-meta/io/src/lib.rs b/examples/wallets/io/src/lib.rs similarity index 86% rename from examples/new-meta/io/src/lib.rs rename to examples/wallets/io/src/lib.rs index 75072030ebb..861c2642186 100644 --- a/examples/new-meta/io/src/lib.rs +++ b/examples/wallets/io/src/lib.rs @@ -3,21 +3,9 @@ extern crate alloc; use alloc::{string::String, vec, vec::Vec}; -use gmeta::{InOut, Metadata, Out}; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; -pub struct ProgramMetadata; - -impl Metadata for ProgramMetadata { - type Init = InOut; - type Handle = InOut; - type Others = InOut>; - type Reply = String; - type Signal = (); - type State = Out>; -} - // Metatypes for input and output #[derive(TypeInfo, Default, Decode, Encode)] pub struct MessageInitIn { diff --git a/examples/new-meta/state-v2/src/lib.rs b/examples/wallets/src/lib.rs similarity index 81% rename from examples/new-meta/state-v2/src/lib.rs rename to examples/wallets/src/lib.rs index d8943dcfb29..03fbcfd3e87 100644 --- a/examples/new-meta/state-v2/src/lib.rs +++ b/examples/wallets/src/lib.rs @@ -16,7 +16,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#![no_std] +#![cfg_attr(not(feature = "std"), no_std)] + +// Reexport of types. +pub use demo_wallets_io::*; #[cfg(feature = "std")] mod code { @@ -24,10 +27,10 @@ mod code { } #[cfg(feature = "std")] -pub use code::WASM_BINARY as META_WASM_V2; +pub use code::WASM_BINARY_OPT as WASM_BINARY; -#[cfg(feature = "std")] -pub use code::WASM_EXPORTS as META_EXPORTS_V2; +#[cfg(not(feature = "std"))] +pub const WASM_BINARY: &[u8] = &[]; #[cfg(not(feature = "std"))] -mod wasm; +pub mod wasm; diff --git a/examples/new-meta/src/wasm.rs b/examples/wallets/src/wasm.rs similarity index 91% rename from examples/new-meta/src/wasm.rs rename to examples/wallets/src/wasm.rs index ff62c7830a0..3b6cc18d711 100644 --- a/examples/new-meta/src/wasm.rs +++ b/examples/wallets/src/wasm.rs @@ -1,4 +1,4 @@ -use crate::{MessageIn, MessageInitIn, MessageInitOut, MessageOut, Wallet}; +use demo_wallets_io::{MessageIn, MessageInitIn, MessageInitOut, MessageOut, Wallet}; use gstd::{msg, prelude::*}; // State diff --git a/gcli/Cargo.toml b/gcli/Cargo.toml index fed73c7699e..22b7cb89457 100644 --- a/gcli/Cargo.toml +++ b/gcli/Cargo.toml @@ -21,21 +21,20 @@ colored.workspace = true color-eyre.workspace = true dirs.workspace = true env_logger.workspace = true -gmeta.workspace = true gear-core.workspace = true gear-core-errors.workspace = true -gring = { workspace = true, features = [ "cli" ] } +gring = { workspace = true, features = ["cli"] } hex.workspace = true -jsonrpsee = { workspace = true, features = [ "http-client", "ws-client" ] } +jsonrpsee = { workspace = true, features = ["http-client", "ws-client"] } keyring.workspace = true log.workspace = true scale-info.workspace = true serde.workspace = true clap = { workspace = true, features = ["std", "derive"] } thiserror.workspace = true -tokio = { workspace = true, features = [ "full" ] } +tokio = { workspace = true, features = ["full"] } whoami.workspace = true -reqwest = { workspace = true, default-features = false, features = [ "json", "rustls-tls" ] } +reqwest = { workspace = true, default-features = false, features = ["json", "rustls-tls"] } etc.workspace = true runtime-primitives.workspace = true url = { workspace = true, features = ["serde"] } @@ -46,7 +45,7 @@ wasmer-types.workspace = true [dev-dependencies] rand.workspace = true demo-messenger.workspace = true -demo-new-meta.workspace = true +demo-wallets.workspace = true demo-waiter.workspace = true gear-node-wrapper.workspace = true diff --git a/gcli/README.md b/gcli/README.md index 759ead02ef9..d3ff03b1eb6 100644 --- a/gcli/README.md +++ b/gcli/README.md @@ -6,12 +6,19 @@ [![License][l1]][l2] [ci1]: https://github.com/gear-tech/gear/workflows/CI/badge.svg + [ci2]: https://github.com/gear-tech/gear/actions/workflows/CI.yaml + [docs1]: https://img.shields.io/badge/current-docs-brightgreen.svg + [docs2]: https://docs.rs/gear-program/ + [d1]: https://img.shields.io/crates/d/gear-program.svg + [d2]: https://crates.io/crates/gear-program + [l1]: https://img.shields.io/badge/License-GPL%203.0-success + [l2]: https://github.com/clearloop/gear-program/blob/master/LICENSE ## Getting Started @@ -36,7 +43,6 @@ Commands: info Get account info from ss58address key Keypair utils login Log in to account - meta Show metadata structure, read types from registry, etc new Create a new gear program program Read program state, etc reply Sends a reply message diff --git a/gcli/src/cmd/mod.rs b/gcli/src/cmd/mod.rs index ef15ce70a3f..5820aba7e4a 100644 --- a/gcli/src/cmd/mod.rs +++ b/gcli/src/cmd/mod.rs @@ -56,7 +56,6 @@ pub enum Command { Info(Info), New(New), Config(Config), - #[clap(subcommand)] Program(Program), Reply(Reply), Send(Send), @@ -98,9 +97,6 @@ impl Command { Command::Upload(upload) => { Command::Upload(upload.clone_with_code_overridden(artifact.opt)) } - Command::Program(program) => { - Command::Program(program.clone_with_meta_overridden(artifact.meta)) - } _ => self.clone(), }; diff --git a/gcli/src/cmd/program.rs b/gcli/src/cmd/program.rs index ce5117950f9..fb6570a4ed0 100644 --- a/gcli/src/cmd/program.rs +++ b/gcli/src/cmd/program.rs @@ -18,115 +18,28 @@ //! Command `program`. //! -use crate::{meta::Meta, result::Result, App}; -use anyhow::anyhow; +use crate::{result::Result, App}; use clap::Parser; -use gclient::{ext::sp_core::H256, GearApi}; -use std::{fs, path::PathBuf}; +use gclient::ext::sp_core::H256; /// Read program state, etc. #[derive(Clone, Debug, Parser)] -pub enum Program { - /// Display metadata of the program. - /// - /// More details please check https://wiki.gear-tech.io/docs/api/metadata-type-creation. - Meta { - /// Path of "*.meta.txt" or "*meta.wasm". - /// - /// - "*.meta.txt" describes the metadata of the program - /// - "*.meta.wasm" describes the wasm exports of the program - #[cfg_attr(feature = "embed", clap(skip))] - meta: PathBuf, - /// Overridden metadata binary if feature embed is enabled. - #[clap(skip)] - meta_override: Vec, - /// Derive the description of the specified type from registry. - #[arg(short, long)] - derive: Option, - }, - /// Read program state. - /// - /// For more details, see https://wiki.gear-tech.io/docs/api/read-state. - State { - /// Program id. - pid: H256, - /// The block hash for reading state. - #[arg(long)] - at: Option, - }, +pub struct Program { + /// Program id. + pid: H256, + /// The block hash for reading state. + #[arg(long)] + at: Option, } impl Program { - /// Clone self with metadata overridden. - pub fn clone_with_meta_overridden(&self, meta: Vec) -> Self { - let mut overridden = self.clone(); - if let Program::Meta { meta_override, .. } = &mut overridden { - *meta_override = meta; - }; - overridden - } - /// Run command program. pub async fn exec(&self, app: &impl App) -> Result<()> { - match self { - Program::State { pid, at } => { - let api = app.signer().await?; - Self::full_state(&api, *pid, *at).await?; - } - Program::Meta { - meta, - derive, - meta_override, - } => { - let meta = if meta_override.is_empty() { - Self::resolve_meta(meta) - } else { - Meta::decode_wasm(meta_override) - }?; - - Self::meta(meta, derive)? - } - } - - Ok(()) - } - - async fn full_state(api: &GearApi, pid: H256, at: Option) -> Result<()> { + let api = app.signer().await?; let state = api - .read_state_bytes_at(pid.0.into(), Default::default(), at) + .read_state_bytes_at(self.pid.0.into(), Default::default(), self.at) .await?; println!("0x{}", hex::encode(state)); Ok(()) } - - fn resolve_meta(path: &PathBuf) -> Result { - let ext = path - .extension() - .ok_or_else(|| anyhow!("Invalid file extension"))?; - let data = fs::read(path)?; - - // parse from hex if end with `txt`. - let meta = if ext == "txt" { - Meta::decode_hex(&data)? - } else if ext == "wasm" { - // parse from wasm if end with `wasm`. - Meta::decode_wasm(&data)? - } else { - return Err(anyhow!(format!("Unsupported file extension {:?}", ext)).into()); - }; - - Ok(meta) - } - - fn meta(meta: Meta, name: &Option) -> Result<()> { - let fmt = if let Some(name) = name { - format!("{:#}", meta.derive(name)?) - } else { - format!("{meta:#}") - }; - - // println result. - println!("{}", fmt.replace('"', "")); - Ok(()) - } } diff --git a/gcli/src/embed.rs b/gcli/src/embed.rs index acdef562fc8..88f0bdf0268 100644 --- a/gcli/src/embed.rs +++ b/gcli/src/embed.rs @@ -48,9 +48,6 @@ const OUT_SUFFIX_LENGTH: usize = 17; pub struct Artifact { /// The optitmized WASM binary. pub opt: Vec, - - /// The metadata WASM binary if any. - pub meta: Vec, } impl Artifact { @@ -79,7 +76,6 @@ impl Artifact { Some(Self { opt: fs::read(bin.join(stem.with_extension("wasm"))).ok()?, - meta: fs::read(bin.join(stem.with_extension("meta.wasm"))).unwrap_or_default(), }) } } diff --git a/gcli/src/lib.rs b/gcli/src/lib.rs index fa64e9bae08..df49205b2cf 100644 --- a/gcli/src/lib.rs +++ b/gcli/src/lib.rs @@ -125,7 +125,6 @@ mod app; pub mod cmd; pub mod embed; -pub mod meta; pub mod result; pub mod template; pub mod utils; diff --git a/gcli/src/meta/executor.rs b/gcli/src/meta/executor.rs deleted file mode 100644 index 30151506c11..00000000000 --- a/gcli/src/meta/executor.rs +++ /dev/null @@ -1,300 +0,0 @@ -// This file is part of Gear. -// -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! The WASM executor in this module is just for parsing the state types -//! of gear programs, some of the host functions are missing logics that -//! is because they are for the on-chain environment data. - -use anyhow::{anyhow, Context, Result}; -use wasmer::{Engine, FunctionEnv, Imports, Instance, Memory, MemoryType, Module, Store}; - -/// HostState for the WASM executor -#[derive(Default)] -pub struct HostState { - /// Message buffer in host state. - pub msg: Vec, -} - -/// Call `metadata` method in the WASM code. -pub fn call_metadata(wasm: &[u8]) -> Result> { - execute(wasm, "metadata") -} - -/// Executes the WASM code. -fn execute(wasm: &[u8], method: &str) -> Result> { - let engine = Engine::default(); - let module = Module::new(&engine, wasm).unwrap(); - - let mut store = Store::new(engine); - let memory_type = MemoryType::new(256, None, false); - let memory = - Memory::new(&mut store, memory_type).map_err(|_| anyhow!("failed to create memory"))?; - let mut imports = Imports::new(); - let state = FunctionEnv::new(&mut store, HostState::default()); - - // Execution environment - // - // TODO: refactor this after #3416. - { - let mut env = env::Env { - imports: &mut imports, - function_env: &state, - store: &mut store, - memory, - }; - - for import in module.imports() { - env.define(import.module(), import.name())?; - } - } - - let instance = Instance::new(&mut store, &module, &imports)?; - let metadata = instance - .exports - .get_function(method) - .with_context(|| format!(r#"could not find function "{method}""#))? - .typed::<(), ()>(&store)?; - metadata.call(&mut store)?; - Ok(state.as_ref(&store).msg.clone()) -} - -mod env { - use super::HostState; - use anyhow::{anyhow, Result}; - use wasmer::{Extern, Function, FunctionEnv, FunctionEnvMut, Imports, Memory, Pages, Store}; - use wasmer_types::TrapCode; - - /// Environment for the wasm execution. - pub struct Env<'e> { - pub imports: &'e mut Imports, - pub function_env: &'e FunctionEnv, - pub store: &'e mut Store, - pub memory: Memory, - } - - macro_rules! func { - ($store:tt) => { - func!($store,) - }; - ($store:tt, $($ty:tt),* ) => { - Extern::Function(Function::new_typed( - $store, - move |$(_: $ty),*| { }, - )) - }; - (@result $store:tt, $($ty:tt),* ) => { - Extern::Function(Function::new_typed( - $store, - move |$(_: $ty),*| { 0 }, - )) - }; - } - - impl Env<'_> { - /// Define function in the environment. - pub fn define(&mut self, module: &str, name: &str) -> Result<()> { - if module != "env" { - return Err(anyhow!("module \"{}\" not found", module)); - } - - let memory = self.memory.clone(); - let store = &mut self.store; - - let external = match name { - "memory" => Extern::Memory(memory), - "alloc" => alloc(self.store, self.function_env, memory), - "gr_oom_panic" => gr_oom_panic(store), - "gr_read" => gr_read(store, self.function_env, memory), - "gr_reply" => gr_reply(store, self.function_env, memory), - "gr_panic" => gr_panic(store, self.function_env, memory), - "gr_size" => gr_size(store, self.function_env, memory), - // methods may be used by programs but not required by metadata. - "free" => func!(@result store, i32), - "free_range" => func!(@result store, i32, i32), - "gr_block_height" => func!(store, u32), - "gr_block_timestamp" => func!(store, u32), - "gr_create_program_wgas" => func!(store, i32, i32, u32, i32, u32, u64, u32, i32), - "gr_create_program" => func!(store, i32, i32, u32, i32, u32, u64, i32), - "gr_debug" => func!(store, i32, u32), - "gr_exit" => func!(store, i32), - "gr_gas_available" => func!(store, i32), - "gr_leave" => func!(store), - "gr_message_id" => func!(store, i32), - "gr_system_break" => func!(store, u32), - "gr_program_id" => func!(store, i32), - "gr_random" => func!(store, i32, i32), - "gr_reply_code" => func!(store, i32), - "gr_reply_commit" => func!(store, i32, i32), - "gr_reply_deposit" => func!(store, i32, u64, i32), - "gr_reply_input" => func!(store, u32, u32, i32, i32), - "gr_reply_push" => func!(store, i32, u32, i32), - "gr_reply_push_input" => func!(store, u32, u32, i32), - "gr_reply_push_input_wgas" => func!(store, u32, u32, u64, i32, i32), - "gr_reply_to" => func!(store, i32), - "gr_reply_wgas" => func!(store, i32, u32, u64, i32, i32), - "gr_reservation_reply" => func!(store, i32, i32, u32, i32), - "gr_reservation_send_commit" => func!(store, u32, i32, u32, i32), - "gr_reservation_send" => func!(store, i32, i32, u32, u32, i32), - "gr_reserve_gas" => func!(store, u64, u32, i32), - "gr_send" => func!(store, i32, i32, u32, u32, i32), - "gr_send_commit" => func!(store, u32, i32, u32, i32), - "gr_send_commit_wgas" => func!(store, u32, i32, u64, u32, i32), - "gr_send_init" => func!(store, i32), - "gr_send_input" => func!(store, i32, u32, u32, u32, i32), - "gr_send_input_wgas" => func!(store, i32, u32, u32, u64, u32, i32), - "gr_send_push" => func!(store, u32, i32, u32, i32), - "gr_send_push_input" => func!(store, u32, u32, u32, i32), - "gr_send_wgas" => func!(store, i32, i32, u32, u64, u32, i32), - "gr_signal_code" => func!(store, i32), - "gr_signal_from" => func!(store, i32), - "gr_source" => func!(store, i32), - "gr_system_reserve_gas" => func!(store, u64, i32), - "gr_unreserve_gas" => func!(store, i32, i32), - "gr_value" => func!(store, i32), - "gr_wait" => func!(store, u32), - "gr_wait_for" => func!(store, u32), - "gr_wait_up_to" => func!(store, u32), - "gr_wake" => func!(store, i32, u32, i32), - _ => return Err(anyhow!("export \"{}\" not found in env", name,)), - }; - - self.imports.define(module, name, external); - - Ok(()) - } - } - - fn alloc(store: &mut Store, env: &FunctionEnv, memory: Memory) -> Extern { - Extern::Function(Function::new_typed_with_env( - store, - env, - move |mut env: FunctionEnvMut, pages: u32| { - memory.grow(&mut env, Pages::from(pages)).map_or_else( - |err| { - log::error!("{err:?}"); - u32::MAX as i32 - }, - |pages| pages.bytes().0 as u32 as i32, - ) - }, - )) - } - - fn gr_read(ctx: &mut Store, env: &FunctionEnv, memory: Memory) -> Extern { - Extern::Function(Function::new_typed_with_env( - ctx, - env, - move |mut env: FunctionEnvMut, at: u32, len: i32, buff: i32, err: i32| { - let (data, store) = env.data_and_store_mut(); - let (at, len, buff, err) = (at as _, len as usize, buff as _, err as _); - - let msg = &data.msg; - let payload = if at + len <= msg.len() { - msg[at..(at + len)].to_vec() - } else { - return Err(TrapCode::HeapAccessOutOfBounds); - }; - - let memory = memory.view(&store); - - let len: u32 = memory - .write(buff, &payload) - .map_err(|e| log::error!("{:?}", e)) - .is_err() - .into(); - - memory.write(err, &len.to_le_bytes()).map_err(|e| { - log::error!("{e:?}"); - TrapCode::HeapAccessOutOfBounds - })?; - - Ok(()) - }, - )) - } - - fn gr_reply(ctx: &mut Store, env: &FunctionEnv, memory: Memory) -> Extern { - Extern::Function(Function::new_typed_with_env( - ctx, - env, - move |mut env: FunctionEnvMut, - ptr: u32, - len: i32, - _value: i32, - _err: i32| - -> Result<(), TrapCode> { - let mut result = vec![0; len as usize]; - - memory - .view(&env) - .read(ptr as u64, &mut result) - .map_err(|e| { - log::error!("{:?}", e); - TrapCode::HeapAccessOutOfBounds - })?; - env.data_mut().msg = result; - - Ok(()) - }, - )) - } - - fn gr_size(ctx: &mut Store, env: &FunctionEnv, memory: Memory) -> Extern { - Extern::Function(Function::new_typed_with_env( - ctx, - env, - move |env: FunctionEnvMut, size_ptr: u32| -> Result<(), TrapCode> { - let size = env.data().msg.len() as u32; - - memory - .view(&env) - .write(size_ptr as u64, &size.to_le_bytes()) - .map_err(|e| { - log::error!("{:?}", e); - TrapCode::HeapAccessOutOfBounds - })?; - - Ok(()) - }, - )) - } - - fn gr_panic(ctx: &mut Store, env: &FunctionEnv, memory: Memory) -> Extern { - Extern::Function(Function::new_typed_with_env( - ctx, - env, - move |env: FunctionEnvMut, ptr: u32, len: i32| -> Result<(), TrapCode> { - let mut buff = Vec::with_capacity(len as usize); - memory.view(&env).read(ptr as u64, &mut buff).map_err(|e| { - log::error!("{e:?}"); - TrapCode::HeapAccessOutOfBounds - })?; - - log::error!("Panic: {}", String::from_utf8_lossy(&buff)); - Ok(()) - }, - )) - } - - fn gr_oom_panic(ctx: &mut Store) -> Extern { - Extern::Function(Function::new_typed(ctx, || -> Result<(), TrapCode> { - log::error!("OOM panic occurred"); - Ok(()) - })) - } -} diff --git a/gcli/src/meta/mod.rs b/gcli/src/meta/mod.rs deleted file mode 100644 index a2d69c7845f..00000000000 --- a/gcli/src/meta/mod.rs +++ /dev/null @@ -1,162 +0,0 @@ -// This file is part of Gear. -// -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Program metadata parser -mod executor; -mod registry; -#[cfg(test)] -mod tests; - -use crate::result::{Error, Result}; -use gear_core::code::{Code, CodeAndId, InstrumentedCodeAndId, TryNewCodeConfig}; -use gmeta::{MetadataRepr, MetawasmData, TypesRepr}; -use registry::LocalRegistry as _; -use scale_info::{scale::Decode, PortableRegistry}; -use std::fmt; - -struct Io<'d> { - io: &'d TypesRepr, - registry: &'d PortableRegistry, -} - -impl<'d> Io<'d> { - /// New instance of `Io` with given `io` and `registry`. - pub fn new(io: &'d TypesRepr, registry: &'d PortableRegistry) -> Self { - Self { io, registry } - } -} - -impl<'d> fmt::Debug for Io<'d> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut display = fmt.debug_struct(""); - for (name, ty) in [("input", self.io.input), ("output", self.io.output)] { - if let Some(id) = ty { - display.field(name, &self.registry.derive_id(id).map_err(|_| fmt::Error)?); - } else { - display.field(name, &"()"); - } - } - - display.finish() - } -} - -impl<'d> fmt::Display for Io<'d> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, fmt) - } -} - -/// Program metadata. -/// -/// TODO: refactor this type with decoded registry. -/// doesn't necessary for now since everything in this crate -/// is just for a one-time call from the command line. -pub enum Meta { - Data(MetadataRepr), - Wasm(MetawasmData), -} - -impl Meta { - fn format_metadata(meta: &MetadataRepr, fmt: &mut fmt::Formatter) -> fmt::Result { - let registry = - PortableRegistry::decode(&mut meta.registry.as_ref()).map_err(|_| fmt::Error)?; - let mut display = fmt.debug_struct("Metadata"); - display.field("init", &Io::new(&meta.init, ®istry)); - display.field("handle", &Io::new(&meta.handle, ®istry)); - display.field("others", &Io::new(&meta.others, ®istry)); - display.field("state", &Io::new(&meta.state, ®istry)); - let single_types = [("reply", meta.reply), ("signal", meta.signal)]; - for (name, ty) in single_types { - if let Some(id) = ty { - display.field(name, ®istry.derive_id(id).map_err(|_| fmt::Error)?); - } else { - display.field(name, &"()"); - } - } - - display.finish() - } - - fn format_metawasm(meta: &MetawasmData, fmt: &mut fmt::Formatter) -> fmt::Result { - let registry = - PortableRegistry::decode(&mut meta.registry.as_ref()).map_err(|_| fmt::Error)?; - - let mut display = fmt.debug_struct("Exports"); - for (name, io) in meta.funcs.iter() { - display.field(name, &Io::new(io, ®istry)); - } - - display.finish() - } - - /// Decode metawasm from wasm binary. - pub fn decode_wasm(wasm: &[u8]) -> Result { - let code = Code::try_new_mock_const_or_no_rules( - wasm.to_vec(), - true, - TryNewCodeConfig::new_no_exports_check(), - )?; - let (code, _) = InstrumentedCodeAndId::from(CodeAndId::new(code)).into_parts(); - let result = executor::call_metadata(code.code())?; - - Ok(Self::Wasm(MetawasmData::decode(&mut result.as_ref())?)) - } - - /// Decode metadata from hex bytes. - pub fn decode_hex(hex: &[u8]) -> Result { - let meta = MetadataRepr::from_hex(hex).map_err(Error::MetaParseError)?; - Ok(Self::Data(meta)) - } - - /// Decode program meta. - /// - /// Either program metadata or state reading functions. - pub fn decode(encoded: &[u8]) -> Result { - MetadataRepr::from_bytes(encoded) - .map(Meta::Data) - .or_else(|_| -> Result { Self::decode_wasm(encoded) }) - .map_err(Into::into) - } - - /// Derive type by name. - pub fn derive(&self, name: &str) -> Result { - let mut encoded_registry = match self { - Meta::Data(meta) => meta.registry.as_ref(), - Meta::Wasm(meta) => meta.registry.as_ref(), - }; - let registry = PortableRegistry::decode(&mut encoded_registry)?; - - Ok(format!("{}", registry.derive_name(name)?)) - } -} - -impl fmt::Debug for Meta { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match self { - Meta::Data(meta) => Self::format_metadata(meta, fmt), - Meta::Wasm(meta) => Self::format_metawasm(meta, fmt), - } - } -} - -impl fmt::Display for Meta { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, fmt) - } -} diff --git a/gcli/src/meta/registry.rs b/gcli/src/meta/registry.rs deleted file mode 100644 index f0b97379d57..00000000000 --- a/gcli/src/meta/registry.rs +++ /dev/null @@ -1,173 +0,0 @@ -// This file is part of Gear. -// -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Local type registry. -use crate::result::{Error, Result}; -use scale_info::{ - form::{Form, PortableForm}, - interner::UntrackedSymbol, - scale::Decode, - PortableRegistry, Type, TypeDef, -}; -use std::{any::TypeId, fmt}; - -/// Wrapper of `scale_info::Type` for rust formatting -pub struct LocalType<'t, T: Form> { - pub ty: &'t Type, - pub registry: &'t PortableRegistry, -} - -impl<'t, T: Form>> fmt::Debug for LocalType<'t, T> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match &self.ty.type_def { - TypeDef::Array(array) => fmt.write_str(&format!( - "[{}; {}]", - self.registry - .derive_id(array.type_param.id) - .map_err(|_| fmt::Error)?, - array.len - )), - TypeDef::BitSequence(bit_sequence) => { - write!( - fmt, - "BitVec<{}, {}>", - self.registry - .derive_id(bit_sequence.bit_store_type.id) - .map_err(|_| fmt::Error)?, - self.registry - .derive_id(bit_sequence.bit_order_type.id) - .map_err(|_| fmt::Error)?, - ) - } - TypeDef::Compact(compact) => { - write!( - fmt, - "{}", - self.registry - .derive_id(compact.type_param.id) - .map_err(|_| fmt::Error)? - ) - } - TypeDef::Composite(composite) => { - let mut debug = fmt.debug_struct(self.ty.path.ident().ok_or(fmt::Error)?.as_ref()); - for field in &composite.fields { - debug.field( - field.name.as_ref().ok_or(fmt::Error)?.as_ref(), - &field.type_name.as_ref().ok_or(fmt::Error)?.as_ref(), - ); - } - - debug.finish() - } - TypeDef::Primitive(primitive) => { - write!(fmt, "{}", format!("{primitive:?}").to_lowercase()) - } - TypeDef::Sequence(sequence) => { - write!( - fmt, - "[{}]", - self.registry - .derive_id(sequence.type_param.id) - .map_err(|_| fmt::Error)?, - ) - } - TypeDef::Tuple(tuple) => { - let mut debug = fmt.debug_tuple(""); - for field in &tuple.fields { - debug.field(&format!( - "{}", - self.registry.derive_id(field.id).map_err(|_| fmt::Error)? - )); - } - - debug.finish() - } - TypeDef::Variant(var) => { - let ident = self.ty.path.ident().ok_or(fmt::Error)?; - if ident.as_ref() == "Option" { - // parsing `Option`. - let ty = self - .registry - .derive_id(var.variants[1].fields[0].ty.id) - .map_err(|_| fmt::Error)? - .ty; - - if let TypeDef::Primitive(primitive) = &ty.type_def { - write!(fmt, "Option<{}>", format!("{primitive:?}").to_lowercase()) - } else { - write!(fmt, "Option<{}>", ty.path.ident().ok_or(fmt::Error)?) - } - } else { - // Parsing `enum`. - write!(fmt, "{} ", self.ty.path.ident().ok_or(fmt::Error)?.as_ref()) - } - } - } - } -} - -impl<'t, T: Form>> fmt::Display for LocalType<'t, T> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, fmt) - } -} - -/// Local type registry -pub trait LocalRegistry: Sized + Clone { - #[allow(dead_code)] - fn from_hex(hex: &str) -> Result; - - /// Get type from identity - fn derive_id(&self, id: u32) -> Result>; - - /// Get type from identity name - /// - /// # TODO - /// - /// Adding a indexer to register types for re-using, - /// currently we don't have this requirement - fn derive_name(&self, ident: &str) -> Result>; -} - -impl LocalRegistry for PortableRegistry { - fn from_hex(encoded: &str) -> Result { - Ok(PortableRegistry::decode( - &mut hex::decode(encoded)?.as_ref(), - )?) - } - - fn derive_id(&self, id: u32) -> Result> { - Ok(LocalType { - ty: self - .resolve(id) - .ok_or_else(|| Error::TypeNotFound(format!("{id:?}")))?, - registry: self, - }) - } - - fn derive_name(&self, ident: &str) -> Result> { - for ty in &self.types { - let ty = &ty.ty; - if ty.path.ident() == Some(ident.into()) { - return Ok(LocalType { ty, registry: self }); - } - } - - Err(Error::TypeNotFound(ident.into())) - } -} diff --git a/gcli/src/meta/tests.rs b/gcli/src/meta/tests.rs deleted file mode 100644 index 1e21afdc67e..00000000000 --- a/gcli/src/meta/tests.rs +++ /dev/null @@ -1,142 +0,0 @@ -// This file is part of Gear. -// -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Tests for metadata -use crate::meta::Meta; - -const WASM_METADATA_OUTPUT: &str = r#" -Metadata { - init: { - input: MessageInitIn { - amount: "u8", - currency: "String", - }, - output: MessageInitOut { - exchange_rate: "Result", - sum: "u8", - }, - }, - handle: { - input: MessageIn { - id: "Id", - }, - output: MessageOut { - res: "Option", - }, - }, - others: { - input: MessageAsyncIn { - empty: "()", - }, - output: Option, - }, - state: { - input: "()", - output: [Wallet { id: "Id", person: "Person" }], - }, - reply: str, - signal: "()", -} -"#; - -const META_WASM_V1_OUTPUT: &str = r#" -Exports { - first_and_last_wallets: { - input: "()", - output: ( - "Option", - "Option", - ), - }, - first_wallet: { - input: "()", - output: Option, - }, - last_wallet: { - input: "()", - output: Option, - }, -} -"#; - -const META_WASM_V2_OUTPUT: &str = r#" -Exports { - wallet_by_id: { - input: Id { - decimal: "u64", - hex: "Vec", - }, - output: Option, - }, - wallet_by_name_and_surname: { - input: ( - "str", - "str", - ), - output: Option, - }, - wallet_by_person: { - input: Person { - surname: "String", - name: "String", - }, - output: Option, - }, -} -"#; - -const META_WASM_V3_OUTPUT: &str = r#" -Exports { - block_number: { - input: "()", - output: u32, - }, - block_timestamp: { - input: "()", - output: u64, - }, -} -"#; - -#[test] -fn test_parse_metadata_works() { - use demo_new_meta::WASM_METADATA; - let meta = Meta::decode(WASM_METADATA).expect("Failed to decode wasm metadata"); - assert_eq!(format!("{:#}", meta), WASM_METADATA_OUTPUT.trim()); -} - -#[test] -fn test_parse_metawasm_data_1_works() { - use demo_new_meta::META_WASM_V1; - let meta = Meta::decode_wasm(META_WASM_V1).unwrap(); - assert_eq!(format!("{:#}", meta), META_WASM_V1_OUTPUT.trim()); -} - -#[test] -fn test_parse_metawasm_data_2_works() { - use demo_new_meta::META_WASM_V2; - let meta = Meta::decode_wasm(META_WASM_V2).unwrap(); - assert_eq!(format!("{:#}", meta), META_WASM_V2_OUTPUT.trim()); -} - -#[test] -fn test_parse_metawasm_data_3_works() { - use demo_new_meta::META_WASM_V3; - let meta = Meta::decode_wasm(META_WASM_V3).unwrap(); - assert_eq!(format!("{:#}", meta), META_WASM_V3_OUTPUT.trim()); -} diff --git a/gcli/src/result.rs b/gcli/src/result.rs index ef4dd244fb5..1e2d0e4a1d7 100644 --- a/gcli/src/result.rs +++ b/gcli/src/result.rs @@ -51,8 +51,6 @@ pub enum Error { Wasmer(wasmer::RuntimeError), #[error(transparent)] Etc(#[from] etc::Error), - #[error("Metadata parsing error {0:?}")] - MetaParseError(gmeta::MetadataParseError), } impl From for Error { diff --git a/gcli/tests/cmd/mod.rs b/gcli/tests/cmd/mod.rs index 9d56db4cd8a..77b2fad8d02 100644 --- a/gcli/tests/cmd/mod.rs +++ b/gcli/tests/cmd/mod.rs @@ -18,7 +18,6 @@ mod claim; mod info; -mod program; mod reply; mod send; mod transfer; diff --git a/gcli/tests/cmd/program.rs b/gcli/tests/cmd/program.rs deleted file mode 100644 index 114931e67dc..00000000000 --- a/gcli/tests/cmd/program.rs +++ /dev/null @@ -1,183 +0,0 @@ -// This file is part of Gear. -// -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Integration tests for command `program` -use crate::common::{ - self, env, - node::{Convert, NodeExec}, - Args, Result, -}; -use demo_new_meta::{MessageInitIn, Wallet}; -use scale_info::scale::Encode; - -#[tokio::test] -async fn test_command_program_state_works() -> Result<()> { - let node = common::dev()?; - - // Deploy demo_new_meta. - let opt = env::wasm_bin("demo_new_meta.opt.wasm"); - let _ = node.run( - Args::new("upload").program(opt).payload(hex::encode( - MessageInitIn { - amount: 42, - currency: "GEAR".into(), - } - .encode(), - )), - )?; - - // Query state of demo_new_meta - let pid = common::program_id(demo_new_meta::WASM_BINARY, &[]); - let state = node.run(Args::new("program").action("state").program(pid))?; - - // Verify result - let expected = hex::encode(Wallet::test_sequence().encode()); - let got = state.stdout.convert(); - assert_eq!( - got.trim_start_matches("0x").trim(), - expected, - "state should be equal to Wallet::test_sequence(). Expected state: {expected}, got: {got}" - ); - Ok(()) -} - -const DEMO_NEW_META_METADATA: &str = r#" -Metadata { - init: { - input: MessageInitIn { - amount: u8, - currency: String, - }, - output: MessageInitOut { - exchange_rate: Result, - sum: u8, - }, - }, - handle: { - input: MessageIn { - id: Id, - }, - output: MessageOut { - res: Option, - }, - }, - others: { - input: MessageAsyncIn { - empty: (), - }, - output: Option, - }, - state: { - input: (), - output: [Wallet { id: Id, person: Person }], - }, - reply: str, - signal: (), -} -"#; - -#[test] -fn test_command_program_metadata_works() -> Result<()> { - let node = common::dev()?; - let meta = env::wasm_bin("demo_new_meta.meta.txt"); - let args = Args::new("program").action("meta").meta(meta); - let stdout = node.stdout(args)?; - - assert_eq!( - stdout.trim(), - DEMO_NEW_META_METADATA.trim(), - "metadata should be equal to DEMO_NEW_META_METADATA. Expected metadata: {DEMO_NEW_META_METADATA}, got: {stdout:?}" - ); - Ok(()) -} - -#[test] -fn test_command_program_metadata_derive_works() -> Result<()> { - let meta = env::wasm_bin("demo_new_meta.meta.txt"); - let node = common::dev()?; - let args = Args::new("program") - .action("meta") - .meta(meta) - .flag("--derive") - .derive("Person"); - - let stdout = node.stdout(args)?; - let expected = "Person { surname: String, name: String }"; - assert_eq!( - stdout.trim(), - expected, - "metadata should be equal to {expected}, but got: {stdout:?}", - ); - Ok(()) -} - -const META_WASM_V1_OUTPUT: &str = r#" -Exports { - first_and_last_wallets: { - input: (), - output: ( - Option, - Option, - ), - }, - first_wallet: { - input: (), - output: Option, - }, - last_wallet: { - input: (), - output: Option, - }, -} -"#; - -#[test] -fn test_command_program_metawasm_works() -> Result<()> { - let node = common::dev()?; - let meta = env::wasm_bin("demo_meta_state_v1.meta.wasm"); - let args = Args::new("program").action("meta").meta(meta); - let stdout = node.stdout(args)?; - - assert_eq!( - stdout.trim(), - META_WASM_V1_OUTPUT.trim(), - "metadata should be equal to META_WASM_V1_OUTPUT. Expected metadata: {META_WASM_V1_OUTPUT}, got: {stdout:?}", - ); - Ok(()) -} - -#[test] -fn test_command_program_metawasm_derive_works() -> Result<()> { - let node = common::dev()?; - let meta = env::wasm_bin("demo_meta_state_v1.meta.wasm"); - let args = Args::new("program") - .action("meta") - .meta(meta) - .flag("--derive") - .derive("Person"); - - let stdout = node.stdout(args)?; - - let expected = "Person { surname: String, name: String }"; - assert_eq!( - stdout.trim(), - expected, - "metadata should be equal to {expected}, but got: {stdout:?}", - ); - Ok(()) -} diff --git a/gcli/tests/cmd/upload.rs b/gcli/tests/cmd/upload.rs index 611c04959cb..b8235a7c3f1 100644 --- a/gcli/tests/cmd/upload.rs +++ b/gcli/tests/cmd/upload.rs @@ -31,13 +31,13 @@ async fn test_command_upload_works() -> Result<()> { let signer = Api::new(node.ws().as_str()) .await? .signer("//Alice", None)?; - let code_id = CodeId::generate(demo_new_meta::WASM_BINARY); + let code_id = CodeId::generate(demo_wallets::WASM_BINARY); assert!( signer.api().code_storage(code_id).await.is_err(), "code should not exist" ); - let output = node.run(Args::new("upload").program(env::wasm_bin("demo_new_meta.opt.wasm")))?; + let output = node.run(Args::new("upload").program(env::wasm_bin("demo_wallets.opt.wasm")))?; assert!( output .stderr @@ -60,7 +60,7 @@ async fn test_command_upload_code_works() -> Result<()> { let output = node.run( Args::new("upload") .flag("--code-only") - .program(env::wasm_bin("demo_new_meta.opt.wasm")), + .program(env::wasm_bin("demo_wallets.opt.wasm")), )?; let stderr = output.stderr.convert(); diff --git a/gcli/tests/common/mod.rs b/gcli/tests/common/mod.rs index 7ed73152238..14698d1a331 100644 --- a/gcli/tests/common/mod.rs +++ b/gcli/tests/common/mod.rs @@ -18,7 +18,6 @@ //! Common utils for integration tests pub use self::{args::Args, node::NodeExec, result::Result}; -use gear_core::ids::{prelude::*, CodeId, ProgramId}; use gear_node_wrapper::{Node, NodeInstance}; use gsdk::ext::{sp_core::crypto::Ss58Codec, sp_runtime::AccountId32}; use std::{ @@ -75,11 +74,6 @@ pub fn login_as_alice() -> Result<()> { Ok(()) } -/// Generate program id from code id and salt -pub fn program_id(bin: &[u8], salt: &[u8]) -> ProgramId { - ProgramId::generate_from_user(CodeId::generate(bin), salt) -} - /// AccountId32 of `addr` pub fn alice_account_id() -> AccountId32 { AccountId32::from_ss58check(ALICE_SS58_ADDRESS).expect("Invalid address") diff --git a/gcli/tests/common/node.rs b/gcli/tests/common/node.rs index 2935681a830..daedd307f70 100644 --- a/gcli/tests/common/node.rs +++ b/gcli/tests/common/node.rs @@ -19,7 +19,6 @@ //! Shared node. use crate::common::{Args, Output, Result}; -use anyhow::anyhow; /// Convert self into `String`. pub trait Convert { @@ -42,22 +41,10 @@ pub trait NodeExec { /// let node = Node::new(); /// let args = Args::new("upload") /// .flag("--code-only") - /// .program(env::wasm_bin("demo_new_meta.opt.wasm")); + /// .program(env::wasm_bin("demo_wallets.opt.wasm")); /// let output = node.run(args) /// /// // ... /// ``` fn run(&self, args: Args) -> Result; - - /// Execute command gcli with Node instance - /// and return stdout. - fn stdout(&self, args: Args) -> Result { - let output = self.run(args)?; - - if output.stdout.is_empty() { - return Err(anyhow!("stdout is empty, stderr: {}", output.stderr.convert()).into()); - } - - Ok(output.stdout.convert()) - } } diff --git a/gcli/tests/gear.rs b/gcli/tests/gear.rs index 6996157c525..aa54b2917fe 100644 --- a/gcli/tests/gear.rs +++ b/gcli/tests/gear.rs @@ -27,8 +27,7 @@ fn paths() { [ env::node_bin(), env::bin("gcli"), - env::wasm_bin("demo_new_meta.opt.wasm"), - env::wasm_bin("demo_new_meta.meta.txt"), + env::wasm_bin("demo_wallets.opt.wasm"), ] .into_iter() .for_each(|path| { diff --git a/gclient/Cargo.toml b/gclient/Cargo.toml index b0ae57fa282..371ae2205b8 100644 --- a/gclient/Cargo.toml +++ b/gclient/Cargo.toml @@ -39,15 +39,14 @@ demo-calc-hash-in-one-block.workspace = true demo-custom.workspace = true demo-constructor = { workspace = true, features = ["std"] } demo-distributor.workspace = true -demo-meta-io.workspace = true -demo-new-meta.workspace = true +demo-wallets.workspace = true +demo-wallets-io.workspace = true demo-mul-by-const.workspace = true demo-node.workspace = true demo-program-factory.workspace = true demo-proxy = { workspace = true, features = ["std"] } demo-proxy-relay.workspace = true demo-reserve-gas = { workspace = true, features = ["std"] } -gmeta = { workspace = true } gstd = { workspace = true, features = ["debug"] } demo-wat.workspace = true demo-bls381 = { workspace = true, features = ["std"] } diff --git a/gmeta/Cargo.toml b/gmeta/Cargo.toml deleted file mode 100644 index 772c3534879..00000000000 --- a/gmeta/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "gmeta" -description = "Metadata library for Gear programs" -documentation = "https://docs.rs/gmeta" -keywords = ["gear", "wasm"] -categories = ["wasm"] -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -rust-version.workspace = true - -[dependencies] -scale-info.workspace = true -blake2.workspace = true -hex = { workspace = true, features = ["alloc"] } -gmeta-codegen = { workspace = true, optional = true } -derive_more.workspace = true - -[dev-dependencies] -gear-wasm-builder.workspace = true -gstd.workspace = true -parity-scale-codec.workspace = true - -[features] -codegen = ["gmeta-codegen"] diff --git a/gmeta/codegen/Cargo.toml b/gmeta/codegen/Cargo.toml deleted file mode 100644 index 44e23058e69..00000000000 --- a/gmeta/codegen/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "gmeta-codegen" -description = "Code generation library for the metadata of Gear program" -documentation = "https://docs.rs/gmeta-codegen" -keywords = ["gear", "wasm", "codegen"] -categories = ["wasm"] -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -rust-version.workspace = true - -[lib] -proc-macro = true - -[dependencies] -syn = { workspace = true, features = ["full", "printing", "parsing", "proc-macro", "extra-traits"] } -quote.workspace = true -proc-macro2.workspace = true - -[dev-dependencies] -gmeta = { workspace = true, features = ["codegen"] } -gstd.workspace = true -parity-scale-codec.workspace = true -scale-info.workspace = true diff --git a/gmeta/codegen/src/lib.rs b/gmeta/codegen/src/lib.rs deleted file mode 100644 index 43df596133e..00000000000 --- a/gmeta/codegen/src/lib.rs +++ /dev/null @@ -1,523 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2022-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use proc_macro::TokenStream; -use quote::{quote, ToTokens}; -use std::{borrow::Borrow, fmt::Display, iter}; -use syn::{ - parse_macro_input, spanned::Spanned, Attribute, Error, FnArg, Item, ItemMod, Pat, ReturnType, - Type, TypePath, Visibility, -}; - -static MODULE_NAME: &str = "metafns"; - -fn error(spanned: impl Spanned, message: impl Display) -> Result { - Err(Error::new(spanned.span(), message)) -} - -macro_rules! return_error_if_some { - ($option:expr, $message:expr) => { - if let Some(spanned) = $option { - return error(spanned, $message); - } - }; -} - -fn validate_if_private(spanned: impl Spanned, visibility: &Visibility) -> Result<(), Error> { - match visibility { - Visibility::Public(_) => Ok(()), - other => match other { - Visibility::Inherited => { - error(spanned, "visibility must be public, add the `pub` keyword") - } - _ => error( - other, - "visibility mustn't be restricted, use the `pub` keyword alone", - ), - }, - } -} - -fn validate_if_has_no_attributes( - attributes: impl IntoIterator>, - message: impl Display, -) -> Result<(), Error> { - let mut attributes = attributes.into_iter(); - - if let Some(attribute) = attributes.next() { - let span = attributes.fold(attribute.borrow().span(), |span, attribute| { - span.join(attribute.borrow().span()).unwrap_or(span) - }); - - error(span, message) - } else { - Ok(()) - } -} - -/// Generates metawasm functions. -/// -/// An example of the expected structure: -/// -/// ``` -/// use gstd::prelude::*; -/// -/// #[derive(Decode, Encode, TypeInfo)] -/// pub struct StateType; -/// -/// #[derive(Encode, TypeInfo)] -/// pub struct SomeReturnType; -/// -/// #[derive(Decode, TypeInfo)] -/// pub struct SomeArg; -/// -/// #[gmeta::metawasm] -/// pub mod metafns { -/// pub type State = StateType; -/// -/// /// Documentation... -/// pub fn some_function(_: State) -> SomeReturnType { -/// unimplemented!() -/// } -/// -/// pub fn another_function_but_with_arg(mut _state: State, _arg: SomeArg) -> State { -/// unimplemented!() -/// } -/// -/// /// Another doc... -/// pub fn function_with_multiple_args( -/// _state: State, -/// mut _arg1: SomeArg, -/// _arg2: u16, -/// mut _arg3: u32, -/// ) -> SomeReturnType { -/// unimplemented!() -/// } -/// } -/// # fn main() {} -/// ``` -/// -/// # Syntax -/// -/// - This attribute **must** be used on the `pub`lic `mod` container with the -/// `metafns` identifier. -/// - The first item in the module **must** be a `pub`lic `type` alias with the -/// `State` identifier. The type for which `State` will be an alias **must** -/// implement [`Decode`] trait. -/// -/// Usually the state type should be imported from the implemented associated -/// [`Metadata::State`](../gmeta/trait.Metadata.html#associatedtype.State) type -/// from the program's `io` crate. -/// -/// - The rest of items **must** be `pub`lic functions. -/// - The first argument's type of metafunctions **must** be `State`. -/// - If the first argument uses -/// [the identifier pattern](https://doc.rust-lang.org/stable/reference/patterns.html#identifier-patterns), -/// the identifier **must** be `state` or `_state`. -/// -/// In addition to the mandatory first argument, functions can have additional -/// ones. -/// -/// - The maximum amount of additional arguments is 18 due restrictions of the -/// SCALE codec. -/// - All additional arguments **must** implement the [`Decode`] & -/// [`TypeInfo`] traits. -/// - A function **mustn't** return `()` or nothing. -/// - A returned type **must** implement the -/// [`Encode`](../gmeta/trait.Encode.html) & [`TypeInfo`] traits. -/// -/// [`Decode`]: ../gmeta/trait.Decode.html -/// [`TypeInfo`]: ../gmeta/trait.TypeInfo.html -/// -/// # Expansion result -/// -/// This attribute doesn't change the `metafns` module and items inside, but -/// adds `use super::*;` inside the module because, in most cases, it'll be -/// useful for importing items from an upper namespace. So every item in the -/// same namespace where the module is located is accessible inside it. -/// -/// The rest of the magic happens in the another generated private `extern` -/// module. It registers all metawasm functions, their arguments & return types, -/// and generates extern functions with the same names. Later, they can be -/// called from a metaWASM binary inside a blockchain. -/// -/// **Important note**: although metafunctions can take more than 1 additional -/// arguments, on the metaWASM binary level, they must be passed as one. So if -/// the amount of additional arguments is 0 or 1, nothing needs to be changed, -/// but if more - they all must be placed inside a tuple in the same order as in -/// their function's signature. -/// -/// E.g., argument definitions for the above example: -/// - For `some_function` an argument must be [`None`]. -/// - For `another_function_but_with_arg` an argument must be `Some(SomeArg)`. -/// - For `function_with_multiple_args` an argument must be -/// `Some((SomeArg, u16, u32))`. -#[proc_macro_attribute] -pub fn metawasm(_: TokenStream, item: TokenStream) -> TokenStream { - process(parse_macro_input!(item)).unwrap_or_else(|error| error.into_compile_error().into()) -} - -fn process(module: ItemMod) -> Result { - let module_span = module.span(); - - validate_if_has_no_attributes( - module.attrs, - "module with #[metawasm] mustn't have attributes", - )?; - validate_if_private(module_span, &module.vis)?; - - if module.ident != MODULE_NAME { - return error( - module.ident, - format_args!("name of a module with #[metawasm] must be `{MODULE_NAME}`"), - ); - } - - let Some((_, items)) = module.content else { - return error( - module_span, - "`#[metawasm]` doesn't work with modules without a body", - ); - }; - - if items.is_empty() { - return Ok(Default::default()); - } - - let mut items = items.into_iter(); - let two_first_items = (items.next(), items.next()); - - let (potential_type_item, potential_functions) = - if let (Some(first), Some(second)) = two_first_items { - (first, iter::once(second).chain(items)) - } else { - return error( - module_span, - "module with #[metawasm] must contain the `State` type alias & at least 1 function", - ); - }; - - // Checking the `State` type - - let Item::Type(type_item) = potential_type_item else { - return error( - potential_type_item, - "first item of a module with `#[metawasm]` must be a type alias to a state type (e.g. `type State = StateType;`)" - ); - }; - let type_item_attributes = &type_item.attrs; - - let (state_type, state_type_inner) = if type_item.ident == "State" { - validate_if_private(&type_item, &type_item.vis)?; - - if type_item.generics.params.is_empty() { - ( - TypePath { - qself: None, - path: type_item.ident.into(), - } - .into(), - *type_item.ty, - ) - } else { - return error(type_item.generics, "must be without generics"); - } - } else { - return error( - type_item.ident, - "identifier of the state type must be `State`", - ); - }; - - // Checking functions - - let mut functions = vec![]; - - for potential_function in potential_functions { - let Item::Fn(function) = potential_function else { - return error( - potential_function, - "rest of items in a module with `#[metawasm]` must be functions", - ); - }; - - validate_if_private(&function, &function.vis)?; - - let signature = function.sig; - - return_error_if_some!(signature.constness, "mustn't be constant"); - return_error_if_some!(signature.asyncness, "mustn't be asynchronous"); - return_error_if_some!(signature.unsafety, "mustn't be unsafe"); - return_error_if_some!(signature.abi, "mustn't have a binary interface"); - return_error_if_some!(signature.variadic, "mustn't have the variadic argument"); - - if !signature.generics.params.is_empty() { - return error(signature.generics, "mustn't have generics"); - } - - if signature.inputs.len() > 19 { - return error(signature.inputs, "too many arguments, no more 19 arguments must be here due restrictions of the SCALE codec"); - } - - let signature_span = signature.span(); - let mut inputs = signature.inputs.into_iter(); - - // Retrieving the first argument - - let first = if let Some(first) = inputs.next() { - if let FnArg::Typed(first) = first { - validate_if_has_no_attributes(&first.attrs, "mustn't have attributes")?; - - first - } else { - return error(first, "mustn't be `self`"); - } - } else { - return error( - signature.paren_token.span, - "mustn't be empty, add `state: State` or `_: State`", - ); - }; - - // Checking the first argument's name - - if let Pat::Ident(ref pat_ident) = *first.pat { - if pat_ident.ident != "state" && pat_ident.ident != "_state" { - return error(&pat_ident.ident, "must be `state` or `_state`"); - } - } - - // Checking the first argument's type - - match *first.ty { - Type::Reference(reference) if *reference.elem == state_type => { - let lifetime_span = reference.lifetime.map(|lifetime| lifetime.span()); - let mutability_span = reference.mutability.map(|mutability| mutability.span()); - - let lifetime_mutability = lifetime_span.map_or(mutability_span, |lifetime_span| { - Some( - mutability_span - .and_then(|mutability_span| mutability_span.join(lifetime_span)) - .unwrap_or(lifetime_span), - ) - }); - - let span = lifetime_mutability - .and_then(|lifetime_mutability| { - lifetime_mutability.join(reference.and_token.span) - }) - .unwrap_or(reference.and_token.span); - - return error(span, "mustn't take a reference"); - } - first_type => { - if first_type != state_type { - return error(first_type, "first argument's type must be `State`"); - } - } - } - - // Checking the rest of arguments - - let mut arguments = vec![]; - - for argument in inputs { - if let FnArg::Typed(argument) = argument { - validate_if_has_no_attributes(&argument.attrs, "mustn't have attributes")?; - - arguments.push((argument.pat, argument.ty)); - } else { - // The rest of arguments can't be the `self` argument because - // the compiler won't allow this. - unreachable!("unexpected `self` argument"); - } - } - - // Checking an output - - let return_type = match signature.output { - ReturnType::Default => { - return error(signature_span, "return type must be specified"); - } - ReturnType::Type(_, return_type) => { - if let Type::Tuple(ref tuple) = *return_type { - if tuple.elems.is_empty() { - return error(tuple, "return type mustn't be `()`"); - } - } - - return_type - } - }; - - functions.push(( - function.attrs, - signature.ident, - first.pat, - arguments, - return_type, - function.block, - )); - } - - // Code generating - - let mut type_registrations = Vec::with_capacity(functions.len()); - let (mut extern_functions, mut public_functions) = - (type_registrations.clone(), type_registrations.clone()); - - for (attributes, function_identifier, state_pattern, arguments, return_type, block) in functions - { - let CodeGenItems { - input_type, - variables, - variables_types, - variables_wo_parentheses, - arguments, - } = process_arguments(arguments, state_pattern); - - let stringed_fn_ident = function_identifier.to_string(); - let output = register_type(&return_type); - - type_registrations.push(quote! { - funcs.insert(#stringed_fn_ident.into(), ::gmeta::TypesRepr { input: #input_type, output: #output }); - }); - - extern_functions.push(quote! { - #[no_mangle] - extern "C" fn #function_identifier() { - let #variables: #variables_types = ::gstd::msg::load() - .expect("Failed to load or decode a payload"); - - ::gstd::msg::reply(super::#function_identifier(#variables_wo_parentheses), 0) - .expect("Failed to encode or reply with a result from a metawasm function"); - } - }); - - public_functions.push(quote! { - #(#attributes)* - pub fn #function_identifier(#arguments) -> #return_type #block - }); - } - - let module_ident = quote::format_ident!("{MODULE_NAME}"); - - Ok(quote! { - pub mod #module_ident { - use super::*; - - mod r#extern { - use super::*; - - #[no_mangle] - extern "C" fn metadata() { - let mut funcs = ::gstd::collections::BTreeMap::new(); - let mut registry = ::gmeta::Registry::new(); - - #(#type_registrations)* - - let metawasm_data = ::gmeta::MetawasmData { - funcs, - registry: ::gstd::Encode::encode(&::gmeta::PortableRegistry::from(registry)), - }; - - ::gstd::msg::reply(metawasm_data, 0).expect("Failed to encode or reply with metawasm data"); - } - - #(#extern_functions)* - } - - #(#type_item_attributes)* - pub type #state_type = #state_type_inner; - - #(#public_functions)* - } - }.into()) -} - -struct CodeGenItems { - input_type: proc_macro2::TokenStream, - variables: proc_macro2::TokenStream, - variables_types: proc_macro2::TokenStream, - variables_wo_parentheses: proc_macro2::TokenStream, - arguments: proc_macro2::TokenStream, -} - -fn process_arguments( - arguments: Vec<(Box, Box)>, - state_pattern: Box, -) -> CodeGenItems { - if arguments.is_empty() { - let variables = quote!(state); - - CodeGenItems { - input_type: quote!(None), - variables: variables.clone(), - variables_types: quote!(State), - variables_wo_parentheses: variables, - arguments: quote!(#state_pattern: State), - } - } else { - let arguments_types = arguments.iter().map(|argument| &argument.1); - let variables_types_wo_parentheses = quote!(#(#arguments_types),*); - - let (variables_wo_parentheses, variables, variables_types) = if arguments.len() > 1 { - let variables_wo_parentheses = - (0..arguments.len()).map(|index| quote::format_ident!("arg{}", index)); - let variables_wo_parentheses = quote!(#(#variables_wo_parentheses),*); - - let variables_with_parentheses = quote!((#variables_wo_parentheses)); - - ( - variables_wo_parentheses, - variables_with_parentheses, - quote!((#variables_types_wo_parentheses)), - ) - } else { - let variables_wo_parentheses = quote!(arg); - - ( - variables_wo_parentheses.clone(), - variables_wo_parentheses, - variables_types_wo_parentheses, - ) - }; - - let input_type = register_type(variables_types.clone()); - - let arguments = arguments - .into_iter() - .map(|(pattern, ty)| quote!(#pattern: #ty)); - - CodeGenItems { - input_type, - variables: quote!((#variables, state)), - variables_types: quote!((#variables_types, State)), - variables_wo_parentheses: quote!(state, #variables_wo_parentheses), - arguments: quote!(#state_pattern: State, #(#arguments),*), - } - } -} - -fn register_type(ty: impl ToTokens) -> proc_macro2::TokenStream { - let ty = ty.to_token_stream(); - - quote! { - Some(registry.register_type(&::gmeta::MetaType::new::<#ty>()).id) - } -} diff --git a/gmeta/src/lib.rs b/gmeta/src/lib.rs deleted file mode 100644 index 704c427aeb0..00000000000 --- a/gmeta/src/lib.rs +++ /dev/null @@ -1,488 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2022-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Crate for providing metadata for Gear programs. -//! -//! Metadata is used to describe the interface of a Gear program. For example, -//! it can be used when uploading a program using . -//! The metadata informs the user about the program's interface and allows them -//! to interact with it using custom types on web applications UI. -//! -//! Another use case is to parse metadata in JavaScript using the `gear-js` -//! library and get the metadata details for some custom UI. -//! -//! Note that metadata is not required for a Gear program to work. It is only -//! used to provide additional information about the program. Also, metadata -//! can be used for various purposes but we will focus on the use cases related -//! to the . -//! -//! To generate a metadata output file for a program, you need: -//! -//! - Add `gmeta` crate to your `Cargo.toml` file. -//! - Define an empty struct that will identify the program metadata. -//! - Implement the [`Metadata`] trait for this struct by defining the -//! associated types of the trait. -//! - **Option 1**: Call [`gear_wasm_builder::build_with_metadata`](https://docs.gear.rs/gear_wasm_builder/fn.build_with_metadata.html) -//! function in `build.rs` file. -//! - **Option 2**: Convert metadata to hex string using [`MetadataRepr::hex`] -//! function and write it to the text file. -//! -//! # Examples -//! -//! In this example we will create a simple ping-pong program. Let's define -//! message types and metadata in a separate `ping-io` crate to be able to use -//! it in both program and `build.rs` files. -//! -//! We will define message types for `handle()` and `state()` functions. -//! -//! - `ping-io` crate: -//! -//! ``` -//! #[no_std] -//! use gmeta::{InOut, Metadata, Out}; -//! use gstd::prelude::*; -//! -//! // Message type for `handle()` function. -//! #[derive(Encode, Decode, TypeInfo)] -//! pub enum PingPong { -//! Ping, -//! Pong, -//! } -//! -//! // Metadata struct. -//! pub struct ProgramMetadata; -//! -//! impl Metadata for ProgramMetadata { -//! // The unit tuple is used as neither incoming nor outgoing messages are -//! // expected in the `init()` function. -//! type Init = (); -//! // We use the same `PingPong` type for both incoming and outgoing -//! // messages. -//! type Handle = InOut; -//! // The unit tuple is used as we don't use asynchronous interaction in this -//! // program. -//! type Others = (); -//! // The unit tuple is used as we don't process any replies in this program. -//! type Reply = (); -//! // The unit tuple is used as we don't process any signals in this program. -//! type Signal = (); -//! // We return a counter value (`i32`) in the `state()` function in this program. -//! type State = Out; -//! } -//! ``` -//! -//! - `ping` program crate: -//! -//! ``` -//! #[no_std] -//! use gmeta::{InOut, Metadata}; -//! use gstd::{msg, prelude::*}; -//! # const IGNORE: &'static str = stringify! { -//! use ping_io::PingPong; -//! # }; -//! -//! // Counter that will be incremented on each `Ping` message. -//! static mut COUNTER: i32 = 0; -//! -//! # #[derive(Encode, Decode, TypeInfo)] -//! # pub enum PingPong { -//! # Ping, -//! # Pong, -//! # } -//! # -//! #[no_mangle] -//! extern "C" fn handle() { -//! // Load incoming message of `PingPong` type. -//! let payload: PingPong = msg::load().expect("Unable to load"); -//! -//! if let PingPong::Ping = payload { -//! unsafe { COUNTER += 1 }; -//! // Send a reply message of `PingPong` type back to the sender. -//! msg::reply(PingPong::Pong, 0).expect("Unable to reply"); -//! } -//! } -//! -//! #[no_mangle] -//! extern "C" fn state() { -//! msg::reply(unsafe { COUNTER }, 0).expect("Unable to reply"); -//! } -//! ``` -//! -//! - `build.rs` file: -//! -//! ```no_run -//! # const IGNORE: &'static str = stringify! { -//! use ping_io::ProgramMetadata; -//! # }; -//! # -//! # pub struct ProgramMetadata; -//! # impl gmeta::Metadata for ProgramMetadata { -//! # type Init = (); -//! # type Handle = (); -//! # type Others = (); -//! # type Reply = (); -//! # type Signal = (); -//! # type State = (); -//! # } -//! -//! fn main() { -//! gear_wasm_builder::build_with_metadata::(); -//! } -//! ``` -//! -//! You can also generate metadata manually and write it to the file without -//! using `build.rs`: -//! -//! ``` -//! use gmeta::{Metadata, Out}; -//! # const IGNORE: &'static str = stringify! { -//! use ping_io::ProgramMetadata; -//! # }; -//! use std::fs; -//! -//! # #[derive(gstd::Encode, gstd::Decode, gstd::TypeInfo)] -//! # pub enum PingPong { -//! # Ping, -//! # Pong, -//! # } -//! # -//! # pub struct ProgramMetadata; -//! # impl gmeta::Metadata for ProgramMetadata { -//! # type Init = (); -//! # type Handle = (PingPong, PingPong); -//! # type Others = (); -//! # type Reply = (); -//! # type Signal = (); -//! # type State = Out; -//! # } -//! # -//! let metadata_hex = ProgramMetadata::repr().hex(); -//! assert_eq!(metadata_hex.len(), 146); -//! fs::write("ping.meta.txt", metadata_hex).expect("Unable to write"); -//! ``` -//! -//! You can parse generated metadata file using `gear-js` API in JavaScript: -//! -//! ```javascript -//! import { getProgramMetadata } from '@gear-js/api'; -//! import { readFileSync } from 'fs'; -//! -//! const metadataHex = readFileSync('ping.meta.txt', 'utf-8'); -//! const metadata = getProgramMetadata('0x' + metadataHex); -//! -//! console.log('Registry:', metadata.regTypes); -//! console.log('Types:', metadata.types); -//! ``` -//! -//! This will print the following: -//! -//! ```text -//! Registry: Map(2) { -//! 0 => { name: 'RustOutPingPong', def: '{"_enum":["Ping","Pong"]}' }, -//! 1 => { name: 'i32', def: null } -//! } -//! Types: { -//! init: { input: null, output: null }, -//! handle: { input: 0, output: 0 }, -//! reply: { input: null, output: null }, -//! others: { input: null, output: null }, -//! signal: null, -//! state: 1 -//! } -//! ``` - -#![no_std] -#![warn(missing_docs)] -#![doc(html_logo_url = "https://docs.gear.rs/logo.svg")] -#![doc(html_favicon_url = "https://gear-tech.io/favicons/favicon.ico")] - -extern crate alloc; - -#[cfg(feature = "codegen")] -pub use gmeta_codegen::metawasm; - -pub use scale_info::{MetaType, PortableRegistry, Registry}; - -use alloc::{collections::BTreeMap, string::String, vec, vec::Vec}; -use blake2::{digest::typenum::U32, Blake2b, Digest}; -use core::any::TypeId; -use scale_info::{ - scale::{self, Decode, Encode}, - TypeInfo, -}; - -/// BLAKE2b-256 hasher state. -type Blake2b256 = Blake2b; - -const METADATA_VERSION: u16 = 2; - -/// Language identifier. -/// -/// Needed to distinguish between different languages used to generate metadata. -#[repr(u8)] -pub enum LanguageId { - /// Rust language. - Rust = 0, - /// AssemblyScript language. - AssemblyScript, -} - -/// Types representation used by metadata. -#[derive(Encode, Debug, Decode, Eq, PartialEq)] -#[codec(crate = scale)] -pub struct TypesRepr { - /// Input types. - pub input: Option, - /// Output types. - pub output: Option, -} - -/// Metadata internal representation. -#[derive(Encode, Debug, Decode, Eq, PartialEq)] -#[codec(crate = scale)] -pub struct MetadataRepr { - /// Internal representation for [`Metadata::Init`] type. - pub init: TypesRepr, - /// Internal representation for [`Metadata::Handle`] type. - pub handle: TypesRepr, - /// Internal representation for [`Metadata::Reply`] type. - pub reply: Option, - /// Internal representation for [`Metadata::Others`] type. - pub others: TypesRepr, - /// Internal representation for [`Metadata::Signal`] type. - pub signal: Option, - /// Internal representation for [`Metadata::State`] type. - pub state: TypesRepr, - /// Encoded registry of types. - pub registry: Vec, -} - -/// Metawasm data. -#[derive(Encode, Debug, Decode)] -#[codec(crate = scale)] -pub struct MetawasmData { - /// Meta functions. - pub funcs: BTreeMap, - /// Registry. - pub registry: Vec, -} - -/// Trait used to get information about types. -pub trait Type: TypeInfo + 'static { - /// Return `true` if type is unit. - fn is_unit() -> bool { - TypeId::of::().eq(&TypeId::of::<()>()) - } - - /// Create [`MetaType`] information about type. - fn meta_type() -> MetaType { - MetaType::new::() - } - - /// Register type in the registry and return its identifier if it is not the - /// unit type. - fn register(registry: &mut Registry) -> Option { - (!Self::is_unit()).then(|| registry.register_type(&Self::meta_type()).id) - } -} - -impl Type for T {} - -/// Trait used for registering types in registry. -pub trait Types { - /// Input type. - type Input: Type; - /// Output type. - type Output: Type; - - /// Register input/output types in registry. - fn register(registry: &mut Registry) -> TypesRepr { - let input = Self::Input::register(registry); - let output = Self::Output::register(registry); - - TypesRepr { input, output } - } -} - -/// Type alias for incoming/outgoing message types. -pub type InOut = (I, O); -/// Type alias for incoming message type without any outgoing type. -pub type In = InOut; -/// Type alias for outgoing message type without any incoming type. -pub type Out = InOut<(), O>; - -impl Types for InOut { - type Input = I; - type Output = O; -} - -impl Types for () { - type Input = (); - type Output = (); -} - -impl MetadataRepr { - /// Encode metadata into bytes using codec. - pub fn bytes(&self) -> Vec { - // Append language ID and version as a preamble - let version_bytes = METADATA_VERSION.to_le_bytes(); - let mut bytes = vec![LanguageId::Rust as u8, version_bytes[0], version_bytes[1]]; - - bytes.extend(self.encode()); - bytes - } - - /// Decode metadata from bytes using codec. - pub fn from_bytes(data: impl AsRef<[u8]>) -> Result { - let preamble_len = size_of::() | size_of_val(&METADATA_VERSION); - let data = data.as_ref(); - if data.len() < preamble_len { - return Err(MetadataParseError::InvalidMetadata); - } - - // Check language ID and version - let lang_id = data[0]; - if lang_id != LanguageId::Rust as u8 { - return Err(MetadataParseError::UnsupportedLanguageId(lang_id)); - } - let version = u16::from_le_bytes([data[1], data[2]]); - if version != METADATA_VERSION { - return Err(MetadataParseError::UnsupportedVersion(version)); - } - - // Remove preamble before decoding - let mut data = &data[preamble_len..]; - - let this = Self::decode(&mut data)?; - Ok(this) - } - - /// Decode metadata from hex. - pub fn from_hex>(data: T) -> Result { - Self::from_bytes(hex::decode(data)?) - } - - /// Encode metadata into hex string. - pub fn hex(&self) -> String { - hex::encode(self.bytes()) - } - - /// Calculate BLAKE2b hash of metadata bytes. - pub fn hash(&self) -> [u8; 32] { - let mut ctx = Blake2b256::new(); - ctx.update(self.bytes()); - ctx.finalize().into() - } - - /// Calculate BLAKE2b hash of metadata and encode it into hex string. - pub fn hash_hex(&self) -> String { - hex::encode(self.hash()) - } -} - -/// Error that can occur during metadata parsing. -#[derive(Debug, derive_more::From)] -pub enum MetadataParseError { - /// Error that can occur during encoding/decoding. - Codec(scale_info::scale::Error), - /// Error that can occur during hex decoding. - FromHex(hex::FromHexError), - /// Error that can occur during metadata parsing. - InvalidMetadata, - /// Error that can occur when trying to parse metadata generated by another - /// language than Rust. - UnsupportedLanguageId(u8), - /// Error that can occur when trying to parse metadata with another version - /// than the current one. - UnsupportedVersion(u16), -} - -/// Trait used for defining metadata. -pub trait Metadata { - /// Init message type. - /// - /// Describes incoming/outgoing types for the `init()` function. Incoming - /// message can be read by calling - /// [`msg::load`](https://docs.gear.rs/gstd/msg/fn.load.html) - /// function. Outgoing message is a reply to the incoming message and - /// can be sent by calling the - /// [`msg::reply`](https://docs.gear.rs/gstd/msg/fn.reply.html) function. - /// - /// - Use unit tuple `()` if neither incoming nor outgoing messages are - /// expected in the `init()` function. - /// - Use [`In`] type alias if only incoming message is expected in the - /// `init()` function. - /// - Use [`Out`] type alias if only outgoing message is expected in the - /// `init()` function. - /// - Use [`InOut`] type alias if both incoming and outgoing messages are - /// expected in the `init()` function. - /// - /// # Note - /// - /// If an outgoing message has been sent using the - /// [`msg::send`](https://docs.gear.rs/gstd/msg/fn.send.html) function, - /// then it is supposed to be parsed by the another type metadata. - /// See [`Others`](Self::Others) type for more details. - type Init: Types; - /// Handle message type. - /// - /// Describes incoming/outgoing types for the `handle()` function. - /// - /// This type is similar to the [`Init`](Self::Init) type, but it is used - /// for the `handle()` function. - type Handle: Types; - /// Reply message type. - /// - /// Describes incoming type for the `handle_reply()` function. - type Reply: Type; - /// Message types for miscellaneous purposes. - /// - /// Here we can define types used in some specific functions. For example, - /// the outgoing message type in `Others` is used as a ordinary message - /// sent by the program using the - /// [`msg::send`](https://docs.gear.rs/gstd/msg/fn.send.html) function. - type Others: Types; - /// Signal message type. - /// - /// Describes only the outgoing type from the program while processing the - /// system signal. - type Signal: Type; - /// State type. - /// - /// Describes the type for the queried state returned by the `state()` - /// function. - /// - /// Use the type that you pass to the `msg::reply` function in the `state()` - /// function or unit tuple `()` if no `state()` function is defined. - type State: Types; - - /// Create metadata representation and register types in registry. - fn repr() -> MetadataRepr { - let mut registry = Registry::new(); - - MetadataRepr { - init: Self::Init::register(&mut registry), - handle: Self::Handle::register(&mut registry), - reply: Self::Reply::register(&mut registry), - others: Self::Others::register(&mut registry), - signal: Self::Signal::register(&mut registry), - state: Self::State::register(&mut registry), - registry: PortableRegistry::from(registry).encode(), - } - } -} diff --git a/gsdk/Cargo.toml b/gsdk/Cargo.toml index eaaed1c305e..07f39694447 100644 --- a/gsdk/Cargo.toml +++ b/gsdk/Cargo.toml @@ -18,18 +18,18 @@ base64.workspace = true colored.workspace = true futures-util.workspace = true futures.workspace = true -gear-core = { workspace = true, features = [ "std" ] } +gear-core = { workspace = true, features = ["std"] } gear-core-errors.workspace = true hex.workspace = true indexmap.workspace = true -jsonrpsee = { workspace = true, features = [ "http-client", "ws-client" ] } +jsonrpsee = { workspace = true, features = ["http-client", "ws-client"] } log.workspace = true scale-value.workspace = true serde.workspace = true serde_json.workspace = true subxt.workspace = true thiserror.workspace = true -sp-runtime = { workspace = true, features = [ "std" ] } +sp-runtime = { workspace = true, features = ["std"] } sp-core.workspace = true gsdk-codegen.workspace = true parking_lot.workspace = true @@ -44,9 +44,9 @@ rand = { workspace = true, optional = true } [dev-dependencies] gear-node-wrapper.workspace = true -tokio = { workspace = true, features = [ "full" ] } +tokio = { workspace = true, features = ["full"] } demo-messenger.workspace = true -demo-new-meta.workspace = true +demo-wallets.workspace = true demo-vec.workspace = true demo-waiter = { workspace = true, features = ["std"] } @@ -54,4 +54,4 @@ demo-waiter = { workspace = true, features = ["std"] } gear-utils.workspace = true [features] -testing = [ "rand" ] +testing = ["rand"] diff --git a/gsdk/tests/rpc.rs b/gsdk/tests/rpc.rs index 8ae224973ce..b24d4511e66 100644 --- a/gsdk/tests/rpc.rs +++ b/gsdk/tests/rpc.rs @@ -361,10 +361,12 @@ async fn test_program_counters() -> Result<()> { #[tokio::test] async fn test_calculate_reply_for_handle() -> Result<()> { + use demo_wallets::{Id, MessageIn, MessageOut, Wallet, WASM_BINARY}; + let node = dev_node(); let salt = vec![]; - let pid = ProgramId::generate_from_user(CodeId::generate(demo_new_meta::WASM_BINARY), &salt); + let pid = ProgramId::generate_from_user(CodeId::generate(WASM_BINARY), &salt); // 1. upload program. let signer = Api::new(node.ws().as_str()) @@ -373,13 +375,7 @@ async fn test_calculate_reply_for_handle() -> Result<()> { signer .calls - .upload_program( - demo_new_meta::WASM_BINARY.to_vec(), - salt, - vec![], - 100_000_000_000, - 0, - ) + .upload_program(WASM_BINARY.to_vec(), salt, vec![], 100_000_000_000, 0) .await?; assert!( @@ -387,15 +383,15 @@ async fn test_calculate_reply_for_handle() -> Result<()> { "Program not exists on chain." ); - let message_in = demo_new_meta::MessageIn { - id: demo_new_meta::Id { + let message_in = MessageIn { + id: Id { decimal: 1, hex: [1].to_vec(), }, }; - let message_out = demo_new_meta::MessageOut { - res: demo_new_meta::Wallet::test_sequence() + let message_out = MessageOut { + res: Wallet::test_sequence() .iter() .find(|w| w.id.decimal == message_in.id.decimal) .cloned(), diff --git a/pallets/gear/Cargo.toml b/pallets/gear/Cargo.toml index af9fb543119..32d2076b22d 100644 --- a/pallets/gear/Cargo.toml +++ b/pallets/gear/Cargo.toml @@ -82,7 +82,7 @@ demo-distributor.workspace = true demo-init-fail-sender.workspace = true demo-init-wait.workspace = true demo-init-wait-reply-exit.workspace = true -demo-new-meta.workspace = true +demo-wallets.workspace = true demo-futures-unordered.workspace = true demo-program-factory.workspace = true demo-program-generator.workspace = true @@ -129,7 +129,6 @@ pallet-gear-messenger = { workspace = true, features = ["std"] } pallet-gear-scheduler = { workspace = true, features = ["std"] } pallet-gear-program = { workspace = true, features = ["std"] } pallet-gear-voucher = { workspace = true, features = ["std"] } -gmeta.workspace = true rand.workspace = true [features] diff --git a/pallets/gear/src/tests.rs b/pallets/gear/src/tests.rs index 9d0f129d77b..30a11c43c48 100644 --- a/pallets/gear/src/tests.rs +++ b/pallets/gear/src/tests.rs @@ -23,7 +23,7 @@ use crate::{ mock::{ self, new_test_ext, run_for_blocks, run_to_block, run_to_block_maybe_with_queue, run_to_next_block, Balances, BlockNumber, DynamicSchedule, Gear, GearVoucher, - RuntimeEvent as MockRuntimeEvent, RuntimeOrigin, System, Test, Timestamp, BLOCK_AUTHOR, + RuntimeEvent as MockRuntimeEvent, RuntimeOrigin, System, Test, BLOCK_AUTHOR, LOW_BALANCE_USER, RENT_POOL, USER_1, USER_2, USER_3, }, pallet, @@ -186,7 +186,7 @@ fn calculate_gas_results_in_finite_wait() { #[test] fn state_rpc_calls_trigger_reinstrumentation() { - use demo_new_meta::{MessageInitIn, META_WASM_V1, WASM_BINARY}; + use demo_wallets::{MessageInitIn, WASM_BINARY}; init_logger(); new_test_ext().execute_with(|| { @@ -244,16 +244,7 @@ fn state_rpc_calls_trigger_reinstrumentation() { ::CodeStorage::update_code(code_and_id); /* ends here */ - assert_ok!(Gear::read_metahash_impl(program_id, None)); assert_ok!(Gear::read_state_impl(program_id, Default::default(), None)); - assert_ok!(Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "last_wallet", - META_WASM_V1.to_vec(), - None, - None, - )); }); } @@ -2590,7 +2581,7 @@ fn unstoppable_block_execution_works() { #[test] fn read_state_works() { - use demo_new_meta::{MessageInitIn, Wallet, WASM_BINARY}; + use demo_wallets::{MessageInitIn, Wallet, WASM_BINARY}; init_logger(); new_test_ext().execute_with(|| { @@ -2619,268 +2610,6 @@ fn read_state_works() { }); } -#[test] -fn read_state_using_wasm_works() { - use demo_new_meta::{ - Id, MessageInitIn, Wallet, META_EXPORTS_V1, META_EXPORTS_V2, META_WASM_V1, META_WASM_V2, - WASM_BINARY, - }; - - init_logger(); - new_test_ext().execute_with(|| { - assert_ok!(Gear::upload_program( - RuntimeOrigin::signed(USER_2), - WASM_BINARY.to_vec(), - DEFAULT_SALT.to_vec(), - ::default().encode(), - DEFAULT_GAS_LIMIT * 100, - 10_000, - false, - )); - - let program_id = utils::get_last_program_id(); - - run_to_next_block(None); - - assert!(Gear::is_initialized(program_id)); - - let expected = Wallet::test_sequence().into_iter().last().encode(); - - let func1 = "last_wallet"; - assert!(META_EXPORTS_V1.contains(&func1)); - - let res = Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - func1, - META_WASM_V1.to_vec(), - None, - None, - ) - .expect("Failed to read state"); - - assert_eq!(res, expected); - - let id = Id { - decimal: 1, - hex: vec![1], - }; - - let expected = Wallet::test_sequence() - .into_iter() - .find(|w| w.id == id) - .encode(); - - let func2 = "wallet_by_id"; - assert!(META_EXPORTS_V2.contains(&func2)); - assert!(!META_EXPORTS_V2.contains(&func1)); - - let res = Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - func2, - META_WASM_V2.to_vec(), - Some(id.encode()), - None, - ) - .expect("Failed to read state"); - - assert_eq!(res, expected); - }); -} - -#[test] -fn read_state_bn_and_timestamp_works() { - use demo_new_meta::{MessageInitIn, META_WASM_V3, WASM_BINARY}; - - let check = |program_id: ProgramId| { - let expected: u32 = Gear::block_number().unique_saturated_into(); - - let res = Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "block_number", - META_WASM_V3.to_vec(), - None, - None, - ) - .expect("Failed to read state"); - let res = u32::decode(&mut res.as_ref()).unwrap(); - - assert_eq!(res, expected); - - let expected: u64 = Timestamp::get().unique_saturated_into(); - - let res = Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "block_timestamp", - META_WASM_V3.to_vec(), - None, - None, - ) - .expect("Failed to read state"); - let res = u64::decode(&mut res.as_ref()).unwrap(); - - assert_eq!(res, expected); - }; - - init_logger(); - new_test_ext().execute_with(|| { - assert_ok!(Gear::upload_program( - RuntimeOrigin::signed(USER_2), - WASM_BINARY.to_vec(), - DEFAULT_SALT.to_vec(), - ::default().encode(), - DEFAULT_GAS_LIMIT * 100, - 10_000, - false, - )); - - let program_id = utils::get_last_program_id(); - - run_to_next_block(None); - assert!(Gear::is_initialized(program_id)); - check(program_id); - - run_to_block(10, None); - check(program_id); - - run_to_block(20, None); - check(program_id); - }); -} - -#[test] -fn wasm_metadata_generation_works() { - use demo_new_meta::{ - MessageInitIn, META_EXPORTS_V1, META_EXPORTS_V2, META_WASM_V1, META_WASM_V2, WASM_BINARY, - }; - - init_logger(); - new_test_ext().execute_with(|| { - assert_ok!(Gear::upload_program( - RuntimeOrigin::signed(USER_2), - WASM_BINARY.to_vec(), - DEFAULT_SALT.to_vec(), - ::default().encode(), - DEFAULT_GAS_LIMIT * 100, - 10_000, - false, - )); - - let program_id = utils::get_last_program_id(); - - run_to_next_block(None); - - assert!(Gear::is_initialized(program_id)); - - let m1 = Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "metadata", - META_WASM_V1.to_vec(), - None, - None, - ) - .expect("Failed to read state"); - - let metadata1 = - gmeta::MetawasmData::decode(&mut m1.as_ref()).expect("Failed to decode metadata"); - let mut exports1 = metadata1.funcs.keys().cloned().collect::>(); - exports1.push("metadata".into()); - exports1.sort(); - let mut expected_exports_1 = META_EXPORTS_V1.to_vec(); - expected_exports_1.sort(); - assert_eq!(exports1, expected_exports_1); - - let m2 = Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "metadata", - META_WASM_V2.to_vec(), - None, - None, - ) - .expect("Failed to read state"); - - let metadata2 = - gmeta::MetawasmData::decode(&mut m2.as_ref()).expect("Failed to decode metadata"); - let mut exports2 = metadata2.funcs.keys().cloned().collect::>(); - exports2.push("metadata".into()); - exports2.sort(); - let mut expected_exports_2 = META_EXPORTS_V2.to_vec(); - expected_exports_2.sort(); - assert_eq!(exports2, expected_exports_2); - }); -} - -#[test] -fn read_state_using_wasm_errors() { - use demo_new_meta::{MessageInitIn, WASM_BINARY}; - - let wat = r#" - (module - (export "loop" (func $loop)) - (export "empty" (func $empty)) - (func $empty) - (func $loop - (loop) - ) - )"#; - - init_logger(); - new_test_ext().execute_with(|| { - let meta_wasm = ProgramCodeKind::Custom(wat).to_bytes().to_vec(); - - assert_ok!(Gear::upload_program( - RuntimeOrigin::signed(USER_2), - WASM_BINARY.to_vec(), - DEFAULT_SALT.to_vec(), - ::default().encode(), - DEFAULT_GAS_LIMIT * 100, - 10_000, - false, - )); - - let program_id = utils::get_last_program_id(); - - run_to_next_block(None); - assert!(Gear::is_initialized(program_id)); - - // Inexistent function - assert!(Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "inexistent", - meta_wasm.clone(), - None, - None, - ) - .is_err()); - // Empty function - assert!(Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "empty", - meta_wasm.clone(), - None, - None, - ) - .is_err()); - // Greed function - assert!(Gear::read_state_using_wasm_impl( - program_id, - Default::default(), - "loop", - meta_wasm, - None, - None, - ) - .is_err()); - }); -} - #[test] fn mailbox_rent_out_of_rent() { use demo_constructor::{demo_value_sender::TestData, Scheme}; diff --git a/scripts/src/format.sh b/scripts/src/format.sh index e0d98f5c7a9..4ac13a311e9 100755 --- a/scripts/src/format.sh +++ b/scripts/src/format.sh @@ -28,6 +28,6 @@ format() { } doc_format() { - cargo fmt -p gstd -p gcore -p gclient -p gmeta -p gtest \ + cargo fmt -p gstd -p gcore -p gclient -p gtest \ -- "$@" --config wrap_comments=true,format_code_in_doc_comments=true } diff --git a/utils/cargo-gbuild/test-program/Cargo.toml b/utils/cargo-gbuild/test-program/Cargo.toml index 4b1d049f3eb..1eb18cb9686 100644 --- a/utils/cargo-gbuild/test-program/Cargo.toml +++ b/utils/cargo-gbuild/test-program/Cargo.toml @@ -18,8 +18,7 @@ default = [] std = [] [workspace] -members = [ "foo", "bar" , "meta"] +members = ["foo", "bar"] [workspace.metadata.gbuild] -programs = [ "foo", "bar" ] -metas = ["meta"] +programs = ["foo", "bar"] diff --git a/utils/cargo-gbuild/test-program/meta/Cargo.toml b/utils/cargo-gbuild/test-program/meta/Cargo.toml deleted file mode 100644 index cd57d437094..00000000000 --- a/utils/cargo-gbuild/test-program/meta/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "gbuild-test-meta" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -gstd = { path = "../../../../gstd" } -gmeta = { path = "../../../../gmeta", features = ["codegen"] } - diff --git a/utils/cargo-gbuild/test-program/meta/src/lib.rs b/utils/cargo-gbuild/test-program/meta/src/lib.rs deleted file mode 100644 index 91918b99fea..00000000000 --- a/utils/cargo-gbuild/test-program/meta/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![no_std] - -use gmeta::metawasm; -use gstd::prelude::*; - -#[metawasm] -pub mod metafns { - pub type State = bool; - - pub fn modified(state: State) -> bool { - state - } -} diff --git a/utils/crates-io/src/handler.rs b/utils/crates-io/src/handler.rs index bf3c23ff203..d89206363b7 100644 --- a/utils/crates-io/src/handler.rs +++ b/utils/crates-io/src/handler.rs @@ -21,7 +21,6 @@ use crate::Manifest; use anyhow::Result; use cargo_metadata::Package; -use toml_edit::DocumentMut; /// The working version of sp-wasm-interface. pub const GP_RUNTIME_INTERFACE_VERSION: &str = "18.0.0"; @@ -47,8 +46,6 @@ pub fn patch(pkg: &Package) -> Result { "gear-sandbox" => sandbox::patch(doc), "gear-sandbox-host" => sandbox_host::patch(doc), "gear-sandbox-interface" => sandbox_interface::patch(doc), - "gmeta" => gmeta::patch(doc), - "gmeta-codegen" => gmeta_codegen::patch(doc), _ => {} } @@ -78,16 +75,6 @@ pub fn patch_workspace(name: &str, table: &mut toml_edit::InlineTable) { } } -// Trim the version of dev dependency. -// -// issue: https://github.com/rust-lang/cargo/issues/4242 -fn trim_dev_dep(name: &str, manifest: &mut DocumentMut) { - if let Some(dep) = manifest["dev-dependencies"][name].as_table_like_mut() { - dep.remove("workspace"); - dep.insert("version", toml_edit::value("~1")); - } -} - /// gear-core-processor handler. mod core_processor { use toml_edit::{DocumentMut, InlineTable}; @@ -116,30 +103,6 @@ mod core_processor { } } -/// gmeta handler -mod gmeta { - use super::trim_dev_dep; - use toml_edit::DocumentMut; - - /// Patch the manifest of gmetadata. - pub fn patch(manifest: &mut DocumentMut) { - trim_dev_dep("gstd", manifest); - trim_dev_dep("gear-wasm-builder", manifest); - } -} - -/// gmeta handler -mod gmeta_codegen { - use super::trim_dev_dep; - use toml_edit::DocumentMut; - - /// Patch the manifest of gmeta. - pub fn patch(manifest: &mut DocumentMut) { - trim_dev_dep("gstd", manifest); - trim_dev_dep("gmeta", manifest); - } -} - /// sandbox handler. mod sandbox { use toml_edit::DocumentMut; diff --git a/utils/crates-io/src/lib.rs b/utils/crates-io/src/lib.rs index ea24b531bee..bc660be1e54 100644 --- a/utils/crates-io/src/lib.rs +++ b/utils/crates-io/src/lib.rs @@ -45,7 +45,6 @@ pub const SAFE_DEPENDENCIES: &[&str] = &[ "gear-runtime-primitives", "gear-sandbox-env", "gear-wasm-instrument", - "gmeta-codegen", "gsdk-codegen", "gsys", "numerated", @@ -63,7 +62,6 @@ pub const STACKED_DEPENDENCIES: &[&str] = &[ "gbuiltin-staking", "gstd-codegen", "gcore", - "gmeta", "gear-core", "gear-utils", "gear-common", diff --git a/utils/wasm-builder/Cargo.toml b/utils/wasm-builder/Cargo.toml index 0a342ce01c5..88431452257 100644 --- a/utils/wasm-builder/Cargo.toml +++ b/utils/wasm-builder/Cargo.toml @@ -21,7 +21,6 @@ pwasm-utils = { workspace = true, features = ["sign_ext"] } toml.workspace = true log.workspace = true pathdiff.workspace = true -gmeta.workspace = true gear-core.workspace = true gear-wasm-instrument.workspace = true gear-wasm-optimizer.workspace = true @@ -33,5 +32,4 @@ wabt.workspace = true parity-wasm.workspace = true [features] -metawasm = ["gmeta/codegen"] wasm-opt = ["gear-wasm-optimizer/wasm-opt"] diff --git a/utils/wasm-builder/README.md b/utils/wasm-builder/README.md index 14766e2c41e..7dfa850ea4f 100644 --- a/utils/wasm-builder/README.md +++ b/utils/wasm-builder/README.md @@ -37,9 +37,11 @@ cargo test --release - `.wasm` — original WASM built from the source files - `.opt.wasm` — optimised WASM binary to be submitted to the blockchain -- `.meta.wasm` — metadata providing WASM binary for auxiliary purposes -5. Also, you can include a generated `wasm_binary.rs` source file to use the WASM code while e.g. writing tests. When doing this, you need to use some feature which will be excluded from passing it down to the build process triggered by the build script. By default, this is the `std` feature. If you want to use a custom feature for that, use one of the the `build_XXX_custom` functions in your `build.rs` +5. Also, you can include a generated `wasm_binary.rs` source file to use the WASM code while e.g. writing tests. When + doing this, you need to use some feature which will be excluded from passing it down to the build process triggered + by the build script. By default, this is the `std` feature. If you want to use a custom feature for that, use one of + the the `build_XXX_custom` functions in your `build.rs` ```rust #[cfg(feature = "std")] @@ -57,10 +59,6 @@ fn debug_wasm() { std::fs::read("target/wasm32-unknown-unknown/debug/test_program.opt.wasm").unwrap(), code::WASM_BINARY_OPT, ); - assert_eq!( - std::fs::read("target/wasm32-unknown-unknown/debug/test_program.meta.wasm").unwrap(), - code::WASM_BINARY_META, - ); } ``` diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 5ad99a99757..498c6a59af0 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -24,10 +24,8 @@ pub use wasm_project::{PreProcessor, PreProcessorResult, PreProcessorTarget}; use crate::wasm_project::WasmProject; use anyhow::Result; -use gmeta::{Metadata, MetadataRepr}; use regex::Regex; use std::{env, path::PathBuf, process}; -use wasm_project::ProjectType; mod builder_error; pub mod code_validator; @@ -48,17 +46,7 @@ pub struct WasmBuilder { impl WasmBuilder { /// Create a new `WasmBuilder`. pub fn new() -> Self { - WasmBuilder::create(WasmProject::new(ProjectType::Program(None))) - } - - /// Create a new `WasmBuilder` for metawasm. - pub fn new_metawasm() -> Self { - WasmBuilder::create(WasmProject::new(ProjectType::Metawasm)) - } - - /// Create a new `WasmBuilder` with metadata. - pub fn with_meta(metadata: MetadataRepr) -> Self { - WasmBuilder::create(WasmProject::new(ProjectType::Program(Some(metadata)))) + WasmBuilder::create(WasmProject::new()) } fn create(wasm_project: WasmProject) -> Self { @@ -229,24 +217,6 @@ pub fn build() -> Option<(PathBuf, PathBuf)> { .build() } -/// Shorthand function to be used in `build.rs`. -/// -/// See [WasmBuilder::build()]. -pub fn build_with_metadata() -> Option<(PathBuf, PathBuf)> { - WasmBuilder::with_meta(T::repr()) - .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) - .build() -} - -/// Shorthand function to be used in `build.rs`. -/// -/// See [WasmBuilder::build()]. -pub fn build_metawasm() -> Option<(PathBuf, PathBuf)> { - WasmBuilder::new_metawasm() - .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) - .build() -} - /// Shorthand function to be used in `build.rs`. /// /// See [WasmBuilder::build()]. @@ -256,23 +226,3 @@ pub fn recommended_nightly() -> Option<(PathBuf, PathBuf)> { .with_recommended_toolchain() .build() } - -/// Shorthand function to be used in `build.rs`. -/// -/// See [WasmBuilder::build()]. -pub fn recommended_nightly_with_metadata() -> Option<(PathBuf, PathBuf)> { - WasmBuilder::with_meta(T::repr()) - .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) - .with_recommended_toolchain() - .build() -} - -/// Shorthand function to be used in `build.rs`. -/// -/// See [WasmBuilder::build()]. -pub fn recommended_nightly_metawasm() -> Option<(PathBuf, PathBuf)> { - WasmBuilder::new_metawasm() - .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) - .with_recommended_toolchain() - .build() -} diff --git a/utils/wasm-builder/src/smart_fs.rs b/utils/wasm-builder/src/smart_fs.rs index a30bd58332e..5465f13d0a4 100644 --- a/utils/wasm-builder/src/smart_fs.rs +++ b/utils/wasm-builder/src/smart_fs.rs @@ -21,7 +21,6 @@ //! because cargo looks for `mtime` metadata file parameter use anyhow::Result; -use gmeta::MetadataRepr; use std::{fs, io::ErrorKind, path::Path}; pub(crate) fn copy_if_newer(from: impl AsRef, to: impl AsRef) -> Result { @@ -72,26 +71,3 @@ pub(crate) fn write, C: AsRef<[u8]>>(path: P, contents: C) -> Res Ok(()) } - -fn check_metadata_changed(path: &Path, metadata: &MetadataRepr) -> Result { - if !path.exists() { - return Ok(true); - } - - let old_metadata = fs::read(path)?; - let Ok(old_metadata) = MetadataRepr::from_hex(old_metadata) else { - return Ok(true); - }; - - Ok(old_metadata != *metadata) -} - -pub(crate) fn write_metadata>(path: P, metadata: &MetadataRepr) -> Result<()> { - let path = path.as_ref(); - - if check_metadata_changed(path, metadata)? { - fs::write(path, metadata.hex())?; - } - - Ok(()) -} diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index ec9b8b1ce50..955cdeecc4f 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -20,8 +20,6 @@ use crate::{code_validator::CodeValidator, crate_info::CrateInfo, smart_fs}; use anyhow::{anyhow, Context, Ok, Result}; use chrono::offset::Local as ChronoLocal; use gear_wasm_optimizer::{self as optimize, OptType, Optimizer}; -use gmeta::MetadataRepr; -use pwasm_utils::parity_wasm::{self, elements::Internal}; use std::{ env, fs, path::{Path, PathBuf}, @@ -30,25 +28,6 @@ use toml::value::Table; const OPT_LEVEL: &str = "z"; -/// Enum defining type of binary compiling: production program or metawasm. -pub enum ProjectType { - Program(Option), - Metawasm, -} - -impl ProjectType { - pub fn is_metawasm(&self) -> bool { - matches!(self, ProjectType::Metawasm) - } - - pub fn metadata(&self) -> Option<&MetadataRepr> { - match self { - ProjectType::Program(metadata) => metadata.as_ref(), - _ => None, - } - } -} - /// Temporary project generated to build a WASM output. /// /// This project is required due to the cargo locking during build. @@ -59,7 +38,6 @@ pub struct WasmProject { wasm_target_dir: PathBuf, file_base_name: Option, profile: String, - project_type: ProjectType, features: Option>, pre_processors: Vec>, } @@ -96,7 +74,7 @@ pub trait PreProcessor { impl WasmProject { /// Create a new `WasmProject`. - pub fn new(project_type: ProjectType) -> Self { + pub fn new() -> Self { let original_dir: PathBuf = env::var("CARGO_MANIFEST_DIR") .expect("`CARGO_MANIFEST_DIR` is always set in build scripts") .into(); @@ -140,7 +118,6 @@ impl WasmProject { wasm_target_dir, file_base_name: None, profile, - project_type, features: None, pre_processors: vec![], } @@ -243,7 +220,7 @@ impl WasmProject { let to_lock = self.out_dir.join("Cargo.lock"); drop(fs::copy(from_lock, to_lock)); - let mut source_code = + let source_code = "#![no_std]\n#[allow(unused_imports)]\npub use orig_project::*;\n".to_owned(); fs::create_dir_all(&self.wasm_target_dir).with_context(|| { @@ -253,52 +230,6 @@ impl WasmProject { ) })?; - // Write metadata - if let Some(metadata) = &self.project_type.metadata() { - let file_base_name = self - .file_base_name - .as_ref() - .expect("Run `WasmProject::create_project()` first"); - - let wasm_meta_path = self - .wasm_target_dir - .join([file_base_name, ".meta.txt"].concat()); - - smart_fs::write_metadata(wasm_meta_path, metadata) - .context("unable to write `*.meta.txt`")?; - - source_code = format!( - r#"{source_code} -#[allow(improper_ctypes)] -mod fake_gsys {{ - extern "C" {{ - pub fn gr_reply( - payload: *const u8, - len: u32, - value: *const u128, - err_mid: *mut [u8; 36], - ); - }} -}} - -#[no_mangle] -extern "C" fn metahash() {{ - const METAHASH: [u8; 32] = {:?}; - let mut res: [u8; 36] = [0; 36]; - unsafe {{ - fake_gsys::gr_reply( - METAHASH.as_ptr(), - METAHASH.len() as _, - u32::MAX as _, - &mut res as _, - ); - }} -}} -"#, - metadata.hash(), - ); - } - let src_dir = self.out_dir.join("src"); fs::create_dir_all(&src_dir).context("Failed to create `src` directory")?; smart_fs::write(src_dir.join("lib.rs"), source_code)?; @@ -306,38 +237,6 @@ extern "C" fn metahash() {{ Ok(()) } - /// Generate output wasm meta file and wasm binary informational file. - pub fn postprocess_meta( - &self, - original_wasm_path: &PathBuf, - file_base_name: &String, - ) -> Result<()> { - let meta_wasm_path = self - .wasm_target_dir - .join([file_base_name, ".meta.wasm"].concat()); - - if smart_fs::check_if_newer(original_wasm_path, &meta_wasm_path)? { - fs::write( - meta_wasm_path.clone(), - Optimizer::new(original_wasm_path.clone())?.optimize(OptType::Meta)?, - )?; - } - - smart_fs::write( - self.out_dir.join("wasm_binary.rs"), - format!( - r#"#[allow(unused)] - pub const WASM_BINARY: &[u8] = include_bytes!("{}"); - #[allow(unused)] - pub const WASM_EXPORTS: &[&str] = &{:?};"#, - display_path(meta_wasm_path.as_path()), - Self::get_exports(&meta_wasm_path)?, - ), - ) - .context("unable to write `wasm_binary.rs`") - .map_err(Into::into) - } - fn generate_bin_path(&self, file_base_name: &String) -> Result<()> { let relative_path_to_wasm = pathdiff::diff_paths(&self.wasm_target_dir, &self.original_dir) .with_context(|| { @@ -400,27 +299,15 @@ extern "C" fn metahash() {{ } // Create `wasm_binary.rs` - let metadata = self - .project_type - .metadata() - .map(|m| { - format!( - "#[allow(unused)] pub const WASM_METADATA: &[u8] = &{:?};\n", - m.bytes() - ) - }) - .unwrap_or_default(); smart_fs::write( self.out_dir.join("wasm_binary.rs"), format!( r#"#[allow(unused)] - pub const WASM_BINARY: &[u8] = include_bytes!("{}"); - #[allow(unused)] - pub const WASM_BINARY_OPT: &[u8] = include_bytes!("{}"); - {}"#, +pub const WASM_BINARY: &[u8] = include_bytes!("{}"); +#[allow(unused)] +pub const WASM_BINARY_OPT: &[u8] = include_bytes!("{}");"#, display_path(original_copy_wasm_path.as_path()), display_path(opt_wasm_path.as_path()), - metadata, ), ) .context("unable to write `wasm_binary.rs`")?; @@ -502,23 +389,15 @@ extern "C" fn metahash() {{ // Tuple with PathBuf last wasm & opt.wasm let mut wasm_paths: Option<(PathBuf, PathBuf)> = None; for (wasm_path, file_base_name) in &wasm_files { - if self.project_type.is_metawasm() { - self.postprocess_meta(wasm_path, file_base_name)?; - } else { - let wasm_opt = self.postprocess_opt(wasm_path, file_base_name)?; - wasm_paths = Some((wasm_path.clone(), wasm_opt)); - } + let wasm_opt = self.postprocess_opt(wasm_path, file_base_name)?; + wasm_paths = Some((wasm_path.clone(), wasm_opt)); } for (wasm_path, _) in &wasm_files { let code = fs::read(wasm_path)?; let validator = CodeValidator::try_from(code)?; - if self.project_type.is_metawasm() { - validator.validate_metawasm()?; - } else { - validator.validate_program()?; - } + validator.validate_program()?; } if env::var("__GEAR_WASM_BUILDER_NO_FEATURES_TRACKING").is_err() { @@ -527,27 +406,6 @@ extern "C" fn metahash() {{ Ok(wasm_paths) } - fn get_exports(file: &PathBuf) -> Result> { - let module = - parity_wasm::deserialize_file(file).with_context(|| format!("File path: {file:?}"))?; - - let exports = module - .export_section() - .ok_or_else(|| anyhow!("Export section not found"))? - .entries() - .iter() - .flat_map(|entry| { - if let Internal::Function(_) = entry.internal() { - Some(entry.field().to_string()) - } else { - None - } - }) - .collect(); - - Ok(exports) - } - // Force cargo to re-run the build script next time it is invoked. // It is needed because feature set or toolchain can change. fn force_rerun_on_next_run(&self, wasm_file_path: &Path) -> Result<()> { @@ -565,20 +423,11 @@ extern "C" fn metahash() {{ return wasm_binary_rs; } - let content = if !self.project_type.is_metawasm() { - r#"#[allow(unused)] + let content = r#"#[allow(unused)] pub const WASM_BINARY: &[u8] = &[]; #[allow(unused)] pub const WASM_BINARY_OPT: &[u8] = &[]; - #[allow(unused)] pub const WASM_METADATA: &[u8] = &[]; - "# - } else { - r#"#[allow(unused)] - pub const WASM_BINARY: &[u8] = &[]; - #[allow(unused)] - pub const WASM_EXPORTS: &[&str] = &[]; - "# - }; + "#; let path = wasm_binary_rs.as_path(); fs::write(path, content) .unwrap_or_else(|_| panic!("Writing `{}` should not fail!", display_path(path))); diff --git a/utils/wasm-proc/src/main.rs b/utils/wasm-proc/src/main.rs index 9e47f7973d2..8ee900b005e 100644 --- a/utils/wasm-proc/src/main.rs +++ b/utils/wasm-proc/src/main.rs @@ -212,7 +212,7 @@ fn main() -> Result<(), Box> { let rt_allowed_imports: HashSet<&str> = RT_ALLOWED_IMPORTS.into(); for file in &wasm_files { - if !file.ends_with(".wasm") || file.ends_with(".meta.wasm") || file.ends_with(".opt.wasm") { + if !file.ends_with(".wasm") || file.ends_with(".opt.wasm") { continue; } From 361019ce20ec4484012e9236bf4bbfeb4be7204e Mon Sep 17 00:00:00 2001 From: Andrey Lazarko Date: Tue, 19 Nov 2024 20:16:12 +0100 Subject: [PATCH 2/3] removed meta from optimizer --- utils/cargo-gbuild/src/artifact.rs | 35 +++++++++--------------- utils/cargo-gbuild/src/metadata.rs | 14 +++------- utils/wasm-builder/src/wasm_project.rs | 4 +-- utils/wasm-optimizer/src/optimize.rs | 37 +++----------------------- utils/wasm-proc/src/main.rs | 4 +-- 5 files changed, 22 insertions(+), 72 deletions(-) diff --git a/utils/cargo-gbuild/src/artifact.rs b/utils/cargo-gbuild/src/artifact.rs index f6b397fdf54..56bb456775f 100644 --- a/utils/cargo-gbuild/src/artifact.rs +++ b/utils/cargo-gbuild/src/artifact.rs @@ -20,7 +20,7 @@ use crate::metadata::Metadata; use anyhow::{anyhow, Result}; use cargo_toml::Manifest; use colored::Colorize; -use gear_wasm_optimizer::{self as optimize, CargoCommand, OptType, Optimizer}; +use gear_wasm_optimizer::{self as optimize, CargoCommand, Optimizer}; use std::{ env, fs, path::{Path, PathBuf}, @@ -56,11 +56,10 @@ impl Artifacts { env::set_current_dir(&metadata.workspace_root); // Collect all possible packages from metadata - let mut artifacts: Vec = - collect_crates(&cwd, &metadata.gbuild.programs, OptType::Opt)? - .into_iter() - .chain(collect_crates(&cwd, &metadata.gbuild.metas, OptType::Meta)?) - .collect(); + let mut artifacts: Vec = collect_crates(&cwd, &metadata.gbuild.programs)? + .into_iter() + .chain(collect_crates(&cwd, &metadata.gbuild.metas)?) + .collect(); // If not using workspace build, filter out the matched package // from metas and programs. @@ -76,7 +75,6 @@ impl Artifacts { if manifest.package.is_some() { artifacts = vec![Artifact { manifest: metadata.manifest, - opt: OptType::Opt, name: manifest.package().name.clone(), }]; } @@ -127,8 +125,6 @@ impl Artifacts { pub struct Artifact { /// The original manifest path. pub manifest: PathBuf, - /// Optimization type - pub opt: OptType, /// Program name of this artifact. pub name: String, } @@ -138,11 +134,7 @@ impl Artifact { fn names(&self) -> (String, String) { let name = self.name.replace('-', "_"); let input = name.clone() + ".wasm"; - let output = if self.opt.is_meta() { - name + ".meta.wasm" - } else { - input.clone() - }; + let output = input.clone(); (input, output) } @@ -153,19 +145,17 @@ impl Artifact { optimize::optimize_wasm(src.join(input), output.clone(), "4", true)?; let mut optimizer = Optimizer::new(output.clone())?; - if !self.opt.is_meta() { - optimizer - .insert_stack_end_export() - .map_err(|e| anyhow!("{e}")); - optimizer.strip_custom_sections(); - } + optimizer + .insert_stack_end_export() + .map_err(|e| anyhow!("{e}")); + optimizer.strip_custom_sections(); - fs::write(output, optimizer.optimize(self.opt)?).map_err(Into::into) + fs::write(output, optimizer.optimize()?).map_err(Into::into) } } /// Collection crate manifests from the provided glob patterns. -fn collect_crates(cwd: &Path, patterns: &[String], opt: OptType) -> Result> { +fn collect_crates(cwd: &Path, patterns: &[String]) -> Result> { let cwd = env::current_dir()?; let mut crates: Vec = Default::default(); for p in patterns { @@ -217,7 +207,6 @@ fn collect_crates(cwd: &Path, patterns: &[String], opt: OptType) -> Result. -use crate::Artifact; -use anyhow::{anyhow, Result}; -use cargo_metadata::{CargoOpt, Message, MetadataCommand}; -use cargo_toml::Manifest; -use gear_wasm_optimizer::OptType; +use anyhow::Result; +use cargo_metadata::{CargoOpt, MetadataCommand}; use serde::{Deserialize, Serialize}; -use std::{ - io::BufReader, - ops::Deref, - path::PathBuf, - process::{Command, Stdio}, -}; +use std::{ops::Deref, path::PathBuf}; /// Cargo metadata pub struct Metadata { diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index 955cdeecc4f..4fa07b70663 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -19,7 +19,7 @@ use crate::{code_validator::CodeValidator, crate_info::CrateInfo, smart_fs}; use anyhow::{anyhow, Context, Ok, Result}; use chrono::offset::Local as ChronoLocal; -use gear_wasm_optimizer::{self as optimize, OptType, Optimizer}; +use gear_wasm_optimizer::{self as optimize, Optimizer}; use std::{ env, fs, path::{Path, PathBuf}, @@ -294,7 +294,7 @@ impl WasmProject { .insert_stack_end_export() .unwrap_or_else(|err| log::info!("Cannot insert stack end export: {}", err)); optimizer.strip_custom_sections(); - fs::write(&opt_wasm_path, optimizer.optimize(OptType::Opt)?) + fs::write(&opt_wasm_path, optimizer.optimize()?) .context("Failed to write optimized WASM binary")?; } diff --git a/utils/wasm-optimizer/src/optimize.rs b/utils/wasm-optimizer/src/optimize.rs index 942662c2535..2b30b7be910 100644 --- a/utils/wasm-optimizer/src/optimize.rs +++ b/utils/wasm-optimizer/src/optimize.rs @@ -23,7 +23,7 @@ use colored::Colorize; use gear_wasm_instrument::STACK_END_EXPORT_NAME; use pwasm_utils::{ parity_wasm, - parity_wasm::elements::{Internal, Module, Section, Serialize}, + parity_wasm::elements::{Module, Section, Serialize}, }; #[cfg(not(feature = "wasm-opt"))] use std::process::Command; @@ -47,20 +47,6 @@ const OPTIMIZED_EXPORTS: [&str; 7] = [ STACK_END_EXPORT_NAME, ]; -/// Type of the output wasm. -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum OptType { - Meta, - Opt, -} - -impl OptType { - /// If the optimization type if meta - pub fn is_meta(&self) -> bool { - self.eq(&OptType::Meta) - } -} - pub struct Optimizer { module: Module, file: PathBuf, @@ -101,27 +87,10 @@ impl Optimizer { } /// Process optimization. - pub fn optimize(&self, ty: OptType) -> Result> { + pub fn optimize(&self) -> Result> { let mut module = self.module.clone(); - let exports = if ty == OptType::Opt { - OPTIMIZED_EXPORTS.to_vec() - } else { - self.module - .export_section() - .ok_or_else(|| anyhow!("Export section not found"))? - .entries() - .iter() - .flat_map(|entry| { - if let Internal::Function(_) = entry.internal() { - let entry = entry.field(); - (!OPTIMIZED_EXPORTS.contains(&entry)).then_some(entry) - } else { - None - } - }) - .collect() - }; + let exports = OPTIMIZED_EXPORTS.to_vec(); pwasm_utils::optimize(&mut module, exports) .map_err(|e| anyhow!("{e:?}")) diff --git a/utils/wasm-proc/src/main.rs b/utils/wasm-proc/src/main.rs index 8ee900b005e..f63e11a2a9b 100644 --- a/utils/wasm-proc/src/main.rs +++ b/utils/wasm-proc/src/main.rs @@ -19,7 +19,7 @@ use clap::Parser; use gear_wasm_builder::{ code_validator::CodeValidator, - optimize::{self, OptType, Optimizer}, + optimize::{self, Optimizer}, }; use parity_wasm::elements::External; use std::{collections::HashSet, fs, path::PathBuf}; @@ -275,7 +275,7 @@ fn main() -> Result<(), Box> { "*** Processing chain optimization: {}", optimized_wasm_path.display() ); - let code = optimizer.optimize(OptType::Opt)?; + let code = optimizer.optimize()?; log::info!("Optimized wasm: {}", optimized_wasm_path.to_string_lossy()); fs::write(&optimized_wasm_path, &code)?; From 494a5bcf71012f7c80856429596184c327688809 Mon Sep 17 00:00:00 2001 From: Andrey Lazarko Date: Tue, 3 Dec 2024 12:44:48 +0100 Subject: [PATCH 3/3] removed wallets demo --- Cargo.lock | 29 +------- Cargo.toml | 4 - examples/fungible-token/io/src/lib.rs | 24 ++++++ examples/fungible-token/src/lib.rs | 2 + examples/wallets/Cargo.toml | 25 ------- examples/wallets/build.rs | 21 ------ examples/wallets/io/Cargo.toml | 13 ---- examples/wallets/io/src/lib.rs | 101 -------------------------- examples/wallets/src/lib.rs | 36 --------- examples/wallets/src/wasm.rs | 41 ----------- gcli/Cargo.toml | 2 +- gcli/tests/cmd/upload.rs | 7 +- gcli/tests/common/node.rs | 2 +- gcli/tests/gear.rs | 2 +- gclient/Cargo.toml | 3 +- gsdk/Cargo.toml | 2 +- gsdk/tests/rpc.rs | 20 ++--- pallets/gear/Cargo.toml | 2 +- pallets/gear/src/tests.rs | 10 +-- 19 files changed, 51 insertions(+), 295 deletions(-) delete mode 100644 examples/wallets/Cargo.toml delete mode 100644 examples/wallets/build.rs delete mode 100644 examples/wallets/io/Cargo.toml delete mode 100644 examples/wallets/io/src/lib.rs delete mode 100644 examples/wallets/src/lib.rs delete mode 100644 examples/wallets/src/wasm.rs diff --git a/Cargo.lock b/Cargo.lock index e630872d9b7..e87938993b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3845,26 +3845,6 @@ dependencies = [ "gstd", ] -[[package]] -name = "demo-wallets" -version = "0.1.0" -dependencies = [ - "demo-wallets-io", - "gear-wasm-builder", - "gstd", - "gtest", - "parity-scale-codec", -] - -[[package]] -name = "demo-wallets-io" -version = "0.1.0" -dependencies = [ - "gstd", - "parity-scale-codec", - "scale-info", -] - [[package]] name = "demo-wat" version = "0.1.0" @@ -5749,9 +5729,9 @@ dependencies = [ "clap 4.5.9", "color-eyre", "colored", + "demo-fungible-token", "demo-messenger", "demo-waiter", - "demo-wallets", "dirs", "env_logger", "etc", @@ -5799,14 +5779,13 @@ dependencies = [ "demo-constructor", "demo-custom", "demo-distributor", + "demo-fungible-token", "demo-mul-by-const", "demo-node", "demo-program-factory", "demo-proxy", "demo-proxy-relay", "demo-reserve-gas", - "demo-wallets", - "demo-wallets-io", "demo-wat", "env_logger", "futures", @@ -6825,10 +6804,10 @@ dependencies = [ "anyhow", "base64 0.21.7", "colored", + "demo-fungible-token", "demo-messenger", "demo-vec", "demo-waiter", - "demo-wallets", "futures", "futures-util", "gear-core", @@ -10747,6 +10726,7 @@ dependencies = [ "demo-delayed-reservation-sender", "demo-delayed-sender", "demo-distributor", + "demo-fungible-token", "demo-futures-unordered", "demo-gas-burned", "demo-incomplete-async-payloads", @@ -10775,7 +10755,6 @@ dependencies = [ "demo-wait-wake", "demo-waiter", "demo-waiting-proxy", - "demo-wallets", "derive_more 0.99.18", "env_logger", "frame-benchmarking", diff --git a/Cargo.toml b/Cargo.toml index e951c3e1655..7dc1c8be359 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,8 +81,6 @@ members = [ "examples/wait_wake", "examples/waiter", "examples/waiting-proxy", - "examples/wallets", - "examples/wallets/io", "examples/wat", "galloc", "gbuiltins/*", @@ -492,8 +490,6 @@ demo-wait-timeout = { path = "examples/wait-timeout" } demo-wait-wake = { path = "examples/wait_wake" } demo-waiting-proxy = { path = "examples/waiting-proxy" } demo-stack-allocations = { path = "examples/stack-allocations" } -demo-wallets = { path = "examples/wallets" } -demo-wallets-io = { path = "examples/wallets/io" } demo-wat = { path = "examples/wat" } # Dependencies that only used in one package diff --git a/examples/fungible-token/io/src/lib.rs b/examples/fungible-token/io/src/lib.rs index 3b7a6b295f6..84313472334 100644 --- a/examples/fungible-token/io/src/lib.rs +++ b/examples/fungible-token/io/src/lib.rs @@ -80,3 +80,27 @@ pub struct IoFungibleToken { pub allowances: Vec<(ActorId, Vec<(ActorId, u128)>)>, pub decimals: u8, } + +impl InitConfig { + pub fn test_sequence() -> Self { + InitConfig { + name: "MyToken".to_string(), + symbol: "MTK".to_string(), + decimals: 18, + initial_capacity: None, + } + } +} + +impl IoFungibleToken { + pub fn test_sequence() -> Self { + IoFungibleToken { + name: "MyToken".to_string(), + symbol: "MTK".to_string(), + total_supply: 0, + balances: vec![], + allowances: vec![], + decimals: 18, + } + } +} diff --git a/examples/fungible-token/src/lib.rs b/examples/fungible-token/src/lib.rs index 14180236d8a..d464fc5b6d7 100644 --- a/examples/fungible-token/src/lib.rs +++ b/examples/fungible-token/src/lib.rs @@ -18,6 +18,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +pub use ft_io::*; + #[cfg(feature = "std")] mod code { include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); diff --git a/examples/wallets/Cargo.toml b/examples/wallets/Cargo.toml deleted file mode 100644 index b68a40dcad9..00000000000 --- a/examples/wallets/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "demo-wallets" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -gstd.workspace = true -parity-scale-codec.workspace = true -demo-wallets-io = { path = "io" } - -[build-dependencies] -demo-wallets-io = { path = "io" } -gear-wasm-builder.workspace = true - -[dev-dependencies] -gtest.workspace = true - -[features] -debug = ["gstd/debug"] -default = ["std"] -std = [] diff --git a/examples/wallets/build.rs b/examples/wallets/build.rs deleted file mode 100644 index bd6ee0ee6b9..00000000000 --- a/examples/wallets/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -fn main() { - gear_wasm_builder::build(); -} diff --git a/examples/wallets/io/Cargo.toml b/examples/wallets/io/Cargo.toml deleted file mode 100644 index b6873f42b96..00000000000 --- a/examples/wallets/io/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "demo-wallets-io" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -gstd.workspace = true -scale-info.workspace = true -parity-scale-codec.workspace = true diff --git a/examples/wallets/io/src/lib.rs b/examples/wallets/io/src/lib.rs deleted file mode 100644 index 861c2642186..00000000000 --- a/examples/wallets/io/src/lib.rs +++ /dev/null @@ -1,101 +0,0 @@ -#![no_std] - -extern crate alloc; - -use alloc::{string::String, vec, vec::Vec}; -use parity_scale_codec::{Decode, Encode}; -use scale_info::TypeInfo; - -// Metatypes for input and output -#[derive(TypeInfo, Default, Decode, Encode)] -pub struct MessageInitIn { - pub amount: u8, - pub currency: String, -} - -#[derive(TypeInfo, Decode, Encode)] -pub struct MessageInitOut { - pub exchange_rate: Result, - pub sum: u8, -} - -impl From for MessageInitOut { - fn from(other: MessageInitIn) -> Self { - let rate = match other.currency.as_ref() { - "USD" => Ok(2), - "EUR" => Ok(3), - _ => Err(1), - }; - - Self { - exchange_rate: rate, - sum: rate.unwrap_or(0) * other.amount, - } - } -} - -#[derive(TypeInfo, Decode, Encode)] -pub struct MessageIn { - pub id: Id, -} - -#[derive(TypeInfo, Decode, Encode)] -pub struct MessageOut { - pub res: Option, -} - -// Additional to primary types -#[derive(TypeInfo, Decode, Encode, Debug, PartialEq, Eq, Clone)] -pub struct Id { - pub decimal: u64, - pub hex: Vec, -} - -#[derive(TypeInfo, Decode, Encode, Clone, Debug, PartialEq, Eq)] -pub struct Person { - pub surname: String, - pub name: String, -} - -#[derive(TypeInfo, Decode, Encode, Clone, Debug, PartialEq)] -pub struct Wallet { - pub id: Id, - pub person: Person, -} - -impl Wallet { - pub fn test_sequence() -> Vec { - vec![ - Wallet { - id: Id { - decimal: 1, - hex: [1].to_vec(), - }, - person: Person { - surname: "SomeSurname".into(), - name: "SomeName".into(), - }, - }, - Wallet { - id: Id { - decimal: 2, - hex: [2].to_vec(), - }, - person: Person { - surname: "OtherSurname".into(), - name: "OtherName".into(), - }, - }, - ] - } -} - -#[derive(TypeInfo, Decode, Encode, Clone)] -pub struct MessageAsyncIn { - pub empty: (), -} - -#[derive(TypeInfo, Encode, Decode, Clone)] -pub struct MessageAsyncOut { - pub empty: (), -} diff --git a/examples/wallets/src/lib.rs b/examples/wallets/src/lib.rs deleted file mode 100644 index 03fbcfd3e87..00000000000 --- a/examples/wallets/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -// This file is part of Gear. - -// Copyright (C) 2021-2024 Gear Technologies Inc. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] - -// Reexport of types. -pub use demo_wallets_io::*; - -#[cfg(feature = "std")] -mod code { - include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -} - -#[cfg(feature = "std")] -pub use code::WASM_BINARY_OPT as WASM_BINARY; - -#[cfg(not(feature = "std"))] -pub const WASM_BINARY: &[u8] = &[]; - -#[cfg(not(feature = "std"))] -pub mod wasm; diff --git a/examples/wallets/src/wasm.rs b/examples/wallets/src/wasm.rs deleted file mode 100644 index 3b6cc18d711..00000000000 --- a/examples/wallets/src/wasm.rs +++ /dev/null @@ -1,41 +0,0 @@ -use demo_wallets_io::{MessageIn, MessageInitIn, MessageInitOut, MessageOut, Wallet}; -use gstd::{msg, prelude::*}; - -// State -static mut WALLETS: Vec = Vec::new(); - -// Init function -#[no_mangle] -extern "C" fn init() { - unsafe { WALLETS = Wallet::test_sequence() }; - - if msg::size() == 0 { - return; - } - - let message_init_in: MessageInitIn = msg::load().unwrap(); - let message_init_out: MessageInitOut = message_init_in.into(); - - msg::reply(message_init_out, 0).unwrap(); -} - -// Handle function -#[no_mangle] -extern "C" fn handle() { - let message_in: MessageIn = msg::load().unwrap(); - - let res = unsafe { &WALLETS } - .iter() - .find(|w| w.id.decimal == message_in.id.decimal) - .cloned(); - - let message_out = MessageOut { res }; - - msg::reply(message_out, 0).unwrap(); -} - -// State-sharing function -#[no_mangle] -extern "C" fn state() { - msg::reply(unsafe { WALLETS.clone() }, 0).expect("Failed to share state"); -} diff --git a/gcli/Cargo.toml b/gcli/Cargo.toml index 22b7cb89457..fdac98044e5 100644 --- a/gcli/Cargo.toml +++ b/gcli/Cargo.toml @@ -45,7 +45,7 @@ wasmer-types.workspace = true [dev-dependencies] rand.workspace = true demo-messenger.workspace = true -demo-wallets.workspace = true +demo-fungible-token.workspace = true demo-waiter.workspace = true gear-node-wrapper.workspace = true diff --git a/gcli/tests/cmd/upload.rs b/gcli/tests/cmd/upload.rs index b8235a7c3f1..dffdbcd9132 100644 --- a/gcli/tests/cmd/upload.rs +++ b/gcli/tests/cmd/upload.rs @@ -31,13 +31,14 @@ async fn test_command_upload_works() -> Result<()> { let signer = Api::new(node.ws().as_str()) .await? .signer("//Alice", None)?; - let code_id = CodeId::generate(demo_wallets::WASM_BINARY); + let code_id = CodeId::generate(demo_fungible_token::WASM_BINARY); assert!( signer.api().code_storage(code_id).await.is_err(), "code should not exist" ); - let output = node.run(Args::new("upload").program(env::wasm_bin("demo_wallets.opt.wasm")))?; + let output = + node.run(Args::new("upload").program(env::wasm_bin("demo_fungible_token.opt.wasm")))?; assert!( output .stderr @@ -60,7 +61,7 @@ async fn test_command_upload_code_works() -> Result<()> { let output = node.run( Args::new("upload") .flag("--code-only") - .program(env::wasm_bin("demo_wallets.opt.wasm")), + .program(env::wasm_bin("demo_fungible_token.opt.wasm")), )?; let stderr = output.stderr.convert(); diff --git a/gcli/tests/common/node.rs b/gcli/tests/common/node.rs index daedd307f70..69eadbbc17a 100644 --- a/gcli/tests/common/node.rs +++ b/gcli/tests/common/node.rs @@ -41,7 +41,7 @@ pub trait NodeExec { /// let node = Node::new(); /// let args = Args::new("upload") /// .flag("--code-only") - /// .program(env::wasm_bin("demo_wallets.opt.wasm")); + /// .program(env::wasm_bin("demo_fungible_token.opt.wasm")); /// let output = node.run(args) /// /// // ... diff --git a/gcli/tests/gear.rs b/gcli/tests/gear.rs index aa54b2917fe..6ece84e7f9d 100644 --- a/gcli/tests/gear.rs +++ b/gcli/tests/gear.rs @@ -27,7 +27,7 @@ fn paths() { [ env::node_bin(), env::bin("gcli"), - env::wasm_bin("demo_wallets.opt.wasm"), + env::wasm_bin("demo_fungible_token.opt.wasm"), ] .into_iter() .for_each(|path| { diff --git a/gclient/Cargo.toml b/gclient/Cargo.toml index 371ae2205b8..c7b637a92e5 100644 --- a/gclient/Cargo.toml +++ b/gclient/Cargo.toml @@ -39,8 +39,7 @@ demo-calc-hash-in-one-block.workspace = true demo-custom.workspace = true demo-constructor = { workspace = true, features = ["std"] } demo-distributor.workspace = true -demo-wallets.workspace = true -demo-wallets-io.workspace = true +demo-fungible-token.workspace = true demo-mul-by-const.workspace = true demo-node.workspace = true demo-program-factory.workspace = true diff --git a/gsdk/Cargo.toml b/gsdk/Cargo.toml index 07f39694447..097ea285b83 100644 --- a/gsdk/Cargo.toml +++ b/gsdk/Cargo.toml @@ -46,7 +46,7 @@ rand = { workspace = true, optional = true } gear-node-wrapper.workspace = true tokio = { workspace = true, features = ["full"] } demo-messenger.workspace = true -demo-wallets.workspace = true +demo-fungible-token.workspace = true demo-vec.workspace = true demo-waiter = { workspace = true, features = ["std"] } diff --git a/gsdk/tests/rpc.rs b/gsdk/tests/rpc.rs index b24d4511e66..f9e23b06c1a 100644 --- a/gsdk/tests/rpc.rs +++ b/gsdk/tests/rpc.rs @@ -361,7 +361,7 @@ async fn test_program_counters() -> Result<()> { #[tokio::test] async fn test_calculate_reply_for_handle() -> Result<()> { - use demo_wallets::{Id, MessageIn, MessageOut, Wallet, WASM_BINARY}; + use demo_fungible_token::{FTAction, FTEvent, InitConfig, WASM_BINARY}; let node = dev_node(); @@ -373,9 +373,11 @@ async fn test_calculate_reply_for_handle() -> Result<()> { .await? .signer("//Alice", None)?; + let payload = InitConfig::test_sequence().encode(); + signer .calls - .upload_program(WASM_BINARY.to_vec(), salt, vec![], 100_000_000_000, 0) + .upload_program(WASM_BINARY.to_vec(), salt, payload, 100_000_000_000, 0) .await?; assert!( @@ -383,19 +385,9 @@ async fn test_calculate_reply_for_handle() -> Result<()> { "Program not exists on chain." ); - let message_in = MessageIn { - id: Id { - decimal: 1, - hex: [1].to_vec(), - }, - }; + let message_in = FTAction::TotalSupply; - let message_out = MessageOut { - res: Wallet::test_sequence() - .iter() - .find(|w| w.id.decimal == message_in.id.decimal) - .cloned(), - }; + let message_out = FTEvent::TotalSupply(0); // 2. calculate reply for handle let reply_info = signer diff --git a/pallets/gear/Cargo.toml b/pallets/gear/Cargo.toml index 32d2076b22d..cc184ab23e7 100644 --- a/pallets/gear/Cargo.toml +++ b/pallets/gear/Cargo.toml @@ -82,7 +82,7 @@ demo-distributor.workspace = true demo-init-fail-sender.workspace = true demo-init-wait.workspace = true demo-init-wait-reply-exit.workspace = true -demo-wallets.workspace = true +demo-fungible-token.workspace = true demo-futures-unordered.workspace = true demo-program-factory.workspace = true demo-program-generator.workspace = true diff --git a/pallets/gear/src/tests.rs b/pallets/gear/src/tests.rs index 30a11c43c48..809ec068143 100644 --- a/pallets/gear/src/tests.rs +++ b/pallets/gear/src/tests.rs @@ -186,7 +186,7 @@ fn calculate_gas_results_in_finite_wait() { #[test] fn state_rpc_calls_trigger_reinstrumentation() { - use demo_wallets::{MessageInitIn, WASM_BINARY}; + use demo_fungible_token::{InitConfig, WASM_BINARY}; init_logger(); new_test_ext().execute_with(|| { @@ -195,7 +195,7 @@ fn state_rpc_calls_trigger_reinstrumentation() { RuntimeOrigin::signed(USER_2), WASM_BINARY.to_vec(), DEFAULT_SALT.to_vec(), - ::default().encode(), + InitConfig::test_sequence().encode(), DEFAULT_GAS_LIMIT * 100, 10_000, false, @@ -2581,7 +2581,7 @@ fn unstoppable_block_execution_works() { #[test] fn read_state_works() { - use demo_wallets::{MessageInitIn, Wallet, WASM_BINARY}; + use demo_fungible_token::{InitConfig, IoFungibleToken, WASM_BINARY}; init_logger(); new_test_ext().execute_with(|| { @@ -2589,7 +2589,7 @@ fn read_state_works() { RuntimeOrigin::signed(USER_2), WASM_BINARY.to_vec(), DEFAULT_SALT.to_vec(), - ::default().encode(), + InitConfig::test_sequence().encode(), DEFAULT_GAS_LIMIT * 100, 10_000, false, @@ -2601,7 +2601,7 @@ fn read_state_works() { assert!(Gear::is_initialized(program_id)); - let expected = Wallet::test_sequence().encode(); + let expected = IoFungibleToken::test_sequence().encode(); let res = Gear::read_state_impl(program_id, Default::default(), None) .expect("Failed to read state");