Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Feat tableinfo v2 (#3942)
* uncomment tableinfo-related codes

* save tableinfo in starcoindb

* add more comments

* refactor variable names and imports
  • Loading branch information
simonjiao committed Aug 21, 2023
1 parent dd5f1b8 commit 641a902
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 47 deletions.
5 changes: 4 additions & 1 deletion chain/open-block/src/lib.rs
Expand Up @@ -225,7 +225,10 @@ impl OpenedBlock {
txn_hash: HashValue,
output: TransactionOutput,
) -> Result<(HashValue, HashValue)> {
let (write_set, events, gas_used, status) = output.into_inner();
// Ignore the newly created table_infos.
// Because they are not needed to calculate state_root, or included to TransactionInfo.
// This auxiliary function is used to create a new block for mining, nothing need to be persisted to storage.
let (_table_infos, write_set, events, gas_used, status) = output.into_inner();
debug_assert!(matches!(status, TransactionStatus::Keep(_)));
let status = status
.status()
Expand Down
6 changes: 6 additions & 0 deletions chain/src/chain.rs
Expand Up @@ -463,6 +463,10 @@ impl BlockChain {
let block_id = block.id();
let txn_infos = executed_data.txn_infos;
let txn_events = executed_data.txn_events;
let txn_table_infos = executed_data
.txn_table_infos
.into_iter()
.collect::<Vec<_>>();

debug_assert!(
txn_events.len() == txn_infos.len(),
Expand Down Expand Up @@ -505,6 +509,8 @@ impl BlockChain {

storage.save_block_info(block_info.clone())?;

storage.save_table_infos(txn_table_infos)?;

watch(CHAIN_WATCH_NAME, "n26");
Ok(ExecutedBlock { block, block_info })
}
Expand Down
2 changes: 1 addition & 1 deletion executor/benchmark/src/lib.rs
Expand Up @@ -256,7 +256,7 @@ pub fn run_benchmark(
let chain_state = ChainStateDB::new(storage, None);
let net = ChainNetwork::new_test();
let genesis_txn = Genesis::build_genesis_transaction(&net).unwrap();
let _txn_info = Genesis::execute_genesis_txn(&chain_state, genesis_txn).unwrap();
let _ = Genesis::execute_genesis_txn(&chain_state, genesis_txn).unwrap();

let (block_sender, block_receiver) = mpsc::sync_channel(50 /* bound */);

Expand Down
8 changes: 7 additions & 1 deletion executor/src/block_executor.rs
Expand Up @@ -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::state_store::table::{TableHandle, TableInfo};
use std::collections::BTreeMap;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BlockExecutedData {
pub state_root: HashValue,
pub txn_infos: Vec<TransactionInfo>,
pub txn_events: Vec<Vec<ContractEvent>>,
pub txn_table_infos: BTreeMap<TableHandle, TableInfo>,
}

impl Default for BlockExecutedData {
Expand All @@ -23,6 +26,7 @@ impl Default for BlockExecutedData {
state_root: HashValue::zero(),
txn_events: vec![],
txn_infos: vec![],
txn_table_infos: BTreeMap::new(),
}
}
}
Expand All @@ -44,7 +48,7 @@ pub fn block_execute<S: ChainStateReader + ChainStateWriter>(
.zip(txn_outputs.into_iter())
{
let txn_hash = txn.id();
let (write_set, events, gas_used, status) = output.into_inner();
let (mut table_infos, write_set, events, gas_used, status) = output.into_inner();
match status {
TransactionStatus::Discard(status) => {
return Err(BlockExecutorError::BlockTransactionDiscard(
Expand All @@ -69,6 +73,8 @@ pub fn block_execute<S: ChainStateReader + ChainStateWriter>(
status,
));
executed_data.txn_events.push(events);
// Merge more table_infos, and keep the latest TableInfo for a same TableHandle
executed_data.txn_table_infos.append(&mut table_infos);
}
};
}
Expand Down
29 changes: 20 additions & 9 deletions genesis/src/lib.rs
Expand Up @@ -28,6 +28,7 @@ use starcoin_vm_types::transaction::{
RawUserTransaction, SignedUserTransaction, TransactionPayload,
};
use starcoin_vm_types::vm_status::KeptVMStatus;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::fs::{create_dir_all, File};
use std::io::{Read, Write};
Expand All @@ -36,6 +37,8 @@ use std::sync::Arc;

mod errors;
pub use errors::GenesisError;
use starcoin_storage::table_info::TableInfoStore;
use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
use starcoin_vm_types::state_view::StateView;

pub static G_GENESIS_GENERATED_DIR: &str = "generated";
Expand Down Expand Up @@ -113,7 +116,8 @@ impl Genesis {
let storage = Arc::new(Storage::new(StorageInstance::new_cache_instance())?);
let chain_state_db = ChainStateDB::new(storage.clone(), None);

let transaction_info = Self::execute_genesis_txn(&chain_state_db, txn.clone())?;
let (table_infos, transaction_info) =
Self::execute_genesis_txn(&chain_state_db, txn.clone())?;

let accumulator = MerkleAccumulator::new_with_info(
AccumulatorInfo::default(),
Expand All @@ -123,6 +127,10 @@ impl Genesis {

let accumulator_root = accumulator.append(vec![txn_info_hash].as_slice())?;
accumulator.flush()?;

// Persist newly created table_infos to storage
storage.save_table_infos(table_infos.into_iter().collect())?;

Ok(Block::genesis_block(
*parent_hash,
*timestamp,
Expand Down Expand Up @@ -177,14 +185,14 @@ impl Genesis {
pub fn execute_genesis_txn<S: ChainStateWriter + StateView>(
chain_state: &S,
txn: SignedUserTransaction,
) -> Result<TransactionInfo> {
) -> Result<(BTreeMap<TableHandle, TableInfo>, TransactionInfo)> {
let txn = Transaction::UserTransaction(txn);
let txn_hash = txn.id();

let output = starcoin_executor::execute_transactions(chain_state, vec![txn], None)?
.pop()
.expect("Execute output must exist.");
let (write_set, events, gas_used, status) = output.into_inner();
let (table_infos, write_set, events, gas_used, status) = output.into_inner();
assert_eq!(gas_used, 0, "Genesis txn output's gas_used must be zero");
let keep_status = status
.status()
Expand All @@ -197,12 +205,15 @@ impl Genesis {
chain_state.apply_write_set(write_set)?;
let state_root = chain_state.commit()?;
chain_state.flush()?;
Ok(TransactionInfo::new(
txn_hash,
state_root,
events.as_slice(),
gas_used,
keep_status,
Ok((
table_infos,
TransactionInfo::new(
txn_hash,
state_root,
events.as_slice(),
gas_used,
keep_status,
),
))
}

Expand Down
2 changes: 1 addition & 1 deletion rpc/api/src/types.rs
Expand Up @@ -1194,7 +1194,7 @@ pub struct TransactionOutputView {

impl From<TransactionOutput> for TransactionOutputView {
fn from(txn_output: TransactionOutput) -> Self {
let (write_set, events, gas_used, status) = txn_output.into_inner();
let (_, write_set, events, gas_used, status) = txn_output.into_inner();
let mut access_write_set = vec![];
let mut table_item_write_set = vec![];
for (state_key, op) in write_set {
Expand Down
19 changes: 9 additions & 10 deletions storage/src/lib.rs
Expand Up @@ -10,7 +10,7 @@ use crate::chain_info::ChainInfoStorage;
use crate::contract_event::ContractEventStorage;
use crate::state_node::StateStorage;
use crate::storage::{CodecKVStore, CodecWriteBatch, ColumnFamilyName, StorageInstance};
//use crate::table_info::{TableInfoStorage, TableInfoStore};
use crate::table_info::{TableInfoStorage, TableInfoStore};
use crate::transaction::TransactionStorage;
use crate::transaction_info::{TransactionInfoHashStorage, TransactionInfoStorage};
use anyhow::{bail, format_err, Error, Result};
Expand All @@ -29,6 +29,7 @@ use starcoin_types::{
startup_info::StartupInfo,
};
//use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
use std::collections::BTreeMap;
use std::fmt::{Debug, Display, Formatter};
use std::sync::Arc;
Expand Down Expand Up @@ -138,7 +139,7 @@ static VEC_PREFIX_NAME_V3: Lazy<Vec<ColumnFamilyName>> = Lazy::new(|| {
TRANSACTION_INFO_HASH_PREFIX_NAME,
CONTRACT_EVENT_PREFIX_NAME,
FAILED_BLOCK_PREFIX_NAME,
// TABLE_INFO_PREFIX_NAME,
TABLE_INFO_PREFIX_NAME,
]
});
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, IntoPrimitive, TryFromPrimitive)]
Expand Down Expand Up @@ -274,7 +275,7 @@ pub struct Storage {
block_info_storage: BlockInfoStorage,
event_storage: ContractEventStorage,
chain_info_storage: ChainInfoStorage,
// table_info_storage: TableInfoStorage,
table_info_storage: TableInfoStorage,
// instance: StorageInstance,
}

Expand All @@ -293,8 +294,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),
// table_info_storage: TableInfoStorage::new(instance),
chain_info_storage: ChainInfoStorage::new(instance.clone()),
table_info_storage: TableInfoStorage::new(instance),
// instance,
};
Ok(storage)
Expand Down Expand Up @@ -573,6 +574,7 @@ pub trait Store:
+ BlockTransactionInfoStore
+ ContractEventStore
+ IntoSuper<dyn StateNodeStore>
+ TableInfoStore
{
fn get_transaction_info_by_block_and_index(
&self,
Expand Down Expand Up @@ -649,8 +651,6 @@ impl Store for Storage {
}
}

/*
XXX FIXME YSG temp comment
impl TableInfoStore for Storage {
fn get_table_info(&self, key: TableHandle) -> Result<Option<TableInfo>> {
self.table_info_storage.get(key)
Expand All @@ -664,9 +664,8 @@ impl TableInfoStore for Storage {
self.table_info_storage.multiple_get(keys)
}

fn save_table_infos(&self, keys: Vec<TableHandle>, table_infos: Vec<TableInfo>) -> Result<()> {
let batch = CodecWriteBatch::new_puts(keys.into_iter().zip(table_infos).collect());
fn save_table_infos(&self, table_infos: Vec<(TableHandle, TableInfo)>) -> Result<()> {
let batch = CodecWriteBatch::new_puts(table_infos);
self.table_info_storage.write_batch(batch)
}
}
*/
6 changes: 3 additions & 3 deletions storage/src/table_info/mod.rs
Expand Up @@ -18,7 +18,7 @@ pub trait TableInfoStore {
fn get_table_info(&self, key: TableHandle) -> Result<Option<TableInfo>>;
fn save_table_info(&self, key: TableHandle, table_info: TableInfo) -> Result<()>;
fn get_table_infos(&self, keys: Vec<TableHandle>) -> Result<Vec<Option<TableInfo>>>;
fn save_table_infos(&self, keys: Vec<TableHandle>, table_infos: Vec<TableInfo>) -> Result<()>;
fn save_table_infos(&self, table_infos: Vec<(TableHandle, TableInfo)>) -> Result<()>;
}

impl ValueCodec for TableHandle {
Expand Down Expand Up @@ -54,8 +54,8 @@ impl TableInfoStore for TableInfoStorage {
self.multiple_get(keys)
}

fn save_table_infos(&self, keys: Vec<TableHandle>, table_infos: Vec<TableInfo>) -> Result<()> {
let batch = CodecWriteBatch::new_puts(keys.into_iter().zip(table_infos).collect());
fn save_table_infos(&self, table_infos: Vec<(TableHandle, TableInfo)>) -> Result<()> {
let batch = CodecWriteBatch::new_puts(table_infos);
self.write_batch(batch)
}
}
27 changes: 15 additions & 12 deletions storage/src/tests/test_storage.rs
Expand Up @@ -6,6 +6,7 @@ extern crate chrono;
use crate::cache_storage::CacheStorage;
use crate::db_storage::DBStorage;
use crate::storage::{CodecKVStore, InnerStore, StorageInstance, ValueCodec};
use crate::table_info::TableInfoStore;
use crate::transaction_info::{BlockTransactionInfo, OldTransactionInfoStorage};
use crate::{
BlockInfoStore, BlockStore, BlockTransactionInfoStore, Storage,
Expand All @@ -17,15 +18,15 @@ use anyhow::Result;
use starcoin_accumulator::accumulator_info::AccumulatorInfo;
use starcoin_config::RocksdbConfig;
use starcoin_crypto::HashValue;
use starcoin_types::block::{Block, BlockBody, BlockHeader, BlockInfo};
//use starcoin_types::language_storage::TypeTag;
use starcoin_types::startup_info::SnapshotRange;
use starcoin_types::transaction::{
RichTransactionInfo, SignedUserTransaction, Transaction, TransactionInfo,
use starcoin_types::{
account_address::AccountAddress,
block::{Block, BlockBody, BlockHeader, BlockInfo},
language_storage::TypeTag,
startup_info::SnapshotRange,
transaction::{RichTransactionInfo, SignedUserTransaction, Transaction, TransactionInfo},
vm_error::KeptVMStatus,
};
use starcoin_types::vm_error::KeptVMStatus;
//use starcoin_vm_types::account_address::AccountAddress;
//use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
use std::path::Path;

#[test]
Expand Down Expand Up @@ -475,8 +476,6 @@ pub fn test_cache_evict_multi_get() -> Result<()> {
Ok(())
}

/*
XXX FIXME YSG temp comment
#[test]
fn test_table_info_storage() -> Result<()> {
let tmpdir = starcoin_config::temp_dir();
Expand All @@ -503,7 +502,12 @@ fn test_table_info_storage() -> Result<()> {
TableInfo::new(TypeTag::U8, TypeTag::Address),
TableInfo::new(TypeTag::Address, TypeTag::U128),
];
storage.save_table_infos(keys.clone(), vals.clone())?;
let table_infos = keys
.clone()
.into_iter()
.zip(vals.clone())
.collect::<Vec<_>>();
storage.save_table_infos(table_infos)?;
let vals2 = storage.get_table_infos(keys);
assert!(vals2.is_ok());
let vals2 = vals2
Expand All @@ -514,4 +518,3 @@ fn test_table_info_storage() -> Result<()> {
assert_eq!(vals, vals2);
Ok(())
}
*/
2 changes: 1 addition & 1 deletion vm/starcoin-transactional-test-harness/src/fork_chain.rs
Expand Up @@ -143,7 +143,7 @@ impl ForkBlockChain {
pub fn add_new_txn(&mut self, txn: Transaction, output: TransactionOutput) -> Result<()> {
let txn_hash = txn.id();
let state_root = *self.state_root.lock().unwrap();
let (_, events, gas_used, status) = output.into_inner();
let (_, _, events, gas_used, status) = output.into_inner();
let status = status
.status()
.expect("TransactionStatus at here must been KeptVMStatus");
Expand Down
4 changes: 2 additions & 2 deletions vm/starcoin-transactional-test-harness/src/lib.rs
Expand Up @@ -646,7 +646,7 @@ impl<'a> StarcoinTestAdapter<'a> {
TransactionStatus::Keep(kept_vm_status) => match kept_vm_status {
KeptVMStatus::Executed => {
self.context
.apply_write_set(output.clone().into_inner().0)?;
.apply_write_set(output.clone().into_inner().1)?;
}
_ => {
bail!("Failed to execute transaction. VMStatus: {}", status)
Expand Down Expand Up @@ -681,7 +681,7 @@ impl<'a> StarcoinTestAdapter<'a> {
match output.status() {
TransactionStatus::Keep(_kept_vm_status) => {
self.context
.apply_write_set(output.clone().into_inner().0)?;
.apply_write_set(output.clone().into_inner().1)?;
let mut chain = self.context.chain.lock().unwrap();
chain.add_new_txn(
Transaction::UserTransaction(signed_txn.clone()),
Expand Down

0 comments on commit 641a902

Please sign in to comment.