Skip to content

Commit

Permalink
Implement remaining PublishStorageDealsFailures tests (#312)
Browse files Browse the repository at this point in the history
* Add remaining publish_storage_deals_failures tests
  • Loading branch information
elmattic committed May 5, 2022
1 parent 135610d commit b23ee91
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 4 deletions.
5 changes: 2 additions & 3 deletions actors/market/tests/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,6 @@ pub fn assert_deal_failure<F>(
} else {
generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch)
};
deal_proposal.verified_deal = false;
rt.set_epoch(current_epoch);
post_setup(&mut rt, &mut deal_proposal);

Expand Down Expand Up @@ -752,7 +751,7 @@ pub fn generate_and_publish_deal_for_piece(
let deal = DealProposal {
piece_cid,
piece_size,
verified_deal: true,
verified_deal: false,
client,
provider: addrs.provider,
label: "label".to_string(),
Expand Down Expand Up @@ -822,7 +821,7 @@ fn generate_deal_proposal_with_collateral(
DealProposal {
piece_cid,
piece_size,
verified_deal: true,
verified_deal: false,
client,
provider,
label: "label".to_string(),
Expand Down
253 changes: 252 additions & 1 deletion actors/market/tests/publish_storage_deals_failures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use fil_actor_market::policy::deal_provider_collateral_bounds;
use fil_actor_market::DealProposal;
use fil_actor_market::{
Actor as MarketActor, ClientDealProposal, DealProposal, Method, PublishStorageDealsParams,
PublishStorageDealsReturn,
};
use fil_actors_runtime::network::EPOCHS_IN_DAY;
use fil_actors_runtime::runtime::Policy;
use fil_actors_runtime::test_utils::*;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
use fvm_shared::bigint::BigInt;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::crypto::signature::Signature;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::piece::PaddedPieceSize;
Expand Down Expand Up @@ -203,4 +208,250 @@ mod publish_storage_deals_failures {
};
assert_deal_failure(true, f, ExitCode::USR_ILLEGAL_ARGUMENT, Ok(()));
}

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

let amount = TokenAmount::from(100u8);
add_participant_funds(&mut rt, CLIENT_ADDR, amount.clone());
let start_epoch = 42;
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;
let deal1 = generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch);
assert!(amount < deal1.client_balance_requirement());
add_provider_funds(&mut rt, deal1.clone().provider_collateral, &MinerAddresses::default());
publish_deals_expect_abort(
&mut rt,
&MinerAddresses::default(),
deal1,
ExitCode::USR_ILLEGAL_ARGUMENT,
);

check_state(&rt);
}

#[test]
fn fail_when_provider_has_some_funds_but_not_enough_for_a_deal() {
let start_epoch = 10;
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;

let mut rt = setup();

let amount = TokenAmount::from(1u8);
add_provider_funds(&mut rt, amount.clone(), &MinerAddresses::default());
let deal1 = generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch);
assert!(amount < deal1.client_balance_requirement());
add_participant_funds(&mut rt, CLIENT_ADDR, deal1.client_balance_requirement());

let buf = RawBytes::serialize(deal1.clone()).expect("failed to marshal deal proposal");
let sig = Signature::new_bls("does not matter".as_bytes().to_vec());
let params = PublishStorageDealsParams {
deals: vec![ClientDealProposal {
proposal: deal1.clone(),
client_signature: sig.clone(),
}],
};

rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
expect_provider_control_address(&mut rt, PROVIDER_ADDR, OWNER_ADDR, WORKER_ADDR);
expect_query_network_info(&mut rt);
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
rt.expect_verify_signature(ExpectedVerifySig {
sig,
signer: deal1.client,
plaintext: buf.to_vec(),
result: Ok(()),
});
expect_abort(
ExitCode::USR_ILLEGAL_ARGUMENT,
rt.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
),
);

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

