@@ -44,7 +44,7 @@ use super::CURRENT_STORAGE_VERSION;
4444struct ApiServerInMemoryStorage {
4545 block_table : BTreeMap < Id < Block > , BlockWithExtraData > ,
4646 block_aux_data_table : BTreeMap < Id < Block > , BlockAuxData > ,
47- address_balance_table : BTreeMap < String , BTreeMap < ( CoinOrTokenId , BlockHeight ) , Amount > > ,
47+ address_balance_table : BTreeMap < String , BTreeMap < CoinOrTokenId , BTreeMap < BlockHeight , Amount > > > ,
4848 address_locked_balance_table : BTreeMap < String , BTreeMap < ( CoinOrTokenId , BlockHeight ) , Amount > > ,
4949 address_transactions_table : BTreeMap < String , BTreeMap < BlockHeight , Vec < Id < Transaction > > > > ,
5050 delegation_table : BTreeMap < DelegationId , BTreeMap < BlockHeight , Delegation > > ,
@@ -62,6 +62,7 @@ struct ApiServerInMemoryStorage {
6262 orders_table : BTreeMap < OrderId , BTreeMap < BlockHeight , Order > > ,
6363 best_block : BlockAuxData ,
6464 genesis_block : Arc < WithId < Genesis > > ,
65+ number_of_coin_decimals : u8 ,
6566 storage_version : u32 ,
6667}
6768
@@ -91,6 +92,7 @@ impl ApiServerInMemoryStorage {
9192 0 . into ( ) ,
9293 chain_config. genesis_block ( ) . timestamp ( ) ,
9394 ) ,
95+ number_of_coin_decimals : chain_config. coin_decimals ( ) ,
9496 storage_version : super :: CURRENT_STORAGE_VERSION ,
9597 } ;
9698 result
@@ -108,15 +110,49 @@ impl ApiServerInMemoryStorage {
108110 address : & str ,
109111 coin_or_token_id : CoinOrTokenId ,
110112 ) -> Result < Option < Amount > , ApiServerStorageError > {
111- self . address_balance_table . get ( address) . map_or_else (
112- || Ok ( None ) ,
113- |balance| {
114- let range_begin = ( coin_or_token_id, BlockHeight :: zero ( ) ) ;
115- let range_end = ( coin_or_token_id, BlockHeight :: max ( ) ) ;
116- let range = balance. range ( range_begin..=range_end) ;
117- Ok ( range. last ( ) . map ( |( _, v) | * v) )
118- } ,
119- )
113+ self . address_balance_table
114+ . get ( address)
115+ . and_then ( |by_coin_or_token| by_coin_or_token. get ( & coin_or_token_id) )
116+ . map_or_else (
117+ || Ok ( None ) ,
118+ |by_height| Ok ( by_height. values ( ) . last ( ) . copied ( ) ) ,
119+ )
120+ }
121+
122+ fn get_address_balances (
123+ & self ,
124+ address : & str ,
125+ ) -> Result < Vec < ( CoinOrTokenId , Amount , u8 ) > , ApiServerStorageError > {
126+ let res =
127+ self . address_balance_table
128+ . get ( address)
129+ . map_or_else ( Vec :: new, |by_coin_or_token| {
130+ by_coin_or_token
131+ . iter ( )
132+ . map ( |( coin_or_token_id, by_height) | {
133+ let number_of_decimals = match coin_or_token_id {
134+ CoinOrTokenId :: Coin => self . number_of_coin_decimals ,
135+ CoinOrTokenId :: TokenId ( token_id) => self
136+ . fungible_token_issuances
137+ . get ( token_id)
138+ . map_or ( 0 , |by_height| {
139+ by_height
140+ . values ( )
141+ . last ( )
142+ . expect ( "not empty" )
143+ . number_of_decimals
144+ } ) ,
145+ } ;
146+
147+ (
148+ * coin_or_token_id,
149+ * by_height. values ( ) . last ( ) . expect ( "not empty" ) ,
150+ number_of_decimals,
151+ )
152+ } )
153+ . collect ( )
154+ } ) ;
155+ Ok ( res)
120156 }
121157
122158 fn get_address_locked_balance (
@@ -749,16 +785,12 @@ impl ApiServerInMemoryStorage {
749785 ) -> Result < ( ) , ApiServerStorageError > {
750786 // Inefficient, but acceptable for testing with InMemoryStorage
751787
752- self . address_balance_table . iter_mut ( ) . for_each ( |( _, balance) | {
753- balance
754- . iter ( )
755- . filter ( |( ( _, height) , _) | * height > block_height)
756- . map ( |( key, _) | * key)
757- . collect :: < Vec < _ > > ( )
758- . iter ( )
759- . for_each ( |key| {
760- balance. remove ( key) ;
761- } )
788+ self . address_balance_table . retain ( |_, by_coin_or_token| {
789+ by_coin_or_token. retain ( |_, by_block_height| {
790+ by_block_height. retain ( |height, _| height <= & block_height) ;
791+ !by_block_height. is_empty ( )
792+ } ) ;
793+ !by_coin_or_token. is_empty ( )
762794 } ) ;
763795
764796 Ok ( ( ) )
@@ -815,7 +847,9 @@ impl ApiServerInMemoryStorage {
815847 self . address_balance_table
816848 . entry ( address. to_string ( ) )
817849 . or_default ( )
818- . entry ( ( coin_or_token_id, block_height) )
850+ . entry ( coin_or_token_id)
851+ . or_default ( )
852+ . entry ( block_height)
819853 . and_modify ( |e| * e = amount)
820854 . or_insert ( amount) ;
821855
0 commit comments