use async_graphql::InputObject;
use linera_base::data_types::{Amount, ArithmeticError};
use serde::{Deserialize, Serialize};
#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize, InputObject)]
pub struct ResourceControlPolicy {
pub block: Amount,
pub fuel_unit: Amount,
pub read_operation: Amount,
pub write_operation: Amount,
pub byte_read: Amount,
pub byte_written: Amount,
pub byte_stored: Amount,
pub operation: Amount,
pub operation_byte: Amount,
pub message: Amount,
pub message_byte: Amount,
pub maximum_bytes_read_per_block: u64,
pub maximum_bytes_written_per_block: u64,
}
impl Default for ResourceControlPolicy {
fn default() -> Self {
Self {
block: Amount::default(),
fuel_unit: Amount::default(),
read_operation: Amount::default(),
write_operation: Amount::default(),
byte_read: Amount::default(),
byte_written: Amount::default(),
byte_stored: Amount::default(),
operation: Amount::default(),
operation_byte: Amount::default(),
message: Amount::default(),
message_byte: Amount::default(),
maximum_bytes_read_per_block: u64::MAX,
maximum_bytes_written_per_block: u64::MAX,
}
}
}
impl ResourceControlPolicy {
pub fn block_price(&self) -> Amount {
self.block
}
pub(crate) fn operation_byte_price(&self, size: u64) -> Result<Amount, ArithmeticError> {
self.operation_byte.try_mul(size as u128)
}
pub(crate) fn message_byte_price(&self, size: u64) -> Result<Amount, ArithmeticError> {
self.message_byte.try_mul(size as u128)
}
pub(crate) fn read_operations_price(&self, count: u32) -> Result<Amount, ArithmeticError> {
self.read_operation.try_mul(count as u128)
}
pub(crate) fn write_operations_price(&self, count: u32) -> Result<Amount, ArithmeticError> {
self.write_operation.try_mul(count as u128)
}
pub(crate) fn bytes_read_price(&self, count: u64) -> Result<Amount, ArithmeticError> {
self.byte_read.try_mul(count as u128)
}
pub(crate) fn bytes_written_price(&self, count: u64) -> Result<Amount, ArithmeticError> {
self.byte_written.try_mul(count as u128)
}
#[allow(dead_code)]
pub(crate) fn bytes_stored_price(&self, count: u64) -> Result<Amount, ArithmeticError> {
self.byte_stored.try_mul(count as u128)
}
pub(crate) fn fuel_price(&self, fuel: u64) -> Result<Amount, ArithmeticError> {
self.fuel_unit.try_mul(u128::from(fuel))
}
pub(crate) fn remaining_fuel(&self, balance: Amount) -> u64 {
u64::try_from(balance.saturating_div(self.fuel_unit)).unwrap_or(u64::MAX)
}
#[cfg(any(test, feature = "test"))]
pub fn only_fuel() -> Self {
Self {
fuel_unit: Amount::from_atto(1_000_000_000_000),
..Self::default()
}
}
#[cfg(any(test, feature = "test"))]
pub fn fuel_and_block() -> Self {
Self {
block: Amount::from_milli(1),
fuel_unit: Amount::from_atto(1_000_000_000_000),
..Self::default()
}
}
#[cfg(any(test, feature = "test"))]
pub fn all_categories() -> Self {
Self {
block: Amount::from_milli(1),
fuel_unit: Amount::from_atto(1_000_000_000),
byte_read: Amount::from_atto(100),
byte_written: Amount::from_atto(1_000),
operation: Amount::from_atto(10),
operation_byte: Amount::from_atto(1),
message: Amount::from_atto(10),
message_byte: Amount::from_atto(1),
..Self::default()
}
}
}