Skip to content

Commit

Permalink
refactor: stop copying dirty StateDB state, so we can remove immutabl…
Browse files Browse the repository at this point in the history
…e structures
  • Loading branch information
jjyr committed Nov 2, 2022
1 parent 9b089e4 commit 6028580
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 23 deletions.
2 changes: 1 addition & 1 deletion crates/generator/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ impl Generator {
}
let r = RunResult {
return_data: run_context.return_data,
logs: state.appended_logs().into_iter().cloned().collect(),
logs: state.appended_logs().to_vec(),
exit_code: run_context.exit_code,
cycles: run_context.cycle_meter,
read_data_hashes: state_tracker
Expand Down
50 changes: 30 additions & 20 deletions crates/store/src/state/state_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ impl JournalEntry {
}
AppendLog { index } => {
assert_eq!(state_db.dirty_logs.len(), index + 1);
state_db.dirty_logs.pop_back();
state_db.dirty_logs.pop();
}
}
}
}

#[derive(Debug, Default, Clone)]
pub struct Journal {
entries: im::Vector<JournalEntry>,
entries: Vec<JournalEntry>,
}

impl Journal {
Expand All @@ -97,12 +97,12 @@ impl Journal {

/// Revert journal to len
/// Return reverted entries sorted in journal emit order
pub fn revert_entries(&mut self, len: usize) -> im::Vector<JournalEntry> {
self.entries.slice(len..)
pub fn revert_entries(&mut self, len: usize) -> Vec<JournalEntry> {
self.entries.split_off(len)
}

pub fn push(&mut self, entry: JournalEntry) {
self.entries.push_back(entry);
self.entries.push(entry);
}

pub fn clear(&mut self) {
Expand Down Expand Up @@ -151,25 +151,34 @@ pub struct StateDB<S> {
/// next_revision_id
next_revision_id: usize,
/// revisions
revisions: im::Vector<Revision>,
revisions: Vec<Revision>,
/// dirty state in memory
dirty_state: im::HashMap<H256, H256>,
dirty_state: HashMap<H256, H256>,
/// dirty account count
dirty_account_count: Option<u32>,
/// dirty scripts
dirty_scripts: im::HashMap<H256, packed::Script>,
dirty_scripts: HashMap<H256, packed::Script>,
/// dirty data
dirty_data: im::HashMap<H256, Bytes>,
dirty_data: HashMap<H256, Bytes>,
/// dirty logs
dirty_logs: im::Vector<LogItem>,
dirty_logs: Vec<LogItem>,
/// state tracker
state_tracker: Option<StateTracker>,
/// last state root
last_state_root: H256,
}

impl<S: Clone> Clone for StateDB<S> {
impl<S: Clone + State + CodeStore> Clone for StateDB<S> {
/// clone StateDB without dirty state
fn clone(&self) -> Self {
Self::new(self.state.clone())
}
}

#[cfg(test)]
impl<S: State + CodeStore + Clone> StateDB<S> {
/// clone StateDB with dirty state
pub(crate) fn clone_dirty(&self) -> Self {
Self {
state: self.state.clone(),
journal: self.journal.clone(),
Expand Down Expand Up @@ -225,6 +234,7 @@ impl<Store: ChainStore + HistoryStateStore + CodeStore + KVStore> BlockStateDB<S

impl<S: State + CodeStore> StateDB<S> {
pub fn new(state: S) -> Self {
let last_state_root = state.calculate_root().expect("last state root");
Self {
state,
journal: Journal::default(),
Expand All @@ -236,7 +246,7 @@ impl<S: State + CodeStore> StateDB<S> {
dirty_scripts: Default::default(),
dirty_logs: Default::default(),
state_tracker: None,
last_state_root: H256::default(),
last_state_root,
}
}

Expand Down Expand Up @@ -325,7 +335,7 @@ impl<S: State + CodeStore> JournalDB for StateDB<S> {
fn snapshot(&mut self) -> usize {
let id = self.next_revision_id;
self.next_revision_id += 1;
self.revisions.push_back(Revision {
self.revisions.push(Revision {
id,
journal_len: self.journal.len(),
});
Expand Down Expand Up @@ -386,10 +396,10 @@ impl<S: State + CodeStore> JournalDB for StateDB<S> {
self.journal.push(JournalEntry::AppendLog {
index: self.dirty_logs.len(),
});
self.dirty_logs.push_back(log);
self.dirty_logs.push(log);
}

fn appended_logs(&self) -> &im::Vector<packed::LogItem> {
fn appended_logs(&self) -> &[packed::LogItem] {
&self.dirty_logs
}

Expand Down Expand Up @@ -561,22 +571,22 @@ mod tests {
fn test_revert_to_histories_revision() {
let store = Store::open_tmp().unwrap();
let mut state = new_state(store.get_snapshot());
let mem_0 = state.clone();
let mem_0 = state.clone_dirty();
let snap_0 = state.snapshot();
state
.update_raw(H256::from_u32(1), H256::from_u32(1))
.unwrap();
state
.update_raw(H256::from_u32(2), H256::from_u32(2))
.unwrap();
let mem_1 = state.clone();
let mem_1 = state.clone_dirty();
let snap_1 = state.snapshot();

// should update the mem DB
state
.update_raw(H256::from_u32(3), H256::from_u32(3))
.unwrap();
let mem_2 = state.clone();
let mem_2 = state.clone_dirty();
assert!(!cmp_dirty_state(&mem_1, &mem_2));

// revert to snap_1
Expand All @@ -592,7 +602,7 @@ mod tests {
fn test_clear_dirty_state() {
let store = Store::open_tmp().unwrap();
let mut state = new_state(store.get_snapshot());
let mem_0 = state.clone();
let mem_0 = state.clone_dirty();
assert!(!state.is_dirty());
state
.update_raw(H256::from_u32(1), H256::from_u32(1))
Expand Down Expand Up @@ -620,7 +630,7 @@ mod tests {
state
.update_raw(H256::from_u32(2), H256::from_u32(2))
.unwrap();
let mem_1 = state.clone();
let mem_1 = state.clone_dirty();
assert!(state.is_dirty());

// finalise
Expand Down
2 changes: 1 addition & 1 deletion crates/store/src/state/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub trait SMTTree<S> {
pub trait JournalDB {
fn snapshot(&mut self) -> usize;
fn revert(&mut self, id: usize) -> Result<(), gw_common::error::Error>;
fn appended_logs(&self) -> &im::Vector<LogItem>;
fn appended_logs(&self) -> &[LogItem];
fn append_log(&mut self, log: LogItem);
fn finalise(&mut self) -> Result<(), gw_common::error::Error>;
fn set_state_tracker(&mut self, tracker: StateTracker);
Expand Down
2 changes: 2 additions & 0 deletions crates/tests/src/tests/meta_contract_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use gw_common::{
state::State,
};
use gw_generator::account_lock_manage::secp256k1::Secp256k1Eth;
use gw_store::state::traits::JournalDB;
use gw_types::{
packed::{
CreateAccount, DeprecatedMetaContractArgs, Fee, L2Transaction, RawL2Transaction, Script,
Expand Down Expand Up @@ -73,6 +74,7 @@ async fn test_backward_compatibility() {
.signature(sign.pack())
.build();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
{
let mut mem_pool = chain.mem_pool().await;
Expand Down
2 changes: 2 additions & 0 deletions crates/tests/src/tests/polyjuice_sender_recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use gw_polyjuice_sender_recover::recover::{
eth_account_creator::EthAccountCreator, eth_recover::EthAccountContext,
eth_sender::PolyjuiceTxEthSender,
};
use gw_store::state::traits::JournalDB;
use gw_types::{
packed::{RawL2Transaction, Script},
prelude::Pack,
Expand Down Expand Up @@ -87,6 +88,7 @@ async fn test_eth_account_creator() {
.build_batch_create_tx(&state, recovered_account_scripts)
.unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
{
let mut mem_pool = chain.mem_pool().await;
Expand Down
9 changes: 9 additions & 0 deletions crates/tests/src/tests/rpc_server/execute_l2transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use gw_common::{
state::State, H256,
};
use gw_polyjuice_sender_recover::recover::error::PolyjuiceTxSenderRecoverError;
use gw_store::state::traits::JournalDB;
use gw_types::{
bytes::Bytes,
packed::{RawL2Transaction, Script},
Expand Down Expand Up @@ -58,6 +59,7 @@ async fn test_polyjuice_erc20_tx() {
.build();
let deploy_tx = test_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let run_result = rpc_server.execute_l2transaction(&deploy_tx).await.unwrap();

Expand Down Expand Up @@ -111,6 +113,7 @@ async fn test_polyjuice_tx_from_id_zero() {
let deploy_tx = deployer_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();
let deploy_tx_hash: H256 = deploy_tx.hash().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
{
let mut mem_pool = chain.mem_pool().await;
Expand Down Expand Up @@ -159,6 +162,7 @@ async fn test_polyjuice_tx_from_id_zero() {
.build();
let balance_tx = test_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let run_result = rpc_server.execute_l2transaction(&balance_tx).await.unwrap();

Expand Down Expand Up @@ -209,6 +213,7 @@ async fn test_invalid_polyjuice_tx_from_id_zero() {
.unwrap();
let deploy_tx_hash: H256 = deploy_tx.hash().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
{
let mut mem_pool = chain.mem_pool().await;
Expand Down Expand Up @@ -300,6 +305,8 @@ async fn test_invalid_polyjuice_tx_from_id_zero() {

let balance = 100u32.into();
test_wallet.mint_ckb_sudt(&mut state, balance).unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);

let err = rpc_server
Expand All @@ -316,6 +323,8 @@ async fn test_invalid_polyjuice_tx_from_id_zero() {
state
.mapping_registry_address_to_script_hash(test_wallet.reg_address().to_owned(), H256::one())
.unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);

let err = rpc_server
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use ckb_types::prelude::{Builder, Entity};
use gw_common::{builtins::CKB_SUDT_ACCOUNT_ID, registry_address::RegistryAddress};
use gw_config::{MemBlockConfig, MemPoolConfig};
use gw_store::state::traits::JournalDB;
use gw_types::{
bytes::Bytes,
packed::{RawL2Transaction, Script},
Expand Down Expand Up @@ -70,6 +71,7 @@ async fn test_block_max_cycles_limit() {
.build();
let deploy_tx = test_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let run_result = rpc_server.execute_l2transaction(&deploy_tx).await.unwrap();

Expand Down Expand Up @@ -120,6 +122,7 @@ async fn test_block_max_cycles_limit() {
.build();
let deploy_tx = test_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let err = rpc_server
.execute_l2transaction(&deploy_tx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use gw_common::{
H256,
};
use gw_generator::account_lock_manage::secp256k1::Secp256k1Eth;
use gw_store::state::{history::history_state::RWConfig, BlockStateDB};
use gw_store::state::{history::history_state::RWConfig, traits::JournalDB, BlockStateDB};
use gw_types::{
bytes::Bytes,
packed::{
Expand Down Expand Up @@ -65,6 +65,8 @@ async fn test_polyjuice_erc20_tx() {
.build();

let reg_addr_bytes = test_wallet.reg_address().to_bytes().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);

let run_result = rpc_server
Expand Down Expand Up @@ -122,6 +124,7 @@ async fn test_polyjuice_tx_from_id_zero() {
let deploy_tx = deployer_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();
let deploy_tx_hash: H256 = deploy_tx.hash().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
{
let mut mem_pool = chain.mem_pool().await;
Expand Down Expand Up @@ -162,6 +165,7 @@ async fn test_polyjuice_tx_from_id_zero() {
.mint_sudt(&mut state, CKB_SUDT_ACCOUNT_ID, test_balance)
.unwrap();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let state = mem_pool_state.load_state_db();

Expand Down Expand Up @@ -486,6 +490,7 @@ async fn test_invalid_registry_address() {
let deploy_tx = deployer_wallet.sign_polyjuice_tx(&state, raw_tx).unwrap();
let deploy_tx_hash: H256 = deploy_tx.hash().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
{
let mut mem_pool = chain.mem_pool().await;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use ckb_types::prelude::{Builder, Entity};
use gw_common::{builtins::CKB_SUDT_ACCOUNT_ID, registry_address::RegistryAddress};
use gw_config::{MemBlockConfig, MemPoolConfig};
use gw_store::state::traits::JournalDB;
use gw_types::{
bytes::Bytes,
packed::{RawL2Transaction, Script},
Expand Down Expand Up @@ -70,6 +71,7 @@ async fn test_block_max_cycles_limit() {
.build();
let reg_addr_bytes = test_wallet.reg_address().to_bytes().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let run_result = rpc_server
.execute_raw_l2transaction(&raw_tx, None, Some(reg_addr_bytes))
Expand Down Expand Up @@ -123,6 +125,7 @@ async fn test_block_max_cycles_limit() {
.build();
let reg_addr_bytes = test_wallet.reg_address().to_bytes().into();

state.finalise().unwrap();
mem_pool_state.store_state_db(state);
let err = rpc_server
.execute_raw_l2transaction(&raw_tx, None, Some(reg_addr_bytes))
Expand Down
Loading

0 comments on commit 6028580

Please sign in to comment.