From b44f03de6efb8291185847e0c20dec8d44c4e258 Mon Sep 17 00:00:00 2001 From: welbon Date: Wed, 31 May 2023 22:27:06 +0800 Subject: [PATCH 01/14] [write_set] Added storage handling for write_set in the executor execution flow. --- chain/src/chain.rs | 6 ++++++ executor/src/block_executor.rs | 11 ++++++++++- storage/src/lib.rs | 29 ++++++++++++++++++++++++++++- storage/src/tests/mod.rs | 1 + storage/src/write_set/mod.rs | 31 +++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 storage/src/write_set/mod.rs diff --git a/chain/src/chain.rs b/chain/src/chain.rs index ea118b890c..aa68b92276 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -42,6 +42,7 @@ use starcoin_vm_types::on_chain_resource::Epoch; use std::cmp::min; use std::iter::Extend; use std::option::Option::{None, Some}; +use std::ptr::write; use std::{collections::HashMap, sync::Arc}; pub struct ChainStatusWithBlock { @@ -463,6 +464,7 @@ impl BlockChain { let block_id = block.id(); let txn_infos = executed_data.txn_infos; let txn_events = executed_data.txn_events; + let txn_write_set = executed_data.txn_write_sets; debug_assert!( txn_events.len() == txn_infos.len(), @@ -505,6 +507,10 @@ impl BlockChain { storage.save_block_info(block_info.clone())?; + for (hash_value, write_set) in txn_write_set.iter() { + storage.save_write_set(*hash_value, write_set.clone())?; + } + watch(CHAIN_WATCH_NAME, "n26"); Ok(ExecutedBlock { block, block_info }) } diff --git a/executor/src/block_executor.rs b/executor/src/block_executor.rs index 6318b6dbe4..0983914249 100644 --- a/executor/src/block_executor.rs +++ b/executor/src/block_executor.rs @@ -9,12 +9,15 @@ use starcoin_types::transaction::TransactionStatus; use starcoin_types::transaction::{Transaction, TransactionInfo}; use starcoin_vm_runtime::metrics::VMMetrics; use starcoin_vm_types::contract_event::ContractEvent; +use starcoin_vm_types::write_set::WriteSet; +use std::collections::HashMap; #[derive(Clone, Debug, Eq, PartialEq)] pub struct BlockExecutedData { pub state_root: HashValue, pub txn_infos: Vec, pub txn_events: Vec>, + pub txn_write_sets: HashMap, } impl Default for BlockExecutedData { @@ -23,6 +26,7 @@ impl Default for BlockExecutedData { state_root: HashValue::zero(), txn_events: vec![], txn_infos: vec![], + txn_write_sets: HashMap::default(), } } } @@ -53,12 +57,13 @@ pub fn block_execute( } TransactionStatus::Keep(status) => { chain_state - .apply_write_set(write_set) + .apply_write_set(write_set.clone()) .map_err(BlockExecutorError::BlockChainStateErr)?; let txn_state_root = chain_state .commit() .map_err(BlockExecutorError::BlockChainStateErr)?; + #[cfg(testing)] info!("txn_hash {} gas_used {}", txn_hash, gas_used); executed_data.txn_infos.push(TransactionInfo::new( @@ -68,7 +73,11 @@ pub fn block_execute( gas_used, status, )); + executed_data.txn_events.push(events); + + // Put write set into result + executed_data.txn_write_sets.insert(txn_hash, write_set); } }; } diff --git a/storage/src/lib.rs b/storage/src/lib.rs index e61d882e6d..3fb72b19be 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -13,6 +13,7 @@ use crate::storage::{CodecKVStore, CodecWriteBatch, ColumnFamilyName, StorageIns //use crate::table_info::{TableInfoStorage, TableInfoStore}; use crate::transaction::TransactionStorage; use crate::transaction_info::{TransactionInfoHashStorage, TransactionInfoStorage}; +use crate::write_set::WriteSetStorage; use anyhow::{bail, format_err, Error, Result}; use network_types::peer_info::PeerId; use num_enum::{IntoPrimitive, TryFromPrimitive}; @@ -29,9 +30,11 @@ use starcoin_types::{ startup_info::StartupInfo, }; //use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; +use starcoin_types::write_set::WriteSet; use std::collections::BTreeMap; use std::fmt::{Debug, Display, Formatter}; use std::sync::Arc; + pub use upgrade::BARNARD_HARD_FORK_HASH; pub use upgrade::BARNARD_HARD_FORK_HEIGHT; @@ -53,6 +56,7 @@ mod tests; pub mod transaction; pub mod transaction_info; mod upgrade; +pub mod write_set; #[macro_use] pub mod storage_macros; @@ -76,6 +80,7 @@ pub const TRANSACTION_INFO_HASH_PREFIX_NAME: ColumnFamilyName = "transaction_inf pub const CONTRACT_EVENT_PREFIX_NAME: ColumnFamilyName = "contract_event"; pub const FAILED_BLOCK_PREFIX_NAME: ColumnFamilyName = "failed_block"; pub const TABLE_INFO_PREFIX_NAME: ColumnFamilyName = "table_info"; +pub const WRITE_SET_PRIFIX_NAME: ColumnFamilyName = "write_set"; ///db storage use prefix_name vec to init /// Please note that adding a prefix needs to be added in vec simultaneously, remember!! @@ -138,9 +143,11 @@ static VEC_PREFIX_NAME_V3: Lazy> = Lazy::new(|| { TRANSACTION_INFO_HASH_PREFIX_NAME, CONTRACT_EVENT_PREFIX_NAME, FAILED_BLOCK_PREFIX_NAME, + WRITE_SET_PRIFIX_NAME, // TABLE_INFO_PREFIX_NAME, ] }); + #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, IntoPrimitive, TryFromPrimitive)] #[repr(u8)] pub enum StorageVersion { @@ -239,6 +246,7 @@ pub trait BlockTransactionInfoStore { ids: Vec, ) -> Result>>; } + pub trait ContractEventStore { /// Save events by key `txn_info_id`. /// As txn_info has accumulator root of events, so there is a one-to-one mapping. @@ -261,6 +269,11 @@ pub trait TransactionStore { fn get_transactions(&self, txn_hash_vec: Vec) -> Result>>; } +pub trait WriteSetStore { + fn get_write_set(&self, hash: HashValue) -> Result>; + fn save_write_set(&self, hash: HashValue, write_set: WriteSet) -> Result<()>; +} + // TODO: remove Arc, we can clone Storage directly. #[derive(Clone)] pub struct Storage { @@ -274,6 +287,7 @@ pub struct Storage { block_info_storage: BlockInfoStorage, event_storage: ContractEventStorage, chain_info_storage: ChainInfoStorage, + write_set_store: WriteSetStorage, // table_info_storage: TableInfoStorage, // instance: StorageInstance, } @@ -293,7 +307,8 @@ impl Storage { AccumulatorStorage::new_transaction_accumulator_storage(instance.clone()), block_info_storage: BlockInfoStorage::new(instance.clone()), event_storage: ContractEventStorage::new(instance.clone()), - chain_info_storage: ChainInfoStorage::new(instance), + chain_info_storage: ChainInfoStorage::new(instance.clone()), + write_set_store: WriteSetStorage::new(instance), // table_info_storage: TableInfoStorage::new(instance), // instance, }; @@ -331,6 +346,7 @@ impl Display for Storage { write!(f, "{}", self.clone()) } } + impl Debug for Storage { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { write!(f, "{}", self) @@ -543,6 +559,16 @@ impl ContractEventStore for Storage { } } +impl WriteSetStore for Storage { + fn get_write_set(&self, hash: HashValue) -> Result> { + self.write_set_store.get_write_set(hash) + } + + fn save_write_set(&self, hash: HashValue, write_set: WriteSet) -> Result<()> { + self.write_set_store.save_write_set(hash, write_set) + } +} + impl TransactionStore for Storage { fn get_transaction(&self, txn_hash: HashValue) -> Result, Error> { self.transaction_storage.get(txn_hash) @@ -572,6 +598,7 @@ pub trait Store: + TransactionStore + BlockTransactionInfoStore + ContractEventStore + + WriteSetStore + IntoSuper { fn get_transaction_info_by_block_and_index( diff --git a/storage/src/tests/mod.rs b/storage/src/tests/mod.rs index abf8a51ed0..9f2f8f9488 100644 --- a/storage/src/tests/mod.rs +++ b/storage/src/tests/mod.rs @@ -4,3 +4,4 @@ mod test_accumulator; mod test_batch; mod test_block; mod test_storage; +mod test_write_set; diff --git a/storage/src/write_set/mod.rs b/storage/src/write_set/mod.rs new file mode 100644 index 0000000000..1b6c7ce53b --- /dev/null +++ b/storage/src/write_set/mod.rs @@ -0,0 +1,31 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::storage::{CodecKVStore, ValueCodec}; +use crate::{define_storage, WriteSetStore, WRITE_SET_PRIFIX_NAME}; +use anyhow::Result; +use bcs_ext::BCSCodec; +use starcoin_crypto::HashValue; +use starcoin_types::write_set::WriteSet; + +define_storage!(WriteSetStorage, HashValue, WriteSet, WRITE_SET_PRIFIX_NAME); + +impl ValueCodec for WriteSet { + fn encode_value(&self) -> Result> { + self.encode() + } + + fn decode_value(data: &[u8]) -> Result { + Self::decode(data) + } +} + +impl WriteSetStore for WriteSetStorage { + fn get_write_set(&self, hash: HashValue) -> Result> { + self.get(hash) + } + + fn save_write_set(&self, hash: HashValue, write_set_vec: WriteSet) -> Result<()> { + self.put(hash, write_set_vec) + } +} From 517cc31267a6c65a5db5b19d0f04c139dfbe4636 Mon Sep 17 00:00:00 2001 From: welbon Date: Wed, 31 May 2023 22:27:21 +0800 Subject: [PATCH 02/14] [write_set] Added storage handling for write_set in the executor execution flow. --- storage/src/tests/test_write_set.rs | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 storage/src/tests/test_write_set.rs diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs new file mode 100644 index 0000000000..8f622d3456 --- /dev/null +++ b/storage/src/tests/test_write_set.rs @@ -0,0 +1,53 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +// use crate::DiemDB; +extern crate chrono; + +use crate::cache_storage::CacheStorage; +use crate::db_storage::DBStorage; +use crate::storage::StorageInstance; +use crate::{Storage, WriteSetStore}; +use starcoin_config::RocksdbConfig; +use starcoin_crypto::HashValue; +use starcoin_vm_types::access_path::AccessPath; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::write_set::{WriteOp, WriteSet, WriteSetMut}; + +fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { + WriteSetMut::new(vec![( + StateKey::AccessPath(access_path), + WriteOp::Value(value), + )]) + .freeze() + .expect("freeze write_set must success.") +} + +#[test] +fn test_put_and_save() { + let tmpdir = starcoin_config::temp_dir(); + let storage = Storage::new(StorageInstance::new_cache_and_db_instance( + CacheStorage::new(None), + DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), + )) + .unwrap(); + + let access_path = AccessPath::random_resource(); + let state0 = HashValue::random().to_vec(); + let write_set = to_write_set(access_path.clone(), state0.clone()); + let hash = HashValue::random(); + storage + .write_set_store + .save_write_set(hash, write_set) + .expect("Save write set failed"); + + let after = storage + .write_set_store + .get_write_set(hash) + .expect("{} Write set not exists!") + .expect("{} Write set not exists!"); + assert!(!after.is_empty()); + let (st_key, op) = after.into_iter().next().expect("Error"); + assert_eq!(st_key, StateKey::AccessPath(access_path)); + assert_eq!(op, WriteOp::Value(state0)); +} From 6e0b101ff57455223f49c642dbd54f154a96dcd5 Mon Sep 17 00:00:00 2001 From: welbon Date: Thu, 1 Jun 2023 15:42:03 +0800 Subject: [PATCH 03/14] [write_set] Added write set for rpc --- chain/api/src/message.rs | 3 + chain/api/src/service.rs | 16 ++++ chain/service/src/chain_service.rs | 8 ++ chain/src/chain.rs | 1 - rpc/api/src/chain/mod.rs | 7 ++ rpc/api/src/types.rs | 79 ++++++++++++++----- rpc/server/src/module/chain_rpc.rs | 18 ++++- .../src/fork_chain.rs | 12 ++- 8 files changed, 118 insertions(+), 26 deletions(-) diff --git a/chain/api/src/message.rs b/chain/api/src/message.rs index d4144fe9a0..020bd3a552 100644 --- a/chain/api/src/message.rs +++ b/chain/api/src/message.rs @@ -14,6 +14,7 @@ use starcoin_types::{ transaction::Transaction, }; use starcoin_vm_types::access_path::AccessPath; +use starcoin_vm_types::write_set::WriteSet; #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] @@ -60,6 +61,7 @@ pub enum ChainRequest { access_path: Option, }, GetBlockInfos(Vec), + GetTransactionWriteSet(HashValue), } impl ServiceRequest for ChainRequest { @@ -88,4 +90,5 @@ pub enum ChainResponse { HashVec(Vec), TransactionProof(Box>), BlockInfoVec(Box>>), + TransactionWriteSet(Option), } diff --git a/chain/api/src/service.rs b/chain/api/src/service.rs index 8ba6adce0e..a90b8ec170 100644 --- a/chain/api/src/service.rs +++ b/chain/api/src/service.rs @@ -15,6 +15,7 @@ use starcoin_types::{ startup_info::StartupInfo, }; use starcoin_vm_types::access_path::AccessPath; +use starcoin_vm_types::write_set::WriteSet; /// Readable block chain service trait pub trait ReadableChainService { @@ -72,6 +73,8 @@ pub trait ReadableChainService { ) -> Result>; fn get_block_infos(&self, ids: Vec) -> Result>>; + + fn get_transaction_write_set(&self, hash: HashValue) -> Result>; } /// Writeable block chain service trait @@ -139,6 +142,8 @@ pub trait ChainAsyncService: ) -> Result>; async fn get_block_infos(&self, hashes: Vec) -> Result>>; + + async fn get_transaction_write_set(&self, hash: HashValue) -> Result>; } #[async_trait::async_trait] @@ -436,4 +441,15 @@ where bail!("get block_infos error") } } + + async fn get_transaction_write_set(&self, hash: HashValue) -> Result> { + let response = self + .send(ChainRequest::GetTransactionWriteSet(hash)) + .await??; + if let ChainResponse::TransactionWriteSet(write_set) = response { + Ok(write_set) + } else { + bail!("get get_write_set error") + } + } } diff --git a/chain/service/src/chain_service.rs b/chain/service/src/chain_service.rs index f7b32799d1..5b593b7dac 100644 --- a/chain/service/src/chain_service.rs +++ b/chain/service/src/chain_service.rs @@ -27,6 +27,7 @@ use starcoin_types::{ }; use starcoin_vm_runtime::metrics::VMMetrics; use starcoin_vm_types::access_path::AccessPath; +use starcoin_vm_types::write_set::WriteSet; use std::sync::Arc; /// A Chain reader service to provider Reader API. @@ -232,6 +233,9 @@ impl ServiceHandler for ChainReaderService { ChainRequest::GetBlockInfos(ids) => Ok(ChainResponse::BlockInfoVec(Box::new( self.inner.get_block_infos(ids)?, ))), + ChainRequest::GetTransactionWriteSet(hash) => Ok(ChainResponse::TransactionWriteSet( + self.inner.get_transaction_write_set(hash)?, + )), } } } @@ -416,6 +420,10 @@ impl ReadableChainService for ChainReaderServiceInner { fn get_block_infos(&self, ids: Vec) -> Result>> { self.storage.get_block_infos(ids) } + + fn get_transaction_write_set(&self, hash: HashValue) -> Result> { + self.storage.get_write_set(hash) + } } #[cfg(test)] diff --git a/chain/src/chain.rs b/chain/src/chain.rs index aa68b92276..10be4ba396 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -42,7 +42,6 @@ use starcoin_vm_types::on_chain_resource::Epoch; use std::cmp::min; use std::iter::Extend; use std::option::Option::{None, Some}; -use std::ptr::write; use std::{collections::HashMap, sync::Arc}; pub struct ChainStatusWithBlock { diff --git a/rpc/api/src/chain/mod.rs b/rpc/api/src/chain/mod.rs index 6901020caf..d3a549fdd8 100644 --- a/rpc/api/src/chain/mod.rs +++ b/rpc/api/src/chain/mod.rs @@ -6,6 +6,7 @@ use crate::types::pubsub::EventFilter; use crate::types::{ BlockHeaderView, BlockInfoView, BlockView, ChainId, ChainInfoView, StrView, TransactionEventResponse, TransactionInfoView, TransactionInfoWithProofView, TransactionView, + TransactionWriteSetView, }; use crate::FutureResult; use jsonrpc_core::Result; @@ -122,6 +123,12 @@ pub trait ChainApi { event_index: Option, access_path: Option>, ) -> FutureResult>>>; + + #[rpc(name = "chain.get_transaction_write_set")] + fn get_transaction_write_set( + &self, + block_hash: HashValue, + ) -> FutureResult>; } #[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema)] diff --git a/rpc/api/src/types.rs b/rpc/api/src/types.rs index 44822caa2c..64c1dc50a8 100644 --- a/rpc/api/src/types.rs +++ b/rpc/api/src/types.rs @@ -48,12 +48,13 @@ use starcoin_vm_types::transaction::{ }; use starcoin_vm_types::transaction_argument::convert_txn_args; use starcoin_vm_types::vm_status::{DiscardedVMStatus, KeptVMStatus, StatusCode}; -use starcoin_vm_types::write_set::WriteOp; +use starcoin_vm_types::write_set::{WriteOp, WriteSet}; use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use std::str::FromStr; pub type ByteCode = Vec; + mod node_api_types; pub mod pubsub; @@ -266,8 +267,8 @@ impl ArgumentsView { /// Because we cannot distinguish whether `0x12341235` is an human readable address or just some bcs bytes in hex string. impl<'de> Deserialize<'de> for ArgumentsView { fn deserialize(deserializer: D) -> Result>::Error> - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let args = >::deserialize(deserializer)?; Ok(ArgumentsView::HumanReadable(args)) @@ -277,8 +278,8 @@ impl<'de> Deserialize<'de> for ArgumentsView { /// Only return BCS hex string when returning arguments out of jsonrpc. impl Serialize for ArgumentsView { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> - where - S: Serializer, + where + S: Serializer, { match self { Self::HumanReadable(_vs) => { @@ -477,7 +478,7 @@ impl From for BlockHeader { } impl FromIterator for Vec { - fn from_iter>(views: T) -> Self { + fn from_iter>(views: T) -> Self { let mut blocks = vec![]; for view in views { blocks.push(view.into()) @@ -1221,6 +1222,7 @@ impl From for TransactionOutputView { } } } + impl From<(AccessPath, WriteOp)> for TransactionOutputAction { fn from((access_path, op): (AccessPath, WriteOp)) -> Self { let (action, value) = match op { @@ -1242,6 +1244,7 @@ impl From<(AccessPath, WriteOp)> for TransactionOutputAction { } } } + #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct TransactionOutputAction { pub access_path: AccessPath, @@ -1546,7 +1549,7 @@ impl JsonSchema for StrView { instance_type: Some(InstanceType::String.into()), ..Default::default() } - .into() + .into() } } @@ -1557,25 +1560,25 @@ impl From for StrView { } impl Serialize for StrView -where - Self: ToString, + where + Self: ToString, { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> - where - S: Serializer, + where + S: Serializer, { serializer.serialize_str(&self.to_string()) } } impl<'de, T> Deserialize<'de> for StrView -where - Self: FromStr, - ::Err: std::fmt::Display, + where + Self: FromStr, + ::Err: std::fmt::Display, { fn deserialize(deserializer: D) -> Result>::Error> - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let s = ::deserialize(deserializer)?; @@ -1790,8 +1793,8 @@ impl From> for BytesView { impl<'de> Deserialize<'de> for BytesView { fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let s = ::deserialize(deserializer)?; >::from_hex(s) @@ -1802,8 +1805,8 @@ impl<'de> Deserialize<'de> for BytesView { impl Serialize for BytesView { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { hex::encode(self).serialize(serializer) } @@ -1822,6 +1825,7 @@ pub struct ConnectLocal; impl ServiceRequest for ConnectLocal { type Response = RpcChannel; } + #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct AccumulatorInfoView { /// Accumulator root hash @@ -1928,6 +1932,41 @@ impl From for StateKeyView { } } +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct TransactionWriteSetView { + hash_value: HashValue, + access_write_set: Vec, + table_write_set: Vec, +} + +impl TransactionWriteSetView { + pub fn new(hash_value: HashValue, write_set: WriteSet) -> anyhow::Result { + let mut access_write_set = vec![]; + let mut table_item_write_set = vec![]; + for (state_key, op) in write_set { + match state_key { + StateKey::AccessPath(access_path) => { + access_write_set.push((access_path, op)); + } + StateKey::TableItem(table_item) => { + table_item_write_set.push((table_item, op)); + } + } + } + Ok(Self { + hash_value, + access_write_set: access_write_set + .into_iter() + .map(TransactionOutputAction::from) + .collect(), + table_write_set: table_item_write_set + .into_iter() + .map(TransactionOutputTableItemAction::from) + .collect(), + }) + } +} + #[cfg(test)] mod tests { use crate::types::{ByteCodeOrScriptFunction, FunctionId, StrView}; diff --git a/rpc/server/src/module/chain_rpc.rs b/rpc/server/src/module/chain_rpc.rs index 3544155169..69dee617f6 100644 --- a/rpc/server/src/module/chain_rpc.rs +++ b/rpc/server/src/module/chain_rpc.rs @@ -16,7 +16,7 @@ use starcoin_rpc_api::types::pubsub::EventFilter; use starcoin_rpc_api::types::{ BlockHeaderView, BlockInfoView, BlockTransactionsView, BlockView, ChainId, ChainInfoView, SignedUserTransactionView, StrView, TransactionEventResponse, TransactionInfoView, - TransactionInfoWithProofView, TransactionView, + TransactionInfoWithProofView, TransactionView, TransactionWriteSetView, }; use starcoin_rpc_api::FutureResult; use starcoin_state_api::StateView; @@ -469,6 +469,22 @@ where Box::pin(fut.boxed()) } + + fn get_transaction_write_set( + &self, + txn_hash: HashValue, + ) -> FutureResult> { + let service = self.service.clone(); + let fut = async move { + let write_set = service.get_transaction_write_set(txn_hash).await?; + match write_set { + None => Ok(None), + Some(w) => Ok(Some(TransactionWriteSetView::new(txn_hash, w)?)), + } + } + .map_err(map_err); + Box::pin(fut.boxed()) + } } fn try_decode_block_txns(state: &dyn StateView, block: &mut BlockView) -> anyhow::Result<()> { diff --git a/vm/starcoin-transactional-test-harness/src/fork_chain.rs b/vm/starcoin-transactional-test-harness/src/fork_chain.rs index a1438b827b..a20fd302ae 100644 --- a/vm/starcoin-transactional-test-harness/src/fork_chain.rs +++ b/vm/starcoin-transactional-test-harness/src/fork_chain.rs @@ -13,10 +13,7 @@ use starcoin_config::{BuiltinNetworkID, ChainNetworkID}; use starcoin_crypto::HashValue; use starcoin_rpc_api::chain::{ChainApi, GetBlockOption}; use starcoin_rpc_api::chain::{ChainApiClient, GetBlocksOption}; -use starcoin_rpc_api::types::{ - BlockInfoView, BlockTransactionsView, BlockView, ChainId, ChainInfoView, - SignedUserTransactionView, TransactionInfoView, TransactionView, -}; +use starcoin_rpc_api::types::{BlockInfoView, BlockTransactionsView, BlockView, ChainId, ChainInfoView, SignedUserTransactionView, TransactionInfoView, TransactionView, TransactionWriteSetView}; use starcoin_rpc_api::FutureResult; use starcoin_rpc_server::module::map_err; use starcoin_state_api::StateView; @@ -498,6 +495,13 @@ impl ChainApi for MockChainApi { }; Box::pin(fut.boxed().map_err(map_err)) } + + fn get_transaction_write_set(&self, _block_hash: HashValue) -> FutureResult> { + let fut = async move { + bail!("not implemented."); + }; + Box::pin(fut.boxed().map_err(map_err)) + } } fn try_decode_block_txns(state: &dyn StateView, block: &mut BlockView) -> anyhow::Result<()> { From bafb56c1b2fe73405d164a4b6180c342b51af3d2 Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 2 Jun 2023 14:37:53 +0800 Subject: [PATCH 04/14] [write_set] add deletion to unittest --- storage/src/tests/test_write_set.rs | 34 ++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index 8f622d3456..2a58be4bd5 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -15,12 +15,18 @@ use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::write_set::{WriteOp, WriteSet, WriteSetMut}; fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { - WriteSetMut::new(vec![( - StateKey::AccessPath(access_path), - WriteOp::Value(value), - )]) - .freeze() - .expect("freeze write_set must success.") + WriteSetMut::new(vec![ + ( + StateKey::AccessPath(access_path.clone()), + WriteOp::Value(value) + ), + ( + StateKey::AccessPath(access_path.clone()), + WriteOp::Deletion + ), + ]) + .freeze() + .expect("freeze write_set must success.") } #[test] @@ -29,13 +35,13 @@ fn test_put_and_save() { let storage = Storage::new(StorageInstance::new_cache_and_db_instance( CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), - )) - .unwrap(); + )).unwrap(); let access_path = AccessPath::random_resource(); let state0 = HashValue::random().to_vec(); let write_set = to_write_set(access_path.clone(), state0.clone()); let hash = HashValue::random(); + storage .write_set_store .save_write_set(hash, write_set) @@ -46,8 +52,16 @@ fn test_put_and_save() { .get_write_set(hash) .expect("{} Write set not exists!") .expect("{} Write set not exists!"); + assert!(!after.is_empty()); - let (st_key, op) = after.into_iter().next().expect("Error"); - assert_eq!(st_key, StateKey::AccessPath(access_path)); + + let mut iter = after.into_iter(); + + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, StateKey::AccessPath(access_path.clone())); assert_eq!(op, WriteOp::Value(state0)); + + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, StateKey::AccessPath(access_path)); + assert_eq!(op, WriteOp::Deletion); } From dfbd2cd3c4509c0101385a6ea65796f87564dae6 Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 2 Jun 2023 14:40:34 +0800 Subject: [PATCH 05/14] [write_set] auto format --- rpc/api/src/types.rs | 38 +++++++++---------- storage/src/tests/test_write_set.rs | 14 +++---- .../src/fork_chain.rs | 10 ++++- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/rpc/api/src/types.rs b/rpc/api/src/types.rs index 64c1dc50a8..80cfbfe517 100644 --- a/rpc/api/src/types.rs +++ b/rpc/api/src/types.rs @@ -267,8 +267,8 @@ impl ArgumentsView { /// Because we cannot distinguish whether `0x12341235` is an human readable address or just some bcs bytes in hex string. impl<'de> Deserialize<'de> for ArgumentsView { fn deserialize(deserializer: D) -> Result>::Error> - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let args = >::deserialize(deserializer)?; Ok(ArgumentsView::HumanReadable(args)) @@ -278,8 +278,8 @@ impl<'de> Deserialize<'de> for ArgumentsView { /// Only return BCS hex string when returning arguments out of jsonrpc. impl Serialize for ArgumentsView { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> - where - S: Serializer, + where + S: Serializer, { match self { Self::HumanReadable(_vs) => { @@ -478,7 +478,7 @@ impl From for BlockHeader { } impl FromIterator for Vec { - fn from_iter>(views: T) -> Self { + fn from_iter>(views: T) -> Self { let mut blocks = vec![]; for view in views { blocks.push(view.into()) @@ -1549,7 +1549,7 @@ impl JsonSchema for StrView { instance_type: Some(InstanceType::String.into()), ..Default::default() } - .into() + .into() } } @@ -1560,25 +1560,25 @@ impl From for StrView { } impl Serialize for StrView - where - Self: ToString, +where + Self: ToString, { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> - where - S: Serializer, + where + S: Serializer, { serializer.serialize_str(&self.to_string()) } } impl<'de, T> Deserialize<'de> for StrView - where - Self: FromStr, - ::Err: std::fmt::Display, +where + Self: FromStr, + ::Err: std::fmt::Display, { fn deserialize(deserializer: D) -> Result>::Error> - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let s = ::deserialize(deserializer)?; @@ -1793,8 +1793,8 @@ impl From> for BytesView { impl<'de> Deserialize<'de> for BytesView { fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let s = ::deserialize(deserializer)?; >::from_hex(s) @@ -1805,8 +1805,8 @@ impl<'de> Deserialize<'de> for BytesView { impl Serialize for BytesView { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { hex::encode(self).serialize(serializer) } diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index 2a58be4bd5..0a02606404 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -18,15 +18,12 @@ fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { WriteSetMut::new(vec![ ( StateKey::AccessPath(access_path.clone()), - WriteOp::Value(value) - ), - ( - StateKey::AccessPath(access_path.clone()), - WriteOp::Deletion + WriteOp::Value(value), ), + (StateKey::AccessPath(access_path.clone()), WriteOp::Deletion), ]) - .freeze() - .expect("freeze write_set must success.") + .freeze() + .expect("freeze write_set must success.") } #[test] @@ -35,7 +32,8 @@ fn test_put_and_save() { let storage = Storage::new(StorageInstance::new_cache_and_db_instance( CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), - )).unwrap(); + )) + .unwrap(); let access_path = AccessPath::random_resource(); let state0 = HashValue::random().to_vec(); diff --git a/vm/starcoin-transactional-test-harness/src/fork_chain.rs b/vm/starcoin-transactional-test-harness/src/fork_chain.rs index a20fd302ae..95d44ef5e0 100644 --- a/vm/starcoin-transactional-test-harness/src/fork_chain.rs +++ b/vm/starcoin-transactional-test-harness/src/fork_chain.rs @@ -13,7 +13,10 @@ use starcoin_config::{BuiltinNetworkID, ChainNetworkID}; use starcoin_crypto::HashValue; use starcoin_rpc_api::chain::{ChainApi, GetBlockOption}; use starcoin_rpc_api::chain::{ChainApiClient, GetBlocksOption}; -use starcoin_rpc_api::types::{BlockInfoView, BlockTransactionsView, BlockView, ChainId, ChainInfoView, SignedUserTransactionView, TransactionInfoView, TransactionView, TransactionWriteSetView}; +use starcoin_rpc_api::types::{ + BlockInfoView, BlockTransactionsView, BlockView, ChainId, ChainInfoView, + SignedUserTransactionView, TransactionInfoView, TransactionView, TransactionWriteSetView, +}; use starcoin_rpc_api::FutureResult; use starcoin_rpc_server::module::map_err; use starcoin_state_api::StateView; @@ -496,7 +499,10 @@ impl ChainApi for MockChainApi { Box::pin(fut.boxed().map_err(map_err)) } - fn get_transaction_write_set(&self, _block_hash: HashValue) -> FutureResult> { + fn get_transaction_write_set( + &self, + _block_hash: HashValue, + ) -> FutureResult> { let fut = async move { bail!("not implemented."); }; From 0e474ebebd212502ad3b13bb5eceb66b6a19ccfd Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 2 Jun 2023 15:07:30 +0800 Subject: [PATCH 06/14] [write_set] for commit check --- storage/src/tests/test_write_set.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index 0a02606404..1fe3bc6d11 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -20,7 +20,7 @@ fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { StateKey::AccessPath(access_path.clone()), WriteOp::Value(value), ), - (StateKey::AccessPath(access_path.clone()), WriteOp::Deletion), + (StateKey::AccessPath(access_path), WriteOp::Deletion), ]) .freeze() .expect("freeze write_set must success.") From afb0a2b1674f043226f84779234fcdca6ebf0fe7 Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 2 Jun 2023 17:31:07 +0800 Subject: [PATCH 07/14] [write_set] Fix commit script check --- Cargo.lock | 86 +- rpc/api/generated_rpc_schema/chain.json | 990 ++++++++++++++++++++++++ 2 files changed, 1066 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7946ae2d82..b63b0ab6f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2534,13 +2534,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi 0.3.9", + "windows-sys 0.48.0", ] [[package]] @@ -8129,9 +8129,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.8" +version = "0.36.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "14e4d67015953998ad0eb82887a0eb0129e18a7e2f3b7b0f6c422fddcd503d62" dependencies = [ "bitflags", "errno", @@ -12780,12 +12780,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.1", "windows_aarch64_msvc 0.42.1", "windows_i686_gnu 0.42.1", "windows_i686_msvc 0.42.1", "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.1", "windows_x86_64_msvc 0.42.1", ] @@ -12795,7 +12795,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -12804,21 +12813,42 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.1", "windows_aarch64_msvc 0.42.1", "windows_i686_gnu 0.42.1", "windows_i686_msvc 0.42.1", "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.1", "windows_x86_64_msvc 0.42.1", ] +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.34.0" @@ -12831,6 +12861,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.34.0" @@ -12843,6 +12879,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.34.0" @@ -12855,6 +12897,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.34.0" @@ -12867,12 +12915,24 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.34.0" @@ -12885,6 +12945,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winreg" version = "0.10.1" diff --git a/rpc/api/generated_rpc_schema/chain.json b/rpc/api/generated_rpc_schema/chain.json index 78a98739ea..c3ecbe05d3 100644 --- a/rpc/api/generated_rpc_schema/chain.json +++ b/rpc/api/generated_rpc_schema/chain.json @@ -3886,6 +3886,996 @@ ] } } + }, + { + "name": "chain.get_transaction_write_set", + "params": [ + { + "name": "block_hash", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "HashValue", + "type": "string", + "format": "HashValue" + } + } + ], + "result": { + "name": "Option < TransactionWriteSetView >", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_TransactionWriteSetView", + "type": [ + "object", + "null" + ], + "required": [ + "access_write_set", + "hash_value", + "table_write_set" + ], + "properties": { + "access_write_set": { + "type": "array", + "items": { + "type": "object", + "required": [ + "access_path", + "action" + ], + "properties": { + "access_path": { + "type": "object", + "required": [ + "address", + "path" + ], + "properties": { + "address": { + "type": "string", + "format": "AccountAddress" + }, + "path": { + "oneOf": [ + { + "type": "object", + "required": [ + "Code" + ], + "properties": { + "Code": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Resource" + ], + "properties": { + "Resource": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "action": { + "type": "string", + "enum": [ + "Deletion", + "Value" + ] + }, + "value": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "Code" + ], + "properties": { + "Code": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "abi": { + "type": [ + "object", + "null" + ], + "required": [ + "module_name", + "script_functions", + "structs" + ], + "properties": { + "module_name": { + "type": "string" + }, + "script_functions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "args", + "doc", + "module_name", + "name", + "returns", + "ty_args" + ], + "properties": { + "args": { + "description": "The description of regular arguments.", + "type": "array", + "items": { + "description": "The description of a (regular) argument in a script.", + "type": "object", + "required": [ + "doc", + "name", + "type_tag" + ], + "properties": { + "doc": { + "description": "The doc of the arg.", + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "type_tag": { + "description": "The expected type. In Move scripts, this does contain generics type parameters.", + "oneOf": [ + { + "type": "string", + "enum": [ + "Bool", + "U8", + "U64", + "U128", + "Address", + "Signer", + "U16", + "U32", + "U256" + ] + }, + { + "type": "object", + "required": [ + "Vector" + ], + "properties": { + "Vector": { + "$ref": "#/definitions/TypeInstantiation" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Struct" + ], + "properties": { + "Struct": { + "type": "object", + "required": [ + "abilities", + "doc", + "fields", + "module_name", + "name", + "ty_args" + ], + "properties": { + "abilities": { + "type": "string" + }, + "doc": { + "description": "The doc of the struct", + "type": "string" + }, + "fields": { + "description": "fields of the structs.", + "type": "array", + "items": { + "type": "object", + "required": [ + "doc", + "name", + "type_abi" + ], + "properties": { + "doc": { + "description": "doc of the field", + "type": "string" + }, + "name": { + "description": "field name", + "type": "string" + }, + "type_abi": { + "description": "type of the field", + "allOf": [ + { + "$ref": "#/definitions/TypeInstantiation" + } + ] + } + } + } + }, + "module_name": { + "description": "module contains the struct", + "type": "string" + }, + "name": { + "description": "name of the struct", + "type": "string" + }, + "ty_args": { + "type": "array", + "items": { + "description": "The description of a type argument in a script.", + "type": "object", + "required": [ + "abilities", + "name", + "phantom", + "ty" + ], + "properties": { + "abilities": { + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "phantom": { + "type": "boolean" + }, + "ty": { + "$ref": "#/definitions/TypeInstantiation" + } + } + } + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "TypeParameter" + ], + "properties": { + "TypeParameter": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Reference" + ], + "properties": { + "Reference": { + "type": "array", + "items": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/TypeInstantiation" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + ] + } + } + } + }, + "doc": { + "description": "Some text comment.", + "type": "string" + }, + "module_name": { + "description": "The module name where the script lives.", + "type": "string" + }, + "name": { + "description": "The public name of the script.", + "type": "string" + }, + "returns": { + "description": "return types", + "type": "array", + "items": { + "oneOf": [ + { + "type": "string", + "enum": [ + "Bool", + "U8", + "U64", + "U128", + "Address", + "Signer", + "U16", + "U32", + "U256" + ] + }, + { + "type": "object", + "required": [ + "Vector" + ], + "properties": { + "Vector": { + "$ref": "#/definitions/TypeInstantiation" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Struct" + ], + "properties": { + "Struct": { + "type": "object", + "required": [ + "abilities", + "doc", + "fields", + "module_name", + "name", + "ty_args" + ], + "properties": { + "abilities": { + "type": "string" + }, + "doc": { + "description": "The doc of the struct", + "type": "string" + }, + "fields": { + "description": "fields of the structs.", + "type": "array", + "items": { + "type": "object", + "required": [ + "doc", + "name", + "type_abi" + ], + "properties": { + "doc": { + "description": "doc of the field", + "type": "string" + }, + "name": { + "description": "field name", + "type": "string" + }, + "type_abi": { + "description": "type of the field", + "allOf": [ + { + "$ref": "#/definitions/TypeInstantiation" + } + ] + } + } + } + }, + "module_name": { + "description": "module contains the struct", + "type": "string" + }, + "name": { + "description": "name of the struct", + "type": "string" + }, + "ty_args": { + "type": "array", + "items": { + "description": "The description of a type argument in a script.", + "type": "object", + "required": [ + "abilities", + "name", + "phantom", + "ty" + ], + "properties": { + "abilities": { + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "phantom": { + "type": "boolean" + }, + "ty": { + "$ref": "#/definitions/TypeInstantiation" + } + } + } + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "TypeParameter" + ], + "properties": { + "TypeParameter": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Reference" + ], + "properties": { + "Reference": { + "type": "array", + "items": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/TypeInstantiation" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + ] + } + }, + "ty_args": { + "description": "The names of the type arguments.", + "type": "array", + "items": { + "description": "The description of a type argument in a script.", + "type": "object", + "required": [ + "abilities", + "name", + "phantom" + ], + "properties": { + "abilities": { + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "phantom": { + "type": "boolean" + } + } + } + } + } + } + }, + "structs": { + "type": "array", + "items": { + "type": "object", + "required": [ + "abilities", + "doc", + "fields", + "module_name", + "name", + "ty_args" + ], + "properties": { + "abilities": { + "type": "string" + }, + "doc": { + "description": "The doc of the struct", + "type": "string" + }, + "fields": { + "description": "fields of the structs.", + "type": "array", + "items": { + "type": "object", + "required": [ + "doc", + "name", + "type_abi" + ], + "properties": { + "doc": { + "description": "doc of the field", + "type": "string" + }, + "name": { + "description": "field name", + "type": "string" + }, + "type_abi": { + "description": "type of the field", + "oneOf": [ + { + "type": "string", + "enum": [ + "Bool", + "U8", + "U64", + "U128", + "Address", + "Signer", + "U16", + "U32", + "U256" + ] + }, + { + "type": "object", + "required": [ + "Vector" + ], + "properties": { + "Vector": { + "$ref": "#/definitions/TypeInstantiation" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Struct" + ], + "properties": { + "Struct": { + "type": "object", + "required": [ + "abilities", + "doc", + "fields", + "module_name", + "name", + "ty_args" + ], + "properties": { + "abilities": { + "type": "string" + }, + "doc": { + "description": "The doc of the struct", + "type": "string" + }, + "fields": { + "description": "fields of the structs.", + "type": "array", + "items": { + "$ref": "#/definitions/FieldABI" + } + }, + "module_name": { + "description": "module contains the struct", + "type": "string" + }, + "name": { + "description": "name of the struct", + "type": "string" + }, + "ty_args": { + "type": "array", + "items": { + "description": "The description of a type argument in a script.", + "type": "object", + "required": [ + "abilities", + "name", + "phantom", + "ty" + ], + "properties": { + "abilities": { + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "phantom": { + "type": "boolean" + }, + "ty": { + "$ref": "#/definitions/TypeInstantiation" + } + } + } + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "TypeParameter" + ], + "properties": { + "TypeParameter": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Reference" + ], + "properties": { + "Reference": { + "type": "array", + "items": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/TypeInstantiation" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + ] + } + } + } + }, + "module_name": { + "description": "module contains the struct", + "type": "string" + }, + "name": { + "description": "name of the struct", + "type": "string" + }, + "ty_args": { + "type": "array", + "items": { + "description": "The description of a type argument in a script.", + "type": "object", + "required": [ + "abilities", + "name", + "phantom" + ], + "properties": { + "abilities": { + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "phantom": { + "type": "boolean" + } + } + } + } + } + } + } + } + }, + "code": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Resource" + ], + "properties": { + "Resource": { + "type": "object", + "required": [ + "raw" + ], + "properties": { + "json": true, + "raw": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + { + "type": "null" + } + ] + } + } + } + }, + "hash_value": { + "type": "string", + "format": "HashValue" + }, + "table_write_set": { + "type": "array", + "items": { + "type": "object", + "required": [ + "action", + "table_item" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "Deletion", + "Value" + ] + }, + "table_item": { + "type": "object", + "required": [ + "handle", + "key" + ], + "properties": { + "handle": { + "type": "string", + "format": "AccountAddress" + }, + "key": { + "type": "string" + } + } + }, + "value": { + "type": [ + "string", + "null" + ] + } + } + } + } + }, + "definitions": { + "FieldABI": { + "type": "object", + "required": [ + "doc", + "name", + "type_abi" + ], + "properties": { + "doc": { + "description": "doc of the field", + "type": "string" + }, + "name": { + "description": "field name", + "type": "string" + }, + "type_abi": { + "description": "type of the field", + "allOf": [ + { + "$ref": "#/definitions/TypeInstantiation" + } + ] + } + } + }, + "TypeInstantiation": { + "oneOf": [ + { + "type": "string", + "enum": [ + "Bool", + "U8", + "U64", + "U128", + "Address", + "Signer", + "U16", + "U32", + "U256" + ] + }, + { + "type": "object", + "required": [ + "Vector" + ], + "properties": { + "Vector": { + "$ref": "#/definitions/TypeInstantiation" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Struct" + ], + "properties": { + "Struct": { + "type": "object", + "required": [ + "abilities", + "doc", + "fields", + "module_name", + "name", + "ty_args" + ], + "properties": { + "abilities": { + "type": "string" + }, + "doc": { + "description": "The doc of the struct", + "type": "string" + }, + "fields": { + "description": "fields of the structs.", + "type": "array", + "items": { + "$ref": "#/definitions/FieldABI" + } + }, + "module_name": { + "description": "module contains the struct", + "type": "string" + }, + "name": { + "description": "name of the struct", + "type": "string" + }, + "ty_args": { + "type": "array", + "items": { + "description": "The description of a type argument in a script.", + "type": "object", + "required": [ + "abilities", + "name", + "phantom", + "ty" + ], + "properties": { + "abilities": { + "type": "string" + }, + "name": { + "description": "The name of the argument.", + "type": "string" + }, + "phantom": { + "type": "boolean" + }, + "ty": { + "$ref": "#/definitions/TypeInstantiation" + } + } + } + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "TypeParameter" + ], + "properties": { + "TypeParameter": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Reference" + ], + "properties": { + "Reference": { + "type": "array", + "items": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/TypeInstantiation" + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + ] + } + } + } + } } ] } \ No newline at end of file From 8b6a73f9eeecab1cff3cc3b768c8beec6c79fd71 Mon Sep 17 00:00:00 2001 From: welbon Date: Mon, 5 Jun 2023 11:48:03 +0800 Subject: [PATCH 08/14] [write_set] set hashmap to vector --- executor/src/block_executor.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/executor/src/block_executor.rs b/executor/src/block_executor.rs index 0983914249..4d6b9415b3 100644 --- a/executor/src/block_executor.rs +++ b/executor/src/block_executor.rs @@ -10,14 +10,13 @@ use starcoin_types::transaction::{Transaction, TransactionInfo}; use starcoin_vm_runtime::metrics::VMMetrics; use starcoin_vm_types::contract_event::ContractEvent; use starcoin_vm_types::write_set::WriteSet; -use std::collections::HashMap; #[derive(Clone, Debug, Eq, PartialEq)] pub struct BlockExecutedData { pub state_root: HashValue, pub txn_infos: Vec, pub txn_events: Vec>, - pub txn_write_sets: HashMap, + pub txn_write_sets: Vec<(HashValue, WriteSet)>, } impl Default for BlockExecutedData { @@ -26,7 +25,7 @@ impl Default for BlockExecutedData { state_root: HashValue::zero(), txn_events: vec![], txn_infos: vec![], - txn_write_sets: HashMap::default(), + txn_write_sets: vec![], } } } @@ -77,7 +76,7 @@ pub fn block_execute( executed_data.txn_events.push(events); // Put write set into result - executed_data.txn_write_sets.insert(txn_hash, write_set); + executed_data.txn_write_sets.push((txn_hash, write_set)); } }; } From 17de1ba2dccab852715ed960079e0f21f8a08eb8 Mon Sep 17 00:00:00 2001 From: welbon Date: Mon, 5 Jun 2023 14:57:55 +0800 Subject: [PATCH 09/14] [write_set] Add table handle test for write set --- storage/src/tests/test_write_set.rs | 60 +++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index 1fe3bc6d11..75881063e4 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -10,8 +10,10 @@ use crate::storage::StorageInstance; use crate::{Storage, WriteSetStore}; use starcoin_config::RocksdbConfig; use starcoin_crypto::HashValue; +use starcoin_types::account_address::AccountAddress; use starcoin_vm_types::access_path::AccessPath; -use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::state_key::{StateKey}; +use starcoin_vm_types::state_store::table::TableHandle; use starcoin_vm_types::write_set::{WriteOp, WriteSet, WriteSetMut}; fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { @@ -22,8 +24,21 @@ fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { ), (StateKey::AccessPath(access_path), WriteOp::Deletion), ]) - .freeze() - .expect("freeze write_set must success.") + .freeze() + .expect("freeze write_set must success.") +} + +fn to_table_item_write_set(table_item: &StateKey, value: Vec) -> WriteSet { + WriteSetMut::new(vec![ + ( + table_item.clone(), + WriteOp::Value(value), + ), + ( + table_item.clone(), + WriteOp::Deletion + ), + ]).freeze().expect("freeze write_set must success.") } #[test] @@ -33,7 +48,7 @@ fn test_put_and_save() { CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), )) - .unwrap(); + .unwrap(); let access_path = AccessPath::random_resource(); let state0 = HashValue::random().to_vec(); @@ -63,3 +78,40 @@ fn test_put_and_save() { assert_eq!(st_key, StateKey::AccessPath(access_path)); assert_eq!(op, WriteOp::Deletion); } + +#[test] +fn test_put_and_save_table_item() { + let tmpdir = starcoin_config::temp_dir(); + let storage = Storage::new(StorageInstance::new_cache_and_db_instance( + CacheStorage::new(None), + DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), + )) + .unwrap(); + + let table_item = StateKey::table_item(TableHandle(AccountAddress::random()), HashValue::random().to_vec()); + let table_item_val = HashValue::random().to_vec(); + let hash = HashValue::random(); + + storage + .write_set_store + .save_write_set(hash, to_table_item_write_set(&table_item, table_item_val.clone())) + .expect("Save write set failed"); + + let after = storage + .write_set_store + .get_write_set(hash) + .expect("{} Write set not exists!") + .expect("{} Write set not exists!"); + + assert!(!after.is_empty()); + + let mut iter = after.into_iter(); + + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, table_item.clone()); + assert_eq!(op, WriteOp::Value(table_item_val.clone())); + + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, table_item.clone()); + assert_eq!(op, WriteOp::Deletion); +} From 710e91cff3a0f1be7dd76b61661581aab4948fd3 Mon Sep 17 00:00:00 2001 From: welbon Date: Tue, 27 Jun 2023 21:49:24 +0800 Subject: [PATCH 10/14] [write_set] consume vector while save --- chain/src/chain.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 10be4ba396..084f404fc5 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -506,9 +506,10 @@ impl BlockChain { storage.save_block_info(block_info.clone())?; - for (hash_value, write_set) in txn_write_set.iter() { - storage.save_write_set(*hash_value, write_set.clone())?; - } + txn_write_set.into_iter().for_each(|(hash_value, write_set)| { + storage.save_write_set(hash_value, write_set).expect("Save write set failed!"); + }); + watch(CHAIN_WATCH_NAME, "n26"); Ok(ExecutedBlock { block, block_info }) From 5f395770f5e61a3d3065f31e18b096acd26566d0 Mon Sep 17 00:00:00 2001 From: welbon Date: Wed, 28 Jun 2023 09:10:01 +0800 Subject: [PATCH 11/14] [write_set] consume vector elements while saving write set --- chain/src/chain.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 084f404fc5..a1c04f8fbf 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -506,9 +506,9 @@ impl BlockChain { storage.save_block_info(block_info.clone())?; - txn_write_set.into_iter().for_each(|(hash_value, write_set)| { - storage.save_write_set(hash_value, write_set).expect("Save write set failed!"); - }); + for (hash_value, write_set) in txn_write_set{ + storage.save_write_set(hash_value, write_set)?; + } watch(CHAIN_WATCH_NAME, "n26"); From 304eacaeed56ff31f8d186f148ff2454312517d4 Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 4 Aug 2023 17:01:43 +0800 Subject: [PATCH 12/14] [write_set] add write set storage batch saving code and test --- chain/src/chain.rs | 14 ++--- storage/src/lib.rs | 5 ++ storage/src/tests/test_write_set.rs | 82 +++++++++++++++++++++++++++-- storage/src/write_set/mod.rs | 8 ++- 4 files changed, 94 insertions(+), 15 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index a1c04f8fbf..863a5f245e 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -321,15 +321,15 @@ impl BlockChain { } pub fn verify_with_verifier(&mut self, block: Block) -> Result - where - V: BlockVerifier, + where + V: BlockVerifier, { V::verify_block(self, block) } pub fn apply_with_verifier(&mut self, block: Block) -> Result - where - V: BlockVerifier, + where + V: BlockVerifier, { let verified_block = self.verify_with_verifier::(block)?; watch(CHAIN_WATCH_NAME, "n1"); @@ -505,11 +505,7 @@ impl BlockChain { storage.commit_block(block.clone())?; storage.save_block_info(block_info.clone())?; - - for (hash_value, write_set) in txn_write_set{ - storage.save_write_set(hash_value, write_set)?; - } - + storage.save_write_set_batch(txn_write_set)?; watch(CHAIN_WATCH_NAME, "n26"); Ok(ExecutedBlock { block, block_info }) diff --git a/storage/src/lib.rs b/storage/src/lib.rs index 3fb72b19be..8e6126e011 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -272,6 +272,7 @@ pub trait TransactionStore { pub trait WriteSetStore { fn get_write_set(&self, hash: HashValue) -> Result>; fn save_write_set(&self, hash: HashValue, write_set: WriteSet) -> Result<()>; + fn save_write_set_batch(&self, write_set_vec: Vec<(HashValue, WriteSet)>) -> Result<()>; } // TODO: remove Arc, we can clone Storage directly. @@ -567,6 +568,10 @@ impl WriteSetStore for Storage { fn save_write_set(&self, hash: HashValue, write_set: WriteSet) -> Result<()> { self.write_set_store.save_write_set(hash, write_set) } + + fn save_write_set_batch(&self, write_set_vec: Vec<(HashValue, WriteSet)>) -> Result<()> { + self.write_set_store.save_write_set_batch(write_set_vec) + } } impl TransactionStore for Storage { diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index 75881063e4..e48231b3a4 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -41,6 +41,7 @@ fn to_table_item_write_set(table_item: &StateKey, value: Vec) -> WriteSet { ]).freeze().expect("freeze write_set must success.") } + #[test] fn test_put_and_save() { let tmpdir = starcoin_config::temp_dir(); @@ -55,21 +56,18 @@ fn test_put_and_save() { let write_set = to_write_set(access_path.clone(), state0.clone()); let hash = HashValue::random(); + // Check save storage .write_set_store - .save_write_set(hash, write_set) + .save_write_set(hash, write_set.clone()) .expect("Save write set failed"); - let after = storage .write_set_store .get_write_set(hash) .expect("{} Write set not exists!") .expect("{} Write set not exists!"); - assert!(!after.is_empty()); - let mut iter = after.into_iter(); - let (st_key, op) = iter.next().expect("Error"); assert_eq!(st_key, StateKey::AccessPath(access_path.clone())); assert_eq!(op, WriteOp::Value(state0)); @@ -77,6 +75,41 @@ fn test_put_and_save() { let (st_key, op) = iter.next().expect("Error"); assert_eq!(st_key, StateKey::AccessPath(access_path)); assert_eq!(op, WriteOp::Deletion); + + +} +#[test] +fn test_put_and_save_batch() { + let tmpdir = starcoin_config::temp_dir(); + let storage = Storage::new(StorageInstance::new_cache_and_db_instance( + CacheStorage::new(None), + DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), + )).unwrap(); + + let access_path = AccessPath::random_resource(); + let state0 = HashValue::random().to_vec(); + let write_set = to_write_set(access_path.clone(), state0.clone()); + let hash = HashValue::random(); + + let mut data_batch = Vec::new(); + data_batch.push((hash, write_set)); + + // Check save + storage.write_set_store + .save_write_set_batch(data_batch) + .expect("Save write set failed"); + let after = storage.write_set_store + .get_write_set(hash) + .expect("{} Write set not exists!") + .expect("{} Write set not exists!"); + assert!(!after.is_empty()); + let mut iter = after.into_iter(); + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, StateKey::AccessPath(access_path.clone())); + assert_eq!(op, WriteOp::Value(state0)); + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, StateKey::AccessPath(access_path)); + assert_eq!(op, WriteOp::Deletion); } #[test] @@ -115,3 +148,42 @@ fn test_put_and_save_table_item() { assert_eq!(st_key, table_item.clone()); assert_eq!(op, WriteOp::Deletion); } + +#[test] +fn test_put_and_save_table_item_batch() { + let tmpdir = starcoin_config::temp_dir(); + let storage = Storage::new(StorageInstance::new_cache_and_db_instance( + CacheStorage::new(None), + DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), + )) + .unwrap(); + + let table_item = StateKey::table_item(TableHandle(AccountAddress::random()), HashValue::random().to_vec()); + let table_item_val = HashValue::random().to_vec(); + let hash = HashValue::random(); + + let mut batch_data = Vec::new(); + batch_data.push((hash, to_table_item_write_set(&table_item, table_item_val.clone()))); + storage + .write_set_store + .save_write_set_batch(batch_data) + .expect("Save write set failed"); + + let after = storage + .write_set_store + .get_write_set(hash) + .expect("{} Write set not exists!") + .expect("{} Write set not exists!"); + + assert!(!after.is_empty()); + + let mut iter = after.into_iter(); + + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, table_item.clone()); + assert_eq!(op, WriteOp::Value(table_item_val.clone())); + + let (st_key, op) = iter.next().expect("Error"); + assert_eq!(st_key, table_item.clone()); + assert_eq!(op, WriteOp::Deletion); +} diff --git a/storage/src/write_set/mod.rs b/storage/src/write_set/mod.rs index 1b6c7ce53b..02b5865e15 100644 --- a/storage/src/write_set/mod.rs +++ b/storage/src/write_set/mod.rs @@ -1,7 +1,7 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::storage::{CodecKVStore, ValueCodec}; +use crate::storage::{CodecKVStore, CodecWriteBatch, ValueCodec}; use crate::{define_storage, WriteSetStore, WRITE_SET_PRIFIX_NAME}; use anyhow::Result; use bcs_ext::BCSCodec; @@ -28,4 +28,10 @@ impl WriteSetStore for WriteSetStorage { fn save_write_set(&self, hash: HashValue, write_set_vec: WriteSet) -> Result<()> { self.put(hash, write_set_vec) } + + fn save_write_set_batch(&self, write_set_vec: Vec<(HashValue, WriteSet)>) -> Result<()> { + let batch = + CodecWriteBatch::new_puts(write_set_vec.into_iter().map(|(hash, write_set)| (hash, write_set)).collect()); + self.write_batch(batch) + } } From a49efe112fd6682c6d892359636de35306e7ac16 Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 4 Aug 2023 17:12:25 +0800 Subject: [PATCH 13/14] [write_set] fix cargo clippy --- storage/src/tests/test_write_set.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index e48231b3a4..2c87252e0f 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -59,7 +59,7 @@ fn test_put_and_save() { // Check save storage .write_set_store - .save_write_set(hash, write_set.clone()) + .save_write_set(hash, write_set) .expect("Save write set failed"); let after = storage .write_set_store @@ -91,8 +91,7 @@ fn test_put_and_save_batch() { let write_set = to_write_set(access_path.clone(), state0.clone()); let hash = HashValue::random(); - let mut data_batch = Vec::new(); - data_batch.push((hash, write_set)); + let data_batch = vec![(hash, write_set)]; // Check save storage.write_set_store @@ -141,11 +140,11 @@ fn test_put_and_save_table_item() { let mut iter = after.into_iter(); let (st_key, op) = iter.next().expect("Error"); - assert_eq!(st_key, table_item.clone()); - assert_eq!(op, WriteOp::Value(table_item_val.clone())); + assert_eq!(st_key, table_item); + assert_eq!(op, WriteOp::Value(table_item_val)); let (st_key, op) = iter.next().expect("Error"); - assert_eq!(st_key, table_item.clone()); + assert_eq!(st_key, table_item); assert_eq!(op, WriteOp::Deletion); } @@ -162,8 +161,7 @@ fn test_put_and_save_table_item_batch() { let table_item_val = HashValue::random().to_vec(); let hash = HashValue::random(); - let mut batch_data = Vec::new(); - batch_data.push((hash, to_table_item_write_set(&table_item, table_item_val.clone()))); + let batch_data = vec![(hash, to_table_item_write_set(&table_item, table_item_val.clone()))]; storage .write_set_store .save_write_set_batch(batch_data) @@ -180,10 +178,10 @@ fn test_put_and_save_table_item_batch() { let mut iter = after.into_iter(); let (st_key, op) = iter.next().expect("Error"); - assert_eq!(st_key, table_item.clone()); - assert_eq!(op, WriteOp::Value(table_item_val.clone())); + assert_eq!(st_key, table_item); + assert_eq!(op, WriteOp::Value(table_item_val)); let (st_key, op) = iter.next().expect("Error"); - assert_eq!(st_key, table_item.clone()); + assert_eq!(st_key, table_item); assert_eq!(op, WriteOp::Deletion); } From 1b6e033596c7d905bdf6b1b6b46e9152dcb6aa8b Mon Sep 17 00:00:00 2001 From: welbon Date: Fri, 4 Aug 2023 17:13:30 +0800 Subject: [PATCH 14/14] [write_set] fix cargo fmt --- chain/src/chain.rs | 8 ++-- storage/src/tests/test_write_set.rs | 58 ++++++++++++++++------------- storage/src/write_set/mod.rs | 8 +++- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 863a5f245e..8e3d56b9b0 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -321,15 +321,15 @@ impl BlockChain { } pub fn verify_with_verifier(&mut self, block: Block) -> Result - where - V: BlockVerifier, + where + V: BlockVerifier, { V::verify_block(self, block) } pub fn apply_with_verifier(&mut self, block: Block) -> Result - where - V: BlockVerifier, + where + V: BlockVerifier, { let verified_block = self.verify_with_verifier::(block)?; watch(CHAIN_WATCH_NAME, "n1"); diff --git a/storage/src/tests/test_write_set.rs b/storage/src/tests/test_write_set.rs index 2c87252e0f..cf34b9bd7d 100644 --- a/storage/src/tests/test_write_set.rs +++ b/storage/src/tests/test_write_set.rs @@ -12,7 +12,7 @@ use starcoin_config::RocksdbConfig; use starcoin_crypto::HashValue; use starcoin_types::account_address::AccountAddress; use starcoin_vm_types::access_path::AccessPath; -use starcoin_vm_types::state_store::state_key::{StateKey}; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_store::table::TableHandle; use starcoin_vm_types::write_set::{WriteOp, WriteSet, WriteSetMut}; @@ -24,24 +24,19 @@ fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { ), (StateKey::AccessPath(access_path), WriteOp::Deletion), ]) - .freeze() - .expect("freeze write_set must success.") + .freeze() + .expect("freeze write_set must success.") } fn to_table_item_write_set(table_item: &StateKey, value: Vec) -> WriteSet { WriteSetMut::new(vec![ - ( - table_item.clone(), - WriteOp::Value(value), - ), - ( - table_item.clone(), - WriteOp::Deletion - ), - ]).freeze().expect("freeze write_set must success.") + (table_item.clone(), WriteOp::Value(value)), + (table_item.clone(), WriteOp::Deletion), + ]) + .freeze() + .expect("freeze write_set must success.") } - #[test] fn test_put_and_save() { let tmpdir = starcoin_config::temp_dir(); @@ -49,7 +44,7 @@ fn test_put_and_save() { CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), )) - .unwrap(); + .unwrap(); let access_path = AccessPath::random_resource(); let state0 = HashValue::random().to_vec(); @@ -75,8 +70,6 @@ fn test_put_and_save() { let (st_key, op) = iter.next().expect("Error"); assert_eq!(st_key, StateKey::AccessPath(access_path)); assert_eq!(op, WriteOp::Deletion); - - } #[test] fn test_put_and_save_batch() { @@ -84,7 +77,8 @@ fn test_put_and_save_batch() { let storage = Storage::new(StorageInstance::new_cache_and_db_instance( CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), - )).unwrap(); + )) + .unwrap(); let access_path = AccessPath::random_resource(); let state0 = HashValue::random().to_vec(); @@ -94,10 +88,12 @@ fn test_put_and_save_batch() { let data_batch = vec![(hash, write_set)]; // Check save - storage.write_set_store + storage + .write_set_store .save_write_set_batch(data_batch) .expect("Save write set failed"); - let after = storage.write_set_store + let after = storage + .write_set_store .get_write_set(hash) .expect("{} Write set not exists!") .expect("{} Write set not exists!"); @@ -118,15 +114,21 @@ fn test_put_and_save_table_item() { CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), )) - .unwrap(); + .unwrap(); - let table_item = StateKey::table_item(TableHandle(AccountAddress::random()), HashValue::random().to_vec()); + let table_item = StateKey::table_item( + TableHandle(AccountAddress::random()), + HashValue::random().to_vec(), + ); let table_item_val = HashValue::random().to_vec(); let hash = HashValue::random(); storage .write_set_store - .save_write_set(hash, to_table_item_write_set(&table_item, table_item_val.clone())) + .save_write_set( + hash, + to_table_item_write_set(&table_item, table_item_val.clone()), + ) .expect("Save write set failed"); let after = storage @@ -155,13 +157,19 @@ fn test_put_and_save_table_item_batch() { CacheStorage::new(None), DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None).unwrap(), )) - .unwrap(); + .unwrap(); - let table_item = StateKey::table_item(TableHandle(AccountAddress::random()), HashValue::random().to_vec()); + let table_item = StateKey::table_item( + TableHandle(AccountAddress::random()), + HashValue::random().to_vec(), + ); let table_item_val = HashValue::random().to_vec(); let hash = HashValue::random(); - let batch_data = vec![(hash, to_table_item_write_set(&table_item, table_item_val.clone()))]; + let batch_data = vec![( + hash, + to_table_item_write_set(&table_item, table_item_val.clone()), + )]; storage .write_set_store .save_write_set_batch(batch_data) diff --git a/storage/src/write_set/mod.rs b/storage/src/write_set/mod.rs index 02b5865e15..8f13298353 100644 --- a/storage/src/write_set/mod.rs +++ b/storage/src/write_set/mod.rs @@ -30,8 +30,12 @@ impl WriteSetStore for WriteSetStorage { } fn save_write_set_batch(&self, write_set_vec: Vec<(HashValue, WriteSet)>) -> Result<()> { - let batch = - CodecWriteBatch::new_puts(write_set_vec.into_iter().map(|(hash, write_set)| (hash, write_set)).collect()); + let batch = CodecWriteBatch::new_puts( + write_set_vec + .into_iter() + .map(|(hash, write_set)| (hash, write_set)) + .collect(), + ); self.write_batch(batch) } }