Monero C++ Library
Loading...
Searching...
No Matches
monero_utils.h
1
52
53#pragma once
54
55#ifndef monero_utils_h
56#define monero_utils_h
57
58#include "wallet/monero_wallet_model.h"
59#include "cryptonote_basic/cryptonote_basic.h"
60#include "serialization/keyvalue_serialization.h" // TODO: consolidate with other binary deps?
61#include "storages/portable_storage.h"
62
66namespace monero_utils
67{
68 using namespace cryptonote;
69
70 // ------------------------------ CONSTANTS ---------------------------------
71
72 static const int RING_SIZE = 16; // network-enforced ring size
73 static const uint64_t XMR_AU_MULTIPLIER = 1000000000000ULL;
74
75 // -------------------------------- UTILS -----------------------------------
76
77 void set_log_level(int level);
78 void set_log_categories(const std::string& categories);
79 void configure_logging(const std::string& path, bool console);
80 monero_integrated_address get_integrated_address(monero_network_type network_type, const std::string& standard_address, const std::string& payment_id);
81 std::string get_payment_uri(const monero_tx_config& config, monero_network_type network_type);
82 std::shared_ptr<monero_tx_config> parse_payment_uri(const std::string& uri, monero_network_type network_type);
83 bool is_valid_address(const std::string& address, monero_network_type network_type);
84 bool is_valid_private_view_key(const std::string& private_view_key);
85 bool is_valid_private_spend_key(const std::string& private_spend_key);
86 bool is_valid_public_view_key(const std::string& public_view_key);
87 bool is_valid_public_spend_key(const std::string& public_spend_key);
88 bool is_valid_payment_id(const std::string& payment_id);
89 bool is_valid_mnemonic(const std::string& mnemonic, const std::string& language = "");
90 void validate_address(const std::string& address, monero_network_type network_type);
91 void validate_private_view_key(const std::string& private_view_key);
92 void validate_private_spend_key(const std::string& private_spend_key);
93 void validate_public_view_key(const std::string& public_view_key);
94 void validate_public_spend_key(const std::string& public_spend_key);
95 void validate_payment_id(const std::string& payment_id);
96 void validate_mnemonic(const std::string& mnemonic, const std::string& language = "");
97 void json_to_binary(const std::string &json, std::string &bin);
98 void binary_to_json(const std::string &bin, std::string &json);
99 void binary_blocks_to_json(const std::string &bin, std::string &json);
100 void binary_blocks_fast_to_json(const std::string &bin, std::string &json);
101 uint64_t xmr_to_atomic_units(double amount_xmr);
102 double atomic_units_to_xmr(uint64_t amount_atomic_units);
103
104 // ------------------------------ RAPIDJSON ---------------------------------
105
111 template <class T>
112 void add_json_member(std::string key, T val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
113 rapidjson::Value field_key(key.c_str(), key.size(), allocator);
114 if (std::is_signed<T>::value) field.SetInt64((int64_t) val);
115 else field.SetUint64((uint64_t) val);
116 root.AddMember(field_key, field, allocator);
117 }
118 void add_json_member(std::string key, std::string val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
119 void add_json_member(std::string key, bool val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root);
120
121 // TODO: template implementation here, could move to monero_utils.hpp per https://stackoverflow.com/questions/3040480/c-template-function-compiles-in-header-but-not-implementation
122 template <class T> rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<std::shared_ptr<T>>& vals) {
123 rapidjson::Value value_arr(rapidjson::kArrayType);
124 for (const auto& val : vals) {
125 value_arr.PushBack(val->to_rapidjson_val(allocator), allocator);
126 }
127 return value_arr;
128 }
129
130 // TODO: template implementation here, could move to monero_utils.hpp per https://stackoverflow.com/questions/3040480/c-template-function-compiles-in-header-but-not-implementation
131 template <class T> rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<T>& vals) {
132 rapidjson::Value value_arr(rapidjson::kArrayType);
133 for (const auto& val : vals) {
134 value_arr.PushBack(val.to_rapidjson_val(allocator), allocator);
135 }
136 return value_arr;
137 }
138
139 rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<std::string>& strs);
140 rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<int>& nums);
141 rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint8_t>& nums);
142 rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint32_t>& nums);
143 rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint64_t>& nums);
144
145 // --------------------------------------------------------------------------
146
153 bool is_valid_language(const std::string& language);
154
162 bool parse_payment_id_long(const std::string& payment_id_str, crypto::hash& payment_id);
163
171 bool parse_payment_id_short(const std::string& payment_id_str, crypto::hash8& payment_id);
172
179 std::shared_ptr<monero_block> cn_block_to_block(const cryptonote::block& cn_block);
180
188 std::shared_ptr<monero_tx> cn_tx_to_tx(const cryptonote::transaction& cn_tx, bool init_as_tx_wallet = false);
189
195 static std::string get_pruned_tx_json(cryptonote::transaction &tx)
196 {
197 std::stringstream ss;
198 json_archive<true> ar(ss);
199 bool r = tx.serialize_base(ar);
200 CHECK_AND_ASSERT_MES(r, std::string(), "Failed to serialize rct signatures base");
201 return ss.str();
202 }
203
204 void binary_blocks_to_property_tree(const std::string &bin, boost::property_tree::ptree &node);
205 void binary_blocks_fast_to_property_tree(const std::string &bin, boost::property_tree::ptree &node);
206
214 void merge_tx(const std::shared_ptr<monero_tx_wallet>& tx, std::map<std::string, std::shared_ptr<monero_tx_wallet>>& tx_map, std::map<uint64_t, std::shared_ptr<monero_block>>& block_map);
215
219 bool tx_height_less_than(const std::shared_ptr<monero_tx>& tx1, const std::shared_ptr<monero_tx>& tx2);
220
224 bool incoming_transfer_before(const std::shared_ptr<monero_incoming_transfer>& transfer1, const std::shared_ptr<monero_incoming_transfer>& transfer2);
225
229 bool vout_before(const std::shared_ptr<monero_output>& o1, const std::shared_ptr<monero_output>& o2);
230
231 // ----------------------------- GATHER BLOCKS ------------------------------
232
233 static std::vector<std::shared_ptr<monero_block>> get_blocks_from_txs(std::vector<std::shared_ptr<monero_tx_wallet>> txs) {
234 std::shared_ptr<monero_block> unconfirmed_block = nullptr; // placeholder for unconfirmed txs
235 std::vector<std::shared_ptr<monero_block>> blocks;
236 std::unordered_set<std::shared_ptr<monero_block>> seen_block_ptrs;
237 for (const std::shared_ptr<monero_tx_wallet>& tx : txs) {
238 if (tx->m_block == nullptr) {
239 if (unconfirmed_block == nullptr) unconfirmed_block = std::make_shared<monero_block>();
240 tx->m_block = unconfirmed_block;
241 unconfirmed_block->m_txs.push_back(tx);
242 }
243 std::unordered_set<std::shared_ptr<monero_block>>::const_iterator got = seen_block_ptrs.find(tx->m_block);
244 if (got == seen_block_ptrs.end()) {
245 seen_block_ptrs.insert(tx->m_block);
246 blocks.push_back(tx->m_block);
247 }
248 }
249 return blocks;
250 }
251
252 static std::vector<std::shared_ptr<monero_block>> get_blocks_from_transfers(std::vector<std::shared_ptr<monero_transfer>> transfers) {
253 std::shared_ptr<monero_block> unconfirmed_block = nullptr; // placeholder for unconfirmed txs in return json
254 std::vector<std::shared_ptr<monero_block>> blocks;
255 std::unordered_set<std::shared_ptr<monero_block>> seen_block_ptrs;
256 for (auto const& transfer : transfers) {
257 if (transfer->m_tx == nullptr) throw std::runtime_error("Transfer has no tx");
258 std::shared_ptr<monero_tx_wallet> tx = transfer->m_tx;
259 if (tx->m_block == nullptr) {
260 if (unconfirmed_block == nullptr) unconfirmed_block = std::make_shared<monero_block>();
261 tx->m_block = unconfirmed_block;
262 unconfirmed_block->m_txs.push_back(tx);
263 }
264 std::unordered_set<std::shared_ptr<monero_block>>::const_iterator got = seen_block_ptrs.find(tx->m_block);
265 if (got == seen_block_ptrs.end()) {
266 seen_block_ptrs.insert(tx->m_block);
267 blocks.push_back(tx->m_block);
268 }
269 }
270 return blocks;
271 }
272
273 static std::vector<std::shared_ptr<monero_block>> get_blocks_from_outputs(std::vector<std::shared_ptr<monero_output_wallet>> outputs) {
274 std::vector<std::shared_ptr<monero_block>> blocks;
275 std::unordered_set<std::shared_ptr<monero_block>> seen_block_ptrs;
276 for (auto const& output : outputs) {
277 if (output->m_tx == nullptr) throw std::runtime_error("Output has no tx");
278 std::shared_ptr<monero_tx_wallet> tx = std::static_pointer_cast<monero_tx_wallet>(output->m_tx);
279 if (tx->m_block == nullptr) throw std::runtime_error("Need to handle unconfirmed output");
280 std::unordered_set<std::shared_ptr<monero_block>>::const_iterator got = seen_block_ptrs.find(tx->m_block);
281 if (got == seen_block_ptrs.end()) {
282 seen_block_ptrs.insert(tx->m_block);
283 blocks.push_back(tx->m_block);
284 }
285 }
286 return blocks;
287 }
288
289 // ------------------------------ FREE MEMORY -------------------------------
290
291 static void free(std::shared_ptr<monero_block> block) {
292 if (block == nullptr) return;
293 for (std::shared_ptr<monero_tx>& tx : block->m_txs) {
294 tx->m_block.reset();
295 monero_tx_wallet* tx_wallet = dynamic_cast<monero_tx_wallet*>(tx.get());
296 if (tx_wallet != nullptr) {
297 if (tx_wallet->m_tx_set != nullptr) tx_wallet->m_tx_set.reset();
298 if (tx_wallet->m_outgoing_transfer != nullptr) tx_wallet->m_outgoing_transfer->m_tx.reset();
299 for (std::shared_ptr<monero_transfer> transfer : tx_wallet->m_incoming_transfers) transfer->m_tx.reset();
300 for (std::shared_ptr<monero_output> output : tx_wallet->m_outputs) output->m_tx.reset();
301 for (std::shared_ptr<monero_output> input : tx_wallet->m_inputs) {
302 input->m_key_image.reset();
303 input->m_tx.reset();
304 }
305 }
306 monero_tx_query* tx_query = dynamic_cast<monero_tx_query*>(tx.get());
307 if (tx_query != nullptr) {
308 if (tx_query->m_transfer_query != nullptr) {
309 tx_query->m_transfer_query->m_tx_query.reset();
310 tx_query->m_transfer_query.reset();
311 }
312 if (tx_query->m_output_query != nullptr) {
313 tx_query->m_output_query->m_tx_query.reset();
314 tx_query->m_output_query.reset();
315 }
316 }
317 }
318 block.reset();
319 }
320
321 static void free(std::vector<std::shared_ptr<monero_block>> blocks) {
322 for (std::shared_ptr<monero_block>& block : blocks) monero_utils::free(block);
323 }
324
325 static void free(std::shared_ptr<monero_tx> tx) {
326 if (tx == nullptr) return;
327 if (tx->m_block == nullptr) {
328 std::shared_ptr<monero_block> block = std::make_shared<monero_block>();
329 tx->m_block = block;
330 block->m_txs.push_back(tx);
331 }
332 monero_utils::free(tx->m_block);
333 }
334
335 static void free(std::vector<std::shared_ptr<monero_tx_wallet>> txs) {
336 return monero_utils::free(monero_utils::get_blocks_from_txs(txs));
337 }
338
339 static void free(std::vector<std::shared_ptr<monero_transfer>> transfers) {
340 return monero_utils::free(monero_utils::get_blocks_from_transfers(transfers));
341 }
342
343 static void free(std::vector<std::shared_ptr<monero_output_wallet>> outputs) {
344 return monero_utils::free(monero_utils::get_blocks_from_outputs(outputs));
345 }
346}
347#endif /* monero_utils_h */
Definition monero_utils.h:67
bool parse_payment_id_long(const std::string &payment_id_str, crypto::hash &payment_id)
Definition monero_utils.cpp:780
bool is_valid_language(const std::string &language)
Definition monero_utils.cpp:467
bool incoming_transfer_before(const std::shared_ptr< monero_incoming_transfer > &transfer1, const std::shared_ptr< monero_incoming_transfer > &transfer2)
Definition monero_utils.cpp:584
bool tx_height_less_than(const std::shared_ptr< monero_tx > &tx1, const std::shared_ptr< monero_tx > &tx2)
Definition monero_utils.cpp:578
bool vout_before(const std::shared_ptr< monero_output > &o1, const std::shared_ptr< monero_output > &o2)
Definition monero_utils.cpp:595
bool parse_payment_id_short(const std::string &payment_id_str, crypto::hash8 &payment_id)
Definition monero_utils.cpp:788
void merge_tx(const std::shared_ptr< monero_tx_wallet > &tx, std::map< std::string, std::shared_ptr< monero_tx_wallet > > &tx_map, std::map< uint64_t, std::shared_ptr< monero_block > > &block_map)
Definition monero_utils.cpp:554
std::shared_ptr< monero_block > cn_block_to_block(const cryptonote::block &cn_block)
Definition monero_utils.cpp:480
void add_json_member(std::string key, T val, rapidjson::Document::AllocatorType &allocator, rapidjson::Value &root, rapidjson::Value &field)
Definition monero_utils.h:112
std::shared_ptr< monero_tx > cn_tx_to_tx(const cryptonote::transaction &cn_tx, bool init_as_tx_wallet=false)
Definition monero_utils.cpp:496
monero_network_type
Definition monero_daemon_model.h:119
Definition monero_wallet_model.h:386
Definition monero_wallet_model.h:409