Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VM and Runtime updates #569

Merged
merged 26 commits into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4dfc78a
Setup network config params
austinabell Jul 17, 2020
2ea5e6a
Implement total circ supply for default runtime
austinabell Jul 17, 2020
f339a6d
Add actor error convenience macro
austinabell Jul 17, 2020
3b176c3
Switch actor error usage to macro in default runtime
austinabell Jul 17, 2020
0d35a7d
updates to runtime functions
austinabell Jul 17, 2020
ddd6d43
Switch message gas limit to i64
austinabell Jul 20, 2020
609bce0
Remove unnecessary conversions
austinabell Jul 20, 2020
55ca390
Switch to using MessageInfo trait for Runtime and refactor MockRuntim…
austinabell Jul 20, 2020
5dceb2a
Update runtime validations and refactor mock runtime usage
austinabell Jul 22, 2020
be1ca62
Update error handling in mock runtime
austinabell Jul 22, 2020
7261273
Update runtime function signatures
austinabell Jul 23, 2020
0839434
Update empty array CID and bytes references and refactor more methods
austinabell Jul 23, 2020
a07fa49
Update state handles
austinabell Jul 23, 2020
98dc1b5
Add allow internal flag in runtime
austinabell Jul 23, 2020
6e011ed
Refactor internal send functions
austinabell Jul 24, 2020
6d10354
misc cleanup
austinabell Jul 24, 2020
ae705ca
update actor initialization
austinabell Jul 24, 2020
2b9ed09
Update gas interfaces
austinabell Jul 24, 2020
3408306
Update runtime generation
austinabell Jul 25, 2020
aa26fe3
Update apply ret struct
austinabell Jul 25, 2020
d1de8c3
Small tweaks around message applying
austinabell Jul 27, 2020
feeb994
Update apply_message
austinabell Jul 27, 2020
15e4dd9
Merge branch 'main' of github.com:ChainSafe/forest into austin/vmupdate
austinabell Jul 27, 2020
01fe6d6
fix conflicts from merge
austinabell Jul 27, 2020
650c01d
merge main and resolve conflicts
austinabell Jul 28, 2020
e84d253
Merge branch 'main' into austin/vmupdate
austinabell Jul 28, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

