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