diff --git a/core/src/wallet/tezos/explorers/ExternalTezosLikeBlockchainExplorer.cpp b/core/src/wallet/tezos/explorers/ExternalTezosLikeBlockchainExplorer.cpp index afc8bb0296..44f39893c2 100644 --- a/core/src/wallet/tezos/explorers/ExternalTezosLikeBlockchainExplorer.cpp +++ b/core/src/wallet/tezos/explorers/ExternalTezosLikeBlockchainExplorer.cpp @@ -69,11 +69,23 @@ namespace ledger { Future> ExternalTezosLikeBlockchainExplorer::getFees() { const bool parseNumbersAsString = true; - auto feesField = + const auto feesField = getConfiguration()->getString(api::Configuration::BLOCKCHAIN_EXPLORER_API_ENDPOINT) .value_or(api::TezosConfigurationDefaults::TEZOS_DEFAULT_API_ENDPOINT) == api::TezosConfigurationDefaults::TZSTATS_API_ENDPOINT ? "fee" : "fees"; + // The best value is probably + // divider_tx = (n_ops - n_ops_failed - n_ops_contract - + // n_seed_nonce_revelation - n_double_baking_evidence - + // n_double_endorsement_evidence - n_endorsement - n_reveal) + // so we are counting all + // n_delegation + n_origination + n_activation + n_tx + // But the deviation of fees in all those transactions is too high so the mean fees value would not be + // accurate anyway. + // + // Therefore, we only return totalFees/n_tx and leave the caller make some adjustments on the value + // afterwards + const auto txCountField = "n_tx"; return _http->GET("block/head") .json(parseNumbersAsString).mapPtr(getContext(), [=](const HttpRequest::JsonResult &result) { @@ -83,17 +95,24 @@ namespace ledger { if (!json.IsObject() || !json.HasMember(feesField) || !json[feesField].IsString()) { throw make_exception(api::ErrorCode::HTTP_ERROR, - "Failed to get fees from network, no (or malformed) field \"result\" in response"); + fmt::format("Failed to get fees from network, no (or malformed) field \"{}\" in response", feesField)); } - std::string fees = json[feesField].GetString(); - // Sometimes network is sending 0 for fees - if (fees == "0") { - fees = api::TezosConfigurationDefaults::TEZOS_DEFAULT_FEES; - } else if (fees.find('.') != std::string::npos) { - fees = api::BigInt::fromDecimalString(fees, 6, ".")->toString(10); + + // Return 0 if the block had no transaction at all + if (!json.HasMember(txCountField) || !json[txCountField].IsString()) { + return std::make_shared(0); + } + + const auto totalTx = api::BigInt::fromIntegerString(json[txCountField].GetString(), 10); + const auto totalFees = api::BigInt::fromDecimalString(json[feesField].GetString(), 6, "."); + std::string fees = api::TezosConfigurationDefaults::TEZOS_DEFAULT_FEES; + if (fees != "0" && totalTx->intValue() != 0) { + fees = totalFees->divide(totalTx)->toString(10); } - // Since nodes are giving some awkward values, we set a threshold to avoid having really fees - // Factor for threshold is inspired from other XTZ wallets + // Since nodes are giving some awkward values, we set a threshold to avoid + // having really fees Factor for threshold is inspired from other XTZ + // wallets + return std::make_shared(std::min(std::stoi(fees), std::stoi(api::TezosConfigurationDefaults::TEZOS_DEFAULT_MAX_FEES))); return std::make_shared(std::min(std::stoi(fees), std::stoi(api::TezosConfigurationDefaults::TEZOS_DEFAULT_MAX_FEES))); }); }