Skip to content

Commit

Permalink
Merge pull request #288 from filecoin-project/feat/debug-execution
Browse files Browse the repository at this point in the history
fvm debug execution
  • Loading branch information
arajasek authored Jun 23, 2022
2 parents 0dd7631 + 0b00ec8 commit 0d607fd
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 53 deletions.
27 changes: 27 additions & 0 deletions cgo/fvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,33 @@ func CreateFvmMachine(fvmVersion FvmRegisteredVersion, chainEpoch, baseFeeHi, ba
return executor, nil
}

func CreateFvmDebugMachine(fvmVersion FvmRegisteredVersion, chainEpoch, baseFeeHi, baseFeeLo, baseCircSupplyHi, baseCircSupplyLo, networkVersion uint64, stateRoot SliceRefUint8, actorRedirect SliceRefUint8, tracing bool, blockstoreId, externsId uint64) (*FvmMachine, error) {
resp := C.create_fvm_debug_machine(
fvmVersion,
C.uint64_t(chainEpoch),
C.uint64_t(baseFeeHi),
C.uint64_t(baseFeeLo),
C.uint64_t(baseCircSupplyHi),
C.uint64_t(baseCircSupplyLo),
C.uint64_t(networkVersion),
stateRoot,
actorRedirect,
C.bool(tracing),
C.uint64_t(blockstoreId),
C.uint64_t(externsId),
)
// take out the pointer from the result to ensure it doesn't get freed
executor := resp.value
resp.value = nil
defer resp.destroy()

if err := CheckErr(resp); err != nil {
return nil, err
}

return executor, nil
}

