From 9f1d25a4a3b684e605c18a7b31ab782f8474df97 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Oct 2023 13:40:06 +0400 Subject: [PATCH 1/7] publish deals event --- actors/market/src/emit.rs | 21 ++++++++++ actors/market/src/lib.rs | 9 +++++ actors/market/tests/harness.rs | 15 ++++++- actors/market/tests/market_actor_test.rs | 39 ++++++++++++++++++- .../tests/publish_storage_deals_failures.rs | 10 +++++ 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 actors/market/src/emit.rs diff --git a/actors/market/src/emit.rs b/actors/market/src/emit.rs new file mode 100644 index 000000000..05e048b84 --- /dev/null +++ b/actors/market/src/emit.rs @@ -0,0 +1,21 @@ +use fil_actors_runtime::runtime::Runtime; +use fil_actors_runtime::{ActorError, EventBuilder}; +use fvm_shared::deal::DealID; +use fvm_shared::ActorID; + +/// Indicates a deal has been published. +pub fn deal_published( + rt: &impl Runtime, + client: ActorID, + provider: ActorID, + deal_id: DealID, +) -> Result<(), ActorError> { + rt.emit_event( + &EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &client) + .field_indexed("provider", &provider) + .field_indexed("deal_id", &deal_id) + .build()?, + ) +} diff --git a/actors/market/src/lib.rs b/actors/market/src/lib.rs index 260a59b87..c0d3e9380 100644 --- a/actors/market/src/lib.rs +++ b/actors/market/src/lib.rs @@ -57,6 +57,8 @@ mod deal; mod state; mod types; +pub mod emit; + #[cfg(feature = "fil-actor")] fil_actors_runtime::wasm_trampoline!(Actor); @@ -478,6 +480,13 @@ impl Actor { .with_context_code(ExitCode::USR_ILLEGAL_ARGUMENT, || { format!("failed to notify deal with proposal cid {}", valid_deal.cid) })?; + + emit::deal_published( + rt, + valid_deal.proposal.client.id().unwrap(), + valid_deal.proposal.provider.id().unwrap(), + new_deal_ids[i], + )?; } Ok(PublishStorageDealsReturn { ids: new_deal_ids, valid_deals: valid_input_bf }) diff --git a/actors/market/tests/harness.rs b/actors/market/tests/harness.rs index e1244bdfd..c026cff49 100644 --- a/actors/market/tests/harness.rs +++ b/actors/market/tests/harness.rs @@ -29,8 +29,8 @@ use fil_actors_runtime::{ network::EPOCHS_IN_DAY, runtime::{builtins::Type, Policy, Runtime}, test_utils::*, - ActorError, BatchReturn, Set, SetMultimap, BURNT_FUNDS_ACTOR_ADDR, CRON_ACTOR_ADDR, - DATACAP_TOKEN_ACTOR_ADDR, REWARD_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ADDR, + ActorError, BatchReturn, EventBuilder, Set, SetMultimap, BURNT_FUNDS_ACTOR_ADDR, + CRON_ACTOR_ADDR, DATACAP_TOKEN_ACTOR_ADDR, REWARD_ACTOR_ADDR, STORAGE_MARKET_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR, SYSTEM_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR, }; use fvm_ipld_encoding::ipld_block::IpldBlock; @@ -687,6 +687,17 @@ pub fn publish_deals( None, ExitCode::OK, ); + + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &deal.client.id().unwrap()) + .field_indexed("provider", &deal.provider.id().unwrap()) + .field_indexed("deal_id", &deal_id) + .build() + .unwrap(), + ); + deal_id += 1; } diff --git a/actors/market/tests/market_actor_test.rs b/actors/market/tests/market_actor_test.rs index 4cc86284d..06ff6dfca 100644 --- a/actors/market/tests/market_actor_test.rs +++ b/actors/market/tests/market_actor_test.rs @@ -15,7 +15,7 @@ use fil_actors_runtime::network::EPOCHS_IN_DAY; use fil_actors_runtime::runtime::{Policy, Runtime, RuntimePolicy}; use fil_actors_runtime::test_utils::*; use fil_actors_runtime::{ - make_empty_map, ActorError, BatchReturn, SetMultimap, BURNT_FUNDS_ACTOR_ADDR, + make_empty_map, ActorError, BatchReturn, EventBuilder, SetMultimap, BURNT_FUNDS_ACTOR_ADDR, DATACAP_TOKEN_ACTOR_ADDR, EPOCHS_IN_YEAR, SYSTEM_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR, }; use frc46_token::token::types::{TransferFromParams, TransferFromReturn}; @@ -944,6 +944,16 @@ fn provider_and_client_addresses_are_resolved_before_persisting_state_and_sent_t ExitCode::OK, ); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &client_resolved.id().unwrap()) + .field_indexed("provider", &provider_resolved.id().unwrap()) + .field_indexed("deal_id", &deal_id) + .build() + .unwrap(), + ); + let ret: PublishStorageDealsReturn = rt .call::( Method::PublishStorageDeals as u64, @@ -2132,6 +2142,15 @@ fn insufficient_client_balance_in_a_batch() { None, ExitCode::OK, ); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &deal2.client.id().unwrap()) + .field_indexed("provider", &deal2.provider.id().unwrap()) + .field_indexed("deal_id", &next_deal_id) + .build() + .unwrap(), + ); rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR); @@ -2272,6 +2291,15 @@ fn insufficient_provider_balance_in_a_batch() { None, ExitCode::OK, ); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &deal2.client.id().unwrap()) + .field_indexed("provider", &deal2.provider.id().unwrap()) + .field_indexed("deal_id", &next_deal_id) + .build() + .unwrap(), + ); rt.set_caller(*ACCOUNT_ACTOR_CODE_ID, WORKER_ADDR); @@ -2415,6 +2443,15 @@ fn psd_restricted_correctly() { None, ExitCode::OK, ); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &deal.client.id().unwrap()) + .field_indexed("provider", &deal.provider.id().unwrap()) + .field_indexed("deal_id", &next_deal_id) + .build() + .unwrap(), + ); let ret: PublishStorageDealsReturn = rt .call::( diff --git a/actors/market/tests/publish_storage_deals_failures.rs b/actors/market/tests/publish_storage_deals_failures.rs index 045815d2e..edc32c860 100644 --- a/actors/market/tests/publish_storage_deals_failures.rs +++ b/actors/market/tests/publish_storage_deals_failures.rs @@ -25,6 +25,7 @@ use fil_actor_market::ext::account::{AuthenticateMessageParams, AUTHENTICATE_MES mod harness; +use fil_actors_runtime::EventBuilder; use fvm_ipld_encoding::ipld_block::IpldBlock; use fvm_shared::sys::SendFlags; use harness::*; @@ -375,6 +376,15 @@ fn fail_when_deals_have_different_providers() { None, ExitCode::OK, ); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-published") + .field_indexed("client", &deal1.client.id().unwrap()) + .field_indexed("provider", &deal1.provider.id().unwrap()) + .field_indexed("deal_id", &next_deal_id) + .build() + .unwrap(), + ); let psd_ret: PublishStorageDealsReturn = rt .call::( From 56b2a34cd3032c5a722361ff6f6627921a53f767 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Oct 2023 14:16:49 +0400 Subject: [PATCH 2/7] activate deals --- actors/market/src/emit.rs | 7 ++++ actors/market/src/lib.rs | 3 ++ actors/market/tests/activate_deal_failures.rs | 5 ++- actors/market/tests/batch_activate_deals.rs | 9 +++-- actors/market/tests/harness.rs | 33 +++++++++++++++++-- actors/market/tests/market_actor_test.rs | 3 ++ .../tests/random_cron_epoch_during_publish.rs | 2 +- 7 files changed, 54 insertions(+), 8 deletions(-) diff --git a/actors/market/src/emit.rs b/actors/market/src/emit.rs index 05e048b84..08055f252 100644 --- a/actors/market/src/emit.rs +++ b/actors/market/src/emit.rs @@ -19,3 +19,10 @@ pub fn deal_published( .build()?, ) } + +/// Indicates a deal has been activated. +pub fn deal_activated(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorError> { + rt.emit_event( + &EventBuilder::new().typ("deal-activated").field_indexed("deal_id", &deal_id).build()?, + ) +} diff --git a/actors/market/src/lib.rs b/actors/market/src/lib.rs index c0d3e9380..fc98cf6c5 100644 --- a/actors/market/src/lib.rs +++ b/actors/market/src/lib.rs @@ -665,6 +665,9 @@ impl Actor { unsealed_cid: data_commitment, }); batch_gen.add_success(); + for d in p.deal_ids { + emit::deal_activated(rt, d)?; + } } Err(e) => { log::warn!("failed to activate deals {:?}: {}", p.deal_ids, e); diff --git a/actors/market/tests/activate_deal_failures.rs b/actors/market/tests/activate_deal_failures.rs index 0ba40faba..71d5901fb 100644 --- a/actors/market/tests/activate_deal_failures.rs +++ b/actors/market/tests/activate_deal_failures.rs @@ -38,6 +38,7 @@ fn fail_when_caller_is_not_the_provider_of_the_deal() { deal_ids: vec![deal_id], }], false, + vec![], ) .unwrap(); let res: BatchActivateDealsResult = @@ -87,6 +88,7 @@ fn fail_when_deal_has_not_been_published_before() { deal_ids: vec![DealID::from(42u32)], }], false, + vec![], ) .unwrap(); let res: BatchActivateDealsResult = @@ -123,6 +125,7 @@ fn fail_when_deal_has_already_been_activated() { deal_ids: vec![deal_id], }], false, + vec![], ) .unwrap(); let res: BatchActivateDealsResult = @@ -169,6 +172,6 @@ fn fail_when_deal_has_already_been_expired() { let mut st: State = rt.get_state::(); st.next_id = deal_id + 1; - let res = activate_deals(&rt, sector_expiry, PROVIDER_ADDR, 0, &[deal_id]); + let res = activate_deals_for(&rt, sector_expiry, PROVIDER_ADDR, 0, &[deal_id], vec![]); assert_eq!(res.activation_results.codes(), vec![EX_DEAL_EXPIRED]) } diff --git a/actors/market/tests/batch_activate_deals.rs b/actors/market/tests/batch_activate_deals.rs index b02359a44..f71066293 100644 --- a/actors/market/tests/batch_activate_deals.rs +++ b/actors/market/tests/batch_activate_deals.rs @@ -121,7 +121,8 @@ fn sectors_fail_and_succeed_independently_during_batch_activation() { SectorDeals { deal_ids: vec![id_4], sector_type, sector_expiry: END_EPOCH + 2 }, // sector succeeds ]; - let res = batch_activate_deals_raw(&rt, PROVIDER_ADDR, sectors_deals, false).unwrap(); + let res = + batch_activate_deals_raw(&rt, PROVIDER_ADDR, sectors_deals, false, vec![id_4]).unwrap(); let res: BatchActivateDealsResult = res.unwrap().deserialize().expect("VerifyDealsForActivation failed!"); @@ -172,7 +173,8 @@ fn handles_sectors_empty_of_deals_gracefully() { SectorDeals { deal_ids: vec![], sector_type, sector_expiry: END_EPOCH + 2 }, // empty sector ]; - let res = batch_activate_deals_raw(&rt, PROVIDER_ADDR, sectors_deals, false).unwrap(); + let res = + batch_activate_deals_raw(&rt, PROVIDER_ADDR, sectors_deals, false, vec![id_1]).unwrap(); let res: BatchActivateDealsResult = res.unwrap().deserialize().expect("VerifyDealsForActivation failed!"); @@ -221,7 +223,8 @@ fn fails_to_activate_sectors_containing_duplicate_deals() { SectorDeals { deal_ids: vec![id_3], sector_type, sector_expiry: END_EPOCH }, ]; - let res = batch_activate_deals_raw(&rt, PROVIDER_ADDR, sectors_deals, false).unwrap(); + let res = batch_activate_deals_raw(&rt, PROVIDER_ADDR, sectors_deals, false, vec![id_1, id_3]) + .unwrap(); let res: BatchActivateDealsResult = res.unwrap().deserialize().expect("VerifyDealsForActivation failed!"); diff --git a/actors/market/tests/harness.rs b/actors/market/tests/harness.rs index c026cff49..8d2220536 100644 --- a/actors/market/tests/harness.rs +++ b/actors/market/tests/harness.rs @@ -311,16 +311,17 @@ pub fn create_deal( deal } -/// Activate a single sector of deals -pub fn activate_deals( +pub fn activate_deals_for( rt: &MockRuntime, sector_expiry: ChainEpoch, provider: Address, current_epoch: ChainEpoch, deal_ids: &[DealID], + expected_deal_activations: Vec, ) -> BatchActivateDealsResult { rt.set_epoch(current_epoch); let compute_cid = false; + let ret = batch_activate_deals_raw( rt, provider, @@ -330,6 +331,7 @@ pub fn activate_deals( sector_type: RegisteredSealProof::StackedDRG8MiBV1, }], compute_cid, + expected_deal_activations, ) .unwrap(); @@ -347,6 +349,17 @@ pub fn activate_deals( ret } +/// Activate a single sector of deals +pub fn activate_deals( + rt: &MockRuntime, + sector_expiry: ChainEpoch, + provider: Address, + current_epoch: ChainEpoch, + deal_ids: &[DealID], +) -> BatchActivateDealsResult { + activate_deals_for(rt, sector_expiry, provider, current_epoch, deal_ids, deal_ids.into()) +} + /// Batch activate deals across multiple sectors /// For each sector, provide its expiry and a list of unique, valid deal ids contained within pub fn batch_activate_deals( @@ -363,7 +376,10 @@ pub fn batch_activate_deals( sector_type: RegisteredSealProof::StackedDRG8MiBV1, }) .collect(); - let ret = batch_activate_deals_raw(rt, provider, sectors_deals, compute_cid).unwrap(); + + let deal_ids = sectors.iter().flat_map(|(_, deal_ids)| deal_ids).cloned().collect::>(); + + let ret = batch_activate_deals_raw(rt, provider, sectors_deals, compute_cid, deal_ids).unwrap(); let ret: BatchActivateDealsResult = ret.unwrap().deserialize().expect("VerifyDealsForActivation failed!"); @@ -379,10 +395,21 @@ pub fn batch_activate_deals_raw( provider: Address, sectors_deals: Vec, compute_cid: bool, + expected_activated_deals: Vec, ) -> Result, ActorError> { rt.set_caller(*MINER_ACTOR_CODE_ID, provider); rt.expect_validate_caller_type(vec![Type::Miner]); + for deal_id in expected_activated_deals { + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-activated") + .field_indexed("deal_id", &deal_id) + .build() + .unwrap(), + ); + } + let params = BatchActivateDealsParams { sectors: sectors_deals, compute_cid }; let ret = rt.call::( diff --git a/actors/market/tests/market_actor_test.rs b/actors/market/tests/market_actor_test.rs index 06ff6dfca..674ee9283 100644 --- a/actors/market/tests/market_actor_test.rs +++ b/actors/market/tests/market_actor_test.rs @@ -1716,6 +1716,7 @@ fn fail_when_current_epoch_greater_than_start_epoch_of_deal() { deal_ids: vec![deal_id], }], false, + vec![], ) .unwrap(); @@ -1751,6 +1752,7 @@ fn fail_when_end_epoch_of_deal_greater_than_sector_expiry() { deal_ids: vec![deal_id], }], false, + vec![], ) .unwrap(); @@ -1797,6 +1799,7 @@ fn fail_to_activate_all_deals_if_one_deal_fails() { deal_ids: vec![deal_id1, deal_id2], }], false, + vec![], ) .unwrap(); let res: BatchActivateDealsResult = diff --git a/actors/market/tests/random_cron_epoch_during_publish.rs b/actors/market/tests/random_cron_epoch_during_publish.rs index 78350c298..666a7dcbb 100644 --- a/actors/market/tests/random_cron_epoch_during_publish.rs +++ b/actors/market/tests/random_cron_epoch_during_publish.rs @@ -134,7 +134,7 @@ fn activation_after_deal_start_epoch_but_before_it_is_processed_fails() { let curr_epoch = START_EPOCH + 1; rt.set_epoch(curr_epoch); - let res = activate_deals(&rt, SECTOR_EXPIRY, PROVIDER_ADDR, curr_epoch, &[deal_id]); + let res = activate_deals_for(&rt, SECTOR_EXPIRY, PROVIDER_ADDR, curr_epoch, &[deal_id], vec![]); assert_eq!(res.activation_results.codes(), vec![ExitCode::USR_ILLEGAL_ARGUMENT]); check_state(&rt); } From 7763f9cf01fc1aa92df59171e01891e09426c2bc Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Oct 2023 14:51:51 +0400 Subject: [PATCH 3/7] deal terminated --- actors/market/src/emit.rs | 7 ++++++ actors/market/src/lib.rs | 2 ++ .../market/tests/cron_tick_deal_slashing.rs | 4 ++-- actors/market/tests/harness.rs | 23 +++++++++++++++++-- .../tests/on_miner_sectors_terminate.rs | 20 ++++++++-------- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/actors/market/src/emit.rs b/actors/market/src/emit.rs index 08055f252..f0016f72f 100644 --- a/actors/market/src/emit.rs +++ b/actors/market/src/emit.rs @@ -26,3 +26,10 @@ pub fn deal_activated(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorErr &EventBuilder::new().typ("deal-activated").field_indexed("deal_id", &deal_id).build()?, ) } + +/// Indicates a deal has been terminated. +pub fn deal_terminated(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorError> { + rt.emit_event( + &EventBuilder::new().typ("deal-terminated").field_indexed("deal_id", &deal_id).build()?, + ) +} diff --git a/actors/market/src/lib.rs b/actors/market/src/lib.rs index fc98cf6c5..37bba32eb 100644 --- a/actors/market/src/lib.rs +++ b/actors/market/src/lib.rs @@ -740,6 +740,8 @@ impl Actor { state.slash_epoch = params.epoch; deal_states.push((id, state)); + emit::deal_terminated(rt, id)?; + println!("emitted"); } st.put_deal_states(rt.store(), &deal_states)?; diff --git a/actors/market/tests/cron_tick_deal_slashing.rs b/actors/market/tests/cron_tick_deal_slashing.rs index 09f11088e..1c54f7a10 100644 --- a/actors/market/tests/cron_tick_deal_slashing.rs +++ b/actors/market/tests/cron_tick_deal_slashing.rs @@ -130,7 +130,7 @@ fn deal_is_slashed_at_the_end_epoch_should_not_be_slashed_and_should_be_consider // as deal is considered to be expired. rt.set_epoch(END_EPOCH); - terminate_deals(&rt, PROVIDER_ADDR, &[deal_id]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal_id], vec![]); // on the next cron tick, it will be processed as expired let current = END_EPOCH + 300; @@ -352,7 +352,7 @@ fn regular_payments_till_deal_expires_and_then_we_attempt_to_slash_it_but_it_wil // as deal is considered to be expired. let duration = END_EPOCH - current; rt.set_epoch(END_EPOCH); - terminate_deals(&rt, PROVIDER_ADDR, &[deal_id]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal_id], vec![]); // next epoch for cron schedule is endEpoch + 300 -> // setting epoch to higher than that will cause deal to be expired, payment will be made diff --git a/actors/market/tests/harness.rs b/actors/market/tests/harness.rs index 8d2220536..d368c756a 100644 --- a/actors/market/tests/harness.rs +++ b/actors/market/tests/harness.rs @@ -1158,16 +1158,26 @@ pub fn generate_deal_proposal( ) } -pub fn terminate_deals(rt: &MockRuntime, miner_addr: Address, deal_ids: &[DealID]) { - let ret = terminate_deals_raw(rt, miner_addr, deal_ids).unwrap(); +pub fn terminate_deals_for( + rt: &MockRuntime, + miner_addr: Address, + deal_ids: &[DealID], + expected_terminations: Vec, +) { + let ret = terminate_deals_raw(rt, miner_addr, deal_ids, expected_terminations).unwrap(); assert!(ret.is_none()); rt.verify(); } +pub fn terminate_deals(rt: &MockRuntime, miner_addr: Address, deal_ids: &[DealID]) { + terminate_deals_for(rt, miner_addr, deal_ids, deal_ids.to_vec()) +} + pub fn terminate_deals_raw( rt: &MockRuntime, miner_addr: Address, deal_ids: &[DealID], + terminated_deals: Vec, ) -> Result, ActorError> { rt.set_caller(*MINER_ACTOR_CODE_ID, miner_addr); rt.expect_validate_caller_type(vec![Type::Miner]); @@ -1175,6 +1185,15 @@ pub fn terminate_deals_raw( let params = OnMinerSectorsTerminateParams { epoch: *rt.epoch.borrow(), deal_ids: deal_ids.to_vec() }; + for deal_id in terminated_deals { + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-terminated") + .field_indexed("deal_id", &deal_id) + .build()?, + ); + } + rt.call::( Method::OnMinerSectorsTerminate as u64, IpldBlock::serialize_cbor(¶ms).unwrap(), diff --git a/actors/market/tests/on_miner_sectors_terminate.rs b/actors/market/tests/on_miner_sectors_terminate.rs index 92ec1dd1a..c4423691d 100644 --- a/actors/market/tests/on_miner_sectors_terminate.rs +++ b/actors/market/tests/on_miner_sectors_terminate.rs @@ -87,7 +87,7 @@ fn ignore_deal_proposal_that_does_not_exist() { ); activate_deals(&rt, sector_expiry, PROVIDER_ADDR, current_epoch, &[deal1]); - terminate_deals(&rt, PROVIDER_ADDR, &[deal1, 42]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal1, 42], vec![deal1]); let s = get_deal_state(&rt, deal1); assert_eq!(s.slash_epoch, current_epoch); @@ -131,7 +131,7 @@ fn terminate_valid_deals_along_with_just_expired_deal() { let new_epoch = end_epoch - 1; rt.set_epoch(new_epoch); - terminate_deals(&rt, PROVIDER_ADDR, &[deal1, deal2, deal3]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal1, deal2, deal3], vec![deal1, deal2]); assert_deals_terminated(&rt, new_epoch, &[deal1, deal2]); assert_deals_not_terminated(&rt, &[deal3]); check_state(&rt); @@ -177,7 +177,7 @@ fn terminate_valid_deals_along_with_expired_and_cleaned_up_deal() { rt.set_epoch(new_epoch); cron_tick(&rt); - terminate_deals(&rt, PROVIDER_ADDR, &deal_ids); + terminate_deals_for(&rt, PROVIDER_ADDR, &deal_ids, vec![deal_ids[0]]); assert_deals_terminated(&rt, new_epoch, &deal_ids[0..0]); assert_deal_deleted(&rt, deal_ids[1], deal2); check_state(&rt); @@ -208,7 +208,7 @@ fn terminating_a_deal_the_second_time_does_not_change_its_slash_epoch() { // set a new epoch and terminate again -> however slash epoch will still be the old epoch. rt.set_epoch(current_epoch + 1); - terminate_deals(&rt, PROVIDER_ADDR, &[deal1]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal1], vec![]); let s = get_deal_state(&rt, deal1); assert_eq!(s.slash_epoch, current_epoch); check_state(&rt); @@ -247,7 +247,7 @@ fn terminating_new_deals_and_an_already_terminated_deal_only_terminates_the_new_ // set a new epoch and terminate again -> however slash epoch will still be the old epoch. let new_epoch = current_epoch + 1; rt.set_epoch(new_epoch); - terminate_deals(&rt, PROVIDER_ADDR, &deals); + terminate_deals_for(&rt, PROVIDER_ADDR, &deals, vec![deal2, deal3]); let s1 = get_deal_state(&rt, deal1); assert_eq!(s1.slash_epoch, current_epoch); @@ -282,7 +282,7 @@ fn do_not_terminate_deal_if_end_epoch_is_equal_to_or_less_than_current_epoch() { ); activate_deals(&rt, sector_expiry, PROVIDER_ADDR, current_epoch, &[deal1]); rt.set_epoch(end_epoch); - terminate_deals(&rt, PROVIDER_ADDR, &[deal1]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal1], vec![]); assert_deals_not_terminated(&rt, &[deal1]); // deal2 has end epoch less than current epoch when terminate is called @@ -296,7 +296,7 @@ fn do_not_terminate_deal_if_end_epoch_is_equal_to_or_less_than_current_epoch() { ); activate_deals(&rt, sector_expiry, PROVIDER_ADDR, current_epoch, &[deal2]); rt.set_epoch(end_epoch + 1); - terminate_deals(&rt, PROVIDER_ADDR, &[deal2]); + terminate_deals_for(&rt, PROVIDER_ADDR, &[deal2], vec![]); assert_deals_not_terminated(&rt, &[deal2]); check_state(&rt); @@ -347,7 +347,7 @@ fn fail_when_caller_is_not_the_provider_of_the_deal() { activate_deals(&rt, sector_expiry, PROVIDER_ADDR, current_epoch, &[deal]); // XXX: Difference between go messages: 't0501' has turned into 'f0501'. - let ret = terminate_deals_raw(&rt, provider2, &[deal]); + let ret = terminate_deals_raw(&rt, provider2, &[deal], vec![]); expect_abort_contains_message( ExitCode::USR_ILLEGAL_STATE, "caller f0501 is not the provider f0102 of deal 0", @@ -375,7 +375,7 @@ fn fail_when_deal_has_been_published_but_not_activated() { end_epoch, ); - let ret = terminate_deals_raw(&rt, PROVIDER_ADDR, &[deal]); + let ret = terminate_deals_raw(&rt, PROVIDER_ADDR, &[deal], vec![]); expect_abort_contains_message(ExitCode::USR_ILLEGAL_ARGUMENT, "no state for deal", ret); rt.verify(); check_state(&rt); @@ -409,7 +409,7 @@ fn termination_of_all_deals_should_fail_when_one_deal_fails() { end_epoch + 1, ); - let ret = terminate_deals_raw(&rt, PROVIDER_ADDR, &[deal1, deal2]); + let ret = terminate_deals_raw(&rt, PROVIDER_ADDR, &[deal1, deal2], vec![deal1]); expect_abort_contains_message(ExitCode::USR_ILLEGAL_ARGUMENT, "no state for deal", ret); rt.verify(); From 8674a6b277789ab052740e11529765d1f73a701e Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Oct 2023 15:25:22 +0400 Subject: [PATCH 4/7] deal completed event --- actors/market/src/emit.rs | 7 +++++++ actors/market/src/lib.rs | 7 +++++-- actors/market/src/state.rs | 10 +++++----- actors/market/tests/cron_tick_deal_expiry.rs | 16 ++++++++++++++++ actors/market/tests/harness.rs | 10 ++++++++++ actors/market/tests/market_actor_test.rs | 8 ++++++++ .../market/tests/on_miner_sectors_terminate.rs | 8 ++++++++ 7 files changed, 59 insertions(+), 7 deletions(-) diff --git a/actors/market/src/emit.rs b/actors/market/src/emit.rs index f0016f72f..0ce3145e0 100644 --- a/actors/market/src/emit.rs +++ b/actors/market/src/emit.rs @@ -33,3 +33,10 @@ pub fn deal_terminated(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorEr &EventBuilder::new().typ("deal-terminated").field_indexed("deal_id", &deal_id).build()?, ) } + +/// Indicates a deal has been completed successfully. +pub fn deal_completed(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorError> { + rt.emit_event( + &EventBuilder::new().typ("deal-completed").field_indexed("deal_id", &deal_id).build()?, + ) +} diff --git a/actors/market/src/lib.rs b/actors/market/src/lib.rs index 37bba32eb..f0aaa9851 100644 --- a/actors/market/src/lib.rs +++ b/actors/market/src/lib.rs @@ -741,7 +741,6 @@ impl Actor { deal_states.push((id, state)); emit::deal_terminated(rt, id)?; - println!("emitted"); } st.put_deal_states(rt.store(), &deal_states)?; @@ -824,7 +823,7 @@ impl Actor { })?; } - let (slash_amount, remove_deal) = + let (slash_amount, remove_deal, complete_success) = st.process_deal_update(rt.store(), &state, &deal, curr_epoch)?; if slash_amount.is_negative() { @@ -856,6 +855,10 @@ impl Actor { "failed to delete deal proposal: does not exist" )); } + + if complete_success { + emit::deal_completed(rt, deal_id)?; + } } else { if !slash_amount.is_zero() { return Err(actor_error!( diff --git a/actors/market/src/state.rs b/actors/market/src/state.rs index 9bcc0c705..fedfc25e2 100644 --- a/actors/market/src/state.rs +++ b/actors/market/src/state.rs @@ -576,7 +576,7 @@ impl State { state: &DealState, deal: &DealProposal, epoch: ChainEpoch, - ) -> Result<(TokenAmount, bool), ActorError> + ) -> Result<(TokenAmount, bool, bool), ActorError> where BS: Blockstore, { @@ -595,7 +595,7 @@ impl State { // This would be the case that the first callback somehow triggers before it is scheduled to // This is expected not to be able to happen if deal.start_epoch > epoch { - return Ok((TokenAmount::zero(), false)); + return Ok((TokenAmount::zero(), false, false)); } let payment_end_epoch = if ever_slashed { @@ -654,14 +654,14 @@ impl State { self.slash_balance(store, &deal.provider, &slashed, Reason::ProviderCollateral) .context("slashing balance")?; - return Ok((slashed, true)); + return Ok((slashed, true, false)); } if epoch >= deal.end_epoch { self.process_deal_expired(store, deal, state)?; - return Ok((TokenAmount::zero(), true)); + return Ok((TokenAmount::zero(), true, true)); } - Ok((TokenAmount::zero(), false)) + Ok((TokenAmount::zero(), false, false)) } /// Deal start deadline elapsed without appearing in a proven sector. diff --git a/actors/market/tests/cron_tick_deal_expiry.rs b/actors/market/tests/cron_tick_deal_expiry.rs index 351745609..2eb074cd6 100644 --- a/actors/market/tests/cron_tick_deal_expiry.rs +++ b/actors/market/tests/cron_tick_deal_expiry.rs @@ -3,6 +3,7 @@ use fil_actors_runtime::network::EPOCHS_IN_DAY; use fil_actors_runtime::runtime::Policy; +use fil_actors_runtime::EventBuilder; use fvm_shared::clock::ChainEpoch; mod harness; @@ -40,6 +41,7 @@ fn deal_is_correctly_processed_if_first_cron_after_expiry() { // total payment = (end - start) let current = END_EPOCH + 5; rt.set_epoch(current); + let (pay, slashed) = cron_tick_and_assert_balances(&rt, CLIENT_ADDR, PROVIDER_ADDR, current, deal_id); let duration = END_EPOCH - START_EPOCH; @@ -168,6 +170,13 @@ fn expired_deal_should_unlock_the_remaining_client_and_provider_locked_balance_a let p_escrow = get_balance(&rt, &PROVIDER_ADDR).balance; // move the current epoch so that deal is expired + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-completed") + .field_indexed("deal_id", &deal_id) + .build() + .unwrap(), + ); rt.set_epoch(END_EPOCH + 1000); cron_tick(&rt); @@ -203,6 +212,13 @@ fn all_payments_are_made_for_a_deal_client_withdraws_collateral_and_client_accou // move the current epoch so that deal is expired rt.set_epoch(END_EPOCH + 100); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-completed") + .field_indexed("deal_id", &deal_id) + .build() + .unwrap(), + ); cron_tick(&rt); assert_eq!(deal_proposal.client_collateral, get_balance(&rt, &CLIENT_ADDR).balance); diff --git a/actors/market/tests/harness.rs b/actors/market/tests/harness.rs index d368c756a..a3bb16099 100644 --- a/actors/market/tests/harness.rs +++ b/actors/market/tests/harness.rs @@ -524,6 +524,16 @@ pub fn cron_tick_and_assert_balances( updated_provider_locked = TokenAmount::zero(); } + if is_deal_expired { + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-completed") + .field_indexed("deal_id", &deal_id) + .build() + .unwrap(), + ); + } + cron_tick(rt); let client_acct = get_balance(rt, &client_addr); diff --git a/actors/market/tests/market_actor_test.rs b/actors/market/tests/market_actor_test.rs index 674ee9283..b62e9fa0e 100644 --- a/actors/market/tests/market_actor_test.rs +++ b/actors/market/tests/market_actor_test.rs @@ -1935,6 +1935,14 @@ fn locked_fund_tracking_states() { None, ExitCode::OK, ); + + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-completed") + .field_indexed("deal_id", &deal_id2) + .build() + .unwrap(), + ); cron_tick(&rt); assert_locked_fund_states(&rt, csf, plc, clc); check_state(&rt); diff --git a/actors/market/tests/on_miner_sectors_terminate.rs b/actors/market/tests/on_miner_sectors_terminate.rs index c4423691d..848a942af 100644 --- a/actors/market/tests/on_miner_sectors_terminate.rs +++ b/actors/market/tests/on_miner_sectors_terminate.rs @@ -7,6 +7,7 @@ use fil_actor_market::{Actor as MarketActor, Method, OnMinerSectorsTerminatePara use fil_actors_runtime::network::EPOCHS_IN_DAY; use fil_actors_runtime::runtime::builtins::Type; use fil_actors_runtime::test_utils::*; +use fil_actors_runtime::EventBuilder; use fvm_ipld_encoding::ipld_block::IpldBlock; use fvm_shared::address::Address; use fvm_shared::deal::DealID; @@ -173,6 +174,13 @@ fn terminate_valid_deals_along_with_expired_and_cleaned_up_deal() { assert_eq!(2, deal_ids.len()); activate_deals(&rt, sector_expiry, PROVIDER_ADDR, current_epoch, &deal_ids); + rt.expect_emitted_event( + EventBuilder::new() + .typ("deal-completed") + .field_indexed("deal_id", &deal_ids[1]) + .build() + .unwrap(), + ); let new_epoch = end_epoch - 1; rt.set_epoch(new_epoch); cron_tick(&rt); From 537232acc9d23f00a670cceaa8fce5c617642720 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Oct 2023 16:09:25 +0400 Subject: [PATCH 5/7] run CI --- actors/market/tests/on_miner_sectors_terminate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/actors/market/tests/on_miner_sectors_terminate.rs b/actors/market/tests/on_miner_sectors_terminate.rs index 848a942af..732597563 100644 --- a/actors/market/tests/on_miner_sectors_terminate.rs +++ b/actors/market/tests/on_miner_sectors_terminate.rs @@ -181,6 +181,7 @@ fn terminate_valid_deals_along_with_expired_and_cleaned_up_deal() { .build() .unwrap(), ); + let new_epoch = end_epoch - 1; rt.set_epoch(new_epoch); cron_tick(&rt); From 405597cc7f00bfa2d437992d6184c9a2d4f3558b Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Oct 2023 16:18:25 +0400 Subject: [PATCH 6/7] rustfmt --- actors/market/tests/on_miner_sectors_terminate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actors/market/tests/on_miner_sectors_terminate.rs b/actors/market/tests/on_miner_sectors_terminate.rs index 732597563..97fef51ec 100644 --- a/actors/market/tests/on_miner_sectors_terminate.rs +++ b/actors/market/tests/on_miner_sectors_terminate.rs @@ -181,7 +181,7 @@ fn terminate_valid_deals_along_with_expired_and_cleaned_up_deal() { .build() .unwrap(), ); - + let new_epoch = end_epoch - 1; rt.set_epoch(new_epoch); cron_tick(&rt); From d7505640c37f20e8c80c8aa6e0e6aeb4dc30c00a Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 1 Nov 2023 09:08:43 +0400 Subject: [PATCH 7/7] replace deal_id with id in market events --- actors/market/src/emit.rs | 12 ++++-------- actors/market/tests/cron_tick_deal_expiry.rs | 12 ++---------- actors/market/tests/harness.rs | 11 ++++------- actors/market/tests/market_actor_test.rs | 14 +++++--------- actors/market/tests/on_miner_sectors_terminate.rs | 2 +- .../market/tests/publish_storage_deals_failures.rs | 2 +- 6 files changed, 17 insertions(+), 36 deletions(-) diff --git a/actors/market/src/emit.rs b/actors/market/src/emit.rs index 0ce3145e0..b1548bfd3 100644 --- a/actors/market/src/emit.rs +++ b/actors/market/src/emit.rs @@ -15,28 +15,24 @@ pub fn deal_published( .typ("deal-published") .field_indexed("client", &client) .field_indexed("provider", &provider) - .field_indexed("deal_id", &deal_id) + .field_indexed("id", &deal_id) .build()?, ) } /// Indicates a deal has been activated. pub fn deal_activated(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorError> { - rt.emit_event( - &EventBuilder::new().typ("deal-activated").field_indexed("deal_id", &deal_id).build()?, - ) + rt.emit_event(&EventBuilder::new().typ("deal-activated").field_indexed("id", &deal_id).build()?) } /// Indicates a deal has been terminated. pub fn deal_terminated(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorError> { rt.emit_event( - &EventBuilder::new().typ("deal-terminated").field_indexed("deal_id", &deal_id).build()?, + &EventBuilder::new().typ("deal-terminated").field_indexed("id", &deal_id).build()?, ) } /// Indicates a deal has been completed successfully. pub fn deal_completed(rt: &impl Runtime, deal_id: DealID) -> Result<(), ActorError> { - rt.emit_event( - &EventBuilder::new().typ("deal-completed").field_indexed("deal_id", &deal_id).build()?, - ) + rt.emit_event(&EventBuilder::new().typ("deal-completed").field_indexed("id", &deal_id).build()?) } diff --git a/actors/market/tests/cron_tick_deal_expiry.rs b/actors/market/tests/cron_tick_deal_expiry.rs index 2eb074cd6..f00306abd 100644 --- a/actors/market/tests/cron_tick_deal_expiry.rs +++ b/actors/market/tests/cron_tick_deal_expiry.rs @@ -171,11 +171,7 @@ fn expired_deal_should_unlock_the_remaining_client_and_provider_locked_balance_a // move the current epoch so that deal is expired rt.expect_emitted_event( - EventBuilder::new() - .typ("deal-completed") - .field_indexed("deal_id", &deal_id) - .build() - .unwrap(), + EventBuilder::new().typ("deal-completed").field_indexed("id", &deal_id).build().unwrap(), ); rt.set_epoch(END_EPOCH + 1000); cron_tick(&rt); @@ -213,11 +209,7 @@ fn all_payments_are_made_for_a_deal_client_withdraws_collateral_and_client_accou // move the current epoch so that deal is expired rt.set_epoch(END_EPOCH + 100); rt.expect_emitted_event( - EventBuilder::new() - .typ("deal-completed") - .field_indexed("deal_id", &deal_id) - .build() - .unwrap(), + EventBuilder::new().typ("deal-completed").field_indexed("id", &deal_id).build().unwrap(), ); cron_tick(&rt); assert_eq!(deal_proposal.client_collateral, get_balance(&rt, &CLIENT_ADDR).balance); diff --git a/actors/market/tests/harness.rs b/actors/market/tests/harness.rs index a3bb16099..9b7370215 100644 --- a/actors/market/tests/harness.rs +++ b/actors/market/tests/harness.rs @@ -404,7 +404,7 @@ pub fn batch_activate_deals_raw( rt.expect_emitted_event( EventBuilder::new() .typ("deal-activated") - .field_indexed("deal_id", &deal_id) + .field_indexed("id", &deal_id) .build() .unwrap(), ); @@ -528,7 +528,7 @@ pub fn cron_tick_and_assert_balances( rt.expect_emitted_event( EventBuilder::new() .typ("deal-completed") - .field_indexed("deal_id", &deal_id) + .field_indexed("id", &deal_id) .build() .unwrap(), ); @@ -730,7 +730,7 @@ pub fn publish_deals( .typ("deal-published") .field_indexed("client", &deal.client.id().unwrap()) .field_indexed("provider", &deal.provider.id().unwrap()) - .field_indexed("deal_id", &deal_id) + .field_indexed("id", &deal_id) .build() .unwrap(), ); @@ -1197,10 +1197,7 @@ pub fn terminate_deals_raw( for deal_id in terminated_deals { rt.expect_emitted_event( - EventBuilder::new() - .typ("deal-terminated") - .field_indexed("deal_id", &deal_id) - .build()?, + EventBuilder::new().typ("deal-terminated").field_indexed("id", &deal_id).build()?, ); } diff --git a/actors/market/tests/market_actor_test.rs b/actors/market/tests/market_actor_test.rs index b62e9fa0e..ce3a30f1d 100644 --- a/actors/market/tests/market_actor_test.rs +++ b/actors/market/tests/market_actor_test.rs @@ -949,7 +949,7 @@ fn provider_and_client_addresses_are_resolved_before_persisting_state_and_sent_t .typ("deal-published") .field_indexed("client", &client_resolved.id().unwrap()) .field_indexed("provider", &provider_resolved.id().unwrap()) - .field_indexed("deal_id", &deal_id) + .field_indexed("id", &deal_id) .build() .unwrap(), ); @@ -1937,11 +1937,7 @@ fn locked_fund_tracking_states() { ); rt.expect_emitted_event( - EventBuilder::new() - .typ("deal-completed") - .field_indexed("deal_id", &deal_id2) - .build() - .unwrap(), + EventBuilder::new().typ("deal-completed").field_indexed("id", &deal_id2).build().unwrap(), ); cron_tick(&rt); assert_locked_fund_states(&rt, csf, plc, clc); @@ -2158,7 +2154,7 @@ fn insufficient_client_balance_in_a_batch() { .typ("deal-published") .field_indexed("client", &deal2.client.id().unwrap()) .field_indexed("provider", &deal2.provider.id().unwrap()) - .field_indexed("deal_id", &next_deal_id) + .field_indexed("id", &next_deal_id) .build() .unwrap(), ); @@ -2307,7 +2303,7 @@ fn insufficient_provider_balance_in_a_batch() { .typ("deal-published") .field_indexed("client", &deal2.client.id().unwrap()) .field_indexed("provider", &deal2.provider.id().unwrap()) - .field_indexed("deal_id", &next_deal_id) + .field_indexed("id", &next_deal_id) .build() .unwrap(), ); @@ -2459,7 +2455,7 @@ fn psd_restricted_correctly() { .typ("deal-published") .field_indexed("client", &deal.client.id().unwrap()) .field_indexed("provider", &deal.provider.id().unwrap()) - .field_indexed("deal_id", &next_deal_id) + .field_indexed("id", &next_deal_id) .build() .unwrap(), ); diff --git a/actors/market/tests/on_miner_sectors_terminate.rs b/actors/market/tests/on_miner_sectors_terminate.rs index 97fef51ec..a373a07ca 100644 --- a/actors/market/tests/on_miner_sectors_terminate.rs +++ b/actors/market/tests/on_miner_sectors_terminate.rs @@ -177,7 +177,7 @@ fn terminate_valid_deals_along_with_expired_and_cleaned_up_deal() { rt.expect_emitted_event( EventBuilder::new() .typ("deal-completed") - .field_indexed("deal_id", &deal_ids[1]) + .field_indexed("id", &deal_ids[1]) .build() .unwrap(), ); diff --git a/actors/market/tests/publish_storage_deals_failures.rs b/actors/market/tests/publish_storage_deals_failures.rs index edc32c860..939765af2 100644 --- a/actors/market/tests/publish_storage_deals_failures.rs +++ b/actors/market/tests/publish_storage_deals_failures.rs @@ -381,7 +381,7 @@ fn fail_when_deals_have_different_providers() { .typ("deal-published") .field_indexed("client", &deal1.client.id().unwrap()) .field_indexed("provider", &deal1.provider.id().unwrap()) - .field_indexed("deal_id", &next_deal_id) + .field_indexed("id", &next_deal_id) .build() .unwrap(), );