@@ -5,6 +5,7 @@ use crate::types::{PreviousQuorumsResponse, QuorumData, QuorumsResponse};
55use arc_swap:: ArcSwap ;
66use async_trait:: async_trait;
77use dash_context_provider:: { ContextProvider , ContextProviderError } ;
8+ use dpp:: data_contract:: accessors:: v0:: DataContractV0Getters ;
89use dpp:: prelude:: { CoreBlockHeight , DataContract , Identifier } ;
910// QuorumHash is just [u8; 32]
1011type QuorumHash = [ u8 ; 32 ] ;
@@ -23,6 +24,7 @@ fn get_llmq_type_for_network(network: Network) -> u32 {
2324}
2425use lru:: LruCache ;
2526use reqwest:: Client ;
27+ use std:: collections:: HashMap ;
2628use std:: num:: NonZeroUsize ;
2729use std:: sync:: { Arc , Mutex } ;
2830use std:: time:: Duration ;
@@ -50,6 +52,9 @@ pub struct TrustedHttpContextProvider {
5052
5153 /// Optional fallback provider for data contracts and token configurations
5254 fallback_provider : Option < Box < dyn ContextProvider > > ,
55+
56+ /// Known contracts cache - contracts that are pre-loaded and can be served immediately
57+ known_contracts : HashMap < Identifier , Arc < DataContract > > ,
5358}
5459
5560impl TrustedHttpContextProvider {
@@ -73,6 +78,7 @@ impl TrustedHttpContextProvider {
7378 last_current_quorums : Arc :: new ( ArcSwap :: new ( Arc :: new ( None ) ) ) ,
7479 last_previous_quorums : Arc :: new ( ArcSwap :: new ( Arc :: new ( None ) ) ) ,
7580 fallback_provider : None ,
81+ known_contracts : HashMap :: new ( ) ,
7682 } )
7783 }
7884
@@ -82,6 +88,15 @@ impl TrustedHttpContextProvider {
8288 self
8389 }
8490
91+ /// Set known contracts that will be served immediately without fallback
92+ pub fn with_known_contracts ( mut self , contracts : Vec < DataContract > ) -> Self {
93+ for contract in contracts {
94+ let id = contract. id ( ) ;
95+ self . known_contracts . insert ( id, Arc :: new ( contract) ) ;
96+ }
97+ self
98+ }
99+
85100 /// Fetch current quorums from the HTTP endpoint
86101 async fn fetch_current_quorums ( & self ) -> Result < QuorumsResponse , TrustedContextProviderError > {
87102 let llmq_type = get_llmq_type_for_network ( self . network ) ;
@@ -261,7 +276,12 @@ impl ContextProvider for TrustedHttpContextProvider {
261276 id : & Identifier ,
262277 platform_version : & PlatformVersion ,
263278 ) -> Result < Option < Arc < DataContract > > , ContextProviderError > {
264- // Delegate to fallback provider if available
279+ // First check known contracts cache
280+ if let Some ( contract) = self . known_contracts . get ( id) {
281+ return Ok ( Some ( contract. clone ( ) ) ) ;
282+ }
283+
284+ // If not found in known contracts, delegate to fallback provider if available
265285 if let Some ( ref provider) = self . fallback_provider {
266286 provider. get_data_contract ( id, platform_version)
267287 } else {
@@ -323,4 +343,27 @@ mod tests {
323343 fn test_devnet_without_name_panics ( ) {
324344 get_quorum_base_url ( Network :: Devnet , None ) ;
325345 }
346+
347+ #[ test]
348+ fn test_known_contracts ( ) {
349+ use dpp:: version:: PlatformVersion ;
350+
351+ // Create a provider
352+ let provider = TrustedHttpContextProvider :: new (
353+ Network :: Testnet ,
354+ None ,
355+ NonZeroUsize :: new ( 100 ) . unwrap ( ) ,
356+ )
357+ . unwrap ( ) ;
358+
359+ // Test that initially there are no known contracts
360+ let contract_id = Identifier :: from ( [ 1u8 ; 32 ] ) ;
361+ let retrieved = provider
362+ . get_data_contract ( & contract_id, PlatformVersion :: latest ( ) )
363+ . unwrap ( ) ;
364+ assert ! ( retrieved. is_none( ) ) ;
365+
366+ // Test that we can use the builder pattern to add known contracts
367+ // The builder pattern is more appropriate since contracts are only added during initialization
368+ }
326369}
0 commit comments