diff --git a/Cargo.lock b/Cargo.lock index e80c69bccb..33b60ba01b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11947,6 +11947,7 @@ dependencies = [ "anyhow", "async-trait", "bcs-ext", + "bytes 1.6.1", "forkable-jellyfish-merkle", "once_cell", "serde", diff --git a/state/api/Cargo.toml b/state/api/Cargo.toml index 6928353365..be6e20b6a1 100644 --- a/state/api/Cargo.toml +++ b/state/api/Cargo.toml @@ -10,6 +10,7 @@ starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } forkable-jellyfish-merkle = { workspace = true } once_cell = { workspace = true } +bytes = { workspace = true } [dev-dependencies] diff --git a/state/api/src/chain_state.rs b/state/api/src/chain_state.rs index 22dae235e1..1524363711 100644 --- a/state/api/src/chain_state.rs +++ b/state/api/src/chain_state.rs @@ -5,7 +5,6 @@ use crate::StateReaderExt; use crate::TABLE_PATH_LIST; use anyhow::{ensure, Result}; use forkable_jellyfish_merkle::{blob::Blob, proof::SparseMerkleProof, RawKey}; -use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use starcoin_crypto::HashValue; use starcoin_state_tree::AccountStateSetIterator; @@ -20,10 +19,9 @@ use starcoin_vm_types::account_config::TABLE_HANDLE_ADDRESS_LIST; use starcoin_vm_types::genesis_config::ChainId; use starcoin_vm_types::on_chain_resource::{Epoch, EpochInfo, GlobalTimeOnChain}; use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; +use starcoin_vm_types::state_store::StateView; use starcoin_vm_types::token::token_code::TokenCode; -use starcoin_vm_types::{ - move_resource::MoveResource, on_chain_config::OnChainConfig, state_view::StateView, -}; +use starcoin_vm_types::{move_resource::MoveResource, on_chain_config::OnChainConfig}; use std::convert::TryFrom; #[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize)] @@ -174,30 +172,30 @@ where pub fn get_account_resource( &self, address: &AccountAddress, - ) -> Result> { + ) -> Result { self.reader.get_account_resource(*address) } /// Get Resource by type - pub fn get_resource(&self, address: AccountAddress) -> Result> + pub fn get_resource(&self, address: AccountAddress) -> Result where R: MoveResource, { - self.reader.get_resource_type(address) + self.reader.get_resource_type::(address) } pub fn get_sequence_number(&self, address: AccountAddress) -> Result { self.reader.get_sequence_number(address) } - pub fn get_on_chain_config(&self) -> Result> + pub fn get_on_chain_config(&self) -> Option where C: OnChainConfig, { self.reader.get_on_chain_config() } - pub fn get_balance(&self, address: &AccountAddress) -> Result> { + pub fn get_balance(&self, address: &AccountAddress) -> Result { self.reader.get_balance(*address) } @@ -206,7 +204,7 @@ where &self, address: &AccountAddress, type_tag: StructTag, - ) -> Result> { + ) -> Result { self.reader.get_balance_by_type(*address, type_tag) } @@ -214,7 +212,7 @@ where &self, address: &AccountAddress, token_code: TokenCode, - ) -> Result> { + ) -> Result { self.reader.get_balance_by_token_code(*address, token_code) } diff --git a/state/api/src/lib.rs b/state/api/src/lib.rs index 09f86e638d..f10c5c8188 100644 --- a/state/api/src/lib.rs +++ b/state/api/src/lib.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::message::{StateRequest, StateResponse}; -use anyhow::Result; +use anyhow::{format_err, Result}; use once_cell::sync::Lazy; use starcoin_crypto::HashValue; use starcoin_service_registry::{ActorService, ServiceHandler, ServiceRef}; @@ -15,18 +15,19 @@ pub use chain_state::{ AccountStateReader, ChainStateReader, ChainStateWriter, StateProof, StateWithProof, StateWithTableItemProof, }; -use serde::de::DeserializeOwned; pub use starcoin_state_tree::StateNodeStore; use starcoin_types::state_set::AccountStateSet; use starcoin_vm_types::access_path::DataPath; use starcoin_vm_types::account_config::TABLE_HANDLE_ADDRESS_LIST; use starcoin_vm_types::move_resource::MoveResource; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; -pub use starcoin_vm_types::state_view::{StateReaderExt, StateView}; +pub use starcoin_vm_types::state_view::StateReaderExt; mod chain_state; pub mod message; pub mod mock; +use bytes::Bytes; pub static TABLE_PATH_LIST: Lazy> = Lazy::new(|| { let mut path_list = vec![]; @@ -42,36 +43,41 @@ pub static TABLE_PATH_LIST: Lazy> = Lazy::new(|| { #[async_trait::async_trait] pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { - async fn get(self, access_path: AccessPath) -> Result>>; + async fn get(self, state_key: &StateKey) -> Result>; - async fn get_with_proof(self, access_path: AccessPath) -> Result; + async fn get_with_proof(self, state_key: &StateKey) -> Result; - async fn get_resource(self, address: AccountAddress) -> Result> + async fn get_resource(self, address: AccountAddress) -> Result where R: MoveResource, { - let access_path = AccessPath::new(address, R::resource_path()); - let r = self.get(access_path).await.and_then(|state| match state { - Some(state) => Ok(Some(bcs_ext::from_bytes::(state.as_slice())?)), - None => Ok(None), - })?; - Ok(r) + let rsrc_bytes = self.get(&StateKey::resource_typed::(&address)?).await?.ok_or_else( + || { + format_err!( + "Resource {:?} not exists at address:{}", + R::module_identifier(), + address + ) + }, + )?; + let rsrc = bcs_ext::from_bytes::(&rsrc_bytes)?; + Ok(rsrc) } - async fn get_account_state(self, address: AccountAddress) -> Result>; + async fn get_account_state(self, address: AccountAddress) -> Result; /// get account stateset on state_root(if empty, use current state root). async fn get_account_state_set( self, address: AccountAddress, state_root: Option, - ) -> Result>; + ) -> Result; async fn state_root(self) -> Result; async fn get_with_proof_by_root( self, - access_path: AccessPath, + state_key: StateKey, state_root: HashValue, ) -> Result; @@ -79,7 +85,7 @@ pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { self, address: AccountAddress, state_root: HashValue, - ) -> Result>; + ) -> Result; async fn get_with_table_item_proof( self, @@ -93,7 +99,7 @@ pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { state_root: HashValue, ) -> Result; - async fn get_table_info(self, address: AccountAddress) -> Result>; + async fn get_table_info(self, address: AccountAddress) -> Result; } #[async_trait::async_trait] @@ -101,8 +107,8 @@ impl ChainStateAsyncService for ServiceRef where S: ActorService + ServiceHandler, { - async fn get(self, access_path: AccessPath) -> Result>> { - let response = self.send(StateRequest::Get(access_path)).await??; + async fn get(self, state_key: &StateKey) -> Result> { + let response = self.send(StateRequest::Get(state_key.clone())).await??; if let StateResponse::State(state) = response { Ok(state) } else { @@ -110,8 +116,8 @@ where } } - async fn get_with_proof(self, access_path: AccessPath) -> Result { - let response = self.send(StateRequest::GetWithProof(access_path)).await??; + async fn get_with_proof(self, state_key: &StateKey) -> Result { + let response = self.send(StateRequest::GetWithProof(state_key.clone())).await??; if let StateResponse::StateWithProof(state) = response { Ok(*state) } else { @@ -119,10 +125,12 @@ where } } - async fn get_account_state(self, address: AccountAddress) -> Result> { + async fn get_account_state(self, address: AccountAddress) -> Result { let response = self.send(StateRequest::GetAccountState(address)).await??; if let StateResponse::AccountState(state) = response { - Ok(state) + Ok(state.ok_or_else(|| { + format_err!("AccountState not exists for address: {}", address) + })?) } else { panic!("Unexpect response type.") } @@ -131,7 +139,7 @@ where self, address: AccountAddress, state_root: Option, - ) -> Result> { + ) -> Result { let response = self .send(StateRequest::GetAccountStateSet { address, @@ -139,7 +147,9 @@ where }) .await??; if let StateResponse::AccountStateSet(state) = response { - Ok(state) + Ok(state.ok_or_else(|| { + format_err!("AccountStateSet not exists for address: {}", address) + })?) } else { panic!("Unexpected response type.") } @@ -155,11 +165,11 @@ where async fn get_with_proof_by_root( self, - access_path: AccessPath, + state_key: StateKey, state_root: HashValue, ) -> Result { let response = self - .send(StateRequest::GetWithProofByRoot(access_path, state_root)) + .send(StateRequest::GetWithProofByRoot(state_key, state_root)) .await??; if let StateResponse::StateWithProof(state) = response { Ok(*state) @@ -172,7 +182,7 @@ where self, account_address: AccountAddress, state_root: HashValue, - ) -> Result> { + ) -> Result { let response = self .send(StateRequest::GetAccountStateByRoot( account_address, @@ -180,7 +190,9 @@ where )) .await??; if let StateResponse::AccountState(state) = response { - Ok(state) + Ok(state.ok_or_else(|| { + format_err!("AccountState not exists for address: {}", account_address) + })?) } else { panic!("Unexpect response type.") } @@ -219,10 +231,12 @@ where } } - async fn get_table_info(self, address: AccountAddress) -> Result> { + async fn get_table_info(self, address: AccountAddress) -> Result { let response = self.send(StateRequest::GetTableInfo(address)).await??; if let StateResponse::TableInfo(state) = response { - Ok(state) + Ok(state.ok_or_else(|| { + format_err!("TableInfo not exists for address: {}", address) + })?) } else { panic!("Unexpect response type.") } diff --git a/state/api/src/message.rs b/state/api/src/message.rs index 331e10b463..287124d96c 100644 --- a/state/api/src/message.rs +++ b/state/api/src/message.rs @@ -3,19 +3,19 @@ use crate::{StateWithProof, StateWithTableItemProof}; use anyhow::Result; +use bytes::Bytes; use starcoin_crypto::HashValue; use starcoin_service_registry::ServiceRequest; use starcoin_types::state_set::AccountStateSet; -use starcoin_types::{ - access_path::AccessPath, account_address::AccountAddress, account_state::AccountState, -}; +use starcoin_types::{account_address::AccountAddress, account_state::AccountState}; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; #[derive(Debug, Clone)] pub enum StateRequest { - Get(AccessPath), - GetWithProof(AccessPath), - GetWithProofByRoot(AccessPath, HashValue), + Get(StateKey), + GetWithProof(StateKey), + GetWithProofByRoot(StateKey, HashValue), GetAccountState(AccountAddress), GetAccountStateSet { address: AccountAddress, @@ -34,7 +34,7 @@ impl ServiceRequest for StateRequest { #[derive(Debug, Clone)] pub enum StateResponse { - State(Option>), + State(Option), StateWithProof(Box), StateRoot(HashValue), AccountState(Option), diff --git a/state/api/src/mock/mock_chain_state_service.rs b/state/api/src/mock/mock_chain_state_service.rs index 71b4a09833..0630811334 100644 --- a/state/api/src/mock/mock_chain_state_service.rs +++ b/state/api/src/mock/mock_chain_state_service.rs @@ -3,11 +3,12 @@ use crate::{ChainStateAsyncService, StateWithProof, StateWithTableItemProof}; use anyhow::Result; +use bytes::Bytes; use starcoin_crypto::HashValue; -use starcoin_types::access_path::AccessPath; use starcoin_types::account_address::AccountAddress; use starcoin_types::account_state::AccountState; use starcoin_types::state_set::AccountStateSet; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; //TODO implement Mock service @@ -23,15 +24,15 @@ impl MockChainStateService { #[allow(clippy::diverging_sub_expression)] #[async_trait::async_trait] impl ChainStateAsyncService for MockChainStateService { - async fn get(self, _access_path: AccessPath) -> Result>> { + async fn get(self, _state_key: &StateKey) -> Result> { unimplemented!() } - async fn get_with_proof(self, _access_path: AccessPath) -> Result { + async fn get_with_proof(self, _state_key: &StateKey) -> Result { unimplemented!() } - async fn get_account_state(self, _address: AccountAddress) -> Result> { + async fn get_account_state(self, _address: AccountAddress) -> Result { unimplemented!() } @@ -39,7 +40,7 @@ impl ChainStateAsyncService for MockChainStateService { self, _address: AccountAddress, _state_root: Option, - ) -> Result> { + ) -> Result { unimplemented!() } @@ -49,7 +50,7 @@ impl ChainStateAsyncService for MockChainStateService { async fn get_with_proof_by_root( self, - _access_path: AccessPath, + _state_key: StateKey, _state_root: HashValue, ) -> Result { unimplemented!() @@ -59,7 +60,7 @@ impl ChainStateAsyncService for MockChainStateService { self, _address: AccountAddress, _state_root: HashValue, - ) -> Result> { + ) -> Result { unimplemented!() } @@ -80,7 +81,7 @@ impl ChainStateAsyncService for MockChainStateService { unimplemented!() } - async fn get_table_info(self, _address: AccountAddress) -> Result> { - Ok(None) + async fn get_table_info(self, _address: AccountAddress) -> Result { + unimplemented!() } }