@@ -32,7 +32,7 @@ APIHandler::APIHandler(BlockChain& blockchain, cs::SolverCore& _solver, executor
3232#ifdef MONITOR_NODE
3333, stats(blockchain)
3434#endif
35- , tm (this ) {
35+ , tm_ (this ) {
3636#ifdef MONITOR_NODE
3737 if (static bool firstTime = true ; firstTime) {
3838 stats_.second .resize (::csstats::collectionPeriods.size ());
@@ -171,7 +171,6 @@ void APIHandler::WalletBalanceGet(api::WalletBalanceGetResult& _return, const ge
171171 BlockChain::WalletData wallData{};
172172 BlockChain::WalletId wallId{};
173173 if (!s_blockchain.findWalletData (addr, wallData, wallId)) {
174- SetResponseStatus (_return.status , APIRequestStatusType::NOT_FOUND);
175174 return ;
176175 }
177176 _return.balance .integral = wallData.balance_ .integral ();
@@ -309,7 +308,7 @@ api::SealedTransaction APIHandler::convertTransaction(const csdb::Transaction& t
309308
310309 if (is_smart_deploy (sci)) {
311310 result.trxn .type = api::TransactionType::TT_SmartDeploy;
312- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , target), [&isToken, &target, &result](const TokensMap& tokens, const HoldersMap&) {
311+ tm_ .loadTokenInfo ([&isToken, &target, &result](const TokensMap& tokens, const HoldersMap&) {
313312 auto it = tokens.find (target);
314313 if (it != tokens.end ()) {
315314 isToken = true ;
@@ -332,7 +331,7 @@ api::SealedTransaction APIHandler::convertTransaction(const csdb::Transaction& t
332331 bool isTransfer = TokensMaster::isTransfer (sci.method , sci.params );
333332 result.trxn .type = api::TransactionType::TT_SmartExecute;
334333 if (isTransfer) {
335- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , target), [&isToken, &isTransfer, &target, &result](const TokensMap& tokens, const HoldersMap&) {
334+ tm_ .loadTokenInfo ([&isToken, &isTransfer, &target, &result](const TokensMap& tokens, const HoldersMap&) {
336335 auto it = tokens.find (target);
337336 if (it != tokens.end ()) {
338337 isToken = true ;
@@ -572,7 +571,7 @@ api::SmartContract APIHandler::fetch_smart_body(const csdb::Transaction& tr) {
572571 res.address = fromByteArray (s_blockchain.getAddressByType (tr.target (), BlockChain::AddressType::PublicKey).public_key ());
573572
574573#ifdef TOKENS_CACHE
575- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , tr. target ()), [&tr, &res](const TokensMap& tokens, const HoldersMap&) {
574+ tm_ .loadTokenInfo ([&tr, &res](const TokensMap& tokens, const HoldersMap&) {
576575 auto it = tokens.find (tr.target ());
577576 if (it != tokens.end ())
578577 res.smartContractDeploy .tokenStandard = it->second .tokenStandard ;
@@ -931,6 +930,22 @@ void APIHandler::SmartContractGet(api::SmartContractGetResult& _return, const ge
931930
932931void APIHandler::store_block_slot (const csdb::Pool& pool) {
933932 updateSmartCachesPool (pool);
933+ #ifdef TOKENS_CACHE
934+ if (!isBDLoaded_) {
935+ isBDLoaded_ = true ;
936+ tm_.loadTokenInfo ([&](const TokensMap& tokens, const HoldersMap&) {
937+ int count{}, i{};
938+ size_t tokenSize = tokens.size ();
939+ cslog () << " tokens are loading(" << tokenSize <<" )..." ;
940+ for (auto & tk : tokens) {
941+ if (tokenSize > 100 && !(i++ % (tokenSize / 10 )))
942+ cslog () << " loading tokens: " << 10 *(count++) << " %" ;
943+ tm_.refreshTokenState (tk.first , cs::SmartContracts::get_contract_state (get_s_blockchain (), tk.first ), true );
944+ }
945+ cslog () << " tokens loaded!" ;
946+ });
947+ }
948+ #endif
934949}
935950
936951void APIHandler::collect_all_stats_slot (const csdb::Pool& pool) {
@@ -1061,6 +1076,8 @@ bool APIHandler::updateSmartCachesTransaction(csdb::Transaction trxn, cs::Sequen
10611076 auto newHashStr = trxn.user_field (cs::trx_uf::new_state::Hash).template value <std::string>();
10621077 if (!newHashStr.empty ())
10631078 std::copy (newHashStr.begin (), newHashStr.end (), res.hash .begin ());
1079+ else
1080+ res.hash = cs::Zero::hash;
10641081 res.retVal = trxn.user_field (cs::trx_uf::new_state::RetVal).template value <std::string>();
10651082 res.isOld = (res.hash == oldHash.hash );
10661083 res.condFlg = true ;
@@ -1072,12 +1089,12 @@ bool APIHandler::updateSmartCachesTransaction(csdb::Transaction trxn, cs::Sequen
10721089 auto caller_pk = s_blockchain.getAddressByType (execTrans.source (), BlockChain::AddressType::PublicKey);
10731090
10741091 if (is_smart_deploy (smart))
1075- tm .checkNewDeploy (target_pk, caller_pk, smart);
1092+ tm_ .checkNewDeploy (target_pk, caller_pk, smart);
10761093
10771094 // state also will be updated in update_smart_state_slot()
10781095 std::string newState = cs::SmartContracts::get_contract_state (s_blockchain, target_pk);
10791096 if (!newState.empty ())
1080- tm .checkNewState (target_pk, caller_pk, smart, newState);
1097+ tm_ .checkNewState (target_pk, caller_pk, smart, newState);
10811098 }
10821099 }
10831100 }
@@ -1406,7 +1423,7 @@ void putTokenInfo(api::TokenInfo& ti, const general::Address& addr, const Token&
14061423}
14071424
14081425template <typename ResultType>
1409- void tokenTransactionsInternal (ResultType& _return, APIHandler& handler, TokensMaster& tm , const general::Address& token, bool transfersOnly, bool filterByWallet, int64_t offset,
1426+ void tokenTransactionsInternal (ResultType& _return, APIHandler& handler, TokensMaster& tm_ , const general::Address& token, bool transfersOnly, bool filterByWallet, int64_t offset,
14101427 int64_t limit, const csdb::Address& wallet = csdb::Address()) {
14111428 if (!validatePagination (_return, handler, offset, limit)) {
14121429 return ;
@@ -1416,9 +1433,9 @@ void tokenTransactionsInternal(ResultType& _return, APIHandler& handler, TokensM
14161433 bool tokenFound = false ;
14171434 std::string code;
14181435
1419- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , addr), [&addr, &tokenFound, &transfersOnly, &filterByWallet, &code, &wallet, &_return](const TokensMap& tm , const HoldersMap&) {
1420- auto it = tm .find (addr);
1421- tokenFound = !(it == tm .end ());
1436+ tm_ .loadTokenInfo ([&addr, &tokenFound, &transfersOnly, &filterByWallet, &code, &wallet, &_return](const TokensMap& tm_ , const HoldersMap&) {
1437+ auto it = tm_ .find (addr);
1438+ tokenFound = !(it == tm_ .end ());
14221439 if (tokenFound) {
14231440 code = it->second .symbol ;
14241441 if (transfersOnly && !filterByWallet) {
@@ -1604,18 +1621,7 @@ void APIHandler::ExecuteCountGet(ExecuteCountGetResult& _return, const std::stri
16041621
16051622void APIHandler::TokenBalancesGet (api::TokenBalancesResult& _return, const general::Address& address) {
16061623 const csdb::Address addr = BlockChain::getAddressFromKey (address);
1607-
1608- std::vector<csdb::Address> vtokenAddr;
1609- tm.loadTokenInfo ({}, [&vtokenAddr, &addr](const TokensMap& tokens, const HoldersMap& holders) {
1610- if (auto holderIt = holders.find (addr); holderIt != holders.end ()) {
1611- for (const auto & tokAddr : holderIt->second ) {
1612- if (tokens.find (tokAddr) != tokens.end ())
1613- vtokenAddr.push_back (tokAddr);
1614- }
1615- }
1616- });
1617-
1618- tm.loadTokenInfo (vtokenAddr, [&_return, &addr](const TokensMap& tokens, const HoldersMap& holders) {
1624+ tm_.loadTokenInfo ([&_return, &addr](const TokensMap& tokens, const HoldersMap& holders) {
16191625 auto holderIt = holders.find (addr);
16201626 if (holderIt != holders.end ()) {
16211627 for (const auto & tokAddr : holderIt->second ) {
@@ -1645,7 +1651,7 @@ void APIHandler::TokenBalancesGet(api::TokenBalancesResult& _return, const gener
16451651}
16461652
16471653void APIHandler::TokenTransfersGet (api::TokenTransfersResult& _return, const general::Address& token, int64_t offset, int64_t limit) {
1648- tokenTransactionsInternal (_return, *this , tm , token, true , false , offset, limit);
1654+ tokenTransactionsInternal (_return, *this , tm_ , token, true , false , offset, limit);
16491655}
16501656
16511657void APIHandler::TokenTransferGet (api::TokenTransfersResult& _return, const general::Address& token, const TransactionId& id) {
@@ -1654,9 +1660,9 @@ void APIHandler::TokenTransferGet(api::TokenTransfersResult& _return, const gene
16541660 const csdb::Address addr = BlockChain::getAddressFromKey (token);
16551661
16561662 std::string code{};
1657- tm .loadTokenInfo (std::vector ( 1 , addr), [&addr, &code](const TokensMap& tm , const HoldersMap&) {
1658- const auto it = tm .find (addr);
1659- if (it != tm .cend ()) {
1663+ tm_ .loadTokenInfo ([&addr, &code](const TokensMap& tm_ , const HoldersMap&) {
1664+ const auto it = tm_ .find (addr);
1665+ if (it != tm_ .cend ()) {
16601666 code = it->second .symbol ;
16611667 }
16621668 });
@@ -1718,16 +1724,15 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17181724 uint64_t totalTransfers = 0 ;
17191725 std::multimap<cs::Sequence, csdb::Address> tokenTransPools;
17201726
1721- tm .loadTokenInfo ({}, [&totalTransfers, &tokenTransPools, this ](const TokensMap& tm , const HoldersMap&) {
1722- for (auto & t : tm ) {
1727+ tm_ .loadTokenInfo ([&totalTransfers, &tokenTransPools, this ](const TokensMap& tm_ , const HoldersMap&) {
1728+ for (auto & t : tm_ ) {
17231729 totalTransfers += t.second .transfersCount ;
17241730 tokenTransPools.insert (std::make_pair (s_blockchain.getLastTransaction (t.first ).pool_seq (), t.first ));
17251731 }
17261732 });
17271733
17281734 _return.count = uint32_t (totalTransfers);
17291735
1730- std::vector<csdb::Address> tokenAddrs;
17311736 cs::Sequence seq = s_blockchain.getLastNonEmptyBlock ().first ;
17321737 while (limit && seq != cs::kWrongSequence && tokenTransPools.size ()) {
17331738 auto it = tokenTransPools.find (seq);
@@ -1748,7 +1753,6 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17481753 csdb::Address target_pk = s_blockchain.getAddressByType (t.target (), BlockChain::AddressType::PublicKey);
17491754 auto addrPair = TokensMaster::getTransferData (target_pk, smart.method , smart.params );
17501755 addTokenResult (_return, target_pk, " " , pool, t, smart, addrPair, s_blockchain);
1751- tokenAddrs.push_back (target_pk);
17521756 if (--limit == 0 ) {
17531757 break ;
17541758 }
@@ -1770,9 +1774,9 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17701774 seq = s_blockchain.getPreviousNonEmptyBlock (seq).first ;
17711775 }
17721776
1773- tm .loadTokenInfo (tokenAddrs, [&_return](const TokensMap& tm , const HoldersMap&) {
1777+ tm_ .loadTokenInfo ([&_return](const TokensMap& tm_ , const HoldersMap&) {
17741778 for (auto & transfer : _return.transfers ) {
1775- if (auto it = tm .find (BlockChain::getAddressFromKey (transfer.token )); it != tm .end ())
1779+ if (auto it = tm_ .find (BlockChain::getAddressFromKey (transfer.token )); it != tm_ .end ())
17761780 transfer.code = it->second .symbol ;
17771781 }
17781782 });
@@ -1782,19 +1786,19 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17821786
17831787void APIHandler::TokenWalletTransfersGet (api::TokenTransfersResult& _return, const general::Address& token, const general::Address& address, int64_t offset, int64_t limit) {
17841788 const csdb::Address wallet = BlockChain::getAddressFromKey (address);
1785- tokenTransactionsInternal (_return, *this , tm , token, true , true , offset, limit, wallet);
1789+ tokenTransactionsInternal (_return, *this , tm_ , token, true , true , offset, limit, wallet);
17861790}
17871791
17881792void APIHandler::TokenTransactionsGet (api::TokenTransactionsResult& _return, const general::Address& token, int64_t offset, int64_t limit) {
1789- tokenTransactionsInternal (_return, *this , tm , token, false , false , offset, limit);
1793+ tokenTransactionsInternal (_return, *this , tm_ , token, false , false , offset, limit);
17901794}
17911795
17921796void APIHandler::TokenInfoGet (api::TokenInfoResult& _return, const general::Address& token) {
17931797 bool found = false ;
17941798 const csdb::Address addr = BlockChain::getAddressFromKey (token);
1795- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , addr), [&token, &addr, &found, &_return](const TokensMap& tm , const HoldersMap&) {
1796- auto tIt = tm .find (addr);
1797- if (tIt != tm .end ()) {
1799+ tm_ .loadTokenInfo ([&token, &addr, &found, &_return](const TokensMap& tm_ , const HoldersMap&) {
1800+ auto tIt = tm_ .find (addr);
1801+ if (tIt != tm_ .end ()) {
17981802 found = true ;
17991803 putTokenInfo (_return.token , token, tIt->second );
18001804 }
@@ -1846,9 +1850,9 @@ void APIHandler::TokenHoldersGet(api::TokenHoldersResult& _return, const general
18461850 }
18471851
18481852 const csdb::Address addr = BlockChain::getAddressFromKey (token);
1849- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , addr), [&token, &addr, &found, &offset, &limit, &_return, comparator](const TokensMap& tm , const HoldersMap&) {
1850- auto tIt = tm .find (addr);
1851- if (tIt != tm .end ()) {
1853+ tm_ .loadTokenInfo ([&token, &addr, &found, &offset, &limit, &_return, comparator](const TokensMap& tm_ , const HoldersMap&) {
1854+ auto tIt = tm_ .find (addr);
1855+ if (tIt != tm_ .end ()) {
18521856 found = true ;
18531857 _return.count = (uint32_t ) tIt->second .realHoldersCount ;
18541858
@@ -1891,23 +1895,14 @@ void APIHandler::TokensListGet(api::TokensListResult& _return, int64_t offset, i
18911895
18921896 switch (order) {
18931897 case TL_Code:
1894- #ifdef SLOW_WORK
18951898 comparator = getComparator<VT>(&Token::symbol, desc);
18961899 break ;
1897- #endif
1898- [[fallthrough]];
18991900 case TL_Name:
1900- #ifdef SLOW_WORK
19011901 comparator = getComparator<VT>(&Token::name, desc);
19021902 break ;
1903- #endif
1904- [[fallthrough]];
19051903 case TL_TotalSupply:
1906- #ifdef SLOW_WORK
19071904 comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (stod (lhs.second .totalSupply ) < stod (rhs.second .totalSupply )); };
19081905 break ;
1909- #endif
1910- [[fallthrough]];
19111906 case TL_Address:
19121907 comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (lhs.first < rhs.first ); };
19131908 break ;
@@ -1922,39 +1917,34 @@ void APIHandler::TokensListGet(api::TokensListResult& _return, int64_t offset, i
19221917 break ;
19231918 };
19241919
1925- std::vector<csdb::Address> sortTokenAddrs;
1926- tm.loadTokenInfo ({}, [&, comparator](const TokensMap& tm, const HoldersMap&) {
1927- _return.count = (uint32_t )tm.size ();
1928- applyToSortedMap (tm, comparator, [&](const TokensMap::value_type& t) {
1929- if (--offset >= 0 )
1920+ tm_.loadTokenInfo ([&, comparator](const TokensMap& tm_, const HoldersMap&) {
1921+ _return.count = (uint32_t )tm_.size ();
1922+ applyToSortedMap (tm_, comparator, [&](const TokensMap::value_type& t) {
1923+ if (--offset >= 0 ) {
19301924 return true ;
1925+ }
19311926
19321927 api::TokenInfo tok;
19331928 putTokenInfo (tok, fromByteArray (t.first .public_key ()), t.second );
1934- sortTokenAddrs.push_back (BlockChain::getAddressFromKey (tok.address ));
1929+
1930+ // filters
1931+ auto posName = tok.name .find (filters.name );
1932+ auto posCode = tok.code .find (filters.code );
1933+ if ((posName != std::string::npos && posCode != std::string::npos && tok.tokenStandard == filters.tokenStandard ) ||
1934+ (posName && posCode && !tok.tokenStandard ) ||
1935+ (posName && filters.code .empty () && !tok.tokenStandard ) ||
1936+ (filters.name .empty () && posCode && tok.tokenStandard ) ||
1937+ (filters.name .empty () && posCode && !tok.tokenStandard ) ||
1938+ (filters.name .empty () && filters.code .empty () && tok.tokenStandard ) ||
1939+ (filters.name .empty () && filters.code .empty () && !tok.tokenStandard ))
1940+ _return.tokens .push_back (tok);
19351941
19361942 if (--limit == 0 )
19371943 return false ;
19381944
19391945 return true ;
1946+ });
19401947 });
1941- });
1942-
1943- tm.loadTokenInfo (sortTokenAddrs, [&](const TokensMap& tm, const HoldersMap&) {
1944- api::TokenInfo tok;
1945- for (auto t : tm) {
1946- if ((t.second .name .find (filters.name ) != std::string::npos && t.second .symbol .find (filters.code ) != std::string::npos && t.second .tokenStandard == filters.tokenStandard ) ||
1947- (t.second .name .find (filters.name ) && t.second .symbol .find (filters.code ) && !t.second .tokenStandard ) ||
1948- (t.second .name .find (filters.name ) && filters.code .empty () && !t.second .tokenStandard ) ||
1949- (filters.name .empty () && t.second .symbol .find (filters.code ) && t.second .tokenStandard ) ||
1950- (filters.name .empty () && t.second .symbol .find (filters.code ) && !t.second .tokenStandard ) ||
1951- (filters.name .empty () && filters.code .empty () && t.second .tokenStandard ) ||
1952- (filters.name .empty () && filters.code .empty () && !t.second .tokenStandard )) {
1953- putTokenInfo (tok, fromByteArray (t.first .public_key ()), t.second );
1954- _return.tokens .push_back (tok);
1955- }
1956- }
1957- });
19581948
19591949 SetResponseStatus (_return.status , APIRequestStatusType::SUCCESS);
19601950}
0 commit comments