func FvmMachineExecuteMessage(executor *FvmMachine, message SliceRefUint8, chainLen, applyKind uint64) (FvmMachineExecuteResponseGo, error) {
resp := C.fvm_machine_execute_message(
executor,
Expand Down
44 changes: 32 additions & 12 deletions fvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type FVMOpts struct {
StateBase cid.Cid
Manifest cid.Cid
Tracing bool

Debug bool
ActorRedirect cid.Cid
}

// CreateFVM creates a new FVM instance.
Expand All @@ -56,18 +59,35 @@ func CreateFVM(opts *FVMOpts) (*FVM, error) {
}

exHandle := cgo.Register(context.TODO(), opts.Externs)
executor, err := cgo.CreateFvmMachine(cgo.FvmRegisteredVersion(opts.FVMVersion),
uint64(opts.Epoch),
baseFeeHi,
baseFeeLo,
baseCircSupplyHi,
baseCircSupplyLo,
uint64(opts.NetworkVersion),
cgo.AsSliceRefUint8(opts.StateBase.Bytes()),
cgo.AsSliceRefUint8(opts.Manifest.Bytes()),
opts.Tracing,
exHandle, exHandle,
)
var executor *cgo.FvmMachine
if !opts.Debug {
executor, err = cgo.CreateFvmMachine(cgo.FvmRegisteredVersion(opts.FVMVersion),
uint64(opts.Epoch),
baseFeeHi,
baseFeeLo,
baseCircSupplyHi,
baseCircSupplyLo,
uint64(opts.NetworkVersion),
cgo.AsSliceRefUint8(opts.StateBase.Bytes()),
cgo.AsSliceRefUint8(opts.Manifest.Bytes()),
opts.Tracing,
exHandle, exHandle,
)
} else {
executor, err = cgo.CreateFvmDebugMachine(cgo.FvmRegisteredVersion(opts.FVMVersion),
uint64(opts.Epoch),
baseFeeHi,
baseFeeLo,
baseCircSupplyHi,
baseCircSupplyLo,
uint64(opts.NetworkVersion),
cgo.AsSliceRefUint8(opts.StateBase.Bytes()),
cgo.AsSliceRefUint8(opts.ActorRedirect.Bytes()),
opts.Tracing,
exHandle, exHandle,
)
}

if err != nil {
return nil, err
}
Expand Down
24 changes: 8 additions & 16 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,11 @@ c-headers = ["safer-ffi/headers"]

[patch.crates-io]
wasmtime = { git = "https://github.com/filecoin-project/wasmtime", branch = "fix/sse-feature" }
fvm = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_shared = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_sdk = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_ipld_hamt = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_ipld_amt = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_ipld_bitfield = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_ipld_encoding = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
fvm_ipld_blockstore = { git = "https://github.com/filecoin-project/ref-fvm", branch = "release/v1" }
140 changes: 115 additions & 25 deletions rust/src/fvm/machine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::convert::{TryFrom, TryInto};
use std::sync::Mutex;

use anyhow::{anyhow, bail};
use anyhow::{anyhow, bail, Context};
use cid::Cid;
use futures::executor::block_on;
use fvm::call_manager::DefaultCallManager;
Expand All @@ -12,7 +12,7 @@ use fvm::DefaultKernel;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_car::load_car;
use fvm_ipld_encoding::tuple::{Deserialize_tuple, Serialize_tuple};
use fvm_ipld_encoding::{to_vec, RawBytes};
use fvm_ipld_encoding::{to_vec, CborStore, RawBytes};
use fvm_shared::address::Address;
use fvm_shared::error::{ErrorNumber, ExitCode};
use fvm_shared::receipt::Receipt;
Expand Down Expand Up @@ -40,12 +40,8 @@ lazy_static! {
static ref ENGINES: MultiEngine = MultiEngine::new();
}

/// Note: the incoming args as u64 and odd conversions to i32/i64
/// for some types is due to the generated bindings not liking the
/// 32bit types as incoming args
///
#[ffi_export]
fn create_fvm_machine(
#[allow(clippy::too_many_arguments)]
fn create_fvm_machine_generic(
fvm_version: FvmRegisteredVersion,
chain_epoch: u64,
base_fee_hi: u64,
Expand All @@ -54,7 +50,9 @@ fn create_fvm_machine(
base_circ_supply_lo: u64,
network_version: u64,
state_root: c_slice::Ref<u8>,
manifest_cid: c_slice::Ref<u8>,
manifest_cid: Option<c_slice::Ref<u8>>,
actor_redirect: Option<c_slice::Ref<u8>>,
actor_debug: bool,
tracing: bool,
blockstore_id: u64,
externs_id: u64,
Expand All @@ -80,20 +78,17 @@ fn create_fvm_machine(
let state_root = Cid::try_from(&state_root[..])
.map_err(|err| anyhow!("invalid state root: {}", err))?;

let manifest_cid = if !manifest_cid.is_empty() {
let cid = Cid::try_from(&manifest_cid[..])
.map_err(|err| anyhow!("invalid manifest: {}", err))?;
Some(cid)
} else {
// handle cid.Undef for no manifest
// this can mean two things:
// - for pre nv16, use the builtin bundles
// - for nv16 or higher, it means we have already migrated state for system
// actor and we can pass None to the machine constructor to fish it from state.
// The presence of the manifest cid argument allows us to test with new bundles
// with minimum friction.
None
};
// There may be no manifest CID:
// - for pre nv16, use the builtin bundles
// - for nv16 or higher, it means we have already migrated state for system
// actor and we can pass None to the machine constructor to fish it from state.
// The presence of the manifest cid argument allows us to test with new bundles
// with minimum friction.
let manifest_cid = manifest_cid
.as_deref() // into a slice
.map(Cid::try_from) // into a cid
.transpose() // Option<Result<Cid>> -> Result<Option<Cid>>
.context("invalid manifest")?;

let blockstore = FakeBlockstore::new(CgoBlockstore::new(blockstore_id));

Expand All @@ -102,9 +97,28 @@ fn create_fvm_machine(
Ok(Some(manifest)) => {
network_config.override_actors(manifest);
}
Ok(None) => {}
Ok(None) => (),
Err(err) => bail!("couldn't load builtin actors: {}", err),
}

if actor_debug {
network_config.enable_actor_debugging();
}

let blockstore = blockstore.finish();
if let Some(ar) = actor_redirect {
let actor_redirect_cid = Cid::try_from(&ar[..])
.map_err(|err| anyhow!("invalid redirect CID: {}", err))?;
let redirect: Vec<(Cid, Cid)> = match blockstore
.get_cbor(&actor_redirect_cid)
.map_err(|err| anyhow!("invalid redirect cid: {}", err))?
{
Some(v) => v,
None => bail!("failed to create engine: missing redirect vector"),
};
network_config.redirect_actors(redirect);
}

let mut machine_context = network_config.for_epoch(chain_epoch, state_root);

machine_context
Expand All @@ -114,7 +128,6 @@ fn create_fvm_machine(
if tracing {
machine_context.enable_tracing();
}
let blockstore = blockstore.finish();

let externs = CgoExterns::new(externs_id);

Expand All @@ -131,6 +144,83 @@ fn create_fvm_machine(
})
}
}
/// Note: the incoming args as u64 and odd conversions to i32/i64
/// for some types is due to the generated bindings not liking the
/// 32bit types as incoming args
///
#[ffi_export]
fn create_fvm_machine(
fvm_version: FvmRegisteredVersion,
chain_epoch: u64,
base_fee_hi: u64,
base_fee_lo: u64,
base_circ_supply_hi: u64,
base_circ_supply_lo: u64,
network_version: u64,
state_root: c_slice::Ref<u8>,
manifest_cid: c_slice::Ref<u8>,
tracing: bool,
blockstore_id: u64,
externs_id: u64,
) -> repr_c::Box<Result<FvmMachine>> {
create_fvm_machine_generic(
fvm_version,
chain_epoch,
base_fee_hi,
base_fee_lo,
base_circ_supply_hi,
base_circ_supply_lo,
network_version,
state_root,
if manifest_cid.is_empty() {
None
} else {
Some(manifest_cid)
},
None,
false,
tracing,
blockstore_id,
externs_id,
)
}

#[ffi_export]
fn create_fvm_debug_machine(
fvm_version: FvmRegisteredVersion,
chain_epoch: u64,
base_fee_hi: u64,
base_fee_lo: u64,
base_circ_supply_hi: u64,
base_circ_supply_lo: u64,
network_version: u64,
state_root: c_slice::Ref<u8>,
actor_redirect: c_slice::Ref<u8>,
tracing: bool,
blockstore_id: u64,
externs_id: u64,
) -> repr_c::Box<Result<FvmMachine>> {
create_fvm_machine_generic(
fvm_version,
chain_epoch,
base_fee_hi,
base_fee_lo,
base_circ_supply_hi,
base_circ_supply_lo,
network_version,
state_root,
None,
if actor_redirect.is_empty() {
None
} else {
Some(actor_redirect)
},
true,
tracing,
blockstore_id,
externs_id,
)
}

#[ffi_export]
fn fvm_machine_execute_message(
Expand Down

0 comments on commit 0d607fd

Please sign in to comment.