@@ -82,6 +82,17 @@ struct ApiServerInMemoryStorage {
8282 statistics :
8383 BTreeMap < CoinOrTokenStatistic , BTreeMap < CoinOrTokenId , BTreeMap < BlockHeight , Amount > > > ,
8484 orders_table : BTreeMap < OrderId , BTreeMap < BlockHeight , Order > > ,
85+ mempool_transaction_table : BTreeMap < Id < Transaction > , TransactionInfo > ,
86+ mempool_utxo_table : BTreeMap < UtxoOutPoint , ( Utxo , bool ) > ,
87+ mempool_address_utxos : BTreeMap < String , BTreeSet < UtxoOutPoint > > ,
88+ mempool_address_balance_table : BTreeMap < String , BTreeMap < CoinOrTokenId , AmountWithDecimals > > ,
89+ mempool_locked_address_balance_table :
90+ BTreeMap < String , BTreeMap < CoinOrTokenId , AmountWithDecimals > > ,
91+ mempool_address_transactions_table : BTreeMap < String , BTreeSet < Id < Transaction > > > ,
92+ mempool_token_transactions_table : BTreeMap < TokenId , BTreeSet < Id < Transaction > > > ,
93+ mempool_fungible_token_data : BTreeMap < TokenId , FungibleTokenData > ,
94+ mempool_nft_token_issuances : BTreeMap < TokenId , NftWithOwner > ,
95+ mempool_orders_table : BTreeMap < OrderId , Order > ,
8596 genesis_block : Arc < WithId < Genesis > > ,
8697 number_of_coin_decimals : u8 ,
8798 storage_version : u32 ,
@@ -109,6 +120,16 @@ impl ApiServerInMemoryStorage {
109120 nft_token_issuances : BTreeMap :: new ( ) ,
110121 statistics : BTreeMap :: new ( ) ,
111122 orders_table : BTreeMap :: new ( ) ,
123+ mempool_transaction_table : BTreeMap :: new ( ) ,
124+ mempool_utxo_table : BTreeMap :: new ( ) ,
125+ mempool_address_utxos : BTreeMap :: new ( ) ,
126+ mempool_address_balance_table : BTreeMap :: new ( ) ,
127+ mempool_locked_address_balance_table : BTreeMap :: new ( ) ,
128+ mempool_address_transactions_table : BTreeMap :: new ( ) ,
129+ mempool_token_transactions_table : BTreeMap :: new ( ) ,
130+ mempool_fungible_token_data : BTreeMap :: new ( ) ,
131+ mempool_nft_token_issuances : BTreeMap :: new ( ) ,
132+ mempool_orders_table : BTreeMap :: new ( ) ,
112133 genesis_block : chain_config. genesis_block ( ) . clone ( ) ,
113134 number_of_coin_decimals : chain_config. coin_decimals ( ) ,
114135 storage_version : CURRENT_STORAGE_VERSION ,
@@ -840,6 +861,127 @@ impl ApiServerInMemoryStorage {
840861 } ) ;
841862 Ok ( ( ) )
842863 }
864+
865+ fn get_utxo_mempool_fallback (
866+ & self ,
867+ outpoint : & UtxoOutPoint ,
868+ ) -> Result < Option < Utxo > , ApiServerStorageError > {
869+ if let Some ( res) = self . mempool_utxo_table . get ( outpoint) . map ( |( utxo, _) | utxo. clone ( ) ) {
870+ return Ok ( Some ( res) ) ;
871+ }
872+
873+ self . get_utxo ( outpoint. clone ( ) )
874+ }
875+
876+ fn get_mempool_address_balance (
877+ & self ,
878+ address : & str ,
879+ coin_or_token_id : CoinOrTokenId ,
880+ ) -> Result < Option < Amount > , ApiServerStorageError > {
881+ let mempool_balance = self
882+ . mempool_address_balance_table
883+ . get ( address)
884+ . and_then ( |by_coin| by_coin. get ( & coin_or_token_id) . map ( |amount| amount. amount ) ) ;
885+
886+ if mempool_balance. is_some ( ) {
887+ return Ok ( mempool_balance) ;
888+ }
889+
890+ self . get_address_balance ( address, coin_or_token_id)
891+ }
892+
893+ fn get_mempool_locked_address_balance (
894+ & self ,
895+ address : & str ,
896+ coin_or_token_id : CoinOrTokenId ,
897+ ) -> Result < Option < Amount > , ApiServerStorageError > {
898+ let mempool_balance = self
899+ . mempool_locked_address_balance_table
900+ . get ( address)
901+ . and_then ( |by_coin| by_coin. get ( & coin_or_token_id) . map ( |amount| amount. amount ) ) ;
902+
903+ if mempool_balance. is_some ( ) {
904+ return Ok ( mempool_balance) ;
905+ }
906+
907+ self . get_address_locked_balance ( address, coin_or_token_id)
908+ }
909+
910+ fn get_mempool_transaction (
911+ & self ,
912+ transaction_id : Id < Transaction > ,
913+ ) -> Result < Option < TransactionInfo > , ApiServerStorageError > {
914+ Ok ( self . mempool_transaction_table . get ( & transaction_id) . cloned ( ) )
915+ }
916+
917+ fn get_mempool_transactions (
918+ & self ,
919+ len : u32 ,
920+ offset : u64 ,
921+ ) -> Result < Vec < TransactionInfo > , ApiServerStorageError > {
922+ Ok ( self
923+ . mempool_transaction_table
924+ . values ( )
925+ . skip ( offset as usize )
926+ . take ( len as usize )
927+ . cloned ( )
928+ . collect ( ) )
929+ }
930+
931+ fn get_mempool_address_transactions (
932+ & self ,
933+ address : & str ,
934+ ) -> Result < Vec < Id < common:: chain:: Transaction > > , ApiServerStorageError > {
935+ Ok ( self
936+ . mempool_address_transactions_table
937+ . get ( address)
938+ . map ( |txs| txs. iter ( ) . copied ( ) . collect ( ) )
939+ . unwrap_or_default ( ) )
940+ }
941+
942+ fn get_mempool_address_balances (
943+ & self ,
944+ address : & str ,
945+ ) -> Result < BTreeMap < CoinOrTokenId , AmountWithDecimals > , ApiServerStorageError > {
946+ Ok ( self
947+ . mempool_address_balance_table
948+ . get ( address)
949+ . cloned ( )
950+ . map ( |balances| balances. into_iter ( ) . collect ( ) )
951+ . unwrap_or_default ( ) )
952+ }
953+
954+ fn get_mempool_address_all_utxos (
955+ & self ,
956+ address : & str ,
957+ ) -> Result < Vec < ( UtxoOutPoint , UtxoWithExtraInfo ) > , ApiServerStorageError > {
958+ let result = self
959+ . mempool_address_utxos
960+ . get ( address)
961+ . unwrap_or ( & BTreeSet :: new ( ) )
962+ // TODO:
963+ . union ( self . address_locked_utxos . get ( address) . unwrap_or ( & BTreeSet :: new ( ) ) )
964+ . filter_map ( |outpoint| {
965+ if let Some ( utxo) = self . get_utxo_mempool_fallback ( outpoint) . expect ( "no error" ) {
966+ ( !utxo. spent ( ) )
967+ . then_some ( ( outpoint. clone ( ) , utxo. utxo_with_extra_info ( ) . clone ( ) ) )
968+ } else {
969+ Some ( (
970+ outpoint. clone ( ) ,
971+ self . locked_utxo_table
972+ . get ( outpoint)
973+ . expect ( "must exit" )
974+ . values ( )
975+ . last ( )
976+ . expect ( "not empty" )
977+ . utxo_with_extra_info ( )
978+ . clone ( ) ,
979+ ) )
980+ }
981+ } )
982+ . collect ( ) ;
983+ Ok ( result)
984+ }
843985}
844986
845987impl ApiServerInMemoryStorage {
@@ -1292,4 +1434,154 @@ impl ApiServerInMemoryStorage {
12921434
12931435 Ok ( ( ) )
12941436 }
1437+
1438+ fn set_mempool_transaction (
1439+ & mut self ,
1440+ transaction_id : Id < Transaction > ,
1441+ transaction : & TransactionInfo ,
1442+ ) -> Result < ( ) , ApiServerStorageError > {
1443+ self . mempool_transaction_table . insert ( transaction_id, transaction. clone ( ) ) ;
1444+ Ok ( ( ) )
1445+ }
1446+
1447+ fn set_mempool_utxo (
1448+ & mut self ,
1449+ outpoint : UtxoOutPoint ,
1450+ utxo : Utxo ,
1451+ spent : bool ,
1452+ addresses : & [ & str ] ,
1453+ ) -> Result < ( ) , ApiServerStorageError > {
1454+ self . mempool_utxo_table . insert ( outpoint. clone ( ) , ( utxo, spent) ) ;
1455+ for address in addresses {
1456+ self . mempool_address_utxos
1457+ . entry ( ( * address) . into ( ) )
1458+ . or_default ( )
1459+ . insert ( outpoint. clone ( ) ) ;
1460+ }
1461+ Ok ( ( ) )
1462+ }
1463+
1464+ fn set_mempool_address_balance (
1465+ & mut self ,
1466+ address : & str ,
1467+ coin_or_token_id : CoinOrTokenId ,
1468+ amount : Amount ,
1469+ decimals : u8 ,
1470+ ) -> Result < ( ) , ApiServerStorageError > {
1471+ self . mempool_address_balance_table
1472+ . entry ( address. to_string ( ) )
1473+ . or_default ( )
1474+ . insert ( coin_or_token_id, AmountWithDecimals { amount, decimals } ) ;
1475+ Ok ( ( ) )
1476+ }
1477+
1478+ fn set_mempool_locked_address_balance (
1479+ & mut self ,
1480+ address : & str ,
1481+ coin_or_token_id : CoinOrTokenId ,
1482+ amount : Amount ,
1483+ decimals : u8 ,
1484+ ) -> Result < ( ) , ApiServerStorageError > {
1485+ self . mempool_locked_address_balance_table
1486+ . entry ( address. to_string ( ) )
1487+ . or_default ( )
1488+ . insert ( coin_or_token_id, AmountWithDecimals { amount, decimals } ) ;
1489+ Ok ( ( ) )
1490+ }
1491+
1492+ fn set_mempool_address_transaction (
1493+ & mut self ,
1494+ address : & str ,
1495+ transaction_id : Id < Transaction > ,
1496+ ) -> Result < ( ) , ApiServerStorageError > {
1497+ self . mempool_address_transactions_table
1498+ . entry ( address. to_string ( ) )
1499+ . or_default ( )
1500+ . insert ( transaction_id) ;
1501+ Ok ( ( ) )
1502+ }
1503+
1504+ fn set_mempool_token_transaction (
1505+ & mut self ,
1506+ token_id : TokenId ,
1507+ transaction_id : Id < Transaction > ,
1508+ ) -> Result < ( ) , ApiServerStorageError > {
1509+ self . mempool_token_transactions_table
1510+ . entry ( token_id)
1511+ . or_default ( )
1512+ . insert ( transaction_id) ;
1513+ Ok ( ( ) )
1514+ }
1515+
1516+ fn set_mempool_fungible_token_issuance (
1517+ & mut self ,
1518+ token_id : TokenId ,
1519+ issuance : FungibleTokenData ,
1520+ ) -> Result < ( ) , ApiServerStorageError > {
1521+ self . mempool_fungible_token_data . insert ( token_id, issuance) ;
1522+ Ok ( ( ) )
1523+ }
1524+
1525+ fn set_mempool_nft_issuance (
1526+ & mut self ,
1527+ token_id : TokenId ,
1528+ issuance : NftIssuance ,
1529+ owner : & Destination ,
1530+ ) -> Result < ( ) , ApiServerStorageError > {
1531+ self . mempool_nft_token_issuances . insert (
1532+ token_id,
1533+ NftWithOwner {
1534+ nft : issuance,
1535+ owner : Some ( owner. clone ( ) ) ,
1536+ } ,
1537+ ) ;
1538+ Ok ( ( ) )
1539+ }
1540+
1541+ fn get_mempool_token_num_decimals (
1542+ & self ,
1543+ token_id : TokenId ,
1544+ ) -> Result < Option < u8 > , ApiServerStorageError > {
1545+ let decimals = self
1546+ . mempool_fungible_token_data
1547+ . get ( & token_id)
1548+ . map ( |data| data. number_of_decimals )
1549+ . or_else ( || self . mempool_nft_token_issuances . get ( & token_id) . map ( |_| 0 ) ) ;
1550+
1551+ if decimals. is_some ( ) {
1552+ return Ok ( decimals) ;
1553+ }
1554+
1555+ self . get_token_num_decimals ( token_id)
1556+ }
1557+
1558+ fn get_mempool_order ( & self , order_id : OrderId ) -> Result < Option < Order > , ApiServerStorageError > {
1559+ let order_result = self . mempool_orders_table . get ( & order_id) . cloned ( ) ;
1560+ if order_result. is_some ( ) {
1561+ return Ok ( order_result) ;
1562+ }
1563+
1564+ self . get_order ( order_id)
1565+ }
1566+
1567+ fn set_mempool_order (
1568+ & mut self ,
1569+ order_id : OrderId ,
1570+ order : Order ,
1571+ ) -> Result < ( ) , ApiServerStorageError > {
1572+ self . mempool_orders_table . insert ( order_id, order) ;
1573+ Ok ( ( ) )
1574+ }
1575+
1576+ fn clear_mempool_data ( & mut self ) -> Result < ( ) , ApiServerStorageError > {
1577+ self . mempool_transaction_table . clear ( ) ;
1578+ self . mempool_utxo_table . clear ( ) ;
1579+ self . mempool_address_utxos . clear ( ) ;
1580+ self . mempool_address_balance_table . clear ( ) ;
1581+ self . mempool_address_transactions_table . clear ( ) ;
1582+ self . mempool_token_transactions_table . clear ( ) ;
1583+ self . mempool_fungible_token_data . clear ( ) ;
1584+ self . mempool_nft_token_issuances . clear ( ) ;
1585+ Ok ( ( ) )
1586+ }
12951587}
0 commit comments