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

Implement Verify Registry Actor #413

Merged
merged 52 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
e124b12
implemented state
StaticallyTypedAnxiety May 12, 2020
75fd786
added add and delete verifier methods
StaticallyTypedAnxiety May 12, 2020
3e63c00
applied cargo fix
StaticallyTypedAnxiety May 12, 2020
de1c05d
implemented all the methods
StaticallyTypedAnxiety May 12, 2020
8e415cd
added traits
StaticallyTypedAnxiety May 12, 2020
7f52fc1
takes reference instead
StaticallyTypedAnxiety May 13, 2020
0224c24
made a few fixes
StaticallyTypedAnxiety May 13, 2020
34c3064
fixes
StaticallyTypedAnxiety May 13, 2020
b39110f
fmt changes
StaticallyTypedAnxiety May 13, 2020
5f0ba24
Merge branch 'master' into ashanti/registryimpl
StaticallyTypedAnxiety May 13, 2020
3a6834a
added license
StaticallyTypedAnxiety May 13, 2020
52a1b60
license headers
StaticallyTypedAnxiety May 13, 2020
6cccc57
license headers
StaticallyTypedAnxiety May 13, 2020
1700414
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
d9ab999
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
867916c
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
c400111
removed datacap new type
StaticallyTypedAnxiety May 13, 2020
d5835a7
run cargo fmt
StaticallyTypedAnxiety May 13, 2020
35c13ce
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
896729c
imports fixed
StaticallyTypedAnxiety May 13, 2020
ed39849
fmt
StaticallyTypedAnxiety May 13, 2020
02c98ee
Update vm/actor/src/builtin/verifreg/state.rs
StaticallyTypedAnxiety May 13, 2020
c1faf45
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
d49699c
fixes
StaticallyTypedAnxiety May 13, 2020
131f689
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
589fa18
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
dea7926
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
e6630a9
changes
StaticallyTypedAnxiety May 13, 2020
e082fac
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
dc3a40d
changed error return type
StaticallyTypedAnxiety May 13, 2020
edb3e8e
changed back
StaticallyTypedAnxiety May 13, 2020
e1a9d44
illegal argument type changed to
StaticallyTypedAnxiety May 13, 2020
7ac9ae8
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
1099d2b
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
9edc803
changed get verified client
StaticallyTypedAnxiety May 13, 2020
c37cf1b
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
ba0a252
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
29815e7
updated CIDs and other fixes
StaticallyTypedAnxiety May 13, 2020
5030a45
clippy fixes
StaticallyTypedAnxiety May 13, 2020
66cef62
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
e4ad9fc
Merge branch 'master' into ashanti/registryimpl
StaticallyTypedAnxiety May 13, 2020
ba77779
removed mutable reference
StaticallyTypedAnxiety May 13, 2020
aef95ac
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
a5f2b0e
line break
StaticallyTypedAnxiety May 13, 2020
f34c163
fixed type error
StaticallyTypedAnxiety May 13, 2020
a94c8e7
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 13, 2020
79940b7
add none clause
StaticallyTypedAnxiety May 13, 2020
07ddd5d
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 13, 2020
7e832fd
removed mutable refs
StaticallyTypedAnxiety May 13, 2020
4eb31ba
Update vm/actor/src/builtin/verifreg/mod.rs
StaticallyTypedAnxiety May 14, 2020
b54dd7e
implemented fix
StaticallyTypedAnxiety May 15, 2020
1b9682e
Merge branch 'ashanti/registryimpl' of https://github.com/chainsafe/f…
StaticallyTypedAnxiety May 15, 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 vm/actor/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod reward;
mod shared;
mod singletons;
pub mod system;
pub mod verifreg;

pub use self::codes::*;
pub(crate) use self::shared::*;
Expand Down
349 changes: 349 additions & 0 deletions vm/actor/src/builtin/verifreg/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

mod state;
mod types;
pub use self::state::State;
pub use self::types::*;
use crate::builtin::singletons::STORAGE_MARKET_ACTOR_ADDR;
use crate::{HAMT_BIT_WIDTH, SYSTEM_ACTOR_ADDR};
use address::Address;
use ipld_blockstore::BlockStore;
use ipld_hamt::BytesKey;
use ipld_hamt::Hamt;
use message::Message;
use num_derive::FromPrimitive;
use num_traits::{FromPrimitive, Zero};
use runtime::{ActorCode, Runtime};
use vm::{ActorError, ExitCode, MethodNum, Serialized, METHOD_CONSTRUCTOR};

