Skip to content

Commit

Permalink
feat(gtest): Introduce reservations for the gtest (#4089)
Browse files Browse the repository at this point in the history
  • Loading branch information
techraed authored Aug 1, 2024
1 parent f42b755 commit 2a8a985
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 56 deletions.
12 changes: 11 additions & 1 deletion common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use frame_support::{
traits::Get,
};
pub use gear_core::{
ids::{CodeId, MessageId, ProgramId},
ids::{CodeId, MessageId, ProgramId, ReservationId},
memory::PageBuf,
pages::GearPage,
program::{ActiveProgram, MemoryInfix, Program},
Expand Down Expand Up @@ -150,6 +150,16 @@ impl Origin for CodeId {
}
}

impl Origin for ReservationId {
fn into_origin(self) -> H256 {
H256(self.into())
}

fn from_origin(val: H256) -> Self {
val.to_fixed_bytes().into()
}
}

#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, MaxEncodedLen, TypeInfo,
)]
Expand Down
24 changes: 24 additions & 0 deletions examples/constructor/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ impl Calls {
self.add_call(Call::MessageId).store_vec(key)
}

pub fn reservation_send_value(
self,
reservation: impl Into<Arg<[u8; 32]>>,
destination: impl Into<Arg<[u8; 32]>>,
payload: impl Into<Arg<Vec<u8>>>,
value: impl Into<Arg<u128>>,
) -> Self {
self.add_call(Call::ReservationSend(
reservation.into(),
destination.into(),
payload.into(),
value.into(),
0.into(),
))
}