#[test]
fn fail_when_deals_have_different_providers() {
let start_epoch = 10;
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;

let mut rt = setup();
let deal1 = generate_deal_and_add_funds(
&mut rt,
CLIENT_ADDR,
&MinerAddresses::default(),
start_epoch,
end_epoch,
);
let m2 = MinerAddresses { provider: Address::new_id(1000), ..MinerAddresses::default() };

let deal2 = generate_deal_and_add_funds(&mut rt, CLIENT_ADDR, &m2, 1, end_epoch);

let buf1 = RawBytes::serialize(deal1.clone()).expect("failed to marshal deal proposal");
let buf2 = RawBytes::serialize(deal2.clone()).expect("failed to marshal deal proposal");
let sig = Signature::new_bls("does not matter".as_bytes().to_vec());
let params = PublishStorageDealsParams {
deals: vec![
ClientDealProposal { proposal: deal1.clone(), client_signature: sig.clone() },
ClientDealProposal { proposal: deal2.clone(), client_signature: sig.clone() },
],
};

rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
expect_provider_control_address(&mut rt, PROVIDER_ADDR, OWNER_ADDR, WORKER_ADDR);
expect_query_network_info(&mut rt);
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
rt.expect_verify_signature(ExpectedVerifySig {
sig: sig.clone(),
signer: deal1.client,
plaintext: buf1.to_vec(),
result: Ok(()),
});
rt.expect_verify_signature(ExpectedVerifySig {
sig,
signer: deal2.client,
plaintext: buf2.to_vec(),
result: Ok(()),
});

let psd_ret: PublishStorageDealsReturn = rt
.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
)
.unwrap()
.deserialize()
.unwrap();

let valid: Vec<u64> = psd_ret.valid_deals.bounded_iter(std::u64::MAX).unwrap().collect();
assert_eq!(vec![0], valid);

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

#[test]
fn fail_when_caller_is_not_of_signable_type() {
let start_epoch = 10;
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;

let mut rt = setup();
let deal = generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch);
let sig = Signature::new_bls("does not matter".as_bytes().to_vec());
let params = PublishStorageDealsParams {
deals: vec![ClientDealProposal { proposal: deal, client_signature: sig }],
};
let w = Address::new_id(1000);
rt.set_caller(*MINER_ACTOR_CODE_ID, w);
rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
expect_abort(
ExitCode::USR_FORBIDDEN,
rt.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
),
);
check_state(&rt);
}

#[test]
fn fail_when_no_deals_in_params() {
let mut rt = setup();
let params = PublishStorageDealsParams { deals: vec![] };
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
expect_abort(
ExitCode::USR_ILLEGAL_ARGUMENT,
rt.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
),
);
check_state(&rt);
}

#[test]
fn fail_to_resolve_provider_address() {
let start_epoch = 10;
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;

let mut rt = setup();
let mut deal = generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch);
deal.provider = new_bls_addr(100);

let sig = Signature::new_bls("does not matter".as_bytes().to_vec());
let params = PublishStorageDealsParams {
deals: vec![ClientDealProposal { proposal: deal, client_signature: sig }],
};
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
expect_abort(
ExitCode::USR_NOT_FOUND,
rt.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
),
);
check_state(&rt);
}

#[test]
fn caller_is_not_the_same_as_the_worker_address_for_miner() {
let start_epoch = 10;
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;

let mut rt = setup();
let deal = generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch);
let sig = Signature::new_bls("does not matter".as_bytes().to_vec());
let params = PublishStorageDealsParams {
deals: vec![ClientDealProposal { proposal: deal, client_signature: sig }],
};

rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
expect_provider_control_address(&mut rt, PROVIDER_ADDR, OWNER_ADDR, WORKER_ADDR);
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, Address::new_id(999));
expect_abort(
ExitCode::USR_FORBIDDEN,
rt.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
),
);

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

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

// deal provider will be a Storage Miner Actor.
let p2 = Address::new_id(505);
rt.set_address_actor_type(p2, *POWER_ACTOR_CODE_ID);
let deal =
generate_deal_proposal(CLIENT_ADDR, p2, ChainEpoch::from(1), ChainEpoch::from(5));

let sig = Signature::new_bls("does not matter".as_bytes().to_vec());
let params = PublishStorageDealsParams {
deals: vec![ClientDealProposal { proposal: deal, client_signature: sig }],
};

rt.expect_validate_caller_type(vec![*ACCOUNT_ACTOR_CODE_ID, *MULTISIG_ACTOR_CODE_ID]);
rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR);
expect_abort(
ExitCode::USR_ILLEGAL_ARGUMENT,
rt.call::<MarketActor>(
Method::PublishStorageDeals as u64,
&RawBytes::serialize(params).unwrap(),
),
);

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

0 comments on commit b23ee91

Please sign in to comment.