diff --git a/Cargo.lock b/Cargo.lock index a2ea2cce229..0c30bec4bb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4300,7 +4300,7 @@ version = "0.1.0" dependencies = [ "clap 4.3.19", "env_logger", - "futures-util", + "futures", "gsdk", "log", "parity-scale-codec", diff --git a/common/src/paused_program_storage.rs b/common/src/paused_program_storage.rs index 19e9275999c..8ff2ba57ef3 100644 --- a/common/src/paused_program_storage.rs +++ b/common/src/paused_program_storage.rs @@ -240,7 +240,8 @@ pub trait PausedProgramStorage: super::ProgramStorage { None => return Err(Self::InternalError::resume_session_not_found().into()), }; - let Some((_block_number, hash)) = Self::PausedProgramMap::get(&session.program_id) else { + let Some((_block_number, hash)) = Self::PausedProgramMap::get(&session.program_id) + else { let result = ResumeResult { end_block: session.end_block, info: None, @@ -250,7 +251,7 @@ pub trait PausedProgramStorage: super::ProgramStorage { Self::SessionMemoryPages::remove(session_id); *maybe_session = None; - return Ok(result) + return Ok(result); }; if !Self::CodeStorage::exists(session.code_hash) { diff --git a/core/src/code.rs b/core/src/code.rs index c45d0f228c7..1069659c8c7 100644 --- a/core/src/code.rs +++ b/core/src/code.rs @@ -127,7 +127,8 @@ fn get_global_init_const_i32(module: &Module, global_index: u32) -> Result Result<(), CodeError> { - let Some(&stack_end_global_index) = get_export_global_index(module, STACK_END_EXPORT_NAME) else { + let Some(&stack_end_global_index) = get_export_global_index(module, STACK_END_EXPORT_NAME) + else { return Ok(()); }; let stack_end_offset = get_global_init_const_i32(module, stack_end_global_index)?; diff --git a/examples/constructor/src/call.rs b/examples/constructor/src/call.rs index 3c768ea91da..c3264e5ac90 100644 --- a/examples/constructor/src/call.rs +++ b/examples/constructor/src/call.rs @@ -59,7 +59,9 @@ mod wasm { // TODO: expand to be able store mid and pid separately. fn create_program(self) -> Option> { - let Self::CreateProgram(code_id, salt, payload, gas_limit, value, delay) = self else { unreachable!() }; + let Self::CreateProgram(code_id, salt, payload, gas_limit, value, delay) = self else { + unreachable!() + }; let code_id = code_id.value().into(); let salt = salt.value(); @@ -86,7 +88,9 @@ mod wasm { } fn reply_deposit(self) -> Option> { - let Self::ReplyDeposit(message_id, gas_limit) = self else { unreachable!() }; + let Self::ReplyDeposit(message_id, gas_limit) = self else { + unreachable!() + }; let message_id = message_id.value().into(); let gas_limit = gas_limit.value(); @@ -129,13 +133,17 @@ mod wasm { } fn store(self, previous: Option) -> Option> { - let Self::Store(key) = self.clone() else { unreachable!() }; + let Self::Store(key) = self.clone() else { + unreachable!() + }; self.store_impl(key, previous, false) } fn store_vec(self, previous: Option) -> Option> { - let Self::StoreVec(key) = self.clone() else { unreachable!() }; + let Self::StoreVec(key) = self.clone() else { + unreachable!() + }; self.store_impl(key, previous, true) } @@ -157,7 +165,9 @@ mod wasm { } fn panic(self) -> ! { - let Self::Panic(msg) = self else { unreachable!() }; + let Self::Panic(msg) = self else { + unreachable!() + }; if let Some(msg) = msg { panic!("{msg}"); @@ -167,7 +177,9 @@ mod wasm { } fn send(self) -> Option> { - let Self::Send(destination, payload, gas_limit, value, delay) = self else { unreachable!() }; + let Self::Send(destination, payload, gas_limit, value, delay) = self else { + unreachable!() + }; let destination = destination.value().into(); let payload = payload.value(); @@ -192,7 +204,9 @@ mod wasm { } fn reply(self) -> Option> { - let Self::Reply(payload, gas_limit, value) = self else { unreachable!() }; + let Self::Reply(payload, gas_limit, value) = self else { + unreachable!() + }; let payload = payload.value(); let value = value.value(); @@ -209,7 +223,9 @@ mod wasm { } fn exit(self) -> ! { - let Self::Exit(inheritor) = self else { unreachable!() }; + let Self::Exit(inheritor) = self else { + unreachable!() + }; let inheritor = inheritor.value().into(); @@ -217,7 +233,9 @@ mod wasm { } fn bytes_eq(self) -> Option> { - let Self::BytesEq(left, right) = self else { unreachable!() }; + let Self::BytesEq(left, right) = self else { + unreachable!() + }; let left = left.value(); let right = right.value(); @@ -226,7 +244,9 @@ mod wasm { } fn if_else(self, previous: Option) -> Option> { - let Self::IfElse(flag, true_call, false_call) = self else { unreachable!() }; + let Self::IfElse(flag, true_call, false_call) = self else { + unreachable!() + }; let flag = flag.value(); @@ -262,7 +282,9 @@ mod wasm { } fn wake(self) -> Option> { - let Self::Wake(message_id) = self else { unreachable!() }; + let Self::Wake(message_id) = self else { + unreachable!() + }; let message_id = message_id.value().into(); diff --git a/gclient/src/api/calls.rs b/gclient/src/api/calls.rs index f8b95e77360..a912d4a73e6 100644 --- a/gclient/src/api/calls.rs +++ b/gclient/src/api/calls.rs @@ -49,7 +49,7 @@ use gsdk::{ utility::Event as UtilityEvent, Convert, Event, }, - types, Error as GsdkError, + Error as GsdkError, GearGasNode, GearGasNodeId, }; use hex::ToHex; use parity_scale_codec::{Decode, Encode}; @@ -306,7 +306,7 @@ impl GearApi { .gpages_at(src_program_id, &src_program, src_block_hash) .await?; - let src_program_reserved_gas_node_ids: Vec = src_program + let src_program_reserved_gas_node_ids: Vec = src_program .gas_reservation_map .iter() .map(|gr| gr.0.into()) @@ -321,7 +321,7 @@ impl GearApi { let mut src_program_reserved_gas_total = 0u64; let mut accounts_with_reserved_funds = HashSet::new(); for gas_node in &src_program_reserved_gas_nodes { - if let types::GearGasNode::Reserved { + if let GearGasNode::Reserved { id, value, lock, .. } = &gas_node.1 { diff --git a/gclient/src/api/listener/iterator.rs b/gclient/src/api/listener/iterator.rs index 982e218f10a..8e42252fc75 100644 --- a/gclient/src/api/listener/iterator.rs +++ b/gclient/src/api/listener/iterator.rs @@ -23,7 +23,7 @@ use gsdk::{ config::GearConfig, ext::sp_core::H256, metadata::{gear::Event as GearEvent, Event}, - types::Blocks, + Blocks, }; use subxt::events::Events; diff --git a/gclient/src/api/listener/subscription.rs b/gclient/src/api/listener/subscription.rs index 5dbeadc4017..9b50614c90d 100644 --- a/gclient/src/api/listener/subscription.rs +++ b/gclient/src/api/listener/subscription.rs @@ -19,10 +19,10 @@ use super::EventProcessor; use crate::{Error, Result}; use async_trait::async_trait; -use gsdk::metadata::{gear_runtime::RuntimeEvent, Event}; +use gsdk::Event; #[async_trait(?Send)] -impl + Clone> EventProcessor for I { +impl + Clone> EventProcessor for I { fn not_waited() -> Error { Error::EventNotFoundInIterator } diff --git a/gclient/src/api/rpc.rs b/gclient/src/api/rpc.rs index 630b8830624..5f0e67ec612 100644 --- a/gclient/src/api/rpc.rs +++ b/gclient/src/api/rpc.rs @@ -19,7 +19,7 @@ use crate::{api::Result, GearApi}; use gear_core::ids::{CodeId, MessageId, ProgramId}; -use gsdk::{ext::sp_core::H256, types::GasInfo}; +use gsdk::{ext::sp_core::H256, GasInfo}; use parity_scale_codec::{Decode, Encode}; use std::path::Path; diff --git a/gmeta/codegen/src/lib.rs b/gmeta/codegen/src/lib.rs index 489d3499a78..e971c8616de 100644 --- a/gmeta/codegen/src/lib.rs +++ b/gmeta/codegen/src/lib.rs @@ -191,7 +191,7 @@ fn process(module: ItemMod) -> Result { let Some((_, items)) = module.content else { return error( module_span, - "`#[metawasm]` doesn't work with modules without a body" + "`#[metawasm]` doesn't work with modules without a body", ); }; @@ -252,7 +252,7 @@ fn process(module: ItemMod) -> Result { let Item::Fn(function) = potential_function else { return error( potential_function, - "rest of items in a module with `#[metawasm]` must be functions" + "rest of items in a module with `#[metawasm]` must be functions", ); }; diff --git a/gsdk/src/api.rs b/gsdk/src/api.rs new file mode 100644 index 00000000000..6826e76d276 --- /dev/null +++ b/gsdk/src/api.rs @@ -0,0 +1,115 @@ +// This file is part of Gear. +// +// Copyright (C) 2021-2023 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 crate::{client::RpcClient, config::GearConfig, signer::Signer, Blocks, Events, Result}; +use core::ops::{Deref, DerefMut}; +use std::sync::Arc; +use subxt::OnlineClient; + +/// Gear api wrapper. +#[derive(Clone)] +pub struct Api { + /// How many times we'll retry when rpc requests failed. + pub retry: u16, + client: OnlineClient, +} + +impl Api { + /// Create new API client. + pub async fn new(url: Option<&str>) -> Result { + Self::new_with_timeout(url, None).await + } + + /// Create new API client with timeout. + pub async fn new_with_timeout(url: Option<&str>, timeout: Option) -> Result { + Ok(Self { + // Retry our failed RPC requests for 5 times by default. + retry: 5, + client: OnlineClient::from_rpc_client(Arc::new(RpcClient::new(url, timeout).await?)) + .await?, + }) + } + + /// Setup retry times and return the API instance. + pub fn with_retry(mut self, retry: u16) -> Self { + self.retry = retry; + self + } + + /// Subscribe all blocks + /// + /// + /// ```ignore + /// let api = Api::new(None).await?; + /// let blocks = api.blocks().await?; + /// + /// while let Ok(block) = blocks.next().await { + /// // ... + /// } + /// ``` + pub async fn blocks(&self) -> Result { + Ok(self.client.blocks().subscribe_all().await?.into()) + } + + /// Subscribe finalized blocks + /// + /// Same as `blocks` but only finalized blocks. + pub async fn finalized_blocks(&self) -> Result { + Ok(self.client.blocks().subscribe_finalized().await?.into()) + } + + /// Subscribe all events. + /// + /// ```ignore + /// let api = Api::new(None).await?; + /// let events = api.events().await?; + /// + /// while let Ok(evs) = events.next().await { + /// // ... + /// } + /// ``` + pub async fn events(&self) -> Result { + Ok(self.client.blocks().subscribe_all().await?.into()) + } + + /// Subscribe finalized events + /// + /// Same as `events` but only finalized events. + pub async fn finalized_events(&self) -> Result { + Ok(self.client.blocks().subscribe_finalized().await?.into()) + } + + /// New signer from api + pub fn signer(self, suri: &str, passwd: Option<&str>) -> Result { + Signer::new(self, suri, passwd) + } +} + +impl Deref for Api { + type Target = OnlineClient; + + fn deref(&self) -> &Self::Target { + &self.client + } +} + +impl DerefMut for Api { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.client + } +} diff --git a/gsdk/src/lib.rs b/gsdk/src/lib.rs index c479ae28c6a..1bbf37d138f 100644 --- a/gsdk/src/lib.rs +++ b/gsdk/src/lib.rs @@ -17,17 +17,32 @@ // along with this program. If not, see . //! Gear api -use client::RpcClient; -use config::GearConfig; -use core::ops::{Deref, DerefMut}; -pub use result::{Error, Result}; -pub use signer::PairSigner; -use signer::Signer; -use std::sync::Arc; +pub use crate::{ + api::Api, + metadata::Event, + result::{Error, Result}, + signer::PairSigner, + subscription::{Blocks, Events}, +}; +use crate::{ + config::GearConfig, + metadata::runtime_types::gear_common::{ + gas_provider::node::{GasNode, GasNodeId}, + ActiveProgram, + }, +}; +use gear_core::ids::{MessageId, ReservationId}; +use parity_scale_codec::{Decode, Encode}; +use serde::{Deserialize, Serialize}; +use sp_runtime::AccountId32; +use std::collections::HashMap; pub use subxt::dynamic::Value; -use subxt::OnlineClient; -pub mod testing; +use subxt::{ + tx::{TxInBlock as SubxtTxInBlock, TxStatus as SubxtTxStatus}, + OnlineClient, +}; +mod api; mod client; pub mod config; mod constants; @@ -37,8 +52,10 @@ pub mod result; mod rpc; pub mod signer; mod storage; -pub mod types; +pub mod subscription; +pub mod testing; mod utils; + pub mod ext { pub use sp_core; pub use sp_runtime::{self, codec, scale_info}; @@ -51,84 +68,41 @@ pub mod gp { }; } +/// Block number type pub type BlockNumber = u32; -/// Gear api wrapper. -#[derive(Clone)] -pub struct Api { - /// How many times we'll retry when rpc requests failed. - pub retry: u16, - client: OnlineClient, +/// Information of gas +#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, Serialize, Deserialize)] +pub struct GasInfo { + /// Represents minimum gas limit required for execution. + pub min_limit: u64, + /// Gas amount that we reserve for some other on-chain interactions. + pub reserved: u64, + /// Contains number of gas burned during message processing. + pub burned: u64, } -impl Api { - /// Create new API client. - pub async fn new(url: Option<&str>) -> Result { - Self::new_with_timeout(url, None).await - } +/// Gear gas node id. +pub type GearGasNodeId = GasNodeId; - /// Create new API client with timeout. - pub async fn new_with_timeout(url: Option<&str>, timeout: Option) -> Result { - Ok(Self { - // Retry our failed RPC requests for 5 times by default. - retry: 5, - client: OnlineClient::from_rpc_client(Arc::new(RpcClient::new(url, timeout).await?)) - .await?, - }) - } +/// Gear gas node. +pub type GearGasNode = GasNode; - /// Setup retry times and return the API instance. - pub fn with_retry(mut self, retry: u16) -> Self { - self.retry = retry; - self - } +/// Gear pages. +pub type GearPages = HashMap>; - /// Subscribe all blocks - /// - /// # Parse events from blocks - /// - /// ```ignore - /// use gsdk::metadata::{Event, system}; - /// - /// let api = Api::new(None).await?; - /// let mut blocks = api.blocks().await?; - /// - /// while let Some(Ok(events)) = blocks.next_events().await { - /// for event in events { - /// let ev = event.as_root_event::(); - /// - /// // Match events here. - /// matches!(ev, Event::System(system::Event::ExtrinsicSuccess(_))); - /// } - /// } - /// ``` - pub async fn blocks(&self) -> Result { - Ok(types::Blocks(self.client.blocks().subscribe_all().await?)) - } +/// Transaction in block. +pub type TxInBlock = SubxtTxInBlock>; - /// Subscribe finalized blocks - pub async fn finalized_blocks(&self) -> Result { - Ok(types::Blocks( - self.client.blocks().subscribe_finalized().await?, - )) - } +/// Transaction in block with result wrapper. +pub type TxInBlockResult = Result; - /// New signer from api - pub fn signer(self, suri: &str, passwd: Option<&str>) -> Result { - Signer::new(self, suri, passwd) - } -} - -impl Deref for Api { - type Target = OnlineClient; - - fn deref(&self) -> &Self::Target { - &self.client - } -} +/// Transaction status. +pub type TxStatus = SubxtTxStatus>; -impl DerefMut for Api { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.client - } +/// Gear Program +#[derive(Debug, Decode)] +pub enum Program { + Active(ActiveProgram), + Terminated, } diff --git a/gsdk/src/result.rs b/gsdk/src/result.rs index a430c382e69..a70041e23bb 100644 --- a/gsdk/src/result.rs +++ b/gsdk/src/result.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . //! GSdk Results -use crate::types::TxStatus; +use crate::TxStatus; use sp_core::H256; /// Transaction Errors diff --git a/gsdk/src/rpc.rs b/gsdk/src/rpc.rs index f704242e788..12c7d4d7948 100644 --- a/gsdk/src/rpc.rs +++ b/gsdk/src/rpc.rs @@ -16,9 +16,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! gear api rpc methods -#![allow(clippy::too_many_arguments)] -use crate::{result::Result, types::GasInfo, Api}; +//! Gear API RPC methods + +use crate::{result::Result, Api, GasInfo}; use gear_core::ids::{CodeId, MessageId, ProgramId}; use sp_core::H256; use subxt::rpc::rpc_params; diff --git a/gsdk/src/signer/calls.rs b/gsdk/src/signer/calls.rs index 901a41a928e..80479d3306f 100644 --- a/gsdk/src/signer/calls.rs +++ b/gsdk/src/signer/calls.rs @@ -33,9 +33,8 @@ use crate::{ Event, }, signer::Signer, - types::{self, InBlock, TxStatus}, utils::storage_address_bytes, - Api, BlockNumber, Error, + Api, BlockNumber, Error, GearGasNode, GearGasNodeId, GearPages, Result, TxInBlock, TxStatus, }; use anyhow::anyhow; use gear_core::{ @@ -61,7 +60,7 @@ type EventsResult = Result, Error>; // pallet-balances impl Signer { /// `pallet_balances::transfer` - pub async fn transfer(&self, dest: impl Into, value: u128) -> InBlock { + pub async fn transfer(&self, dest: impl Into, value: u128) -> Result { self.run_tx( BalancesCall::Transfer, vec![ @@ -83,7 +82,7 @@ impl Signer { payload: Vec, gas_limit: u64, value: u128, - ) -> InBlock { + ) -> Result { self.run_tx( GearCall::CreateProgram, vec![ @@ -98,7 +97,7 @@ impl Signer { } /// `pallet_gear::claim_value` - pub async fn claim_value(&self, message_id: MessageId) -> InBlock { + pub async fn claim_value(&self, message_id: MessageId) -> Result { self.run_tx(GearCall::ClaimValue, vec![Value::from_bytes(message_id)]) .await } @@ -110,7 +109,7 @@ impl Signer { payload: Vec, gas_limit: u64, value: u128, - ) -> InBlock { + ) -> Result { self.run_tx( GearCall::SendMessage, vec![ @@ -130,7 +129,7 @@ impl Signer { payload: Vec, gas_limit: u64, value: u128, - ) -> InBlock { + ) -> Result { self.run_tx( GearCall::SendReply, vec![ @@ -144,7 +143,7 @@ impl Signer { } /// `pallet_gear::upload_code` - pub async fn upload_code(&self, code: Vec) -> InBlock { + pub async fn upload_code(&self, code: Vec) -> Result { self.run_tx(GearCall::UploadCode, vec![Value::from_bytes(code)]) .await } @@ -157,7 +156,7 @@ impl Signer { payload: Vec, gas_limit: u64, value: u128, - ) -> InBlock { + ) -> Result { self.run_tx( GearCall::UploadProgram, vec![ @@ -175,7 +174,7 @@ impl Signer { // pallet-utility impl Signer { /// `pallet_utility::force_batch` - pub async fn force_batch(&self, calls: Vec) -> InBlock { + pub async fn force_batch(&self, calls: Vec) -> Result { self.run_tx( UtilityCall::ForceBatch, vec![calls.into_iter().map(Value::from).collect::>()], @@ -261,7 +260,7 @@ impl Signer { /// Writes Gear gas nodes into storage at their ids. pub async fn set_gas_nodes( &self, - gas_nodes: &impl AsRef<[(types::GearGasNodeId, types::GearGasNode)]>, + gas_nodes: &impl AsRef<[(GearGasNodeId, GearGasNode)]>, ) -> EventsResult { let gas_nodes = gas_nodes.as_ref(); let mut gas_nodes_to_set = Vec::with_capacity(gas_nodes.len()); @@ -297,7 +296,7 @@ impl Signer { pub async fn set_gpages( &self, program_id: ProgramId, - program_pages: &types::GearPages, + program_pages: &GearPages, ) -> EventsResult { let mut program_pages_to_set = Vec::with_capacity(program_pages.len()); for program_page in program_pages { @@ -376,7 +375,7 @@ impl Signer { } /// Listen transaction process and print logs. - pub async fn process<'a>(&self, tx: DynamicPayload) -> InBlock { + pub async fn process<'a>(&self, tx: DynamicPayload) -> Result { use subxt::tx::TxStatus::*; let before = self.balance().await?; diff --git a/gsdk/src/signer/rpc.rs b/gsdk/src/signer/rpc.rs index a3bf58404cd..6fa642be1c1 100644 --- a/gsdk/src/signer/rpc.rs +++ b/gsdk/src/signer/rpc.rs @@ -17,8 +17,8 @@ // along with this program. If not, see . //! RPC calls with signer -#![allow(clippy::too_many_arguments)] -use crate::{result::Result, signer::Signer, types::GasInfo}; + +use crate::{result::Result, signer::Signer, GasInfo}; use gear_core::ids::{CodeId, MessageId, ProgramId}; use sp_core::H256; diff --git a/gsdk/src/signer/utils.rs b/gsdk/src/signer/utils.rs index 954231b6f31..e815cf92efc 100644 --- a/gsdk/src/signer/utils.rs +++ b/gsdk/src/signer/utils.rs @@ -19,7 +19,7 @@ //! Utils use crate::{ - config::GearConfig, metadata::CallInfo, result::Result, signer::Signer, types::InBlock, Error, + config::GearConfig, metadata::CallInfo, result::Result, signer::Signer, Error, TxInBlock, }; use scale_value::Composite; use subxt::blocks::ExtrinsicEvents; @@ -83,7 +83,7 @@ impl Signer { &self, call: Call, fields: impl Into>, - ) -> InBlock { + ) -> Result { let tx = subxt::dynamic::tx(Call::PALLET, call.call_name(), fields.into()); self.process(tx).await diff --git a/gsdk/src/storage.rs b/gsdk/src/storage.rs index 780dd747dc7..974787f026e 100644 --- a/gsdk/src/storage.rs +++ b/gsdk/src/storage.rs @@ -32,9 +32,8 @@ use crate::{ }, }, result::{Error, Result}, - types, utils::storage_address_bytes, - Api, BlockNumber, + Api, BlockNumber, GearGasNode, GearGasNodeId, GearPages, }; use anyhow::anyhow; use gear_core::ids::*; @@ -108,7 +107,7 @@ impl Api { } /// Get program pages from program id. - pub async fn program_pages(&self, pid: ProgramId) -> Result { + pub async fn program_pages(&self, pid: ProgramId) -> Result { let program = self.gprog(pid).await?; self.gpages(pid, &program).await } @@ -183,9 +182,9 @@ impl Api { #[storage_fetch] pub async fn gas_nodes_at( &self, - gas_node_ids: &impl AsRef<[types::GearGasNodeId]>, + gas_node_ids: &impl AsRef<[GearGasNodeId]>, block_hash: Option, - ) -> Result> { + ) -> Result> { let gas_node_ids = gas_node_ids.as_ref(); let mut gas_nodes = Vec::with_capacity(gas_node_ids.len()); @@ -299,7 +298,7 @@ impl Api { program_id: ProgramId, program: &ActiveProgram, block_hash: Option, - ) -> Result { + ) -> Result { let mut pages = HashMap::new(); for page in &program.pages_with_data { diff --git a/gsdk/src/subscription.rs b/gsdk/src/subscription.rs new file mode 100644 index 00000000000..2d0d18f72fb --- /dev/null +++ b/gsdk/src/subscription.rs @@ -0,0 +1,84 @@ +// This file is part of Gear. +// +// Copyright (C) 2021-2023 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 . + +//! Subscription implementation. + +use crate::{config::GearConfig, metadata::Event}; +use futures::{Stream, StreamExt}; +use std::{marker::Unpin, pin::Pin, result::Result as StdResult, task::Poll}; +use subxt::{blocks::Block, events::Events as SubxtEvents, Error, OnlineClient}; + +type SubxtBlock = Block>; +type BlockSubscription = Pin> + Send>>; + +/// Subscription of finalized blocks. +pub struct Blocks(BlockSubscription); + +impl Unpin for Blocks {} + +impl Stream for Blocks { + type Item = StdResult; + + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let res = futures::ready!(self.0.poll_next_unpin(cx)); + + Poll::Ready(res) + } +} + +impl Blocks { + /// Wait for the next block from the subscription. + pub async fn next_events(&mut self) -> Option, Error>> { + if let Some(block) = StreamExt::next(self).await { + Some(block.ok()?.events().await) + } else { + None + } + } +} + +impl From for Blocks { + fn from(sub: BlockSubscription) -> Self { + Self(sub) + } +} + +/// Subscription of events. +pub struct Events(Blocks); + +impl Events { + /// Wait for the next events from the subscription. + pub async fn next(&mut self) -> Option, Error>> { + self.0.next_events().await.map(|r| { + r.and_then(|es| { + es.iter() + .map(|ev| ev.and_then(|e| e.as_root_event::())) + .collect::, Error>>() + }) + }) + } +} + +impl From for Events { + fn from(sub: BlockSubscription) -> Self { + Self(sub.into()) + } +} diff --git a/gsdk/src/types.rs b/gsdk/src/types.rs deleted file mode 100644 index ffedb789b53..00000000000 --- a/gsdk/src/types.rs +++ /dev/null @@ -1,104 +0,0 @@ -// This file is part of Gear. -// -// Copyright (C) 2021-2023 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 . - -//! Shared types -use crate::{ - config::GearConfig, - metadata::runtime_types::gear_common::{ - gas_provider::node::{GasNode, GasNodeId}, - ActiveProgram, - }, - result::Result, - BlockNumber, -}; -use futures::{Stream, StreamExt}; -use gear_core::ids::*; -use parity_scale_codec::{Decode, Encode}; -use serde::{Deserialize, Serialize}; -use sp_runtime::AccountId32; -use std::{collections::HashMap, marker::Unpin, pin::Pin, result::Result as StdResult, task::Poll}; -use subxt::{ - blocks::Block, - events::Events, - tx::{self, TxInBlock}, - Error, OnlineClient, -}; - -type SubxtBlock = Block>; - -/// Subscription of finalized blocks. -pub struct Blocks(pub Pin> + Send>>); - -impl Unpin for Blocks {} - -impl Stream for Blocks { - type Item = StdResult>, Error>; - - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> Poll> { - let res = futures::ready!(self.0.poll_next_unpin(cx)); - - Poll::Ready(res) - } -} - -impl Blocks { - /// Wait for the next item from the subscription. - pub async fn next_events(&mut self) -> Option, Error>> { - if let Some(block) = StreamExt::next(self).await { - Some(block.ok()?.events().await) - } else { - None - } - } -} - -/// Information of gas -#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, Serialize, Deserialize)] -pub struct GasInfo { - /// Represents minimum gas limit required for execution. - pub min_limit: u64, - /// Gas amount that we reserve for some other on-chain interactions. - pub reserved: u64, - /// Contains number of gas burned during message processing. - pub burned: u64, -} - -/// Gear gas node id. -pub type GearGasNodeId = GasNodeId; - -/// Gear gas node. -pub type GearGasNode = GasNode; - -/// Gear pages. -pub type GearPages = HashMap>; - -/// Transaction in block. -pub type InBlock = Result>>; - -/// Transaction status. -pub type TxStatus = tx::TxStatus>; - -/// Gear Program -#[derive(Debug, Decode)] -pub enum Program { - Active(ActiveProgram), - Terminated, -} diff --git a/node/service/src/rpc/runtime_info.rs b/node/service/src/rpc/runtime_info.rs index e5350a5738a..d7d02c8b96a 100644 --- a/node/service/src/rpc/runtime_info.rs +++ b/node/service/src/rpc/runtime_info.rs @@ -71,13 +71,20 @@ where &sp_storage::StorageKey(sp_core::storage::well_known_keys::CODE.into()), ) .map_err(map_err_into_rpc_err)?; - let Some(wasm_blob_data) = wasm_blob_data else { return Err(rpc_err("Unable to find WASM blob in storage", None)); }; + let Some(wasm_blob_data) = wasm_blob_data else { + return Err(rpc_err("Unable to find WASM blob in storage", None)); + }; let wasm_runtime_blob = RuntimeBlob::uncompress_if_needed(&wasm_blob_data.0).map_err(map_err_into_rpc_err)?; let wasm_blob_version = wasm_runtime_blob.custom_section_contents("wasm_blob_version"); - let Some(wasm_blob_version) = wasm_blob_version else { return Err(rpc_err("Unable to find WASM blob version in WASM blob", None)); }; + let Some(wasm_blob_version) = wasm_blob_version else { + return Err(rpc_err( + "Unable to find WASM blob version in WASM blob", + None, + )); + }; let wasm_blob_version = String::from_utf8(wasm_blob_version.into()).map_err(map_err_into_rpc_err)?; diff --git a/pallets/gear-debug/src/tests.rs b/pallets/gear-debug/src/tests.rs index 644bf47ddb7..2fb9e2fca10 100644 --- a/pallets/gear-debug/src/tests.rs +++ b/pallets/gear-debug/src/tests.rs @@ -104,16 +104,21 @@ fn vec() { let program_details = &snapshot.programs[0]; assert_eq!(program_details.id, vec_id); - let crate::ProgramState::Active(ref program_info) = program_details.state else { panic!("Inactive program") }; + let crate::ProgramState::Active(ref program_info) = program_details.state else { + panic!("Inactive program") + }; assert_eq!(program_info.code_hash, code_id.into_origin()); - let pages = program_info.persistent_pages.keys().fold(BTreeSet::new(), |mut set, page| { - let page = page.to_page::().raw(); - if page >= static_pages { - set.insert(page); - } - set - }); + let pages = program_info + .persistent_pages + .keys() + .fold(BTreeSet::new(), |mut set, page| { + let page = page.to_page::().raw(); + if page >= static_pages { + set.insert(page); + } + set + }); let pages = pages.into_iter().collect::>(); assert_eq!(pages, vec![17, 18]); diff --git a/pallets/gear/src/manager/task.rs b/pallets/gear/src/manager/task.rs index 5f27762f3d1..75cda3d6b78 100644 --- a/pallets/gear/src/manager/task.rs +++ b/pallets/gear/src/manager/task.rs @@ -51,8 +51,9 @@ where let Some(init_message_id) = program.is_uninitialized() else { // pause initialized program - let gas_reservation_map = ProgramStorageOf::::pause_program(program_id, Pallet::::block_number()) - .unwrap_or_else(|e| unreachable!("Failed to pause program: {:?}", e)); + let gas_reservation_map = + ProgramStorageOf::::pause_program(program_id, Pallet::::block_number()) + .unwrap_or_else(|e| unreachable!("Failed to pause program: {:?}", e)); // clean wait list from the messages let reason = MessageWokenSystemReason::ProgramGotInitialized.into_reason(); diff --git a/pallets/gear/src/runtime_api.rs b/pallets/gear/src/runtime_api.rs index b3efd92ede1..3b5b005352a 100644 --- a/pallets/gear/src/runtime_api.rs +++ b/pallets/gear/src/runtime_api.rs @@ -124,8 +124,11 @@ where ); } - let Some(queued_dispatch) = QueueOf::::dequeue() - .map_err(|_| b"MQ storage corrupted".to_vec())? else { break; }; + let Some(queued_dispatch) = + QueueOf::::dequeue().map_err(|_| b"MQ storage corrupted".to_vec())? + else { + break; + }; let actor_id = queued_dispatch.destination(); diff --git a/utils/validator-checks/Cargo.toml b/utils/validator-checks/Cargo.toml index dc991c8ab55..346637e4353 100644 --- a/utils/validator-checks/Cargo.toml +++ b/utils/validator-checks/Cargo.toml @@ -12,7 +12,7 @@ gsdk.workspace = true clap = { workspace = true, features = ["derive"] } subxt.workspace = true thiserror.workspace = true -futures-util.workspace = true +futures.workspace = true log.workspace = true env_logger.workspace = true tokio = { workspace = true, features = [ "full" ] } diff --git a/utils/validator-checks/src/listener.rs b/utils/validator-checks/src/listener.rs index ae004684f02..edb3d1a0091 100644 --- a/utils/validator-checks/src/listener.rs +++ b/utils/validator-checks/src/listener.rs @@ -4,14 +4,13 @@ use crate::{ cmd::Opt, result::{Error, Result}, }; -use futures_util::StreamExt; +use futures::StreamExt; use gsdk::{ ext::{ sp_core::crypto::{PublicError, Ss58Codec}, sp_runtime::AccountId32, }, - types::Blocks, - Api, + Api, Blocks, }; use std::{result::Result as StdResult, time::Instant}; diff --git a/utils/wasm-builder/src/stack_end.rs b/utils/wasm-builder/src/stack_end.rs index 0a0490161dc..529ec48fd52 100644 --- a/utils/wasm-builder/src/stack_end.rs +++ b/utils/wasm-builder/src/stack_end.rs @@ -109,9 +109,9 @@ pub fn insert_start_call_in_export_funcs(module: &mut Module) -> Result<(), &'st .ok_or("Cannot find export section")? .entries() .iter() - .find(|export| export.field() == export_name) else - { - continue + .find(|export| export.field() == export_name) + else { + continue; }; let index = match export.internal() {