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

Clean actors and update to spec #279

Merged
merged 11 commits into from
Mar 16, 2020
8 changes: 4 additions & 4 deletions blockchain/state_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
mod errors;

pub use self::errors::*;
use actor::{ActorState, MinerInfo, StorageMinerActorState};
use actor::{miner, ActorState};
use address::Address;
use blockstore::BlockStore;
use encoding::de::DeserializeOwned;
Expand Down Expand Up @@ -40,13 +40,13 @@ where
}
/// Returns the epoch at which the miner was slashed at
pub fn miner_slashed(&self, addr: &Address, ts: &Tipset) -> Result<u64, Error> {
let act: StorageMinerActorState = self.load_actor_state(addr, ts)?;
let act: miner::State = self.load_actor_state(addr, ts)?;
Ok(act.slashed_at)
}
/// Returns the amount of space in each sector committed to the network by this miner
pub fn miner_sector_size(&self, addr: &Address, ts: &Tipset) -> Result<u64, Error> {
let act: StorageMinerActorState = self.load_actor_state(addr, ts)?;
let info: MinerInfo = self.bs.get(&act.info)?.ok_or_else(|| {
let act: miner::State = self.load_actor_state(addr, ts)?;
let info: miner::MinerInfo = self.bs.get(&act.info)?.ok_or_else(|| {
Error::State("Could not retrieve miner info from IPLD store".to_owned())
})?;
Ok(*info.sector_size())
Expand Down
50 changes: 0 additions & 50 deletions vm/actor/src/builtin/account.rs

This file was deleted.

83 changes: 83 additions & 0 deletions vm/actor/src/builtin/account/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

mod state;

pub use self::state::State;
use crate::{assert_empty_params, empty_return};
use address::{Address, Protocol};
use ipld_blockstore::BlockStore;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use runtime::{ActorCode, Runtime};
use vm::{ExitCode, MethodNum, Serialized, METHOD_CONSTRUCTOR};

/// Account actor methods available
#[derive(FromPrimitive)]
pub enum Method {
Constructor = METHOD_CONSTRUCTOR,
PubkeyAddress = 2,
}

impl Method {
/// from_method_num converts a method number into a Method enum
fn from_method_num(m: MethodNum) -> Option<Method> {
FromPrimitive::from_u64(u64::from(m))
}
}

/// Account Actor
pub struct Actor;
impl Actor {
/// Constructor for Account actor
pub fn constructor<BS, RT>(rt: &RT, address: Address)
where
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_is(std::iter::once(&address));
match address.protocol() {
Protocol::Secp256k1 | Protocol::BLS => (),
protocol => rt.abort(
ExitCode::ErrIllegalArgument,
format!("address must use BLS or SECP protocol, got {}", protocol),
),
}
rt.create(&State { address })
}

// Fetches the pubkey-type address from this actor.
pub fn pubkey_address<BS, RT>(rt: &RT) -> Address
where
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_accept_any();
let st: State = rt.state();
st.address
}
}

impl ActorCode for Actor {
fn invoke_method<BS, RT>(&self, rt: &RT, method: MethodNum, params: &Serialized) -> Serialized
where
BS: BlockStore,
RT: Runtime<BS>,
{
match Method::from_method_num(method) {
Some(Method::Constructor) => {
Self::constructor(rt, params.deserialize().unwrap());
empty_return()
}
Some(Method::PubkeyAddress) => {
assert_empty_params(params);
Self::pubkey_address(rt);
empty_return()
}
_ => {
rt.abort(ExitCode::SysErrInvalidMethod, "Invalid method".to_owned());
unreachable!();
}
}
}
}
33 changes: 33 additions & 0 deletions vm/actor/src/builtin/account/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use address::Address;
use encoding::Cbor;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// State includes the address for the actor
pub struct State {
pub address: Address,
}

/// Account actor state
impl Serialize for State {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
[&self.address].serialize(serializer)
}
}

impl<'de> Deserialize<'de> for State {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let [address]: [Address; 1] = Deserialize::deserialize(deserializer)?;
Ok(Self { address })
}
}

impl Cbor for State {}
87 changes: 0 additions & 87 deletions vm/actor/src/builtin/cron.rs

This file was deleted.

116 changes: 116 additions & 0 deletions vm/actor/src/builtin/cron/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

mod state;

pub use self::state::{Entry, State};
use crate::{assert_empty_params, empty_return};
use ipld_blockstore::BlockStore;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use runtime::{ActorCode, Runtime};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use vm::{ExitCode, MethodNum, Serialized, METHOD_CONSTRUCTOR};

/// Cron actor methods available
#[derive(FromPrimitive)]
pub enum Method {
Constructor = METHOD_CONSTRUCTOR,
EpochTick = 2,
}

impl Method {
/// from_method_num converts a method number into an Method enum
fn from_method_num(m: MethodNum) -> Option<Method> {
FromPrimitive::from_u64(u64::from(m))
}
}

/// Constructor parameters for Cron actor, contains entries
/// of actors and methods to call on each epoch
#[derive(Default)]
pub struct ConstructorParams {
/// Entries is a set of actors (and corresponding methods) to call during EpochTick.
pub entries: Vec<Entry>,
}

impl Serialize for ConstructorParams {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.entries.serialize(serializer)
}
}

impl<'de> Deserialize<'de> for ConstructorParams {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let entries: Vec<Entry> = Deserialize::deserialize(deserializer)?;
Ok(Self { entries })
}
}

/// Cron actor
pub struct Actor;
impl Actor {
/// Constructor for Cron actor
fn constructor<BS, RT>(_rt: &RT, _params: ConstructorParams)
where
BS: BlockStore,
RT: Runtime<BS>,
{
// TODO now finished spec
todo!()
}
/// epoch_tick executes built-in periodic actions, run at every Epoch.
/// epoch_tick(r) is called after all other messages in the epoch have been applied.
/// This can be seen as an implicit last message.
fn epoch_tick<BS, RT>(_rt: &RT)
where
BS: BlockStore,
RT: Runtime<BS>,
{
// self.entries is basically a static registry for now, loaded
// in the interpreter static registry.
// TODO update to new spec
todo!()
// for entry in &self.entries {
// let res = rt.send_catching_errors(InvocInput {
// to: entry.to_addr.clone(),
// method: entry.method_num,
// params: Serialized::default(),
// value: TokenAmount::new(0),
// });
// if let Err(e) = res {
// return e.into();
// }
// }
}
}

impl ActorCode for Actor {
fn invoke_method<BS, RT>(&self, rt: &RT, method: MethodNum, params: &Serialized) -> Serialized
where
BS: BlockStore,
RT: Runtime<BS>,
{
match Method::from_method_num(method) {
Some(Method::Constructor) => {
Self::constructor(rt, params.deserialize().unwrap());
empty_return()
}
Some(Method::EpochTick) => {
assert_empty_params(params);
Self::epoch_tick(rt);
empty_return()
}
_ => {
rt.abort(ExitCode::SysErrInvalidMethod, "Invalid method".to_owned());
unreachable!();
}
}
}
}
Loading