Skip to content

Commit

Permalink
market actor tests p8 (#328)
Browse files Browse the repository at this point in the history
  • Loading branch information
LesnyRumcajs authored May 5, 2022
1 parent f33b07c commit 9573015
Show file tree
Hide file tree
Showing 4 changed files with 312 additions and 8 deletions.
2 changes: 1 addition & 1 deletion actors/market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,7 @@ where
.map_err(|e| e.wrap(&format!("cannot activate deal {}", deal_id)))?;

total_deal_space += proposal.piece_size.0;
let deal_space_time = deal_weight(proposal);
let deal_space_time = detail::deal_weight(proposal);
if proposal.verified_deal {
total_verified_space_time += deal_space_time;
} else {
Expand Down
14 changes: 8 additions & 6 deletions actors/market/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ use num_traits::Zero;
use super::deal::DealProposal;

pub mod detail {
use super::*;

/// Maximum length of a deal label.
pub const DEAL_MAX_LABEL_SIZE: usize = 256;

/// Computes the weight for a deal proposal, which is a function of its size and duration.
pub fn deal_weight(proposal: &DealProposal) -> DealWeight {
let deal_duration = DealWeight::from(proposal.duration());
deal_duration * proposal.piece_size.0
}
}

/// Bounds (inclusive) on deal duration.
Expand Down Expand Up @@ -66,9 +74,3 @@ pub(super) fn collateral_penalty_for_deal_activation_missed(
) -> TokenAmount {
provider_collateral
}

/// Computes the weight for a deal proposal, which is a function of its size and duration.
pub(super) fn deal_weight(proposal: &DealProposal) -> DealWeight {
let deal_duration = DealWeight::from(proposal.duration());
deal_duration * proposal.piece_size.0
}
38 changes: 37 additions & 1 deletion actors/market/tests/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use fil_actor_market::{
balance_table::BalanceTable, ext, ext::miner::GetControlAddressesReturnParams,
gen_rand_next_epoch, ActivateDealsParams, Actor as MarketActor, ClientDealProposal, DealArray,
DealMetaArray, DealProposal, DealState, Method, OnMinerSectorsTerminateParams,
PublishStorageDealsParams, PublishStorageDealsReturn, State, WithdrawBalanceParams,
PublishStorageDealsParams, PublishStorageDealsReturn, SectorDeals, State,
VerifyDealsForActivationParams, VerifyDealsForActivationReturn, WithdrawBalanceParams,
WithdrawBalanceReturn, PROPOSALS_AMT_BITWIDTH,
};
use fil_actor_power::{CurrentTotalPowerReturn, Method as PowerMethod};
Expand Down Expand Up @@ -744,6 +745,20 @@ pub fn generate_and_publish_deal(
deal_ids[0]
}

pub fn generate_and_publish_verified_deal(
rt: &mut MockRuntime,
client: Address,
addrs: &MinerAddresses,
start_epoch: ChainEpoch,
end_epoch: ChainEpoch,
) -> DealID {
let mut deal = generate_deal_and_add_funds(rt, client, addrs, start_epoch, end_epoch);
deal.verified_deal = true;
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, addrs.worker);
let deal_ids = publish_deals(rt, addrs, &[deal]);
deal_ids[0]
}

pub fn generate_and_publish_deal_for_piece(
rt: &mut MockRuntime,
client: Address,
Expand Down Expand Up @@ -887,3 +902,24 @@ pub fn assert_account_zero(rt: &mut MockRuntime, addr: Address) {
assert!(get_escrow_balance(rt, &addr).unwrap().is_zero());
assert!(get_locked_balance(rt, addr).is_zero());
}

pub fn verify_deals_for_activation(
rt: &mut MockRuntime,
provider: Address,
sector_deals: Vec<SectorDeals>,
) -> VerifyDealsForActivationReturn {
let param = VerifyDealsForActivationParams { sectors: sector_deals };
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
rt.set_caller(*MINER_ACTOR_CODE_ID, provider);

let ret: VerifyDealsForActivationReturn = rt
.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(param).unwrap(),
)
.unwrap()
.deserialize()
.expect("VerifyDealsForActivation failed!");
rt.verify();
ret
}
266 changes: 266 additions & 0 deletions actors/market/tests/verify_deals_for_activation_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
// Copyright 2019-2022 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

mod harness;
use fil_actor_market::policy::detail::deal_weight;
use fil_actor_market::{Actor as MarketActor, Method, SectorDeals, VerifyDealsForActivationParams};
use fil_actors_runtime::test_utils::{
expect_abort, expect_abort_contains_message, ACCOUNT_ACTOR_CODE_ID, MINER_ACTOR_CODE_ID,
};
use fil_actors_runtime::EPOCHS_IN_DAY;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
use fvm_shared::bigint::BigInt;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::error::ExitCode;
use harness::*;
use num_traits::Zero;

const START_EPOCH: ChainEpoch = 10;
const END_EPOCH: ChainEpoch = 200 * EPOCHS_IN_DAY;
const SECTOR_EXPIRY: ChainEpoch = END_EPOCH + 200;
const MINER_ADDRESSES: MinerAddresses = MinerAddresses {
owner: OWNER_ADDR,
worker: WORKER_ADDR,
provider: PROVIDER_ADDR,
control: vec![],
};

#[test]
fn verify_deal_and_get_deal_weight_for_unverified_deal_proposal() {
let mut rt = setup();
let deal_id =
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
let deal_proposal = get_deal_proposal(&mut rt, deal_id);

let response = verify_deals_for_activation(
&mut rt,
PROVIDER_ADDR,
vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
);

assert_eq!(1, response.sectors.len());
assert_eq!(BigInt::zero(), response.sectors[0].verified_deal_weight);
assert_eq!(deal_weight(&deal_proposal), response.sectors[0].deal_weight);

check_state(&rt);
}

#[test]
fn verify_deal_and_get_deal_weight_for_verified_deal_proposal() {
let mut rt = setup();
let deal_id = generate_and_publish_verified_deal(
&mut rt,
CLIENT_ADDR,
&MINER_ADDRESSES,
START_EPOCH,
END_EPOCH,
);
let deal_proposal = get_deal_proposal(&mut rt, deal_id);

let response = verify_deals_for_activation(
&mut rt,
PROVIDER_ADDR,
vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
);

assert_eq!(1, response.sectors.len());
assert_eq!(deal_weight(&deal_proposal), response.sectors[0].verified_deal_weight);
assert_eq!(BigInt::zero(), response.sectors[0].deal_weight);

check_state(&rt);
}

#[test]
fn verification_and_weights_for_verified_and_unverified_deals() {
let mut rt = setup();
let mut create_deal = |end_epoch, verified| {
let mut deal = generate_deal_and_add_funds(
&mut rt,
CLIENT_ADDR,
&MINER_ADDRESSES,
START_EPOCH,
end_epoch,
);
deal.verified_deal = verified;
deal
};

let verified_deal_1 = create_deal(END_EPOCH, true);
let verified_deal_2 = create_deal(END_EPOCH + 1, true);
let unverified_deal_1 = create_deal(END_EPOCH + 2, false);
let unverified_deal_2 = create_deal(END_EPOCH + 3, false);

rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
let deal_ids = publish_deals(
&mut rt,
&MINER_ADDRESSES,
&[
verified_deal_1.clone(),
verified_deal_2.clone(),
unverified_deal_1.clone(),
unverified_deal_2.clone(),
],
);

let response = verify_deals_for_activation(
&mut rt,
PROVIDER_ADDR,
vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids }],
);