/// Account actor methods available
#[derive(FromPrimitive)]
#[repr(u64)]
pub enum Method {
Constructor = METHOD_CONSTRUCTOR,
AddVerifier = 2,
RemoveVerifier = 3,
AddVerifiedClient = 4,
UseBytes = 5,
RestoreBytes = 6,
}

pub struct Actor;
StaticallyTypedAnxiety marked this conversation as resolved.
Show resolved Hide resolved
impl Actor {
/// Constructor for Registry Actor
pub fn constructor<BS, RT>(rt: &mut RT, root_key: Address) -> Result<(), ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_is(std::iter::once(&*SYSTEM_ACTOR_ADDR))?;
let empty_root = Hamt::<BytesKey, _>::new_with_bit_width(rt.store(), HAMT_BIT_WIDTH)
.flush()
.map_err(|e| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("Failed to create registry state {:}", e),
)
})?;
let st = State::new(empty_root, root_key);
rt.create(&st)?;
Ok(())
}

pub fn add_verifier<BS, RT>(rt: &mut RT, params: AddVerifierParams) -> Result<(), ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
let state: State = rt.state()?;
rt.validate_immediate_caller_is(std::iter::once(&state.root_key))?;

rt.transaction::<_, Result<_, ActorError>, _>(|st: &mut State, rt| {
st.put_verifier(rt.store(), &params.address, &params.allowance)
.map_err(|e| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("failed to add verifier: {:}", e),
)
})?;
Ok(())
})??;

Ok(())
}

pub fn remove_verifier<BS, RT>(rt: &mut RT, params: AddVerifierParams) -> Result<(), ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
let state: State = rt.state()?;
rt.validate_immediate_caller_is(std::iter::once(&state.root_key))?;

rt.transaction::<_, Result<_, ActorError>, _>(|st: &mut State, rt| {
st.delete_verifier(rt.store(), &params.address)
.map_err(|e| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("failed to add verifier: {:}", e),
)
})?;
Ok(())
})??;

Ok(())
}

pub fn add_verified_client<BS, RT>(
rt: &mut RT,
params: AddVerifierClientParams,
) -> Result<(), ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
if params.allowance <= *MINIMUM_VERIFIED_SIZE {
return Err(ActorError::new(
ExitCode::ErrIllegalArgument,
format!(
"Allowance {:} below MinVerifiedDealSize for add verified client {:}",
params.allowance, params.address
),
));
}

dutterbutter marked this conversation as resolved.
Show resolved Hide resolved
rt.transaction(|st: &mut State, rt| {
// Validate caller is one of the verifiers.
let message: Box<&dyn Message> = Box::new(rt.message());
let verify_addr = message.from();

let verifier_cap = st
.get_verifier(rt.store(), &verify_addr)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("Failed to get Verifier {:?}", verify_addr),
)
})?
.ok_or_else(|| {
ActorError::new(
ExitCode::ErrNotFound,
format!("Invalid Verifier {:}", verify_addr),
)
})?;

// Compute new verifier cap and update.
if verifier_cap < params.allowance {
return Err(ActorError::new(
ExitCode::ErrIllegalArgument,
format!(
"Add more DataCap {:} for VerifiedClient than allocated {:}",
params.allowance, verifier_cap
),
));
}
let new_verifier_cap = verifier_cap - &params.allowance;
st.put_verifier(rt.store(), &verify_addr, &new_verifier_cap)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Failed to update new verifier cap {:?} for {:?}",
new_verifier_cap, params.allowance
),
)
})?;

// Write-once entry and does not get changed for simplicity.
// If parties neeed more allowance, they can get another VerifiedClient account.
// This is a one-time, upfront allocation.
// Returns error if VerifiedClient already exists
st.get_verified_client(rt.store(), &params.address)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("Failed to get verified client{:}", params.address),
)
})?
.ok_or_else(|| {
ActorError::new(
ExitCode::ErrIllegalArgument,
format!("Illegal Argument{:}", params.address),
)
})?;
st.put_verified_client(rt.store(), &params.address, &params.allowance)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Failed to add verified client {:?} with cap {:?}",
params.address, params.allowance
),
)
})?;

