Skip to content

Test tinyufo - #2649

Draft
carneiro-cw wants to merge 17 commits into
mainfrom
test_tinyufo
Draft

Test tinyufo#2649
carneiro-cw wants to merge 17 commits into
mainfrom
test_tinyufo

Conversation

@carneiro-cw

@carneiro-cw carneiro-cw commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

PR Type

Enhancement


Description

  • Introduce generic State<S> replacing Changes

  • Simplify cache: remove pending cache, use TinyUfo for latest

  • Refactor storage APIs to accept State<Complete>/State<Final>

  • Update EVM and miner to pass state with transactions


Diagram Walkthrough

flowchart LR
  ExecInput["TransactionExecution Input"]
  Proc["Extract State<Complete>"]
  Temp["TemporaryStorage (State<Complete>)"]
  Pending["finish_pending_block → State<Complete>"]
  Perm["PermanentStorage (State<Final>)"]
  ExecInput -- "execute" --> Proc
  Proc -- "save_execution(tx, state)" --> Temp
  Temp -- "finish_pending_block()" --> Pending
  Pending -- "save_block(block, state.finalize())" --> Perm
Loading

File Walkthrough

Relevant files
Enhancement
16 files
stratus_storage.rs
Remove pending cache & adapt read/cache logic                       
+62/-114
values.rs
Define `Change` trait & remove old `Changes`                         
+109/-153
cache.rs
Replace quick_cache with `TinyUfo` and versioning               
+60/-113
transaction_execution.rs
Add `state: State` to execution output                 
+51/-46 
mod.rs
Propagate state through executor and miner calls                 
+33/-38 
transaction.rs
Store `State` in temp transaction storage           
+31/-27 
rocks_state.rs
Accept `State` & update batch insertion                     
+25/-39 
mod.rs
Introduce generic `State` and `Stage` markers                 
+194/-0 
miner.rs
Change `save_execution` signature with state                         
+18/-27 
mod.rs
Unify call and transaction storage, use `State`                   
+13/-31 
transaction_mined.rs
Persist `TransactionExecutionResult` & state                         
+19/-21 
transaction_mined.rs
Use `input` instead of `evm_input` fields                               
+4/-4     
block.rs
Update transaction input references in block                         
+3/-3     
block_changes.rs
Map `AccountChanges` into RocksDB changes                 
+14/-0   
account.rs
Add `update` method for `AccountChanges`                   
+19/-0   
events.rs
Use `tx.input` instead of `tx.evm_input` in events             
+12/-12 
Additional files
25 files
Cargo.toml +2/-1     
mod.rs +5/-5     
session.rs +11/-0   
call_execution.rs +0/-15   
mod.rs +1/-0     
call_execution.rs +4/-0     
util.rs +4/-4     
mod.rs +2/-9     
transaction_execution.rs +16/-16 
block_with_changes.rs +3/-3     
fake_leader.rs +9/-29   
replication.rs +3/-3     
mod.rs +13/-13 
server.rs +1/-2     
log_filter_input.rs +1/-1     
mod.rs +0/-1     
rocks_permanent.rs +4/-3     
resolve_pending.rs +17/-86 
call.rs +0/-127 
pending_block_header.rs +1/-1     
execution_kind.rs +0/-58   
mod.rs +0/-1     
unix_time_now.rs +1/-1     
transaction_stage.rs +4/-4     
metrics_definitions.rs +1/-1     

@github-actions

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 5 🔵🔵🔵🔵🔵
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Cache Ordering

In save_block, the latest cache is populated before persisting the block to permanent storage. If perm.save_block fails, the cache may reflect uncommitted state, leading to inconsistency between the in‐memory cache and the durable store.

timed(|| {
    let guard = self.transient_state_lock.write();
    self.cache.cache_account_and_slots_latest_from_changes(&changes);
    self.perm.save_block(block, changes.finalize())?;
    drop(guard);
    Ok(())
})
Unconditional Account Insertion

