diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 288aa24..81ac013 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -34,6 +34,7 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "profile_tools.h" #include "ringct/rctOps.h" +#include "ringct/rctSigs.h" #include "lmdb/db_lmdb.h" @@ -240,7 +241,10 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair if (miner_tx && tx.version == 2) { cryptonote::tx_out vout = tx.vout[i]; - rct::key commitment = rct::zeroCommit(vout.amount); + // TODO: avoid multiple expensive zeroCommitVartime call here + get_outs_by_last_locked_block + ver_non_input_consensus + rct::key commitment; + if (!rct::getCommitment(tx, i, commitment)) + throw std::runtime_error("Failed to get miner tx commitment, aborting"); vout.amount = 0; amount_output_indices[i] = add_output(tx_hash, vout, i, unlock_time, &commitment); diff --git a/src/cryptonote_core/tx_verification_utils.cpp b/src/cryptonote_core/tx_verification_utils.cpp index 15b14c2..c6ccb90 100644 --- a/src/cryptonote_core/tx_verification_utils.cpp +++ b/src/cryptonote_core/tx_verification_utils.cpp @@ -113,6 +113,26 @@ static crypto::hash calc_tx_mixring_hash(const transaction& tx, const rct::ctkey namespace cryptonote { +bool collect_pubkeys_and_commitments(const transaction& tx, std::vector &pubkeys_and_commitments_inout) +{ + for (std::size_t i = 0; i < tx.vout.size(); ++i) + { + crypto::public_key output_pubkey; + if (!cryptonote::get_output_public_key(tx.vout[i], output_pubkey)) + return false; + rct::key pubkey = rct::pk2rct(output_pubkey); + + rct::key commitment; + if (!rct::getCommitment(tx, i, commitment)) + return false; + + pubkeys_and_commitments_inout.emplace_back(pubkey); + pubkeys_and_commitments_inout.emplace_back(commitment); + } + + return true; +} + uint64_t get_transaction_weight_limit(const uint8_t hf_version) { // from v2, limit a tx to 50% of the minimum block weight diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 26351d2..6357800 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -1839,4 +1839,17 @@ namespace rct { key mask; return decodeRctSimple(rv, sk, i, mask, hwdev); } + + bool getCommitment(const cryptonote::transaction &tx, const std::size_t output_idx, rct::key &c_out) { + const bool miner_tx = cryptonote::is_coinbase(tx); + if (miner_tx || tx.version < 2) + { + CHECK_AND_ASSERT_MES(tx.vout.size() > output_idx, false, "unexpected size of vout"); + c_out = zeroCommit(tx.vout[output_idx].amount); + return true; + } + CHECK_AND_ASSERT_MES(tx.rct_signatures.outPk.size() > output_idx, false, "unexpected size of outPk"); + c_out = tx.rct_signatures.outPk[output_idx].mask; + return true; + } } diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index 85e95b2..a2c9d5b 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -48,7 +48,7 @@ extern "C" { } #include "crypto/crypto.h" -//#include "cryptonote_basic/cryptonote_basic.h" +#include "cryptonote_basic/cryptonote_basic.h" //#include "cryptonote_protocol/enums.h" #include "rctTypes.h" @@ -185,6 +185,7 @@ namespace rct { xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key & mask, hw::device &hwdev); xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, hw::device &hwdev); key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev); + bool getCommitment(const cryptonote::transaction &tx, const std::size_t output_idx, rct::key &c_out); } #endif /* RCTSIGS_H */