Skip to content

Commit

Permalink
feat(sails-rs): introduce 'ethexe' feature in 'sails-rs' (#555)
Browse files Browse the repository at this point in the history
  • Loading branch information
DennisInSky authored Sep 30, 2024
1 parent fe694b6 commit d58f87d
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 33 deletions.
2 changes: 1 addition & 1 deletion examples/demo/app/tests/gclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ async fn ping_pong_works() {
ping_call_payload,
Some(gas_limit),
0,
GClientArgs,
GClientArgs::default(),
)
.await
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ gtest = { workspace = true, optional = true }
[features]
default = ["gstd"]
debug = ["gstd?/debug"]
ethexe = ["gstd?/ethexe"]
gclient = ["dep:gclient"]
gstd = ["dep:gstd", "dep:gear-core", "dep:sails-macros"]
gtest = ["dep:gtest"]
Expand Down
31 changes: 26 additions & 5 deletions rs/src/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ use core::{future::Future, marker::PhantomData};
pub trait Action {
type Args;

#[cfg(not(feature = "ethexe"))]
fn with_gas_limit(self, gas_limit: GasUnit) -> Self;
fn with_value(self, value: ValueUnit) -> Self;
fn with_args(self, args: Self::Args) -> Self;

#[cfg(not(feature = "ethexe"))]
fn gas_limit(&self) -> Option<GasUnit>;
fn value(&self) -> ValueUnit;
fn args(&self) -> &Self::Args;
Expand Down Expand Up @@ -124,7 +126,7 @@ pub trait Remoting {
code_id: CodeId,
salt: impl AsRef<[u8]>,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: Self::Args,
) -> Result<impl Future<Output = Result<(ActorId, Vec<u8>)>>>;
Expand All @@ -133,7 +135,7 @@ pub trait Remoting {
self,
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: Self::Args,
) -> Result<impl Future<Output = Result<Vec<u8>>>>;
Expand All @@ -142,7 +144,7 @@ pub trait Remoting {
self,
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: Self::Args,
) -> Result<Vec<u8>>;
Expand All @@ -151,6 +153,7 @@ pub trait Remoting {
pub struct RemotingAction<TRemoting: Remoting, TActionIo: ActionIo> {
remoting: TRemoting,
params: TActionIo::Params,
#[cfg(not(feature = "ethexe"))]
gas_limit: Option<GasUnit>,
value: ValueUnit,
args: TRemoting::Args,
Expand All @@ -161,6 +164,7 @@ impl<TRemoting: Remoting, TActionIo: ActionIo> RemotingAction<TRemoting, TAction
Self {
remoting,
params,
#[cfg(not(feature = "ethexe"))]
gas_limit: Default::default(),
value: Default::default(),
args: Default::default(),
Expand All @@ -171,6 +175,7 @@ impl<TRemoting: Remoting, TActionIo: ActionIo> RemotingAction<TRemoting, TAction
impl<TRemoting: Remoting, TActionIo: ActionIo> Action for RemotingAction<TRemoting, TActionIo> {
type Args = TRemoting::Args;

#[cfg(not(feature = "ethexe"))]
fn with_gas_limit(self, gas_limit: GasUnit) -> Self {
Self {
gas_limit: Some(gas_limit),
Expand All @@ -186,6 +191,7 @@ impl<TRemoting: Remoting, TActionIo: ActionIo> Action for RemotingAction<TRemoti
Self { args, ..self }
}

#[cfg(not(feature = "ethexe"))]
fn gas_limit(&self) -> Option<GasUnit> {
self.gas_limit
}
Expand All @@ -210,7 +216,14 @@ where
let payload = TActionIo::encode_call(&self.params);
let reply_future = self
.remoting
.message(target, payload, self.gas_limit, self.value, self.args)
.message(
target,
payload,
#[cfg(not(feature = "ethexe"))]
self.gas_limit,
self.value,
self.args,
)
.await?;
Ok(CallTicket::<_, TActionIo>::new(reply_future))
}
Expand All @@ -233,6 +246,7 @@ where
code_id,
salt,
payload,
#[cfg(not(feature = "ethexe"))]
self.gas_limit,
self.value,
self.args,
Expand All @@ -253,7 +267,14 @@ where
let payload = TActionIo::encode_call(&self.params);
let reply_bytes = self
.remoting
.query(target, payload, self.gas_limit, self.value, self.args)
.query(
target,
payload,
#[cfg(not(feature = "ethexe"))]
self.gas_limit,
self.value,
self.args,
)
.await?;
TActionIo::decode_reply(reply_bytes)
}
Expand Down
45 changes: 36 additions & 9 deletions rs/src/gclient/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@ use crate::{
};
use core::future::Future;
use futures::{stream, Stream, StreamExt};
use gclient::metadata::runtime_types::gear_core::message::user::UserMessage as GenUserMessage;
use gclient::metadata::runtime_types::{
gear_core::message::user::UserMessage as GenUserMessage,
pallet_gear_voucher::internal::VoucherId,
};
use gclient::{ext::sp_core::ByteArray, EventProcessor, GearApi};
use gear_core_errors::ReplyCode;

#[derive(Debug, Default)]
pub struct GClientArgs;
pub struct GClientArgs {
voucher: Option<(VoucherId, bool)>,
}

impl GClientArgs {
pub fn with_voucher(mut self, voucher_id: VoucherId, keep_alive: bool) -> Self {
self.voucher = Some((voucher_id, keep_alive));
self
}
}

#[derive(Clone)]
pub struct GClientRemoting {
Expand All @@ -37,12 +49,13 @@ impl Remoting for GClientRemoting {
code_id: CodeId,
salt: impl AsRef<[u8]>,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
_args: GClientArgs,
) -> Result<impl Future<Output = Result<(ActorId, Vec<u8>)>>> {
let api = self.api;
// Calculate gas amount if it is not explicitly set
#[cfg(not(feature = "ethexe"))]
let gas_limit = if let Some(gas_limit) = gas_limit {
gas_limit
} else {
Expand All @@ -52,6 +65,8 @@ impl Remoting for GClientRemoting {
.await?;
gas_info.min_limit
};
#[cfg(feature = "ethexe")]
let gas_limit = 0;

let mut listener = api.subscribe().await?;
let (message_id, program_id, ..) = api
Expand All @@ -69,12 +84,13 @@ impl Remoting for GClientRemoting {
self,
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
_args: GClientArgs,
args: GClientArgs,
) -> Result<impl Future<Output = Result<Vec<u8>>>> {
let api = self.api;
// Calculate gas amount if it is not explicitly set
#[cfg(not(feature = "ethexe"))]
let gas_limit = if let Some(gas_limit) = gas_limit {
gas_limit
} else {
Expand All @@ -84,11 +100,19 @@ impl Remoting for GClientRemoting {
.await?;
gas_info.min_limit
};
#[cfg(feature = "ethexe")]
let gas_limit = 0;

let mut listener = api.subscribe().await?;
let (message_id, ..) = api
.send_message_bytes(target, payload, gas_limit, value)
.await?;
let (message_id, ..) = if let Some((voucher_id, keep_alive)) = args.voucher {
api.send_message_bytes_with_voucher(
voucher_id, target, payload, gas_limit, value, keep_alive,
)
.await?
} else {
api.send_message_bytes(target, payload, gas_limit, value)
.await?
};

Ok(async move {
let (_, result, _) = listener.reply_bytes_on(message_id).await?;
Expand All @@ -101,17 +125,20 @@ impl Remoting for GClientRemoting {
self,
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
_args: GClientArgs,
) -> Result<Vec<u8>> {
let api = self.api;
// Get Max gas amount if it is not explicitly set
#[cfg(not(feature = "ethexe"))]
let gas_limit = if let Some(gas_limit) = gas_limit {
gas_limit
} else {
api.block_gas_limit()?
};
#[cfg(feature = "ethexe")]
let gas_limit = 0;
let origin = H256::from_slice(api.account_id().as_slice());
let payload = payload.as_ref().to_vec();

Expand Down
50 changes: 39 additions & 11 deletions rs/src/gstd/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ use gstd::{msg, prog};

#[derive(Default)]
pub struct GStdArgs {
#[cfg(not(feature = "ethexe"))]
reply_deposit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))]
reply_hook: Option<Box<dyn FnOnce() + Send + 'static>>,
}

#[cfg(not(feature = "ethexe"))]
impl GStdArgs {
pub fn with_reply_deposit(mut self, reply_deposit: Option<GasUnit>) -> Self {
self.reply_deposit = reply_deposit;
Expand All @@ -32,10 +35,11 @@ impl GStdRemoting {
fn send_for_reply(
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: GStdArgs,
#[allow(unused_variables)] args: GStdArgs,
) -> Result<msg::MessageFuture, crate::errors::Error> {
#[cfg(not(feature = "ethexe"))]
let message_future = if let Some(gas_limit) = gas_limit {
msg::send_bytes_with_gas_for_reply(
target,
Expand All @@ -52,11 +56,15 @@ impl GStdRemoting {
args.reply_deposit.unwrap_or_default(),
)?
};
#[cfg(feature = "ethexe")]
let message_future = msg::send_bytes_for_reply(target, payload, value)?;

#[cfg(not(feature = "ethexe"))]
if let Some(reply_hook) = args.reply_hook {
Ok(message_future.handle_reply(reply_hook)?)
} else {
Ok(message_future)
return Ok(message_future.handle_reply(reply_hook)?);
}

Ok(message_future)
}
}

Expand All @@ -68,10 +76,11 @@ impl Remoting for GStdRemoting {
code_id: CodeId,
salt: impl AsRef<[u8]>,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: GStdArgs,
#[allow(unused_variables)] args: GStdArgs,
) -> Result<impl Future<Output = Result<(ActorId, Vec<u8>)>>> {
#[cfg(not(feature = "ethexe"))]
let mut reply_future = if let Some(gas_limit) = gas_limit {
prog::create_program_bytes_with_gas_for_reply(
code_id,
Expand All @@ -90,9 +99,14 @@ impl Remoting for GStdRemoting {
args.reply_deposit.unwrap_or_default(),
)?
};
#[cfg(feature = "ethexe")]
let reply_future = prog::create_program_bytes_for_reply(code_id, salt, payload, value)?;

#[cfg(not(feature = "ethexe"))]
if let Some(reply_hook) = args.reply_hook {
reply_future = reply_future.handle_reply(reply_hook)?;
}

let reply_future = reply_future.map(|result| result.map_err(Into::into));
Ok(reply_future)
}
Expand All @@ -101,11 +115,18 @@ impl Remoting for GStdRemoting {
self,
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: GStdArgs,
) -> Result<impl Future<Output = Result<Vec<u8>>>> {
let reply_future = GStdRemoting::send_for_reply(target, payload, gas_limit, value, args)?;
let reply_future = GStdRemoting::send_for_reply(
target,
payload,
#[cfg(not(feature = "ethexe"))]
gas_limit,
value,
args,
)?;
let reply_future = reply_future.map(|result| result.map_err(Into::into));
Ok(reply_future)
}
Expand All @@ -114,11 +135,18 @@ impl Remoting for GStdRemoting {
self,
target: ActorId,
payload: impl AsRef<[u8]>,
gas_limit: Option<GasUnit>,
#[cfg(not(feature = "ethexe"))] gas_limit: Option<GasUnit>,
value: ValueUnit,
args: GStdArgs,
) -> Result<Vec<u8>> {
let reply_future = GStdRemoting::send_for_reply(target, payload, gas_limit, value, args)?;
let reply_future = GStdRemoting::send_for_reply(
target,
payload,
#[cfg(not(feature = "ethexe"))]
gas_limit,
value,
args,
)?;
let reply = reply_future.await?;
Ok(reply)
}
Expand Down
5 changes: 4 additions & 1 deletion rs/src/gstd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#[cfg(not(feature = "ethexe"))]
#[doc(hidden)]
pub use gstd::{async_init, async_main, handle_reply_with_hook, handle_signal, message_loop};
pub use gstd::handle_signal;
#[doc(hidden)]
pub use gstd::{async_init, async_main, handle_reply_with_hook, message_loop};
pub use gstd::{debug, exec, msg};
pub use sails_macros::*;

Expand Down
Loading

0 comments on commit d58f87d

Please sign in to comment.