@@ -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 ();
@@ -305,7 +304,7 @@ api::SealedTransaction APIHandler::convertTransaction(const csdb::Transaction& t
305304
306305 if (is_smart_deploy (sci)) {
307306 result.trxn .type = api::TransactionType::TT_SmartDeploy;
308- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , target), [&isToken, &target, &result](const TokensMap& tokens, const HoldersMap&) {
307+ tm_ .loadTokenInfo ([&isToken, &target, &result](const TokensMap& tokens, const HoldersMap&) {
309308 auto it = tokens.find (target);
310309 if (it != tokens.end ()) {
311310 isToken = true ;
@@ -328,7 +327,7 @@ api::SealedTransaction APIHandler::convertTransaction(const csdb::Transaction& t
328327 bool isTransfer = TokensMaster::isTransfer (sci.method , sci.params );
329328 result.trxn .type = api::TransactionType::TT_SmartExecute;
330329 if (isTransfer) {
331- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , target), [&isToken, &isTransfer, &target, &result](const TokensMap& tokens, const HoldersMap&) {
330+ tm_ .loadTokenInfo ([&isToken, &isTransfer, &target, &result](const TokensMap& tokens, const HoldersMap&) {
332331 auto it = tokens.find (target);
333332 if (it != tokens.end ()) {
334333 isToken = true ;
@@ -568,7 +567,7 @@ api::SmartContract APIHandler::fetch_smart_body(const csdb::Transaction& tr) {
568567 res.address = fromByteArray (s_blockchain.getAddressByType (tr.target (), BlockChain::AddressType::PublicKey).public_key ());
569568
570569#ifdef TOKENS_CACHE
571- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , tr. target ()), [&tr, &res](const TokensMap& tokens, const HoldersMap&) {
570+ tm_ .loadTokenInfo ([&tr, &res](const TokensMap& tokens, const HoldersMap&) {
572571 auto it = tokens.find (tr.target ());
573572 if (it != tokens.end ())
574573 res.smartContractDeploy .tokenStandard = it->second .tokenStandard ;
@@ -927,6 +926,22 @@ void APIHandler::SmartContractGet(api::SmartContractGetResult& _return, const ge
927926
928927void APIHandler::store_block_slot (const csdb::Pool& pool) {
929928 updateSmartCachesPool (pool);
929+ #ifdef TOKENS_CACHE
930+ if (!isBDLoaded_) {
931+ isBDLoaded_ = true ;
932+ tm_.loadTokenInfo ([&](const TokensMap& tokens, const HoldersMap&) {
933+ int count{}, i{};
934+ size_t tokenSize = tokens.size ();
935+ cslog () << " tokens are loading(" << tokenSize <<" )..." ;
936+ for (auto & tk : tokens) {
937+ if (tokenSize > 100 && !(i++ % (tokenSize / 10 )))
938+ cslog () << " loading tokens: " << 10 *(count++) << " %" ;
939+ tm_.refreshTokenState (tk.first , cs::SmartContracts::get_contract_state (get_s_blockchain (), tk.first ), true );
940+ }
941+ cslog () << " tokens loaded!" ;
942+ });
943+ }
944+ #endif
930945}
931946
932947void APIHandler::collect_all_stats_slot (const csdb::Pool& pool) {
@@ -1073,6 +1088,8 @@ bool APIHandler::updateSmartCachesTransaction(csdb::Transaction trxn, cs::Sequen
10731088 auto newHashStr = trxn.user_field (cs::trx_uf::new_state::Hash).template value <std::string>();
10741089 if (!newHashStr.empty ())
10751090 std::copy (newHashStr.begin (), newHashStr.end (), res.hash .begin ());
1091+ else
1092+ res.hash = cs::Zero::hash;
10761093 res.retVal = trxn.user_field (cs::trx_uf::new_state::RetVal).template value <std::string>();
10771094 res.isOld = (res.hash == oldHash.hash );
10781095 res.condFlg = true ;
@@ -1084,13 +1101,13 @@ bool APIHandler::updateSmartCachesTransaction(csdb::Transaction trxn, cs::Sequen
10841101 auto caller_pk = s_blockchain.getAddressByType (execTrans.source (), BlockChain::AddressType::PublicKey);
10851102
10861103 if (is_smart_deploy (smart))
1087- tm .checkNewDeploy (target_pk, caller_pk, smart);
1104+ tm_ .checkNewDeploy (target_pk, caller_pk, smart);
10881105
10891106 if (newStateStr.empty ()) {
10901107 newStateStr = cs::SmartContracts::get_contract_state (s_blockchain, target_pk);
10911108 }
10921109 if (!newStateStr.empty ()) {
1093- tm .checkNewState (target_pk, caller_pk, smart, newStateStr);
1110+ tm_ .checkNewState (target_pk, caller_pk, smart, newStateStr);
10941111 }
10951112 }
10961113 }
@@ -1420,7 +1437,7 @@ void putTokenInfo(api::TokenInfo& ti, const general::Address& addr, const Token&
14201437}
14211438
14221439template <typename ResultType>
1423- void tokenTransactionsInternal (ResultType& _return, APIHandler& handler, TokensMaster& tm , const general::Address& token, bool transfersOnly, bool filterByWallet, int64_t offset,
1440+ void tokenTransactionsInternal (ResultType& _return, APIHandler& handler, TokensMaster& tm_ , const general::Address& token, bool transfersOnly, bool filterByWallet, int64_t offset,
14241441 int64_t limit, const csdb::Address& wallet = csdb::Address()) {
14251442 if (!validatePagination (_return, handler, offset, limit)) {
14261443 return ;
@@ -1430,9 +1447,9 @@ void tokenTransactionsInternal(ResultType& _return, APIHandler& handler, TokensM
14301447 bool tokenFound = false ;
14311448 std::string code;
14321449
1433- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , addr), [&addr, &tokenFound, &transfersOnly, &filterByWallet, &code, &wallet, &_return](const TokensMap& tm , const HoldersMap&) {
1434- auto it = tm .find (addr);
1435- tokenFound = !(it == tm .end ());
1450+ tm_ .loadTokenInfo ([&addr, &tokenFound, &transfersOnly, &filterByWallet, &code, &wallet, &_return](const TokensMap& tm_ , const HoldersMap&) {
1451+ auto it = tm_ .find (addr);
1452+ tokenFound = !(it == tm_ .end ());
14361453 if (tokenFound) {
14371454 code = it->second .symbol ;
14381455 if (transfersOnly && !filterByWallet) {
@@ -1618,18 +1635,7 @@ void APIHandler::ExecuteCountGet(ExecuteCountGetResult& _return, const std::stri
16181635
16191636void APIHandler::TokenBalancesGet (api::TokenBalancesResult& _return, const general::Address& address) {
16201637 const csdb::Address addr = BlockChain::getAddressFromKey (address);
1621-
1622- std::vector<csdb::Address> vtokenAddr;
1623- tm.loadTokenInfo ({}, [&vtokenAddr, &addr](const TokensMap& tokens, const HoldersMap& holders) {
1624- if (auto holderIt = holders.find (addr); holderIt != holders.end ()) {
1625- for (const auto & tokAddr : holderIt->second ) {
1626- if (tokens.find (tokAddr) != tokens.end ())
1627- vtokenAddr.push_back (tokAddr);
1628- }
1629- }
1630- });
1631-
1632- tm.loadTokenInfo (vtokenAddr, [&_return, &addr](const TokensMap& tokens, const HoldersMap& holders) {
1638+ tm_.loadTokenInfo ([&_return, &addr](const TokensMap& tokens, const HoldersMap& holders) {
16331639 auto holderIt = holders.find (addr);
16341640 if (holderIt != holders.end ()) {
16351641 for (const auto & tokAddr : holderIt->second ) {
@@ -1659,7 +1665,7 @@ void APIHandler::TokenBalancesGet(api::TokenBalancesResult& _return, const gener
16591665}
16601666
16611667void APIHandler::TokenTransfersGet (api::TokenTransfersResult& _return, const general::Address& token, int64_t offset, int64_t limit) {
1662- tokenTransactionsInternal (_return, *this , tm , token, true , false , offset, limit);
1668+ tokenTransactionsInternal (_return, *this , tm_ , token, true , false , offset, limit);
16631669}
16641670
16651671void APIHandler::TokenTransferGet (api::TokenTransfersResult& _return, const general::Address& token, const TransactionId& id) {
@@ -1668,9 +1674,9 @@ void APIHandler::TokenTransferGet(api::TokenTransfersResult& _return, const gene
16681674 const csdb::Address addr = BlockChain::getAddressFromKey (token);
16691675
16701676 std::string code{};
1671- tm .loadTokenInfo (std::vector ( 1 , addr), [&addr, &code](const TokensMap& tm , const HoldersMap&) {
1672- const auto it = tm .find (addr);
1673- if (it != tm .cend ()) {
1677+ tm_ .loadTokenInfo ([&addr, &code](const TokensMap& tm_ , const HoldersMap&) {
1678+ const auto it = tm_ .find (addr);
1679+ if (it != tm_ .cend ()) {
16741680 code = it->second .symbol ;
16751681 }
16761682 });
@@ -1732,16 +1738,15 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17321738 uint64_t totalTransfers = 0 ;
17331739 std::multimap<cs::Sequence, csdb::Address> tokenTransPools;
17341740
1735- tm .loadTokenInfo ({}, [&totalTransfers, &tokenTransPools, this ](const TokensMap& tm , const HoldersMap&) {
1736- for (auto & t : tm ) {
1741+ tm_ .loadTokenInfo ([&totalTransfers, &tokenTransPools, this ](const TokensMap& tm_ , const HoldersMap&) {
1742+ for (auto & t : tm_ ) {
17371743 totalTransfers += t.second .transfersCount ;
17381744 tokenTransPools.insert (std::make_pair (s_blockchain.getLastTransaction (t.first ).pool_seq (), t.first ));
17391745 }
17401746 });
17411747
17421748 _return.count = uint32_t (totalTransfers);
17431749
1744- std::vector<csdb::Address> tokenAddrs;
17451750 cs::Sequence seq = s_blockchain.getLastNonEmptyBlock ().first ;
17461751 while (limit && seq != cs::kWrongSequence && tokenTransPools.size ()) {
17471752 auto it = tokenTransPools.find (seq);
@@ -1762,7 +1767,6 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17621767 csdb::Address target_pk = s_blockchain.getAddressByType (t.target (), BlockChain::AddressType::PublicKey);
17631768 auto addrPair = TokensMaster::getTransferData (target_pk, smart.method , smart.params );
17641769 addTokenResult (_return, target_pk, " " , pool, t, smart, addrPair, s_blockchain);
1765- tokenAddrs.push_back (target_pk);
17661770 if (--limit == 0 ) {
17671771 break ;
17681772 }
@@ -1784,9 +1788,9 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17841788 seq = s_blockchain.getPreviousNonEmptyBlock (seq).first ;
17851789 }
17861790
1787- tm .loadTokenInfo (tokenAddrs, [&_return](const TokensMap& tm , const HoldersMap&) {
1791+ tm_ .loadTokenInfo ([&_return](const TokensMap& tm_ , const HoldersMap&) {
17881792 for (auto & transfer : _return.transfers ) {
1789- if (auto it = tm .find (BlockChain::getAddressFromKey (transfer.token )); it != tm .end ())
1793+ if (auto it = tm_ .find (BlockChain::getAddressFromKey (transfer.token )); it != tm_ .end ())
17901794 transfer.code = it->second .symbol ;
17911795 }
17921796 });
@@ -1796,19 +1800,19 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17961800
17971801void APIHandler::TokenWalletTransfersGet (api::TokenTransfersResult& _return, const general::Address& token, const general::Address& address, int64_t offset, int64_t limit) {
17981802 const csdb::Address wallet = BlockChain::getAddressFromKey (address);
1799- tokenTransactionsInternal (_return, *this , tm , token, true , true , offset, limit, wallet);
1803+ tokenTransactionsInternal (_return, *this , tm_ , token, true , true , offset, limit, wallet);
18001804}
18011805
18021806void APIHandler::TokenTransactionsGet (api::TokenTransactionsResult& _return, const general::Address& token, int64_t offset, int64_t limit) {
1803- tokenTransactionsInternal (_return, *this , tm , token, false , false , offset, limit);
1807+ tokenTransactionsInternal (_return, *this , tm_ , token, false , false , offset, limit);
18041808}
18051809
18061810void APIHandler::TokenInfoGet (api::TokenInfoResult& _return, const general::Address& token) {
18071811 bool found = false ;
18081812 const csdb::Address addr = BlockChain::getAddressFromKey (token);
1809- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , addr), [&token, &addr, &found, &_return](const TokensMap& tm , const HoldersMap&) {
1810- auto tIt = tm .find (addr);
1811- if (tIt != tm .end ()) {
1813+ tm_ .loadTokenInfo ([&token, &addr, &found, &_return](const TokensMap& tm_ , const HoldersMap&) {
1814+ auto tIt = tm_ .find (addr);
1815+ if (tIt != tm_ .end ()) {
18121816 found = true ;
18131817 putTokenInfo (_return.token , token, tIt->second );
18141818 }
@@ -1860,9 +1864,9 @@ void APIHandler::TokenHoldersGet(api::TokenHoldersResult& _return, const general
18601864 }
18611865
18621866 const csdb::Address addr = BlockChain::getAddressFromKey (token);
1863- tm .loadTokenInfo (std::vector<csdb::Address>( 1 , addr), [&token, &addr, &found, &offset, &limit, &_return, comparator](const TokensMap& tm , const HoldersMap&) {
1864- auto tIt = tm .find (addr);
1865- if (tIt != tm .end ()) {
1867+ tm_ .loadTokenInfo ([&token, &addr, &found, &offset, &limit, &_return, comparator](const TokensMap& tm_ , const HoldersMap&) {
1868+ auto tIt = tm_ .find (addr);
1869+ if (tIt != tm_ .end ()) {
18661870 found = true ;
18671871 _return.count = (uint32_t ) tIt->second .realHoldersCount ;
18681872
@@ -1905,23 +1909,14 @@ void APIHandler::TokensListGet(api::TokensListResult& _return, int64_t offset, i
19051909
19061910 switch (order) {
19071911 case TL_Code:
1908- #ifdef SLOW_WORK
19091912 comparator = getComparator<VT>(&Token::symbol, desc);
19101913 break ;
1911- #endif
1912- [[fallthrough]];
19131914 case TL_Name:
1914- #ifdef SLOW_WORK
19151915 comparator = getComparator<VT>(&Token::name, desc);
19161916 break ;
1917- #endif
1918- [[fallthrough]];
19191917 case TL_TotalSupply:
1920- #ifdef SLOW_WORK
19211918 comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (stod (lhs.second .totalSupply ) < stod (rhs.second .totalSupply )); };
19221919 break ;
1923- #endif
1924- [[fallthrough]];
19251920 case TL_Address:
19261921 comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (lhs.first < rhs.first ); };
19271922 break ;
@@ -1936,39 +1931,34 @@ void APIHandler::TokensListGet(api::TokensListResult& _return, int64_t offset, i
19361931 break ;
19371932 };
19381933
1939- std::vector<csdb::Address> sortTokenAddrs;
1940- tm.loadTokenInfo ({}, [&, comparator](const TokensMap& tm, const HoldersMap&) {
1941- _return.count = (uint32_t )tm.size ();
1942- applyToSortedMap (tm, comparator, [&](const TokensMap::value_type& t) {
1943- if (--offset >= 0 )
1934+ tm_.loadTokenInfo ([&, comparator](const TokensMap& tm_, const HoldersMap&) {
1935+ _return.count = (uint32_t )tm_.size ();
1936+ applyToSortedMap (tm_, comparator, [&](const TokensMap::value_type& t) {
1937+ if (--offset >= 0 ) {
19441938 return true ;
1939+ }
19451940
19461941 api::TokenInfo tok;
19471942 putTokenInfo (tok, fromByteArray (t.first .public_key ()), t.second );
1948- sortTokenAddrs.push_back (BlockChain::getAddressFromKey (tok.address ));
1943+
1944+ // filters
1945+ auto posName = tok.name .find (filters.name );
1946+ auto posCode = tok.code .find (filters.code );
1947+ if ((posName != std::string::npos && posCode != std::string::npos && tok.tokenStandard == filters.tokenStandard ) ||
1948+ (posName && posCode && !tok.tokenStandard ) ||
1949+ (posName && filters.code .empty () && !tok.tokenStandard ) ||
1950+ (filters.name .empty () && posCode && tok.tokenStandard ) ||
1951+ (filters.name .empty () && posCode && !tok.tokenStandard ) ||
1952+ (filters.name .empty () && filters.code .empty () && tok.tokenStandard ) ||
1953+ (filters.name .empty () && filters.code .empty () && !tok.tokenStandard ))
1954+ _return.tokens .push_back (tok);
19491955
19501956 if (--limit == 0 )
19511957 return false ;
19521958
19531959 return true ;
1960+ });
19541961 });
1955- });
1956-
1957- tm.loadTokenInfo (sortTokenAddrs, [&](const TokensMap& tm, const HoldersMap&) {
1958- api::TokenInfo tok;
1959- for (auto t : tm) {
1960- if ((t.second .name .find (filters.name ) != std::string::npos && t.second .symbol .find (filters.code ) != std::string::npos && t.second .tokenStandard == filters.tokenStandard ) ||
1961- (t.second .name .find (filters.name ) && t.second .symbol .find (filters.code ) && !t.second .tokenStandard ) ||
1962- (t.second .name .find (filters.name ) && filters.code .empty () && !t.second .tokenStandard ) ||
1963- (filters.name .empty () && t.second .symbol .find (filters.code ) && t.second .tokenStandard ) ||
1964- (filters.name .empty () && t.second .symbol .find (filters.code ) && !t.second .tokenStandard ) ||
1965- (filters.name .empty () && filters.code .empty () && t.second .tokenStandard ) ||
1966- (filters.name .empty () && filters.code .empty () && !t.second .tokenStandard )) {
1967- putTokenInfo (tok, fromByteArray (t.first .public_key ()), t.second );
1968- _return.tokens .push_back (tok);
1969- }
1970- }
1971- });
19721962
19731963 SetResponseStatus (_return.status , APIRequestStatusType::SUCCESS);
19741964}
0 commit comments