diff --git a/Cargo.lock b/Cargo.lock index fd538581d..2647b6788 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13904,6 +13904,7 @@ dependencies = [ "log", "pallet-file-system-runtime-api", "pallet-proofs-dealer-runtime-api", + "sc-rpc-api", "serde", "shc-common", "shc-file-manager", diff --git a/Cargo.toml b/Cargo.toml index 706f56e4c..64ffcc069 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,6 +115,7 @@ sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } sc-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } sp-weights = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } +sc-rpc-api = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 066729f9f..5c43dac97 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -26,6 +26,7 @@ sp-core = { workspace = true } sp-runtime = { workspace = true } sp-trie = { workspace = true } sp-keystore = { workspace = true } +sc-rpc-api = { workspace = true } # Local pallet-file-system-runtime-api = { workspace = true } diff --git a/client/rpc/src/lib.rs b/client/rpc/src/lib.rs index ec641c569..90e42f472 100644 --- a/client/rpc/src/lib.rs +++ b/client/rpc/src/lib.rs @@ -4,8 +4,10 @@ use jsonrpsee::{ core::{async_trait, RpcResult}, proc_macros::rpc, types::error::{ErrorObjectOwned as JsonRpseeError, INTERNAL_ERROR_CODE, INTERNAL_ERROR_MSG}, + Extensions, }; use log::{debug, error, info}; +use sc_rpc_api::check_if_safe; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use tokio::{fs, fs::create_dir_all, sync::RwLock}; @@ -101,7 +103,6 @@ pub enum GetFileFromFileStorageResult { /// Used by the `rpc` macro from `jsonrpsee` /// to generate the trait that is actually going to be implemented. #[rpc(server, namespace = "storagehubclient")] -#[async_trait] pub trait StorageHubClientApi { #[method(name = "loadFileInStorage")] async fn load_file_in_storage( @@ -180,22 +181,22 @@ pub trait StorageHubClientApi { file_key: H256, ) -> RpcResult>; - #[method(name = "insertBcsvKeys")] + #[method(name = "insertBcsvKeys", with_extensions)] async fn insert_bcsv_keys(&self, seed: Option) -> RpcResult; - #[method(name = "removeBcsvKeys")] + #[method(name = "removeBcsvKeys", with_extensions)] async fn remove_bcsv_keys(&self, keystore_path: String) -> RpcResult<()>; // Note: This RPC method allow BSP administrator to add a file to the exclude list (and later // buckets, users or file fingerprint). This method is required to call before deleting a file to // avoid re-uploading a file that has just been deleted. - #[method(name = "addToExcludeList")] + #[method(name = "addToExcludeList", with_extensions)] async fn add_to_exclude_list(&self, file_key: H256, exclude_type: String) -> RpcResult<()>; // Note: This RPC method allow BSP administrator to remove a file from the exclude list (allowing // the BSP to volunteer for this specific file key again). Later it will allow to remove from the exclude // list ban users, bucket or even file fingerprint. - #[method(name = "removeFromExcludeList")] + #[method(name = "removeFromExcludeList", with_extensions)] async fn remove_from_exclude_list(&self, file_key: H256, exclude_type: String) -> RpcResult<()>; } @@ -706,7 +707,9 @@ where // In the case a seed is not provided, we delegate generation and insertion to `sr25519_generate_new`, which // internally uses the block number as a seed. // See https://paritytech.github.io/polkadot-sdk/master/sc_keystore/struct.LocalKeystore.html#method.sr25519_generate_new - async fn insert_bcsv_keys(&self, seed: Option) -> RpcResult { + async fn insert_bcsv_keys(&self, ext: &Extensions, seed: Option) -> RpcResult { + check_if_safe(ext)?; + let seed = seed.as_deref(); let new_pub_key = match seed { @@ -729,7 +732,9 @@ where } // Deletes all files with keys of type BCSV from the Keystore. - async fn remove_bcsv_keys(&self, keystore_path: String) -> RpcResult<()> { + async fn remove_bcsv_keys(&self, ext: &Extensions, keystore_path: String) -> RpcResult<()> { + check_if_safe(ext)?; + let pub_keys = self.keystore.keys(BCSV_KEY_TYPE).map_err(into_rpc_error)?; let key_path = PathBuf::from(keystore_path); @@ -748,7 +753,14 @@ where Ok(()) } - async fn add_to_exclude_list(&self, file_key: H256, exclude_type: String) -> RpcResult<()> { + async fn add_to_exclude_list( + &self, + ext: &Extensions, + file_key: H256, + exclude_type: String, + ) -> RpcResult<()> { + check_if_safe(ext)?; + let et = ExcludeType::from_str(&exclude_type).map_err(into_rpc_error)?; let mut write_file_storage = self.file_storage.write().await; @@ -763,9 +775,12 @@ where async fn remove_from_exclude_list( &self, + ext: &Extensions, file_key: H256, exclude_type: String, ) -> RpcResult<()> { + check_if_safe(ext)?; + let et = ExcludeType::from_str(&exclude_type).map_err(into_rpc_error)?; let mut write_file_storage = self.file_storage.write().await; diff --git a/node/src/rpc.rs b/node/src/rpc.rs index 5250b6951..475966ee8 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -13,6 +13,7 @@ use sc_consensus_manual_seal::{ rpc::{ManualSeal, ManualSealApiServer}, EngineCommand, }; +use sc_rpc::DenyUnsafe; use sc_transaction_pool_api::TransactionPool; use shc_common::types::{ BackupStorageProviderId, BlockNumber, ChunkId, CustomChallenge, ForestLeaf, @@ -102,5 +103,8 @@ where )?; }; + // Deny unsafe RPCs. + io.extensions_mut().insert(DenyUnsafe::Yes); + Ok(io) } diff --git a/test/suites/integration/bsp/submit-proofs.test.ts b/test/suites/integration/bsp/submit-proofs.test.ts index 2786183ef..5434c94f0 100644 --- a/test/suites/integration/bsp/submit-proofs.test.ts +++ b/test/suites/integration/bsp/submit-proofs.test.ts @@ -323,6 +323,12 @@ describeBspNet( checkTxPool: true }); + await userApi.assert.extrinsicPresent({ + module: "fileSystem", + method: "mspRespondStorageRequestsMultipleBuckets", + checkTxPool: true + }); + // Seal block and check that the transaction was successful. await userApi.block.seal();