Skip to content

Commit

Permalink
miner batch claim of datacap allocations in confirm_sector_proofs_val…
Browse files Browse the repository at this point in the history
…id_internal
  • Loading branch information
alexytsu committed May 30, 2023
1 parent e0f6c27 commit b92f4a6
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 120 deletions.
14 changes: 11 additions & 3 deletions actors/miner/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub mod market {
}
}

#[derive(Serialize_tuple, Deserialize_tuple)]
#[derive(Serialize_tuple, Deserialize_tuple, Clone)]
pub struct ActivateDealsResult {
#[serde(with = "bigint_ser")]
pub nonverified_deal_space: BigInt,
Expand Down Expand Up @@ -210,10 +210,18 @@ pub mod verifreg {
pub sectors: Vec<SectorAllocationClaim>,
pub all_or_nothing: bool,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize_tuple, Deserialize_tuple)]
pub struct ClaimAllocationsReturn {
pub batch_info: BatchReturn,
pub struct SectorAllocationClaimResult {
#[serde(with = "bigint_ser")]
pub claimed_space: BigInt,
pub sector: SectorNumber,
pub sector_expiry: ChainEpoch,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize_tuple, Deserialize_tuple)]
pub struct ClaimAllocationsReturn {
pub batch_info: BatchReturn,
pub claim_results: Vec<SectorAllocationClaimResult>,
}
}
152 changes: 128 additions & 24 deletions actors/miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::ops::Neg;
use anyhow::{anyhow, Error};
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use cid::Cid;
use ext::market::ActivateDealsResult;
use fvm_ipld_bitfield::{BitField, Validate};
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::{from_slice, BytesDe, CborStore};
Expand Down Expand Up @@ -4795,43 +4796,26 @@ fn confirm_sector_proofs_valid_internal(
// Ideally, we'd combine some of these operations, but at least we have
// a constant number of them.
let activation = rt.curr_epoch();
// Pre-commits for new sectors.
let mut valid_pre_commits = Vec::default();

for pre_commit in pre_commits {
match activate_deals_and_claim_allocations(
rt,
pre_commit.clone().info.deal_ids,
pre_commit.info.expiration,
pre_commit.info.sector_number,
)? {
let activated_sectors: Vec<(SectorPreCommitOnChainInfo, ext::market::DealSpaces)> =
match batch_activate_deals_and_claim_allocations(rt, pre_commits, false)? {
None => {
info!(
"failed to activate deals on sector {}, dropping from prove commit set",
pre_commit.info.sector_number,
);
continue;
return Err(actor_error!(illegal_argument, "all prove commits failed to validate"));
}
Some(deal_spaces) => valid_pre_commits.push((pre_commit, deal_spaces)),
Some(activated_sectors) => activated_sectors,
};
}

// When all prove commits have failed abort early
if valid_pre_commits.is_empty() {
return Err(actor_error!(illegal_argument, "all prove commits failed to validate"));
}

let (total_pledge, newly_vested) = rt.transaction(|state: &mut State, rt| {
let policy = rt.policy();
let store = rt.store();
let info = get_miner_info(store, state)?;

let mut new_sector_numbers = Vec::<SectorNumber>::with_capacity(valid_pre_commits.len());
let mut new_sector_numbers = Vec::<SectorNumber>::with_capacity(activated_sectors.len());
let mut deposit_to_unlock = TokenAmount::zero();
let mut new_sectors = Vec::<SectorOnChainInfo>::new();
let mut total_pledge = TokenAmount::zero();

for (pre_commit, deal_spaces) in valid_pre_commits {
for (pre_commit, deal_spaces) in activated_sectors {
// compute initial pledge
let duration = pre_commit.info.expiration - activation;

Expand Down Expand Up @@ -4962,6 +4946,123 @@ fn confirm_sector_proofs_valid_internal(
Ok(())
}

fn batch_activate_deals_and_claim_allocations(
rt: &impl Runtime,
pre_commits: Vec<SectorPreCommitOnChainInfo>,
all_or_nothing: bool,
) -> Result<Option<Vec<(SectorPreCommitOnChainInfo, ext::market::DealSpaces)>>, ActorError> {
// non-verified deal space
let mut activation_results = Vec::new();

// TODO: https://github.com/filecoin-project/builtin-actors/pull/1303 enable activation batching
for pre_commit in pre_commits {
// Check (and activate) storage deals associated to sector
let deal_ids = pre_commit.info.deal_ids.clone();
if deal_ids.is_empty() {
activation_results.push((
pre_commit,
ActivateDealsResult {
nonverified_deal_space: BigInt::default(),
verified_infos: Vec::default(),
},
));
continue;
}

let activate_raw = extract_send_result(rt.send_simple(
&STORAGE_MARKET_ACTOR_ADDR,
ext::market::ACTIVATE_DEALS_METHOD,
IpldBlock::serialize_cbor(&ext::market::ActivateDealsParams {
deal_ids,
sector_expiry: pre_commit.info.expiration,
})?,
TokenAmount::zero(),
));
let activate_res: ext::market::ActivateDealsResult = match activate_raw {
Ok(res) => deserialize_block(res)?,
Err(e) => {
info!(
"error activating deals on sector {}: {}",
pre_commit.info.sector_number,
e.msg()
);
if all_or_nothing {
return Ok(None);
} else {
continue;
}
}
};

activation_results.push((pre_commit, activate_res));
}

// When all prove commits have failed abort early
if activation_results.is_empty() {
return Err(actor_error!(illegal_argument, "all sectors failed to activate"));
}

// Claims aggregated across all sectors
let mut sectors_claims = Vec::new();
for (pre_commit, activate_res) in activation_results.clone() {
let mut sector_claims = activate_res
.verified_infos
.iter()
.map(|info| ext::verifreg::SectorAllocationClaim {
client: info.client,
allocation_id: info.allocation_id,
data: info.data,
size: info.size,
sector: pre_commit.info.sector_number,
sector_expiry: pre_commit.info.expiration,
})
.collect();
sectors_claims.append(&mut sector_claims);
}

// TODO: skip claiming datacap if no sectors have any verified deals
// if sectors_claims.is_empty()

let claim_raw = extract_send_result(rt.send_simple(
&VERIFIED_REGISTRY_ACTOR_ADDR,
ext::verifreg::CLAIM_ALLOCATIONS_METHOD,
IpldBlock::serialize_cbor(&ext::verifreg::ClaimAllocationsParams {
sectors: sectors_claims,
all_or_nothing: true,
})?,
TokenAmount::zero(),
));

let claim_res: ext::verifreg::ClaimAllocationsReturn = match claim_raw {
Ok(res) => deserialize_block(res)?,
Err(e) => {
info!("error claiming allocations for batch {}", e.msg());
return Ok(None);
}
};

let activation_and_claim_results: Vec<(SectorPreCommitOnChainInfo, ext::market::DealSpaces)> =
activation_results
.iter()
.map(|(pre_commit, activation_result)| {
let verified_deal_space = claim_res
.claim_results
.iter()
.filter(|c| pre_commit.info.sector_number == c.sector)
.fold(BigInt::zero(), |acc, c| acc + c.claimed_space.clone());
(
pre_commit.clone(),
ext::market::DealSpaces {
verified_deal_space,
deal_space: activation_result.nonverified_deal_space.clone(),
},
)
})
.collect();

Ok(Some(activation_and_claim_results))
}

// activate deals with builtin market and claim allocations with verified registry actor
// returns an error in case of a fatal programmer error
// returns Ok(None) in case deal activation or verified allocation claim fails
Expand Down Expand Up @@ -5027,7 +5128,10 @@ fn activate_deals_and_claim_allocations(
};
Ok(Some(ext::market::DealSpaces {
deal_space: activate_res.nonverified_deal_space,
verified_deal_space: claim_res.claimed_space,
verified_deal_space: claim_res
.claim_results
.iter()
.fold(BigInt::zero(), |acc, claim_result| acc + claim_result.claimed_space.clone()),
}))
}

Expand Down
55 changes: 34 additions & 21 deletions actors/miner/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use fil_actor_market::{
use fil_actor_miner::ext::market::ON_MINER_SECTORS_TERMINATE_METHOD;
use fil_actor_miner::ext::power::{UPDATE_CLAIMED_POWER_METHOD, UPDATE_PLEDGE_TOTAL_METHOD};
use fil_actor_miner::ext::verifreg::{
ClaimAllocationsParams, ClaimAllocationsReturn, SectorAllocationClaim, CLAIM_ALLOCATIONS_METHOD,
ClaimAllocationsParams, ClaimAllocationsReturn, SectorAllocationClaim,
SectorAllocationClaimResult, CLAIM_ALLOCATIONS_METHOD,
};
use fil_actor_miner::{
aggregate_pre_commit_network_fee, aggregate_prove_commit_network_fee, consensus_fault_penalty,
Expand Down Expand Up @@ -1053,6 +1054,9 @@ impl ActorHarness {
pcs: &[SectorPreCommitOnChainInfo],
) {
let mut valid_pcs = Vec::new();
// claim FIL+ allocations
let mut sectors_claims: Vec<SectorAllocationClaim> = Vec::new();

for pc in pcs {
if !pc.info.deal_ids.is_empty() {
let deal_spaces = cfg.deal_spaces(&pc.info.sector_number);
Expand Down Expand Up @@ -1091,8 +1095,7 @@ impl ActorHarness {
valid_pcs.push(pc);
}
} else {
// calim FIL+ allocations
let sector_claims = ret
let mut sector_claims: Vec<SectorAllocationClaim> = ret
.verified_infos
.iter()
.map(|info| SectorAllocationClaim {
Expand All @@ -1104,31 +1107,41 @@ impl ActorHarness {
sector_expiry: pc.info.expiration,
})
.collect();

let claim_allocation_params =
ClaimAllocationsParams { sectors: sector_claims, all_or_nothing: true };

// TODO handle failures of claim allocations
// use exit code map for claim allocations in config
sectors_claims.append(&mut sector_claims);
valid_pcs.push(pc);
let claim_allocs_ret = ClaimAllocationsReturn {
batch_info: BatchReturn::ok(ret.verified_infos.len() as u32),
claimed_space: deal_spaces.verified_deal_space,
};
rt.expect_send_simple(
VERIFIED_REGISTRY_ACTOR_ADDR,
CLAIM_ALLOCATIONS_METHOD as u64,
IpldBlock::serialize_cbor(&claim_allocation_params).unwrap(),
TokenAmount::zero(),
IpldBlock::serialize_cbor(&claim_allocs_ret).unwrap(),
ExitCode::OK,
);
}
} else {
// empty deal ids
valid_pcs.push(pc);
}
}

let claim_allocation_params =
ClaimAllocationsParams { sectors: sectors_claims.clone(), all_or_nothing: true };

// TODO handle failures of claim allocations
// use exit code map for claim allocations in config

let claim_allocs_ret = ClaimAllocationsReturn {
batch_info: BatchReturn::ok(sectors_claims.len() as u32),
claim_results: sectors_claims
.iter()
.map(|claim| SectorAllocationClaimResult {
claimed_space: claim.size.0.into(),
sector: claim.sector,
sector_expiry: claim.sector_expiry,
})
.collect(),
};
rt.expect_send_simple(
VERIFIED_REGISTRY_ACTOR_ADDR,
CLAIM_ALLOCATIONS_METHOD as u64,
IpldBlock::serialize_cbor(&claim_allocation_params).unwrap(),
TokenAmount::zero(),
IpldBlock::serialize_cbor(&claim_allocs_ret).unwrap(),
ExitCode::OK,
);

if !valid_pcs.is_empty() {
let mut expected_pledge = TokenAmount::zero();
let mut expected_qa_power = BigInt::from(0);
Expand Down
Loading

0 comments on commit b92f4a6

Please sign in to comment.