@@ -5,13 +5,71 @@ use crate::model::wallet::WalletSeedHash;
55use crate :: ui:: tokens:: tokens_screen:: { IdentityTokenBalance , IdentityTokenIdentifier } ;
66use bincode:: config;
77use dash_sdk:: dpp:: data_contract:: TokenConfiguration ;
8+ use dash_sdk:: dpp:: data_contract:: accessors:: v0:: DataContractV0Getters ;
89use dash_sdk:: platform:: { DataContract , Identifier } ;
910use dash_sdk:: query_types:: IndexMap ;
1011use rusqlite:: Result ;
1112use std:: sync:: Arc ;
1213use std:: sync:: atomic:: Ordering ;
1314
1415impl AppContext {
16+ /// Returns borrowed references to the cached system-contract `Arc`s alongside their aliases.
17+ ///
18+ /// Use this for read-only lookups (id checks, membership tests, `Arc` cloning) to avoid
19+ /// the deep `DataContract` clones that `system_contracts()` performs.
20+ pub ( crate ) fn system_contract_arcs ( & self ) -> [ ( & Arc < DataContract > , & ' static str ) ; 5 ] {
21+ [
22+ ( & self . dpns_contract , "dpns" ) ,
23+ ( & self . token_history_contract , "token_history" ) ,
24+ ( & self . withdraws_contract , "withdrawals" ) ,
25+ ( & self . keyword_search_contract , "keyword_search" ) ,
26+ ( & self . dashpay_contract , "dashpay" ) ,
27+ ]
28+ }
29+
30+ pub ( crate ) fn system_contracts ( & self ) -> [ QualifiedContract ; 5 ] {
31+ self . system_contract_arcs ( )
32+ . map ( |( contract, alias) | QualifiedContract {
33+ contract : contract. as_ref ( ) . clone ( ) ,
34+ alias : Some ( alias. to_string ( ) ) ,
35+ } )
36+ }
37+
38+ pub ( crate ) fn system_contract_ids ( & self ) -> [ Identifier ; 5 ] {
39+ self . system_contract_arcs ( )
40+ . map ( |( contract, _alias) | contract. id ( ) )
41+ }
42+
43+ pub ( crate ) fn system_contract_by_id (
44+ & self ,
45+ contract_id : & Identifier ,
46+ ) -> Option < QualifiedContract > {
47+ self . system_contract_arcs ( )
48+ . into_iter ( )
49+ . find ( |( contract, _alias) | contract. id ( ) == * contract_id)
50+ . map ( |( contract, alias) | QualifiedContract {
51+ contract : contract. as_ref ( ) . clone ( ) ,
52+ alias : Some ( alias. to_string ( ) ) ,
53+ } )
54+ }
55+
56+ /// Returns an `Arc::clone` of a cached system contract by id, without deep cloning.
57+ pub ( crate ) fn system_contract_arc_by_id (
58+ & self ,
59+ contract_id : & Identifier ,
60+ ) -> Option < Arc < DataContract > > {
61+ self . system_contract_arcs ( )
62+ . into_iter ( )
63+ . find ( |( contract, _alias) | contract. id ( ) == * contract_id)
64+ . map ( |( contract, _alias) | Arc :: clone ( contract) )
65+ }
66+
67+ pub ( crate ) fn is_system_contract_id ( & self , contract_id : & Identifier ) -> bool {
68+ self . system_contract_arcs ( )
69+ . iter ( )
70+ . any ( |( contract, _alias) | contract. id ( ) == * contract_id)
71+ }
72+
1573 /// Retrieves all contracts from the database plus the system contracts from app context.
1674 pub fn get_contracts (
1775 & self ,
@@ -21,50 +79,9 @@ impl AppContext {
2179 // Get contracts from the database
2280 let mut contracts = self . db . get_contracts ( self , limit, offset) ?;
2381
24- // Add the DPNS contract to the list
25- let dpns_contract = QualifiedContract {
26- contract : Arc :: clone ( & self . dpns_contract ) . as_ref ( ) . clone ( ) ,
27- alias : Some ( "dpns" . to_string ( ) ) ,
28- } ;
29-
30- // Insert the DPNS contract at 0
31- contracts. insert ( 0 , dpns_contract) ;
32-
33- // Add the token history contract to the list
34- let token_history_contract = QualifiedContract {
35- contract : Arc :: clone ( & self . token_history_contract ) . as_ref ( ) . clone ( ) ,
36- alias : Some ( "token_history" . to_string ( ) ) ,
37- } ;
38-
39- // Insert the token history contract at 1
40- contracts. insert ( 1 , token_history_contract) ;
41-
42- // Add the withdrawal contract to the list
43- let withdraws_contract = QualifiedContract {
44- contract : Arc :: clone ( & self . withdraws_contract ) . as_ref ( ) . clone ( ) ,
45- alias : Some ( "withdrawals" . to_string ( ) ) ,
46- } ;
47-
48- // Insert the withdrawal contract at 2
49- contracts. insert ( 2 , withdraws_contract) ;
50-
51- // Add the keyword search contract to the list
52- let keyword_search_contract = QualifiedContract {
53- contract : Arc :: clone ( & self . keyword_search_contract ) . as_ref ( ) . clone ( ) ,
54- alias : Some ( "keyword_search" . to_string ( ) ) ,
55- } ;
56-
57- // Insert the keyword search contract at 3
58- contracts. insert ( 3 , keyword_search_contract) ;
59-
60- // Add the DashPay contract to the list
61- let dashpay_contract = QualifiedContract {
62- contract : Arc :: clone ( & self . dashpay_contract ) . as_ref ( ) . clone ( ) ,
63- alias : Some ( "dashpay" . to_string ( ) ) ,
64- } ;
65-
66- // Insert the DashPay contract at 4
67- contracts. insert ( 4 , dashpay_contract) ;
82+ for ( index, system_contract) in self . system_contracts ( ) . into_iter ( ) . enumerate ( ) {
83+ contracts. insert ( index, system_contract) ;
84+ }
6885
6986 Ok ( contracts)
7087 }
@@ -73,6 +90,10 @@ impl AppContext {
7390 & self ,
7491 contract_id : & Identifier ,
7592 ) -> Result < Option < QualifiedContract > > {
93+ if let Some ( system_contract) = self . system_contract_by_id ( contract_id) {
94+ return Ok ( Some ( system_contract) ) ;
95+ }
96+
7697 // Get the contract from the database
7798 self . db . get_contract_by_id ( * contract_id, self )
7899 }
@@ -81,12 +102,20 @@ impl AppContext {
81102 & self ,
82103 contract_id : & Identifier ,
83104 ) -> Result < Option < DataContract > > {
105+ if let Some ( system_contract) = self . system_contract_by_id ( contract_id) {
106+ return Ok ( Some ( system_contract. contract ) ) ;
107+ }
108+
84109 // Get the contract from the database
85110 self . db . get_unqualified_contract_by_id ( * contract_id, self )
86111 }
87112
88113 // Remove contract from the database by ID
89114 pub fn remove_contract ( & self , contract_id : & Identifier ) -> Result < ( ) > {
115+ if self . is_system_contract_id ( contract_id) {
116+ return Ok ( ( ) ) ;
117+ }
118+
90119 self . db . remove_contract ( contract_id. as_bytes ( ) , self )
91120 }
92121
@@ -95,6 +124,10 @@ impl AppContext {
95124 contract_id : Identifier ,
96125 new_contract : & DataContract ,
97126 ) -> Result < ( ) > {
127+ if self . is_system_contract_id ( & contract_id) {
128+ return Ok ( ( ) ) ;
129+ }
130+
98131 self . db . replace_contract ( contract_id, new_contract, self )
99132 }
100133
@@ -183,6 +216,6 @@ impl AppContext {
183216 let Some ( contract_id) = self . db . get_contract_id_by_token_id ( token_id, self ) ? else {
184217 return Ok ( None ) ;
185218 } ;
186- self . db . get_contract_by_id ( contract_id, self )
219+ self . get_contract_by_id ( & contract_id)
187220 }
188221}
0 commit comments