20 changes: 12 additions & 8 deletions blockchain/state_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use cid::Cid;
use clock::ChainEpoch;
use encoding::de::DeserializeOwned;
use encoding::Cbor;
use fil_types::DevnetParams;
use flo_stream::Subscriber;
use forest_blocks::{Block, BlockHeader, FullTipset, Tipset, TipsetKeys};
use futures::channel::oneshot;
Expand Down Expand Up @@ -163,7 +164,8 @@ where
) -> Result<(Cid, Cid), Box<dyn StdError>> {
let mut buf_store = BufferedBlockStore::new(self.bs.as_ref());
// TODO possibly switch out syscalls to be saved at state manager level
let mut vm = VM::new(
// TODO change from statically using devnet params when needed
let mut vm = VM::<_, _, DevnetParams>::new(
ts.parent_state(),
&buf_store,
ts.epoch(),
Expand All @@ -172,7 +174,7 @@ where
)?;

// Apply tipset messages
let receipts = vm.apply_tip_set_messages(ts, callback)?;
let receipts = vm.apply_tipset_messages(ts, callback)?;

// Construct receipt root from receipts
let rect_root = Amt::new_from_slice(self.bs.as_ref(), &receipts)?;
Expand Down Expand Up @@ -238,7 +240,7 @@ where
span!("state_call_raw", {
let block_store = self.get_block_store_ref();
let buf_store = BufferedBlockStore::new(block_store);
let mut vm = VM::new(
let mut vm = VM::<_, _, DevnetParams>::new(
bstate,
&buf_store,
*bheight,
Expand All @@ -261,14 +263,14 @@ where
msg.gas_price(),
msg.value()
);
if let Some(err) = apply_ret.act_error() {
if let Some(err) = &apply_ret.act_error {
warn!("chain call failed: {:?}", err);
}

Ok(InvocResult {
msg: msg.clone(),
msg_rct: Some(apply_ret.msg_receipt().clone()),
actor_error: apply_ret.act_error().map(|e| e.to_string()),
msg_rct: Some(apply_ret.msg_receipt.clone()),
actor_error: apply_ret.act_error.map(|e| e.to_string()),
})
})
}
Expand Down Expand Up @@ -672,7 +674,7 @@ where
Ok(actor.balance)
}

pub fn lookup_id(&self, addr: &Address, ts: &Tipset) -> Result<Address, Error> {
pub fn lookup_id(&self, addr: &Address, ts: &Tipset) -> Result<Option<Address>, Error> {
let state_tree = StateTree::new_from_root(self.bs.as_ref(), ts.parent_state())?;
state_tree.lookup_id(addr).map_err(Error::State)
}
Expand All @@ -681,7 +683,9 @@ where
let market_state: market::State =
self.load_actor_state(&*STORAGE_MARKET_ACTOR_ADDR, ts.parent_state())?;

let new_addr = self.lookup_id(addr, ts)?;
let new_addr = self
.lookup_id(addr, ts)?
.ok_or_else(|| Error::State(format!("Failed to resolve address {}", addr)))?;

let out = MarketBalance {
escrow: {
Expand Down
6 changes: 3 additions & 3 deletions node/state_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@ where

Ok(InvocResult {
msg,
msg_rct: ret.clone().map(|s| s.msg_receipt().clone()),
msg_rct: ret.as_ref().map(|s| s.msg_receipt.clone()),
actor_error: ret
.map(|act| act.act_error().map(|e| e.to_string()))
.map(|act| act.act_error.map(|e| e.to_string()))
.unwrap_or_default(),
})
}
Expand Down Expand Up @@ -323,7 +323,7 @@ pub fn state_lookup_id<DB>(
state_manager: &StateManager<DB>,
address: &Address,
key: &TipsetKeys,
) -> Result<Address, BoxError>
) -> Result<Option<Address>, BoxError>
where
DB: BlockStore,
{
Expand Down
31 changes: 31 additions & 0 deletions types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,34 @@ pub mod sector;

pub use self::piece::*;
pub use self::sector::*;

use num_bigint::BigInt;

/// Config trait which handles different network configurations.
pub trait NetworkParams {
/// Total filecoin available to network.
const TOTAL_FILECOIN: i64;

/// Available rewards for mining.
const MINING_REWARD_TOTAL: i64;

/// Initial reward actor balance. This function is only called in genesis setting up state.
fn initial_reward_balance() -> BigInt {
BigInt::from(Self::MINING_REWARD_TOTAL) * Self::TOTAL_FILECOIN
}

/// Convert integer value of tokens into BigInt based on the token precision.
fn from_fil(i: i64) -> BigInt {
BigInt::from(i) * FILECOIN_PRECISION
}
}

// Not yet finalized
pub struct DevnetParams;
impl NetworkParams for DevnetParams {
const TOTAL_FILECOIN: i64 = 2_000_000_000;
const MINING_REWARD_TOTAL: i64 = 1_400_000_000;
}

/// Ratio of integer values to token value.
pub const FILECOIN_PRECISION: i64 = 1_000_000_000_000_000_000;
1 change: 1 addition & 0 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ cid = { package = "forest_cid", path = "../ipld/cid", version = "0.1", features
num-traits = "0.2"
num-derive = "0.3.0"
thiserror = "1.0.11"
lazy_static = "1.4"

[features]
json = []
4 changes: 2 additions & 2 deletions vm/actor/src/builtin/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ impl Actor {
}

// Fetches the pubkey-type address from this actor.
pub fn pubkey_address<BS, RT>(rt: &RT) -> Result<Address, ActorError>
pub fn pubkey_address<BS, RT>(rt: &mut RT) -> Result<Address, ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_accept_any();
rt.validate_immediate_caller_accept_any()?;
let st: State = rt.state()?;
Ok(st.address)
}
Expand Down
2 changes: 1 addition & 1 deletion vm/actor/src/builtin/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ lazy_static! {
pub static ref PAYCH_ACTOR_CODE_ID: Cid = make_builtin(b"fil/1/paymentchannel");
pub static ref MULTISIG_ACTOR_CODE_ID: Cid = make_builtin(b"fil/1/multisig");
pub static ref REWARD_ACTOR_CODE_ID: Cid = make_builtin(b"fil/1/reward");
pub static ref VERIFIED_ACTOR_CODE_ID: Cid = make_builtin(b"fil/1/verifiedregistry");
pub static ref VERIFREG_ACTOR_CODE_ID: Cid = make_builtin(b"fil/1/verifiedregistry");

// Set of actor code types that can represent external signing parties.
pub static ref CALLER_TYPES_SIGNABLE: [Cid; 2] =
Expand Down
6 changes: 3 additions & 3 deletions vm/actor/src/builtin/cron/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ impl Actor {
let st: State = rt.state()?;
for entry in st.entries {
let _v = rt.send(
&entry.receiver,
entry.receiver,
entry.method_num,
&Serialized::default(),
&TokenAmount::from(0u8),
Serialized::default(),
TokenAmount::from(0u8),
);
}
Ok(())
Expand Down
19 changes: 8 additions & 11 deletions vm/actor/src/builtin/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use ipld_blockstore::BlockStore;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use runtime::{ActorCode, Runtime};
use vm::{ActorError, ExitCode, MethodNum, Serialized, METHOD_CONSTRUCTOR};
use vm::{actor_error, ActorError, ExitCode, MethodNum, Serialized, METHOD_CONSTRUCTOR};

/// Init actor methods available
#[derive(FromPrimitive)]
Expand Down Expand Up @@ -56,17 +56,14 @@ impl Actor {
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_accept_any();
rt.validate_immediate_caller_accept_any()?;
let caller_code = rt
.get_actor_code_cid(rt.message().caller())
.expect("no code for actor");
.get_actor_code_cid(rt.message().caller())?
.ok_or_else(|| actor_error!(ErrForbidden; "No code for actor"))?;
if !can_exec(&caller_code, &params.code_cid) {
return Err(rt.abort(
ExitCode::ErrForbidden,
format!(
return Err(actor_error!(ErrForbidden;
"called type {} cannot exec actor type {}",
&caller_code, &params.code_cid
),
));
}

Expand All @@ -90,10 +87,10 @@ impl Actor {

// Invoke constructor
rt.send(
&id_address,
id_address,
METHOD_CONSTRUCTOR,
&params.constructor_params,
&rt.message().value_received().clone(),
params.constructor_params,
rt.message().value_received().clone(),
)
.map_err(|err| rt.abort(err.exit_code(), "constructor failed"))?;

Expand Down
12 changes: 5 additions & 7 deletions vm/actor/src/builtin/init/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,17 @@ impl State {
&self,
store: &BS,
addr: &Address,
) -> Result<Address, String> {
) -> Result<Option<Address>, String> {
if addr.protocol() == Protocol::ID {
return Ok(*addr);
return Ok(Some(*addr));
}

let map: Hamt<BytesKey, _> =
Hamt::load_with_bit_width(&self.address_map, store, HAMT_BIT_WIDTH)?;

let actor_id: ActorID = map
.get(&addr.to_bytes())?
.ok_or_else(|| "Address not found".to_owned())?;

Ok(Address::new_id(actor_id))
Ok(map
.get::<_, ActorID>(&addr.to_bytes())?
.map(Address::new_id))
}
}

Expand Down
70 changes: 33 additions & 37 deletions vm/actor/src/builtin/market/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use num_derive::FromPrimitive;
use num_traits::{FromPrimitive, Zero};
use runtime::{ActorCode, Runtime};
use vm::{
ActorError, ExitCode, MethodNum, Serialized, TokenAmount, METHOD_CONSTRUCTOR, METHOD_SEND,
actor_error, ActorError, ExitCode, MethodNum, Serialized, TokenAmount, METHOD_CONSTRUCTOR,
METHOD_SEND,
};

/// Market actor methods available
Expand Down Expand Up @@ -154,17 +155,17 @@ impl Actor {
// TODO this will never be hit
if amount_slashed_total > BigInt::zero() {
rt.send(
&*BURNT_FUNDS_ACTOR_ADDR,
*BURNT_FUNDS_ACTOR_ADDR,
METHOD_SEND,
&Serialized::default(),
&amount_slashed_total,
Serialized::default(),
amount_slashed_total,
)?;
}
rt.send(
&recipient,
recipient,
METHOD_SEND,
&Serialized::default(),
&amount_extracted,
Serialized::default(),
amount_extracted,
)?;
Ok(())
}
Expand All @@ -189,10 +190,12 @@ impl Actor {
}

// All deals should have the same provider so get worker once
let provider_raw = &params.deals[0].proposal.provider;
let provider = rt.resolve_address(&provider_raw)?;
let provider_raw = params.deals[0].proposal.provider;
let provider = rt.resolve_address(&provider_raw)?.ok_or_else(
|| actor_error!(ErrNotFound; "failed to resolve provider address {}", provider_raw),
)?;

let (_, worker) = request_miner_control_addrs(rt, &provider)?;
let (_, worker) = request_miner_control_addrs(rt, provider)?;
if &worker != rt.message().caller() {
return Err(ActorError::new(
ExitCode::ErrForbidden,
Expand All @@ -210,18 +213,14 @@ impl Actor {
deal_size: BigInt::from(deal.proposal.piece_size.0),
})?;
rt.send(
&*VERIFIED_REGISTRY_ACTOR_ADDR,
*VERIFIED_REGISTRY_ACTOR_ADDR,
VerifregMethod::UseBytes as u64,
&ser_params,
&TokenAmount::zero(),
ser_params,
TokenAmount::zero(),
)?;
}
}

// All deals should have the same provider so get worker once
let provider_raw = params.deals[0].proposal.provider;
let provider = rt.resolve_address(&provider_raw)?;

let mut new_deal_ids: Vec<DealID> = Vec::new();
rt.transaction(|st: &mut State, rt| {
let mut prop = Amt::load(&st.proposals, rt.store())
Expand All @@ -240,7 +239,10 @@ impl Actor {
));
}

let client = rt.resolve_address(&deal.proposal.client)?;
let client = rt.resolve_address(&deal.proposal.client)?.ok_or_else(|| {
actor_error!(ErrNotFound;
"failed to resolve provider address {}", provider_raw)
})?;
// Normalise provider and client addresses in the proposal stored on chain (after signature verification).
deal.proposal.provider = provider;
deal.proposal.client = client;
Expand Down Expand Up @@ -615,18 +617,18 @@ impl Actor {
deal_size: BigInt::from(d.piece_size.0),
})?;
rt.send(
&*VERIFIED_REGISTRY_ACTOR_ADDR,
*VERIFIED_REGISTRY_ACTOR_ADDR,
VerifregMethod::RestoreBytes as u64,
&ser_params,
&TokenAmount::zero(),
ser_params,
TokenAmount::zero(),
)?;
}

rt.send(
&*BURNT_FUNDS_ACTOR_ADDR,
*BURNT_FUNDS_ACTOR_ADDR,
METHOD_SEND,
&Serialized::default(),
&amount_slashed,
Serialized::default(),
amount_slashed,
)?;
Ok(())
}
Expand Down Expand Up @@ -768,19 +770,13 @@ where
RT: Runtime<BS>,
{
// Resolve the provided address to the canonical form against which the balance is held.
let nominal = rt.resolve_address(addr).map_err(|e| {
ActorError::new(
ExitCode::ErrIllegalArgument,
format!("Failed to resolve address provided: {}", e),
)
})?;
let nominal = rt
.resolve_address(addr)?
.ok_or_else(|| actor_error!(ErrIllegalArgument; "failed to resolve address {}", addr))?;

let code_id = rt.get_actor_code_cid(&nominal).map_err(|e| {
ActorError::new(
ExitCode::ErrIllegalArgument,
format!("Failed to retrieve actor code cid: {}", e),
)
})?;
let code_id = rt
.get_actor_code_cid(&nominal)?
.ok_or_else(|| actor_error!(ErrIllegalArgument; "no code for address {}", nominal))?;

if code_id != *MINER_ACTOR_CODE_ID {
// Ordinary account-style actor entry; funds recipient is just the entry address itself.
Expand All @@ -789,7 +785,7 @@ where
}

// Storage miner actor entry; implied funds recipient is the associated owner address.
let (owner_addr, worker_addr) = request_miner_control_addrs(rt, &nominal)?;
let (owner_addr, worker_addr) = request_miner_control_addrs(rt, nominal)?;
rt.validate_immediate_caller_is([owner_addr, worker_addr].iter())?;
Ok((nominal, owner_addr))
}
Expand Down
Loading