Skip to content

Commit

Permalink
Support gas allowance in signal
Browse files Browse the repository at this point in the history
  • Loading branch information
ukint-vs committed Aug 21, 2023
1 parent b665b13 commit 001e6ac
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 14 deletions.
11 changes: 5 additions & 6 deletions core-backend/common/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,15 @@ use gear_core::{
};
use gear_core_errors::MemoryError as FallibleMemoryError;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use scale_info::scale::{Decode, DecodeAll, Encode, MaxEncodedLen};
use scale_info::scale::{Decode, DecodeAll, MaxEncodedLen};

/// Memory access error during sys-call that lazy-pages have caught.
/// 0 index is reserved for an ok result.
#[derive(Debug, Clone, Encode, Decode, IntoPrimitive, TryFromPrimitive)]
#[derive(Debug, Clone, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub enum ProcessAccessError {
OutOfBounds = 1,
GasLimitExceeded = 2,
GasAllowanceExceeded = 3,
}

#[derive(Debug, Clone, derive_more::From)]
Expand Down Expand Up @@ -78,9 +77,9 @@ impl BackendSyscallError for MemoryAccessError {
// previously it was able to figure out that gas ended up in
// pre-process charges: now we need actual counter type, so
// it will be parsed and handled further (issue #3018).
MemoryAccessError::ProcessAccess(
ProcessAccessError::GasLimitExceeded | ProcessAccessError::GasAllowanceExceeded,
) => UndefinedTerminationReason::ProcessAccessErrorResourcesExceed,
MemoryAccessError::ProcessAccess(ProcessAccessError::GasLimitExceeded) => {
UndefinedTerminationReason::ProcessAccessErrorResourcesExceed
}
MemoryAccessError::Decode => unreachable!(),
}
}
Expand Down
7 changes: 3 additions & 4 deletions lazy-pages/src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,15 @@ fn apply_for_global_internal(

pub(crate) unsafe fn apply_for_global(
globals_ctx: &GlobalsContext,
global_no: GlobalNo,
global_name: &str,
f: impl FnMut(u64) -> Result<Option<u64>, Error>,
) -> Result<u64, Error> {
let name = globals_ctx.names[global_no as usize].as_str();
match globals_ctx.access_mod {
GlobalsAccessMod::WasmRuntime => {
let instance = (globals_ctx.access_ptr as *mut SandboxInstance)
.as_mut()
.ok_or(Error::HostInstancePointerIsInvalid)?;
apply_for_global_internal(GlobalsAccessWasmRuntime { instance }, name, f)
apply_for_global_internal(GlobalsAccessWasmRuntime { instance }, global_name, f)
}
GlobalsAccessMod::NativeRuntime => {
let inner_access_provider = (globals_ctx.access_ptr as *mut &mut dyn GlobalsAccessor)
Expand All @@ -127,7 +126,7 @@ pub(crate) unsafe fn apply_for_global(
GlobalsAccessNativeRuntime {
inner_access_provider,
},
name,
global_name,
f,
)
}
Expand Down
27 changes: 25 additions & 2 deletions lazy-pages/src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ unsafe fn user_signal_handler_internal(
load_data_cost: ctx.weight(WeightNo::LoadPageDataFromStorage),
};

let gas_counter = globals::apply_for_global(globals_config, GlobalNo::Gas, |_| Ok(None))?;
let gas_counter = globals::apply_for_global(
globals_config,
globals_config.names[GlobalNo::Gas as usize].as_str(),
|_| Ok(None),
)?;

Some((gas_counter, gas_charger))
} else {
Expand Down Expand Up @@ -176,9 +180,28 @@ impl AccessHandler for SignalAccessHandler {
if let (Some((gas_counter, _)), Some(globals_config)) =
(self.gas_ctx, ctx.globals_context.as_ref())
{
let mut diff = 0;
unsafe {
globals::apply_for_global(globals_config, GlobalNo::Gas, |_| Ok(Some(gas_counter)))?
globals::apply_for_global(
globals_config,
globals_config.names[GlobalNo::Gas as usize].as_str(),
|current| {
diff = current - gas_counter;
Ok(Some(gas_counter))
},
)?
};

// support old runtimes
if globals_config.names.len() == 2
&& globals_config.names[1].as_str() == "gear_allowance"
{
unsafe {
globals::apply_for_global(globals_config, "gear_allowance", |current| {
Ok(Some(current.saturating_sub(diff)))
})?
};
}
}
Ok(())
}
Expand Down
26 changes: 24 additions & 2 deletions runtime-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ fn deserialize_mem_intervals(bytes: &[u8], intervals: &mut Vec<MemoryInterval>)
}
}

#[derive(Debug, Clone, Encode, Decode)]
#[codec(crate = codec)]
pub enum ProcessAccessErrorVer1 {
OutOfBounds,
GasLimitExceeded,
GasAllowanceExceeded,
}

/// Runtime interface for gear node and runtime.
/// Note: name is expanded as gear_ri
#[runtime_interface]
Expand All @@ -104,7 +112,7 @@ pub trait GearRI {
reads: &[MemoryInterval],
writes: &[MemoryInterval],
gas_left: (GasLeft,),
) -> (GasLeft, Result<(), ProcessAccessError>) {
) -> (GasLeft, Result<(), ProcessAccessErrorVer1>) {
let mut gas_left = gas_left.0;
let gas_before = gas_left.gas;
let res = lazy_pages::pre_process_memory_accesses(reads, writes, &mut gas_left.gas);
Expand All @@ -114,7 +122,21 @@ pub trait GearRI {
.allowance
.saturating_sub(gas_before.saturating_sub(gas_left.gas));

(gas_left, res)
match res {
Ok(_) => {
if gas_left.allowance > 0 {
(gas_left, Ok(()))
} else {
(gas_left, Err(ProcessAccessErrorVer1::GasAllowanceExceeded))
}
}
Err(ProcessAccessError::OutOfBounds) => {
(gas_left, Err(ProcessAccessErrorVer1::OutOfBounds))
}
Err(ProcessAccessError::GasLimitExceeded) => {
(gas_left, Err(ProcessAccessErrorVer1::GasLimitExceeded))
}
}
}

#[version(2)]
Expand Down

0 comments on commit 001e6ac

Please sign in to comment.