Electroneum
cryptonote_basic.h
Go to the documentation of this file.
1 // Copyrights(c) 2017-2020, The Electroneum Project
2 // Copyrights(c) 2014-2019, The Monero Project
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without modification, are
7 // permitted provided that the following conditions are met:
8 //
9 // 1. Redistributions of source code must retain the above copyright notice, this list of
10 // conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 // of conditions and the following disclaimer in the documentation and/or other
14 // materials provided with the distribution.
15 //
16 // 3. Neither the name of the copyright holder nor the names of its contributors may be
17 // used to endorse or promote products derived from this software without specific
18 // prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31 
32 #pragma once
33 
34 #include <boost/variant.hpp>
35 #include <boost/functional/hash/hash.hpp>
36 #include <vector>
37 #include <cstring> // memcmp
38 #include <sstream>
39 #include <atomic>
40 #include "serialization/variant.h"
41 #include "serialization/vector.h"
45 #include "serialization/crypto.h"
46 #include "serialization/keyvalue_serialization.h" // eepe named serialization
47 #include "cryptonote_config.h"
48 #include "crypto/crypto.h"
49 #include "crypto/hash.h"
50 #include "misc_language.h"
51 #include "ringct/rctTypes.h"
52 #include "device/device.hpp"
53 
54 namespace cryptonote
55 {
56  typedef std::vector<crypto::signature> ring_signature;
57 
58 
59  /* outputs */
60 
62  {
63  std::vector<crypto::public_key> keys;
64  std::vector<uint8_t> script;
65 
67  FIELD(keys)
68  FIELD(script)
70  };
71 
73  {
75  };
76 
77  struct txout_to_key
78  {
80  txout_to_key(const crypto::public_key &_key) : key(_key) { }
82  };
83 
84 
85  /* inputs */
86 
87  struct txin_gen
88  {
89  size_t height;
90 
94  };
95 
97  {
99  size_t prevout;
100  std::vector<uint8_t> sigset;
101 
103  FIELD(prev)
104  VARINT_FIELD(prevout)
105  FIELD(sigset)
106  END_SERIALIZE()
107  };
108 
110  {
112  size_t prevout;
114  std::vector<uint8_t> sigset;
115 
117  FIELD(prev)
118  VARINT_FIELD(prevout)
119  FIELD(script)
120  FIELD(sigset)
121  END_SERIALIZE()
122  };
123 
124  struct txin_to_key
125  {
126  uint64_t amount;
127  std::vector<uint64_t> key_offsets;
128  crypto::key_image k_image; // double spending protection
129 
131  VARINT_FIELD(amount)
132  FIELD(key_offsets)
133  FIELD(k_image)
134  END_SERIALIZE()
135  };
136 
137 
139 
141 
142  //typedef std::pair<uint64_t, txout> out_t;
143  struct tx_out
144  {
145  uint64_t amount;
147 
149  VARINT_FIELD(amount)
150  FIELD(target)
151  END_SERIALIZE()
152 
153 
154  };
155 
156  template<typename T> static inline unsigned int getpos(T &ar) { return 0; }
157  template<> inline unsigned int getpos(binary_archive<true> &ar) { return ar.stream().tellp(); }
158  template<> inline unsigned int getpos(binary_archive<false> &ar) { return ar.stream().tellg(); }
159 
160  struct validator_db {
161  uint64_t expiration_date;
162  std::vector<uint8_t> validators;
163 
165  VARINT_FIELD(expiration_date)
166  FIELD(validators)
167  END_SERIALIZE()
168  };
169 
171  {
172 
173  public:
174  // tx information
175  size_t version;
176  uint64_t unlock_time; //number of block (or time), used as a limitation like: spend this tx not early then block/time
177 
178  std::vector<txin_v> vin;
179  std::vector<tx_out> vout;
180  //extra
181  std::vector<uint8_t> extra;
182 
186  VARINT_FIELD(unlock_time)
187  FIELD(vin)
188  FIELD(vout)
189  FIELD(extra)
190  END_SERIALIZE()
191 
192  public:
193  transaction_prefix(){ set_null(); }
194  void set_null()
195  {
196  version = 1;
197  unlock_time = 0;
198  vin.clear();
199  vout.clear();
200  extra.clear();
201  }
202  };
203 
205  {
206  private:
207  // hash cash
208  mutable std::atomic<bool> hash_valid;
209  mutable std::atomic<bool> blob_size_valid;
210 
211  public:
212  std::vector<std::vector<crypto::signature> > signatures; //count signatures always the same as inputs count
214 
215  // hash cash
217  mutable size_t blob_size;
218 
219  bool pruned;
220 
221  std::atomic<unsigned int> unprunable_size;
222  std::atomic<unsigned int> prefix_size;
223 
224  transaction();
225  transaction(const transaction &t): transaction_prefix(t), hash_valid(false), blob_size_valid(false), signatures(t.signatures), rct_signatures(t.rct_signatures), pruned(t.pruned), unprunable_size(t.unprunable_size.load()), prefix_size(t.prefix_size.load()) { if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } }
226  transaction &operator=(const transaction &t) { transaction_prefix::operator=(t); set_hash_valid(false); set_blob_size_valid(false); signatures = t.signatures; rct_signatures = t.rct_signatures; if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } pruned = t.pruned; unprunable_size = t.unprunable_size.load(); prefix_size = t.prefix_size.load(); return *this; }
227  virtual ~transaction();
228  void set_null();
229  void invalidate_hashes();
230  bool is_hash_valid() const { return hash_valid.load(std::memory_order_acquire); }
231  void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); }
232  bool is_blob_size_valid() const { return blob_size_valid.load(std::memory_order_acquire); }
233  void set_blob_size_valid(bool v) const { blob_size_valid.store(v,std::memory_order_release); }
234  void set_hash(const crypto::hash &h) { hash = h; set_hash_valid(true); }
235  void set_blob_size(size_t sz) { blob_size = sz; set_blob_size_valid(true); }
236 
238  if (!typename Archive<W>::is_saving())
239  {
240  set_hash_valid(false);
241  set_blob_size_valid(false);
242  }
243 
244  const unsigned int start_pos = getpos(ar);
245 
246  FIELDS(*static_cast<transaction_prefix *>(this))
247 
248  if (std::is_same<Archive<W>, binary_archive<W>>())
249  prefix_size = getpos(ar) - start_pos;
250 
251  if (version == 1)
252  {
253  if (std::is_same<Archive<W>, binary_archive<W>>())
254  unprunable_size = getpos(ar) - start_pos;
255 
256  ar.tag("signatures");
257  ar.begin_array();
258  PREPARE_CUSTOM_VECTOR_SERIALIZATION(vin.size(), signatures);
259  bool signatures_not_expected = signatures.empty();
260  if (!signatures_not_expected && vin.size() != signatures.size())
261  return false;
262 
263  if (!pruned) for (size_t i = 0; i < vin.size(); ++i)
264  {
265  size_t signature_size = get_signature_size(vin[i]);
266  if (signatures_not_expected)
267  {
268  if (0 == signature_size)
269  continue;
270  else
271  return false;
272  }
273 
274  PREPARE_CUSTOM_VECTOR_SERIALIZATION(signature_size, signatures[i]);
275  if (signature_size != signatures[i].size())
276  return false;
277 
278  FIELDS(signatures[i]);
279 
280  if (vin.size() - i > 1)
281  ar.delimit_array();
282  }
283  ar.end_array();
284  }
285  else
286  {
287  ar.tag("rct_signatures");
288  if (!vin.empty())
289  {
290  ar.begin_object();
291  bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
292  if (!r || !ar.stream().good()) return false;
293  ar.end_object();
294 
295  if (std::is_same<Archive<W>, binary_archive<W>>())
296  unprunable_size = getpos(ar) - start_pos;
297 
298  if (!pruned && rct_signatures.type != rct::RCTTypeNull)
299  {
300  ar.tag("rctsig_prunable");
301  ar.begin_object();
302  r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(),
303  vin.size() > 0 && vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 : 0);
304  if (!r || !ar.stream().good()) return false;
305  ar.end_object();
306  }
307  }
308  }
309  if (!typename Archive<W>::is_saving())
310  pruned = false;
311  END_SERIALIZE()
312 
313  template<bool W, template <bool> class Archive>
314  bool serialize_base(Archive<W> &ar)
315  {
316  FIELDS(*static_cast<transaction_prefix *>(this))
317 
318  if (version == 1)
319  {
320  }
321  else
322  {
323  ar.tag("rct_signatures");
324  if (!vin.empty())
325  {
326  ar.begin_object();
327  bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
328  if (!r || !ar.stream().good()) return false;
329  ar.end_object();
330  }
331  }
332  if (!typename Archive<W>::is_saving())
333  pruned = true;
334  return ar.stream().good();
335  }
336 
337  private:
338  static size_t get_signature_size(const txin_v& tx_in);
339  };
340 
341 
342  inline
344  {
345  set_null();
346  }
347 
348  inline
350  {
351  }
352 
353  inline
355  {
357  signatures.clear();
358  rct_signatures.type = rct::RCTTypeNull;
359  set_hash_valid(false);
360  set_blob_size_valid(false);
361  pruned = false;
362  unprunable_size = 0;
363  prefix_size = 0;
364  }
365 
366  inline
368  {
369  set_hash_valid(false);
370  set_blob_size_valid(false);
371  }
372 
373  inline
375  {
376  struct txin_signature_size_visitor : public boost::static_visitor<size_t>
377  {
378  size_t operator()(const txin_gen& txin) const{return 0;}
379  size_t operator()(const txin_to_script& txin) const{return 0;}
380  size_t operator()(const txin_to_scripthash& txin) const{return 0;}
381  size_t operator()(const txin_to_key& txin) const {return txin.key_offsets.size();}
382  };
383 
384  return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
385  }
386 
387 
388 
389  /************************************************************************/
390  /* */
391  /************************************************************************/
393  {
394  uint8_t major_version;
395  uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
396  uint64_t timestamp;
398  uint32_t nonce;
399 
401  VARINT_FIELD(major_version)
402  VARINT_FIELD(minor_version)
403  VARINT_FIELD(timestamp)
404  FIELD(prev_id)
405  FIELD(nonce)
406  END_SERIALIZE()
407  };
408 
409  struct block: public block_header
410  {
411  private:
412  // hash cash
413  mutable std::atomic<bool> hash_valid;
414 
415  public:
416  block(): block_header(), hash_valid(false) {}
417  block(const block &b): block_header(b), hash_valid(false), miner_tx(b.miner_tx), tx_hashes(b.tx_hashes), signature(b.signature), signatory(b.signatory) { if (b.is_hash_valid()) { hash = b.hash; set_hash_valid(true); } }
418  block &operator=(const block &b) { block_header::operator=(b); hash_valid = false; miner_tx = b.miner_tx; tx_hashes = b.tx_hashes; signature = b.signature; signatory = b.signatory; if (b.is_hash_valid()) { hash = b.hash; set_hash_valid(true); } return *this; }
419  void invalidate_hashes() { set_hash_valid(false); }
420  bool is_hash_valid() const { return hash_valid.load(std::memory_order_acquire); }
421  void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); }
422 
424  std::vector<crypto::hash> tx_hashes;
425 
426  mutable std::vector<uint8_t> signature;
427  mutable std::vector<uint8_t> signatory;
428 
429  // hash cash
431 
433  if (!typename Archive<W>::is_saving())
434  set_hash_valid(false);
435 
436  FIELDS(*static_cast<block_header *>(this))
437  FIELD(miner_tx)
438  FIELD(tx_hashes)
440  FIELD(signatory)
441 
442  if (tx_hashes.size() > CRYPTONOTE_MAX_TX_PER_BLOCK)
443  return false;
444 
445  END_SERIALIZE()
446  };
447 
448 
449  /************************************************************************/
450  /* */
451  /************************************************************************/
453  {
456 
458  FIELD(m_spend_public_key)
459  FIELD(m_view_public_key)
460  END_SERIALIZE()
461 
462  BEGIN_KV_SERIALIZE_MAP()
463  KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_spend_public_key)
464  KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(m_view_public_key)
465  END_KV_SERIALIZE_MAP()
466 
467  bool operator==(const account_public_address& rhs) const
468  {
469  return m_spend_public_key == rhs.m_spend_public_key &&
470  m_view_public_key == rhs.m_view_public_key;
471  }
472 
473  bool operator!=(const account_public_address& rhs) const
474  {
475  return !(*this == rhs);
476  }
477  };
478 
479  struct keypair
480  {
483 
484  static inline keypair generate(hw::device &hwdev)
485  {
486  keypair k;
487  hwdev.generate_keys(k.pub, k.sec);
488  return k;
489  }
490  };
491  //---------------------------------------------------------------
492 
493 }
494 
495 namespace std {
496  template <>
497  struct hash<cryptonote::account_public_address>
498  {
499  std::size_t operator()(const cryptonote::account_public_address& addr) const
500  {
501  // https://stackoverflow.com/a/17017281
502  size_t res = 17;
503  res = res * 31 + hash<crypto::public_key>()(addr.m_spend_public_key);
504  res = res * 31 + hash<crypto::public_key>()(addr.m_view_public_key);
505  return res;
506  }
507  };
508 }
509 
512 
522 
532 
uint64_t height
Definition: blockchain.cpp:91
uint8_t version
Definition: blockchain.cpp:90
Definition: cryptonote_basic.h:171
std::vector< uint8_t > extra
Definition: cryptonote_basic.h:181
std::vector< txin_v > vin
Definition: cryptonote_basic.h:178
size_t version
Definition: cryptonote_basic.h:175
void set_null()
Definition: cryptonote_basic.h:194
std::vector< tx_out > vout
Definition: cryptonote_basic.h:179
uint64_t unlock_time
Definition: cryptonote_basic.h:176
Definition: cryptonote_basic.h:205
bool is_hash_valid() const
Definition: cryptonote_basic.h:230
rct::rctSig rct_signatures
Definition: cryptonote_basic.h:213
transaction & operator=(const transaction &t)
Definition: cryptonote_basic.h:226
void set_hash(const crypto::hash &h)
Definition: cryptonote_basic.h:234
std::atomic< bool > blob_size_valid
Definition: cryptonote_basic.h:209
void set_null()
Definition: cryptonote_basic.h:354
transaction()
Definition: cryptonote_basic.h:343
std::atomic< unsigned int > unprunable_size
Definition: cryptonote_basic.h:221
std::atomic< unsigned int > prefix_size
Definition: cryptonote_basic.h:222
bool pruned
Definition: cryptonote_basic.h:219
void set_blob_size(size_t sz)
Definition: cryptonote_basic.h:235
void set_hash_valid(bool v) const
Definition: cryptonote_basic.h:231
static size_t get_signature_size(const txin_v &tx_in)
Definition: cryptonote_basic.h:374
transaction(const transaction &t)
Definition: cryptonote_basic.h:225
std::vector< std::vector< crypto::signature > > signatures
Definition: cryptonote_basic.h:212
void invalidate_hashes()
Definition: cryptonote_basic.h:367
virtual ~transaction()
Definition: cryptonote_basic.h:349
size_t blob_size
Definition: cryptonote_basic.h:217
void set_blob_size_valid(bool v) const
Definition: cryptonote_basic.h:233
crypto::hash hash
Definition: cryptonote_basic.h:216
bool is_blob_size_valid() const
Definition: cryptonote_basic.h:232
std::atomic< bool > hash_valid
Definition: cryptonote_basic.h:208
Definition: device.hpp:87
virtual crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key &recovery_key=crypto::secret_key(), bool recover=false)=0
VARIANT_TAG(binary_archive, cryptonote::txin_gen, 0xff)
BLOB_SERIALIZER(cryptonote::txout_to_key)
#define CRYPTONOTE_MAX_TX_PER_BLOCK
Definition: cryptonote_config.h:43
#define CURRENT_TRANSACTION_VERSION
Definition: cryptonote_config.h:47
const uint32_t T[512]
Definition: groestl_tables.h:37
#define inline
Definition: inline_c.h:35
JSON archive.
int b
Definition: base.py:1
void load(Archive &a, std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
Definition: unordered_containers_boost_serialization.h:55
Definition: unordered_containers_boost_serialization.h:39
const
Definition: build_protob.py:9
POD_CLASS signature
Definition: crypto.h:108
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition: crypto.h:82
POD_CLASS public_key
Definition: crypto.h:76
POD_CLASS key_image
Definition: crypto.h:102
POD_CLASS hash
Definition: hash.h:50
Holds cryptonote related classes and helpers.
Definition: db_bdb.cpp:226
boost::variant< txout_to_script, txout_to_scripthash, txout_to_key > txout_target_v
Definition: cryptonote_basic.h:140
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key > txin_v
Definition: cryptonote_basic.h:138
std::vector< crypto::signature > ring_signature
Definition: cryptonote_basic.h:56
static unsigned int getpos(T &ar)
Definition: cryptonote_basic.h:156
@ RCTTypeNull
Definition: rctTypes.h:229
Definition: blockchain_ancestry.cpp:73
#define BEGIN_SERIALIZE()
Begins the environment of the DSL \detailed for describing how to serialize an of an archive type.
Definition: serialization.h:181
#define BEGIN_SERIALIZE_OBJECT()
begins the environment of the DSL \detailed for described the serialization of an object
Definition: serialization.h:190
#define FIELD(f)
tags the field with the variable name and then serializes it
Definition: serialization.h:243
#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec)
Definition: serialization.h:203
#define FIELDS(f)
does not add a tag to the serialized value
Definition: serialization.h:254
#define END_SERIALIZE()
self-explanatory
Definition: serialization.h:214
#define VARINT_FIELD(f)
tags and serializes the varint f
Definition: serialization.h:263
#define false
Definition: stdbool.h:38
Definition: binary_archive.h:99
Definition: binary_archive.h:182
stream_type & stream()
Definition: binary_archive.h:77
Definition: binary_archive.h:94
Definition: cryptonote_basic.h:453
crypto::public_key m_view_public_key
Definition: cryptonote_basic.h:455
bool operator!=(const account_public_address &rhs) const
Definition: cryptonote_basic.h:473
crypto::public_key m_spend_public_key
Definition: cryptonote_basic.h:454
Definition: cryptonote_basic.h:393
crypto::hash prev_id
Definition: cryptonote_basic.h:397
uint64_t timestamp
Definition: cryptonote_basic.h:396
uint8_t minor_version
Definition: cryptonote_basic.h:395
uint8_t major_version
Definition: cryptonote_basic.h:394
uint32_t nonce
Definition: cryptonote_basic.h:398
Definition: cryptonote_basic.h:410
transaction miner_tx
Definition: cryptonote_basic.h:423
std::vector< uint8_t > signature
Definition: cryptonote_basic.h:426
void invalidate_hashes()
Definition: cryptonote_basic.h:419
block()
Definition: cryptonote_basic.h:416
crypto::hash hash
Definition: cryptonote_basic.h:430
bool is_hash_valid() const
Definition: cryptonote_basic.h:420
void set_hash_valid(bool v) const
Definition: cryptonote_basic.h:421
std::vector< uint8_t > signatory
Definition: cryptonote_basic.h:427
block(const block &b)
Definition: cryptonote_basic.h:417
std::vector< crypto::hash > tx_hashes
Definition: cryptonote_basic.h:424
block & operator=(const block &b)
Definition: cryptonote_basic.h:418
std::atomic< bool > hash_valid
Definition: cryptonote_basic.h:413
Definition: cryptonote_basic.h:480
crypto::secret_key sec
Definition: cryptonote_basic.h:482
static keypair generate(hw::device &hwdev)
Definition: cryptonote_basic.h:484
crypto::public_key pub
Definition: cryptonote_basic.h:481
Definition: cryptonote_basic.h:144
txout_target_v target
Definition: cryptonote_basic.h:146
uint64_t amount
Definition: cryptonote_basic.h:145
Definition: cryptonote_basic.h:88
size_t height
Definition: cryptonote_basic.h:89
Definition: cryptonote_basic.h:125
crypto::key_image k_image
Definition: cryptonote_basic.h:128
std::vector< uint64_t > key_offsets
Definition: cryptonote_basic.h:127
uint64_t amount
Definition: cryptonote_basic.h:126
Definition: cryptonote_basic.h:97
crypto::hash prev
Definition: cryptonote_basic.h:98
std::vector< uint8_t > sigset
Definition: cryptonote_basic.h:100
size_t prevout
Definition: cryptonote_basic.h:99
Definition: cryptonote_basic.h:110
size_t prevout
Definition: cryptonote_basic.h:112
std::vector< uint8_t > sigset
Definition: cryptonote_basic.h:114
txout_to_script script
Definition: cryptonote_basic.h:113
crypto::hash prev
Definition: cryptonote_basic.h:111
Definition: cryptonote_basic.h:78
crypto::public_key key
Definition: cryptonote_basic.h:81
txout_to_key()
Definition: cryptonote_basic.h:79
txout_to_key(const crypto::public_key &_key)
Definition: cryptonote_basic.h:80
Definition: cryptonote_basic.h:62
std::vector< crypto::public_key > keys
Definition: cryptonote_basic.h:63
std::vector< uint8_t > script
Definition: cryptonote_basic.h:64
Definition: cryptonote_basic.h:73
crypto::hash hash
Definition: cryptonote_basic.h:74
Definition: cryptonote_basic.h:160
uint64_t expiration_date
Definition: cryptonote_basic.h:161
std::vector< uint8_t > validators
Definition: cryptonote_basic.h:162
Definition: debug_archive.h:38
a archive using the JSON standard
Definition: json_archive.h:112
uint8_t type
Definition: rctTypes.h:241
bool serialize_rctsig_base(Archive< W > &ar, size_t inputs, size_t outputs)
Definition: rctTypes.h:251
bool serialize_rctsig_prunable(Archive< W > &ar, uint8_t type, size_t inputs, size_t outputs, size_t mixin)
Definition: rctTypes.h:325
Definition: rctTypes.h:436
rctSigPrunable p
Definition: rctTypes.h:437
std::size_t operator()(const cryptonote::account_public_address &addr) const
Definition: cryptonote_basic.h:499
for dealing with variants