let verified_weight = deal_weight(&verified_deal_1) + deal_weight(&verified_deal_2);
let unverified_weight = deal_weight(&unverified_deal_1) + deal_weight(&unverified_deal_2);

assert_eq!(1, response.sectors.len());
assert_eq!(verified_weight, response.sectors[0].verified_deal_weight);
assert_eq!(unverified_weight, response.sectors[0].deal_weight);

check_state(&rt);
}

#[test]
fn fail_when_caller_is_not_a_storage_miner_actor() {
let mut rt = setup();
let deal_id =
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);

rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);

let params = VerifyDealsForActivationParams {
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
};
expect_abort(
ExitCode::USR_FORBIDDEN,
rt.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(params).unwrap(),
),
);

rt.verify();
check_state(&rt);
}

#[test]
fn fail_when_deal_proposal_is_not_found() {
let mut rt = setup();

let params = VerifyDealsForActivationParams {
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![1] }],
};
rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
expect_abort(
ExitCode::USR_NOT_FOUND,
rt.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(params).unwrap(),
),
);

rt.verify();
check_state(&rt);
}

#[test]
fn fail_when_caller_is_not_the_provider() {
let mut rt = setup();
let deal_id =
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);

rt.set_caller(*MINER_ACTOR_CODE_ID, Address::new_id(205));
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);

let params = VerifyDealsForActivationParams {
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
};
expect_abort(
ExitCode::USR_FORBIDDEN,
rt.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(params).unwrap(),
),
);

rt.verify();
check_state(&rt);
}

#[test]
fn fail_when_current_epoch_is_greater_than_proposal_start_epoch() {
let mut rt = setup();
let deal_id =
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
rt.set_epoch(START_EPOCH + 1);

rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);

let params = VerifyDealsForActivationParams {
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
};
expect_abort(
ExitCode::USR_ILLEGAL_ARGUMENT,
rt.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(params).unwrap(),
),
);

rt.verify();
check_state(&rt);
}

#[test]
fn fail_when_deal_end_epoch_is_greater_than_sector_expiration() {
let mut rt = setup();
let deal_id =
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);

rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);

let params = VerifyDealsForActivationParams {
sectors: vec![SectorDeals { sector_expiry: END_EPOCH - 1, deal_ids: vec![deal_id] }],
};
expect_abort(
ExitCode::USR_ILLEGAL_ARGUMENT,
rt.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(params).unwrap(),
),
);

rt.verify();
check_state(&rt);
}

#[test]
fn fail_when_the_same_deal_id_is_passed_multiple_times() {
let mut rt = setup();
let deal_id =
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);

rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);

let params = VerifyDealsForActivationParams {
sectors: vec![SectorDeals {
sector_expiry: SECTOR_EXPIRY,
deal_ids: vec![deal_id, deal_id],
}],
};
expect_abort_contains_message(
ExitCode::USR_ILLEGAL_ARGUMENT,
"multiple times",
rt.call::<MarketActor>(
Method::VerifyDealsForActivation as u64,
&RawBytes::serialize(params).unwrap(),
),
);

rt.verify();
check_state(&rt);
}

0 comments on commit 9573015

Please sign in to comment.