aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLee Clagett <code@leeclagett.com>2018-10-19 22:06:03 -0400
committerLee Clagett <code@leeclagett.com>2018-10-23 23:46:31 -0400
commit6097472a195fe81b34c2e5ab83ff2a1786c2a5e3 (patch)
treed6f7111fb8fc7811983b6d875681130e7eb9873f /src
parentMerge pull request #4524 (diff)
downloadmonero-6097472a195fe81b34c2e5ab83ff2a1786c2a5e3.tar.xz
Update ZMQ fee estimate and add ZMQ output distribution
Diffstat (limited to 'src')
-rw-r--r--src/rpc/CMakeLists.txt7
-rw-r--r--src/rpc/core_rpc_server.cpp56
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h13
-rw-r--r--src/rpc/daemon_handler.cpp48
-rw-r--r--src/rpc/daemon_handler.h4
-rw-r--r--src/rpc/daemon_messages.cpp58
-rw-r--r--src/rpc/daemon_messages.h27
-rw-r--r--src/rpc/message_data_structs.h7
-rw-r--r--src/rpc/rpc_handler.cpp69
-rw-r--r--src/rpc/rpc_handler.h17
-rw-r--r--src/serialization/json_object.cpp23
-rw-r--r--src/serialization/json_object.h3
-rw-r--r--src/wallet/wallet2.cpp16
13 files changed, 260 insertions, 88 deletions
diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt
index 4f8f96524..8b4c27e3e 100644
--- a/src/rpc/CMakeLists.txt
+++ b/src/rpc/CMakeLists.txt
@@ -27,7 +27,8 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(rpc_base_sources
- rpc_args.cpp)
+ rpc_args.cpp
+ rpc_handler.cpp)
set(rpc_sources
core_rpc_server.cpp
@@ -43,7 +44,8 @@ set(daemon_rpc_server_sources
set(rpc_base_headers
- rpc_args.h)
+ rpc_args.h
+ rpc_handler.h)
set(rpc_headers)
@@ -63,7 +65,6 @@ set(daemon_rpc_server_private_headers
message.h
daemon_messages.h
daemon_handler.h
- rpc_handler.h
zmq_server.h)
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 55ee66a79..dc3860d60 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -45,6 +45,7 @@ using namespace epee;
#include "storages/http_abstract_invoke.h"
#include "crypto/hash.h"
#include "rpc/rpc_args.h"
+#include "rpc/rpc_handler.h"
#include "core_rpc_server_error_codes.h"
#include "p2p/net_node.h"
#include "version.h"
@@ -2124,62 +2125,15 @@ namespace cryptonote
const uint64_t req_to_height = req.to_height ? req.to_height : (m_core.get_current_blockchain_height() - 1);
for (uint64_t amount: req.amounts)
{
- static struct D
- {
- boost::mutex mutex;
- std::vector<uint64_t> cached_distribution;
- uint64_t cached_from, cached_to, cached_start_height, cached_base;
- bool cached;
- D(): cached_from(0), cached_to(0), cached_start_height(0), cached_base(0), cached(false) {}
- } d;
- boost::unique_lock<boost::mutex> lock(d.mutex);
-
- if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req_to_height)
- {
- res.distributions.push_back({amount, d.cached_start_height, req.binary, d.cached_distribution, d.cached_base});
- if (!req.cumulative)
- {
- auto &distribution = res.distributions.back().distribution;
- for (size_t n = distribution.size() - 1; n > 0; --n)
- distribution[n] -= distribution[n-1];
- distribution[0] -= d.cached_base;
- }
- continue;
- }
-
- std::vector<uint64_t> distribution;
- uint64_t start_height, base;
- if (!m_core.get_output_distribution(amount, req.from_height, req_to_height, start_height, distribution, base))
+ auto data = rpc::RpcHandler::get_output_distribution(m_core, amount, req.from_height, req_to_height, req.cumulative);
+ if (!data)
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
- error_resp.message = "Failed to get rct distribution";
+ error_resp.message = "Failed to get output distribution";
return false;
}
- if (req_to_height > 0 && req_to_height >= req.from_height)
- {
- uint64_t offset = std::max(req.from_height, start_height);
- if (offset <= req_to_height && req_to_height - offset + 1 < distribution.size())
- distribution.resize(req_to_height - offset + 1);
- }
-
- if (amount == 0)
- {
- d.cached_from = req.from_height;
- d.cached_to = req_to_height;
- d.cached_distribution = distribution;
- d.cached_start_height = start_height;
- d.cached_base = base;
- d.cached = true;
- }
-
- if (!req.cumulative)
- {
- for (size_t n = distribution.size() - 1; n > 0; --n)
- distribution[n] -= distribution[n-1];
- distribution[0] -= base;
- }
- res.distributions.push_back({amount, start_height, req.binary, std::move(distribution), base});
+ res.distributions.push_back({std::move(*data), amount, req.binary});
}
}
catch (const std::exception &e)
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 3b654d4cb..e8720cb14 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -33,6 +33,7 @@
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/difficulty.h"
#include "crypto/hash.h"
+#include "rpc/rpc_handler.h"
namespace cryptonote
{
@@ -2236,21 +2237,19 @@ namespace cryptonote
struct distribution
{
+ rpc::output_distribution_data data;
uint64_t amount;
- uint64_t start_height;
bool binary;
- std::vector<uint64_t> distribution;
- uint64_t base;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
- KV_SERIALIZE(start_height)
+ KV_SERIALIZE_N(data.start_height, "start_height")
KV_SERIALIZE(binary)
if (this_ref.binary)
- KV_SERIALIZE_CONTAINER_POD_AS_BLOB(distribution)
+ KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(data.distribution, "distribution")
else
- KV_SERIALIZE(distribution)
- KV_SERIALIZE(base)
+ KV_SERIALIZE_N(data.distribution, "distribution")
+ KV_SERIALIZE_N(data.base, "base")
END_KV_SERIALIZE_MAP()
};
diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp
index 9d3b09b68..8822bd378 100644
--- a/src/rpc/daemon_handler.cpp
+++ b/src/rpc/daemon_handler.cpp
@@ -724,12 +724,53 @@ namespace rpc
res.status = Message::STATUS_OK;
}
- void DaemonHandler::handle(const GetPerKBFeeEstimate::Request& req, GetPerKBFeeEstimate::Response& res)
+ void DaemonHandler::handle(const GetFeeEstimate::Request& req, GetFeeEstimate::Response& res)
{
- res.estimated_fee_per_kb = m_core.get_blockchain_storage().get_dynamic_base_fee_estimate(req.num_grace_blocks);
+ res.hard_fork_version = m_core.get_blockchain_storage().get_current_hard_fork_version();
+ res.estimated_base_fee = m_core.get_blockchain_storage().get_dynamic_base_fee_estimate(req.num_grace_blocks);
+
+ if (res.hard_fork_version < HF_VERSION_PER_BYTE_FEE)
+ {
+ res.size_scale = 1024; // per KiB fee
+ res.fee_mask = 1;
+ }
+ else
+ {
+ res.size_scale = 1; // per byte fee
+ res.fee_mask = Blockchain::get_fee_quantization_mask();
+ }
res.status = Message::STATUS_OK;
}
+ void DaemonHandler::handle(const GetOutputDistribution::Request& req, GetOutputDistribution::Response& res)
+ {
+ try
+ {
+ res.distributions.reserve(req.amounts.size());
+
+ const uint64_t req_to_height = req.to_height ? req.to_height : (m_core.get_current_blockchain_height() - 1);
+ for (std::uint64_t amount : req.amounts)
+ {
+ auto data = get_output_distribution(m_core, amount, req.from_height, req_to_height, req.cumulative);
+ if (!data)
+ {
+ res.distributions.clear();
+ res.status = Message::STATUS_FAILED;
+ res.error_details = "Failed to get output distribution";
+ return;
+ }
+ res.distributions.push_back(output_distribution{std::move(*data), amount, req.cumulative});
+ }
+ res.status = Message::STATUS_OK;
+ }
+ catch (const std::exception& e)
+ {
+ res.distributions.clear();
+ res.status = Message::STATUS_FAILED;
+ res.error_details = e.what();
+ }
+ }
+
bool DaemonHandler::getBlockHeaderByHash(const crypto::hash& hash_in, cryptonote::rpc::BlockHeaderResponse& header)
{
block b;
@@ -804,7 +845,8 @@ namespace rpc
REQ_RESP_TYPES_MACRO(request_type, GetOutputHistogram, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetOutputKeys, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetRPCVersion, req_json, resp_message, handle);
- REQ_RESP_TYPES_MACRO(request_type, GetPerKBFeeEstimate, req_json, resp_message, handle);
+ REQ_RESP_TYPES_MACRO(request_type, GetFeeEstimate, req_json, resp_message, handle);
+ REQ_RESP_TYPES_MACRO(request_type, GetOutputDistribution, req_json, resp_message, handle);
// if none of the request types matches
if (resp_message == NULL)
diff --git a/src/rpc/daemon_handler.h b/src/rpc/daemon_handler.h
index 5f9687511..2c8ac3867 100644
--- a/src/rpc/daemon_handler.h
+++ b/src/rpc/daemon_handler.h
@@ -126,7 +126,9 @@ class DaemonHandler : public RpcHandler
void handle(const GetRPCVersion::Request& req, GetRPCVersion::Response& res);
- void handle(const GetPerKBFeeEstimate::Request& req, GetPerKBFeeEstimate::Response& res);
+ void handle(const GetFeeEstimate::Request& req, GetFeeEstimate::Response& res);
+
+ void handle(const GetOutputDistribution::Request& req, GetOutputDistribution::Response& res);
std::string handle(const std::string& request);
diff --git a/src/rpc/daemon_messages.cpp b/src/rpc/daemon_messages.cpp
index 56f6f6a8c..fa848cff4 100644
--- a/src/rpc/daemon_messages.cpp
+++ b/src/rpc/daemon_messages.cpp
@@ -59,7 +59,8 @@ const char* const HardForkInfo::name = "hard_fork_info";
const char* const GetOutputHistogram::name = "get_output_histogram";
const char* const GetOutputKeys::name = "get_output_keys";
const char* const GetRPCVersion::name = "get_rpc_version";
-const char* const GetPerKBFeeEstimate::name = "get_dynamic_per_kb_fee_estimate";
+const char* const GetFeeEstimate::name = "get_dynamic_fee_estimate";
+const char* const GetOutputDistribution::name = "get_output_distribution";
@@ -825,7 +826,7 @@ void GetRPCVersion::Response::fromJson(rapidjson::Value& val)
GET_FROM_JSON_OBJECT(val, version, version);
}
-rapidjson::Value GetPerKBFeeEstimate::Request::toJson(rapidjson::Document& doc) const
+rapidjson::Value GetFeeEstimate::Request::toJson(rapidjson::Document& doc) const
{
auto val = Message::toJson(doc);
@@ -836,27 +837,70 @@ rapidjson::Value GetPerKBFeeEstimate::Request::toJson(rapidjson::Document& doc)
return val;
}
-void GetPerKBFeeEstimate::Request::fromJson(rapidjson::Value& val)
+void GetFeeEstimate::Request::fromJson(rapidjson::Value& val)
{
GET_FROM_JSON_OBJECT(val, num_grace_blocks, num_grace_blocks);
}
-rapidjson::Value GetPerKBFeeEstimate::Response::toJson(rapidjson::Document& doc) const
+rapidjson::Value GetFeeEstimate::Response::toJson(rapidjson::Document& doc) const
{
auto val = Message::toJson(doc);
auto& al = doc.GetAllocator();
- INSERT_INTO_JSON_OBJECT(val, doc, estimated_fee_per_kb, estimated_fee_per_kb);
+ INSERT_INTO_JSON_OBJECT(val, doc, estimated_base_fee, estimated_base_fee);
+ INSERT_INTO_JSON_OBJECT(val, doc, fee_mask, fee_mask);
+ INSERT_INTO_JSON_OBJECT(val, doc, size_scale, size_scale);
+ INSERT_INTO_JSON_OBJECT(val, doc, hard_fork_version, hard_fork_version);
return val;
}
-void GetPerKBFeeEstimate::Response::fromJson(rapidjson::Value& val)
+void GetFeeEstimate::Response::fromJson(rapidjson::Value& val)
{
- GET_FROM_JSON_OBJECT(val, estimated_fee_per_kb, estimated_fee_per_kb);
+ GET_FROM_JSON_OBJECT(val, estimated_base_fee, estimated_base_fee);
+ GET_FROM_JSON_OBJECT(val, fee_mask, fee_mask);
+ GET_FROM_JSON_OBJECT(val, size_scale, size_scale);
+ GET_FROM_JSON_OBJECT(val, hard_fork_version, hard_fork_version);
}
+rapidjson::Value GetOutputDistribution::Request::toJson(rapidjson::Document& doc) const
+{
+ auto val = Message::toJson(doc);
+ auto& al = doc.GetAllocator();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, amounts, amounts);
+ INSERT_INTO_JSON_OBJECT(val, doc, from_height, from_height);
+ INSERT_INTO_JSON_OBJECT(val, doc, to_height, to_height);
+ INSERT_INTO_JSON_OBJECT(val, doc, cumulative, cumulative);
+
+ return val;
+}
+
+void GetOutputDistribution::Request::fromJson(rapidjson::Value& val)
+{
+ GET_FROM_JSON_OBJECT(val, amounts, amounts);
+ GET_FROM_JSON_OBJECT(val, from_height, from_height);
+ GET_FROM_JSON_OBJECT(val, to_height, to_height);
+ GET_FROM_JSON_OBJECT(val, cumulative, cumulative);
+}
+
+rapidjson::Value GetOutputDistribution::Response::toJson(rapidjson::Document& doc) const
+{
+ auto val = Message::toJson(doc);
+ auto& al = doc.GetAllocator();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, status, status);
+ INSERT_INTO_JSON_OBJECT(val, doc, distributions, distributions);
+
+ return val;
+}
+
+void GetOutputDistribution::Response::fromJson(rapidjson::Value& val)
+{
+ GET_FROM_JSON_OBJECT(val, status, status);
+ GET_FROM_JSON_OBJECT(val, distributions, distributions);
+}
} // namespace rpc
diff --git a/src/rpc/daemon_messages.h b/src/rpc/daemon_messages.h
index be3138e3b..70f4c50f1 100644
--- a/src/rpc/daemon_messages.h
+++ b/src/rpc/daemon_messages.h
@@ -28,6 +28,9 @@
#pragma once
+#include <unordered_map>
+#include <vector>
+
#include "message.h"
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
#include "rpc/message_data_structs.h"
@@ -62,8 +65,6 @@ class classname \
#define END_RPC_MESSAGE_RESPONSE };
#define END_RPC_MESSAGE_CLASS };
-#define COMMA() ,
-
// NOTE: when using a type with multiple template parameters,
// replace any comma in the template specifier with the macro
// above, or the preprocessor will eat the comma in a bad way.
@@ -118,7 +119,8 @@ BEGIN_RPC_MESSAGE_CLASS(GetTransactions);
RPC_MESSAGE_MEMBER(std::vector<crypto::hash>, tx_hashes);
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
- RPC_MESSAGE_MEMBER(std::unordered_map<crypto::hash COMMA() cryptonote::rpc::transaction_info>, txs);
+ using txes_map = std::unordered_map<crypto::hash, transaction_info>;
+ RPC_MESSAGE_MEMBER(txes_map, txs);
RPC_MESSAGE_MEMBER(std::vector<crypto::hash>, missed_hashes);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
@@ -407,12 +409,27 @@ BEGIN_RPC_MESSAGE_CLASS(GetRPCVersion);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
-BEGIN_RPC_MESSAGE_CLASS(GetPerKBFeeEstimate);
+BEGIN_RPC_MESSAGE_CLASS(GetFeeEstimate);
BEGIN_RPC_MESSAGE_REQUEST;
RPC_MESSAGE_MEMBER(uint64_t, num_grace_blocks);
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
- RPC_MESSAGE_MEMBER(uint64_t, estimated_fee_per_kb);
+ RPC_MESSAGE_MEMBER(uint64_t, estimated_base_fee);
+ RPC_MESSAGE_MEMBER(uint64_t, fee_mask);
+ RPC_MESSAGE_MEMBER(uint32_t, size_scale);
+ RPC_MESSAGE_MEMBER(uint8_t, hard_fork_version);
+ END_RPC_MESSAGE_RESPONSE;
+END_RPC_MESSAGE_CLASS;
+
+BEGIN_RPC_MESSAGE_CLASS(GetOutputDistribution);
+ BEGIN_RPC_MESSAGE_REQUEST;
+ RPC_MESSAGE_MEMBER(std::vector<uint64_t>, amounts);
+ RPC_MESSAGE_MEMBER(uint64_t, from_height);
+ RPC_MESSAGE_MEMBER(uint64_t, to_height);
+ RPC_MESSAGE_MEMBER(bool, cumulative);
+ END_RPC_MESSAGE_REQUEST;
+ BEGIN_RPC_MESSAGE_RESPONSE;
+ RPC_MESSAGE_MEMBER(std::vector<output_distribution>, distributions);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h
index cf15ade1c..3b56aff15 100644
--- a/src/rpc/message_data_structs.h
+++ b/src/rpc/message_data_structs.h
@@ -31,6 +31,7 @@
#include "crypto/hash.h"
#include "cryptonote_basic/cryptonote_basic.h"
#include "ringct/rctSigs.h"
+#include "rpc/rpc_handler.h"
#include <unordered_map>
#include <vector>
@@ -192,6 +193,12 @@ namespace rpc
uint64_t start_time;
};
+ struct output_distribution
+ {
+ output_distribution_data data;
+ uint64_t amount;
+ bool cumulative;
+ };
} // namespace rpc
} // namespace cryptonote
diff --git a/src/rpc/rpc_handler.cpp b/src/rpc/rpc_handler.cpp
new file mode 100644
index 000000000..d4beb1928
--- /dev/null
+++ b/src/rpc/rpc_handler.cpp
@@ -0,0 +1,69 @@
+
+#include <algorithm>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include "cryptonote_core/cryptonote_core.h"
+
+namespace cryptonote
+{
+namespace rpc
+{
+ namespace
+ {
+ output_distribution_data
+ process_distribution(bool cumulative, std::uint64_t start_height, std::vector<std::uint64_t> distribution, std::uint64_t base)
+ {
+ if (!cumulative && !distribution.empty())
+ {
+ for (std::size_t n = distribution.size() - 1; 0 < n; --n)
+ distribution[n] -= distribution[n - 1];
+ distribution[0] -= base;
+ }
+
+ return {std::move(distribution), start_height, base};
+ }
+ }
+
+ boost::optional<output_distribution_data>
+ RpcHandler::get_output_distribution(core& src, std::uint64_t amount, std::uint64_t from_height, std::uint64_t to_height, bool cumulative)
+ {
+ static struct D
+ {
+ boost::mutex mutex;
+ std::vector<std::uint64_t> cached_distribution;
+ std::uint64_t cached_from, cached_to, cached_start_height, cached_base;
+ bool cached;
+ D(): cached_from(0), cached_to(0), cached_start_height(0), cached_base(0), cached(false) {}
+ } d;
+ const boost::unique_lock<boost::mutex> lock(d.mutex);
+
+ if (d.cached && amount == 0 && d.cached_from == from_height && d.cached_to == to_height)
+ return process_distribution(cumulative, d.cached_start_height, d.cached_distribution, d.cached_base);
+
+ std::vector<std::uint64_t> distribution;
+ std::uint64_t start_height, base;
+ if (!src.get_output_distribution(amount, from_height, to_height, start_height, distribution, base))
+ return boost::none;
+
+ if (to_height > 0 && to_height >= from_height)
+ {
+ const std::uint64_t offset = std::max(from_height, start_height);
+ if (offset <= to_height && to_height - offset + 1 < distribution.size())
+ distribution.resize(to_height - offset + 1);
+ }
+
+ if (amount == 0)
+ {
+ d.cached_from = from_height;
+ d.cached_to = to_height;
+ d.cached_distribution = distribution;
+ d.cached_start_height = start_height;
+ d.cached_base = base;
+ d.cached = true;
+ }
+
+ return process_distribution(cumulative, start_height, std::move(distribution), base);
+ }
+} // rpc
+} // cryptonote
diff --git a/src/rpc/rpc_handler.h b/src/rpc/rpc_handler.h
index 64bade5a8..3cccef78a 100644
--- a/src/rpc/rpc_handler.h
+++ b/src/rpc/rpc_handler.h
@@ -28,24 +28,35 @@
#pragma once
+#include <boost/optional/optional.hpp>
+#include <cstdint>
#include <string>
+#include <vector>
namespace cryptonote
{
+class core;
namespace rpc
{
+struct output_distribution_data
+{
+ std::vector<std::uint64_t> distribution;
+ std::uint64_t start_height;
+ std::uint64_t base;
+};
class RpcHandler
{
public:
+ RpcHandler() { }
+ virtual ~RpcHandler() { }
virtual std::string handle(const std::string& request) = 0;
- RpcHandler() { }
-
- virtual ~RpcHandler() { }
+ static boost::optional<output_distribution_data>
+ get_output_distribution(core& src, std::uint64_t amount, std::uint64_t from_height, std::uint64_t to_height, bool cumulative);
};
diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp
index 89a1dbd23..7980e8953 100644
--- a/src/serialization/json_object.cpp
+++ b/src/serialization/json_object.cpp
@@ -1232,6 +1232,29 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& inf
GET_FROM_JSON_OBJECT(val, info.start_time, start_time);
}
+void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_distribution& dist, rapidjson::Value& val)
+{
+ val.SetObject();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, distribution, dist.data.distribution);
+ INSERT_INTO_JSON_OBJECT(val, doc, amount, dist.amount);
+ INSERT_INTO_JSON_OBJECT(val, doc, start_height, dist.data.start_height);
+ INSERT_INTO_JSON_OBJECT(val, doc, base, dist.data.base);
+}
+
+void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_distribution& dist)
+{
+ if (!val.IsObject())
+ {
+ throw WRONG_TYPE("json object");
+ }
+
+ GET_FROM_JSON_OBJECT(val, dist.data.distribution, distribution);
+ GET_FROM_JSON_OBJECT(val, dist.amount, amount);
+ GET_FROM_JSON_OBJECT(val, dist.data.start_height, start_height);
+ GET_FROM_JSON_OBJECT(val, dist.data.base, base);
+}
+
} // namespace json
} // namespace cryptonote
diff --git a/src/serialization/json_object.h b/src/serialization/json_object.h
index da3351fe3..b6384ca0d 100644
--- a/src/serialization/json_object.h
+++ b/src/serialization/json_object.h
@@ -281,6 +281,9 @@ void fromJsonValue(const rapidjson::Value& val, rct::mgSig& sig);
void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::DaemonInfo& info, rapidjson::Value& val);
void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& info);
+void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::output_distribution& dist, rapidjson::Value& val);
+void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_distribution& dist);
+
template <typename Map>
typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type toJsonValue(rapidjson::Document& doc, const Map& map, rapidjson::Value& val);
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 6b3a8533e..21793b58d 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2865,8 +2865,8 @@ bool wallet2::get_rct_distribution(uint64_t &start_height, std::vector<uint64_t>
MWARNING("Failed to request output distribution: results are not for amount 0");
return false;
}
- start_height = res.distributions[0].start_height;
- distribution = std::move(res.distributions[0].distribution);
+ start_height = res.distributions[0].data.start_height;
+ distribution = std::move(res.distributions[0].data.distribution);
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -6747,13 +6747,13 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
{
if (d.amount == amount)
{
- THROW_WALLET_EXCEPTION_IF(d.start_height > segregation_fork_height, error::get_output_distribution, "Distribution start_height too high");
- THROW_WALLET_EXCEPTION_IF(segregation_fork_height - d.start_height >= d.distribution.size(), error::get_output_distribution, "Distribution size too small");
- THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS - d.start_height >= d.distribution.size(), error::get_output_distribution, "Distribution size too small");
+ THROW_WALLET_EXCEPTION_IF(d.data.start_height > segregation_fork_height, error::get_output_distribution, "Distribution start_height too high");
+ THROW_WALLET_EXCEPTION_IF(segregation_fork_height - d.data.start_height >= d.data.distribution.size(), error::get_output_distribution, "Distribution size too small");
+ THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS - d.data.start_height >= d.data.distribution.size(), error::get_output_distribution, "Distribution size too small");
THROW_WALLET_EXCEPTION_IF(segregation_fork_height <= RECENT_OUTPUT_BLOCKS, error::wallet_internal_error, "Fork height too low");
- THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS < d.start_height, error::get_output_distribution, "Bad start height");
- uint64_t till_fork = d.distribution[segregation_fork_height - d.start_height];
- uint64_t recent = till_fork - d.distribution[segregation_fork_height - RECENT_OUTPUT_BLOCKS - d.start_height];
+ THROW_WALLET_EXCEPTION_IF(segregation_fork_height - RECENT_OUTPUT_BLOCKS < d.data.start_height, error::get_output_distribution, "Bad start height");
+ uint64_t till_fork = d.data.distribution[segregation_fork_height - d.data.start_height];
+ uint64_t recent = till_fork - d.data.distribution[segregation_fork_height - RECENT_OUTPUT_BLOCKS - d.data.start_height];
segregation_limit[amount] = std::make_pair(till_fork, recent);
found = true;
break;