Skip to content

Commit ebca9e1

Browse files
committed
Merge branch 'dapsnet' of https://gitlab.com/credits_bc/core/node into dev
2 parents 0fe6f66 + 0a06873 commit ebca9e1

5 files changed

Lines changed: 115 additions & 88 deletions

File tree

api/include/tokens.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct Token {
4242
std::string totalSupply { "not loaded" };
4343

4444
struct HolderInfo {
45-
std::string balance { "not loaded" };
45+
std::string balance { "0" };
4646
uint64_t transfersCount = 0;
4747
};
4848
std::map<HolderKey, HolderInfo> holders; // Including guys with zero balance
@@ -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&)>, bool needLoad = true);
63+
void loadTokenInfo(const std::vector<csdb::Address>& vaddr, const std::function<void(const TokensMap&, const HoldersMap&)>);
6464

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

api/src/apihandler.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,8 @@ void APIHandler::WalletDataGet(WalletDataGetResult& _return, const general::Addr
130130
const csdb::Address addr = BlockChain::getAddressFromKey(address);
131131
BlockChain::WalletData wallData{};
132132
BlockChain::WalletId wallId{};
133-
if (!s_blockchain.findWalletData(addr, wallData, wallId)) {
134-
SetResponseStatus(_return.status, APIRequestStatusType::NOT_FOUND);
133+
if (!s_blockchain.findWalletData(addr, wallData, wallId))
135134
return;
136-
}
137135
_return.walletData.walletId = wallId;
138136
_return.walletData.balance.integral = wallData.balance_.integral();
139137
_return.walletData.balance.fraction = static_cast<decltype(_return.walletData.balance.fraction)>(wallData.balance_.fraction());
@@ -1606,7 +1604,18 @@ void APIHandler::ExecuteCountGet(ExecuteCountGetResult& _return, const std::stri
16061604

16071605
void APIHandler::TokenBalancesGet(api::TokenBalancesResult& _return, const general::Address& address) {
16081606
const csdb::Address addr = BlockChain::getAddressFromKey(address);
1609-
tm.loadTokenInfo(std::vector(1, addr), [&_return, &addr](const TokensMap& tokens, const HoldersMap& holders) {
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) {
16101619
auto holderIt = holders.find(addr);
16111620
if (holderIt != holders.end()) {
16121621
for (const auto& tokAddr : holderIt->second) {
@@ -1714,7 +1723,7 @@ void APIHandler::TokenTransfersListGet(api::TokenTransfersResult& _return, int64
17141723
totalTransfers += t.second.transfersCount;
17151724
tokenTransPools.insert(std::make_pair(s_blockchain.getLastTransaction(t.first).pool_seq(), t.first));
17161725
}
1717-
}, false);
1726+
});
17181727

17191728
_return.count = uint32_t(totalTransfers);
17201729

@@ -1782,7 +1791,6 @@ void APIHandler::TokenTransactionsGet(api::TokenTransactionsResult& _return, con
17821791

17831792
void APIHandler::TokenInfoGet(api::TokenInfoResult& _return, const general::Address& token) {
17841793
bool found = false;
1785-
17861794
const csdb::Address addr = BlockChain::getAddressFromKey(token);
17871795
tm.loadTokenInfo(std::vector<csdb::Address>(1, addr), [&token, &addr, &found, &_return](const TokensMap& tm, const HoldersMap&) {
17881796
auto tIt = tm.find(addr);
@@ -1791,7 +1799,6 @@ void APIHandler::TokenInfoGet(api::TokenInfoResult& _return, const general::Addr
17911799
putTokenInfo(_return.token, token, tIt->second);
17921800
}
17931801
});
1794-
17951802
SetResponseStatus(_return.status, found ? APIRequestStatusType::SUCCESS : APIRequestStatusType::FAILURE);
17961803
}
17971804

@@ -1884,17 +1891,26 @@ void APIHandler::TokensListGet(api::TokensListResult& _return, int64_t offset, i
18841891

18851892
switch (order) {
18861893
case TL_Code:
1894+
#ifdef SLOW_WORK
18871895
comparator = getComparator<VT>(&Token::symbol, desc);
18881896
break;
1897+
#endif
1898+
[[fallthrough]];
18891899
case TL_Name:
1900+
#ifdef SLOW_WORK
18901901
comparator = getComparator<VT>(&Token::name, desc);
18911902
break;
1892-
case TL_Address:
1893-
comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (lhs.first < rhs.first); };
1894-
break;
1903+
#endif
1904+
[[fallthrough]];
18951905
case TL_TotalSupply:
1906+
#ifdef SLOW_WORK
18961907
comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (stod(lhs.second.totalSupply) < stod(rhs.second.totalSupply)); };
18971908
break;
1909+
#endif
1910+
[[fallthrough]];
1911+
case TL_Address:
1912+
comparator = [desc](const VT& lhs, const VT& rhs) { return desc ^ (lhs.first < rhs.first); };
1913+
break;
18981914
case TL_HoldersCount:
18991915
comparator = getComparator<VT>(&Token::realHoldersCount, desc);
19001916
break;

api/src/tokens.cpp

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -184,47 +184,7 @@ void TokensMaster::refreshTokenState(const csdb::Address& token, const std::stri
184184
auto& t = tokens_[token];
185185
t.name = name;
186186
t.symbol = symbol;
187-
t.totalSupply = totalSupply;
188-
189-
// balance
190-
if (checkBalance) {
191-
executor::ExecuteByteCodeMultipleResult result;
192-
if (byteCodeObjects.empty())
193-
return;
194-
195-
executor::SmartContractBinary smartContractBinary;
196-
smartContractBinary.contractAddress = addr;
197-
smartContractBinary.object.byteCodeObjects = byteCodeObjects;
198-
smartContractBinary.object.instance = newState;
199-
smartContractBinary.stateCanModify = 0;
200-
201-
std::vector<csdb::Address> holders;
202-
holders.reserve(t.holders.size());
203-
for (auto& h : t.holders)
204-
holders.push_back(h.first);
205-
206-
std::vector<std::vector<general::Variant>> holderKeysParams;
207-
holderKeysParams.reserve(holders.size());
208-
for (auto& h : holders) {
209-
general::Variant var;
210-
auto key = h.public_key();
211-
var.__set_v_string(EncodeBase58(cs::Bytes(key.begin(), key.end())));
212-
holderKeysParams.push_back(std::vector<general::Variant>(1, var));
213-
}
214-
215-
api_->getExecutor().executeByteCodeMultiple(result, dpAddr, smartContractBinary, "balanceOf", holderKeysParams, 100, executor::Executor::kUseLastSequence);
216-
217-
++t.realHoldersCount = 0;
218-
if (!result.status.code && (result.results.size() == holders.size())) {
219-
for (uint32_t i = 0; i < holders.size(); ++i) {
220-
const auto& res = result.results[i];
221-
if (!res.status.code) {
222-
t.holders[holders[i]].balance = tryExtractAmount(getVariantAs<std::string>(res.ret_val));
223-
++t.realHoldersCount;
224-
}
225-
}
226-
}
227-
}
187+
t.totalSupply = totalSupply;
228188
}
229189

230190
/* Call under data lock only */
@@ -269,6 +229,73 @@ void TokensMaster::updateTokenChaches(const csdb::Address& addr, const std::stri
269229
initiateHolder(tIt->second, tIt->first, regDude);
270230
}
271231
}
232+
233+
// Balance update
234+
auto refreshBalance = [&](const csdb::Address& addrFrom, const csdb::Address& addrTo = csdb::Address{}, const std::string& amount = "") {
235+
auto getCurrBalance = [&](const csdb::Address& addrOwner) -> std::string {
236+
bool present = false;
237+
auto byteCodeObjects = api_->getSmartByteCode(addr, present);
238+
if (!present || byteCodeObjects.empty()) return "0";
239+
240+
general::Address addrToken{ addr.public_key().begin(), addr.public_key().end() };
241+
242+
auto dpAddrPK = tokens_[addr].owner.public_key();
243+
general::Address dpAddr{ dpAddrPK.begin(), dpAddrPK.end() };
244+
245+
// param: owner
246+
std::vector<general::Variant> param(1);
247+
std::string addrOwnerStr = addrOwner.to_api_addr();
248+
param[0].__set_v_string(EncodeBase58({ addrOwnerStr.begin(), addrOwnerStr.end() }));
249+
//
250+
std::string retBalance{ "0" };
251+
executeAndCall<std::string>(api_, dpAddr, addrToken, byteCodeObjects, newState, "balanceOf", param,
252+
[&retBalance](const std::string& balance) { retBalance = balance; });
253+
254+
if (!std::all_of(retBalance.begin(), retBalance.end(), [](char ch) { return (isdigit(ch) || ch == '.'); })) {
255+
retBalance = "0";
256+
cserror() << "executor return text balance!";
257+
}
258+
return retBalance;
259+
};
260+
261+
auto& t = tokens_[addr];
262+
if (addrTo == csdb::Address{}) { // for deploy token
263+
t.holders[addrFrom].balance = getCurrBalance(addrFrom);
264+
++t.realHoldersCount;
265+
return;
266+
}
267+
268+
// from
269+
auto& currFromBalance = t.holders[addrFrom].balance;
270+
auto newFromBalance = [&] {
271+
if (isZeroAmount(currFromBalance))
272+
return getCurrBalance(addrFrom);
273+
else
274+
return std::to_string(stof(currFromBalance) - stof(amount));
275+
}();
276+
if (isZeroAmount(newFromBalance))
277+
--t.realHoldersCount;
278+
currFromBalance = newFromBalance;
279+
280+
// to
281+
auto& currToBalance = t.holders[addrTo].balance;
282+
auto newToBalance = [&] {
283+
if (isZeroAmount(currToBalance))
284+
return getCurrBalance(addrTo);
285+
else
286+
return std::to_string(stof(currToBalance) + stof(amount));
287+
}();
288+
if (isZeroAmount(currToBalance) && !isZeroAmount(newToBalance))
289+
++t.realHoldersCount;
290+
currToBalance = newToBalance;
291+
};
292+
293+
if (ps.method == "transfer" && ps.params.size() == 2)
294+
refreshBalance(ps.initiator, tryExtractPublicKey(ps.params[0].v_string), ps.params[1].v_string);
295+
else if (ps.method == "transferFrom" && ps.params.size() == 3)
296+
refreshBalance(tryExtractPublicKey(ps.params[0].v_string), tryExtractPublicKey(ps.params[1].v_string), ps.params[2].v_string);
297+
else if (ps.method.empty()) // deploy token
298+
refreshBalance(tokens_[addr].owner);
272299
}
273300

274301
void TokensMaster::checkNewDeploy(const csdb::Address& sc, const csdb::Address& deployer, const api::SmartContractInvocation& sci) {
@@ -303,40 +330,24 @@ void TokensMaster::checkNewState(const csdb::Address& sc, const csdb::Address& i
303330
updateTokenChaches(sc, newState, ps);
304331
}
305332

306-
void TokensMaster::loadTokenInfo(const std::vector<csdb::Address>& vtokenAddr, const std::function<void(const TokensMap&, const HoldersMap&)> func, bool needLoad) {
333+
void TokensMaster::loadTokenInfo(const std::vector<csdb::Address>& vtokenAddr, const std::function<void(const TokensMap&, const HoldersMap&)> func) {
307334
std::lock_guard<decltype(dataMut_)> l(dataMut_);
308-
if (!needLoad) {
335+
if (vtokenAddr.empty()) {
309336
func(tokens_, holders_);
310337
return;
311338
}
312-
auto freeChache = [&tokens_ = tokens_](const csdb::Address& addr, bool checkBalance = true) {
313-
tokens_[addr].name = "not loaded";
314-
tokens_[addr].symbol = "not loaded";
315-
tokens_[addr].totalSupply = "not loaded";
316-
if (checkBalance) {
317-
for (auto& h : tokens_[addr].holders)
318-
h.second.balance = "not loaded";
319-
}
320-
};
321-
322-
if (!vtokenAddr.empty()) {
323-
TokensMap loadedToken;
324-
for (const auto& addr : vtokenAddr) {
325-
if (tokens_.find(addr) == tokens_.end())
326-
continue;
327-
refreshTokenState(addr, cs::SmartContracts::get_contract_state(api_->get_s_blockchain(), addr));
328-
loadedToken[addr] = tokens_[addr];
329-
}
330-
func(loadedToken, holders_);
331-
for (const auto& itLoaded : loadedToken)
332-
freeChache(itLoaded.first);
333-
}
334-
else {
335-
for (const auto& tk : tokens_) // need for sort
336-
refreshTokenState(tk.first, cs::SmartContracts::get_contract_state(api_->get_s_blockchain(), tk.first), false);
337-
func(tokens_, holders_);
338-
for (const auto& tk : tokens_)
339-
freeChache(tk.first, false);
339+
TokensMap loadedToken;
340+
for (const auto& addr : vtokenAddr) {
341+
if (tokens_.find(addr) == tokens_.end())
342+
continue;
343+
refreshTokenState(addr, cs::SmartContracts::get_contract_state(api_->get_s_blockchain(), addr));
344+
loadedToken[addr] = tokens_[addr];
345+
}
346+
func(loadedToken, holders_);
347+
for (const auto& itLoaded : loadedToken) {
348+
tokens_[itLoaded.first].name = "not loaded";
349+
tokens_[itLoaded.first].symbol = "not loaded";
350+
tokens_[itLoaded.first].totalSupply = "not loaded";
340351
}
341352
}
342353

@@ -380,7 +391,7 @@ void TokensMaster::checkNewDeploy(const csdb::Address&, const csdb::Address&, co
380391
}
381392
void TokensMaster::checkNewState(const csdb::Address&, const csdb::Address&, const api::SmartContractInvocation&, const std::string&) {
382393
}
383-
void TokensMaster::loadTokenInfo(const std::vector<csdb::Address>&, const std::function<void(const TokensMap&, const HoldersMap&)>, bool) {
394+
void TokensMaster::loadTokenInfo(const std::vector<csdb::Address>&, const std::function<void(const TokensMap&, const HoldersMap&)>) {
384395
}
385396
bool TokensMaster::isTransfer(const std::string&, const std::vector<general::Variant>&) {
386397
return false;

csnode/src/transactionsvalidator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ bool TransactionsValidator::validateTransactionAsSource(SolverContext& context,
180180
}
181181

182182
if (wallState.balance_ < zeroBalance_ && !SmartContracts::is_new_state(trx)) {
183-
csdebug() << kLogPrefix << "transaction[" << trxInd << "] results to potentially negative balance " << wallState.balance_.to_double();
183+
csdetails() << kLogPrefix << "transaction[" << trxInd << "] results to potentially negative balance " << wallState.balance_.to_double();
184184
// will be checked in rejected smarts
185185
if (context.smart_contracts().is_known_smart_contract(trx.source())) {
186186
return false;
@@ -255,7 +255,7 @@ size_t TransactionsValidator::makeSmartsValid(SolverContext& context, RejectedSm
255255
if (s.absolute_address(smarts[i].first.source()) == s.absolute_address(source) && smarts[i].second < maskSize) {
256256
maskIncluded[smarts[i].second] = kValidMarker;
257257
++restoredCounter;
258-
csdebug() << kLogPrefix << "balance of transation[" << smarts[i].second << "] source is replenished by other transaction";
258+
csdetails() << kLogPrefix << "balance of transation[" << smarts[i].second << "] source is replenished by other transaction";
259259

260260
WalletsState::WalletId walletId{};
261261
WalletsState::WalletData& wallState = walletsState_.getData(smarts[i].first.source(), walletId);

solver/src/smartcontracts.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,7 @@ void SmartContracts::on_next_block_impl(const csdb::Pool& block, bool reading_db
12581258
csdb::Transaction starter = get_transaction(contract_item.ref_execute, abs_addr);
12591259
if (starter.is_valid()) {
12601260
if (!reading_db) {
1261-
csdebug() << kLogPrefix << "found emitted transaction in " << contract_item.ref_execute;
1261+
csdetails() << kLogPrefix << "found emitted transaction in " << contract_item.ref_execute;
12621262
}
12631263
emit signal_emitted_accepted(tr, starter);
12641264
}
@@ -1647,7 +1647,7 @@ void SmartContracts::on_execution_completed_impl(const std::vector<SmartExecutio
16471647
// is not by primary contract emitted
16481648
continue;
16491649
}
1650-
csdebug() << kLogPrefix << "set innerID = " << next_id << " in " << data_item.contract_ref << " emitted transaction";
1650+
csdetails() << kLogPrefix << "set innerID = " << next_id << " in " << data_item.contract_ref << " emitted transaction";
16511651
// auto inner id generating
16521652
csdb::Transaction tmp(
16531653
++next_id,

0 commit comments

Comments
 (0)