From d26783b49fb3560d63f00cc07c11e3784edd8581 Mon Sep 17 00:00:00 2001 From: Renato Dinhani Date: Wed, 21 Feb 2024 20:58:38 -0300 Subject: [PATCH] refactor: organize StratusStorage methods by context --- src/bin/importer/importer-import.rs | 2 +- src/config.rs | 2 +- src/eth/executor.rs | 10 ++-- src/eth/storage/stratus_storage.rs | 73 +++++++++++++++-------------- tests/test_execution.rs | 2 +- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/bin/importer/importer-import.rs b/src/bin/importer/importer-import.rs index 4fa301e58..d6140ce79 100644 --- a/src/bin/importer/importer-import.rs +++ b/src/bin/importer/importer-import.rs @@ -31,7 +31,7 @@ async fn main() -> anyhow::Result<()> { .into_iter() .map(|row| Account::new_with_balance(row.address, row.balance)) .collect_vec(); - storage.save_accounts(accounts).await?; + storage.save_accounts_to_perm(accounts).await?; // process blocks let mut tx = db_init_blocks_cursor(&pg).await?; diff --git a/src/config.rs b/src/config.rs index 812ef67b6..fa84ce9b4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -124,7 +124,7 @@ impl CommonConfig { if self.env.is_production() { tracing::warn!("cannot enable test accounts in production environment"); } else { - storage.save_accounts(test_accounts()).await?; + storage.save_accounts_to_perm(test_accounts()).await?; } } Ok(storage) diff --git a/src/eth/executor.rs b/src/eth/executor.rs index c350b7c76..01b25e0ad 100644 --- a/src/eth/executor.rs +++ b/src/eth/executor.rs @@ -102,7 +102,7 @@ impl EthExecutor { }; // temporarily save state to next transactions from the same block - self.storage.save_account_changes(block.number(), execution.clone()).await?; + self.storage.save_account_changes_to_temp(block.number(), execution.clone()).await?; executions.push((tx, receipt, execution)); } Err(e) => { @@ -116,7 +116,7 @@ impl EthExecutor { let block = Block::from_external(block, executions)?; self.storage.increment_block_number().await?; - if let Err(e) = self.storage.commit(block.clone()).await { + if let Err(e) = self.storage.commit_to_perm(block.clone()).await { let json_block = serde_json::to_string(&block).unwrap(); tracing::error!(reason = ?e, %json_block); return Err(e.into()); @@ -145,7 +145,7 @@ impl EthExecutor { let block = self.miner.lock().await.mine_with_one_transaction(transaction_input, execution).await?; - self.storage.commit(block).await?; + self.storage.commit_to_perm(block).await?; } //TODO compare slots/changes @@ -191,7 +191,7 @@ impl EthExecutor { pub async fn mine_empty_block(&self) -> anyhow::Result<()> { let mut miner_lock = self.miner.lock().await; let block = miner_lock.mine_with_no_transactions().await?; - self.storage.commit(block.clone()).await?; + self.storage.commit_to_perm(block.clone()).await?; if let Err(e) = self.block_notifier.send(block.clone()) { tracing::error!(reason = ?e, "failed to send block notification"); @@ -215,7 +215,7 @@ impl EthExecutor { // mine and commit block let mut miner_lock = self.miner.lock().await; let block = miner_lock.mine_with_one_transaction(transaction.clone(), execution.clone()).await?; - match self.storage.commit(block.clone()).await { + match self.storage.commit_to_perm(block.clone()).await { Ok(()) => {} Err(EthStorageError::Conflict(conflicts)) => { tracing::warn!(?conflicts, "storage conflict detected when saving block"); diff --git a/src/eth/storage/stratus_storage.rs b/src/eth/storage/stratus_storage.rs index f9157b64a..51e0dd322 100644 --- a/src/eth/storage/stratus_storage.rs +++ b/src/eth/storage/stratus_storage.rs @@ -53,18 +53,18 @@ impl StratusStorage { result } - /// Retrieves a block from the storage. - pub async fn read_block(&self, block_selection: &BlockSelection) -> anyhow::Result> { + // ------------------------------------------------------------------------- + // State queries + // ------------------------------------------------------------------------- + + /// Checks if the transaction execution conflicts with the current storage state. + pub async fn check_conflicts(&self, execution: &Execution) -> anyhow::Result> { let start = Instant::now(); - let result = self.perm.read_block(block_selection).await; - metrics::inc_storage_read_block(start.elapsed(), result.is_ok()); + let result = TemporaryStorage::check_conflicts(self.temp.deref(), execution).await; + metrics::inc_storage_check_conflicts(start.elapsed(), result.as_ref().is_ok_and(|v| v.is_some()), result.is_ok()); result } - // ------------------------------------------------------------------------- - // State operations - // ------------------------------------------------------------------------- - /// Retrieves an account from the storage. Returns default value when not found. pub async fn read_account(&self, address: &Address, point_in_time: &StoragePointInTime) -> anyhow::Result { let start = Instant::now(); @@ -99,33 +99,11 @@ impl StratusStorage { result } - /// Commits changes to permanent storage and flushes temporary storage - /// Basically calls the `save_block` method from the permanent storage, which - /// will by definition update accounts, slots, transactions, logs etc - pub async fn commit(&self, block: Block) -> anyhow::Result<(), EthStorageError> { - let start = Instant::now(); - - // save block in permanent storage and resets temporary storage - let result = self.perm.save_block(block).await; - self.reset_temp().await?; - - metrics::inc_storage_commit(start.elapsed(), result.is_ok()); - result - } - - /// Checks if the transaction execution conflicts with the current storage state. - pub async fn check_conflicts(&self, execution: &Execution) -> anyhow::Result> { - let start = Instant::now(); - let result = TemporaryStorage::check_conflicts(self.temp.deref(), execution).await; - metrics::inc_storage_check_conflicts(start.elapsed(), result.as_ref().is_ok_and(|v| v.is_some()), result.is_ok()); - result - } - - /// Temporarily stores account changes during block production - pub async fn save_account_changes(&self, block_number: BlockNumber, execution: Execution) -> anyhow::Result<()> { + /// Retrieves a block from the storage. + pub async fn read_block(&self, block_selection: &BlockSelection) -> anyhow::Result> { let start = Instant::now(); - let result = self.temp.save_account_changes(block_number, execution).await; - metrics::inc_storage_save_account_changes(start.elapsed(), result.is_ok()); + let result = self.perm.read_block(block_selection).await; + metrics::inc_storage_read_block(start.elapsed(), result.is_ok()); result } @@ -145,14 +123,37 @@ impl StratusStorage { result } - /// Enables pre-genesis accounts - pub async fn save_accounts(&self, accounts: Vec) -> anyhow::Result<()> { + // ------------------------------------------------------------------------- + // State mutations + // ------------------------------------------------------------------------- + + /// Persist accounts like pre-genesis accounts or test accounts. + pub async fn save_accounts_to_perm(&self, accounts: Vec) -> anyhow::Result<()> { let start = Instant::now(); let result = self.perm.save_accounts(accounts).await; metrics::inc_storage_save_accounts(start.elapsed(), result.is_ok()); result } + /// Persists temporary accounts changes produced during block production. + pub async fn save_account_changes_to_temp(&self, block_number: BlockNumber, execution: Execution) -> anyhow::Result<()> { + let start = Instant::now(); + let result = self.temp.save_account_changes(block_number, execution).await; + metrics::inc_storage_save_account_changes(start.elapsed(), result.is_ok()); + result + } + + /// Commits changes to permanent storage and prepares temporary storage to a new block to be produced. + pub async fn commit_to_perm(&self, block: Block) -> anyhow::Result<(), EthStorageError> { + let start = Instant::now(); + + let result = self.perm.save_block(block).await; + self.reset_temp().await?; + + metrics::inc_storage_commit(start.elapsed(), result.is_ok()); + result + } + /// Resets temporary storage pub async fn reset_temp(&self) -> anyhow::Result<()> { let start = Instant::now(); diff --git a/tests/test_execution.rs b/tests/test_execution.rs index 2871d6b45..04fe051f9 100644 --- a/tests/test_execution.rs +++ b/tests/test_execution.rs @@ -27,7 +27,7 @@ mod tests { fake_transaction_input.gas_limit = 0.into(); let accounts = test_accounts(); - storage.save_accounts(accounts.clone()).await.unwrap(); + storage.save_accounts_to_perm(accounts.clone()).await.unwrap(); let address = accounts.last().unwrap().address.clone(); fake_transaction_input.from = address;