From 76f79ce126d37f51e1778a7d0aeea8198285bd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C4=8Cerni=C4=8D?= Date: Tue, 26 Nov 2024 05:46:34 -0800 Subject: [PATCH] feat(market): enable deal state retrieval (#609) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Duarte --- .dockerignore | 17 ----------- docs/src/storagext-cli/market.md | 20 ++++++++++++- examples/rpc_publish.sh | 5 +++- storagext/cli/src/cmd/market.rs | 17 +++++++++-- storagext/lib/src/clients/market.rs | 27 ++++++++++++++++++ storagext/lib/src/runtime/display/market.rs | 31 +++++++++++++++++---- 6 files changed, 91 insertions(+), 26 deletions(-) delete mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index a9d84ea41..000000000 --- a/.dockerignore +++ /dev/null @@ -1,17 +0,0 @@ -# Ignore everything -* - -# Allow files and directories -!/api -!/cli -!/Justfile -!/lib -!/maat -!/node -!/pallets -!/primitives -!/runtime -!/storage -!/rust-toolchain.toml -!/Cargo.lock -!/Cargo.toml diff --git a/docs/src/storagext-cli/market.md b/docs/src/storagext-cli/market.md index 6716defb8..ae4e6e37d 100644 --- a/docs/src/storagext-cli/market.md +++ b/docs/src/storagext-cli/market.md @@ -174,10 +174,28 @@ The `retrieve-balance` command checks the balance of a given market account. | ------------ | ------------------------------------ | | `ACCOUNT_ID` | The IDs of the account being checked | -### Example +### Example ```bash storagext-cli market retrieve-balance "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice's account ``` > This command **is not signed**, and does not need to be called using any of the `--X-key` flags. + +## `retrieve-deal` + +The `retrieve-deal` command fetches detailed information about a specific storage deal from the chain. This command allows users to check the current status, parameters, and other relevant details of an existing deal. If the specified deal is not found, it could indicate that the deal was never published, has already been completed, or was terminated. + +### Parameters + +| Name | Description | +| --------- | ---------------------------------- | +| `DEAL_ID` | The ID of the deal being retrieved | + +### Example + +```bash +storagext-cli market market retrieve-deal 0 +``` + +> This command **is not signed**, and does not need to be called using any of the `--X-key` flags. diff --git a/examples/rpc_publish.sh b/examples/rpc_publish.sh index ffab76a4f..cdf67d08a 100755 --- a/examples/rpc_publish.sh +++ b/examples/rpc_publish.sh @@ -36,7 +36,10 @@ target/release/storagext-cli --sr25519-key "$PROVIDER" market add-balance 250000 wait # Register the SP -target/release/storagext-cli --sr25519-key "//Charlie" storage-provider register "peer_id" +target/release/storagext-cli --sr25519-key "$PROVIDER" storage-provider register "peer_id" + +# Set PoRep verifying key +target/release/storagext-cli --sr25519-key "$PROVIDER" proofs set-porep-verifying-key @2KiB.porep.vk.scale DEAL_JSON=$( jq -n \ diff --git a/storagext/cli/src/cmd/market.rs b/storagext/cli/src/cmd/market.rs index 0f8be58a3..5c3aa8daf 100644 --- a/storagext/cli/src/cmd/market.rs +++ b/storagext/cli/src/cmd/market.rs @@ -78,6 +78,12 @@ pub(crate) enum MarketCommand { /// The target account's ID. account_id: ::AccountId, }, + + /// Retrieve the deal for a given deal ID. + RetrieveDeal { + /// The target deal's ID. + deal_id: DealId, + }, } impl MarketCommand { @@ -97,8 +103,6 @@ impl MarketCommand { let client = storagext::Client::new(node_rpc, n_retries, retry_interval).await?; match self { - // Only command that doesn't need a key. - // // NOTE: subcommand_negates_reqs does not work for this since it only negates the parents' // requirements, and the global arguments (keys) are at the grandparent level // https://users.rust-lang.org/t/clap-ignore-global-argument-in-sub-command/101701/8 @@ -116,6 +120,15 @@ impl MarketCommand { tracing::error!("Could not find account {}", account_id); } } + MarketCommand::RetrieveDeal { deal_id } => { + if let Some(deal) = client.retrieve_deal(deal_id).await? { + tracing::debug!("Deal {:?}", deal); + + println!("{}", output_format.format(&deal)?); + } else { + tracing::error!("Could not find deal {}", deal_id); + } + } else_ => { let Some(account_keypair) = account_keypair else { return Err(missing_keypair_error::().into()); diff --git a/storagext/lib/src/clients/market.rs b/storagext/lib/src/clients/market.rs index b129346b0..438dd1654 100644 --- a/storagext/lib/src/clients/market.rs +++ b/storagext/lib/src/clients/market.rs @@ -92,6 +92,12 @@ pub trait MarketClientExt { &self, account_id: ::AccountId, ) -> impl Future>, subxt::Error>>; + + /// Retrieve the deal for a given deal ID. + fn retrieve_deal( + &self, + deal_id: DealId, + ) -> impl Future, subxt::Error>>; } impl MarketClientExt for crate::runtime::client::Client { @@ -279,4 +285,25 @@ impl MarketClientExt for crate::runtime::client::Client { .fetch(&balance_table_query) .await } + + #[tracing::instrument(level = "debug", skip_all, fields(deal_id))] + async fn retrieve_deal(&self, deal_id: DealId) -> Result, subxt::Error> { + let deal_table_query = runtime::storage().market().proposals(deal_id); + let Some(deal) = self + .client + .storage() + .at_latest() + .await? + .fetch(&deal_table_query) + .await? + else { + return Ok(None); + }; + + let deal = DealProposal::try_from(deal).map_err(|e| { + subxt::Error::Other(format!("failed to convert deal proposal: {:?}", e)) + })?; + + Ok(Some(deal)) + } } diff --git a/storagext/lib/src/runtime/display/market.rs b/storagext/lib/src/runtime/display/market.rs index 8ba4a67e4..cc1307ea8 100644 --- a/storagext/lib/src/runtime/display/market.rs +++ b/storagext/lib/src/runtime/display/market.rs @@ -1,11 +1,32 @@ -use crate::runtime::{ - market::Event, - runtime_types::{ - pallet_market::{pallet, pallet::BalanceEntry}, - polka_storage_runtime::Runtime, +use crate::{ + runtime::{ + market::Event, + runtime_types::{ + pallet_market::pallet::{self, BalanceEntry, DealState}, + polka_storage_runtime::Runtime, + }, }, + types::market::DealProposal, }; +impl std::fmt::Display for DealState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DealState::Published => f.write_str("Published"), + DealState::Active(state) => f.write_fmt(format_args!("Active({{ sector_number: {}, sector_start_block: {}, last_updated_block: {:?}, slash_block: {:?} }})", state.sector_number, state.sector_start_block, state.last_updated_block, state.slash_block)), + } + } +} + +impl std::fmt::Display for DealProposal { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!( + "Deal Proposal {{ piece_cid: {}, piece_size: {}, provider: {}, client: {}, label: {}, start_block: {}, end_block: {}, storage_price_per_block: {}, provider_collateral: {}, state: {} }}", + self.piece_cid, self.piece_size, self.provider, self.client, self.label, self.start_block, self.end_block, self.storage_price_per_block, self.provider_collateral, self.state + )) + } +} + impl std::fmt::Display for pallet::SettledDealData { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!(