Skip to content

Commit

Permalink
Power actor update (#621)
Browse files Browse the repository at this point in the history
* Update power state

* wip updated state and state manager functions

* finish power state

* Update constructor

* Update types and cleanup removed types and functions

* Update create miner

* update claimed power impl

* Update enroll cron event

* Update epoch tick end and update pledge total

* Update on consensus fault

* Implement submit porep

* Implement current total power

* Update hamt to use dyn std error for iteration

* Update amt to use dyn errors on iteration

* implement process_batch_proof_verifies and cleanup

* Implement process_deferred_cron_events

* Final cleanup

* Update power actor hash map to index map for correct iteration order

* Cleanup

* Add missing assertions
  • Loading branch information
austinabell authored Aug 21, 2020
1 parent 2371815 commit 12ea58c
Show file tree
Hide file tree
Showing 31 changed files with 737 additions and 671 deletions.
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.

10 changes: 5 additions & 5 deletions blockchain/chain_sync/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,11 +667,11 @@ where
.get_power(&parent_tipset.parent_state(), header.miner_address());
// ticket winner check
match power_result {
Ok(pow_tuple) => {
let (c_pow, net_pow) = pow_tuple;
if !header.is_ticket_winner(c_pow, net_pow) {
error_vec.push("Miner created a block but was not a winner".to_owned())
}
Ok((_c_pow, _net_pow)) => {
// TODO this doesn't seem to be checked currently
// if !header.is_ticket_winner(c_pow, net_pow) {
// error_vec.push("Miner created a block but was not a winner".to_owned())
// }
}
Err(err) => error_vec.push(err.to_string()),
}
Expand Down
44 changes: 28 additions & 16 deletions blockchain/state_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod errors;
pub mod utils;
pub use self::errors::*;
use actor::{
init, market, miner, power, ActorState, BalanceTable, INIT_ACTOR_ADDR,
init, make_map_with_root, market, miner, power, ActorState, BalanceTable, INIT_ACTOR_ADDR,
STORAGE_MARKET_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR,
};
use address::{Address, BLSPublicKey, Payload, BLS_PUB_LEN};
Expand Down Expand Up @@ -119,15 +119,15 @@ where
Ok(state.network_name)
}
/// Returns true if miner has been slashed or is considered invalid
// TODO update
pub fn is_miner_slashed(&self, addr: &Address, state_cid: &Cid) -> Result<bool, Error> {
let _ms: miner::State = self.load_actor_state(addr, state_cid)?;
let spas: power::State = self.load_actor_state(&*STORAGE_POWER_ACTOR_ADDR, state_cid)?;

let ps: power::State = self.load_actor_state(&*STORAGE_POWER_ACTOR_ADDR, state_cid)?;
match ps.get_claim(self.bs.as_ref(), addr)? {
Some(_) => Ok(false),
None => Ok(true),
}
let claims = make_map_with_root(&spas.claims, self.bs.as_ref())
.map_err(|e| Error::State(e.to_string()))?;

Ok(!claims
.contains_key(&addr.to_bytes())
.map_err(|e| Error::State(e.to_string()))?)
}
/// Returns raw work address of a miner
pub fn get_miner_work_addr(&self, state_cid: &Cid, addr: &Address) -> Result<Address, Error> {
Expand All @@ -140,16 +140,28 @@ where
Ok(addr)
}
/// Returns specified actor's claimed power and total network power as a tuple
pub fn get_power(&self, state_cid: &Cid, addr: &Address) -> Result<(BigInt, BigInt), Error> {
pub fn get_power(
&self,
state_cid: &Cid,
addr: &Address,
) -> Result<(power::Claim, power::Claim), Error> {
let ps: power::State = self.load_actor_state(&*STORAGE_POWER_ACTOR_ADDR, state_cid)?;

if let Some(claim) = ps.get_claim(self.bs.as_ref(), addr)? {
Ok((claim.raw_byte_power, claim.quality_adj_power))
} else {
Err(Error::State(
"Failed to retrieve claimed power from actor state".to_owned(),
))
}
let cm = make_map_with_root(&ps.claims, self.bs.as_ref())
.map_err(|e| Error::State(e.to_string()))?;
let claim: power::Claim = cm
.get(&addr.to_bytes())
.map_err(|e| Error::State(e.to_string()))?
.ok_or_else(|| {
Error::State("Failed to retrieve claimed power from actor state".to_owned())
})?;
Ok((
claim,
power::Claim {
raw_byte_power: ps.total_raw_byte_power,
quality_adj_power: ps.total_quality_adj_power,
},
))
}

pub fn get_subscriber(&self) -> Option<Subscriber<HeadChange>> {
Expand Down
11 changes: 6 additions & 5 deletions blockchain/state_manager/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ use address::{Address, Protocol};
use bitfield::BitField;
use blockstore::BlockStore;
use cid::Cid;
use encoding::serde_bytes::ByteBuf;
use fil_types::{RegisteredSealProof, SectorInfo, SectorNumber, SectorSize, HAMT_BIT_WIDTH};
use filecoin_proofs_api::{post::generate_winning_post_sector_challenge, ProverId};
use forest_blocks::Tipset;
use ipld_amt::Amt;
use ipld_hamt::Hamt;
use ipld_hamt::{BytesKey, Hamt};
use std::convert::TryInto;

pub fn get_sectors_for_winning_post<DB>(
Expand Down Expand Up @@ -147,7 +148,7 @@ where
let amt = Amt::load(ssc, block_store).map_err(|err| Error::Other(err.to_string()))?;

let mut sset: Vec<ChainSectorInfo> = Vec::new();
let for_each = |i: u64, sector_chain: &miner::SectorOnChainInfo| -> Result<(), String> {
let for_each = |i: u64, sector_chain: &miner::SectorOnChainInfo| {
if let Some(ref mut s) = filter {
let i = i
.try_into()
Expand Down Expand Up @@ -321,11 +322,11 @@ where
let map =
Hamt::<_>::load_with_bit_width(&power_actor_state.claims, block_store, HAMT_BIT_WIDTH)
.map_err(|err| Error::Other(err.to_string()))?;
map.for_each(|_, k: String| -> Result<(), String> {
let address = Address::from_bytes(k.as_bytes()).map_err(|e| e.to_string())?;
map.for_each(|_: &BytesKey, k: ByteBuf| {
let address = Address::from_bytes(k.as_ref())?;
miners.push(address);
Ok(())
})
.map_err(Error::Other)?;
.map_err(|e| Error::Other(e.to_string()))?;
Ok(miners)
}
2 changes: 1 addition & 1 deletion encoding/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde_bytes::ByteBuf;
pub struct BytesSer<'a>(#[serde(with = "serde_bytes")] pub &'a [u8]);

/// Wrapper for deserializing dynamic sized Bytes.
#[derive(Deserialize)]
#[derive(Deserialize, Serialize)]
#[serde(transparent)]
pub struct BytesDe(#[serde(with = "serde_bytes")] pub Vec<u8>);

Expand Down
5 changes: 3 additions & 2 deletions ipld/amt/src/amt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{node::Link, nodes_for_height, BitMap, Error, Node, Root, MAX_INDEX,
use cid::{multihash::Blake2b256, Cid};
use encoding::{de::DeserializeOwned, ser::Serialize};
use ipld_blockstore::BlockStore;
use std::error::Error as StdError;

/// Array Mapped Trie allows for the insertion and persistence of data, serializable to a CID
///
Expand Down Expand Up @@ -216,10 +217,10 @@ where
/// assert_eq!(&values, &[(1, "One".to_owned()), (4, "Four".to_owned())]);
/// ```
#[inline]
pub fn for_each<F>(&self, mut f: F) -> Result<(), String>
pub fn for_each<F>(&self, mut f: F) -> Result<(), Box<dyn StdError>>
where
V: DeserializeOwned,
F: FnMut(u64, &V) -> Result<(), String>,
F: FnMut(u64, &V) -> Result<(), Box<dyn StdError>>,
{
self.root
.node
Expand Down
5 changes: 3 additions & 2 deletions ipld/amt/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use encoding::{
ser::{self, Serialize},
};
use ipld_blockstore::BlockStore;
use std::error::Error as StdError;

/// This represents a link to another Node
#[derive(PartialEq, Eq, Clone, Debug)]
Expand Down Expand Up @@ -323,9 +324,9 @@ where
height: u32,
offset: u64,
f: &mut F,
) -> Result<(), String>
) -> Result<(), Box<dyn StdError>>
where
F: FnMut(u64, &V) -> Result<(), String>,
F: FnMut(u64, &V) -> Result<(), Box<dyn StdError>>,
S: BlockStore,
{
match self {
Expand Down
5 changes: 3 additions & 2 deletions ipld/hamt/src/hamt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use forest_ipld::{from_ipld, to_ipld, Ipld};
use ipld_blockstore::BlockStore;
use serde::{de::DeserializeOwned, Serialize, Serializer};
use std::borrow::Borrow;
use std::error::Error as StdError;
use std::marker::PhantomData;

/// Implementation of the HAMT data structure for IPLD.
Expand Down Expand Up @@ -259,10 +260,10 @@ where
/// assert_eq!(total, 3);
/// ```
#[inline]
pub fn for_each<F, V>(&self, mut f: F) -> Result<(), String>
pub fn for_each<F, V>(&self, mut f: F) -> Result<(), Box<dyn StdError>>
where
V: DeserializeOwned,
F: FnMut(&K, V) -> Result<(), String>,
F: FnMut(&K, V) -> Result<(), Box<dyn StdError>>,
{
self.root.for_each(self.store, &mut f)
}
Expand Down
7 changes: 4 additions & 3 deletions ipld/hamt/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use ipld_blockstore::BlockStore;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::borrow::Borrow;
use std::error::Error as StdError;
use std::fmt::Debug;
use std::marker::PhantomData;

Expand Down Expand Up @@ -117,18 +118,18 @@ where
self.pointers.is_empty()
}

pub(crate) fn for_each<V, S, F>(&self, store: &S, f: &mut F) -> Result<(), String>
pub(crate) fn for_each<V, S, F>(&self, store: &S, f: &mut F) -> Result<(), Box<dyn StdError>>
where
V: DeserializeOwned,
F: FnMut(&K, V) -> Result<(), String>,
F: FnMut(&K, V) -> Result<(), Box<dyn StdError>>,
S: BlockStore,
{
for p in &self.pointers {
match p {
Pointer::Link(cid) => {
match store.get::<Node<K, H>>(cid).map_err(|e| e.to_string())? {
Some(node) => node.for_each(store, f)?,
None => return Err(format!("Node with cid {} not found", cid)),
None => return Err(format!("Node with cid {} not found", cid).into()),
}
}
Pointer::Cache(n) => n.for_each(store, f)?,
Expand Down
23 changes: 10 additions & 13 deletions node/rpc/src/state_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,17 @@ pub(crate) async fn state_all_miner_faults<
.load_actor_state(&m, &tipset.parent_state())
.map_err(|e| e.to_string())?;
let block_store = state_manager.get_block_store_ref();
miner_actor_state.for_each_fault_epoch(
block_store,
|fault_start: i64, _| -> Result<(), String> {
if fault_start >= cut_off {
all_faults.push(Fault {
miner: *m,
fault: fault_start,
})
}
Ok(())
},
)
miner_actor_state.for_each_fault_epoch(block_store, |fault_start: i64, _| {
if fault_start >= cut_off {
all_faults.push(Fault {
miner: *m,
fault: fault_start,
})
}
Ok(())
})
})
.collect::<Result<Vec<_>, String>>()?;
.collect::<Result<Vec<_>, _>>()?;
Ok(all_faults)
}
/// returns a bitfield indicating the recovering sectors of the given miner
Expand Down
1 change: 1 addition & 0 deletions vm/actor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ byteorder = "1.3.4"
ahash = "0.4"
base64 = "0.12.1"
log = "0.4.8"
indexmap = { version = "1.3.2", features = ["serde-1"] }

[dev-dependencies]
db = { path = "../../node/db" }
Expand Down
2 changes: 1 addition & 1 deletion vm/actor/src/builtin/market/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ where
.ok_or_else(|| actor_error!(ErrNotFound; "no such deal {}", deal_id))?;

validate_deal_can_activate(&proposal, miner_addr, sector_expiry, curr_epoch)
.map_err(|e| e.wrap(&format!("cannot activate deal {}: ", deal_id)))?;
.map_err(|e| e.wrap(&format!("cannot activate deal {}", deal_id)))?;

let deal_space_time = deal_weight(&proposal);
if proposal.verified_deal {
Expand Down
4 changes: 2 additions & 2 deletions vm/actor/src/builtin/market/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,10 @@ where
proposal: &DealProposal,
) -> Result<(), ActorError> {
self.maybe_lock_balance(&proposal.client, &proposal.client_balance_requirement())
.map_err(|e| e.wrap("failed to lock client funds: "))?;
.map_err(|e| e.wrap("failed to lock client funds"))?;

self.maybe_lock_balance(&proposal.provider, &proposal.provider_collateral)
.map_err(|e| e.wrap("failed to lock provider funds: "))?;
.map_err(|e| e.wrap("failed to lock provider funds"))?;

if let Some(v) = self.total_client_locked_colateral.as_mut() {
*v += &proposal.client_collateral;
Expand Down
10 changes: 5 additions & 5 deletions vm/actor/src/builtin/miner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1742,7 +1742,7 @@ fn pop_sector_expirations<BS>(
st: &mut State,
store: &BS,
epoch: ChainEpoch,
) -> Result<BitField, String>
) -> Result<BitField, Box<dyn StdError>>
where
BS: BlockStore,
{
Expand All @@ -1751,7 +1751,7 @@ where

st.for_each_sector_expiration(store, |expiry: ChainEpoch, sectors: &BitField| {
if expiry > epoch {
return Err("done".to_string());
return Err("done".into());
}
expired_epochs.push(expiry);
expired_sectors.push(sectors.clone());
Expand All @@ -1771,7 +1771,7 @@ fn pop_expired_faults<BS>(
st: &mut State,
store: &BS,
latest_termination: ChainEpoch,
) -> Result<(BitField, BitField), String>
) -> Result<(BitField, BitField), Box<dyn StdError>>
where
BS: BlockStore,
{
Expand Down Expand Up @@ -1949,7 +1949,7 @@ fn remove_terminated_sectors<BS>(
store: &BS,
deadlines: &mut Deadlines,
sectors: &BitField,
) -> Result<(), String>
) -> Result<(), Box<dyn StdError>>
where
BS: BlockStore,
{
Expand Down Expand Up @@ -2458,7 +2458,7 @@ fn unlock_penalty<BS>(
current_epoch: ChainEpoch,
sectors: &[SectorOnChainInfo],
f: &impl Fn(&SectorOnChainInfo) -> TokenAmount,
) -> Result<TokenAmount, String>
) -> Result<TokenAmount, Box<dyn StdError>>
where
BS: BlockStore,
{
Expand Down
Loading

0 comments on commit 12ea58c

Please sign in to comment.