In prepare_batch_with_execution_changes, every account in State<Final> is now inserted into the batch even if no fields changed. The previous change.is_modified() check was removed, resulting in unnecessary writes and bloated block_changes entries.

/// Updates the in-memory state with changes from transaction execution
fn prepare_batch_with_execution_changes(&self, changes: State<Final>, block_number: BlockNumber, batch: &mut WriteBatch) -> Result<()> {
    let mut block_changes = BlockChangesRocksdb::with_capacity(changes.accounts.len());
    let block_number = block_number.into();

    for (address, change) in changes.accounts {
        let address_rocks: AddressRocksdb = address.into();
        let account_change_entry = (&change).into();
        let account_info_entry: CfAccountsValue = match self.accounts.get(&address_rocks)? {
            Some(existing_account) => existing_account.into_inner().update(change).into(),
            None => change.to_account(address).into(),
        };

        self.accounts.prepare_batch_insertion([(address_rocks, account_info_entry.clone())], batch)?;
        self.accounts_history
            .prepare_batch_insertion([((address_rocks, block_number), account_info_entry.into_inner().into())], batch)?;
        block_changes.account_changes.insert(address_rocks, account_change_entry);
    }

@github-actions

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Return correct U256 default

The storage_ref function is defined to return a Result<U256, Self::Error> but is
currently returning a Uint, causing a type mismatch. Replace Uint::default() with
U256::default() (or U256::zero()) to return the correct type and remove the unused
Uint import if it's no longer needed.

src/eth/executor/evm/session.rs [90-92]

 if address.is_ignored() {
-    return Ok(Uint::default());
+    return Ok(U256::default());
 }
Suggestion importance[1-10]: 9

__

Why: The function signature returns Result<U256, _> but the code returns a Uint, causing a type mismatch; using U256::default() resolves the compilation error and aligns with the expected return type.

High
General
Clear cache after finishing block

To avoid serving stale cache entries after finalizing the pending block, clear the
in-memory caches when a block finishes. This ensures new reads reflect the updated
chain state.

src/eth/storage/stratus_storage.rs [445-451]

 let result = timed(|| self.temp.finish_pending_block()).with(|m| {
     metrics::inc_storage_finish_pending_block(m.elapsed);
 });
 Span::with(|s| s.rec_str("block_number", &result.0.header.number));
+self.cache.clear();
 result
Suggestion importance[1-10]: 7

__

Why: Inserting self.cache.clear() after finish_pending_block prevents stale cache entries and ensures subsequent reads reflect the new chain state.

Medium
Filter only changed slots

Only include storage slots that were actually mutated by the transaction to avoid
bloating the state. Filter storage entries by value.is_changed() before inserting.

src/eth/executor/evm/types/output/transaction_execution.rs [308-311]

-let account_slots = storage.into_iter().map(|(index, value)| (index.into(), value.into())).collect();
+let account_slots = storage.into_iter()
+    .filter_map(|(index, value)| {
+        if value.is_changed() {
+            Some((index.into(), CompleteValue::Changed(value.present_value.into())))
+        } else {
+            None
+        }
+    })
+    .collect();
 execution_changes.insert_slots(address, account_slots);
 execution_changes.insert_account(address, revm_account.into());
Suggestion importance[1-10]: 5

__

Why: Filtering for value.is_changed() before inserting slots avoids bloating the State with unchanged storage entries, improving memory use without breaking behavior.

Low

@stratus-benchmark

Copy link
Copy Markdown

Benchmark:
Run ID: bench-7d058fbe

Git Info:

Leader Stats:
RPS Stats: Max: 9899.00, Min: 1982.00, Avg: 3196.85, StdDev: 442.97
TPS Stats: Max: 3653.00, Min: 159.00, Avg: 3133.96, StdDev: 346.22

Follower Stats:
Imported Blocks/s: Max: 7.00, Min: 1.00, Avg: 4.68, StdDev: 1.24
Imported Transactions/s: Max: 21775.00, Min: 2886.00, Avg: 14657.31, StdDev: 4196.48

Plots:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant