From dc4aad7eb5fffa450d4c5eb094cf962e45b2f43a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 15 Jun 2016 23:37:13 +0100 Subject: add rct to the protocol It is not yet constrained to a fork, so don't use on the real network or you'll be orphaned or rejected. --- src/blockchain_db/blockchain_db.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/blockchain_db/blockchain_db.cpp') diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 68f635d18..86a117405 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -91,6 +91,8 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti for (uint64_t i = 0; i < tx.vout.size(); ++i) { amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time)); + if (tx.version > 1 && tx.vout[i].amount == 0) + add_rct_commitment(tx.rct_signatures.outPk[i].mask); } add_tx_amount_output_indices(tx_id, amount_output_indices); } -- cgit v1.2.3 From 59a66e209a844ac6d4221f7c04141b32fa2823c3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 29 Jun 2016 19:55:49 +0100 Subject: move the rct commitments to the output_amounts database Since these are needed at the same time as the output pubkeys, this is a whole lot faster, and takes less space. Only outputs of 0 amount store the commitment. When reading other outputs, a fake commitment is regenerated on the fly. This avoids having to rewrite the database to add space for fake commitments for existing outputs. This code relies on two things: - LMDB must support fixed size records per key, rather than per database (ie, all records on key 0 are the same size, all records for non 0 keys are same size, but records from key 0 and non 0 keys do have different sizes). - the commitment must be directly after the rest of the data in outkey and output_data_t. --- src/blockchain_db/berkeleydb/db_bdb.cpp | 2 +- src/blockchain_db/berkeleydb/db_bdb.h | 2 +- src/blockchain_db/blockchain_db.cpp | 5 +- src/blockchain_db/blockchain_db.h | 37 +------ src/blockchain_db/lmdb/db_lmdb.cpp | 167 ++++++++++---------------------- src/blockchain_db/lmdb/db_lmdb.h | 14 +-- src/cryptonote_core/blockchain.cpp | 25 +---- tests/unit_tests/hardfork.cpp | 6 +- 8 files changed, 63 insertions(+), 195 deletions(-) (limited to 'src/blockchain_db/blockchain_db.cpp') diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index 4d759d157..4ec284e38 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -361,7 +361,7 @@ void BlockchainBDB::remove_transaction_data(const crypto::hash& tx_hash, const t throw1(DB_ERROR("Failed to add removal of tx outputs to db transaction")); } -void BlockchainBDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time) +void BlockchainBDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) { LOG_PRINT_L3("BlockchainBDB::" << __func__); check_open(); diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h index 6bc26ed3d..f8e9440bd 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.h +++ b/src/blockchain_db/berkeleydb/db_bdb.h @@ -364,7 +364,7 @@ private: virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx); - virtual void add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time); + virtual void add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment); virtual void remove_output(const tx_out& tx_output); diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 86a117405..3719d9eb0 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -90,9 +90,8 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti // we need the index for (uint64_t i = 0; i < tx.vout.size(); ++i) { - amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time)); - if (tx.version > 1 && tx.vout[i].amount == 0) - add_rct_commitment(tx.rct_signatures.outPk[i].mask); + amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time, + tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL)); } add_tx_amount_output_indices(tx_id, amount_output_indices); } diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 5b759db4c..d26080a3b 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -110,6 +110,7 @@ struct output_data_t crypto::public_key pubkey; //!< the output's public key (for spend verification) uint64_t unlock_time; //!< the output's unlock time (or height) uint64_t height; //!< the height of the block which created the output + rct::key commitment; //!< the output's amount commitment (for spend verification) }; #pragma pack(pop) @@ -407,9 +408,10 @@ private: * @param tx_output the output * @param local_index index of the output in its transaction * @param unlock_time unlock time/height of the output + * @param commitment the rct commitment to the output amount * @return amount output index */ - virtual uint64_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time) = 0; + virtual uint64_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) = 0; /** * @brief store amount output indices for a tx's outputs @@ -1199,39 +1201,6 @@ public: */ virtual bool has_key_image(const crypto::key_image& img) const = 0; - /** - * @brief returns the number of ringct outputs in the database - * - * @return the number of ringct outputs in the database - */ - virtual uint64_t get_num_rct_outputs() const = 0; - - /** - * @brief returns the commitment for a given ringct output - * - * Throws OUTPUT_DNE if the index is out of range - * Throws DB_ERROR on other error - * - * @return the commitment for the given index - */ - virtual rct::key get_rct_commitment(uint64_t idx) const = 0; - - /** - * @brief Adds a new ringct output with the given commitment - * - * Throws DB_ERROR if the addition fails - * - * @return the index of the newly added record - */ - virtual uint64_t add_rct_commitment(const rct::key &commitment) = 0; - - /** - * @brief Remove a ringct output with the given index - * - * Throws DB_ERROR if the removal fails - */ - virtual void remove_rct_commitment(uint64_t idx) = 0; - /** * @brief runs a function over all key images stored * diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 887740e06..a0a0a041d 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -51,6 +51,13 @@ using epee::string_tools::pod_to_hex; namespace { +struct pre_rct_output_data_t +{ + crypto::public_key pubkey; //!< the output's public key (for spend verification) + uint64_t unlock_time; //!< the output's unlock time (or height) + uint64_t height; //!< the height of the block which created the output +}; + template inline void throw0(const T &e) { @@ -155,8 +162,6 @@ int compare_string(const MDB_val *a, const MDB_val *b) * * spent_keys input hash - * - * rct_commitments input ID {commitment key} - * * Note: where the data items are of uniform size, DUPFIXED tables have * been used to save space. In most of these cases, a dummy "zerokval" * key is used when accessing the table; the Key listed above will be @@ -177,8 +182,6 @@ const char* const LMDB_OUTPUT_TXS = "output_txs"; const char* const LMDB_OUTPUT_AMOUNTS = "output_amounts"; const char* const LMDB_SPENT_KEYS = "spent_keys"; -const char* const LMDB_RCT_COMMITMENTS = "rct_commitments"; - const char* const LMDB_HF_STARTING_HEIGHTS = "hf_starting_heights"; const char* const LMDB_HF_VERSIONS = "hf_versions"; @@ -246,6 +249,12 @@ typedef struct txindex { tx_data_t data; } txindex; +typedef struct pre_rct_outkey { + uint64_t amount_index; + uint64_t output_id; + pre_rct_output_data_t data; +} pre_rct_outkey; + typedef struct outkey { uint64_t amount_index; uint64_t output_id; @@ -769,7 +778,8 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const uint64_t BlockchainLMDB::add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, - const uint64_t unlock_time) + const uint64_t unlock_time, + const rct::key *commitment) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -782,6 +792,8 @@ uint64_t BlockchainLMDB::add_output(const crypto::hash& tx_hash, if (tx_output.target.type() != typeid(txout_to_key)) throw0(DB_ERROR("Wrong output type: expected txout_to_key")); + if (tx_output.amount == 0 && !commitment) + throw0(DB_ERROR("RCT output without commitment")); outtx ot = {m_num_outputs, tx_hash, local_index}; MDB_val_set(vot, ot); @@ -810,8 +822,16 @@ uint64_t BlockchainLMDB::add_output(const crypto::hash& tx_hash, ok.data.pubkey = boost::get < txout_to_key > (tx_output.target).key; ok.data.unlock_time = unlock_time; ok.data.height = m_height; + if (tx_output.amount == 0) + { + ok.data.commitment = *commitment; + data.mv_size = sizeof(ok); + } + else + { + data.mv_size = sizeof(pre_rct_outkey); + } data.mv_data = &ok; - data.mv_size = sizeof(ok); if ((result = mdb_cursor_put(m_cur_output_amounts, &val_amount, &data, MDB_APPENDDUP))) throw0(DB_ERROR(lmdb_error("Failed to add output pubkey to db transaction: ", result).c_str())); @@ -861,8 +881,6 @@ void BlockchainLMDB::remove_tx_outputs(const uint64_t tx_id, const transaction& { const tx_out tx_output = tx.vout[i-1]; remove_output(tx_output.amount, amount_output_indices[i-1]); - if (tx_output.amount == 0) - remove_rct_commitment(amount_output_indices[i-1]); } } @@ -1090,8 +1108,6 @@ void BlockchainLMDB::open(const std::string& filename, const int mdb_flags) lmdb_db_open(txn, LMDB_SPENT_KEYS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_spent_keys, "Failed to open db handle for m_spent_keys"); - lmdb_db_open(txn, LMDB_RCT_COMMITMENTS, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_rct_commitments, "Failed to open db handle for m_rct_commitments"); - // this subdb is dropped on sight, so it may not be present when we open the DB. // Since we use MDB_CREATE, we'll get an exception if we open read-only and it does not exist. // So we don't open for read-only, and also not drop below. It is not used elsewhere. @@ -1261,8 +1277,6 @@ void BlockchainLMDB::reset() throw0(DB_ERROR(lmdb_error("Failed to drop m_output_amounts: ", result).c_str())); if (auto result = mdb_drop(txn, m_spent_keys, 0)) throw0(DB_ERROR(lmdb_error("Failed to drop m_spent_keys: ", result).c_str())); - if (auto result = mdb_drop(txn, m_rct_commitments, 0)) - throw0(DB_ERROR(lmdb_error("Failed to drop m_rct_commitments: ", result).c_str())); (void)mdb_drop(txn, m_hf_starting_heights, 0); // this one is dropped in new code if (auto result = mdb_drop(txn, m_hf_versions, 0)) throw0(DB_ERROR(lmdb_error("Failed to drop m_hf_versions: ", result).c_str())); @@ -1943,8 +1957,19 @@ output_data_t BlockchainLMDB::get_output_key(const uint64_t& amount, const uint6 throw1(OUTPUT_DNE("Attempting to get output pubkey by index, but key does not exist")); else if (get_result) throw0(DB_ERROR("Error attempting to retrieve an output pubkey from the db")); - outkey *okp = (outkey *)v.mv_data; - output_data_t ret = okp->data; + + output_data_t ret; + if (amount == 0) + { + const outkey *okp = (const outkey *)v.mv_data; + ret = okp->data; + } + else + { + const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data; + memcpy(&ret, &okp->data, sizeof(pre_rct_output_data_t));; + ret.commitment = rct::zeroCommit(amount); + } TXN_POSTFIX_RDONLY(); return ret; } @@ -2567,8 +2592,18 @@ void BlockchainLMDB::get_output_key(const uint64_t &amount, const std::vectordata; + output_data_t data; + if (amount == 0) + { + const outkey *okp = (const outkey *)v.mv_data; + data = okp->data; + } + else + { + const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data; + memcpy(&data, &okp->data, sizeof(pre_rct_output_data_t)); + data.commitment = rct::zeroCommit(amount); + } outputs.push_back(data); } @@ -2742,106 +2777,6 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const return ret; } -uint64_t BlockchainLMDB::get_num_rct_outputs() const -{ - LOG_PRINT_L3("BlockchainLMDB::" << __func__); - check_open(); - - TXN_PREFIX_RDONLY(); - RCURSOR(rct_commitments); - - mdb_size_t num_outputs = 0; - MDB_stat ms; - auto result = mdb_stat(m_txn, m_rct_commitments, &ms); - if (result == MDB_SUCCESS) - { - num_outputs = ms.ms_entries; - } - else if (result == MDB_NOTFOUND) - { - num_outputs = 0; - } - else - { - throw0(DB_ERROR("DB error attempting to get number of ringct outputs")); - } - - TXN_POSTFIX_RDONLY(); - - return num_outputs; -} - -rct::key BlockchainLMDB::get_rct_commitment(uint64_t idx) const -{ - LOG_PRINT_L3("BlockchainLMDB::" << __func__); - check_open(); - - TXN_PREFIX_RDONLY(); - RCURSOR(rct_commitments); - - MDB_val_set(val_key, idx); - MDB_val val_ret; - auto result = mdb_cursor_get(m_cur_rct_commitments, &val_key, &val_ret, MDB_SET); - if (result == MDB_NOTFOUND) - throw0(OUTPUT_DNE(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast(idx) + " from the db: ", result).c_str())); - else if (result) - throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast(idx) + " from the db: ", result).c_str())); - - rct::key commitment = *(const rct::key*)val_ret.mv_data; - TXN_POSTFIX_RDONLY(); - return commitment; -} - -void BlockchainLMDB::remove_rct_commitment(uint64_t idx) -{ - LOG_PRINT_L3("BlockchainLMDB::" << __func__); - check_open(); - - mdb_txn_cursors *m_cursors = &m_wcursors; - CURSOR(rct_commitments); - - MDB_val_set(val_key, idx); - MDB_val val_ret; - auto result = mdb_cursor_get(m_cur_rct_commitments, &val_key, &val_ret, MDB_SET); - if (result == MDB_NOTFOUND) - throw0(OUTPUT_DNE(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast(idx) + " from the db: ", result).c_str())); - else if (result) - throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct commitment for " + boost::lexical_cast(idx) + " from the db: ", result).c_str())); - result = mdb_cursor_del(m_cur_rct_commitments, 0); - if (result) - throw0(DB_ERROR(lmdb_error("Error attempting to remove rct commitment for " + boost::lexical_cast(idx) + " from the db: ", result).c_str())); -} - -uint64_t BlockchainLMDB::add_rct_commitment(const rct::key &commitment) -{ - LOG_PRINT_L3("BlockchainLMDB::" << __func__); - check_open(); - - mdb_txn_cursors *m_cursors = &m_wcursors; - - CURSOR(rct_commitments); - - uint64_t num_outputs = 0; - MDB_stat ms; - auto result = mdb_stat(*m_write_txn, m_rct_commitments, &ms); - if (result == MDB_SUCCESS) - num_outputs = ms.ms_entries; - else if (result == MDB_NOTFOUND) - num_outputs = 0; - else - throw0(DB_ERROR("DB error attempting to get number of ringct outputs")); - - MDB_val_set(val_key, num_outputs); - MDB_val val_value; - val_value.mv_size = sizeof(rct::key); - val_value.mv_data = (void*)&commitment; - result = mdb_cursor_put(m_cur_rct_commitments, (MDB_val *)&val_key, &val_value, 0); - if (result) - throw0(DB_ERROR(lmdb_error("Failed to add rct output to db transaction: ", result).c_str())); - - return num_outputs; -} - bool BlockchainLMDB::is_read_only() const { unsigned int flags; diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 9e92b0661..050e9e0ae 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -55,8 +55,6 @@ typedef struct mdb_txn_cursors MDB_cursor *m_txc_spent_keys; - MDB_cursor *m_txc_rct_commitments; - MDB_cursor *m_txc_hf_versions; } mdb_txn_cursors; @@ -69,7 +67,6 @@ typedef struct mdb_txn_cursors #define m_cur_tx_indices m_cursors->m_txc_tx_indices #define m_cur_tx_outputs m_cursors->m_txc_tx_outputs #define m_cur_spent_keys m_cursors->m_txc_spent_keys -#define m_cur_rct_commitments m_cursors->m_txc_rct_commitments #define m_cur_hf_versions m_cursors->m_txc_hf_versions typedef struct mdb_rflags @@ -84,7 +81,6 @@ typedef struct mdb_rflags bool m_rf_tx_indices; bool m_rf_tx_outputs; bool m_rf_spent_keys; - bool m_rf_rct_commitments; bool m_rf_hf_versions; } mdb_rflags; @@ -236,11 +232,6 @@ public: virtual bool has_key_image(const crypto::key_image& img) const; - virtual uint64_t get_num_rct_outputs() const; - virtual rct::key get_rct_commitment(uint64_t idx) const; - virtual uint64_t add_rct_commitment(const rct::key &commitment); - virtual void remove_rct_commitment(uint64_t idx); - virtual bool for_all_key_images(std::function) const; virtual bool for_all_blocks(std::function) const; virtual bool for_all_transactions(std::function) const; @@ -302,7 +293,8 @@ private: virtual uint64_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, - const uint64_t unlock_time + const uint64_t unlock_time, + const rct::key *commitment ); virtual void add_tx_amount_output_indices(const uint64_t tx_id, @@ -369,8 +361,6 @@ private: MDB_dbi m_spent_keys; - MDB_dbi m_rct_commitments; - MDB_dbi m_hf_starting_heights; MDB_dbi m_hf_versions; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 82bc6c0d4..f46de9ca8 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -207,21 +207,8 @@ bool Blockchain::scan_outputkeys_for_indexes(size_t tx_version, const txin_to_ke else output_index = m_db->get_output_key(tx_in_to_key.amount, i); - rct::key commitment; - if (tx_version > 1) - { - if (tx_in_to_key.amount == 0) - commitment = m_db->get_rct_commitment(i); - else - commitment = rct::zeroCommit(tx_in_to_key.amount); - } - else - { - rct::identity(commitment); - } - // call to the passed boost visitor to grab the public key for the output - if (!vis.handle_output(output_index.unlock_time, output_index.pubkey, commitment)) + if (!vis.handle_output(output_index.unlock_time, output_index.pubkey, output_index.commitment)) { LOG_PRINT_L0("Failed to handle_output for output no = " << count << ", with absolute offset " << i); return false; @@ -1633,15 +1620,7 @@ void Blockchain::add_out_to_get_rct_random_outs(std::listget_output_key(amount, i); oen.out_key = data.pubkey; - if (amount == 0) - { - oen.commitment = m_db->get_rct_commitment(i); - } - else - { - // not a rct output, make a fake commitment with zero key - oen.commitment = rct::zeroCommit(amount); - } + oen.commitment = data.commitment; } //------------------------------------------------------------------ // This function takes an RPC request for mixins and creates an RPC response diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index 1eb73e156..a279b6c68 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -96,14 +96,10 @@ public: virtual void remove_block() { blocks.pop_back(); } virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash& tx_hash) {return 0;} virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx) {} - virtual uint64_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time) {return 0;} + virtual uint64_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) {return 0;} virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector& amount_output_indices) {} virtual void add_spent_key(const crypto::key_image& k_image) {} virtual void remove_spent_key(const crypto::key_image& k_image) {} - virtual uint64_t get_num_rct_outputs() const { return 0; } - virtual rct::key get_rct_commitment(uint64_t idx) const { return rct::key(); } - virtual uint64_t add_rct_commitment(const rct::key &commitment) { return 0; } - virtual void remove_rct_commitment(uint64_t idx) {} virtual bool for_all_key_images(std::function) const { return true; } virtual bool for_all_blocks(std::function) const { return true; } -- cgit v1.2.3 From c3b3260ae5b5acde445fa88a6f0909f582903754 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 12 Aug 2016 18:45:07 +0100 Subject: New "Halfway RingCT" outputs for coinbase transactions When RingCT is enabled, outputs from coinbase transactions are created as a single output, and stored as RingCT output, with a fake mask. Their amount is not hidden on the blockchain itself, but they are then able to be used as fake inputs in a RingCT ring. Since the output amounts are hidden, their "dustiness" is not an obstacle anymore to mixing, and this makes the coinbase transactions a lot smaller, as well as helping the TXO set to grow more slowly. Also add a new "Null" type of rct signature, which decreases the size required when no signatures are to be stored, as in a coinbase tx. --- src/blockchain_db/blockchain_db.cpp | 19 +++++++++++++-- src/cryptonote_core/blockchain.cpp | 24 ++++++++----------- src/cryptonote_core/cryptonote_basic.h | 3 +++ .../cryptonote_boost_serialization.h | 4 ++++ src/cryptonote_core/cryptonote_format_utils.cpp | 21 ++++++++++++---- src/cryptonote_core/cryptonote_format_utils.h | 1 + src/ringct/rctTypes.h | 9 +++++-- src/wallet/wallet2.cpp | 17 +++++++++++++ src/wallet/wallet2.h | 19 +++++++++++++-- tests/core_tests/block_validation.cpp | 2 ++ tests/core_tests/chaingen.cpp | 1 + tests/core_tests/double_spend.inl | 1 + tests/core_tests/integer_overflow.cpp | 1 + tests/core_tests/rct.cpp | 28 ++++++++++++++-------- tests/core_tests/rct.h | 2 +- tests/core_tests/transaction_tests.cpp | 1 + tests/core_tests/v2_tests.cpp | 1 + .../transactions_generation_from_blockchain.cpp | 1 + tests/performance_tests/multi_tx_test_base.h | 1 + 19 files changed, 120 insertions(+), 36 deletions(-) (limited to 'src/blockchain_db/blockchain_db.cpp') diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 3719d9eb0..7eb81d933 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -46,6 +46,7 @@ void BlockchainDB::pop_block() void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash* tx_hash_ptr) { + bool miner_tx = false; crypto::hash tx_hash; if (!tx_hash_ptr) { @@ -67,6 +68,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti else if (tx_input.type() == typeid(txin_gen)) { /* nothing to do here */ + miner_tx = true; } else { @@ -90,8 +92,21 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti // we need the index for (uint64_t i = 0; i < tx.vout.size(); ++i) { - amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time, - tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL)); + // miner v2 txes have their coinbase output in one single out to save space, + // and we store them as rct outputs with an identity mask + if (miner_tx && tx.version == 2) + { + cryptonote::tx_out vout = tx.vout[i]; + rct::key commitment = rct::zeroCommit(vout.amount); + vout.amount = 0; + amount_output_indices.push_back(add_output(tx_hash, vout, i, tx.unlock_time, + &commitment)); + } + else + { + amount_output_indices.push_back(add_output(tx_hash, tx.vout[i], i, tx.unlock_time, + tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL)); + } } add_tx_amount_output_indices(tx_id, amount_output_indices); } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 44dde7759..82691eb6b 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -959,7 +959,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl money_in_use += o.amount; partial_block_reward = false; - if (version >= 3) { + if (version == 3) { for (auto &o: b.miner_tx.vout) { if (!is_valid_decomposed_amount(o.amount)) { LOG_PRINT_L1("miner tx output " << print_money(o.amount) << " is not a valid decomposed amount"); @@ -1128,7 +1128,9 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m block size, so first miner transaction generated with fake amount of money, and with phase we know think we know expected block size */ //make blocks coin-base tx looks close to real coinbase tx to get truthful blob size - bool r = construct_miner_tx(height, median_size, already_generated_coins, txs_size, fee, miner_address, b.miner_tx, ex_nonce, 11, m_hardfork->get_current_version()); + uint8_t hf_version = m_hardfork->get_current_version(); + size_t max_outs = hf_version >= 4 ? 1 : 11; + bool r = construct_miner_tx(height, median_size, already_generated_coins, txs_size, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version); CHECK_AND_ASSERT_MES(r, false, "Failed to construc miner tx, first chance"); size_t cumulative_size = txs_size + get_object_blobsize(b.miner_tx); #if defined(DEBUG_CREATE_BLOCK_TEMPLATE) @@ -1137,7 +1139,7 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m #endif for (size_t try_count = 0; try_count != 10; ++try_count) { - r = construct_miner_tx(height, median_size, already_generated_coins, cumulative_size, fee, miner_address, b.miner_tx, ex_nonce, 11, m_hardfork->get_current_version()); + r = construct_miner_tx(height, median_size, already_generated_coins, cumulative_size, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version); CHECK_AND_ASSERT_MES(r, false, "Failed to construc miner tx, second chance"); size_t coinbase_blob_size = get_object_blobsize(b.miner_tx); @@ -2354,17 +2356,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, } } - // for v3, we force txes with all mixable inputs to be rct - if (m_hardfork->get_current_version() >= 4) - { - if (n_unmixable == 0 && tx.version == 1) - { - LOG_PRINT_L1("Tx " << get_transaction_hash(tx) << " is not rct and does not have unmixable inputs"); - tvc.m_not_rct = true; - return false; - } - } - if (mixin < 2) { if (n_unmixable == 0) @@ -2543,6 +2534,11 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, const rct::rctSig &rv = tx.rct_signatures; switch (rv.type) { + case rct::RCTTypeNull: { + // we only accept no signatures for coinbase txes + LOG_PRINT_L1("Null rct signature on non-coinbase tx"); + return false; + } case rct::RCTTypeSimple: { // check all this, either recontructed (so should really pass), or not { diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index b68040597..f54b8c2b3 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -233,6 +233,8 @@ namespace cryptonote FIELD(rct_signatures) switch (rct_signatures.type) { + case rct::RCTTypeNull: + break; case rct::RCTTypeSimple: if (rct_signatures.mixRing.size() && rct_signatures.mixRing.size() != vin.size()) return false; @@ -276,6 +278,7 @@ namespace cryptonote vout.clear(); extra.clear(); signatures.clear(); + rct_signatures.type = rct::RCTTypeNull; } inline diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h index 09e9a7fa7..c91f78c58 100644 --- a/src/cryptonote_core/cryptonote_boost_serialization.h +++ b/src/cryptonote_core/cryptonote_boost_serialization.h @@ -249,6 +249,8 @@ namespace boost inline void serialize(Archive &a, rct::rctSigBase &x, const boost::serialization::version_type ver) { a & x.type; + if (x.type == rct::RCTTypeNull) + return; if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple) throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type"); // a & x.message; message is not serialized, as it can be reconstructed from the tx data @@ -264,6 +266,8 @@ namespace boost inline void serialize(Archive &a, rct::rctSig &x, const boost::serialization::version_type ver) { a & x.type; + if (x.type == rct::RCTTypeNull) + return; if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple) throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type"); // a & x.message; message is not serialized, as it can be reconstructed from the tx data diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp index 6a3172d4e..cbaf11398 100644 --- a/src/cryptonote_core/cryptonote_format_utils.cpp +++ b/src/cryptonote_core/cryptonote_format_utils.cpp @@ -136,7 +136,10 @@ namespace cryptonote // from hard fork 2, we cut out the low significant digits. This makes the tx smaller, and // keeps the paid amount almost the same. The unpaid remainder gets pushed back to the // emission schedule - if (hard_fork_version >= 2) { + // from hard fork 4, we use a single "dusty" output. This makes the tx even smaller, + // and avoids the quantization. These outputs will be added as rct outputs with identity + // masks, to they can be used as rct inputs. + if (hard_fork_version >= 2 && hard_fork_version < 4) { block_reward = block_reward - block_reward % ::config::BASE_REWARD_CLAMP_THRESHOLD; } @@ -146,12 +149,16 @@ namespace cryptonote [&out_amounts](uint64_t a_dust) { out_amounts.push_back(a_dust); }); CHECK_AND_ASSERT_MES(1 <= max_outs, false, "max_out must be non-zero"); - if (height == 0) + if (height == 0 || hard_fork_version >= 4) { // the genesis block was not decomposed, for unknown reasons while (max_outs < out_amounts.size()) { - out_amounts[out_amounts.size() - 2] += out_amounts.back(); + //out_amounts[out_amounts.size() - 2] += out_amounts.back(); + //out_amounts.resize(out_amounts.size() - 1); + out_amounts[1] += out_amounts[0]; + for (size_t n = 1; n < out_amounts.size(); ++n) + out_amounts[n - 1] = out_amounts[n]; out_amounts.resize(out_amounts.size() - 1); } } @@ -182,7 +189,11 @@ namespace cryptonote CHECK_AND_ASSERT_MES(summary_amounts == block_reward, false, "Failed to construct miner tx, summary_amounts = " << summary_amounts << " not equal block_reward = " << block_reward); - tx.version = 1; + if (hard_fork_version >= 4) + tx.version = 2; + else + tx.version = 1; + //lock tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW; tx.vin.push_back(in); @@ -726,7 +737,7 @@ namespace cryptonote // zero out all amounts to mask rct outputs, real amounts are now encrypted for (size_t i = 0; i < tx.vin.size(); ++i) { - if (!(sources[i].mask == rct::identity())) + if (sources[i].rct) boost::get(tx.vin[i]).amount = 0; } for (size_t i = 0; i < tx.vout.size(); ++i) diff --git a/src/cryptonote_core/cryptonote_format_utils.h b/src/cryptonote_core/cryptonote_format_utils.h index 5da256921..e6a3bfba4 100644 --- a/src/cryptonote_core/cryptonote_format_utils.h +++ b/src/cryptonote_core/cryptonote_format_utils.h @@ -58,6 +58,7 @@ namespace cryptonote crypto::public_key real_out_tx_key; //incoming real tx public key size_t real_output_in_tx_index; //index in transaction outputs vector uint64_t amount; //money + bool rct; //true if the output is rct rct::key mask; //ringct amount mask void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount) { outputs.push_back(std::make_pair(idx, rct::ctkey({rct::pk2rct(k), rct::zeroCommit(amount)}))); } diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index da2e3808c..58e08b0f7 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -174,8 +174,9 @@ namespace rct { // outPk contains public keypairs which are destinations (P, C), // P = address, C = commitment to amount enum { - RCTTypeFull = 0, - RCTTypeSimple = 1, + RCTTypeNull = 0, + RCTTypeFull = 1, + RCTTypeSimple = 2, }; struct rctSigBase { uint8_t type; @@ -189,6 +190,8 @@ namespace rct { BEGIN_SERIALIZE() FIELD(type) + if (type == RCTTypeNull) + return true; // FIELD(message) - not serialized, it can be reconstructed // FIELD(mixRing) - not serialized, it can be reconstructed if (type == RCTTypeSimple) @@ -224,6 +227,8 @@ namespace rct { BEGIN_SERIALIZE_OBJECT() FIELDS(*static_cast(this)) + if (type == RCTTypeNull) + return true; FIELDS(p); END_SERIALIZE() }; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index b3b8e6561..985ebe778 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -489,10 +489,17 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s { td.m_mask = mask[o]; td.m_amount = amount[o]; + td.m_rct = true; + } + else if (miner_tx && tx.version == 2) + { + td.m_mask = rct::identity(); + td.m_rct = true; } else { td.m_mask = rct::identity(); + td.m_rct = false; } set_unspent(td); m_key_images[td.m_key_image] = m_transfers.size()-1; @@ -529,10 +536,17 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s { td.m_mask = mask[o]; td.m_amount = amount[o]; + td.m_rct = true; + } + else if (miner_tx && tx.version == 2) + { + td.m_mask = rct::identity(); + td.m_rct = true; } else { td.m_mask = rct::identity(); + td.m_rct = false; } THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki[o], error::wallet_internal_error, "Inconsistent key images"); THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status"); @@ -2847,6 +2861,7 @@ void wallet2::transfer_selected(const std::vectoris_rct()) { @@ -3732,6 +3748,7 @@ void wallet2::transfer_from(const std::vector &outs, size_t num_outputs, cryptonote::tx_source_entry& src = sources.back(); transfer_details& td = *it; src.amount = td.amount(); + src.rct = td.is_rct(); //paste real transaction to the random index auto it_to_insert = std::find_if(src.outputs.begin(), src.outputs.end(), [&](const tx_output_entry& a) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 0d61f90e2..259f7aca7 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -108,8 +108,9 @@ namespace tools crypto::key_image m_key_image; //TODO: key_image stored twice :( rct::key m_mask; uint64_t m_amount; + bool m_rct; - bool is_rct() const { return m_tx.vout[m_internal_output_index].amount == 0; } + bool is_rct() const { return m_rct; } uint64_t amount() const { return m_amount; } }; @@ -502,7 +503,7 @@ namespace tools }; } BOOST_CLASS_VERSION(tools::wallet2, 14) -BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 3) +BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 4) BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1) BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 5) BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2) @@ -527,6 +528,10 @@ namespace boost { x.m_spent_height = 0; } + if (ver < 4) + { + x.m_rct = x.m_tx.vout[x.m_internal_output_index].amount == 0; + } } template @@ -563,8 +568,17 @@ namespace boost } a & x.m_spent_height; if (ver < 3) + { + initialize_transfer_details(a, x, ver); return; + } a & x.m_txid; + if (ver < 4) + { + initialize_transfer_details(a, x, ver); + return; + } + a & x.m_rct; } template @@ -770,6 +784,7 @@ namespace tools cryptonote::tx_source_entry& src = sources.back(); transfer_details& td = *it; src.amount = td.amount(); + src.rct = false; //paste mixin transaction if(daemon_resp.outs.size()) { diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index 3989a71c9..df8972556 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -337,6 +337,7 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector& events se.amount = blk_0.miner_tx.vout[0].amount; se.push_output(0, boost::get(blk_0.miner_tx.vout[0].target).key, se.amount); se.real_output = 0; + se.rct = false; se.real_out_tx_key = get_tx_pub_key_from_extra(blk_0.miner_tx); se.real_output_in_tx_index = 0; std::vector sources; @@ -379,6 +380,7 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector se.amount = blk_1.miner_tx.vout[0].amount; se.push_output(0, boost::get(blk_1.miner_tx.vout[0].target).key, se.amount); se.real_output = 0; + se.rct = false; se.real_out_tx_key = get_tx_pub_key_from_extra(blk_1.miner_tx); se.real_output_in_tx_index = 0; std::vector sources; diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index b7a1c3dec..4cb70e745 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -458,6 +458,7 @@ bool fill_tx_sources(std::vector& sources, const std::vector::generate(std::vector(tx_0.vout[0].target).key, se.amount); se.real_output = 0; + se.rct = false; se.real_out_tx_key = get_tx_pub_key_from_extra(tx_0); se.real_output_in_tx_index = 0; sources.push_back(se); diff --git a/tests/core_tests/integer_overflow.cpp b/tests/core_tests/integer_overflow.cpp index aad377d6d..936f29675 100644 --- a/tests/core_tests/integer_overflow.cpp +++ b/tests/core_tests/integer_overflow.cpp @@ -63,6 +63,7 @@ namespace se.amount = tx.vout[out_idx].amount; se.push_output(0, boost::get(tx.vout[out_idx].target).key, se.amount); se.real_output = 0; + se.rct = false; se.real_out_tx_key = get_tx_pub_key_from_extra(tx); se.real_output_in_tx_index = out_idx; diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp index b358ce8b2..c29854888 100644 --- a/tests/core_tests/rct.cpp +++ b/tests/core_tests/rct.cpp @@ -57,8 +57,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev miner_accounts[n].generate(); CHECK_AND_ASSERT_MES(generator.construct_block_manually(blocks[n], *prev_block, miner_accounts[n], test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version, - 4, 4, prev_block->timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long - crypto::hash(), 0, transaction(), std::vector(), 0, 0, 4), + 2, 2, prev_block->timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long + crypto::hash(), 0, transaction(), std::vector(), 0, 0, 2), false, "Failed to generate block"); events.push_back(blocks[n]); prev_block = blocks + n; @@ -74,8 +74,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev cryptonote::block blk; CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account, test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version, - 4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long - crypto::hash(), 0, transaction(), std::vector(), 0, 0, 4), + 2, 2, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long + crypto::hash(), 0, transaction(), std::vector(), 0, 0, 2), false, "Failed to generate block"); events.push_back(blk); blk_last = blk; @@ -104,6 +104,7 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev src.real_output = n; src.real_output_in_tx_index = index_in_tx; src.mask = rct::identity(); + src.rct = false; //fill outputs entry tx_destination_entry td; @@ -135,9 +136,9 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev } CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes[n], blk_last, miner_account, - test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version, + test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs, 4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long - crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 0, 4), + crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4), false, "Failed to generate block"); events.push_back(blk_txes[n]); blk_last = blk_txes[n]; @@ -149,9 +150,9 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev { cryptonote::block blk; CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account, - test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version, + test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_max_outs, 4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long - crypto::hash(), 0, transaction(), std::vector(), 0, 0, 4), + crypto::hash(), 0, transaction(), std::vector(), 0, 6, 4), false, "Failed to generate block"); events.push_back(blk); blk_last = blk; @@ -161,7 +162,9 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev // create a tx from the requested ouputs std::vector sources; - size_t rct_idx = 0, pre_rct_idx = 0; + size_t global_rct_idx = 6; // skip first coinbase (6 outputs) + size_t rct_idx = 0; + size_t pre_rct_idx = 0; for (size_t out_idx_idx = 0; out_idx[out_idx_idx] >= 0; ++out_idx_idx) { sources.resize(sources.size()+1); tx_source_entry& src = sources.back(); @@ -173,12 +176,16 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev src.real_out_tx_key = get_tx_pub_key_from_extra(rct_txes[rct_idx/4]); src.real_output_in_tx_index = rct_idx&3; src.mask = rct_tx_masks[rct_idx]; + src.rct = true; for (int m = 0; m <= mixin; ++m) { rct::ctkey ctkey; ctkey.dest = rct::pk2rct(boost::get(rct_txes[rct_idx/4].vout[rct_idx&3].target).key); ctkey.mask = rct_txes[rct_idx/4].rct_signatures.outPk[rct_idx&3].mask; - src.outputs.push_back(std::make_pair(rct_idx, ctkey)); + src.outputs.push_back(std::make_pair(global_rct_idx, ctkey)); ++rct_idx; + ++global_rct_idx; + if (global_rct_idx % 10 == 0) + global_rct_idx += 6; // skip the coinbase } } else @@ -188,6 +195,7 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[pre_rct_idx].miner_tx); src.real_output_in_tx_index = 4; src.mask = rct::identity(); + src.rct = false; for (int m = 0; m <= mixin; ++m) { src.push_output(m, boost::get(blocks[pre_rct_idx].miner_tx.vout[4].target).key, src.amount); ++pre_rct_idx; diff --git a/tests/core_tests/rct.h b/tests/core_tests/rct.h index bf0dc61f5..e01815d26 100644 --- a/tests/core_tests/rct.h +++ b/tests/core_tests/rct.h @@ -81,7 +81,7 @@ private: template<> struct get_test_options { - const std::pair hard_forks[2] = {std::make_pair(1, 0), std::make_pair(4, 1)}; + const std::pair hard_forks[3] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65)}; const cryptonote::test_options test_options = { hard_forks }; diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index 8a1638c1d..cb585b975 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -97,6 +97,7 @@ bool test_transaction_generation_and_ring_signature() src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(tx_mine_2); src.real_output = 1; + src.rct = false; src.real_output_in_tx_index = 0; } //fill outputs entry diff --git a/tests/core_tests/v2_tests.cpp b/tests/core_tests/v2_tests.cpp index d9328d13a..93ddd8a12 100644 --- a/tests/core_tests/v2_tests.cpp +++ b/tests/core_tests/v2_tests.cpp @@ -96,6 +96,7 @@ bool gen_v2_tx_validation_base::generate_with(std::vector& eve } src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[0].miner_tx); src.real_output = 0; + src.rct = false; src.real_output_in_tx_index = out_idx[out_idx_idx]; } diff --git a/tests/functional_tests/transactions_generation_from_blockchain.cpp b/tests/functional_tests/transactions_generation_from_blockchain.cpp index 9dbcbbc10..63ff0343b 100644 --- a/tests/functional_tests/transactions_generation_from_blockchain.cpp +++ b/tests/functional_tests/transactions_generation_from_blockchain.cpp @@ -113,6 +113,7 @@ bool make_tx(blockchain_storage& bch) src.real_out_tx_key = td.m_tx.tx_pub_key; src.real_output = interted_it - src.outputs.begin(); src.real_output_in_tx_index = td.m_internal_output_index; + src.rct = false; ++i; } diff --git a/tests/performance_tests/multi_tx_test_base.h b/tests/performance_tests/multi_tx_test_base.h index 0883d674c..d8898b60d 100644 --- a/tests/performance_tests/multi_tx_test_base.h +++ b/tests/performance_tests/multi_tx_test_base.h @@ -72,6 +72,7 @@ public: source_entry.real_output_in_tx_index = 0; source_entry.outputs.swap(output_entries); source_entry.real_output = real_source_idx; + source_entry.rct = false; m_sources.push_back(source_entry); -- cgit v1.2.3