From c5cffcd26db34b6ee0401a9aa6226a68ac5d5a13 Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 23 Jan 2025 13:50:07 +0800 Subject: [PATCH 1/9] remove Result from StateKey::resource --- chain/src/chain.rs | 2 +- cmd/airdrop/src/main.rs | 2 +- cmd/db-exporter/src/force_deploy_output.rs | 2 +- cmd/genesis-nft-miner/src/main.rs | 2 +- cmd/starcoin/src/state/get_proof_cmd.rs | 4 +-- contrib-contracts/src/starcoin_merkle_test.rs | 4 +-- network-rpc/src/tests.rs | 2 +- rpc/server/src/module/contract_rpc.rs | 2 +- rpc/server/src/module/state_rpc.rs | 2 +- state/api/src/lib.rs | 2 +- state/statedb/src/lib.rs | 6 ++-- state/statedb/src/tests.rs | 16 +++++----- testsuite/tests/steps/state.rs | 2 +- types/src/account.rs | 4 +-- vm/e2e-tests/src/account.rs | 4 +-- vm/e2e-tests/src/data_store.rs | 4 +-- vm/e2e-tests/src/executor.rs | 2 +- .../src/lib.rs | 4 +-- .../src/remote_state.rs | 2 +- vm/types/src/on_chain_config/mod.rs | 2 +- vm/types/src/state_store/mod.rs | 2 +- vm/types/src/state_store/state_key/mod.rs | 32 +++++++++---------- vm/types/src/state_store/state_key/prefix.rs | 4 +-- vm/types/src/state_store/state_key/tests.rs | 4 +-- vm/types/src/state_view.rs | 8 ++--- vm/vm-runtime/src/move_vm_ext/mod.rs | 11 ++----- .../src/move_vm_ext/warm_vm_cache.rs | 8 +---- vm/vm-runtime/src/starcoin_vm.rs | 4 +-- 28 files changed, 65 insertions(+), 78 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index b36441ea8b..df267555f0 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -2097,7 +2097,7 @@ impl ChainReader for BlockChain { let state_key = match access_path.path { DataPath::Code(module_name) => StateKey::module(&access_path.address, &module_name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, &struct_tag)? + StateKey::resource(&access_path.address, &struct_tag) } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, &struct_tag) diff --git a/cmd/airdrop/src/main.rs b/cmd/airdrop/src/main.rs index 4b056f4aa2..dcd2cd74f8 100644 --- a/cmd/airdrop/src/main.rs +++ b/cmd/airdrop/src/main.rs @@ -218,7 +218,7 @@ async fn main() -> Result<()> { // read from onchain let account_sequence_number = { - let state_key = StateKey::resource(&sender, &account_struct_tag())?; + let state_key = StateKey::resource(&sender, &account_struct_tag()); let account_data: Option> = state_client .get(state_key) .await diff --git a/cmd/db-exporter/src/force_deploy_output.rs b/cmd/db-exporter/src/force_deploy_output.rs index 4b5ae41a7d..3466f719c2 100644 --- a/cmd/db-exporter/src/force_deploy_output.rs +++ b/cmd/db-exporter/src/force_deploy_output.rs @@ -113,7 +113,7 @@ pub fn force_deploy_output( AccessPath::resource_access_path(genesis_address(), ModuleUpgradeStrategy::struct_tag()); // Write upgrade strategy resource to 0 let upgrade_strategy_path = - StateKey::resource(&genesis_address(), &ModuleUpgradeStrategy::struct_tag())?; + StateKey::resource(&genesis_address(), &ModuleUpgradeStrategy::struct_tag()); let statedb = chain.chain_state(); let before_ret = statedb diff --git a/cmd/genesis-nft-miner/src/main.rs b/cmd/genesis-nft-miner/src/main.rs index 1e0cc0f941..d4cffcbc0c 100644 --- a/cmd/genesis-nft-miner/src/main.rs +++ b/cmd/genesis-nft-miner/src/main.rs @@ -87,7 +87,7 @@ async fn main() -> Result<()> { let txpool_client = TxPoolClient::from(channel.clone()); let chain_id: u8 = chain_client.id().await.map_err(map_rpc_error)?.id; let account_sequence_number = { - let state_key = StateKey::resource(&sender, &account_struct_tag())?; + let state_key = StateKey::resource(&sender, &account_struct_tag()); let account_data: Option> = state_client .get(state_key) .await diff --git a/cmd/starcoin/src/state/get_proof_cmd.rs b/cmd/starcoin/src/state/get_proof_cmd.rs index 55e5a1b3f2..0908dc90aa 100644 --- a/cmd/starcoin/src/state/get_proof_cmd.rs +++ b/cmd/starcoin/src/state/get_proof_cmd.rs @@ -69,9 +69,7 @@ impl CommandAction for GetProofCommand { let access_path = opt.access_path.clone(); let state_key = match access_path.clone().path { DataPath::Code(module_name) => StateKey::module(&access_path.address, &module_name), - DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, &struct_tag)? - } + DataPath::Resource(struct_tag) => StateKey::resource(&access_path.address, &struct_tag), DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, &struct_tag) } diff --git a/contrib-contracts/src/starcoin_merkle_test.rs b/contrib-contracts/src/starcoin_merkle_test.rs index dd8a75cd83..5d7aefb2e7 100644 --- a/contrib-contracts/src/starcoin_merkle_test.rs +++ b/contrib-contracts/src/starcoin_merkle_test.rs @@ -16,7 +16,7 @@ use test_helper::executor::{ #[stest::test] fn test_starcoin_merkle() -> Result<()> { let (chain_state, net) = prepare_genesis(); - let state_key = StateKey::resource(&association_address(), &account_struct_tag())?; + let state_key = StateKey::resource(&association_address(), &account_struct_tag()); let ap = AccessPath::resource_access_path(association_address(), account_struct_tag()); let state_with_proof = chain_state.get_with_proof(&state_key)?; state_with_proof.proof.verify( @@ -72,7 +72,7 @@ fn test_starcoin_merkle() -> Result<()> { // let state_root = chain_state.state_root(); let _expected_root = MoveValue::vector_u8(state_root.to_vec()); - let ap = StateKey::resource(&association_address(), &account_struct_tag())?; + let ap = StateKey::resource(&association_address(), &account_struct_tag()); let state_with_proof = old_chain_state.get_with_proof(&ap)?; let account_address = MoveValue::vector_u8(association_address().to_vec()); let account_state_hash = MoveValue::vector_u8( diff --git a/network-rpc/src/tests.rs b/network-rpc/src/tests.rs index 77a6a1885c..c62abc8604 100644 --- a/network-rpc/src/tests.rs +++ b/network-rpc/src/tests.rs @@ -45,7 +45,7 @@ fn test_network_rpc() { DataPath::Resource(Epoch::struct_tag_for_epoch()), ); - let state_key = StateKey::resource(&genesis_address(), &Epoch::struct_tag_for_epoch()).unwrap(); + let state_key = StateKey::resource(&genesis_address(), &Epoch::struct_tag_for_epoch()); //ping ok let req = Ping { diff --git a/rpc/server/src/module/contract_rpc.rs b/rpc/server/src/module/contract_rpc.rs index 92afafeb2b..07bab68415 100644 --- a/rpc/server/src/module/contract_rpc.rs +++ b/rpc/server/src/module/contract_rpc.rs @@ -103,7 +103,7 @@ where let playground = self.playground.clone(); let f = async move { let state_root = service.clone().state_root().await?; - let state_key = StateKey::resource(&addr, &resource_type.0)?; + let state_key = StateKey::resource(&addr, &resource_type.0); let data = service.get(state_key).await?; match data { None => Ok(None), diff --git a/rpc/server/src/module/state_rpc.rs b/rpc/server/src/module/state_rpc.rs index db49398748..036757de03 100644 --- a/rpc/server/src/module/state_rpc.rs +++ b/rpc/server/src/module/state_rpc.rs @@ -273,7 +273,7 @@ where .state_root .unwrap_or(service.clone().state_root().await?); let chain_state = ChainStateDB::new(state_store, Some(state_root)); - let state_key = StateKey::resource(&addr, &resource_type.0)?; + let state_key = StateKey::resource(&addr, &resource_type.0); let data = chain_state.get_state_value_bytes(&state_key)?; Ok(match data { None => None, diff --git a/state/api/src/lib.rs b/state/api/src/lib.rs index 56d873774e..8eb94c22ea 100644 --- a/state/api/src/lib.rs +++ b/state/api/src/lib.rs @@ -52,7 +52,7 @@ pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { R: MoveResource, { let rsrc_bytes = self - .get(StateKey::resource_typed::(&address)?) + .get(StateKey::resource_typed::(&address)) .await? .ok_or_else(|| { format_err!( diff --git a/state/statedb/src/lib.rs b/state/statedb/src/lib.rs index 28ba9563ba..fcdb771fae 100644 --- a/state/statedb/src/lib.rs +++ b/state/statedb/src/lib.rs @@ -583,7 +583,7 @@ impl ChainStateReader for ChainStateDB { name: Identifier::new("TableHandles").unwrap(), type_args: vec![], }; - let state_key = StateKey::resource(handle_address, &struct_tag)?; + let state_key = StateKey::resource(handle_address, &struct_tag); let table_path_proof = self.get_with_proof(&state_key)?; let state_tree_table_handle = self.get_state_tree_table_handles(idx)?; let table_handle_proof = state_tree_table_handle.get_with_proof(handle)?; @@ -620,7 +620,7 @@ impl ChainStateWriter for ChainStateDB { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag)? + StateKey::resource(&access_path.address, struct_tag) } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) @@ -639,7 +639,7 @@ impl ChainStateWriter for ChainStateDB { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag)? + StateKey::resource(&access_path.address, struct_tag) } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) diff --git a/state/statedb/src/tests.rs b/state/statedb/src/tests.rs index 70dbe01dff..711f6bd843 100644 --- a/state/statedb/src/tests.rs +++ b/state/statedb/src/tests.rs @@ -43,7 +43,7 @@ fn test_state_proof() -> Result<()> { type_args: vec![], }; let access_path = AccessPath::new(account_address, DataPath::Resource(struct_tag.clone())); - let state_key = StateKey::resource(&account_address, &struct_tag)?; + let state_key = StateKey::resource(&account_address, &struct_tag); let state0 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key.clone(), state0.clone()))?; @@ -72,7 +72,7 @@ fn test_state_db() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key = StateKey::resource(&account_address, &struct_tag)?; + let state_key = StateKey::resource(&account_address, &struct_tag); let state0 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key.clone(), state0))?; let state_root = chain_state_db.commit()?; @@ -95,7 +95,7 @@ fn test_state_db_dump_and_apply() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key = StateKey::resource(&account_address, &struct_tag)?; + let state_key = StateKey::resource(&account_address, &struct_tag); let state0 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key, state0))?; @@ -130,7 +130,7 @@ fn test_state_version() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key = StateKey::resource(&account_address, &struct_tag)?; + let state_key = StateKey::resource(&account_address, &struct_tag); let old_state = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key.clone(), old_state.clone()))?; chain_state_db.commit()?; @@ -160,7 +160,7 @@ fn test_state_db_dump_iter() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key1 = StateKey::resource(&account_address, &struct_tag)?; + let state_key1 = StateKey::resource(&account_address, &struct_tag); let state1 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key1, state1))?; let state2 = random_bytes(); @@ -171,7 +171,7 @@ fn test_state_db_dump_iter() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key2 = StateKey::resource(&account_address2, &struct_tag2)?; + let state_key2 = StateKey::resource(&account_address2, &struct_tag2); chain_state_db.apply_write_set(to_write_set(state_key2, state2))?; chain_state_db.commit()?; chain_state_db.flush()?; @@ -260,7 +260,7 @@ fn test_state_db_with_table_item_once() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key2 = StateKey::resource(&account_address2, &struct_tag2)?; + let state_key2 = StateKey::resource(&account_address2, &struct_tag2); let state_keys = vec![ state_key1, @@ -480,7 +480,7 @@ fn test_state_with_table_item_proof() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key2 = StateKey::resource(&account_address2, &struct_tag2)?; + let state_key2 = StateKey::resource(&account_address2, &struct_tag2); let state_keys = vec![ state_key1, state_key2, diff --git a/testsuite/tests/steps/state.rs b/testsuite/tests/steps/state.rs index b2d6ec3ec6..9208ac4265 100644 --- a/testsuite/tests/steps/state.rs +++ b/testsuite/tests/steps/state.rs @@ -15,7 +15,7 @@ pub fn steps() -> Steps { account.address.clone(), AccountResource::struct_tag(), ); - let key = StateKey::resource(account.address(), &AccountResource::struct_tag()).unwrap(); + let key = StateKey::resource(account.address(), &AccountResource::struct_tag()); let proof = client.clone().state_get_with_proof(key).unwrap(); let state_root = client.clone().state_get_state_root().unwrap(); proof diff --git a/types/src/account.rs b/types/src/account.rs index 8bebeec5bd..8455551033 100644 --- a/types/src/account.rs +++ b/types/src/account.rs @@ -510,11 +510,11 @@ impl AccountData { pub fn to_writeset(&self) -> WriteSet { let write_set = vec![ ( - StateKey::resource_typed::(self.address()).unwrap(), + StateKey::resource_typed::(self.address()), WriteOp::legacy_modification(self.to_bytes().into()), ), ( - StateKey::resource_typed::(self.address()).unwrap(), + StateKey::resource_typed::(self.address()), WriteOp::legacy_modification(self.coin_store.to_bytes().into()), ), ]; diff --git a/vm/e2e-tests/src/account.rs b/vm/e2e-tests/src/account.rs index 14af3d577a..259249d342 100644 --- a/vm/e2e-tests/src/account.rs +++ b/vm/e2e-tests/src/account.rs @@ -609,7 +609,7 @@ impl AccountData { .simple_serialize(&AccountData::layout()) .unwrap(); write_set.push(( - StateKey::resource_typed::(self.address()).unwrap(), + StateKey::resource_typed::(self.address()), WriteOp::legacy_modification(account.into()), )); @@ -619,7 +619,7 @@ impl AccountData { .simple_serialize(&CoinStore::layout()) .unwrap(); write_set.push(( - StateKey::resource_typed::(self.address()).unwrap(), + StateKey::resource_typed::(self.address()), WriteOp::legacy_modification(balance.into()), )); diff --git a/vm/e2e-tests/src/data_store.rs b/vm/e2e-tests/src/data_store.rs index 7cd0645dbb..befa362584 100644 --- a/vm/e2e-tests/src/data_store.rs +++ b/vm/e2e-tests/src/data_store.rs @@ -125,7 +125,7 @@ impl ChainStateWriter for FakeDataStore { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag)? + StateKey::resource(&access_path.address, struct_tag) } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) @@ -142,7 +142,7 @@ impl ChainStateWriter for FakeDataStore { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag)? + StateKey::resource(&access_path.address, struct_tag) } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) diff --git a/vm/e2e-tests/src/executor.rs b/vm/e2e-tests/src/executor.rs index 79c3b173bd..e5c2c40664 100644 --- a/vm/e2e-tests/src/executor.rs +++ b/vm/e2e-tests/src/executor.rs @@ -280,7 +280,7 @@ impl FakeExecutor { fn read_resource(&self, addr: &AccountAddress) -> Option { let data_blob = TStateView::get_state_value_bytes( &self.data_store, - &StateKey::resource_typed::(addr).expect("failed to create StateKey"), + &StateKey::resource_typed::(addr), ) .expect("account must exist in data store") .unwrap_or_else(|| panic!("Can't fetch {} resource for {}", T::STRUCT_NAME, addr)); diff --git a/vm/starcoin-transactional-test-harness/src/lib.rs b/vm/starcoin-transactional-test-harness/src/lib.rs index 7dc263cb83..05776532ac 100644 --- a/vm/starcoin-transactional-test-harness/src/lib.rs +++ b/vm/starcoin-transactional-test-harness/src/lib.rs @@ -480,7 +480,7 @@ impl<'a> StarcoinTestAdapter<'a> { let account_blob = self .context .storage - .get_state_value_bytes(&StateKey::resource_typed::(signer_addr)?) + .get_state_value_bytes(&StateKey::resource_typed::(signer_addr)) .unwrap() .ok_or_else(|| { format_err!( @@ -500,7 +500,7 @@ impl<'a> StarcoinTestAdapter<'a> { ) -> Result { let token_code = TokenCode::from_str(balance_currency_code.as_str())?; let balance_resource_tag = BalanceResource::struct_tag_for_token(token_code.try_into()?); - let balance_access_key = StateKey::resource(signer_addr, &balance_resource_tag)?; + let balance_access_key = StateKey::resource(signer_addr, &balance_resource_tag); let balance_blob = self .context diff --git a/vm/starcoin-transactional-test-harness/src/remote_state.rs b/vm/starcoin-transactional-test-harness/src/remote_state.rs index dd0a1fe305..49b98259c7 100644 --- a/vm/starcoin-transactional-test-harness/src/remote_state.rs +++ b/vm/starcoin-transactional-test-harness/src/remote_state.rs @@ -318,7 +318,7 @@ impl RemoteRpcAsyncClient { address: &AccountAddress, tag: &StructTag, ) -> PartialVMResult>> { - let state_key = StateKey::resource(address, tag).unwrap(); + let state_key = StateKey::resource(address, tag); let state_with_proof = self .state_client .get_with_proof_by_root(state_key, self.state_root) diff --git a/vm/types/src/on_chain_config/mod.rs b/vm/types/src/on_chain_config/mod.rs index e3bd466de9..1865ba38bb 100644 --- a/vm/types/src/on_chain_config/mod.rs +++ b/vm/types/src/on_chain_config/mod.rs @@ -182,7 +182,7 @@ pub trait OnChainConfig: Send + Sync + DeserializeOwned { where T: ConfigStorage + ?Sized, { - let state_key = StateKey::on_chain_config::().ok()?; + let state_key = StateKey::on_chain_config::(); let bytes = storage.fetch_config_bytes(&state_key)?; Self::deserialize_into_config(&bytes).ok() } diff --git a/vm/types/src/state_store/mod.rs b/vm/types/src/state_store/mod.rs index 665cc09193..a9c30af95f 100644 --- a/vm/types/src/state_store/mod.rs +++ b/vm/types/src/state_store/mod.rs @@ -139,7 +139,7 @@ pub trait MoveResourceExt: MoveResource { state_view: &dyn StateView, address: &AccountAddress, ) -> Result> { - let state_key = StateKey::resource_typed::(address)?; + let state_key = StateKey::resource_typed::(address); Ok(state_view .get_state_value_bytes(&state_key)? .map(|bytes| bcs::from_bytes(&bytes)) diff --git a/vm/types/src/state_store/state_key/mod.rs b/vm/types/src/state_store/state_key/mod.rs index e534cf927b..bc124baec4 100644 --- a/vm/types/src/state_store/state_key/mod.rs +++ b/vm/types/src/state_store/state_key/mod.rs @@ -75,7 +75,7 @@ impl StateKey { let AccessPath { address, path } = bcs::from_bytes(&val[1..])?; match path { DataPath::Code(module_name) => Self::module(&address, &module_name), - DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag)?, + DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag), DataPath::ResourceGroup(struct_tag) => { Self::resource_group(&address, &struct_tag) } @@ -116,7 +116,7 @@ impl StateKey { let myself = match deserialized { StateKeyInner::AccessPath(AccessPath { address, path }) => match path { DataPath::Code(module_name) => Self::module(&address, &module_name), - DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag)?, + DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag), DataPath::ResourceGroup(struct_tag) => Self::resource_group(&address, &struct_tag), }, StateKeyInner::TableItem { handle, key } => Self::table_item(&handle, &key), @@ -126,25 +126,25 @@ impl StateKey { Ok(myself) } - // todo: remove Result - pub fn resource(address: &AccountAddress, struct_tag: &StructTag) -> Result { - Ok(Self(REGISTRY.resource(struct_tag, address).get_or_add( - struct_tag, - address, - || { - Ok(StateKeyInner::AccessPath(AccessPath::resource_access_path( - *address, - struct_tag.clone(), - ))) - }, - )?)) + pub fn resource(address: &AccountAddress, struct_tag: &StructTag) -> Self { + Self( + REGISTRY + .resource(struct_tag, address) + .get_or_add(struct_tag, address, || { + Ok(StateKeyInner::AccessPath(AccessPath::resource_access_path( + *address, + struct_tag.clone(), + ))) + }) + .expect("only possible error is resource path serialization"), + ) } - pub fn resource_typed(address: &AccountAddress) -> Result { + pub fn resource_typed(address: &AccountAddress) -> Self { Self::resource(address, &T::struct_tag()) } - pub fn on_chain_config() -> Result { + pub fn on_chain_config() -> Self { Self::resource(T::address(), &T::struct_tag()) } diff --git a/vm/types/src/state_store/state_key/prefix.rs b/vm/types/src/state_store/state_key/prefix.rs index a29bfd146d..b5438c3ef3 100644 --- a/vm/types/src/state_store/state_key/prefix.rs +++ b/vm/types/src/state_store/state_key/prefix.rs @@ -54,8 +54,8 @@ mod tests { fn test_state_key_prefix() { let address1 = AccountAddress::new([12u8; AccountAddress::LENGTH]); let address2 = AccountAddress::new([22u8; AccountAddress::LENGTH]); - let key1 = StateKey::resource_typed::(&address1).unwrap(); - let key2 = StateKey::resource_typed::(&address2).unwrap(); + let key1 = StateKey::resource_typed::(&address1); + let key2 = StateKey::resource_typed::(&address2); let account1_key_prefx = StateKeyPrefix::new(StateKeyTag::AccessPath, address1.to_vec()); let account2_key_prefx = StateKeyPrefix::new(StateKeyTag::AccessPath, address2.to_vec()); diff --git a/vm/types/src/state_store/state_key/tests.rs b/vm/types/src/state_store/state_key/tests.rs index f66a2aebc5..21c96ef802 100644 --- a/vm/types/src/state_store/state_key/tests.rs +++ b/vm/types/src/state_store/state_key/tests.rs @@ -15,7 +15,7 @@ fn assert_crypto_hash(key: &StateKey, expected_hash: &str) { #[test] fn test_resource_hash() { assert_crypto_hash( - &StateKey::resource_typed::(&AccountAddress::TWO).unwrap(), + &StateKey::resource_typed::(&AccountAddress::TWO), "fdec56915926115cd094939bf5ef500157dd63a56e1a0e7521600adacdc50b90", ); } @@ -62,7 +62,7 @@ fn test_debug() { ); // resource - let key = StateKey::resource_typed::(&AccountAddress::FOUR).unwrap(); + let key = StateKey::resource_typed::(&AccountAddress::FOUR); assert_eq!( &format!("{:?}", key), "StateKey::AccessPath { address: 0x4, path: \"Resource(0x00000000000000000000000000000001::account::Account)\" }", diff --git a/vm/types/src/state_view.rs b/vm/types/src/state_view.rs index 95f15fcd3d..bbb078b877 100644 --- a/vm/types/src/state_view.rs +++ b/vm/types/src/state_view.rs @@ -42,7 +42,7 @@ pub trait StateReaderExt: StateView { /// Get Resource by StructTag fn get_resource(&self, address: AccountAddress, struct_tag: &StructTag) -> Result { let rsrc_bytes = self - .get_state_value_bytes(&StateKey::resource(&address, struct_tag)?)? + .get_state_value_bytes(&StateKey::resource(&address, struct_tag))? .ok_or_else(|| { format_err!( "Resource {:?} not exists at address:{}", @@ -57,7 +57,7 @@ pub trait StateReaderExt: StateView { where R: MoveResource, { - self.get_state_value_bytes(&StateKey::resource_typed::(&address)?)? + self.get_state_value_bytes(&StateKey::resource_typed::(&address))? .ok_or_else(|| { format_err!( "Resource {:?} {:?} not exists at address:{}", @@ -74,7 +74,7 @@ pub trait StateReaderExt: StateView { R: MoveResource, { let rsrc_bytes = self - .get_state_value_bytes(&StateKey::resource_typed::(&address)?)? + .get_state_value_bytes(&StateKey::resource_typed::(&address))? .ok_or_else(|| { format_err!( "Resource {:?} {:?} not exists at address:{}", @@ -109,7 +109,7 @@ pub trait StateReaderExt: StateView { .get_state_value_bytes(&StateKey::resource( &address, &BalanceResource::struct_tag_for_token(type_tag.clone()), - )?)? + ))? .ok_or_else(|| { format_err!( "BalanceResource not exists at address:{} for type tag:{}", diff --git a/vm/vm-runtime/src/move_vm_ext/mod.rs b/vm/vm-runtime/src/move_vm_ext/mod.rs index 248547cb29..d24150587a 100644 --- a/vm/vm-runtime/src/move_vm_ext/mod.rs +++ b/vm/vm-runtime/src/move_vm_ext/mod.rs @@ -16,18 +16,13 @@ pub use crate::move_vm_ext::{ session::{SessionExt, SessionId}, vm::MoveVmExt, }; -use move_binary_format::errors::{PartialVMError, PartialVMResult}; -use move_core_types::{ - account_address::AccountAddress, language_storage::StructTag, vm_status::StatusCode, -}; +use move_binary_format::errors::PartialVMResult; +use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; use starcoin_vm_types::state_store::state_key::StateKey; pub(crate) fn resource_state_key( address: &AccountAddress, tag: &StructTag, ) -> PartialVMResult { - StateKey::resource(address, tag).map_err(|e| { - PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) - .with_message(format!("Failed to serialize struct tag: {}", e)) - }) + Ok(StateKey::resource(address, tag)) } diff --git a/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs b/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs index b2b52bae12..07063dc3fa 100644 --- a/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs +++ b/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs @@ -135,13 +135,7 @@ impl WarmVmId { let bytes = { #[cfg(feature = "metrics")] let _timer = TIMER.timer_with(&["fetch_pkgreg"]); - resolver.fetch_config_bytes(&StateKey::on_chain_config::().map_err( - |err| { - PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) - .with_message(format!("failed to create StateKey: {}", err)) - .finish(Location::Undefined) - }, - )?) + resolver.fetch_config_bytes(&StateKey::on_chain_config::()) }; let core_package_registry = { diff --git a/vm/vm-runtime/src/starcoin_vm.rs b/vm/vm-runtime/src/starcoin_vm.rs index 0d43e0b090..3aff03235d 100644 --- a/vm/vm-runtime/src/starcoin_vm.rs +++ b/vm/vm-runtime/src/starcoin_vm.rs @@ -479,7 +479,7 @@ impl StarcoinVM { remote_cache: &StateViewCache, package_address: AccountAddress, ) -> Result { - let key = StateKey::resource(&package_address, &ModuleUpgradeStrategy::struct_tag())?; + let key = StateKey::resource(&package_address, &ModuleUpgradeStrategy::struct_tag()); if let Some(data) = remote_cache.get_state_value(&key)? { Ok(bcs_ext::from_bytes::(data.bytes())?.only_new_module()) } else { @@ -503,7 +503,7 @@ impl StarcoinVM { || (chain_id.is_barnard() && block_number < 8311392) { let key = - StateKey::resource(&package_address, &TwoPhaseUpgradeV2Resource::struct_tag())?; + StateKey::resource(&package_address, &TwoPhaseUpgradeV2Resource::struct_tag()); if let Some(data) = remote_cache.get_state_value(&key)? { let enforced = bcs_ext::from_bytes::(data.bytes())?.enforced(); From 808e6a893b907360189be92e78d34a2799bf8cd2 Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 23 Jan 2025 13:54:50 +0800 Subject: [PATCH 2/9] remove unnecessary function --- vm/vm-runtime/src/data_cache.rs | 4 ++-- vm/vm-runtime/src/move_vm_ext/mod.rs | 10 ---------- vm/vm-runtime/src/move_vm_ext/session.rs | 4 ++-- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/vm/vm-runtime/src/data_cache.rs b/vm/vm-runtime/src/data_cache.rs index 2a25732626..5914747b6b 100644 --- a/vm/vm-runtime/src/data_cache.rs +++ b/vm/vm-runtime/src/data_cache.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 //! Scratchpad for on chain values during the execution. -use crate::move_vm_ext::{resource_state_key, AsExecutorView, ResourceGroupResolver}; +use crate::move_vm_ext::{AsExecutorView, ResourceGroupResolver}; use bytes::Bytes; use move_binary_format::deserializer::DeserializerConfig; use move_binary_format::CompiledModule; @@ -236,7 +236,7 @@ impl<'a, S: StateView> ResourceResolver for StorageAdapter<'a, S> { let buf_size = resource_size(&buf); Ok((buf, buf_size + group_size as usize)) } else { - let state_key = resource_state_key(address, struct_tag)?; + let state_key = StateKey::resource(address, struct_tag); let buf = self .executor_view .get_resource_bytes(&state_key, maybe_layout)?; diff --git a/vm/vm-runtime/src/move_vm_ext/mod.rs b/vm/vm-runtime/src/move_vm_ext/mod.rs index d24150587a..adf0d83d8b 100644 --- a/vm/vm-runtime/src/move_vm_ext/mod.rs +++ b/vm/vm-runtime/src/move_vm_ext/mod.rs @@ -16,13 +16,3 @@ pub use crate::move_vm_ext::{ session::{SessionExt, SessionId}, vm::MoveVmExt, }; -use move_binary_format::errors::PartialVMResult; -use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; -use starcoin_vm_types::state_store::state_key::StateKey; - -pub(crate) fn resource_state_key( - address: &AccountAddress, - tag: &StructTag, -) -> PartialVMResult { - Ok(StateKey::resource(address, tag)) -} diff --git a/vm/vm-runtime/src/move_vm_ext/session.rs b/vm/vm-runtime/src/move_vm_ext/session.rs index 6ad75a19e9..9fed914f38 100644 --- a/vm/vm-runtime/src/move_vm_ext/session.rs +++ b/vm/vm-runtime/src/move_vm_ext/session.rs @@ -1,6 +1,6 @@ use crate::data_cache::get_resource_group_member_from_metadata; use crate::move_vm_ext::write_op_converter::WriteOpConverter; -use crate::move_vm_ext::{resource_state_key, StarcoinMoveResolver}; +use crate::move_vm_ext::StarcoinMoveResolver; use bytes::Bytes; use move_binary_format::{ access::ModuleAccess, @@ -388,7 +388,7 @@ impl<'r, 'l> SessionExt<'r, 'l> { for (addr, account_changeset) in change_set.into_inner() { let (modules, resources) = account_changeset.into_inner(); for (struct_tag, blob_and_layout_op) in resources { - let state_key = resource_state_key(&addr, &struct_tag)?; + let state_key = StateKey::resource(&addr, &struct_tag); let op = woc.convert_resource( &state_key, blob_and_layout_op, From e9dffb4f9745ea16ccb159db5ea6b473054d99b2 Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 23 Jan 2025 16:30:17 +0800 Subject: [PATCH 3/9] parse resources in group for rpc-api module --- rpc/api/src/types.rs | 79 +++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/rpc/api/src/types.rs b/rpc/api/src/types.rs index 4eca0ffa90..ace5ae4488 100644 --- a/rpc/api/src/types.rs +++ b/rpc/api/src/types.rs @@ -3,6 +3,7 @@ use anyhow::bail; use bcs_ext::BCSCodec; +use bytes::Bytes; use hex::FromHex; use jsonrpc_core_client::RpcChannel; use move_core_types::u256; @@ -36,7 +37,7 @@ use starcoin_types::transaction::authenticator::{AuthenticationKey, TransactionA use starcoin_types::transaction::{EntryFunction, RawUserTransaction, TransactionArgument}; use starcoin_types::vm_error::AbortLocation; use starcoin_types::U256; -use starcoin_vm_types::access_path::AccessPath; +use starcoin_vm_types::access_path::{AccessPath, DataPath}; use starcoin_vm_types::block_metadata::BlockMetadata; use starcoin_vm_types::identifier::Identifier; use starcoin_vm_types::language_storage::{parse_module_id, FunctionId, ModuleId, StructTag}; @@ -1205,6 +1206,47 @@ pub struct TransactionOutputView { pub table_item_write_set: Vec, } +fn merge_ap_write_set( + output: &mut Vec, + access_path: AccessPath, + op: WriteOp, +) { + match op { + WriteOp::Deletion { .. } => output.push(TransactionOutputAction { + access_path, + action: WriteOpView::Deletion, + value: None, + }), + WriteOp::Modification { data, .. } | WriteOp::Creation { data, .. } => { + match access_path.path { + DataPath::Resource(_) => output.push(TransactionOutputAction { + access_path, + action: WriteOpView::Value, + value: Some(WriteOpValueView::Resource(data.to_vec().into())), + }), + DataPath::ResourceGroup(_) => { + let group_data: BTreeMap = + bcs_ext::from_bytes(&data).expect("resource group data must be valid"); + for (struct_tag, data) in group_data { + let resource_ap = + AccessPath::resource_access_path(access_path.address, struct_tag); + output.push(TransactionOutputAction { + access_path: resource_ap, + action: WriteOpView::Value, + value: Some(WriteOpValueView::Resource(data.to_vec().into())), + }); + } + } + DataPath::Code(_) => output.push(TransactionOutputAction { + access_path, + action: WriteOpView::Value, + value: Some(WriteOpValueView::Code(data.to_vec().into())), + }), + } + } + }; +} + impl From for TransactionOutputView { fn from(txn_output: TransactionOutput) -> Self { let (write_set, events, gas_used, status, _) = txn_output.into_inner(); @@ -1225,14 +1267,19 @@ impl From for TransactionOutputView { StateKeyInner::Raw(_) => todo!("not support raw key"), } } + let write_set = + access_write_set + .into_iter() + .fold(Vec::new(), |mut acc, (access_path, op)| { + merge_ap_write_set(&mut acc, access_path, op); + acc + }); + Self { events: events.into_iter().map(Into::into).collect(), gas_used: gas_used.into(), status: status.into(), - write_set: access_write_set - .into_iter() - .map(TransactionOutputAction::from) - .collect(), + write_set, table_item_write_set: table_item_write_set .into_iter() .map(TransactionOutputTableItemAction::from) @@ -1241,28 +1288,6 @@ impl From for TransactionOutputView { } } -impl From<(AccessPath, WriteOp)> for TransactionOutputAction { - fn from((access_path, op): (AccessPath, WriteOp)) -> Self { - let (action, value) = match op { - WriteOp::Deletion { .. } => (WriteOpView::Deletion, None), - WriteOp::Modification { data, .. } | WriteOp::Creation { data, .. } => ( - WriteOpView::Value, - Some(if access_path.path.is_resource() { - WriteOpValueView::Resource(data.to_vec().into()) - } else { - WriteOpValueView::Code(data.to_vec().into()) - }), - ), - }; - - Self { - access_path, - action, - value, - } - } -} - #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct TransactionOutputAction { pub access_path: AccessPath, From c511e0d4f2b11861bdc191ab769cbf1a57947f3c Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 23 Jan 2025 17:54:57 +0800 Subject: [PATCH 4/9] remove unused functions --- vm/types/src/access_path.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/vm/types/src/access_path.rs b/vm/types/src/access_path.rs index 294243d4b5..9bd5e656de 100644 --- a/vm/types/src/access_path.rs +++ b/vm/types/src/access_path.rs @@ -328,12 +328,6 @@ impl DataPath { pub fn is_code(&self) -> bool { matches!(self, Self::Code(_)) } - pub fn is_resource(&self) -> bool { - matches!(self, Self::Resource(_)) - } - pub fn is_resource_group(&self) -> bool { - matches!(self, Self::ResourceGroup(_)) - } // todo(simon): handle ResourceGroup pub fn as_struct_tag(&self) -> Option<&StructTag> { match self { From 75a7d262747d6b66d0d48ca63d8cf15fa3f53198 Mon Sep 17 00:00:00 2001 From: simonjiao Date: Fri, 24 Jan 2025 21:53:56 +0800 Subject: [PATCH 5/9] refactor as_struct_tag --- rpc/api/src/types.rs | 1 + rpc/server/src/module/contract_rpc.rs | 2 +- state/statedb/src/lib.rs | 10 ++++++---- vm/dev/src/playground.rs | 2 +- vm/types/src/access_path.rs | 10 ++++++++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/rpc/api/src/types.rs b/rpc/api/src/types.rs index ace5ae4488..8a66da930c 100644 --- a/rpc/api/src/types.rs +++ b/rpc/api/src/types.rs @@ -1224,6 +1224,7 @@ fn merge_ap_write_set( action: WriteOpView::Value, value: Some(WriteOpValueView::Resource(data.to_vec().into())), }), + // Parsing resources in group and expanding them into individual actions. DataPath::ResourceGroup(_) => { let group_data: BTreeMap = bcs_ext::from_bytes(&data).expect("resource group data must be valid"); diff --git a/rpc/server/src/module/contract_rpc.rs b/rpc/server/src/module/contract_rpc.rs index 07bab68415..15b7c1dda8 100644 --- a/rpc/server/src/module/contract_rpc.rs +++ b/rpc/server/src/module/contract_rpc.rs @@ -306,7 +306,7 @@ pub fn dry_run( view.abi = Some(resolver.resolve_module_code(view.code.0.as_slice())?); } WriteOpValueView::Resource(view) => { - let struct_tag = access_path.path.as_struct_tag().ok_or_else(|| { + let struct_tag = access_path.path.resource_tag().ok_or_else(|| { format_err!("invalid resource access path: {}", access_path) })?; let struct_abi = resolver.resolve_struct_tag(struct_tag)?; diff --git a/state/statedb/src/lib.rs b/state/statedb/src/lib.rs index fcdb771fae..b90f88f85c 100644 --- a/state/statedb/src/lib.rs +++ b/state/statedb/src/lib.rs @@ -164,10 +164,12 @@ impl AccountStateObject { if data_path.is_code() { bail!("Not supported remove code currently."); } - let struct_tag = data_path - .as_struct_tag() - .expect("DataPath must been struct tag at here."); - self.resource_tree.lock().remove(struct_tag); + if let Some(struct_tag) = data_path.resource_tag() { + self.resource_tree.lock().remove(struct_tag); + } + if let Some(struct_tag) = data_path.resource_group_tag() { + self.resource_tree.lock().remove(struct_tag); + } Ok(()) } diff --git a/vm/dev/src/playground.rs b/vm/dev/src/playground.rs index 53384da8b9..a873a72f50 100644 --- a/vm/dev/src/playground.rs +++ b/vm/dev/src/playground.rs @@ -134,7 +134,7 @@ pub fn dry_run_explain( view.abi = Some(resolver.resolve_module_code(view.code.0.as_slice())?); } WriteOpValueView::Resource(view) => { - let struct_tag = access_path.path.as_struct_tag().ok_or_else(|| { + let struct_tag = access_path.path.resource_tag().ok_or_else(|| { format_err!("invalid resource access path: {}", access_path) })?; let struct_abi = resolver.resolve_struct_tag(struct_tag)?; diff --git a/vm/types/src/access_path.rs b/vm/types/src/access_path.rs index 9bd5e656de..e3e2bc6b0f 100644 --- a/vm/types/src/access_path.rs +++ b/vm/types/src/access_path.rs @@ -58,6 +58,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use starcoin_crypto::hash::HashValue; use std::fmt; use std::str::FromStr; + #[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, JsonSchema)] #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] #[schemars(with = "String")] @@ -328,13 +329,18 @@ impl DataPath { pub fn is_code(&self) -> bool { matches!(self, Self::Code(_)) } - // todo(simon): handle ResourceGroup - pub fn as_struct_tag(&self) -> Option<&StructTag> { + pub fn resource_tag(&self) -> Option<&StructTag> { match self { Self::Resource(struct_tag) => Some(struct_tag), _ => None, } } + pub fn resource_group_tag(&self) -> Option<&StructTag> { + match self { + Self::ResourceGroup(struct_tag) => Some(struct_tag), + _ => None, + } + } pub fn data_type(&self) -> DataType { match self { Self::Code(_) => DataType::CODE, From 876bdddfb13801ccb903cc1ebdb0bb854636ea7b Mon Sep 17 00:00:00 2001 From: simonjiao Date: Mon, 27 Jan 2025 22:21:23 +0800 Subject: [PATCH 6/9] update test for proxima network From 674c5d770159c96fa47214e74d5f52d326086e3a Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 6 Feb 2025 09:41:34 +0800 Subject: [PATCH 7/9] update proxima's example genesis config From bbe360efa4ccfefdbd20509a896eb7bd7e49c612 Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 6 Feb 2025 12:22:23 +0800 Subject: [PATCH 8/9] Revert "remove unnecessary function" This reverts commit 808e6a893b907360189be92e78d34a2799bf8cd2. --- vm/vm-runtime/src/data_cache.rs | 4 ++-- vm/vm-runtime/src/move_vm_ext/mod.rs | 10 ++++++++++ vm/vm-runtime/src/move_vm_ext/session.rs | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/vm/vm-runtime/src/data_cache.rs b/vm/vm-runtime/src/data_cache.rs index 5914747b6b..2a25732626 100644 --- a/vm/vm-runtime/src/data_cache.rs +++ b/vm/vm-runtime/src/data_cache.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 //! Scratchpad for on chain values during the execution. -use crate::move_vm_ext::{AsExecutorView, ResourceGroupResolver}; +use crate::move_vm_ext::{resource_state_key, AsExecutorView, ResourceGroupResolver}; use bytes::Bytes; use move_binary_format::deserializer::DeserializerConfig; use move_binary_format::CompiledModule; @@ -236,7 +236,7 @@ impl<'a, S: StateView> ResourceResolver for StorageAdapter<'a, S> { let buf_size = resource_size(&buf); Ok((buf, buf_size + group_size as usize)) } else { - let state_key = StateKey::resource(address, struct_tag); + let state_key = resource_state_key(address, struct_tag)?; let buf = self .executor_view .get_resource_bytes(&state_key, maybe_layout)?; diff --git a/vm/vm-runtime/src/move_vm_ext/mod.rs b/vm/vm-runtime/src/move_vm_ext/mod.rs index adf0d83d8b..d24150587a 100644 --- a/vm/vm-runtime/src/move_vm_ext/mod.rs +++ b/vm/vm-runtime/src/move_vm_ext/mod.rs @@ -16,3 +16,13 @@ pub use crate::move_vm_ext::{ session::{SessionExt, SessionId}, vm::MoveVmExt, }; +use move_binary_format::errors::PartialVMResult; +use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; +use starcoin_vm_types::state_store::state_key::StateKey; + +pub(crate) fn resource_state_key( + address: &AccountAddress, + tag: &StructTag, +) -> PartialVMResult { + Ok(StateKey::resource(address, tag)) +} diff --git a/vm/vm-runtime/src/move_vm_ext/session.rs b/vm/vm-runtime/src/move_vm_ext/session.rs index 9fed914f38..6ad75a19e9 100644 --- a/vm/vm-runtime/src/move_vm_ext/session.rs +++ b/vm/vm-runtime/src/move_vm_ext/session.rs @@ -1,6 +1,6 @@ use crate::data_cache::get_resource_group_member_from_metadata; use crate::move_vm_ext::write_op_converter::WriteOpConverter; -use crate::move_vm_ext::StarcoinMoveResolver; +use crate::move_vm_ext::{resource_state_key, StarcoinMoveResolver}; use bytes::Bytes; use move_binary_format::{ access::ModuleAccess, @@ -388,7 +388,7 @@ impl<'r, 'l> SessionExt<'r, 'l> { for (addr, account_changeset) in change_set.into_inner() { let (modules, resources) = account_changeset.into_inner(); for (struct_tag, blob_and_layout_op) in resources { - let state_key = StateKey::resource(&addr, &struct_tag); + let state_key = resource_state_key(&addr, &struct_tag)?; let op = woc.convert_resource( &state_key, blob_and_layout_op, From ccf4472ad694be3df2249826e77e8bb0867f12c4 Mon Sep 17 00:00:00 2001 From: simonjiao Date: Thu, 6 Feb 2025 12:22:33 +0800 Subject: [PATCH 9/9] Revert "remove Result from StateKey::resource" This reverts commit c5cffcd26db34b6ee0401a9aa6226a68ac5d5a13. --- chain/src/chain.rs | 2 +- cmd/airdrop/src/main.rs | 2 +- cmd/db-exporter/src/force_deploy_output.rs | 2 +- cmd/genesis-nft-miner/src/main.rs | 2 +- cmd/starcoin/src/state/get_proof_cmd.rs | 4 ++- contrib-contracts/src/starcoin_merkle_test.rs | 4 +-- network-rpc/src/tests.rs | 2 +- rpc/server/src/module/contract_rpc.rs | 2 +- rpc/server/src/module/state_rpc.rs | 2 +- state/api/src/lib.rs | 2 +- state/statedb/src/lib.rs | 6 ++-- state/statedb/src/tests.rs | 16 +++++----- testsuite/tests/steps/state.rs | 2 +- types/src/account.rs | 4 +-- vm/e2e-tests/src/account.rs | 4 +-- vm/e2e-tests/src/data_store.rs | 4 +-- vm/e2e-tests/src/executor.rs | 2 +- .../src/lib.rs | 4 +-- .../src/remote_state.rs | 2 +- vm/types/src/on_chain_config/mod.rs | 2 +- vm/types/src/state_store/mod.rs | 2 +- vm/types/src/state_store/state_key/mod.rs | 32 +++++++++---------- vm/types/src/state_store/state_key/prefix.rs | 4 +-- vm/types/src/state_store/state_key/tests.rs | 4 +-- vm/types/src/state_view.rs | 8 ++--- vm/vm-runtime/src/move_vm_ext/mod.rs | 11 +++++-- .../src/move_vm_ext/warm_vm_cache.rs | 8 ++++- vm/vm-runtime/src/starcoin_vm.rs | 4 +-- 28 files changed, 78 insertions(+), 65 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index df267555f0..b36441ea8b 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -2097,7 +2097,7 @@ impl ChainReader for BlockChain { let state_key = match access_path.path { DataPath::Code(module_name) => StateKey::module(&access_path.address, &module_name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, &struct_tag) + StateKey::resource(&access_path.address, &struct_tag)? } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, &struct_tag) diff --git a/cmd/airdrop/src/main.rs b/cmd/airdrop/src/main.rs index dcd2cd74f8..4b056f4aa2 100644 --- a/cmd/airdrop/src/main.rs +++ b/cmd/airdrop/src/main.rs @@ -218,7 +218,7 @@ async fn main() -> Result<()> { // read from onchain let account_sequence_number = { - let state_key = StateKey::resource(&sender, &account_struct_tag()); + let state_key = StateKey::resource(&sender, &account_struct_tag())?; let account_data: Option> = state_client .get(state_key) .await diff --git a/cmd/db-exporter/src/force_deploy_output.rs b/cmd/db-exporter/src/force_deploy_output.rs index 3466f719c2..4b5ae41a7d 100644 --- a/cmd/db-exporter/src/force_deploy_output.rs +++ b/cmd/db-exporter/src/force_deploy_output.rs @@ -113,7 +113,7 @@ pub fn force_deploy_output( AccessPath::resource_access_path(genesis_address(), ModuleUpgradeStrategy::struct_tag()); // Write upgrade strategy resource to 0 let upgrade_strategy_path = - StateKey::resource(&genesis_address(), &ModuleUpgradeStrategy::struct_tag()); + StateKey::resource(&genesis_address(), &ModuleUpgradeStrategy::struct_tag())?; let statedb = chain.chain_state(); let before_ret = statedb diff --git a/cmd/genesis-nft-miner/src/main.rs b/cmd/genesis-nft-miner/src/main.rs index d4cffcbc0c..1e0cc0f941 100644 --- a/cmd/genesis-nft-miner/src/main.rs +++ b/cmd/genesis-nft-miner/src/main.rs @@ -87,7 +87,7 @@ async fn main() -> Result<()> { let txpool_client = TxPoolClient::from(channel.clone()); let chain_id: u8 = chain_client.id().await.map_err(map_rpc_error)?.id; let account_sequence_number = { - let state_key = StateKey::resource(&sender, &account_struct_tag()); + let state_key = StateKey::resource(&sender, &account_struct_tag())?; let account_data: Option> = state_client .get(state_key) .await diff --git a/cmd/starcoin/src/state/get_proof_cmd.rs b/cmd/starcoin/src/state/get_proof_cmd.rs index 0908dc90aa..55e5a1b3f2 100644 --- a/cmd/starcoin/src/state/get_proof_cmd.rs +++ b/cmd/starcoin/src/state/get_proof_cmd.rs @@ -69,7 +69,9 @@ impl CommandAction for GetProofCommand { let access_path = opt.access_path.clone(); let state_key = match access_path.clone().path { DataPath::Code(module_name) => StateKey::module(&access_path.address, &module_name), - DataPath::Resource(struct_tag) => StateKey::resource(&access_path.address, &struct_tag), + DataPath::Resource(struct_tag) => { + StateKey::resource(&access_path.address, &struct_tag)? + } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, &struct_tag) } diff --git a/contrib-contracts/src/starcoin_merkle_test.rs b/contrib-contracts/src/starcoin_merkle_test.rs index 5d7aefb2e7..dd8a75cd83 100644 --- a/contrib-contracts/src/starcoin_merkle_test.rs +++ b/contrib-contracts/src/starcoin_merkle_test.rs @@ -16,7 +16,7 @@ use test_helper::executor::{ #[stest::test] fn test_starcoin_merkle() -> Result<()> { let (chain_state, net) = prepare_genesis(); - let state_key = StateKey::resource(&association_address(), &account_struct_tag()); + let state_key = StateKey::resource(&association_address(), &account_struct_tag())?; let ap = AccessPath::resource_access_path(association_address(), account_struct_tag()); let state_with_proof = chain_state.get_with_proof(&state_key)?; state_with_proof.proof.verify( @@ -72,7 +72,7 @@ fn test_starcoin_merkle() -> Result<()> { // let state_root = chain_state.state_root(); let _expected_root = MoveValue::vector_u8(state_root.to_vec()); - let ap = StateKey::resource(&association_address(), &account_struct_tag()); + let ap = StateKey::resource(&association_address(), &account_struct_tag())?; let state_with_proof = old_chain_state.get_with_proof(&ap)?; let account_address = MoveValue::vector_u8(association_address().to_vec()); let account_state_hash = MoveValue::vector_u8( diff --git a/network-rpc/src/tests.rs b/network-rpc/src/tests.rs index c62abc8604..77a6a1885c 100644 --- a/network-rpc/src/tests.rs +++ b/network-rpc/src/tests.rs @@ -45,7 +45,7 @@ fn test_network_rpc() { DataPath::Resource(Epoch::struct_tag_for_epoch()), ); - let state_key = StateKey::resource(&genesis_address(), &Epoch::struct_tag_for_epoch()); + let state_key = StateKey::resource(&genesis_address(), &Epoch::struct_tag_for_epoch()).unwrap(); //ping ok let req = Ping { diff --git a/rpc/server/src/module/contract_rpc.rs b/rpc/server/src/module/contract_rpc.rs index 15b7c1dda8..7854e91225 100644 --- a/rpc/server/src/module/contract_rpc.rs +++ b/rpc/server/src/module/contract_rpc.rs @@ -103,7 +103,7 @@ where let playground = self.playground.clone(); let f = async move { let state_root = service.clone().state_root().await?; - let state_key = StateKey::resource(&addr, &resource_type.0); + let state_key = StateKey::resource(&addr, &resource_type.0)?; let data = service.get(state_key).await?; match data { None => Ok(None), diff --git a/rpc/server/src/module/state_rpc.rs b/rpc/server/src/module/state_rpc.rs index 036757de03..db49398748 100644 --- a/rpc/server/src/module/state_rpc.rs +++ b/rpc/server/src/module/state_rpc.rs @@ -273,7 +273,7 @@ where .state_root .unwrap_or(service.clone().state_root().await?); let chain_state = ChainStateDB::new(state_store, Some(state_root)); - let state_key = StateKey::resource(&addr, &resource_type.0); + let state_key = StateKey::resource(&addr, &resource_type.0)?; let data = chain_state.get_state_value_bytes(&state_key)?; Ok(match data { None => None, diff --git a/state/api/src/lib.rs b/state/api/src/lib.rs index 8eb94c22ea..56d873774e 100644 --- a/state/api/src/lib.rs +++ b/state/api/src/lib.rs @@ -52,7 +52,7 @@ pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { R: MoveResource, { let rsrc_bytes = self - .get(StateKey::resource_typed::(&address)) + .get(StateKey::resource_typed::(&address)?) .await? .ok_or_else(|| { format_err!( diff --git a/state/statedb/src/lib.rs b/state/statedb/src/lib.rs index b90f88f85c..9aac840959 100644 --- a/state/statedb/src/lib.rs +++ b/state/statedb/src/lib.rs @@ -585,7 +585,7 @@ impl ChainStateReader for ChainStateDB { name: Identifier::new("TableHandles").unwrap(), type_args: vec![], }; - let state_key = StateKey::resource(handle_address, &struct_tag); + let state_key = StateKey::resource(handle_address, &struct_tag)?; let table_path_proof = self.get_with_proof(&state_key)?; let state_tree_table_handle = self.get_state_tree_table_handles(idx)?; let table_handle_proof = state_tree_table_handle.get_with_proof(handle)?; @@ -622,7 +622,7 @@ impl ChainStateWriter for ChainStateDB { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag) + StateKey::resource(&access_path.address, struct_tag)? } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) @@ -641,7 +641,7 @@ impl ChainStateWriter for ChainStateDB { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag) + StateKey::resource(&access_path.address, struct_tag)? } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) diff --git a/state/statedb/src/tests.rs b/state/statedb/src/tests.rs index 711f6bd843..70dbe01dff 100644 --- a/state/statedb/src/tests.rs +++ b/state/statedb/src/tests.rs @@ -43,7 +43,7 @@ fn test_state_proof() -> Result<()> { type_args: vec![], }; let access_path = AccessPath::new(account_address, DataPath::Resource(struct_tag.clone())); - let state_key = StateKey::resource(&account_address, &struct_tag); + let state_key = StateKey::resource(&account_address, &struct_tag)?; let state0 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key.clone(), state0.clone()))?; @@ -72,7 +72,7 @@ fn test_state_db() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key = StateKey::resource(&account_address, &struct_tag); + let state_key = StateKey::resource(&account_address, &struct_tag)?; let state0 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key.clone(), state0))?; let state_root = chain_state_db.commit()?; @@ -95,7 +95,7 @@ fn test_state_db_dump_and_apply() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key = StateKey::resource(&account_address, &struct_tag); + let state_key = StateKey::resource(&account_address, &struct_tag)?; let state0 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key, state0))?; @@ -130,7 +130,7 @@ fn test_state_version() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key = StateKey::resource(&account_address, &struct_tag); + let state_key = StateKey::resource(&account_address, &struct_tag)?; let old_state = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key.clone(), old_state.clone()))?; chain_state_db.commit()?; @@ -160,7 +160,7 @@ fn test_state_db_dump_iter() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key1 = StateKey::resource(&account_address, &struct_tag); + let state_key1 = StateKey::resource(&account_address, &struct_tag)?; let state1 = random_bytes(); chain_state_db.apply_write_set(to_write_set(state_key1, state1))?; let state2 = random_bytes(); @@ -171,7 +171,7 @@ fn test_state_db_dump_iter() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key2 = StateKey::resource(&account_address2, &struct_tag2); + let state_key2 = StateKey::resource(&account_address2, &struct_tag2)?; chain_state_db.apply_write_set(to_write_set(state_key2, state2))?; chain_state_db.commit()?; chain_state_db.flush()?; @@ -260,7 +260,7 @@ fn test_state_db_with_table_item_once() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key2 = StateKey::resource(&account_address2, &struct_tag2); + let state_key2 = StateKey::resource(&account_address2, &struct_tag2)?; let state_keys = vec![ state_key1, @@ -480,7 +480,7 @@ fn test_state_with_table_item_proof() -> Result<()> { name: random_identity(), type_args: vec![], }; - let state_key2 = StateKey::resource(&account_address2, &struct_tag2); + let state_key2 = StateKey::resource(&account_address2, &struct_tag2)?; let state_keys = vec![ state_key1, state_key2, diff --git a/testsuite/tests/steps/state.rs b/testsuite/tests/steps/state.rs index 9208ac4265..b2d6ec3ec6 100644 --- a/testsuite/tests/steps/state.rs +++ b/testsuite/tests/steps/state.rs @@ -15,7 +15,7 @@ pub fn steps() -> Steps { account.address.clone(), AccountResource::struct_tag(), ); - let key = StateKey::resource(account.address(), &AccountResource::struct_tag()); + let key = StateKey::resource(account.address(), &AccountResource::struct_tag()).unwrap(); let proof = client.clone().state_get_with_proof(key).unwrap(); let state_root = client.clone().state_get_state_root().unwrap(); proof diff --git a/types/src/account.rs b/types/src/account.rs index 8455551033..8bebeec5bd 100644 --- a/types/src/account.rs +++ b/types/src/account.rs @@ -510,11 +510,11 @@ impl AccountData { pub fn to_writeset(&self) -> WriteSet { let write_set = vec![ ( - StateKey::resource_typed::(self.address()), + StateKey::resource_typed::(self.address()).unwrap(), WriteOp::legacy_modification(self.to_bytes().into()), ), ( - StateKey::resource_typed::(self.address()), + StateKey::resource_typed::(self.address()).unwrap(), WriteOp::legacy_modification(self.coin_store.to_bytes().into()), ), ]; diff --git a/vm/e2e-tests/src/account.rs b/vm/e2e-tests/src/account.rs index 259249d342..14af3d577a 100644 --- a/vm/e2e-tests/src/account.rs +++ b/vm/e2e-tests/src/account.rs @@ -609,7 +609,7 @@ impl AccountData { .simple_serialize(&AccountData::layout()) .unwrap(); write_set.push(( - StateKey::resource_typed::(self.address()), + StateKey::resource_typed::(self.address()).unwrap(), WriteOp::legacy_modification(account.into()), )); @@ -619,7 +619,7 @@ impl AccountData { .simple_serialize(&CoinStore::layout()) .unwrap(); write_set.push(( - StateKey::resource_typed::(self.address()), + StateKey::resource_typed::(self.address()).unwrap(), WriteOp::legacy_modification(balance.into()), )); diff --git a/vm/e2e-tests/src/data_store.rs b/vm/e2e-tests/src/data_store.rs index befa362584..7cd0645dbb 100644 --- a/vm/e2e-tests/src/data_store.rs +++ b/vm/e2e-tests/src/data_store.rs @@ -125,7 +125,7 @@ impl ChainStateWriter for FakeDataStore { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag) + StateKey::resource(&access_path.address, struct_tag)? } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) @@ -142,7 +142,7 @@ impl ChainStateWriter for FakeDataStore { match &access_path.path { DataPath::Code(name) => StateKey::module(&access_path.address, name), DataPath::Resource(struct_tag) => { - StateKey::resource(&access_path.address, struct_tag) + StateKey::resource(&access_path.address, struct_tag)? } DataPath::ResourceGroup(struct_tag) => { StateKey::resource_group(&access_path.address, struct_tag) diff --git a/vm/e2e-tests/src/executor.rs b/vm/e2e-tests/src/executor.rs index e5c2c40664..79c3b173bd 100644 --- a/vm/e2e-tests/src/executor.rs +++ b/vm/e2e-tests/src/executor.rs @@ -280,7 +280,7 @@ impl FakeExecutor { fn read_resource(&self, addr: &AccountAddress) -> Option { let data_blob = TStateView::get_state_value_bytes( &self.data_store, - &StateKey::resource_typed::(addr), + &StateKey::resource_typed::(addr).expect("failed to create StateKey"), ) .expect("account must exist in data store") .unwrap_or_else(|| panic!("Can't fetch {} resource for {}", T::STRUCT_NAME, addr)); diff --git a/vm/starcoin-transactional-test-harness/src/lib.rs b/vm/starcoin-transactional-test-harness/src/lib.rs index 05776532ac..7dc263cb83 100644 --- a/vm/starcoin-transactional-test-harness/src/lib.rs +++ b/vm/starcoin-transactional-test-harness/src/lib.rs @@ -480,7 +480,7 @@ impl<'a> StarcoinTestAdapter<'a> { let account_blob = self .context .storage - .get_state_value_bytes(&StateKey::resource_typed::(signer_addr)) + .get_state_value_bytes(&StateKey::resource_typed::(signer_addr)?) .unwrap() .ok_or_else(|| { format_err!( @@ -500,7 +500,7 @@ impl<'a> StarcoinTestAdapter<'a> { ) -> Result { let token_code = TokenCode::from_str(balance_currency_code.as_str())?; let balance_resource_tag = BalanceResource::struct_tag_for_token(token_code.try_into()?); - let balance_access_key = StateKey::resource(signer_addr, &balance_resource_tag); + let balance_access_key = StateKey::resource(signer_addr, &balance_resource_tag)?; let balance_blob = self .context diff --git a/vm/starcoin-transactional-test-harness/src/remote_state.rs b/vm/starcoin-transactional-test-harness/src/remote_state.rs index 49b98259c7..dd0a1fe305 100644 --- a/vm/starcoin-transactional-test-harness/src/remote_state.rs +++ b/vm/starcoin-transactional-test-harness/src/remote_state.rs @@ -318,7 +318,7 @@ impl RemoteRpcAsyncClient { address: &AccountAddress, tag: &StructTag, ) -> PartialVMResult>> { - let state_key = StateKey::resource(address, tag); + let state_key = StateKey::resource(address, tag).unwrap(); let state_with_proof = self .state_client .get_with_proof_by_root(state_key, self.state_root) diff --git a/vm/types/src/on_chain_config/mod.rs b/vm/types/src/on_chain_config/mod.rs index 1865ba38bb..e3bd466de9 100644 --- a/vm/types/src/on_chain_config/mod.rs +++ b/vm/types/src/on_chain_config/mod.rs @@ -182,7 +182,7 @@ pub trait OnChainConfig: Send + Sync + DeserializeOwned { where T: ConfigStorage + ?Sized, { - let state_key = StateKey::on_chain_config::(); + let state_key = StateKey::on_chain_config::().ok()?; let bytes = storage.fetch_config_bytes(&state_key)?; Self::deserialize_into_config(&bytes).ok() } diff --git a/vm/types/src/state_store/mod.rs b/vm/types/src/state_store/mod.rs index a9c30af95f..665cc09193 100644 --- a/vm/types/src/state_store/mod.rs +++ b/vm/types/src/state_store/mod.rs @@ -139,7 +139,7 @@ pub trait MoveResourceExt: MoveResource { state_view: &dyn StateView, address: &AccountAddress, ) -> Result> { - let state_key = StateKey::resource_typed::(address); + let state_key = StateKey::resource_typed::(address)?; Ok(state_view .get_state_value_bytes(&state_key)? .map(|bytes| bcs::from_bytes(&bytes)) diff --git a/vm/types/src/state_store/state_key/mod.rs b/vm/types/src/state_store/state_key/mod.rs index bc124baec4..e534cf927b 100644 --- a/vm/types/src/state_store/state_key/mod.rs +++ b/vm/types/src/state_store/state_key/mod.rs @@ -75,7 +75,7 @@ impl StateKey { let AccessPath { address, path } = bcs::from_bytes(&val[1..])?; match path { DataPath::Code(module_name) => Self::module(&address, &module_name), - DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag), + DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag)?, DataPath::ResourceGroup(struct_tag) => { Self::resource_group(&address, &struct_tag) } @@ -116,7 +116,7 @@ impl StateKey { let myself = match deserialized { StateKeyInner::AccessPath(AccessPath { address, path }) => match path { DataPath::Code(module_name) => Self::module(&address, &module_name), - DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag), + DataPath::Resource(struct_tag) => Self::resource(&address, &struct_tag)?, DataPath::ResourceGroup(struct_tag) => Self::resource_group(&address, &struct_tag), }, StateKeyInner::TableItem { handle, key } => Self::table_item(&handle, &key), @@ -126,25 +126,25 @@ impl StateKey { Ok(myself) } - pub fn resource(address: &AccountAddress, struct_tag: &StructTag) -> Self { - Self( - REGISTRY - .resource(struct_tag, address) - .get_or_add(struct_tag, address, || { - Ok(StateKeyInner::AccessPath(AccessPath::resource_access_path( - *address, - struct_tag.clone(), - ))) - }) - .expect("only possible error is resource path serialization"), - ) + // todo: remove Result + pub fn resource(address: &AccountAddress, struct_tag: &StructTag) -> Result { + Ok(Self(REGISTRY.resource(struct_tag, address).get_or_add( + struct_tag, + address, + || { + Ok(StateKeyInner::AccessPath(AccessPath::resource_access_path( + *address, + struct_tag.clone(), + ))) + }, + )?)) } - pub fn resource_typed(address: &AccountAddress) -> Self { + pub fn resource_typed(address: &AccountAddress) -> Result { Self::resource(address, &T::struct_tag()) } - pub fn on_chain_config() -> Self { + pub fn on_chain_config() -> Result { Self::resource(T::address(), &T::struct_tag()) } diff --git a/vm/types/src/state_store/state_key/prefix.rs b/vm/types/src/state_store/state_key/prefix.rs index b5438c3ef3..a29bfd146d 100644 --- a/vm/types/src/state_store/state_key/prefix.rs +++ b/vm/types/src/state_store/state_key/prefix.rs @@ -54,8 +54,8 @@ mod tests { fn test_state_key_prefix() { let address1 = AccountAddress::new([12u8; AccountAddress::LENGTH]); let address2 = AccountAddress::new([22u8; AccountAddress::LENGTH]); - let key1 = StateKey::resource_typed::(&address1); - let key2 = StateKey::resource_typed::(&address2); + let key1 = StateKey::resource_typed::(&address1).unwrap(); + let key2 = StateKey::resource_typed::(&address2).unwrap(); let account1_key_prefx = StateKeyPrefix::new(StateKeyTag::AccessPath, address1.to_vec()); let account2_key_prefx = StateKeyPrefix::new(StateKeyTag::AccessPath, address2.to_vec()); diff --git a/vm/types/src/state_store/state_key/tests.rs b/vm/types/src/state_store/state_key/tests.rs index 21c96ef802..f66a2aebc5 100644 --- a/vm/types/src/state_store/state_key/tests.rs +++ b/vm/types/src/state_store/state_key/tests.rs @@ -15,7 +15,7 @@ fn assert_crypto_hash(key: &StateKey, expected_hash: &str) { #[test] fn test_resource_hash() { assert_crypto_hash( - &StateKey::resource_typed::(&AccountAddress::TWO), + &StateKey::resource_typed::(&AccountAddress::TWO).unwrap(), "fdec56915926115cd094939bf5ef500157dd63a56e1a0e7521600adacdc50b90", ); } @@ -62,7 +62,7 @@ fn test_debug() { ); // resource - let key = StateKey::resource_typed::(&AccountAddress::FOUR); + let key = StateKey::resource_typed::(&AccountAddress::FOUR).unwrap(); assert_eq!( &format!("{:?}", key), "StateKey::AccessPath { address: 0x4, path: \"Resource(0x00000000000000000000000000000001::account::Account)\" }", diff --git a/vm/types/src/state_view.rs b/vm/types/src/state_view.rs index bbb078b877..95f15fcd3d 100644 --- a/vm/types/src/state_view.rs +++ b/vm/types/src/state_view.rs @@ -42,7 +42,7 @@ pub trait StateReaderExt: StateView { /// Get Resource by StructTag fn get_resource(&self, address: AccountAddress, struct_tag: &StructTag) -> Result { let rsrc_bytes = self - .get_state_value_bytes(&StateKey::resource(&address, struct_tag))? + .get_state_value_bytes(&StateKey::resource(&address, struct_tag)?)? .ok_or_else(|| { format_err!( "Resource {:?} not exists at address:{}", @@ -57,7 +57,7 @@ pub trait StateReaderExt: StateView { where R: MoveResource, { - self.get_state_value_bytes(&StateKey::resource_typed::(&address))? + self.get_state_value_bytes(&StateKey::resource_typed::(&address)?)? .ok_or_else(|| { format_err!( "Resource {:?} {:?} not exists at address:{}", @@ -74,7 +74,7 @@ pub trait StateReaderExt: StateView { R: MoveResource, { let rsrc_bytes = self - .get_state_value_bytes(&StateKey::resource_typed::(&address))? + .get_state_value_bytes(&StateKey::resource_typed::(&address)?)? .ok_or_else(|| { format_err!( "Resource {:?} {:?} not exists at address:{}", @@ -109,7 +109,7 @@ pub trait StateReaderExt: StateView { .get_state_value_bytes(&StateKey::resource( &address, &BalanceResource::struct_tag_for_token(type_tag.clone()), - ))? + )?)? .ok_or_else(|| { format_err!( "BalanceResource not exists at address:{} for type tag:{}", diff --git a/vm/vm-runtime/src/move_vm_ext/mod.rs b/vm/vm-runtime/src/move_vm_ext/mod.rs index d24150587a..248547cb29 100644 --- a/vm/vm-runtime/src/move_vm_ext/mod.rs +++ b/vm/vm-runtime/src/move_vm_ext/mod.rs @@ -16,13 +16,18 @@ pub use crate::move_vm_ext::{ session::{SessionExt, SessionId}, vm::MoveVmExt, }; -use move_binary_format::errors::PartialVMResult; -use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; +use move_binary_format::errors::{PartialVMError, PartialVMResult}; +use move_core_types::{ + account_address::AccountAddress, language_storage::StructTag, vm_status::StatusCode, +}; use starcoin_vm_types::state_store::state_key::StateKey; pub(crate) fn resource_state_key( address: &AccountAddress, tag: &StructTag, ) -> PartialVMResult { - Ok(StateKey::resource(address, tag)) + StateKey::resource(address, tag).map_err(|e| { + PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) + .with_message(format!("Failed to serialize struct tag: {}", e)) + }) } diff --git a/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs b/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs index 07063dc3fa..b2b52bae12 100644 --- a/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs +++ b/vm/vm-runtime/src/move_vm_ext/warm_vm_cache.rs @@ -135,7 +135,13 @@ impl WarmVmId { let bytes = { #[cfg(feature = "metrics")] let _timer = TIMER.timer_with(&["fetch_pkgreg"]); - resolver.fetch_config_bytes(&StateKey::on_chain_config::()) + resolver.fetch_config_bytes(&StateKey::on_chain_config::().map_err( + |err| { + PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) + .with_message(format!("failed to create StateKey: {}", err)) + .finish(Location::Undefined) + }, + )?) }; let core_package_registry = { diff --git a/vm/vm-runtime/src/starcoin_vm.rs b/vm/vm-runtime/src/starcoin_vm.rs index 3aff03235d..0d43e0b090 100644 --- a/vm/vm-runtime/src/starcoin_vm.rs +++ b/vm/vm-runtime/src/starcoin_vm.rs @@ -479,7 +479,7 @@ impl StarcoinVM { remote_cache: &StateViewCache, package_address: AccountAddress, ) -> Result { - let key = StateKey::resource(&package_address, &ModuleUpgradeStrategy::struct_tag()); + let key = StateKey::resource(&package_address, &ModuleUpgradeStrategy::struct_tag())?; if let Some(data) = remote_cache.get_state_value(&key)? { Ok(bcs_ext::from_bytes::(data.bytes())?.only_new_module()) } else { @@ -503,7 +503,7 @@ impl StarcoinVM { || (chain_id.is_barnard() && block_number < 8311392) { let key = - StateKey::resource(&package_address, &TwoPhaseUpgradeV2Resource::struct_tag()); + StateKey::resource(&package_address, &TwoPhaseUpgradeV2Resource::struct_tag())?; if let Some(data) = remote_cache.get_state_value(&key)? { let enforced = bcs_ext::from_bytes::(data.bytes())?.enforced();