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