Ok(())
})??;

Ok(())
}

pub fn use_bytes<BS, RT>(rt: &mut RT, params: UseBytesParams) -> Result<(), ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_is(std::iter::once(&*STORAGE_MARKET_ACTOR_ADDR))?;
if params.deal_size < *MINIMUM_VERIFIED_SIZE {
return Err(ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Verified Dealsize {:} is below minimum in usedbytes",
params.deal_size
),
));
}

rt.transaction(|st: &mut State, rt| {
let verifier_cap = st
.get_verifier(rt.store(), &params.address)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("Failed to get Verifier {:?}", &params.address),
)
})?
.ok_or_else(|| {
ActorError::new(
ExitCode::ErrIllegalArgument,
format!("Invalid Verifier {:}", params.address),
)
})?;

if params.deal_size <= verifier_cap {
return Err(ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Deal size of {:} is greater than verifier_cap {:}",
params.deal_size, verifier_cap
),
));
};
let new_verifier_cap = &verifier_cap - &params.deal_size;
if new_verifier_cap < *MINIMUM_VERIFIED_SIZE {
// Delete entry if remaining DataCap is less than MinVerifiedDealSize.
// Will be restored later if the deal did not get activated with a ProvenSector.
st.delete_verified_client(rt.store(), &params.address)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Failed to delete verified client{:} with bytes {:?}",
params.address, params.deal_size
),
)
})
} else {
st.put_verified_client(rt.store(), &params.address, &new_verifier_cap)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Failed to put verified client{:} with bytes {:}",
params.address, params.deal_size
),
)
})
}
})??;

Ok(())
}

// Called by HandleInitTimeoutDeals from StorageMarketActor when a VerifiedDeal fails to init.
// Restore allowable cap for the client, creating new entry if the client has been deleted.
pub fn restore_bytes<BS, RT>(rt: &mut RT, params: RestoreBytesParams) -> Result<(), ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
rt.validate_immediate_caller_is(std::iter::once(&*STORAGE_MARKET_ACTOR_ADDR))?;
if params.deal_size < *MINIMUM_VERIFIED_SIZE {
return Err(ActorError::new(
ExitCode::ErrIllegalArgument,
format!(
"Verified Dealsize {:} is below minimum in usedbytes",
params.deal_size
),
));
}

rt.transaction(|st: &mut State, rt| {
let verifier_cap = st
.get_verified_client(rt.store(), &params.address)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!("Failed to get Verifier {:?}", params.address.clone()),
)
})?
.unwrap_or_else(Zero::zero);

let new_verifier_cap = verifier_cap + &params.deal_size;
st.put_verified_client(rt.store(), &params.address, &new_verifier_cap)
.map_err(|_| {
ActorError::new(
ExitCode::ErrIllegalState,
format!(
"Failed to put verified client{:} with bytes {:}",
params.address, params.deal_size
),
)
})
})??;

Ok(())
}
}

impl ActorCode for Actor {
fn invoke_method<BS, RT>(
&self,
rt: &mut RT,
method: MethodNum,
params: &Serialized,
) -> Result<Serialized, ActorError>
where
BS: BlockStore,
RT: Runtime<BS>,
{
match FromPrimitive::from_u64(method) {
Some(Method::Constructor) => {
Self::constructor(rt, params.deserialize()?)?;
Ok(Serialized::default())
}
Some(Method::AddVerifier) => {
Self::add_verifier(rt, params.deserialize()?)?;
Ok(Serialized::default())
}
Some(Method::RemoveVerifier) => {
Self::remove_verifier(rt, params.deserialize()?)?;
Ok(Serialized::default())
}
Some(Method::AddVerifiedClient) => {
Self::add_verified_client(rt, params.deserialize()?)?;
Ok(Serialized::default())
}
Some(Method::UseBytes) => {
Self::use_bytes(rt, params.deserialize()?)?;
Ok(Serialized::default())
}
Some(Method::RestoreBytes) => {
Self::restore_bytes(rt, params.deserialize()?)?;
Ok(Serialized::default())
}
None => Err(rt.abort(ExitCode::SysErrInvalidMethod, "Invalid method".to_owned())),
}
}
}
Loading