pub fn send(
self,
destination: impl Into<Arg<[u8; 32]>>,
Expand Down Expand Up @@ -341,6 +357,14 @@ impl Calls {
self.add_call(Call::SystemReserveGas(gas.into()))
}

pub fn reserve_gas(self, gas: impl Into<Arg<u64>>, duration: impl Into<Arg<u32>>) -> Self {
self.add_call(Call::ReserveGas(gas.into(), duration.into()))
}

pub fn unreserve_gas(self, reservation_id: impl Into<Arg<[u8; 32]>>) -> Self {
self.add_call(Call::UnreserveGas(reservation_id.into()))
}

pub fn write_in_loop(self, count: impl Into<Arg<u64>>) -> Self {
self.add_call(Call::WriteN(count.into()))
}
Expand Down
56 changes: 56 additions & 0 deletions examples/constructor/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ pub enum Call {
ReplyCode,
Value,
ValueAvailable,
ReservationSend(
Arg<[u8; 32]>,
Arg<[u8; 32]>,
Arg<Vec<u8>>,
Arg<u128>,
Arg<u32>,
),
Send(
Arg<[u8; 32]>,
Arg<Vec<u8>>,
Expand All @@ -42,6 +49,8 @@ pub enum Call {
Wake(Arg<[u8; 32]>),
MessageId,
Loop,
ReserveGas(Arg<u64>, Arg<u32>),
UnreserveGas(Arg<[u8; 32]>),
SystemReserveGas(Arg<u64>),
WriteN(Arg<u64>),
}
Expand Down Expand Up @@ -180,6 +189,25 @@ mod wasm {
}
}

fn reservation_send(self) -> Option<Vec<u8>> {
let Self::ReservationSend(reservation, destination, payload, value, delay) = self
else {
unreachable!()
};

let reservation = reservation.value().into();
let destination = destination.value().into();
let payload = payload.value();
let value = value.value();
let delay = delay.value();

let message_id =
msg::send_delayed_from_reservation(reservation, destination, payload, value, delay)
.expect("Failed to send message from reservation");

Some(message_id.encode())
}

fn send(self) -> Option<Vec<u8>> {
let Self::Send(destination, payload, gas_limit, value, delay) = self else {
unreachable!()
Expand Down Expand Up @@ -332,6 +360,31 @@ mod wasm {
None
}

fn reserve_gas(self) -> Option<Vec<u8>> {
let Self::ReserveGas(amount, duration) = self else {
unreachable!()
};

let amount = amount.value();
let duration = duration.value();
let reservation_id =
exec::reserve_gas(amount, duration).expect("Failed to reserve gas");

Some(reservation_id.encode())
}

fn unreserve_gas(self) -> Option<Vec<u8>> {
let Self::UnreserveGas(reservation) = self else {
unreachable!()
};

let reservation = reservation.value().into();
let unreserved_value =
exec::unreserve_gas(reservation).expect("Failed to unreserve gas");

Some(unreserved_value.encode())
}

fn write_n(self) -> Option<Vec<u8>> {
let Self::WriteN(count) = self else {
unreachable!()
Expand Down Expand Up @@ -359,6 +412,7 @@ mod wasm {
Call::Source => self.source(),
Call::ReplyCode => self.reply_code(),
Call::Panic(..) => self.panic(),
Call::ReservationSend(..) => self.reservation_send(),
Call::Send(..) => self.send(),
Call::Reply(..) => self.reply(),
Call::Exit(..) => self.exit(),
Expand All @@ -376,6 +430,8 @@ mod wasm {
#[allow(clippy::empty_loop)]
Call::Loop => loop {},
Call::SystemReserveGas(..) => self.system_reserve_gas(),
Call::ReserveGas(..) => self.reserve_gas(),
Call::UnreserveGas(..) => self.unreserve_gas(),
Call::WriteN(..) => self.write_n(),
};

Expand Down
32 changes: 25 additions & 7 deletions gtest/src/gas_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
use crate::GAS_MULTIPLIER;
use gear_common::{
auxiliary::gas_provider::{AuxiliaryGasProvider, GasTreeError, PlainNodeId},
gas_provider::{ConsumeResultOf, GasNodeId, Provider, Tree},
gas_provider::{ConsumeResultOf, GasNodeId, Provider, ReservableTree, Tree},
Gas, Origin,
};
use gear_core::ids::{MessageId, ProgramId};
use gear_core::ids::{MessageId, ProgramId, ReservationId};

pub(crate) type PositiveImbalance = <GasTree as Tree>::PositiveImbalance;
pub(crate) type NegativeImbalance = <GasTree as Tree>::NegativeImbalance;
Expand Down Expand Up @@ -94,13 +94,13 @@ impl GasTreeManager {
pub(crate) fn split(
&self,
is_reply: bool,
original_mid: MessageId,
original_node: impl Origin,
new_mid: MessageId,
) -> Result<(), GasTreeError> {
if !is_reply && !GasTree::exists_and_deposit(GasNodeId::from(new_mid.cast::<PlainNodeId>()))
{
return GasTree::split(
GasNodeId::from(original_mid.cast::<PlainNodeId>()),
GasNodeId::from(original_node.cast::<PlainNodeId>()),
GasNodeId::from(new_mid.cast::<PlainNodeId>()),
);
}
Expand All @@ -111,12 +111,12 @@ impl GasTreeManager {
/// Adapted by argument types version of the gas tree `cut` method.
pub(crate) fn cut(
&self,
original_mid: MessageId,
original_node: MessageId,
new_mid: MessageId,
amount: Gas,
) -> Result<(), GasTreeError> {
GasTree::cut(
GasNodeId::from(original_mid.cast::<PlainNodeId>()),
GasNodeId::from(original_node.cast::<PlainNodeId>()),
GasNodeId::from(new_mid.cast::<PlainNodeId>()),
amount,
)
Expand All @@ -137,10 +137,28 @@ impl GasTreeManager {
}

/// Adapted by argument types version of the gas tree `consume` method.
pub(crate) fn consume(&self, mid: MessageId) -> ConsumeResultOf<GasTree> {
pub(crate) fn consume(&self, mid: impl Origin) -> ConsumeResultOf<GasTree> {
GasTree::consume(GasNodeId::from(mid.cast::<PlainNodeId>()))
}

pub(crate) fn reserve_gas(
&self,
original_mid: MessageId,
reservation_id: ReservationId,
amount: Gas,
) -> Result<(), GasTreeError> {
GasTree::reserve(
GasNodeId::from(original_mid.cast::<PlainNodeId>()),
GasNodeId::from(reservation_id.cast::<PlainNodeId>()),
amount,
)
}

#[cfg(test)]
pub(crate) fn exists(&self, node_id: impl Origin) -> bool {
GasTree::exists(GasNodeId::from(node_id.cast::<PlainNodeId>()))
}

/// Adapted by argument types version of the gas tree `reset` method.
///
/// *Note* Call with caution as it completely resets the storage.
Expand Down
Loading

0 comments on commit 2a8a985

Please sign in to comment.