From 3560a616c562909117c2788a4dbeeaccd03141a9 Mon Sep 17 00:00:00 2001 From: jiangying Date: Sat, 30 Jul 2022 19:33:29 +0800 Subject: [PATCH] [rpc][state.list_resource] add resource type filter (#3586) * draft * save * clean up * pass scripts/check_commit.sh * clean up --- cmd/starcoin/src/account/nft_cmd.rs | 2 ++ cmd/starcoin/src/account/show_cmd.rs | 1 + cmd/starcoin/src/state/list_cmd.rs | 1 + rpc/api/src/state/mod.rs | 3 ++- rpc/client/src/lib.rs | 2 ++ rpc/generated_rpc_schema/state.json | 10 ++++++++++ rpc/server/src/module/state_rpc.rs | 20 +++++++++++++++++++- state/statedb/src/tests.rs | 2 +- 8 files changed, 38 insertions(+), 3 deletions(-) diff --git a/cmd/starcoin/src/account/nft_cmd.rs b/cmd/starcoin/src/account/nft_cmd.rs index 56b7c6f614..bfe7d08df5 100644 --- a/cmd/starcoin/src/account/nft_cmd.rs +++ b/cmd/starcoin/src/account/nft_cmd.rs @@ -94,6 +94,7 @@ impl CommandAction for NFTCommand { None, 0, std::usize::MAX, + None, )?; let galleries: Result> = all_resources .resources @@ -128,6 +129,7 @@ impl CommandAction for NFTCommand { None, 0, std::usize::MAX, + None, )?; let ident_nfts: Result> = all_resources .resources diff --git a/cmd/starcoin/src/account/show_cmd.rs b/cmd/starcoin/src/account/show_cmd.rs index 187fb226bd..97634718d6 100644 --- a/cmd/starcoin/src/account/show_cmd.rs +++ b/cmd/starcoin/src/account/show_cmd.rs @@ -67,6 +67,7 @@ impl CommandAction for ShowCommand { Some(chain_state_reader.state_root()), 0, std::usize::MAX, + None, )?; let balances: HashMap = resources .resources diff --git a/cmd/starcoin/src/state/list_cmd.rs b/cmd/starcoin/src/state/list_cmd.rs index 67935a1b2a..dcc5ebc34e 100644 --- a/cmd/starcoin/src/state/list_cmd.rs +++ b/cmd/starcoin/src/state/list_cmd.rs @@ -118,6 +118,7 @@ impl CommandAction for ListCmd { state_root, 0, std::usize::MAX, + None, )?, )) } diff --git a/rpc/api/src/state/mod.rs b/rpc/api/src/state/mod.rs index 1a02c34f98..a976543bb2 100644 --- a/rpc/api/src/state/mod.rs +++ b/rpc/api/src/state/mod.rs @@ -114,7 +114,7 @@ pub struct ListResourceOption { pub state_root: Option, pub start_index: usize, pub max_size: usize, - //TODO support filter by type + pub resource_types: Option>, } impl Default for ListResourceOption { @@ -124,6 +124,7 @@ impl Default for ListResourceOption { state_root: None, start_index: 0, max_size: std::usize::MAX, + resource_types: None, } } } diff --git a/rpc/client/src/lib.rs b/rpc/client/src/lib.rs index da0f34ca33..ce37c744df 100644 --- a/rpc/client/src/lib.rs +++ b/rpc/client/src/lib.rs @@ -585,6 +585,7 @@ impl RpcClient { state_root: Option, start_index: usize, max_size: usize, + resource_types: Option>, ) -> anyhow::Result { self.call_rpc_blocking(|inner| { inner.state_client.list_resource( @@ -594,6 +595,7 @@ impl RpcClient { state_root, start_index, max_size, + resource_types, }), ) }) diff --git a/rpc/generated_rpc_schema/state.json b/rpc/generated_rpc_schema/state.json index 44eb3a5248..3fceae5801 100644 --- a/rpc/generated_rpc_schema/state.json +++ b/rpc/generated_rpc_schema/state.json @@ -1828,6 +1828,16 @@ "format": "uint", "minimum": 0.0 }, + "resource_types": { + "default": null, + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "start_index": { "default": 0, "type": "integer", diff --git a/rpc/server/src/module/state_rpc.rs b/rpc/server/src/module/state_rpc.rs index e5ea64099a..6f6e6eeaf0 100644 --- a/rpc/server/src/module/state_rpc.rs +++ b/rpc/server/src/module/state_rpc.rs @@ -26,7 +26,7 @@ use starcoin_types::{ }; use starcoin_vm_types::identifier::Identifier; use starcoin_vm_types::language_storage::StructTag; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::sync::Arc; pub struct StateRpcImpl @@ -260,6 +260,10 @@ where let statedb = ChainStateDB::new(db, Some(state_root)); //TODO implement list state by iter, and pagination let state = statedb.get_account_state_set(&addr)?; + let resource_types_set: Option> = + option.resource_types.map(|resource_types_value| { + HashSet::from_iter(resource_types_value.iter().cloned()) + }); match state { None => Ok(ListResourceView::default()), Some(s) => { @@ -268,6 +272,20 @@ where .cloned() .unwrap_or_default() .iter() + .filter(|(k, _)| { + if resource_types_set.is_none() { + return true; + } + let struct_tag = StructTag::decode(k.as_slice()).unwrap(); + let resource_type_address_module_name_str = format!( + "{}::{}::{}", + struct_tag.address, struct_tag.module, struct_tag.name + ); + resource_types_set + .as_ref() + .unwrap() + .contains(&resource_type_address_module_name_str) + }) .skip(option.start_index) .take(option.max_size) .map(|(k, v)| { diff --git a/state/statedb/src/tests.rs b/state/statedb/src/tests.rs index f04ff758fb..0dd9e7bbb5 100644 --- a/state/statedb/src/tests.rs +++ b/state/statedb/src/tests.rs @@ -120,7 +120,7 @@ fn test_state_db_dump_iter() -> Result<()> { assert_eq!( global_state1.state_sets().len(), 2, - "unexpect state_set length." + "unexpected state_set length." ); let mut kv1 = HashMap::new(); for item in global_state1.into_inner() {