From e9763ff2826e48f1099f74973cb12f66ce5bc0d8 Mon Sep 17 00:00:00 2001 From: aidan46 <47111423+aidan46@users.noreply.github.com> Date: Wed, 23 Oct 2024 09:50:42 +0200 Subject: [PATCH] feat(storagext): Add terminate sectors extrinsic (#465) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Duarte --- cli/artifacts/metadata.scale | Bin 149503 -> 150525 bytes .../storagext-cli/src/cmd/storage_provider.rs | 29 +++++++++++ .../storagext/src/clients/storage_provider.rs | 28 +++++++++- .../src/runtime/display/storage_provider.rs | 15 ++++++ .../storagext/src/runtime/mod.rs | 4 ++ .../storagext/src/types/storage_provider.rs | 49 ++++++++++++++++++ docs/src/pallets/storage-provider.md | 21 +++++++- 7 files changed, 144 insertions(+), 2 deletions(-) diff --git a/cli/artifacts/metadata.scale b/cli/artifacts/metadata.scale index 634cbc762eff0c46abd6f7f92745101606a915e2..04e06dc0f8fcf0b69e10b4afc479c39db386348b 100644 GIT binary patch delta 7694 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 delta 7102 zcmc&(eOQ%Mwts*7ea`_55=IbEP(b-oNKhoA>X5 z)lswmw8}OzKE5GtdM?wl6-84l3<39A3zBn|DM~IApHyKwf8H8gJ^x!>Zsb9RLVH<$g;RwkOI*5SS60|cb}Gt2 zqBb$5k?(tKGnyPDk9`g_^Wi5}pv~c1|D`FgS+Z?m3Vp;jF;QugfJCL8zuPdKuXt)T zI(hw55ma_Rbz5Q=Q#=t+Qd&`LDe7X-aumdrmRTz-mA2B7uRwE)EhUAP%F>EzCyml& zFpFtOMh~|&1TXAiNZe2+$0TpE+IH@$T&5tT!fLlx?6DSp2U6+bFEoUsm)Oh;>SM^s zv{tON*~=`I1-sIUEOvWx)uM&8MtxFAeox~f^z+9WlQF#(Vd7oQ%f6;Ef&7k!!-Llz z59B#Vw%Akp%nX*d08-Ws`3-ab~fqLZ4xZcvXov zq`cqqw(dm= zpLaTn546r*nmVD{CET1UfA zxQaSHx4WFxtHS31lKc*;&LG#M-VAaF`FlNq{EO~&w>GK>y2omoP>z~A~kJxSY=$C|jsxrV!1_JpF z$2{8PJ-vav^^C7$Qqul5=H(pTpLg+K+4Wfei@`)RMBp9qTUFn?Y{nv$F(ae zMPG?uJQ$*lPq677oU2_^DN;&I(wpIE;`wjZY0Vm`CP6EQ=F|F?4IR+VYc7p)-U`yL zPjudT%a>hJMb85WbGQ#5@}e+z?A=8ea}2%vfy&kMGx*SDUtHzCyL>y9Gv8mMj;o#` z{{Ut<_P_t4MzTGlM1CG-^80=t&#tSECx1W96BfsbPnW1Lo&5D*DRPSizL@TvSYa(L zt+eLvuv+c;w!%gMU&K0*(KJxc^TkV^)DZrmh-5cZac3xIAy(vvVyWyt6N+F!ycmiw z4`}2w6xvN9Bn7X-Lv)AXXOgIG8RoD+jh|f^u6NJDNg!BUii4jR3dc0@P&iU10T$4R z!x139PMSL+uymsRd^X%gLj?SZhUc$|n1F|@K#&x)Yy~zvYYrAk+|@`@ zg6fPk43Tb^qi`4V(!|4wxFbRF(k6#tAMIOV*oWpu!CzLIySJaF`035jh+qg5XXoQC z5_(Gv?)DGWkhsZKRG3j!RB21K+pU#yRH!J4L3%*AhGdCcT~)Hvw%t}_tE`sTa4{5v zv?6A*ye~^Rzgv%P2K_apj#5PsCv!%hGtr>KJU4_Pobg`3W+aN#rktKhb{~j+vri zE!-xM$K#Pc(Kc*uB0?6c88$cgOkyD6&#!Tb@#P<_ai^gJ3-J(fUbcwbBUazM2mv7d zsuFO@sgAE$uoyp@Xuo$ienezjZ^sLmm7yWWb@Ui!yt}l($b^TyXgP_OcMzT3~j!o)PtSQC+VCM+hIbN(>(_fi`r~l7) z5Gm{v1>eI_@OC!eLb(WDiDfh~!#%5=?pZBoQllv~|ATw-7gsJtxxOt6+W)tgRyn=2 z>VM^>v;U!&)@uCMD`pA%N<=zlr~L}fnc7ux_g%;oEt&At7i>hTMuE0G7e~-2rsRrt zpzW=mBZDUI#w`7VLX<(2S7SA6Gu+;<-L+A=CT)~<$#bR%IS#Yfy^BI^r+Dywgt5+> zJEcpmX}hNMNYWs&&_=7?E6QzH@6)egZf0qAWoAWb=?+EdH3l8NA8x*VlVtQs2Hr}) zbNn6m)8=qW!GHwK5HH-10-STUZ{H0&&Wn$$;ID5e!b2tu>Ti@|4`YMQSq!^oacz=> zVS`?@R^qOyBO2vDA!QY%Wu)NvwzI@iSye%~{fNk} zLNqRlnks}*)mnuRjEVsg?thWAR_~--)m<5t%~Yd#NlMDmu4t&_Tk`@${vNFTTF*_q zz6TFuOsw0Bne56}W+aH5llb{w#80`Zp)9qa(zeGc*6)SCMq&P{6TM&`_OfwJbnK(! zit53A6nUxsU?1jAxh4%ctSQ$u;aiQ9?1m=#s!_z~ia}vbY2P4thM3^1t_(7El9*V@>MGqPMEE0!@LX*0i8pyGNpg&zc)0~rdBcPLDRfOU zUIbE1h%v5jbd52d1yW33zt@a`GW1m9V-$?KtDLh;cg-?ulK6D7)V9@`^qX_rSlB%bhl#PbYW1!1wuJAs9yD6v> z)dQ-<yDf)8zD` z-1M#VqMYQB56DV$cXwB+Oztun5VeoPSIl|>=0Fb(aeEfhQ-sxCM%M?c!W8#=7in}L zraXc9)2oe<-WQ?N$d+eZl($lA*eJ5jWuy8@HmWnoFVc0qo?48$2gS$}cz_~NW<3(9 zs;fu1XOqFpTWQpkW^tw-&rt~4{zD|O7ANaA7wh&(tlJFMM*@^~$(eec25nTAi?(MH zZI?kCKw9@mV(Rvq_;2U<@jo8&(C>c|Y3}F~&vVqGU&K9)^yvPt8FJv;h8!S1WXJ(I z%3t(7jm#q_5dPvMsSztaKZ$bc8RGW06VZ`Vh@gdfBFzwk`}AcU2zD3U-SDGK^%vck zOGf=;H^oeg)9fidDAJhKEFWm;)as=}-zH_J%`g6@(Bf|hO(3B)QrU7tS@GN%1Wc(i zW~js|)nf1r-AZZ<&eQd&Iu@HzD^~R*&A-l!kTvnCJ9gMgtO|m*)9ZBp&iFcUq91m_pG1Tti&rMQ@|3%>y_v=%uBeT`L!3;YdgcU!?hGZN(6(S%sqsdc2P8b|uOEA_Iu z&1iZYq&6d5qn`XSvN5BH`r6!PbBnpn+-~kP_n3Rledc~M#ma}y()M}v70_djvwiDX zIt|*K?VPiSM7wM!QyyfHUO0=0Te{5fTvcIFlrA%Wi}~sS19--p(mR7|H{v{%@&(3&_!cd?72YkjuM7b z66s^YDgIG#ptyE{E@gxsi6|NaQ>G@(|1=GWNDP_KXf8|(tAMd7=YOE!wucaboSo?Y$>h+9!q zTCm&sGHq`cAHIvzB;u*x;%B7(%J+~@8SJU|a0^J+?n}6e5pn!7l5kP~&&$XGpvV3W z87e&V2R{S{eDtYfcm?b_)8G07C2t7S|NKXaJ_yz4T*VGxvHru4kP0QHFSx~H;WM2k14vfB`^-XCtI%WdK`^as8zLW;Rg(_<1nf39CMD7W;)< z%kkOlKC12tVcXSeQ;qnS5Y|dNHZzocN;jBQVQj71WNH=-VeDRX>K}%&qiO&>e|0P9 zHO*F{(yEH9imL4Q6%;FI63r3p4w~3-1bbFJXF4zTM3UW_^%Ie7H$#tp%RH6|syEMP z>!m9^7ejiEh!11fCba0wW7$a`Qv3a7EL^pkoeQhaU(UW%aY@WiV;5o5O)J??<(2D& zRqS?9Cid}aw#Azs+On8$NT#Kz$Xc0RSgmhf!+xxiAFJzF1s?44-9a`w3( zZD#K{1G2_iVzt}s?dAk0MMh~wrA5B}bea>Q3<^JDUtsMqABi!#&P~!QUS7v$s(t1o VqUUY+dG?!+Y@t6&)SLmc@^`8iLtOv> diff --git a/cli/polka-storage/storagext-cli/src/cmd/storage_provider.rs b/cli/polka-storage/storagext-cli/src/cmd/storage_provider.rs index 934589e5..2d2bfbe8 100644 --- a/cli/polka-storage/storagext-cli/src/cmd/storage_provider.rs +++ b/cli/polka-storage/storagext-cli/src/cmd/storage_provider.rs @@ -14,6 +14,7 @@ use storagext::{ RecoveryDeclaration as SxtRecoveryDeclaration, SectorPreCommitInfo as SxtSectorPreCommitInfo, SubmitWindowedPoStParams as SxtSubmitWindowedPoStParams, + TerminationDeclaration as SxtTerminationDeclaration, }, PolkaStorageConfig, StorageProviderClientExt, }; @@ -82,6 +83,12 @@ pub enum StorageProviderCommand { #[arg(value_parser = as DeserializablePath>::deserialize_json)] recoveries: std::vec::Vec, }, + + /// Terminate sectors. + TerminateSectors { + #[arg(value_parser = as DeserializablePath>::deserialize_json)] + terminations: std::vec::Vec, + }, } impl StorageProviderCommand { @@ -165,6 +172,9 @@ impl StorageProviderCommand { StorageProviderCommand::DeclareFaultsRecovered { recoveries } => { Self::declare_faults_recovered(client, account_keypair, recoveries).await? } + StorageProviderCommand::TerminateSectors { terminations } => { + Self::terminate_sectors(client, account_keypair, terminations).await? + } _unsigned => unreachable!("unsigned commands should have been previously handled"), }; @@ -316,4 +326,23 @@ impl StorageProviderCommand { Ok(submission_result) } + + async fn terminate_sectors( + client: Client, + account_keypair: MultiPairSigner, + terminations: Vec, + ) -> Result, subxt::Error> + where + Client: StorageProviderClientExt, + { + let submission_result = client + .terminate_sectors(&account_keypair, terminations) + .await?; + tracing::debug!( + "[{}] Successfully terminated sectors.", + submission_result.hash + ); + + Ok(submission_result) + } } diff --git a/cli/polka-storage/storagext/src/clients/storage_provider.rs b/cli/polka-storage/storagext/src/clients/storage_provider.rs index f078981c..26ee45c5 100644 --- a/cli/polka-storage/storagext/src/clients/storage_provider.rs +++ b/cli/polka-storage/storagext/src/clients/storage_provider.rs @@ -18,7 +18,9 @@ use crate::{ }, storage_provider::calls::types::register_storage_provider::PeerId, }, - types::storage_provider::{FaultDeclaration, RecoveryDeclaration, SectorPreCommitInfo}, + types::storage_provider::{ + FaultDeclaration, RecoveryDeclaration, SectorPreCommitInfo, TerminationDeclaration, + }, BlockNumber, Currency, PolkaStorageConfig, }; pub trait StorageProviderClientExt { @@ -71,6 +73,14 @@ pub trait StorageProviderClientExt { where Keypair: subxt::tx::Signer; + fn terminate_sectors( + &self, + account_keypair: &Keypair, + terminations: Vec, + ) -> impl Future, subxt::Error>> + where + Keypair: subxt::tx::Signer; + fn retrieve_storage_provider( &self, account_id: &AccountId32, @@ -217,6 +227,22 @@ impl StorageProviderClientExt for crate::runtime::client::Client { self.traced_submission(&payload, account_keypair).await } + #[tracing::instrument(level = "debug", skip_all)] + async fn terminate_sectors( + &self, + account_keypair: &Keypair, + terminations: Vec, + ) -> Result, subxt::Error> + where + Keypair: subxt::tx::Signer, + { + let payload = runtime::tx() + .storage_provider() + .terminate_sectors(terminations.into()); + + self.traced_submission(&payload, account_keypair).await + } + #[tracing::instrument(level = "debug", skip_all)] async fn retrieve_storage_provider( &self, diff --git a/cli/polka-storage/storagext/src/runtime/display/storage_provider.rs b/cli/polka-storage/storagext/src/runtime/display/storage_provider.rs index 94a31e63..47eebd15 100644 --- a/cli/polka-storage/storagext/src/runtime/display/storage_provider.rs +++ b/cli/polka-storage/storagext/src/runtime/display/storage_provider.rs @@ -125,6 +125,21 @@ impl std::fmt::Display for Event { ) .collect::() )), + Event::SectorsTerminated { + owner, + terminations, + } => f.write_fmt(format_args!( + "Sectors terminated: {{ owner: {}, terminations: [{}]", + owner, + itertools::Itertools::intersperse( + terminations + .0 + .iter() + .map(|termination| format!("{termination:?}")), + ", ".to_string() + ) + .collect::() + )), } } } diff --git a/cli/polka-storage/storagext/src/runtime/mod.rs b/cli/polka-storage/storagext/src/runtime/mod.rs index c3423f8a..484a1d43 100644 --- a/cli/polka-storage/storagext/src/runtime/mod.rs +++ b/cli/polka-storage/storagext/src/runtime/mod.rs @@ -87,6 +87,10 @@ pub mod display; path = "pallet_storage_provider::fault::RecoveryDeclaration", derive = "::serde::Serialize" ), + derive_for_type( + path = "pallet_storage_provider::sector::TerminationDeclaration", + derive = "::serde::Serialize" + ), derive_for_type( path = "pallet_market::pallet::ActiveDealState", derive = "::serde::Serialize" diff --git a/cli/polka-storage/storagext/src/types/storage_provider.rs b/cli/polka-storage/storagext/src/types/storage_provider.rs index fad99e4b..94f8ef4a 100644 --- a/cli/polka-storage/storagext/src/types/storage_provider.rs +++ b/cli/polka-storage/storagext/src/types/storage_provider.rs @@ -27,6 +27,8 @@ use crate::{ sector::{ ProveCommitSector as RuntimeProveCommitSector, SectorPreCommitInfo as RuntimeSectorPreCommitInfo, + TerminateSectorsParams as RuntimeTerminateSectorsParams, + TerminationDeclaration as RuntimeTerminationDeclaration, }, }, }, @@ -273,6 +275,32 @@ impl Into for SubmitWindowedPoStParams { } } +#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)] +pub struct TerminationDeclaration { + pub deadline: u64, + pub partition: u32, + pub sectors: BTreeSet, +} + +impl From for RuntimeTerminationDeclaration { + fn from(value: TerminationDeclaration) -> Self { + Self { + deadline: value.deadline, + partition: value.partition, + // Converts from BTreeSet -> Vec -> BoundedBTreeSet because subxt... + sectors: bounded_btree_set::BoundedBTreeSet(value.sectors.into_iter().collect()), + } + } +} + +impl From> for RuntimeTerminateSectorsParams { + fn from(value: Vec) -> Self { + Self { + terminations: bounded_vec::BoundedVec(value.into_iter().map(Into::into).collect()), + } + } +} + #[cfg(test)] mod tests { use std::{collections::BTreeSet, str::FromStr}; @@ -286,6 +314,7 @@ mod tests { market::DealProposal, storage_provider::{ FaultDeclaration, PoStProof, RecoveryDeclaration, SubmitWindowedPoStParams, + TerminationDeclaration, }, }, PolkaStorageConfig, @@ -448,4 +477,24 @@ mod tests { } ); } + + #[test] + fn ensure_serde_for_termination_declaration() { + let termination = serde_json::from_str::>( + r#"[{ + "deadline": 69, + "partition": 420, + "sectors": [1, 2] + }]"#, + ) + .unwrap(); + assert_eq!( + termination, + vec![TerminationDeclaration { + deadline: 69, + partition: 420, + sectors: BTreeSet::from([1, 2]), + }] + ) + } } diff --git a/docs/src/pallets/storage-provider.md b/docs/src/pallets/storage-provider.md index a179e6cf..f104fb99 100644 --- a/docs/src/pallets/storage-provider.md +++ b/docs/src/pallets/storage-provider.md @@ -281,7 +281,26 @@ Where the termination declarations contain: #### Example -TODO(@aidan46, #463, 2024/10/18): Add storagext example after implementation +Storage provider `//Alice` terminating sectors[^terminate_sectors] on deadline 0, partition 0, sector 1. + + +```bash +storagext-cli --sr25519-key "//Alice" storage-provider terminate-sectors @terminate-sectors.json +``` + +Where `terminate-sectors.json` is a file with contents similar to: + +```json +[ + { + "deadline": 0, + "partition": 0, + "sectors": [1] + } +] +``` + +[^terminate_sectors]: Read more about the `terminate-sectors` command in [_Storagext CLI/Subcommand `storage-provider`/`terminate-sectors`_](../storagext-cli/storage-provider.md#terminate-sectors) ## Events