Skip to content
This repository was archived by the owner on Feb 12, 2025. It is now read-only.

Commit

Permalink
Improve get balance time to compute
Browse files Browse the repository at this point in the history
Use postgresql sum instead of useless fetching-all + ordering before summing in memory
  • Loading branch information
BertrandD committed Nov 8, 2022
1 parent 8565b59 commit 31a92e9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 19 deletions.
28 changes: 9 additions & 19 deletions core/src/wallet/bitcoin/BitcoinLikeAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,9 @@ namespace ledger {
std::vector<BitcoinLikeBlockchainExplorerOutput> utxo;

utils::cache_type<bool, std::string> cache{};
std::function<bool(const std::string &)> filter = utils::cached(cache, utils::to_function([&keychain](const std::string addr) -> bool { // NOLINT(performance-unnecessary-value-param)
return keychain->contains(addr);
}));
const std::function<bool(const std::string &)> filter = utils::cached(cache, utils::to_function([&keychain](const std::string addr) -> bool { // NOLINT(performance-unnecessary-value-param)
return keychain->contains(addr);
}));

BitcoinLikeUTXODatabaseHelper::queryUTXO(sql, self->getAccountUid(), from, to - from, worthlessUtxoAmount, utxo, filter);
return functional::map<BitcoinLikeBlockchainExplorerOutput, std::shared_ptr<api::BitcoinLikeOutput>>(utxo, [&currency](const BitcoinLikeBlockchainExplorerOutput &output) -> std::shared_ptr<api::BitcoinLikeOutput> {
Expand Down Expand Up @@ -597,20 +597,10 @@ namespace ledger {
return FuturePtr<Amount>::async(getWallet()->getPool()->getThreadPoolExecutionContext(), [=]() -> std::shared_ptr<Amount> {
const auto &uid = self->getAccountUid();
soci::session sql(self->getWallet()->getDatabase()->getReadonlyPool());
std::vector<BitcoinLikeBlockchainExplorerOutput> utxos;
auto keychain = self->getKeychain();
utils::cache_type<bool, std::string> cache{};
std::function<bool(const std::string &)> filter = utils::cached(cache, utils::to_function([&keychain](const std::string addr) -> bool { // NOLINT(performance-unnecessary-value-param)
return keychain->contains(addr);
}));

BigInt sum(0);
auto keychain = self->getKeychain();
constexpr auto worthlessUtxoAmount = 0;
BitcoinLikeUTXODatabaseHelper::queryUTXO(sql, uid, 0, std::numeric_limits<int32_t>::max(), worthlessUtxoAmount, utxos, filter);
for (const auto &utxo : utxos) {
sum = sum + utxo.value;
}
Amount balance(self->getWallet()->getCurrency(), 0, sum);
const auto sum = BitcoinLikeUTXODatabaseHelper::sumUTXO(sql, uid, worthlessUtxoAmount);
const Amount balance(self->getWallet()->getCurrency(), 0, sum);
self->getWallet()->updateBalanceCache(self->getIndex(), balance);
return std::make_shared<Amount>(balance);
});
Expand All @@ -636,9 +626,9 @@ namespace ledger {
auto keychain = self->getKeychain();

utils::cache_type<bool, std::string> cache{};
std::function<bool(const std::string &)> filter = utils::cached(cache, utils::to_function([&keychain](const std::string addr) -> bool { // NOLINT(performance-unnecessary-value-param)
return keychain->contains(addr);
}));
const std::function<bool(const std::string &)> filter = utils::cached(cache, utils::to_function([&keychain](const std::string addr) -> bool { // NOLINT(performance-unnecessary-value-param)
return keychain->contains(addr);
}));

// Get operations related to an account
OperationDatabaseHelper::queryOperations(sql, uid, operations, filter);
Expand Down
16 changes: 16 additions & 0 deletions core/src/wallet/bitcoin/database/BitcoinLikeUTXODatabaseHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ namespace ledger {
return out.size();
}

BigInt BitcoinLikeUTXODatabaseHelper::sumUTXO(soci::session &sql, const std::string &accountUid, int64_t dustAmount) {
rowset<row> rows = (sql.prepare << "SELECT sum(o.amount)::bigint"
" FROM bitcoin_outputs AS o "
" LEFT OUTER JOIN bitcoin_inputs AS i ON i.previous_tx_uid = o.transaction_uid "
" AND i.previous_output_idx = o.idx"
" WHERE i.previous_tx_uid IS NULL AND o.account_uid = :uid AND o.amount > :dustAmount",
use(accountUid), use(dustAmount));

for (auto &row : rows) {
if (row.get_indicator(0) != i_null) {
return row.get<BigInt>(0);
}
}
return BigInt(0);
}

std::vector<BitcoinLikeUtxo> BitcoinLikeUTXODatabaseHelper::queryAllUtxos(
soci::session &session,
std::string const &accountUid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ namespace ledger {
std::vector<BitcoinLikeBlockchainExplorerOutput> &out,
const std::function<bool(const std::string &address)> &filter);

public:
static BigInt sumUTXO(soci::session &sql,
const std::string &accountUid,
int64_t dustAmount);

static std::size_t UTXOcount(soci::session &sql,
const std::string &accountUid,
int64_t dustAmount,
Expand Down

0 comments on commit 31a92e9

Please sign in to comment.