Skip to content

Commit

Permalink
Introduce gr_exec_settings sys-call
Browse files Browse the repository at this point in the history
  • Loading branch information
DennisInSky committed Oct 11, 2023
1 parent 71168c5 commit e3694a6
Show file tree
Hide file tree
Showing 32 changed files with 344 additions and 21 deletions.
1 change: 1 addition & 0 deletions core-backend/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ where
{
#[rustfmt::skip]
fn bind_funcs(builder: &mut EnvBuilder<Ext>) {
builder.add_func(ExecSettings, wrap_common_func!(FuncsHandler::exec_settings, (3) -> ()));
builder.add_func(BlockHeight, wrap_common_func!(FuncsHandler::block_height, (2) -> ()));
builder.add_func(BlockTimestamp,wrap_common_func!(FuncsHandler::block_timestamp, (2) -> ()));
builder.add_func(CreateProgram, wrap_common_func!(FuncsHandler::create_program, (8) -> ()));
Expand Down
2 changes: 2 additions & 0 deletions core-backend/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ pub enum UnrecoverableExecutionError {
TooBigReadLen,
#[display(fmt = "Cannot take data in payload range from message with size")]
ReadWrongRange,
#[display(fmt = "Unexpected version of execution settings encountered ")]
UnexpectedExecSettingsVersion,
}

/// Memory error in infallible sys-call.
Expand Down
16 changes: 16 additions & 0 deletions core-backend/src/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,22 @@ where
Ok(res.is_err() as i32)
}

#[host(cost = RuntimeCosts::ExecSettings)]
pub fn exec_settings(
ctx: &mut CallerWrap<'_, '_, Ext>,
gas: u64,
settings_ptr: u32,
settings_ver: u32,
) -> Result<(u64, ()), HostError> {
let settings = ctx.ext_mut().exec_settings(settings_ver)?;
let settings_bytes = settings.to_bytes();
let settings_write = ctx
.manager
.register_write(settings_ptr, settings_bytes.len() as u32);
ctx.write(settings_write, settings_bytes)
.map_err(Into::into)
}

#[host(cost = RuntimeCosts::BlockHeight)]
pub fn block_height(
ctx: &mut CallerWrap<'_, '_, Ext>,
Expand Down
16 changes: 12 additions & 4 deletions core-backend/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ use core::{cell::Cell, fmt, fmt::Debug};
use gear_core::{
costs::RuntimeCosts,
env::{Externalities, PayloadSliceLock, UnlockPayloadBound},
exec_settings::{ExecSettings, ExecSettingsV1},
gas::{ChargeError, CounterType, CountersOwner, GasAmount, GasCounter, GasLeft},
ids::{MessageId, ProgramId, ReservationId},
memory::{Memory, MemoryError, MemoryInterval},
message::{HandlePacket, InitPacket, ReplyPacket},
pages::{PageNumber, PageU32Size, WasmPage, WASM_PAGE_SIZE},
percent::Percent,
};
use gear_core_errors::{ReplyCode, SignalCode};
use gear_lazy_pages_common::ProcessAccessError;
Expand Down Expand Up @@ -115,15 +115,23 @@ impl Externalities for MockExt {
fn free(&mut self, _page: WasmPage) -> Result<(), Self::AllocError> {
Err(Error)
}
fn exec_settings(&self, version: u32) -> Result<ExecSettings, Self::FallibleError> {
match version {
1 => Ok(ExecSettings::V1(ExecSettingsV1 {
performance_multiplier_percent: 100,
existential_deposit: 10,
mailbox_threshold: 20,
gas_to_value_multiplier: 30,
})),
_ => unreachable!("Unexpected version of execution settings"),
}
}
fn block_height(&self) -> Result<u32, Self::UnrecoverableError> {
Ok(0)
}
fn block_timestamp(&self) -> Result<u64, Self::UnrecoverableError> {
Ok(0)
}
fn performance_multiplier(&self) -> Result<Percent, Self::UnrecoverableError> {
Ok(Percent::new(100))
}
fn send_init(&mut self) -> Result<u32, Self::UnrecoverableError> {
Ok(0)
}
Expand Down
4 changes: 4 additions & 0 deletions core-processor/src/configs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ pub struct ExecutionSettings {
pub random_data: (Vec<u8>, u32),
/// Rent cost per block.
pub rent_cost: u128,
/// Value per gas multiplier.
pub gas_to_value_multiplier: u128,
}

/// Stable parameters for the whole block across processing runs.
Expand Down Expand Up @@ -221,4 +223,6 @@ pub struct BlockConfig {
pub code_instrumentation_byte_cost: u64,
/// Rent cost per block.
pub rent_cost: u128,
/// Value per gas multiplier.
pub gas_to_value_multiplier: u128,
}
2 changes: 2 additions & 0 deletions core-processor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ where
reservation: settings.reservation,
random_data: settings.random_data,
rent_cost: settings.rent_cost,
gas_to_value_multiplier: settings.gas_to_value_multiplier,
};

let lazy_pages_weights = context.page_costs.lazy_pages_weights();
Expand Down Expand Up @@ -418,6 +419,7 @@ where
random_data: Default::default(),
system_reservation: Default::default(),
rent_cost: Default::default(),
gas_to_value_multiplier: Default::default(),
};

let lazy_pages_weights = context.page_costs.lazy_pages_weights();
Expand Down
20 changes: 16 additions & 4 deletions core-processor/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use alloc::{
use gear_core::{
costs::{HostFnWeights, RuntimeCosts},
env::{Externalities, PayloadSliceLock, UnlockPayloadBound},
exec_settings::{ExecSettings, ExecSettingsV1},
gas::{
ChargeError, ChargeResult, CounterType, CountersOwner, GasAllowanceCounter, GasAmount,
GasCounter, GasLeft, Token, ValueCounter,
Expand Down Expand Up @@ -109,6 +110,8 @@ pub struct ProcessorContext {
pub random_data: (Vec<u8>, u32),
/// Rent cost per block.
pub rent_cost: u128,
/// Gas to value multiplier.
pub gas_to_value_multiplier: u128,
}

#[cfg(any(feature = "mock", test))]
Expand Down Expand Up @@ -154,6 +157,7 @@ impl ProcessorContext {
reservation: 0,
random_data: ([0u8; 32].to_vec(), 0),
rent_cost: 0,
gas_to_value_multiplier: Default::default(),
}
}
}
Expand Down Expand Up @@ -721,6 +725,18 @@ impl Externalities for Ext {
.map_err(Into::into)
}

fn exec_settings(&self, version: u32) -> Result<ExecSettings, Self::UnrecoverableError> {
match version {
1 => Ok(ExecSettings::V1(ExecSettingsV1 {
performance_multiplier_percent: self.context.performance_multiplier.value(),
existential_deposit: self.context.existential_deposit,
mailbox_threshold: self.context.mailbox_threshold,
gas_to_value_multiplier: self.context.gas_to_value_multiplier,
})),
_ => Err(UnrecoverableExecutionError::UnexpectedExecSettingsVersion.into()),
}
}

fn block_height(&self) -> Result<u32, Self::UnrecoverableError> {
Ok(self.context.block_info.height)
}
Expand All @@ -729,10 +745,6 @@ impl Externalities for Ext {
Ok(self.context.block_info.timestamp)
}

fn performance_multiplier(&self) -> Result<Percent, Self::UnrecoverableError> {
Ok(self.context.performance_multiplier)
}

fn send_init(&mut self) -> Result<u32, Self::FallibleError> {
let handle = self.context.message_context.send_init()?;
Ok(handle)
Expand Down
2 changes: 2 additions & 0 deletions core-processor/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ where
reservation,
write_cost,
rent_cost,
gas_to_value_multiplier,
..
} = block_config.clone();

Expand All @@ -89,6 +90,7 @@ where
reservation,
random_data,
rent_cost,
gas_to_value_multiplier,
};

let dispatch = execution_context.dispatch;
Expand Down
6 changes: 6 additions & 0 deletions core/src/costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ pub struct HostFnWeights {
/// Weight per payload byte by `gr_read`.
pub gr_read_per_byte: u64,

/// Weight of calling `gr_exec_settings`.
pub gr_exec_settings: u64,

/// Weight of calling `gr_block_height`.
pub gr_block_height: u64,

Expand Down Expand Up @@ -349,6 +352,8 @@ pub enum RuntimeCosts {
Read,
/// Weight of calling `gr_read` per read buffer bytes number.
ReadPerByte(u32),
/// Weight of calling `gr_exec_settings`.
ExecSettings,
/// Weight of calling `gr_block_height`.
BlockHeight,
/// Weight of calling `gr_block_timestamp`.
Expand Down Expand Up @@ -475,6 +480,7 @@ impl RuntimeCosts {
Size => s.gr_size,
Read => s.gr_read,
ReadPerByte(len) => cost_per_byte(s.gr_read_per_byte, len),
ExecSettings => s.gr_exec_settings,
BlockHeight => s.gr_block_height,
BlockTimestamp => s.gr_block_timestamp,
Random => s.gr_random,
Expand Down
9 changes: 5 additions & 4 deletions core/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
//! Environment for running a module.
use crate::{
exec_settings::ExecSettings,
ids::{MessageId, ProgramId, ReservationId},
memory::Memory,
message::{HandlePacket, InitPacket, MessageContext, Payload, ReplyPacket},
pages::WasmPage,
percent::Percent,
};
use alloc::collections::BTreeSet;
use core::{fmt::Display, mem};
Expand Down Expand Up @@ -198,15 +198,16 @@ pub trait Externalities {
/// should be `free`-d separately.
fn free(&mut self, page: WasmPage) -> Result<(), Self::AllocError>;

/// Get execution settings currently set in the system and in the form
/// corresponded to the requested version.
fn exec_settings(&self, version: u32) -> Result<ExecSettings, Self::UnrecoverableError>;

/// Get the current block height.
fn block_height(&self) -> Result<u32, Self::UnrecoverableError>;

/// Get the current block timestamp.
fn block_timestamp(&self) -> Result<u64, Self::UnrecoverableError>;

/// Get current performance multiplier.
fn performance_multiplier(&self) -> Result<Percent, Self::UnrecoverableError>;

/// Initialize a new incomplete message for another program and return its handle.
fn send_init(&mut self) -> Result<u32, Self::FallibleError>;

Expand Down
53 changes: 53 additions & 0 deletions core/src/exec_settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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/>.

//! Execution settings
use core::{mem, slice};

/// All supported versions of execution settings
pub enum ExecSettings {
/// Values of execution settings V1
V1(ExecSettingsV1),
}

impl ExecSettings {
/// Returns byte representation of execution settings
pub fn to_bytes(&self) -> &[u8] {
match self {
ExecSettings::V1(v1) => {
let ptr = v1 as *const ExecSettingsV1 as *const u8;
unsafe { slice::from_raw_parts(ptr, mem::size_of::<ExecSettingsV1>()) }
}
}
}
}

/// Values of execution settings V1
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct ExecSettingsV1 {
/// Performance multiplier percentage
pub performance_multiplier_percent: u32,
/// Existential deposit
pub existential_deposit: u128,
/// Mailbox threshold
pub mailbox_threshold: u64,
/// Multiplier for converting gas into value
pub gas_to_value_multiplier: u128,
}
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern crate alloc;
pub mod code;
pub mod costs;
pub mod env;
pub mod exec_settings;
pub mod gas;
pub mod ids;
pub mod memory;
Expand Down
2 changes: 1 addition & 1 deletion core/src/percent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl Percent {
Self(value)
}

/// Returns the inner `u16` value.
/// Returns the inner `u32` value.
pub fn value(self) -> u32 {
self.0
}
Expand Down
7 changes: 7 additions & 0 deletions examples/sys-calls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ pub enum Kind {
ReplyDetails(MessageId, [u8; 4]),
SignalDetails,
SignalDetailsWake,
// Expected values
ExecSettings {
performance_multiplier: u32,
existential_deposit: u128,
mailbox_threshold: u64,
gas_to_value_multiplier: u128,
},
// Expected(block height)
BlockHeight(u32),
// Expected(block timestamp)
Expand Down
28 changes: 28 additions & 0 deletions examples/sys-calls/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,34 @@ fn process(syscall_kind: Kind) {
Kind::SignalDetailsWake => {
panic!("must be called in handle_reply");
}
Kind::ExecSettings {
performance_multiplier: expected_performance_multiplier_percent,
existential_deposit: expected_existential_deposit,
mailbox_threshold: expected_mailbox_threshold,
gas_to_value_multiplier: expected_gas_to_value_multiplier,
} => {
let settings = exec::settings();
let actual_performance_multiplier_percent = settings.performance_multiplier_percent;
assert_eq!(
actual_performance_multiplier_percent, expected_performance_multiplier_percent,
"Kind::ExecSettings: performance_multiplier test failed"
);
let actual_existential_deposit = settings.existential_deposit;
assert_eq!(
actual_existential_deposit, expected_existential_deposit,
"Kind::ExecSettings: existential_deposit test failed"
);
let actual_mailbox_threshold = settings.mailbox_threshold;
assert_eq!(
actual_mailbox_threshold, expected_mailbox_threshold,
"Kind::ExecSettings: mailbox_threshold test failed"
);
let actual_gas_to_value_multiplier = settings.gas_to_value_multiplier;
assert_eq!(
actual_gas_to_value_multiplier, expected_gas_to_value_multiplier,
"Kind::ExecSettings: gas_to_value_multiplier test failed"
);
}
Kind::BlockHeight(expected_height) => {
let actual_height = exec::block_height();
assert_eq!(
Expand Down
Loading

0 comments on commit e3694a6

Please sign in to comment.