use crate::GAS_MULTIPLIER;
use gear_common::{
auxiliary::gas_provider::{AuxiliaryGasProvider, GasTreeError, PlainNodeId},
gas_provider::{ConsumeResultOf, GasNodeId, Provider, ReservableTree, Tree},
Gas, Origin,
};
use gear_core::ids::{MessageId, ProgramId, ReservationId};
pub(crate) type PositiveImbalance = <GasTree as Tree>::PositiveImbalance;
pub(crate) type NegativeImbalance = <GasTree as Tree>::NegativeImbalance;
type GasTree = <AuxiliaryGasProvider as Provider>::GasTree;
#[derive(Debug, Default)]
pub(crate) struct GasTreeManager;
impl GasTreeManager {
pub(crate) fn create(
&self,
origin: ProgramId,
mid: MessageId,
amount: Gas,
) -> Result<PositiveImbalance, GasTreeError> {
GasTree::create(
origin.cast(),
GAS_MULTIPLIER,
GasNodeId::from(mid.cast::<PlainNodeId>()),
amount,
)
}
pub(crate) fn create_deposit(
&self,
original_mid: MessageId,
future_reply_id: MessageId,
amount: Gas,
) -> Result<(), GasTreeError> {
GasTree::create_deposit(
GasNodeId::from(original_mid.cast::<PlainNodeId>()),
GasNodeId::from(future_reply_id.cast::<PlainNodeId>()),
amount,
)
}
pub(crate) fn split_with_value(
&self,
is_reply: bool,
original_mid: MessageId,
new_mid: MessageId,
amount: Gas,
) -> Result<(), GasTreeError> {
if !is_reply && !GasTree::exists_and_deposit(GasNodeId::from(new_mid.cast::<PlainNodeId>()))
{
return GasTree::split_with_value(
GasNodeId::from(original_mid.cast::<PlainNodeId>()),
GasNodeId::from(new_mid.cast::<PlainNodeId>()),
amount,
);
}
Ok(())
}
pub(crate) fn split(
&self,
is_reply: bool,
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_node.cast::<PlainNodeId>()),
GasNodeId::from(new_mid.cast::<PlainNodeId>()),
);
}
Ok(())
}
pub(crate) fn cut(
&self,
original_node: MessageId,
new_mid: MessageId,
amount: Gas,
) -> Result<(), GasTreeError> {
GasTree::cut(
GasNodeId::from(original_node.cast::<PlainNodeId>()),
GasNodeId::from(new_mid.cast::<PlainNodeId>()),
amount,
)
}
pub(crate) fn get_limit(&self, mid: MessageId) -> Result<Gas, GasTreeError> {
GasTree::get_limit(GasNodeId::from(mid.cast::<PlainNodeId>()))
}
pub(crate) fn spend(
&self,
mid: MessageId,
amount: Gas,
) -> Result<NegativeImbalance, GasTreeError> {
GasTree::spend(GasNodeId::from(mid.cast::<PlainNodeId>()), amount)
}
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>()))
}
pub(crate) fn reset(&self) {
<AuxiliaryGasProvider as Provider>::reset();
}
pub(crate) fn system_unreserve(&self, key: MessageId) -> Result<Gas, GasTreeError> {
GasTree::system_unreserve(GasNodeId::from(key.cast::<PlainNodeId>()))
}
pub(crate) fn system_reserve(&self, key: MessageId, amount: Gas) -> Result<(), GasTreeError> {
GasTree::system_reserve(GasNodeId::from(key.cast::<PlainNodeId>()), amount)
}
}