1+ use std:: sync:: Arc ;
2+
13use anyhow:: { bail, Context , Result } ;
24use katana_primitives:: block:: {
35 BlockHashOrNumber , BlockIdOrTag , BlockNumber , FinalityStatus , GasPrices , Header , SealedBlock ,
46 SealedBlockWithStatus ,
57} ;
6- use katana_provider:: api:: block:: { BlockProvider , BlockWriter } ;
8+ use katana_provider:: api:: block:: { BlockIdReader , BlockProvider , BlockWriter } ;
79use katana_provider:: api:: contract:: ContractClassWriter ;
810use katana_provider:: api:: env:: BlockEnvProvider ;
911use katana_provider:: api:: stage:: StageCheckpointProvider ;
@@ -14,8 +16,7 @@ use katana_provider::api::transaction::{
1416 TransactionsProviderExt ,
1517} ;
1618use katana_provider:: api:: trie:: TrieWriter ;
17- use katana_provider:: providers:: db:: DbProvider ;
18- use katana_provider:: providers:: fork:: ForkedProvider ;
19+ use katana_provider:: { DbProviderFactory , ForkProviderFactory , ProviderFactory } ;
1920use katana_rpc_client:: starknet:: Client as StarknetClient ;
2021use katana_rpc_client:: HttpClientBuilder ;
2122use katana_rpc_types:: GetBlockWithTxHashesResponse ;
@@ -24,79 +25,39 @@ use starknet::core::utils::parse_cairo_short_string;
2425use tracing:: info;
2526use url:: Url ;
2627
27- pub trait DatabaseRO :
28- BlockProvider
29- + TransactionProvider
30- + TransactionStatusProvider
31- + TransactionTraceProvider
32- + TransactionsProviderExt
33- + ReceiptProvider
34- + StateUpdateProvider
35- + StateFactoryProvider
36- + BlockEnvProvider
37- + ' static
38- + Send
39- + Sync
40- + core:: fmt:: Debug
41- {
42- }
43-
44- pub trait DatabaseRW :
45- DatabaseRO + BlockWriter + StateWriter + ContractClassWriter + TrieWriter + StageCheckpointProvider
46- {
47- }
48-
49- impl < T > DatabaseRO for T where
50- T : BlockProvider
51- + TransactionProvider
52- + TransactionStatusProvider
53- + TransactionTraceProvider
54- + TransactionsProviderExt
55- + ReceiptProvider
56- + StateUpdateProvider
57- + StateFactoryProvider
58- + BlockEnvProvider
59- + ' static
60- + Send
61- + Sync
62- + core:: fmt:: Debug
63- {
64- }
65-
66- impl < T > DatabaseRW for T where
67- T : DatabaseRO
68- + BlockWriter
69- + StateWriter
70- + ContractClassWriter
71- + TrieWriter
72- + StageCheckpointProvider
73- {
74- }
28+ pub type GenericStorageProvider =
29+ Arc < dyn ProviderFactory < Provider = Box < dyn DatabaseRO > , ProviderMut = Box < dyn DatabaseRW > > > ;
7530
7631#[ derive( Debug , Clone ) ]
77- pub struct Blockchain {
78- inner : BlockchainProvider < Box < dyn DatabaseRW > > ,
32+ pub struct StorageProvider < P > {
33+ provider_factory : P ,
7934}
8035
81- impl Blockchain {
82- pub fn new ( provider : impl DatabaseRW ) -> Self {
83- Self { inner : BlockchainProvider :: new ( Box :: new ( provider ) ) }
36+ impl < P : ProviderFactory > StorageProvider < P > {
37+ pub fn new ( provider_factory : P ) -> Self {
38+ Self { provider_factory }
8439 }
40+ }
8541
86- /// Creates a new [Blockchain] from a database at `path` and `genesis` state.
42+ impl StorageProvider < DbProviderFactory < katana_db :: Db > > {
8743 pub fn new_with_db ( db : katana_db:: Db ) -> Self {
88- Self :: new ( DbProvider :: new ( db) )
44+ Self :: new ( DbProviderFactory :: new ( db) )
45+ }
46+
47+ pub fn new_in_memory ( ) -> Self {
48+ Self :: new ( DbProviderFactory :: new_in_memory ( ) )
8949 }
50+ }
9051
52+ impl StorageProvider < ForkProviderFactory < katana_db:: Db > > {
9153 /// Builds a new blockchain with a forked block.
92- pub async fn new_from_forked (
54+ pub async fn new_forked (
9355 db : katana_db:: Db ,
94- fork_url : Url ,
56+ client : StarknetClient ,
9557 fork_block : Option < BlockHashOrNumber > ,
9658 chain : & mut katana_chain_spec:: dev:: ChainSpec ,
9759 ) -> Result < ( Self , BlockNumber ) > {
98- let provider = StarknetClient :: new ( HttpClientBuilder :: new ( ) . build ( fork_url) ?) ;
99- let chain_id = provider. chain_id ( ) . await . context ( "failed to fetch forked network id" ) ?;
60+ let chain_id = client. chain_id ( ) . await . context ( "failed to fetch forked network id" ) ?;
10061
10162 // if the id is not in ASCII encoding, we display the chain id as is in hex.
10263 let parsed_id = match parse_cairo_short_string ( & chain_id) {
@@ -109,13 +70,13 @@ impl Blockchain {
10970 let block_id = if let Some ( id) = fork_block {
11071 id
11172 } else {
112- let res = provider . block_number ( ) . await ?;
73+ let res = client . block_number ( ) . await ?;
11374 BlockHashOrNumber :: Num ( res. block_number )
11475 } ;
11576
11677 info ! ( chain = %parsed_id, block = %block_id, "Forking chain." ) ;
11778
118- let block = provider
79+ let block = client
11980 . get_block_with_tx_hashes ( BlockIdOrTag :: from ( block_id) )
12081 . await
12182 . context ( "failed to fetch forked block" ) ?;
@@ -145,15 +106,15 @@ impl Blockchain {
145106
146107 // TODO: convert this to block number instead of BlockHashOrNumber so that it is easier to
147108 // check if the requested block is within the supported range or not.
148- let database = ForkedProvider :: new ( db, block_num, provider . clone ( ) ) ;
109+ let provider_factory = ForkProviderFactory :: new ( db, block_num, client . clone ( ) ) ;
149110
150111 // initialize parent fork block
151112 //
152113 // NOTE: this is just a workaround for allowing forked genesis block to be initialize using
153114 // `Backend::do_mine_block`.
154115 {
155116 let parent_block_id = BlockIdOrTag :: from ( forked_block. parent_hash ) ;
156- let parent_block = provider . get_block_with_tx_hashes ( parent_block_id) . await ?;
117+ let parent_block = client . get_block_with_tx_hashes ( parent_block_id) . await ?;
157118
158119 let GetBlockWithTxHashesResponse :: Block ( parent_block) = parent_block else {
159120 bail ! ( "parent block is a preconfirmed block" ) ;
@@ -175,7 +136,8 @@ impl Blockchain {
175136 status : FinalityStatus :: AcceptedOnL2 ,
176137 } ;
177138
178- database
139+ provider_factory
140+ . provider_mut ( )
179141 . insert_block_with_states_and_receipts (
180142 parent_block,
181143 Default :: default ( ) ,
@@ -201,10 +163,75 @@ impl Blockchain {
201163
202164 block. header . l1_da_mode = forked_block. l1_da_mode ;
203165
204- Ok ( ( Self :: new ( database ) , block_num) )
166+ Ok ( ( Self :: new ( provider_factory ) , block_num) )
205167 }
168+ }
206169
207- pub fn provider ( & self ) -> & BlockchainProvider < Box < dyn Database > > {
208- & self . inner
170+ impl < P > ProviderFactory for StorageProvider < P >
171+ where
172+ P : ProviderFactory ,
173+ <P as ProviderFactory >:: Provider : DatabaseRO ,
174+ <P as ProviderFactory >:: ProviderMut : DatabaseRW ,
175+ {
176+ type Provider = Box < dyn DatabaseRO > ;
177+ type ProviderMut = Box < dyn DatabaseRW > ;
178+
179+ fn provider ( & self ) -> Self :: Provider {
180+ Box :: new ( self . provider_factory . provider_mut ( ) )
181+ }
182+
183+ fn provider_mut ( & self ) -> Self :: ProviderMut {
184+ Box :: new ( self . provider_factory . provider_mut ( ) )
209185 }
210186}
187+
188+ pub trait DatabaseRO :
189+ BlockIdReader
190+ + BlockProvider
191+ + TransactionProvider
192+ + TransactionStatusProvider
193+ + TransactionTraceProvider
194+ + TransactionsProviderExt
195+ + ReceiptProvider
196+ + StateUpdateProvider
197+ + StateFactoryProvider
198+ + BlockEnvProvider
199+ + ' static
200+ + Send
201+ + Sync
202+ + core:: fmt:: Debug
203+ {
204+ }
205+
206+ pub trait DatabaseRW :
207+ DatabaseRO + BlockWriter + StateWriter + ContractClassWriter + TrieWriter + StageCheckpointProvider
208+ {
209+ }
210+
211+ impl < T > DatabaseRO for T where
212+ T : BlockProvider
213+ + BlockIdReader
214+ + TransactionProvider
215+ + TransactionStatusProvider
216+ + TransactionTraceProvider
217+ + TransactionsProviderExt
218+ + ReceiptProvider
219+ + StateUpdateProvider
220+ + StateFactoryProvider
221+ + BlockEnvProvider
222+ + ' static
223+ + Send
224+ + Sync
225+ + core:: fmt:: Debug
226+ {
227+ }
228+
229+ impl < T > DatabaseRW for T where
230+ T : DatabaseRO
231+ + BlockWriter
232+ + StateWriter
233+ + ContractClassWriter
234+ + TrieWriter
235+ + StageCheckpointProvider
236+ {
237+ }
0 commit comments