Monero C++ Library
monero_utils.h
1 
53 #ifndef monero_utils_h
54 #define monero_utils_h
55 
56 #include "wallet/monero_wallet.h"
57 #include "cryptonote_basic/cryptonote_basic.h"
58 #include "serialization/keyvalue_serialization.h" // TODO: consolidate with other binary deps?
59 #include "storages/portable_storage.h"
60 
64 namespace monero_utils
65 {
66  using namespace std;
67  using namespace cryptonote;
68 
69  void json_to_binary(const std::string &json, std::string &bin);
70 
71  void binary_to_json(const std::string &bin, std::string &json);
72 
73  void binary_blocks_to_json(const std::string &bin, std::string &json);
74 
75  shared_ptr<monero_tx_query> deserialize_tx_query(const string& txQueryStr);
76 
77  shared_ptr<monero_transfer_query> deserialize_transfer_query(const string& transfer_query_str);
78 
79  shared_ptr<monero_output_query> deserialize_output_query(const string& output_query_str);
80 
81  shared_ptr<monero_send_request> deserialize_send_request(const string& send_request_str);
82 
83  vector<shared_ptr<monero_key_image>> deserialize_key_images(const string& key_images_json);
84 
85  string serialize(const boost::property_tree::ptree& node);
86 
93  shared_ptr<monero_block> cn_block_to_block(const cryptonote::block& cn_block);
94 
95 
103  shared_ptr<monero_tx> cn_tx_to_tx(const cryptonote::transaction& cn_tx, bool init_as_tx_wallet = false);
104 
110  static std::string get_pruned_tx_json(cryptonote::transaction &tx)
111  {
112  std::stringstream ss;
113  json_archive<true> ar(ss);
114  bool r = tx.serialize_base(ar);
115  CHECK_AND_ASSERT_MES(r, std::string(), "Failed to serialize rct signatures base");
116  return ss.str();
117  }
118 
119  // ----------------------------- PROPERTY TREE ------------------------------
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> boost::property_tree::ptree to_property_tree(const vector<shared_ptr<T>>& types) {
123  boost::property_tree::ptree typeNodes;
124  for (const auto& type : types) {
125  typeNodes.push_back(std::make_pair("", type->to_property_tree()));
126  }
127  return typeNodes;
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> boost::property_tree::ptree to_property_tree(const vector<T>& types) {
132  boost::property_tree::ptree typeNodes;
133  for (const auto& type : types) {
134  typeNodes.push_back(std::make_pair("", type.to_property_tree()));
135  }
136  return typeNodes;
137  }
138 
139  boost::property_tree::ptree to_property_tree(const vector<string>& strs);
140  boost::property_tree::ptree to_property_tree(const vector<uint8_t>& nums);
141  boost::property_tree::ptree to_property_tree(const vector<uint32_t>& nums);
142  boost::property_tree::ptree to_property_tree(const vector<uint64_t>& nums);
143 
144  // ------------------------- VALUE RECONCILATION- ---------------------------
145 
146  // TODO: refactor common template code
147  template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
148  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
149 
150  // check for equality
151  if (val1 == val2) return val1;
152 
153  // resolve one value none
154  if (val1 == boost::none || val2 == boost::none) {
155  if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
156  else return val1 == boost::none ? val2 : val1;
157  }
158 
159  throw runtime_error(string("Cannot reconcile strings: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
160  }
161  template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
162  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
163  return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
164  }
165 
166  template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
167  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
168 
169  // check for equality
170  if (val1 == val2) return val1;
171 
172  // resolve one value none
173  if (val1 == boost::none || val2 == boost::none) {
174  if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
175  else return val1 == boost::none ? val2 : val1;
176  }
177 
178  // resolve different numbers
179  if (resolve_max != boost::none) {
180  return *resolve_max ? max(*val1, *val2) : min(*val1, *val2);
181  }
182 
183  // throw runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", val1, val2);
184  throw runtime_error(string("Cannot reconcile integrals: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
185  }
186  template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
187  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
188  return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
189  }
190 
191  template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
192  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
193 
194  // check for equality
195  if (val1 == val2) return val1;
196 
197  // resolve one value none
198  if (val1 == boost::none || val2 == boost::none) {
199  if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
200  else return val1 == boost::none ? val2 : val1;
201  }
202 
203  // resolve different booleans
204  if (resolve_true != boost::none) {
205  return val1 == resolve_true ? val1 : val2; // if resolve true, return true, else return false
206  } else {
207  throw runtime_error(string("Cannot reconcile booleans: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
208  }
209  }
210  template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
211  boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
212  return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
213  }
214 
215  template <class T>
216  vector<T> reconcile(const vector<T>& v1, const vector<T>& v2, const string& err_msg = "") {
217 
218  // check for equality
219  if (v1 == v2) return v1;
220 
221  // resolve one vector empty
222  if (v1.empty()) return v2;
223  if (v2.empty()) return v1;
224 
225  // otherwise cannot reconcile
226  throw runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? string(". ") + err_msg : string("")));
227  }
228 
229 // template <class T>
230 // boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2) {
231 // return reconcile(val1, val2, boost::none, boost::none, boost::none);
232 // }
233 }
234 #endif /* monero_utils_h */
shared_ptr< monero_block > cn_block_to_block(const cryptonote::block &cn_block)
Definition: monero_utils.cpp:494
shared_ptr< monero_tx > cn_tx_to_tx(const cryptonote::transaction &cn_tx, bool init_as_tx_wallet=false)
Definition: monero_utils.cpp:510
Definition: monero_utils.h:64