|
|
|
@ -823,8 +823,10 @@ static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &
|
|
|
|
|
switch (rv.type)
|
|
|
|
|
{
|
|
|
|
|
case rct::RCTTypeSimple:
|
|
|
|
|
case rct::RCTTypeSimpleBulletproof:
|
|
|
|
|
return rct::decodeRctSimple(rv, rct::sk2rct(scalar1), i, mask);
|
|
|
|
|
case rct::RCTTypeFull:
|
|
|
|
|
case rct::RCTTypeFullBulletproof:
|
|
|
|
|
return rct::decodeRct(rv, rct::sk2rct(scalar1), i, mask);
|
|
|
|
|
default:
|
|
|
|
|
LOG_ERROR("Unsupported rct type: " << rv.type);
|
|
|
|
@ -3774,9 +3776,10 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f
|
|
|
|
|
LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size());
|
|
|
|
|
signed_txes.ptx.push_back(pending_tx());
|
|
|
|
|
tools::wallet2::pending_tx &ptx = signed_txes.ptx.back();
|
|
|
|
|
bool bulletproof = sd.use_rct && !ptx.tx.rct_signatures.p.bulletproofs.empty();
|
|
|
|
|
crypto::secret_key tx_key;
|
|
|
|
|
std::vector<crypto::secret_key> additional_tx_keys;
|
|
|
|
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct);
|
|
|
|
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, bulletproof);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_testnet);
|
|
|
|
|
// we don't test tx size, because we don't know the current limit, due to not having a blockchain,
|
|
|
|
|
// and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway,
|
|
|
|
@ -4659,7 +4662,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
|
|
|
|
|
|
|
|
|
void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
|
|
|
|
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
|
|
|
|
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx)
|
|
|
|
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, bool bulletproof)
|
|
|
|
|
{
|
|
|
|
|
using namespace cryptonote;
|
|
|
|
|
// throw if attempting a transaction with no destinations
|
|
|
|
@ -4775,7 +4778,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
|
|
|
|
crypto::secret_key tx_key;
|
|
|
|
|
std::vector<crypto::secret_key> additional_tx_keys;
|
|
|
|
|
LOG_PRINT_L2("constructing tx");
|
|
|
|
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true);
|
|
|
|
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, bulletproof);
|
|
|
|
|
LOG_PRINT_L2("constructed tx, r="<<r);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_testnet);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(upper_transaction_size_limit <= get_object_blobsize(tx), error::tx_too_big, tx, upper_transaction_size_limit);
|
|
|
|
@ -5734,7 +5737,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|
|
|
|
tx.selected_transfers.size() << " inputs");
|
|
|
|
|
if (use_rct)
|
|
|
|
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
test_tx, test_ptx);
|
|
|
|
|
test_tx, test_ptx, bulletproof);
|
|
|
|
|
else
|
|
|
|
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
|
|
|
@ -5777,7 +5780,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|
|
|
|
while (needed_fee > test_ptx.fee) {
|
|
|
|
|
if (use_rct)
|
|
|
|
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
test_tx, test_ptx);
|
|
|
|
|
test_tx, test_ptx, bulletproof);
|
|
|
|
|
else
|
|
|
|
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
|
|
|
@ -5984,7 +5987,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|
|
|
|
tx.selected_transfers.size() << " outputs");
|
|
|
|
|
if (use_rct)
|
|
|
|
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
test_tx, test_ptx);
|
|
|
|
|
test_tx, test_ptx, bulletproof);
|
|
|
|
|
else
|
|
|
|
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
|
|
|
@ -6001,7 +6004,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|
|
|
|
tx.dsts[0].amount = available_for_fee - needed_fee;
|
|
|
|
|
if (use_rct)
|
|
|
|
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
test_tx, test_ptx);
|
|
|
|
|
test_tx, test_ptx, bulletproof);
|
|
|
|
|
else
|
|
|
|
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
|
|
|
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
|
|
|
|