Skip to content

Commit ae7b7ae

Browse files
committed
market actor tests p8
1 parent f33b07c commit ae7b7ae

File tree

4 files changed

+312
-8
lines changed

4 files changed

+312
-8
lines changed

actors/market/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ where
10911091
.map_err(|e| e.wrap(&format!("cannot activate deal {}", deal_id)))?;
10921092

10931093
total_deal_space += proposal.piece_size.0;
1094-
let deal_space_time = deal_weight(proposal);
1094+
let deal_space_time = detail::deal_weight(proposal);
10951095
if proposal.verified_deal {
10961096
total_verified_space_time += deal_space_time;
10971097
} else {

actors/market/src/policy.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,16 @@ use num_traits::Zero;
1717
use super::deal::DealProposal;
1818

1919
pub mod detail {
20+
use super::*;
21+
2022
/// Maximum length of a deal label.
2123
pub const DEAL_MAX_LABEL_SIZE: usize = 256;
24+
25+
/// Computes the weight for a deal proposal, which is a function of its size and duration.
26+
pub fn deal_weight(proposal: &DealProposal) -> DealWeight {
27+
let deal_duration = DealWeight::from(proposal.duration());
28+
deal_duration * proposal.piece_size.0
29+
}
2230
}
2331

2432
/// Bounds (inclusive) on deal duration.
@@ -66,9 +74,3 @@ pub(super) fn collateral_penalty_for_deal_activation_missed(
6674
) -> TokenAmount {
6775
provider_collateral
6876
}
69-
70-
/// Computes the weight for a deal proposal, which is a function of its size and duration.
71-
pub(super) fn deal_weight(proposal: &DealProposal) -> DealWeight {
72-
let deal_duration = DealWeight::from(proposal.duration());
73-
deal_duration * proposal.piece_size.0
74-
}

actors/market/tests/harness.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use fil_actor_market::{
77
balance_table::BalanceTable, ext, ext::miner::GetControlAddressesReturnParams,
88
gen_rand_next_epoch, ActivateDealsParams, Actor as MarketActor, ClientDealProposal, DealArray,
99
DealMetaArray, DealProposal, DealState, Method, OnMinerSectorsTerminateParams,
10-
PublishStorageDealsParams, PublishStorageDealsReturn, State, WithdrawBalanceParams,
10+
PublishStorageDealsParams, PublishStorageDealsReturn, SectorDeals, State,
11+
VerifyDealsForActivationParams, VerifyDealsForActivationReturn, WithdrawBalanceParams,
1112
WithdrawBalanceReturn, PROPOSALS_AMT_BITWIDTH,
1213
};
1314
use fil_actor_power::{CurrentTotalPowerReturn, Method as PowerMethod};
@@ -744,6 +745,20 @@ pub fn generate_and_publish_deal(
744745
deal_ids[0]
745746
}
746747

748+
pub fn generate_and_publish_verified_deal(
749+
rt: &mut MockRuntime,
750+
client: Address,
751+
addrs: &MinerAddresses,
752+
start_epoch: ChainEpoch,
753+
end_epoch: ChainEpoch,
754+
) -> DealID {
755+
let mut deal = generate_deal_and_add_funds(rt, client, addrs, start_epoch, end_epoch);
756+
deal.verified_deal = true;
757+
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, addrs.worker);
758+
let deal_ids = publish_deals(rt, addrs, &[deal]);
759+
deal_ids[0]
760+
}
761+
747762
pub fn generate_and_publish_deal_for_piece(
748763
rt: &mut MockRuntime,
749764
client: Address,
@@ -887,3 +902,24 @@ pub fn assert_account_zero(rt: &mut MockRuntime, addr: Address) {
887902
assert!(get_escrow_balance(rt, &addr).unwrap().is_zero());
888903
assert!(get_locked_balance(rt, addr).is_zero());
889904
}
905+
906+
pub fn verify_deals_for_activation(
907+
rt: &mut MockRuntime,
908+
provider: Address,
909+
sector_deals: Vec<SectorDeals>,
910+
) -> VerifyDealsForActivationReturn {
911+
let param = VerifyDealsForActivationParams { sectors: sector_deals };
912+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
913+
rt.set_caller(*MINER_ACTOR_CODE_ID, provider);
914+
915+
let ret: VerifyDealsForActivationReturn = rt
916+
.call::<MarketActor>(
917+
Method::VerifyDealsForActivation as u64,
918+
&RawBytes::serialize(param).unwrap(),
919+
)
920+
.unwrap()
921+
.deserialize()
922+
.expect("VerifyDealsForActivation failed!");
923+
rt.verify();
924+
ret
925+
}
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
// Copyright 2019-2022 ChainSafe Systems
2+
// SPDX-License-Identifier: Apache-2.0, MIT
3+
4+
mod harness;
5+
use fil_actor_market::policy::detail::deal_weight;
6+
use fil_actor_market::{Actor as MarketActor, Method, SectorDeals, VerifyDealsForActivationParams};
7+
use fil_actors_runtime::test_utils::{
8+
expect_abort, expect_abort_contains_message, ACCOUNT_ACTOR_CODE_ID, MINER_ACTOR_CODE_ID,
9+
};
10+
use fil_actors_runtime::EPOCHS_IN_DAY;
11+
use fvm_ipld_encoding::RawBytes;
12+
use fvm_shared::address::Address;
13+
use fvm_shared::bigint::BigInt;
14+
use fvm_shared::clock::ChainEpoch;
15+
use fvm_shared::error::ExitCode;
16+
use harness::*;
17+
use num_traits::Zero;
18+
19+
const START_EPOCH: ChainEpoch = 10;
20+
const END_EPOCH: ChainEpoch = 200 * EPOCHS_IN_DAY;
21+
const SECTOR_EXPIRY: ChainEpoch = END_EPOCH + 200;
22+
const MINER_ADDRESSES: MinerAddresses = MinerAddresses {
23+
owner: OWNER_ADDR,
24+
worker: WORKER_ADDR,
25+
provider: PROVIDER_ADDR,
26+
control: vec![],
27+
};
28+
29+
#[test]
30+
fn verify_deal_and_get_deal_weight_for_unverified_deal_proposal() {
31+
let mut rt = setup();
32+
let deal_id =
33+
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
34+
let deal_proposal = get_deal_proposal(&mut rt, deal_id);
35+
36+
let response = verify_deals_for_activation(
37+
&mut rt,
38+
PROVIDER_ADDR,
39+
vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
40+
);
41+
42+
assert_eq!(1, response.sectors.len());
43+
assert_eq!(BigInt::zero(), response.sectors[0].verified_deal_weight);
44+
assert_eq!(deal_weight(&deal_proposal), response.sectors[0].deal_weight);
45+
46+
check_state(&rt);
47+
}
48+
49+
#[test]
50+
fn verify_deal_and_get_deal_weight_for_verified_deal_proposal() {
51+
let mut rt = setup();
52+
let deal_id = generate_and_publish_verified_deal(
53+
&mut rt,
54+
CLIENT_ADDR,
55+
&MINER_ADDRESSES,
56+
START_EPOCH,
57+
END_EPOCH,
58+
);
59+
let deal_proposal = get_deal_proposal(&mut rt, deal_id);
60+
61+
let response = verify_deals_for_activation(
62+
&mut rt,
63+
PROVIDER_ADDR,
64+
vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
65+
);
66+
67+
assert_eq!(1, response.sectors.len());
68+
assert_eq!(deal_weight(&deal_proposal), response.sectors[0].verified_deal_weight);
69+
assert_eq!(BigInt::zero(), response.sectors[0].deal_weight);
70+
71+
check_state(&rt);
72+
}
73+
74+
#[test]
75+
fn verification_and_weights_for_verified_and_unverified_deals() {
76+
let mut rt = setup();
77+
let mut create_deal = |end_epoch, verified| {
78+
let mut deal = generate_deal_and_add_funds(
79+
&mut rt,
80+
CLIENT_ADDR,
81+
&MINER_ADDRESSES,
82+
START_EPOCH,
83+
end_epoch,
84+
);
85+
deal.verified_deal = verified;
86+
deal
87+
};
88+
89+
let verified_deal_1 = create_deal(END_EPOCH, true);
90+
let verified_deal_2 = create_deal(END_EPOCH + 1, true);
91+
let unverified_deal_1 = create_deal(END_EPOCH + 2, false);
92+
let unverified_deal_2 = create_deal(END_EPOCH + 3, false);
93+
94+
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
95+
let deal_ids = publish_deals(
96+
&mut rt,
97+
&MINER_ADDRESSES,
98+
&[
99+
verified_deal_1.clone(),
100+
verified_deal_2.clone(),
101+
unverified_deal_1.clone(),
102+
unverified_deal_2.clone(),
103+
],
104+
);
105+
106+
let response = verify_deals_for_activation(
107+
&mut rt,
108+
PROVIDER_ADDR,
109+
vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids }],
110+
);
111+
112+
let verified_weight = deal_weight(&verified_deal_1) + deal_weight(&verified_deal_2);
113+
let unverified_weight = deal_weight(&unverified_deal_1) + deal_weight(&unverified_deal_2);
114+
115+
assert_eq!(1, response.sectors.len());
116+
assert_eq!(verified_weight, response.sectors[0].verified_deal_weight);
117+
assert_eq!(unverified_weight, response.sectors[0].deal_weight);
118+
119+
check_state(&rt);
120+
}
121+
122+
#[test]
123+
fn fail_when_caller_is_not_a_storage_miner_actor() {
124+
let mut rt = setup();
125+
let deal_id =
126+
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
127+
128+
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
129+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
130+
131+
let params = VerifyDealsForActivationParams {
132+
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
133+
};
134+
expect_abort(
135+
ExitCode::USR_FORBIDDEN,
136+
rt.call::<MarketActor>(
137+
Method::VerifyDealsForActivation as u64,
138+
&RawBytes::serialize(params).unwrap(),
139+
),
140+
);
141+
142+
rt.verify();
143+
check_state(&rt);
144+
}
145+
146+
#[test]
147+
fn fail_when_deal_proposal_is_not_found() {
148+
let mut rt = setup();
149+
150+
let params = VerifyDealsForActivationParams {
151+
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![1] }],
152+
};
153+
rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
154+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
155+
expect_abort(
156+
ExitCode::USR_NOT_FOUND,
157+
rt.call::<MarketActor>(
158+
Method::VerifyDealsForActivation as u64,
159+
&RawBytes::serialize(params).unwrap(),
160+
),
161+
);
162+
163+
rt.verify();
164+
check_state(&rt);
165+
}
166+
167+
#[test]
168+
fn fail_when_caller_is_not_the_provider() {
169+
let mut rt = setup();
170+
let deal_id =
171+
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
172+
173+
rt.set_caller(*MINER_ACTOR_CODE_ID, Address::new_id(205));
174+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
175+
176+
let params = VerifyDealsForActivationParams {
177+
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
178+
};
179+
expect_abort(
180+
ExitCode::USR_FORBIDDEN,
181+
rt.call::<MarketActor>(
182+
Method::VerifyDealsForActivation as u64,
183+
&RawBytes::serialize(params).unwrap(),
184+
),
185+
);
186+
187+
rt.verify();
188+
check_state(&rt);
189+
}
190+
191+
#[test]
192+
fn fail_when_current_epoch_is_greater_than_proposal_start_epoch() {
193+
let mut rt = setup();
194+
let deal_id =
195+
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
196+
rt.set_epoch(START_EPOCH + 1);
197+
198+
rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
199+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
200+
201+
let params = VerifyDealsForActivationParams {
202+
sectors: vec![SectorDeals { sector_expiry: SECTOR_EXPIRY, deal_ids: vec![deal_id] }],
203+
};
204+
expect_abort(
205+
ExitCode::USR_ILLEGAL_ARGUMENT,
206+
rt.call::<MarketActor>(
207+
Method::VerifyDealsForActivation as u64,
208+
&RawBytes::serialize(params).unwrap(),
209+
),
210+
);
211+
212+
rt.verify();
213+
check_state(&rt);
214+
}
215+
216+
#[test]
217+
fn fail_when_deal_end_epoch_is_greater_than_sector_expiration() {
218+
let mut rt = setup();
219+
let deal_id =
220+
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
221+
222+
rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
223+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
224+
225+
let params = VerifyDealsForActivationParams {
226+
sectors: vec![SectorDeals { sector_expiry: END_EPOCH - 1, deal_ids: vec![deal_id] }],
227+
};
228+
expect_abort(
229+
ExitCode::USR_ILLEGAL_ARGUMENT,
230+
rt.call::<MarketActor>(
231+
Method::VerifyDealsForActivation as u64,
232+
&RawBytes::serialize(params).unwrap(),
233+
),
234+
);
235+
236+
rt.verify();
237+
check_state(&rt);
238+
}
239+
240+
#[test]
241+
fn fail_when_the_same_deal_id_is_passed_multiple_times() {
242+
let mut rt = setup();
243+
let deal_id =
244+
generate_and_publish_deal(&mut rt, CLIENT_ADDR, &MINER_ADDRESSES, START_EPOCH, END_EPOCH);
245+
246+
rt.set_caller(*MINER_ACTOR_CODE_ID, PROVIDER_ADDR);
247+
rt.expect_validate_caller_type(vec![*MINER_ACTOR_CODE_ID]);
248+
249+
let params = VerifyDealsForActivationParams {
250+
sectors: vec![SectorDeals {
251+
sector_expiry: SECTOR_EXPIRY,
252+
deal_ids: vec![deal_id, deal_id],
253+
}],
254+
};
255+
expect_abort_contains_message(
256+
ExitCode::USR_ILLEGAL_ARGUMENT,
257+
"multiple times",
258+
rt.call::<MarketActor>(
259+
Method::VerifyDealsForActivation as u64,
260+
&RawBytes::serialize(params).unwrap(),
261+
),
262+
);
263+
264+
rt.verify();
265+
check_state(&rt);
266+
}

0 commit comments

Comments
 (0)