1+ use crate :: db:: CachingDb ;
12use alloy:: {
23 consensus:: constants:: KECCAK_EMPTY ,
34 primitives:: { Address , B256 , U256 } ,
@@ -10,6 +11,8 @@ use revm::{
1011 Database , DatabaseCommit , DatabaseRef ,
1112} ;
1213
14+ use super :: TryCachingDb ;
15+
1316/// A version of [`CacheDB`] that caches only on write, not on read.
1417///
1518/// This saves memory when wrapping some other caching database, like [`State`]
@@ -49,11 +52,21 @@ impl<Db> CacheOnWrite<Db> {
4952 & self . inner
5053 }
5154
55+ /// Get a mutable reference to the inner database.
56+ pub const fn inner_mut ( & mut self ) -> & mut Db {
57+ & mut self . inner
58+ }
59+
5260 /// Get a refernce to the [`Cache`].
5361 pub const fn cache ( & self ) -> & Cache {
5462 & self . cache
5563 }
5664
65+ /// Get a mutable reference to the [`Cache`].
66+ pub const fn cache_mut ( & mut self ) -> & mut Cache {
67+ & mut self . cache
68+ }
69+
5770 /// Deconstruct the `CacheOnWrite` into its parts.
5871 pub fn into_parts ( self ) -> ( Db , Cache ) {
5972 ( self . inner , self . cache )
@@ -91,29 +104,67 @@ impl<Db> CacheOnWrite<Db> {
91104 }
92105}
93106
94- impl < Db > CacheOnWrite < CacheOnWrite < Db > > {
95- /// Discard the outer cache, returning the inner.
96- pub fn discard_outer ( self ) -> CacheOnWrite < Db > {
97- self . inner
107+ impl < Db > CachingDb for CacheOnWrite < Db > {
108+ fn cache ( & self ) -> & Cache {
109+ & self . cache
110+ }
111+
112+ fn cache_mut ( & mut self ) -> & mut Cache {
113+ & mut self . cache
98114 }
99115
116+ fn into_cache ( self ) -> Cache {
117+ self . cache
118+ }
119+ }
120+
121+ impl < Db > CacheOnWrite < Db >
122+ where
123+ Db : CachingDb ,
124+ {
100125 /// Flattens a nested cache by applying the outer cache to the inner cache.
101126 ///
102127 /// The behavior is as follows:
103128 /// - Accounts are overridden with outer accounts
104129 /// - Contracts are overridden with outer contracts
105130 /// - Block hashes are overridden with outer block hashes
106- pub fn flatten ( self ) -> CacheOnWrite < Db > {
131+ pub fn flatten ( self ) -> Db {
107132 let Self { cache : Cache { accounts, contracts, logs, block_hashes } , mut inner } = self ;
108133
109- inner. cache . accounts . extend ( accounts) ;
110- inner. cache . contracts . extend ( contracts) ;
111- inner. cache . logs . extend ( logs) ;
112- inner. cache . block_hashes . extend ( block_hashes) ;
134+ let inner_cache = inner. cache_mut ( ) ;
135+
136+ inner_cache. accounts . extend ( accounts) ;
137+ inner_cache. contracts . extend ( contracts) ;
138+ inner_cache. logs . extend ( logs) ;
139+ inner_cache. block_hashes . extend ( block_hashes) ;
113140 inner
114141 }
115142}
116143
144+ impl < Db > CacheOnWrite < Db >
145+ where
146+ Db : TryCachingDb ,
147+ {
148+ /// Attempts to flatten a nested cache by applying the outer cache to the
149+ /// inner cache. This is a fallible version of [`CacheOnWrite::flatten`].
150+ ///
151+ /// The behavior is as follows:
152+ /// - Accounts are overridden with outer accounts
153+ /// - Contracts are overridden with outer contracts
154+ /// - Block hashes are overridden with outer block hashes
155+ pub fn try_flatten ( self ) -> Result < Db , Db :: Error > {
156+ let Self { cache : Cache { accounts, contracts, logs, block_hashes } , mut inner } = self ;
157+
158+ let inner_cache = inner. try_cache_mut ( ) ?;
159+
160+ inner_cache. accounts . extend ( accounts) ;
161+ inner_cache. contracts . extend ( contracts) ;
162+ inner_cache. logs . extend ( logs) ;
163+ inner_cache. block_hashes . extend ( block_hashes) ;
164+ Ok ( inner)
165+ }
166+ }
167+
117168impl < Db : DatabaseRef > Database for CacheOnWrite < Db > {
118169 type Error = Db :: Error ;
119170
0 commit comments