Skip to content

Commit

Permalink
fix state invariant issues at genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
alexytsu committed Oct 17, 2023
1 parent a2ebc54 commit 4eb7dfe
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 13 deletions.
119 changes: 118 additions & 1 deletion Cargo.lock

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

5 changes: 4 additions & 1 deletion api/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub trait WorkbenchBuilder {

/// Creates a workbench ready to execute messages.
/// The System and Init actors must be created before a workbench can be built or used.
fn build(&mut self) -> anyhow::Result<Box<dyn Bench>>;
fn build(&mut self, circulating_supply: TokenAmount) -> anyhow::Result<Box<dyn Bench>>;
}

/// A VM workbench that can execute messages to actors.
Expand Down Expand Up @@ -82,6 +82,9 @@ pub trait Bench {
/// referenced elsewhere)
fn flush(&mut self) -> Cid;

/// Gets a generic state root (ActorMap)
fn state_root(&mut self) -> Cid;

/// Get a manifest of the builtin actors
fn builtin_actors_manifest(&self) -> BTreeMap<Cid, vm_api::builtin::Type>;

Expand Down
2 changes: 1 addition & 1 deletion api/src/wrangler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ impl VM for ExecutionWrangler {
}

fn state_root(&self) -> cid::Cid {
self.bench.borrow_mut().flush()
self.bench.borrow_mut().state_root()
}

fn set_actor(&self, key: &Address, state: ActorState) {
Expand Down
11 changes: 8 additions & 3 deletions builtin/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use fil_actors_runtime::{
STORAGE_MARKET_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ID, STORAGE_POWER_ACTOR_ADDR,
STORAGE_POWER_ACTOR_ID, SYSTEM_ACTOR_ID, VERIFIED_REGISTRY_ACTOR_ID,
};
use fvm_shared::address::Address;
use fvm_shared::address::{Address, BLS_PUB_LEN};
use fvm_shared::bigint::Zero;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::StoragePower;
Expand Down Expand Up @@ -189,12 +189,17 @@ pub fn create_genesis_actors<B: WorkbenchBuilder>(
)?;

// Faucet account
let faucet_state = fil_actor_account::State { address: TEST_FAUCET_ADDR };
// user space account must be a BLS or SECP address
let address = Address::new_bls(&[0; BLS_PUB_LEN]).unwrap();
let faucet_state = fil_actor_account::State { address };
let faucet_id = builder.create_builtin_actor(
Type::Account as u32,
&TEST_FAUCET_ADDR,
&address,
&faucet_state,
spec.faucet_balance.clone(),
)?;
// match builtin-actor's test expectation of a FAUCET_ACTOR as the first user-space actor
assert_eq!(faucet_id, TEST_FAUCET_ADDR.id().unwrap());

Ok(GenesisResult { verifreg_signer_id, verifreg_root_id, faucet_id })
}
3 changes: 2 additions & 1 deletion builtin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub fn setup() -> ExecutionWrangler {
.unwrap();
let spec = GenesisSpec::default(manifest_data_cid);
let _genesis = create_genesis_actors(&mut builder, &spec).unwrap();
let bench = builder.build().unwrap();
let circulating_supply = &spec.reward_balance + &spec.faucet_balance;
let bench = builder.build(circulating_supply).unwrap();
ExecutionWrangler::new_default(bench, Box::new(store), Box::new(FakePrimitives {}))
}
24 changes: 21 additions & 3 deletions builtin/tests/builtin_actors_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,25 @@ fn benchmark_builtin_actors() {
#[test]
fn problematic_test() {
let w = &setup();
// =============
aggregate_bad_sector_number_test(w);
// ============
// =============
change_beneficiary_success_test(w);
// =============
}

// do not commit: run the problematic test here to isolate it's failure
#[test]
fn problematic_test_2() {
let w = &setup();
// =============
placeholder_deploy_test(w);
// =============
}

// do not commit: run the problematic test here to isolate it's failure
#[test]
fn problematic_test_3() {
let w = &setup();
// =============
evm_eth_create_external_test(w);
// =============
}
44 changes: 43 additions & 1 deletion vm/src/bench/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ use std::collections::BTreeMap;
use anyhow::anyhow;

use cid::Cid;
use futures::stream::iter;
use fvm::call_manager::DefaultCallManager;
use fvm::engine::EnginePool;
use fvm::executor::{ApplyKind, ApplyRet, DefaultExecutor, Executor};
use fvm::machine::{DefaultMachine, Machine};
use fvm::state_tree::StateTree;
use fvm::trace::ExecutionEvent;
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::address::Address;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::message::Message;
use fvm_shared::ActorID;
use fvm_workbench_api::blockstore::DynBlockstore;
use fvm_workbench_api::trace::ExecutionEvent::{
Call, CallError, CallReturn, GasCharge, InvokeActor,
};
Expand Down Expand Up @@ -150,6 +153,11 @@ where
let manifest = self.executor.builtin_actors();
let mut map = BTreeMap::new();

let system = manifest.code_by_id(1);
if let Some(code) = system {
map.insert(*code, vm_api::builtin::Type::System);
}

let init = manifest.code_by_id(2);
if let Some(code) = init {
map.insert(*code, vm_api::builtin::Type::Init);
Expand Down Expand Up @@ -197,14 +205,39 @@ where

let verifreg = manifest.code_by_id(11);
if let Some(code) = verifreg {
map.insert(*code, vm_api::builtin::Type::Reward);
map.insert(*code, vm_api::builtin::Type::VerifiedRegistry);
}

let datacap = manifest.code_by_id(12);
if let Some(code) = datacap {
map.insert(*code, vm_api::builtin::Type::DataCap);
}

let placeholder = manifest.code_by_id(13);
if let Some(code) = placeholder {
map.insert(*code, vm_api::builtin::Type::Placeholder);
}

let evm = manifest.code_by_id(14);
if let Some(code) = evm {
map.insert(*code, vm_api::builtin::Type::EVM);
}

let eam = manifest.code_by_id(15);
if let Some(code) = eam {
map.insert(*code, vm_api::builtin::Type::EAM);
}

let ethaccount = manifest.code_by_id(16);
if let Some(code) = ethaccount {
map.insert(*code, vm_api::builtin::Type::EthAccount);
}

println!("Constructed bactors manifest");
map.iter().for_each(|(code, value)| {
println!("Id: {:?}, Code: {}, Name: {}", *value as i32, code, value.name());
});

map
}

Expand Down Expand Up @@ -234,6 +267,15 @@ where
.unwrap()
});
}

fn state_root(&mut self) -> Cid {
let fvm_root_cid = self.flush();
// FIXME: this is a hack that may leave other parts of the state_tree unflushed
// in reality, the check state_invariants method should ask for the tree directly rather than a Cid to the tree
let mut tree =
StateTree::new_from_root(DynBlockstore::new(self.store()), &fvm_root_cid).unwrap();
tree.hamt.flush().unwrap()
}
}

// Converts an FVM-internal application result to an API execution result.
Expand Down
Loading

0 comments on commit 4eb7dfe

Please sign in to comment.