Skip to content

Commit 8799f1d

Browse files
authored
Implement FIP-0032 (#452)
1 parent a8bdd28 commit 8799f1d

File tree

12 files changed

+519
-107
lines changed

12 files changed

+519
-107
lines changed

fvm/src/call_manager/default.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use anyhow::Context as _;
1+
use anyhow::Context;
22
use derive_more::{Deref, DerefMut};
33
use fvm_ipld_encoding::{RawBytes, DAG_CBOR};
44
use fvm_shared::actor::builtin::Type;
55
use fvm_shared::address::{Address, Protocol};
66
use fvm_shared::econ::TokenAmount;
77
use fvm_shared::error::ExitCode;
8+
use fvm_shared::version::NetworkVersion;
89
use fvm_shared::{ActorID, MethodNum, METHOD_SEND};
910
use num_traits::Zero;
1011

@@ -294,7 +295,19 @@ where
294295
};
295296

296297
// Make a store.
298+
let gas_available = kernel.gas_available();
299+
let exec_units_to_add = match kernel.network_version() {
300+
NetworkVersion::V14 | NetworkVersion::V15 => i64::MAX,
301+
_ => kernel.price_list().gas_to_exec_units(gas_available, false),
302+
};
303+
297304
let mut store = engine.new_store(kernel);
305+
if let Err(err) = store.add_fuel(u64::try_from(exec_units_to_add).unwrap_or(0)) {
306+
return (
307+
Err(ExecutionError::Fatal(err)),
308+
store.into_data().kernel.take(),
309+
);
310+
}
298311

299312
// Instantiate the module.
300313
let instance = match engine
@@ -315,12 +328,30 @@ where
315328
.map_err(Abort::Fatal)?;
316329

317330
// Invoke it.
318-
let return_block_id = invoke.call(&mut store, (param_id,))?;
331+
let res = invoke.call(&mut store, (param_id,));
332+
333+
// Charge gas for the "latest" use of execution units (all the exec units used since the most recent syscall)
334+
// We do this by first loading the _total_ execution units consumed
335+
let exec_units_consumed = store
336+
.fuel_consumed()
337+
.context("expected to find fuel consumed")
338+
.map_err(Abort::Fatal)?;
339+
// Then, pass the _total_ exec_units_consumed to the InvocationData,
340+
// which knows how many execution units had been consumed at the most recent snapshot
341+
// It will charge gas for the delta between the total units (the number we provide) and its snapshot
342+
store
343+
.data_mut()
344+
.charge_gas_for_exec_units(exec_units_consumed)
345+
.map_err(|e| Abort::from_error(ExitCode::SYS_ASSERTION_FAILED, e))?;
346+
347+
// If the invocation failed due to running out of exec_units, we have already detected it and returned OutOfGas above.
348+
// Any other invocation failure is returned here as an Abort
349+
let return_block_id = res?;
319350

320351
// Extract the return value, if there is one.
321352
let return_value: RawBytes = if return_block_id > NO_DATA_BLOCK_ID {
322353
let (code, ret) = store
323-
.data()
354+
.data_mut()
324355
.kernel
325356
.block_get(return_block_id)
326357
.map_err(|e| Abort::from_error(ExitCode::SYS_MISSING_RETURN, e))?;

fvm/src/call_manager/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use crate::Kernel;
1212

1313
pub mod backtrace;
1414
pub use backtrace::Backtrace;
15+
1516
mod default;
17+
1618
pub use default::DefaultCallManager;
1719

1820
/// BlockID representing nil parameters or return data.
@@ -81,7 +83,7 @@ pub trait CallManager: 'static {
8183

8284
/// Returns the current price list.
8385
fn price_list(&self) -> &PriceList {
84-
&self.machine().context().price_list
86+
self.machine().context().price_list
8587
}
8688

8789
/// Returns the machine context.
@@ -118,9 +120,9 @@ pub trait CallManager: 'static {
118120

119121
/// The result of a method invocation.
120122
pub enum InvocationResult {
121-
/// Indicates that the actor sucessfully returned. The value may be empty.
123+
/// Indicates that the actor successfully returned. The value may be empty.
122124
Return(RawBytes),
123-
/// Indicates taht the actor aborted with the given exit code.
125+
/// Indicates that the actor aborted with the given exit code.
124126
Failure(ExitCode),
125127
}
126128

0 commit comments

Comments
 (0)