Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gsdk): introduce events API #2979

Merged
merged 12 commits into from
Aug 10, 2023
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions common/src/paused_program_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion core/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ fn get_global_init_const_i32(module: &Module, global_index: u32) -> Result<i32,
}

fn check_and_canonize_gear_stack_end(module: &mut Module) -> 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)?;
Expand Down
44 changes: 33 additions & 11 deletions examples/constructor/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ mod wasm {

// TODO: expand to be able store mid and pid separately.
fn create_program(self) -> Option<Vec<u8>> {
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();
Expand All @@ -86,7 +88,9 @@ mod wasm {
}

fn reply_deposit(self) -> Option<Vec<u8>> {
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();
Expand Down Expand Up @@ -129,13 +133,17 @@ mod wasm {
}

fn store(self, previous: Option<CallResult>) -> Option<Vec<u8>> {
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<CallResult>) -> Option<Vec<u8>> {
let Self::StoreVec(key) = self.clone() else { unreachable!() };
let Self::StoreVec(key) = self.clone() else {
unreachable!()
};

self.store_impl(key, previous, true)
}
Expand All @@ -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}");
Expand All @@ -167,7 +177,9 @@ mod wasm {
}

fn send(self) -> Option<Vec<u8>> {
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();
Expand All @@ -192,7 +204,9 @@ mod wasm {
}

fn reply(self) -> Option<Vec<u8>> {
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();
Expand All @@ -209,15 +223,19 @@ mod wasm {
}

fn exit(self) -> ! {
let Self::Exit(inheritor) = self else { unreachable!() };
let Self::Exit(inheritor) = self else {
unreachable!()
};

let inheritor = inheritor.value().into();

exec::exit(inheritor)
}

fn bytes_eq(self) -> Option<Vec<u8>> {
let Self::BytesEq(left, right) = self else { unreachable!() };
let Self::BytesEq(left, right) = self else {
unreachable!()
};

let left = left.value();
let right = right.value();
Expand All @@ -226,7 +244,9 @@ mod wasm {
}

fn if_else(self, previous: Option<CallResult>) -> Option<Vec<u8>> {
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();

Expand Down Expand Up @@ -262,7 +282,9 @@ mod wasm {
}

fn wake(self) -> Option<Vec<u8>> {
let Self::Wake(message_id) = self else { unreachable!() };
let Self::Wake(message_id) = self else {
unreachable!()
};

let message_id = message_id.value().into();

Expand Down
6 changes: 3 additions & 3 deletions gclient/src/api/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<types::GearGasNodeId> = src_program
let src_program_reserved_gas_node_ids: Vec<GearGasNodeId> = src_program
.gas_reservation_map
.iter()
.map(|gr| gr.0.into())
Expand All @@ -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
{
Expand Down
2 changes: 1 addition & 1 deletion gclient/src/api/listener/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions gclient/src/api/listener/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<I: IntoIterator<Item = RuntimeEvent> + Clone> EventProcessor for I {
impl<I: IntoIterator<Item = Event> + Clone> EventProcessor for I {
fn not_waited() -> Error {
Error::EventNotFoundInIterator
}
Expand Down
2 changes: 1 addition & 1 deletion gclient/src/api/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions gmeta/codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ fn process(module: ItemMod) -> Result<TokenStream, Error> {
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",
);
};

Expand Down Expand Up @@ -252,7 +252,7 @@ fn process(module: ItemMod) -> Result<TokenStream, Error> {
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",
);
};

Expand Down
115 changes: 115 additions & 0 deletions gsdk/src/api.rs
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.

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<GearConfig>,
}

impl Api {
/// Create new API client.
pub async fn new(url: Option<&str>) -> Result<Self> {
Self::new_with_timeout(url, None).await
}

/// Create new API client with timeout.
pub async fn new_with_timeout(url: Option<&str>, timeout: Option<u64>) -> Result<Self> {
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<Blocks> {
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<Blocks> {
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<Events> {
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<Events> {
Ok(self.client.blocks().subscribe_finalized().await?.into())
}

/// New signer from api
pub fn signer(self, suri: &str, passwd: Option<&str>) -> Result<Signer> {
Signer::new(self, suri, passwd)
}
}

impl Deref for Api {
type Target = OnlineClient<GearConfig>;

fn deref(&self) -> &Self::Target {
&self.client
}
}

impl DerefMut for Api {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.client
}
}
Loading