Skip to content

Commit 8903cf4

Browse files
author
Alexander Avramenko
committed
Merge branch 'dapsnet'
2 parents 2d55f10 + aca4d85 commit 8903cf4

File tree

4 files changed

+127
-105
lines changed

4 files changed

+127
-105
lines changed

api/include/apihandler.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,10 +698,14 @@ class APIHandler : public APIHandlerInterface {
698698
return executor_;
699699
}
700700

701+
bool isBDLoaded() { return isBDLoaded_; }
702+
701703
private:
702704
::csstats::AllStats stats_;
703705
executor::Executor& executor_;
704706

707+
bool isBDLoaded_{ false };
708+
705709
struct smart_trxns_queue {
706710
cs::SpinLock lock{ATOMIC_FLAG_INIT};
707711
std::condition_variable_any new_trxn_cv{};
@@ -817,7 +821,7 @@ class APIHandler : public APIHandlerInterface {
817821

818822
std::optional<std::string> checkTransaction(const ::api::Transaction&);
819823

820-
TokensMaster tm;
824+
TokensMaster tm_;
821825

822826
const uint8_t ERROR_CODE = 1;
823827

api/include/tokens.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ struct Token {
3737
uint64_t realHoldersCount = 0; // Non-zero balance
3838

3939
// TmpÑache: name, symbol, totalSupply, balance
40-
std::string name { "not loaded" };
41-
std::string symbol { "not loaded" };
42-
std::string totalSupply { "not loaded" };
40+
std::string name;
41+
std::string symbol;
42+
std::string totalSupply;
4343

4444
struct HolderInfo {
4545
std::string balance { "0" };
@@ -60,7 +60,7 @@ class TokensMaster {
6060

6161
void checkNewState(const csdb::Address& sc, const csdb::Address& initiator, const api::SmartContractInvocation&, const std::string& newState);
6262

63-
void loadTokenInfo(const std::vector<csdb::Address>& vaddr, const std::function<void(const TokensMap&, const HoldersMap&)>);
63+
void loadTokenInfo(const std::function<void(const TokensMap&, const HoldersMap&)>);
6464

6565
static bool isTransfer(const std::string& method, const std::vector<general::Variant>& params);
6666

@@ -85,9 +85,9 @@ class TokensMaster {
8585

8686
void updateTokenChaches(const csdb::Address& addr, const std::string& newState, const TokenInvocationData::Params& params);
8787

88-
private:
89-
void refreshTokenState(const csdb::Address& token, const std::string& newState, bool checkBalance = true);
88+
void refreshTokenState(const csdb::Address& token, const std::string& newState, bool checkBalance = false);
9089

90+
private:
9191
void initiateHolder(Token&, const csdb::Address& token, const csdb::Address& holder, bool increaseTransfers = false);
9292

9393
api::APIHandler* api_;

api/src/apihandler.cpp

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -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

928927
void 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

932947
void 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

14221439
template <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

16191636
void 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

16611667
void 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

16651671
void 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

17971801
void 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

18021806
void 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

18061810
void 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

Comments
 (0)