Skip to content

Commit fdaa1cb

Browse files
committed
jeffro comments
1 parent 8de45fd commit fdaa1cb

File tree

8 files changed

+38
-27
lines changed

8 files changed

+38
-27
lines changed

src/blockchain_db/blockchain_db.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti
236236
if (miner_tx && tx.version == 2)
237237
{
238238
cryptonote::tx_out vout = tx.vout[i];
239-
// TODO: avoid multiple expensive zeroCommitVartime call here + get_outs_by_last_locked_block + ver_non_input_consensus
240-
rct::key commitment = rct::getCommitment(tx, i);
239+
rct::key commitment = rct::getCtKey(tx, i).mask;
241240
vout.amount = 0;
242241
amount_output_indices[i] = add_output(tx_hash, vout, i, tx.unlock_time,
243242
&commitment);

src/blockchain_db/blockchain_db_utils.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,19 @@ static uint64_t set_tx_outs_by_last_locked_block(const cryptonote::transaction &
6666
{
6767
const auto &out = tx.vout[i];
6868

69-
crypto::public_key output_public_key;
70-
if (!cryptonote::get_output_public_key(out, output_public_key))
71-
throw std::runtime_error("Could not get an output public key from a tx output.");
72-
7369
static_assert(CURRENT_TRANSACTION_VERSION == 2, "This section of code was written with 2 tx versions in mind. "
7470
"Revisit this section and update for the new tx version.");
7571
CHECK_AND_ASSERT_THROW_MES(tx.version == 1 || tx.version == 2, "encountered unexpected tx version");
7672

7773
TIME_MEASURE_NS_START(getting_commitment);
7874

79-
rct::key commitment = rct::getCommitment(tx, i);
75+
rct::ctkey ctKey = rct::getCtKey(tx, i);
8076

8177
TIME_MEASURE_NS_FINISH(getting_commitment);
8278

8379
auto output_pair = fcmp_pp::curve_trees::OutputPair{
84-
.output_pubkey = std::move(output_public_key),
85-
.commitment = std::move(commitment)
80+
.output_pubkey = std::move(rct::rct2pk(ctKey.dest)),
81+
.commitment = std::move(ctKey.mask)
8682
};
8783

8884
const uint64_t output_id = first_output_id + i;

src/cryptonote_core/tx_verification_utils.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,11 @@ bool collect_pubkeys_and_commitments(const transaction& tx, std::vector<rct::key
445445
{
446446
for (std::size_t i = 0; i < tx.vout.size(); ++i)
447447
{
448-
crypto::public_key output_pubkey;
449-
if (!cryptonote::get_output_public_key(tx.vout[i], output_pubkey))
450-
return false;
451-
452-
rct::key pubkey = rct::pk2rct(output_pubkey);
453-
pubkeys_and_commitments_inout.emplace_back(std::move(pubkey));
454-
pubkeys_and_commitments_inout.emplace_back(rct::getCommitment(tx, i));
448+
rct::ctkey ctKey;
449+
try { ctKey = rct::getCtKey(tx, i); }
450+
catch (...) { return false; }
451+
pubkeys_and_commitments_inout.emplace_back(std::move(ctKey.dest));
452+
pubkeys_and_commitments_inout.emplace_back(std::move(ctKey.mask));
455453
}
456454

457455
return true;

src/fcmp_pp/curve_trees.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,14 @@ struct OutputContext final
123123
uint64_t output_id{0};
124124
// TODO: consider using a variant instead
125125
// True if the output pair elems are guaranteed to not have torsion and are not equal to identity
126-
bool torsion_checked{false};
126+
uint8_t torsion_checked{0};
127127
OutputPair output_pair;
128128

129+
// Using uint8_t for torsion_checked because sizeof(bool) is platform-dependent: https://github.com/seraphis-migration/monero/pull/20#discussion_r2027787352
130+
// These static asserts ensure booleans cast to the expected uint8_t value and vice versa
131+
static_assert((uint8_t) 0 == (uint8_t) false && (uint8_t) 1 == (uint8_t) true, "Unexpected bool <> uint8_t casting");
132+
static_assert((bool) ((uint8_t) 0) == false && (bool) ((uint8_t) 1) == true, "Unexpected uint8_t <> bool casting");
133+
129134
bool operator==(const OutputContext &other) const { return output_id == other.output_id && output_pair == other.output_pair; }
130135

131136
template <class Archive>

src/ringct/rctOps.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ extern "C" {
4545
#include "rctCryptoOps.h"
4646
}
4747
#include "crypto/crypto.h"
48-
#include "cryptonote_basic/cryptonote_basic.h"
4948

5049
#include "rctTypes.h"
5150

src/ringct/rctSigs.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,15 +1751,29 @@ namespace rct {
17511751
return decodeRctSimple(rv, sk, i, mask, hwdev);
17521752
}
17531753

1754-
key getCommitment(const cryptonote::transaction &tx, const std::size_t output_idx) {
1755-
const bool miner_tx = cryptonote::is_coinbase(tx);
1756-
if (miner_tx || tx.version < 2)
1754+
ctkey getCtKey(const cryptonote::transaction &tx, const std::size_t output_idx) {
1755+
if (tx.rct_signatures.outPk.size() > output_idx)
17571756
{
1758-
CHECK_AND_ASSERT_THROW_MES(tx.vout.size() > output_idx, "unexpected size of vout");
1759-
return zeroCommitVartime(tx.vout[output_idx].amount);
1757+
return tx.rct_signatures.outPk[output_idx];
17601758
}
1761-
CHECK_AND_ASSERT_THROW_MES(tx.rct_signatures.outPk.size() > output_idx, "unexpected size of outPk");
1762-
return tx.rct_signatures.outPk[output_idx].mask;
1759+
1760+
// Expand tx.rct_signatures.outPk to include the output pubkey and commitment, so that we don't have to call
1761+
// the expensive zeroCommitVartime multiple times unnecessarily.
1762+
// If we don't expand outPk in order of its outputs, then the if statement above could return the incorrect mask.
1763+
CHECK_AND_ASSERT_THROW_MES(tx.rct_signatures.outPk.size() == output_idx, "must expand outPk in order");
1764+
1765+
// We expect all txs to have outPk expanded already, except for coinbase and v1 txs
1766+
const bool miner_tx = cryptonote::is_coinbase(tx);
1767+
CHECK_AND_ASSERT_THROW_MES(miner_tx || tx.version < 2, "unexpected tx missing commitment");
1768+
1769+
crypto::public_key output_public_key;
1770+
CHECK_AND_ASSERT_THROW_MES(tx.vout.size() > output_idx, "tx.vout too small");
1771+
CHECK_AND_ASSERT_THROW_MES(cryptonote::get_output_public_key(tx.vout[output_idx], output_public_key),
1772+
"failed to get output public key");
1773+
1774+
auto outPk = ctkey{.dest = rct::pk2rct(output_public_key), .mask = zeroCommitVartime(tx.vout[output_idx].amount)};
1775+
tx.rct_signatures.outPk.emplace_back(std::move(outPk));
1776+
return tx.rct_signatures.outPk.back();
17631777
}
17641778

17651779
bool verPointsForTorsion(const std::vector<key> & pts) {

src/ringct/rctSigs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ namespace rct {
142142
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key & mask, hw::device &hwdev);
143143
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, hw::device &hwdev);
144144
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev);
145-
key getCommitment(const cryptonote::transaction &tx, const std::size_t output_idx);
145+
ctkey getCtKey(const cryptonote::transaction &tx, const std::size_t output_idx);
146146

147147
// Make sure points are valid points, don't have torsion, and are not equal to identity
148148
bool verPointsForTorsion(const std::vector<key> & pts);

src/ringct/rctTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ namespace rct {
325325
//pairs that you mix with
326326
keyV pseudoOuts; //C - for simple rct
327327
std::vector<ecdhTuple> ecdhInfo;
328-
ctkeyV outPk;
328+
mutable ctkeyV outPk; // mutable so that getCtKey can expand it
329329
xmr_amount txnFee; // contains b
330330

331331
rctSigBase() :

0 commit comments

Comments
 (0)