Monero
Loading...
Searching...
No Matches
cryptonote_basic.h
Go to the documentation of this file.
1// Copyright (c) 2014-2022, 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>
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"
53
54namespace 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)
70 };
71
76
77 // outputs <= HF_VERSION_VIEW_TAGS
84
85 // outputs >= HF_VERSION_VIEW_TAGS
87 {
89 txout_to_tagged_key(const crypto::public_key &_key, const crypto::view_tag &_view_tag) : key(_key), view_tag(_view_tag) { }
91 crypto::view_tag view_tag; // optimization to reduce scanning time
92
94 FIELD(key)
97 };
98
99 /* inputs */
100
101 struct txin_gen
102 {
103 size_t height;
104
108 };
109
111 {
113 size_t prevout;
114 std::vector<uint8_t> sigset;
115
117 FIELD(prev)
121 };
122
137
139 {
141 std::vector<uint64_t> key_offsets;
142 crypto::key_image k_image; // double spending protection
143
149 };
150
151
153
155
156 //typedef std::pair<uint64_t, txout> out_t;
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
187 FIELD(vin)
188 FIELD(vout)
189 FIELD(extra)
191
192 public:
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> prunable_hash_valid;
210 mutable std::atomic<bool> blob_size_valid;
211
212 public:
213 std::vector<std::vector<crypto::signature> > signatures; //count signatures always the same as inputs count
215
216 // hash cash
219 mutable size_t blob_size;
220
221 bool pruned;
222
223 std::atomic<unsigned int> unprunable_size;
224 std::atomic<unsigned int> prefix_size;
225
226 transaction();
227 transaction(const transaction &t);
229 virtual ~transaction();
230 void set_null();
231 void invalidate_hashes();
232 bool is_hash_valid() const { return hash_valid.load(std::memory_order_acquire); }
233 void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); }
234 bool is_prunable_hash_valid() const { return prunable_hash_valid.load(std::memory_order_acquire); }
235 void set_prunable_hash_valid(bool v) const { prunable_hash_valid.store(v,std::memory_order_release); }
236 bool is_blob_size_valid() const { return blob_size_valid.load(std::memory_order_acquire); }
237 void set_blob_size_valid(bool v) const { blob_size_valid.store(v,std::memory_order_release); }
238 void set_hash(const crypto::hash &h) const { hash = h; set_hash_valid(true); }
240 void set_blob_size(size_t sz) const { blob_size = sz; set_blob_size_valid(true); }
241
243 if (!typename Archive<W>::is_saving())
244 {
245 set_hash_valid(false);
247 set_blob_size_valid(false);
248 }
249
250 const auto start_pos = ar.getpos();
251
252 FIELDS(*static_cast<transaction_prefix *>(this))
253
254 if (std::is_same<Archive<W>, binary_archive<W>>())
255 prefix_size = ar.getpos() - start_pos;
256
257 if (version == 1)
258 {
259 if (std::is_same<Archive<W>, binary_archive<W>>())
260 unprunable_size = ar.getpos() - start_pos;
261
262 ar.tag("signatures");
263 ar.begin_array();
265 bool signatures_not_expected = signatures.empty();
266 if (!signatures_not_expected && vin.size() != signatures.size())
267 return false;
268
269 if (!pruned) for (size_t i = 0; i < vin.size(); ++i)
270 {
271 size_t signature_size = get_signature_size(vin[i]);
272 if (signatures_not_expected)
273 {
274 if (0 == signature_size)
275 continue;
276 else
277 return false;
278 }
279
281 if (signature_size != signatures[i].size())
282 return false;
283
284 FIELDS(signatures[i]);
285
286 if (vin.size() - i > 1)
287 ar.delimit_array();
288 }
289 ar.end_array();
290 }
291 else
292 {
293 ar.tag("rct_signatures");
294 if (!vin.empty())
295 {
296 ar.begin_object();
297 bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
298 if (!r || !ar.good()) return false;
299 ar.end_object();
300
301 if (std::is_same<Archive<W>, binary_archive<W>>())
302 unprunable_size = ar.getpos() - start_pos;
303
304 if (!pruned && rct_signatures.type != rct::RCTTypeNull)
305 {
306 ar.tag("rctsig_prunable");
307 ar.begin_object();
308 r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(),
309 vin.size() > 0 && vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 : 0);
310 if (!r || !ar.good()) return false;
311 ar.end_object();
312 }
313 }
314 }
315 if (!typename Archive<W>::is_saving())
316 pruned = false;
318
319 template<bool W, template <bool> class Archive>
320 bool serialize_base(Archive<W> &ar)
321 {
322 FIELDS(*static_cast<transaction_prefix *>(this))
323
324 if (version == 1)
325 {
326 }
327 else
328 {
329 ar.tag("rct_signatures");
330 if (!vin.empty())
331 {
332 ar.begin_object();
333 bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
334 if (!r || !ar.good()) return false;
335 ar.end_object();
336 }
337 }
338 if (!typename Archive<W>::is_saving())
339 pruned = true;
340 return ar.good();
341 }
342
343 private:
344 static size_t get_signature_size(const txin_v& tx_in);
345 };
346
354 pruned(t.pruned),
356 prefix_size(t.prefix_size.load())
357 {
358 if (t.is_hash_valid())
359 {
360 hash = t.hash;
361 set_hash_valid(true);
362 }
363 if (t.is_blob_size_valid())
364 {
365 blob_size = t.blob_size;
366 set_blob_size_valid(true);
367 }
368 if (t.is_prunable_hash_valid())
369 {
370 prunable_hash = t.prunable_hash;
371 set_prunable_hash_valid(true);
372 }
373 }
374
376 {
377 transaction_prefix::operator=(t);
378
379 set_hash_valid(false);
381 set_blob_size_valid(false);
382 signatures = t.signatures;
383 rct_signatures = t.rct_signatures;
384 if (t.is_hash_valid())
385 {
386 hash = t.hash;
387 set_hash_valid(true);
388 }
389 if (t.is_prunable_hash_valid())
390 {
391 prunable_hash = t.prunable_hash;
393 }
394 if (t.is_blob_size_valid())
395 {
396 blob_size = t.blob_size;
398 }
399 pruned = t.pruned;
400 unprunable_size = t.unprunable_size.load();
401 prefix_size = t.prefix_size.load();
402 return *this;
403 }
404
405 inline
407 {
408 set_null();
409 }
410
411 inline
415
416 inline
418 {
420 signatures.clear();
422 set_hash_valid(false);
424 set_blob_size_valid(false);
425 pruned = false;
426 unprunable_size = 0;
427 prefix_size = 0;
428 }
429
430 inline
432 {
433 set_hash_valid(false);
435 set_blob_size_valid(false);
436 }
437
438 inline
440 {
441 struct txin_signature_size_visitor : public boost::static_visitor<size_t>
442 {
443 size_t operator()(const txin_gen& txin) const{return 0;}
444 size_t operator()(const txin_to_script& txin) const{return 0;}
445 size_t operator()(const txin_to_scripthash& txin) const{return 0;}
446 size_t operator()(const txin_to_key& txin) const {return txin.key_offsets.size();}
447 };
448
449 return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
450 }
451
452
453
454 /************************************************************************/
455 /* */
456 /************************************************************************/
458 {
460 uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
464
470 FIELD(nonce)
472 };
473
474 struct block: public block_header
475 {
476 private:
477 // hash cash
478 mutable std::atomic<bool> hash_valid;
479
480 public:
482 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); } }
483 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; }
485 bool is_hash_valid() const { return hash_valid.load(std::memory_order_acquire); }
486 void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); }
487 void set_hash(const crypto::hash &h) const { hash = h; set_hash_valid(true); }
488
490 std::vector<crypto::hash> tx_hashes;
491
492 // hash cash
494
496 if (!typename Archive<W>::is_saving())
498
499 FIELDS(*static_cast<block_header *>(this))
503 return false;
505 };
506
507
508 /************************************************************************/
509 /* */
510 /************************************************************************/
537
538 struct keypair
539 {
542
543 static inline keypair generate(hw::device &hwdev)
544 {
545 keypair k;
546 hwdev.generate_keys(k.pub, k.sec);
547 return k;
548 }
549 };
550 //---------------------------------------------------------------
551
552}
553
554namespace std {
555 template <>
556 struct hash<cryptonote::account_public_address>
557 {
558 std::size_t operator()(const cryptonote::account_public_address& addr) const
559 {
560 // https://stackoverflow.com/a/17017281
561 size_t res = 17;
562 res = res * 31 + hash<crypto::public_key>()(addr.m_spend_public_key);
563 res = res * 31 + hash<crypto::public_key>()(addr.m_view_public_key);
564 return res;
565 }
566 };
567}
568
571
582
593
cryptonote::block b
Definition block.cpp:40
static uint64_t h
Definition blockchain_stats.cpp:55
std::vector< uint8_t > extra
Definition cryptonote_basic.h:181
if(version==0||CURRENT_TRANSACTION_VERSION< version) return false
std::vector< txin_v > vin
Definition cryptonote_basic.h:178
size_t version
Definition cryptonote_basic.h:175
transaction_prefix()
Definition cryptonote_basic.h:193
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
const auto start_pos
Definition cryptonote_basic.h:250
bool is_hash_valid() const
Definition cryptonote_basic.h:232
bool is_prunable_hash_valid() const
Definition cryptonote_basic.h:234
rct::rctSig rct_signatures
Definition cryptonote_basic.h:214
std::atomic< bool > blob_size_valid
Definition cryptonote_basic.h:210
void set_null()
Definition cryptonote_basic.h:417
transaction()
Definition cryptonote_basic.h:406
void set_blob_size(size_t sz) const
Definition cryptonote_basic.h:240
std::atomic< unsigned int > unprunable_size
Definition cryptonote_basic.h:223
void set_prunable_hash(const crypto::hash &h) const
Definition cryptonote_basic.h:239
std::atomic< unsigned int > prefix_size
Definition cryptonote_basic.h:224
bool pruned
Definition cryptonote_basic.h:221
void set_hash(const crypto::hash &h) const
Definition cryptonote_basic.h:238
void set_hash_valid(bool v) const
Definition cryptonote_basic.h:233
bool serialize_base(Archive< W > &ar)
Definition cryptonote_basic.h:320
static size_t get_signature_size(const txin_v &tx_in)
Definition cryptonote_basic.h:439
if(!typename Archive< W >::is_saving())
Definition cryptonote_basic.h:243
void set_prunable_hash_valid(bool v) const
Definition cryptonote_basic.h:235
transaction & operator=(const transaction &t)
Definition cryptonote_basic.h:375
std::atomic< bool > prunable_hash_valid
Definition cryptonote_basic.h:209
crypto::hash prunable_hash
Definition cryptonote_basic.h:218
std::vector< std::vector< crypto::signature > > signatures
Definition cryptonote_basic.h:213
void invalidate_hashes()
Definition cryptonote_basic.h:431
virtual ~transaction()
Definition cryptonote_basic.h:412
size_t blob_size
Definition cryptonote_basic.h:219
void set_blob_size_valid(bool v) const
Definition cryptonote_basic.h:237
crypto::hash hash
Definition cryptonote_basic.h:217
bool is_blob_size_valid() const
Definition cryptonote_basic.h:236
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
binary_archive< false > ar
Definition cold-outputs.cpp:54
#define CRYPTONOTE_MAX_TX_PER_BLOCK
Definition cryptonote_config.h:42
#define CURRENT_TRANSACTION_VERSION
Definition cryptonote_config.h:45
#define BEGIN_SERIALIZE()
#define BEGIN_SERIALIZE_OBJECT()
#define BLOB_SERIALIZER(T)
#define FIELD(f)
#define false
#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec)
#define FIELDS(f)
#define END_SERIALIZE()
#define VARIANT_TAG(Archive, Type, Tag)
#define VARINT_FIELD(f)
const char * res
Definition hmac_keccak.cpp:42
#define const
Definition ipfrdr.c:80
JSON archive.
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble)
Definition keyvalue_serialization.h:123
#define END_KV_SERIALIZE_MAP()
Definition keyvalue_serialization.h:118
#define BEGIN_KV_SERIALIZE_MAP()
Definition keyvalue_serialization.h:43
Definition portable_binary_archive.hpp:29
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition crypto.h:72
POD_CLASS view_tag
Definition crypto.h:103
POD_CLASS public_key
Definition crypto.h:64
POD_CLASS key_image
Definition crypto.h:95
POD_CLASS hash
Definition hash.h:49
Holds cryptonote related classes and helpers.
Definition blockchain_db.cpp:45
boost::variant< txout_to_script, txout_to_scripthash, txout_to_key, txout_to_tagged_key > txout_target_v
Definition cryptonote_basic.h:154
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key > txin_v
Definition cryptonote_basic.h:152
std::vector< crypto::signature > ring_signature
Definition cryptonote_basic.h:56
@ RCTTypeNull
Definition rctTypes.h:299
Definition enums.h:68
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
Definition binary_archive.h:89
Definition cryptonote_basic.h:512
crypto::public_key m_view_public_key
Definition cryptonote_basic.h:514
bool operator!=(const account_public_address &rhs) const
Definition cryptonote_basic.h:532
crypto::public_key m_spend_public_key
Definition cryptonote_basic.h:513
Definition cryptonote_basic.h:458
crypto::hash prev_id
Definition cryptonote_basic.h:462
uint64_t timestamp
Definition cryptonote_basic.h:461
uint8_t minor_version
Definition cryptonote_basic.h:460
uint8_t major_version
Definition cryptonote_basic.h:459
uint32_t nonce
Definition cryptonote_basic.h:463
Definition cryptonote_basic.h:475
transaction miner_tx
Definition cryptonote_basic.h:489
void set_hash(const crypto::hash &h) const
Definition cryptonote_basic.h:487
void invalidate_hashes()
Definition cryptonote_basic.h:484
block()
Definition cryptonote_basic.h:481
crypto::hash hash
Definition cryptonote_basic.h:493
block & operator=(const block &b)
Definition cryptonote_basic.h:483
bool is_hash_valid() const
Definition cryptonote_basic.h:485
void set_hash_valid(bool v) const
Definition cryptonote_basic.h:486
block(const block &b)
Definition cryptonote_basic.h:482
std::vector< crypto::hash > tx_hashes
Definition cryptonote_basic.h:490
if(!typename Archive< W >::is_saving()) set_hash_valid(false)
std::atomic< bool > hash_valid
Definition cryptonote_basic.h:478
Definition cryptonote_basic.h:539
crypto::secret_key sec
Definition cryptonote_basic.h:541
static keypair generate(hw::device &hwdev)
Definition cryptonote_basic.h:543
crypto::public_key pub
Definition cryptonote_basic.h:540
Definition cryptonote_basic.h:158
txout_target_v target
Definition cryptonote_basic.h:160
uint64_t amount
Definition cryptonote_basic.h:159
Definition cryptonote_basic.h:102
size_t height
Definition cryptonote_basic.h:103
Definition cryptonote_basic.h:139
crypto::key_image k_image
Definition cryptonote_basic.h:142
std::vector< uint64_t > key_offsets
Definition cryptonote_basic.h:141
uint64_t amount
Definition cryptonote_basic.h:140
Definition cryptonote_basic.h:111
crypto::hash prev
Definition cryptonote_basic.h:112
std::vector< uint8_t > sigset
Definition cryptonote_basic.h:114
size_t prevout
Definition cryptonote_basic.h:113
Definition cryptonote_basic.h:124
size_t prevout
Definition cryptonote_basic.h:126
std::vector< uint8_t > sigset
Definition cryptonote_basic.h:128
txout_to_script script
Definition cryptonote_basic.h:127
crypto::hash prev
Definition cryptonote_basic.h:125
Definition cryptonote_basic.h:79
crypto::public_key key
Definition cryptonote_basic.h:82
txout_to_key()
Definition cryptonote_basic.h:80
txout_to_key(const crypto::public_key &_key)
Definition cryptonote_basic.h:81
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:87
txout_to_tagged_key(const crypto::public_key &_key, const crypto::view_tag &_view_tag)
Definition cryptonote_basic.h:89
txout_to_tagged_key()
Definition cryptonote_basic.h:88
crypto::public_key key
Definition cryptonote_basic.h:90
crypto::view_tag view_tag
Definition cryptonote_basic.h:91
Definition debug_archive.h:37
a archive using the JSON standard
Definition json_archive.h:116
Definition rctTypes.h:613
std::size_t operator()(const cryptonote::account_public_address &addr) const
Definition cryptonote_basic.h:558
for dealing with variants