mirror of
				https://git.wownero.com/wownero/wownero.git
				synced 2024-08-15 01:03:23 +00:00 
			
		
		
		
	Merge pull request #8483
6075be9 feat(trezor): add HF15 support, BP+ (Dusan Klinec)
			
			
This commit is contained in:
		
						commit
						72490ca04f
					
				
					 6 changed files with 232 additions and 181 deletions
				
			
		| 
						 | 
				
			
			@ -324,8 +324,8 @@ namespace trezor {
 | 
			
		|||
 | 
			
		||||
      std::vector<protocol::ki::MoneroTransferDetails> mtds;
 | 
			
		||||
      std::vector<protocol::ki::MoneroExportedKeyImage> kis;
 | 
			
		||||
      protocol::ki::key_image_data(wallet, transfers, mtds, client_version() <= 1);
 | 
			
		||||
      protocol::ki::generate_commitment(mtds, transfers, req, client_version() <= 1);
 | 
			
		||||
      protocol::ki::key_image_data(wallet, transfers, mtds);
 | 
			
		||||
      protocol::ki::generate_commitment(mtds, transfers, req);
 | 
			
		||||
 | 
			
		||||
      EVENT_PROGRESS(0.);
 | 
			
		||||
      this->set_msg_addr<messages::monero::MoneroKeyImageExportInitRequest>(req.get());
 | 
			
		||||
| 
						 | 
				
			
			@ -635,11 +635,7 @@ namespace trezor {
 | 
			
		|||
      }
 | 
			
		||||
 | 
			
		||||
      // Step: sort
 | 
			
		||||
      auto perm_req = signer->step_permutation();
 | 
			
		||||
      if (perm_req){
 | 
			
		||||
        auto perm_ack = this->client_exchange<messages::monero::MoneroTransactionInputsPermutationAck>(perm_req);
 | 
			
		||||
        signer->step_permutation_ack(perm_ack);
 | 
			
		||||
      }
 | 
			
		||||
      signer->sort_ki();
 | 
			
		||||
      EVENT_PROGRESS(3, 1, 1);
 | 
			
		||||
 | 
			
		||||
      // Step: input_vini
 | 
			
		||||
| 
						 | 
				
			
			@ -697,13 +693,13 @@ namespace trezor {
 | 
			
		|||
    unsigned device_trezor::client_version()
 | 
			
		||||
    {
 | 
			
		||||
      auto trezor_version = get_version();
 | 
			
		||||
      if (trezor_version <= pack_version(2, 0, 10)){
 | 
			
		||||
        throw exc::TrezorException("Trezor firmware 2.0.10 and lower are not supported. Please update.");
 | 
			
		||||
      if (trezor_version < pack_version(2, 4, 3)){
 | 
			
		||||
        throw exc::TrezorException("Minimal Trezor firmware version is 2.4.3. Please update.");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      unsigned client_version = 1;
 | 
			
		||||
      if (trezor_version >= pack_version(2, 3, 1)){
 | 
			
		||||
        client_version = 3;
 | 
			
		||||
      unsigned client_version = 3;
 | 
			
		||||
      if (trezor_version >= pack_version(2, 5, 2)){
 | 
			
		||||
        client_version = 4;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_TREZOR_DEBUGGING
 | 
			
		||||
| 
						 | 
				
			
			@ -739,14 +735,6 @@ namespace trezor {
 | 
			
		|||
      CHECK_AND_ASSERT_THROW_MES(init_msg, "TransactionInitRequest is empty");
 | 
			
		||||
      CHECK_AND_ASSERT_THROW_MES(init_msg->has_tsx_data(), "TransactionInitRequest has no transaction data");
 | 
			
		||||
      CHECK_AND_ASSERT_THROW_MES(m_features, "Device state not initialized");  // make sure the caller did not reset features
 | 
			
		||||
      const bool nonce_required = init_msg->tsx_data().has_payment_id() && init_msg->tsx_data().payment_id().size() > 0;
 | 
			
		||||
 | 
			
		||||
      if (nonce_required && init_msg->tsx_data().payment_id().size() == 8){
 | 
			
		||||
        // Versions 2.0.9 and lower do not support payment ID
 | 
			
		||||
        if (get_version() <= pack_version(2, 0, 9)) {
 | 
			
		||||
          throw exc::TrezorException("Trezor firmware 2.0.9 and lower does not support transactions with short payment IDs or integrated addresses. Please update.");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void device_trezor::transaction_check(const protocol::tx::TData & tdata, const hw::tx_aux_data & aux_data)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@
 | 
			
		|||
#include <crypto/hmac-keccak.h>
 | 
			
		||||
#include <ringct/rctSigs.h>
 | 
			
		||||
#include <ringct/bulletproofs.h>
 | 
			
		||||
#include <ringct/bulletproofs_plus.h>
 | 
			
		||||
#include "cryptonote_config.h"
 | 
			
		||||
#include <sodium.h>
 | 
			
		||||
#include <sodium/crypto_verify_32.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -145,8 +146,7 @@ namespace ki {
 | 
			
		|||
 | 
			
		||||
  bool key_image_data(wallet_shim * wallet,
 | 
			
		||||
                      const std::vector<tools::wallet2::transfer_details> & transfers,
 | 
			
		||||
                      std::vector<MoneroTransferDetails> & res,
 | 
			
		||||
                      bool need_all_additionals)
 | 
			
		||||
                      std::vector<MoneroTransferDetails> & res)
 | 
			
		||||
  {
 | 
			
		||||
    for(auto & td : transfers){
 | 
			
		||||
      ::crypto::public_key tx_pub_key = wallet->get_tx_pub_key_from_received_outs(td);
 | 
			
		||||
| 
						 | 
				
			
			@ -159,11 +159,7 @@ namespace ki {
 | 
			
		|||
      cres.set_internal_output_index(td.m_internal_output_index);
 | 
			
		||||
      cres.set_sub_addr_major(td.m_subaddr_index.major);
 | 
			
		||||
      cres.set_sub_addr_minor(td.m_subaddr_index.minor);
 | 
			
		||||
      if (need_all_additionals) {
 | 
			
		||||
        for (auto &aux : additional_tx_pub_keys) {
 | 
			
		||||
          cres.add_additional_tx_pub_keys(key_to_string(aux));
 | 
			
		||||
        }
 | 
			
		||||
      } else if (!additional_tx_pub_keys.empty() && additional_tx_pub_keys.size() > td.m_internal_output_index) {
 | 
			
		||||
      if (!additional_tx_pub_keys.empty() && additional_tx_pub_keys.size() > td.m_internal_output_index) {
 | 
			
		||||
        cres.add_additional_tx_pub_keys(key_to_string(additional_tx_pub_keys[td.m_internal_output_index]));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -194,8 +190,7 @@ namespace ki {
 | 
			
		|||
 | 
			
		||||
  void generate_commitment(std::vector<MoneroTransferDetails> & mtds,
 | 
			
		||||
                           const std::vector<tools::wallet2::transfer_details> & transfers,
 | 
			
		||||
                           std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req,
 | 
			
		||||
                           bool need_subaddr_indices)
 | 
			
		||||
                           std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req)
 | 
			
		||||
  {
 | 
			
		||||
    req = std::make_shared<messages::monero::MoneroKeyImageExportInitRequest>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -219,16 +214,6 @@ namespace ki {
 | 
			
		|||
      auto & st = search.first->second;
 | 
			
		||||
      st.insert(cur.m_subaddr_index.minor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (need_subaddr_indices) {
 | 
			
		||||
      for (auto &x: sub_indices) {
 | 
			
		||||
        auto subs = req->add_subs();
 | 
			
		||||
        subs->set_account(x.first);
 | 
			
		||||
        for (auto minor : x.second) {
 | 
			
		||||
          subs->add_minor_indices(minor);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void live_refresh_ack(const ::crypto::secret_key & view_key_priv,
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +384,7 @@ namespace tx {
 | 
			
		|||
    m_tx_idx = tx_idx;
 | 
			
		||||
    m_ct.tx_data = cur_src_tx();
 | 
			
		||||
    m_multisig = false;
 | 
			
		||||
    m_client_version = 1;
 | 
			
		||||
    m_client_version = 3;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Signer::extract_payment_id(){
 | 
			
		||||
| 
						 | 
				
			
			@ -474,25 +459,19 @@ namespace tx {
 | 
			
		|||
      auto & cur = src.outputs[i];
 | 
			
		||||
      auto out = dst->add_outputs();
 | 
			
		||||
 | 
			
		||||
      if (i == src.real_output || need_ring_indices || client_version() <= 1) {
 | 
			
		||||
      if (i == src.real_output || need_ring_indices) {
 | 
			
		||||
        out->set_idx(cur.first);
 | 
			
		||||
      }
 | 
			
		||||
      if (i == src.real_output || need_ring_keys || client_version() <= 1) {
 | 
			
		||||
      if (i == src.real_output || need_ring_keys) {
 | 
			
		||||
        translate_rct_key(out->mutable_key(), &(cur.second));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dst->set_real_out_tx_key(key_to_string(src.real_out_tx_key));
 | 
			
		||||
    dst->set_real_output_in_tx_index(src.real_output_in_tx_index);
 | 
			
		||||
 | 
			
		||||
    if (client_version() <= 1) {
 | 
			
		||||
      for (auto &cur : src.real_out_additional_tx_keys) {
 | 
			
		||||
        dst->add_real_out_additional_tx_keys(key_to_string(cur));
 | 
			
		||||
      }
 | 
			
		||||
    } else if (!src.real_out_additional_tx_keys.empty()) {
 | 
			
		||||
    if (!src.real_out_additional_tx_keys.empty()) {
 | 
			
		||||
      dst->add_real_out_additional_tx_keys(key_to_string(src.real_out_additional_tx_keys.at(src.real_output_in_tx_index)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dst->set_amount(src.amount);
 | 
			
		||||
    dst->set_rct(src.rct);
 | 
			
		||||
    dst->set_mask(key_to_string(src.mask));
 | 
			
		||||
| 
						 | 
				
			
			@ -532,7 +511,7 @@ namespace tx {
 | 
			
		|||
 | 
			
		||||
    m_ct.tx.version = 2;
 | 
			
		||||
    m_ct.tx.unlock_time = tx.unlock_time;
 | 
			
		||||
    m_client_version = (m_aux_data->client_version ? m_aux_data->client_version.get() : 1);
 | 
			
		||||
    m_client_version = (m_aux_data->client_version ? m_aux_data->client_version.get() : 3);
 | 
			
		||||
 | 
			
		||||
    tsx_data.set_version(1);
 | 
			
		||||
    tsx_data.set_client_version(client_version());
 | 
			
		||||
| 
						 | 
				
			
			@ -543,18 +522,13 @@ namespace tx {
 | 
			
		|||
    tsx_data.set_monero_version(std::string(MONERO_VERSION) + "|" + MONERO_VERSION_TAG);
 | 
			
		||||
    tsx_data.set_hard_fork(m_aux_data->hard_fork ? m_aux_data->hard_fork.get() : 0);
 | 
			
		||||
 | 
			
		||||
    if (client_version() <= 1){
 | 
			
		||||
      assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Rsig decision
 | 
			
		||||
    auto rsig_data = tsx_data.mutable_rsig_data();
 | 
			
		||||
    m_ct.rsig_type = get_rsig_type(tx.rct_config, tx.splitted_dsts.size());
 | 
			
		||||
    rsig_data->set_rsig_type(m_ct.rsig_type);
 | 
			
		||||
    if (tx.rct_config.range_proof_type != rct::RangeProofBorromean){
 | 
			
		||||
      m_ct.bp_version = (m_aux_data->bp_version ? m_aux_data->bp_version.get() : 1);
 | 
			
		||||
      rsig_data->set_bp_version((uint32_t) m_ct.bp_version);
 | 
			
		||||
    }
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(tx.rct_config.range_proof_type != rct::RangeProofBorromean, "Borromean rsig not supported");
 | 
			
		||||
    m_ct.bp_version = (m_aux_data->bp_version ? m_aux_data->bp_version.get() : 1);
 | 
			
		||||
    rsig_data->set_bp_version((uint32_t) m_ct.bp_version);
 | 
			
		||||
 | 
			
		||||
    generate_rsig_batch_sizes(m_ct.grouping_vct, m_ct.rsig_type, tx.splitted_dsts.size());
 | 
			
		||||
    assign_to_repeatable(rsig_data->mutable_grouping(), m_ct.grouping_vct.begin(), m_ct.grouping_vct.end());
 | 
			
		||||
| 
						 | 
				
			
			@ -652,22 +626,6 @@ namespace tx {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::shared_ptr<messages::monero::MoneroTransactionInputsPermutationRequest> Signer::step_permutation(){
 | 
			
		||||
    sort_ki();
 | 
			
		||||
    if (client_version() >= 2){
 | 
			
		||||
      return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto res = std::make_shared<messages::monero::MoneroTransactionInputsPermutationRequest>();
 | 
			
		||||
    assign_to_repeatable(res->mutable_perm(), m_ct.source_permutation.begin(), m_ct.source_permutation.end());
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Signer::step_permutation_ack(std::shared_ptr<const messages::monero::MoneroTransactionInputsPermutationAck> ack){
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::shared_ptr<messages::monero::MoneroTransactionInputViniRequest> Signer::step_set_vini_input(size_t idx){
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_data.sources.size(), "Invalid transaction index");
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx.vin.size(), "Invalid transaction index");
 | 
			
		||||
| 
						 | 
				
			
			@ -711,8 +669,10 @@ namespace tx {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  void Signer::step_set_output_ack(std::shared_ptr<const messages::monero::MoneroTransactionSetOutputAck> ack){
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(is_req_bulletproof(), "Borromean rsig not supported");
 | 
			
		||||
    cryptonote::tx_out tx_out;
 | 
			
		||||
    rct::Bulletproof bproof{};
 | 
			
		||||
    rct::BulletproofPlus bproof_plus{};
 | 
			
		||||
    rct::ctkey out_pk{};
 | 
			
		||||
    rct::ecdhTuple ecdh{};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -727,7 +687,7 @@ namespace tx {
 | 
			
		|||
        rsig_buff = rsig_data.rsig();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client_version() >= 1 && rsig_data.has_mask()){
 | 
			
		||||
      if (rsig_data.has_mask()){
 | 
			
		||||
        rct::key cmask{};
 | 
			
		||||
        string_to_key(cmask, rsig_data.mask());
 | 
			
		||||
        m_ct.rsig_gamma.emplace_back(cmask);
 | 
			
		||||
| 
						 | 
				
			
			@ -751,22 +711,32 @@ namespace tx {
 | 
			
		|||
      memcpy(ecdh.amount.bytes, ack->ecdh_info().data(), 8);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (has_rsig && is_req_bulletproof() && !cn_deserialize(rsig_buff, bproof)){
 | 
			
		||||
      throw exc::ProtocolException("Cannot deserialize bulletproof rangesig");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_ct.tx.vout.emplace_back(tx_out);
 | 
			
		||||
    m_ct.tx_out_hmacs.push_back(ack->vouti_hmac());
 | 
			
		||||
    m_ct.tx_out_pk.emplace_back(out_pk);
 | 
			
		||||
    m_ct.tx_out_ecdh.emplace_back(ecdh);
 | 
			
		||||
 | 
			
		||||
    // ClientV0, if no rsig was generated on Trezor, do not continue.
 | 
			
		||||
    // ClientV1+ generates BP after all masks in the current batch are generated
 | 
			
		||||
    if (!has_rsig || (client_version() >= 1 && is_offloading())){
 | 
			
		||||
    rsig_v bp_obj{};
 | 
			
		||||
    if (has_rsig) {
 | 
			
		||||
      bool deserialize_success;
 | 
			
		||||
      if (is_req_bulletproof_plus()) {
 | 
			
		||||
        deserialize_success = cn_deserialize(rsig_buff, bproof_plus);
 | 
			
		||||
        bp_obj = bproof_plus;
 | 
			
		||||
      } else {
 | 
			
		||||
        deserialize_success = cn_deserialize(rsig_buff, bproof);
 | 
			
		||||
        bp_obj = bproof;
 | 
			
		||||
      }
 | 
			
		||||
      if (!deserialize_success) {
 | 
			
		||||
        throw exc::ProtocolException("Cannot deserialize bulletproof rangesig");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Generates BP after all masks in the current batch are generated
 | 
			
		||||
    if (!has_rsig || is_offloading()){
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    process_bproof(bproof);
 | 
			
		||||
    process_bproof(bp_obj);
 | 
			
		||||
    m_ct.cur_batch_idx += 1;
 | 
			
		||||
    m_ct.cur_output_in_batch_idx = 0;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -791,13 +761,21 @@ namespace tx {
 | 
			
		|||
      masks.push_back(m_ct.rsig_gamma[bidx]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto bp = bulletproof_PROVE(amounts, masks);
 | 
			
		||||
    auto serRsig = cn_serialize(bp);
 | 
			
		||||
    m_ct.tx_out_rsigs.emplace_back(bp);
 | 
			
		||||
    std::string serRsig;
 | 
			
		||||
    if (is_req_bulletproof_plus()) {
 | 
			
		||||
      auto bp = bulletproof_plus_PROVE(amounts, masks);
 | 
			
		||||
      serRsig = cn_serialize(bp);
 | 
			
		||||
      m_ct.tx_out_rsigs.emplace_back(bp);
 | 
			
		||||
    } else {
 | 
			
		||||
      auto bp = bulletproof_PROVE(amounts, masks);
 | 
			
		||||
      serRsig = cn_serialize(bp);
 | 
			
		||||
      m_ct.tx_out_rsigs.emplace_back(bp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rsig_data.set_rsig(serRsig);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Signer::process_bproof(rct::Bulletproof & bproof){
 | 
			
		||||
  void Signer::process_bproof(rsig_v & bproof){
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(m_ct.cur_batch_idx < m_ct.grouping_vct.size(), "Invalid batch index");
 | 
			
		||||
    auto batch_size = m_ct.grouping_vct[m_ct.cur_batch_idx];
 | 
			
		||||
    for (size_t i = 0; i < batch_size; ++i){
 | 
			
		||||
| 
						 | 
				
			
			@ -806,12 +784,22 @@ namespace tx {
 | 
			
		|||
 | 
			
		||||
      rct::key commitment = m_ct.tx_out_pk[bidx].mask;
 | 
			
		||||
      commitment = rct::scalarmultKey(commitment, rct::INV_EIGHT);
 | 
			
		||||
      bproof.V.push_back(commitment);
 | 
			
		||||
      if (is_req_bulletproof_plus()) {
 | 
			
		||||
        boost::get<rct::BulletproofPlus>(bproof).V.push_back(commitment);
 | 
			
		||||
      } else {
 | 
			
		||||
        boost::get<rct::Bulletproof>(bproof).V.push_back(commitment);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_ct.tx_out_rsigs.emplace_back(bproof);
 | 
			
		||||
    if (!rct::bulletproof_VERIFY(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs.back()))) {
 | 
			
		||||
      throw exc::ProtocolException("Returned range signature is invalid");
 | 
			
		||||
    if (is_req_bulletproof_plus()) {
 | 
			
		||||
      if (!rct::bulletproof_plus_VERIFY(boost::get<rct::BulletproofPlus>(m_ct.tx_out_rsigs.back()))) {
 | 
			
		||||
        throw exc::ProtocolException("Returned range signature is invalid");
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      if (!rct::bulletproof_VERIFY(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs.back()))) {
 | 
			
		||||
        throw exc::ProtocolException("Returned range signature is invalid");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -840,6 +828,7 @@ namespace tx {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  void Signer::step_all_outs_set_ack(std::shared_ptr<const messages::monero::MoneroTransactionAllOutSetAck> ack, hw::device &hwdev){
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(is_req_bulletproof(), "Borromean rsig not supported");
 | 
			
		||||
    m_ct.rv = std::make_shared<rct::rctSig>();
 | 
			
		||||
    m_ct.rv->txnFee = ack->rv().txn_fee();
 | 
			
		||||
    m_ct.rv->type = static_cast<uint8_t>(ack->rv().rv_type());
 | 
			
		||||
| 
						 | 
				
			
			@ -864,24 +853,15 @@ namespace tx {
 | 
			
		|||
 | 
			
		||||
    // RctSig
 | 
			
		||||
    auto num_sources = m_ct.tx_data.sources.size();
 | 
			
		||||
    if (is_simple() || is_req_bulletproof()){
 | 
			
		||||
      auto dst = &m_ct.rv->pseudoOuts;
 | 
			
		||||
      if (is_bulletproof()){
 | 
			
		||||
        dst = &m_ct.rv->p.pseudoOuts;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      dst->clear();
 | 
			
		||||
      for (const auto &pseudo_out : m_ct.pseudo_outs) {
 | 
			
		||||
        dst->emplace_back();
 | 
			
		||||
        string_to_key(dst->back(), pseudo_out);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      m_ct.rv->mixRing.resize(num_sources);
 | 
			
		||||
    } else {
 | 
			
		||||
      m_ct.rv->mixRing.resize(m_ct.tsx_data.mixin());
 | 
			
		||||
      m_ct.rv->mixRing[0].resize(num_sources);
 | 
			
		||||
    auto dst = &m_ct.rv->p.pseudoOuts;
 | 
			
		||||
    dst->clear();
 | 
			
		||||
    for (const auto &pseudo_out : m_ct.pseudo_outs) {
 | 
			
		||||
      dst->emplace_back();
 | 
			
		||||
      string_to_key(dst->back(), pseudo_out);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_ct.rv->mixRing.resize(num_sources);
 | 
			
		||||
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(m_ct.tx_out_pk.size() == m_ct.tx_out_ecdh.size(), "Invalid vector sizes");
 | 
			
		||||
    for(size_t i = 0; i < m_ct.tx_out_ecdh.size(); ++i){
 | 
			
		||||
      m_ct.rv->outPk.push_back(m_ct.tx_out_pk[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -889,10 +869,10 @@ namespace tx {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    for(size_t i = 0; i < m_ct.tx_out_rsigs.size(); ++i){
 | 
			
		||||
      if (is_bulletproof()){
 | 
			
		||||
        m_ct.rv->p.bulletproofs.push_back(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs[i]));
 | 
			
		||||
      if (is_req_bulletproof_plus()) {
 | 
			
		||||
        m_ct.rv->p.bulletproofs_plus.push_back(boost::get<rct::BulletproofPlus>(m_ct.tx_out_rsigs[i]));
 | 
			
		||||
      } else {
 | 
			
		||||
        m_ct.rv->p.rangeSigs.push_back(boost::get<rct::rangeSig>(m_ct.tx_out_rsigs[i]));
 | 
			
		||||
        m_ct.rv->p.bulletproofs.push_back(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs[i]));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -936,8 +916,8 @@ namespace tx {
 | 
			
		|||
  void Signer::step_sign_input_ack(std::shared_ptr<const messages::monero::MoneroTransactionSignInputAck> ack){
 | 
			
		||||
    m_ct.signatures.push_back(ack->signature());
 | 
			
		||||
 | 
			
		||||
    // Sync updated pseudo_outputs, client_version>=1, HF10+
 | 
			
		||||
    if (client_version() >= 1 && ack->has_pseudo_out()){
 | 
			
		||||
    // Sync updated pseudo_outputs
 | 
			
		||||
    if (ack->has_pseudo_out()){
 | 
			
		||||
      CHECK_AND_ASSERT_THROW_MES(m_ct.cur_input_idx < m_ct.pseudo_outs.size(), "Invalid pseudo-out index");
 | 
			
		||||
      m_ct.pseudo_outs[m_ct.cur_input_idx] = ack->pseudo_out();
 | 
			
		||||
      if (is_bulletproof()){
 | 
			
		||||
| 
						 | 
				
			
			@ -955,6 +935,8 @@ namespace tx {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  void Signer::step_final_ack(std::shared_ptr<const messages::monero::MoneroTransactionFinalAck> ack){
 | 
			
		||||
    CHECK_AND_ASSERT_THROW_MES(is_clsag(), "Only CLSAGs signatures are supported");
 | 
			
		||||
 | 
			
		||||
    if (m_multisig){
 | 
			
		||||
      auto & cout_key = ack->cout_key();
 | 
			
		||||
      for(auto & cur : m_ct.couts){
 | 
			
		||||
| 
						 | 
				
			
			@ -975,47 +957,34 @@ namespace tx {
 | 
			
		|||
    m_ct.enc_keys = ack->tx_enc_keys();
 | 
			
		||||
 | 
			
		||||
    // Opening the sealed signatures
 | 
			
		||||
    if (client_version() >= 3){
 | 
			
		||||
      if(!ack->has_opening_key()){
 | 
			
		||||
        throw exc::ProtocolException("Client version 3+ requires sealed signatures");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for(size_t i = 0; i < m_ct.signatures.size(); ++i){
 | 
			
		||||
        CHECK_AND_ASSERT_THROW_MES(m_ct.signatures[i].size() > crypto::chacha::TAG_SIZE, "Invalid signature size");
 | 
			
		||||
        std::string nonce = compute_sealing_key(ack->opening_key(), i, true);
 | 
			
		||||
        std::string key = compute_sealing_key(ack->opening_key(), i, false);
 | 
			
		||||
        size_t plen = m_ct.signatures[i].size() - crypto::chacha::TAG_SIZE;
 | 
			
		||||
        std::unique_ptr<uint8_t[]> plaintext(new uint8_t[plen]);
 | 
			
		||||
        uint8_t * buff = plaintext.get();
 | 
			
		||||
 | 
			
		||||
        protocol::crypto::chacha::decrypt(
 | 
			
		||||
            m_ct.signatures[i].data(),
 | 
			
		||||
            m_ct.signatures[i].size(),
 | 
			
		||||
            reinterpret_cast<const uint8_t *>(key.data()),
 | 
			
		||||
            reinterpret_cast<const uint8_t *>(nonce.data()),
 | 
			
		||||
            reinterpret_cast<char *>(buff), &plen);
 | 
			
		||||
        m_ct.signatures[i].assign(reinterpret_cast<const char *>(buff), plen);
 | 
			
		||||
      }
 | 
			
		||||
    if(!ack->has_opening_key()){
 | 
			
		||||
      throw exc::ProtocolException("Client version 3+ requires sealed signatures");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_ct.rv->type == rct::RCTTypeCLSAG){
 | 
			
		||||
      m_ct.rv->p.CLSAGs.reserve(m_ct.signatures.size());
 | 
			
		||||
      for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
 | 
			
		||||
        rct::clsag clsag;
 | 
			
		||||
        if (!cn_deserialize(m_ct.signatures[i], clsag)) {
 | 
			
		||||
          throw exc::ProtocolException("Cannot deserialize clsag[i]");
 | 
			
		||||
        }
 | 
			
		||||
        m_ct.rv->p.CLSAGs.push_back(clsag);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      m_ct.rv->p.MGs.reserve(m_ct.signatures.size());
 | 
			
		||||
      for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
 | 
			
		||||
        rct::mgSig mg;
 | 
			
		||||
        if (!cn_deserialize(m_ct.signatures[i], mg)) {
 | 
			
		||||
          throw exc::ProtocolException("Cannot deserialize mg[i]");
 | 
			
		||||
        }
 | 
			
		||||
        m_ct.rv->p.MGs.push_back(mg);
 | 
			
		||||
    for(size_t i = 0; i < m_ct.signatures.size(); ++i){
 | 
			
		||||
      CHECK_AND_ASSERT_THROW_MES(m_ct.signatures[i].size() > crypto::chacha::TAG_SIZE, "Invalid signature size");
 | 
			
		||||
      std::string nonce = compute_sealing_key(ack->opening_key(), i, true);
 | 
			
		||||
      std::string key = compute_sealing_key(ack->opening_key(), i, false);
 | 
			
		||||
      size_t plen = m_ct.signatures[i].size() - crypto::chacha::TAG_SIZE;
 | 
			
		||||
      std::unique_ptr<uint8_t[]> plaintext(new uint8_t[plen]);
 | 
			
		||||
      uint8_t * buff = plaintext.get();
 | 
			
		||||
 | 
			
		||||
      protocol::crypto::chacha::decrypt(
 | 
			
		||||
          m_ct.signatures[i].data(),
 | 
			
		||||
          m_ct.signatures[i].size(),
 | 
			
		||||
          reinterpret_cast<const uint8_t *>(key.data()),
 | 
			
		||||
          reinterpret_cast<const uint8_t *>(nonce.data()),
 | 
			
		||||
          reinterpret_cast<char *>(buff), &plen);
 | 
			
		||||
      m_ct.signatures[i].assign(reinterpret_cast<const char *>(buff), plen);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_ct.rv->p.CLSAGs.reserve(m_ct.signatures.size());
 | 
			
		||||
    for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
 | 
			
		||||
      rct::clsag clsag;
 | 
			
		||||
      if (!cn_deserialize(m_ct.signatures[i], clsag)) {
 | 
			
		||||
        throw exc::ProtocolException("Cannot deserialize clsag[i]");
 | 
			
		||||
      }
 | 
			
		||||
      m_ct.rv->p.CLSAGs.push_back(clsag);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_ct.tx.rct_signatures = *(m_ct.rv);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,8 +116,7 @@ namespace ki {
 | 
			
		|||
   */
 | 
			
		||||
  bool key_image_data(wallet_shim * wallet,
 | 
			
		||||
                      const std::vector<tools::wallet2::transfer_details> & transfers,
 | 
			
		||||
                      std::vector<MoneroTransferDetails> & res,
 | 
			
		||||
                      bool need_all_additionals=false);
 | 
			
		||||
                      std::vector<MoneroTransferDetails> & res);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Computes a hash over MoneroTransferDetails. Commitment used in the KI sync.
 | 
			
		||||
| 
						 | 
				
			
			@ -129,8 +128,7 @@ namespace ki {
 | 
			
		|||
   */
 | 
			
		||||
  void generate_commitment(std::vector<MoneroTransferDetails> & mtds,
 | 
			
		||||
                           const std::vector<tools::wallet2::transfer_details> & transfers,
 | 
			
		||||
                           std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req,
 | 
			
		||||
                           bool need_subaddr_indices=false);
 | 
			
		||||
                           std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Processes Live refresh step response, parses KI, checks the signature
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +164,7 @@ namespace tx {
 | 
			
		|||
  ::crypto::secret_key compute_enc_key(const ::crypto::secret_key & private_view_key, const std::string & aux, const std::string & salt);
 | 
			
		||||
  std::string compute_sealing_key(const std::string & master_key, size_t idx, bool is_iv=false);
 | 
			
		||||
 | 
			
		||||
  typedef boost::variant<rct::rangeSig, rct::Bulletproof> rsig_v;
 | 
			
		||||
  typedef boost::variant<rct::Bulletproof, rct::BulletproofPlus> rsig_v;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Transaction signer state holder.
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +245,7 @@ namespace tx {
 | 
			
		|||
    void compute_integrated_indices(TsxData * tsx_data);
 | 
			
		||||
    bool should_compute_bp_now() const;
 | 
			
		||||
    void compute_bproof(messages::monero::MoneroTransactionRsigData & rsig_data);
 | 
			
		||||
    void process_bproof(rct::Bulletproof & bproof);
 | 
			
		||||
    void process_bproof(rsig_v & bproof);
 | 
			
		||||
    void set_tx_input(MoneroTransactionSourceEntry * dst, size_t idx, bool need_ring_keys=false, bool need_ring_indices=false);
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
| 
						 | 
				
			
			@ -260,8 +258,6 @@ namespace tx {
 | 
			
		|||
    void step_set_input_ack(std::shared_ptr<const messages::monero::MoneroTransactionSetInputAck> ack);
 | 
			
		||||
 | 
			
		||||
    void sort_ki();
 | 
			
		||||
    std::shared_ptr<messages::monero::MoneroTransactionInputsPermutationRequest> step_permutation();
 | 
			
		||||
    void step_permutation_ack(std::shared_ptr<const messages::monero::MoneroTransactionInputsPermutationAck> ack);
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<messages::monero::MoneroTransactionInputViniRequest> step_set_vini_input(size_t idx);
 | 
			
		||||
    void step_set_vini_input_ack(std::shared_ptr<const messages::monero::MoneroTransactionInputViniAck> ack);
 | 
			
		||||
| 
						 | 
				
			
			@ -290,11 +286,15 @@ namespace tx {
 | 
			
		|||
      return m_client_version;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_simple() const {
 | 
			
		||||
    uint8_t get_rv_type() const {
 | 
			
		||||
      if (!m_ct.rv){
 | 
			
		||||
        throw std::invalid_argument("RV not initialized");
 | 
			
		||||
      }
 | 
			
		||||
      auto tp = m_ct.rv->type;
 | 
			
		||||
      return m_ct.rv->type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_simple() const {
 | 
			
		||||
      auto tp = get_rv_type();
 | 
			
		||||
      return tp == rct::RCTTypeSimple;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -302,12 +302,27 @@ namespace tx {
 | 
			
		|||
      return m_ct.tx_data.rct_config.range_proof_type != rct::RangeProofBorromean;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_req_clsag() const {
 | 
			
		||||
      return is_req_bulletproof() && m_ct.tx_data.rct_config.bp_version >= 3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_req_bulletproof_plus() const {
 | 
			
		||||
      return is_req_bulletproof() && m_ct.tx_data.rct_config.bp_version == 4;  // rct::genRctSimple
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_bulletproof() const {
 | 
			
		||||
      if (!m_ct.rv){
 | 
			
		||||
        throw std::invalid_argument("RV not initialized");
 | 
			
		||||
      }
 | 
			
		||||
      auto tp = m_ct.rv->type;
 | 
			
		||||
      return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2 || tp == rct::RCTTypeCLSAG;
 | 
			
		||||
      auto tp = get_rv_type();
 | 
			
		||||
      return rct::is_rct_bulletproof(tp) || rct::is_rct_bulletproof_plus(tp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_bulletproof_plus() const {
 | 
			
		||||
      auto tp = get_rv_type();
 | 
			
		||||
      return rct::is_rct_bulletproof_plus(tp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_clsag() const {
 | 
			
		||||
      auto tp = get_rv_type();
 | 
			
		||||
      return rct::is_rct_clsag(tp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool is_offloading() const {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -661,7 +661,7 @@ void block_tracker::process(const block* blk, const transaction * tx, size_t i)
 | 
			
		|||
  for (size_t j = 0; j < tx->vout.size(); ++j) {
 | 
			
		||||
    const tx_out &out = tx->vout[j];
 | 
			
		||||
 | 
			
		||||
    if (typeid(cryptonote::txout_to_key) != out.target.type()) { // out_to_key
 | 
			
		||||
    if (typeid(cryptonote::txout_to_key) != out.target.type() && typeid(cryptonote::txout_to_tagged_key) != out.target.type()) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,6 @@ namespace po = boost::program_options;
 | 
			
		|||
namespace
 | 
			
		||||
{
 | 
			
		||||
  const command_line::arg_descriptor<std::string> arg_filter                      = { "filter", "Regular expression filter for which tests to run" };
 | 
			
		||||
  const command_line::arg_descriptor<bool>        arg_generate_and_play_test_data = {"generate_and_play_test_data", ""};
 | 
			
		||||
  const command_line::arg_descriptor<std::string> arg_trezor_path                 = {"trezor_path", "Path to the trezor device to use, has to support debug link", ""};
 | 
			
		||||
  const command_line::arg_descriptor<bool>        arg_heavy_tests                 = {"heavy_tests", "Runs expensive tests (volume tests with real device)", false};
 | 
			
		||||
  const command_line::arg_descriptor<std::string> arg_chain_path                  = {"chain_path", "Path to the serialized blockchain, speeds up testing", ""};
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +137,7 @@ int main(int argc, char* argv[])
 | 
			
		|||
    hw::register_device(HW_TREZOR_NAME, ensure_trezor_test_device());  // shim device for call tracking
 | 
			
		||||
 | 
			
		||||
    // Bootstrapping common chain & accounts
 | 
			
		||||
    const uint8_t initial_hf =  (uint8_t)get_env_long("TEST_MIN_HF", 12);
 | 
			
		||||
    const uint8_t initial_hf =  (uint8_t)get_env_long("TEST_MIN_HF", HF_VERSION_CLSAG);
 | 
			
		||||
    const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", HF_VERSION_CLSAG);
 | 
			
		||||
    auto sync_test = get_env_long("TEST_KI_SYNC", 1);
 | 
			
		||||
    MINFO("Test versions " << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")");
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +161,10 @@ int main(int argc, char* argv[])
 | 
			
		|||
    // Transaction tests
 | 
			
		||||
    for(uint8_t hf=initial_hf; hf <= max_hf + 1; ++hf)
 | 
			
		||||
    {
 | 
			
		||||
      if (hf == 14) {  // HF 14 is skipped.
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (hf > initial_hf || hf > max_hf)
 | 
			
		||||
      {
 | 
			
		||||
        daemon->stop_and_deinit();
 | 
			
		||||
| 
						 | 
				
			
			@ -201,12 +204,14 @@ int main(int argc, char* argv[])
 | 
			
		|||
      TREZOR_COMMON_TEST_CASE(gen_trezor_4utxo_to_1norm_2sub, core, trezor_base);
 | 
			
		||||
      TREZOR_COMMON_TEST_CASE(gen_trezor_2utxo_sub_acc_to_1norm_2sub, core, trezor_base);
 | 
			
		||||
      TREZOR_COMMON_TEST_CASE(gen_trezor_4utxo_to_7outs, core, trezor_base);
 | 
			
		||||
      TREZOR_COMMON_TEST_CASE(gen_trezor_4utxo_to_15outs, core, trezor_base);
 | 
			
		||||
      TREZOR_COMMON_TEST_CASE(wallet_api_tests, core, trezor_base);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (trezor_base.heavy_tests())
 | 
			
		||||
    {
 | 
			
		||||
      TREZOR_COMMON_TEST_CASE(gen_trezor_many_utxo, core, trezor_base);
 | 
			
		||||
      TREZOR_COMMON_TEST_CASE(gen_trezor_many_utxo_many_txo, core, trezor_base);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    core->deinit();
 | 
			
		||||
| 
						 | 
				
			
			@ -555,7 +560,7 @@ static void expand_tsx(cryptonote::transaction &tx)
 | 
			
		|||
      rv.p.MGs[n].II[0] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (rv.type == rct::RCTTypeCLSAG)
 | 
			
		||||
  else if (rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
 | 
			
		||||
  {
 | 
			
		||||
    if (!tx.pruned)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1269,6 +1274,8 @@ void gen_trezor_base::set_hard_fork(uint8_t hf)
 | 
			
		|||
    rct_config({rct::RangeProofPaddedBulletproof, 2});
 | 
			
		||||
  } else if (hf == HF_VERSION_CLSAG){
 | 
			
		||||
    rct_config({rct::RangeProofPaddedBulletproof, 3});
 | 
			
		||||
  }  else if (hf == HF_VERSION_BULLETPROOF_PLUS){
 | 
			
		||||
    rct_config({rct::RangeProofPaddedBulletproof, 4});
 | 
			
		||||
  } else {
 | 
			
		||||
    throw std::runtime_error("Unsupported HF");
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1655,7 +1662,7 @@ bool gen_trezor_1utxo::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
           ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
           ->mixin(num_mixin())
 | 
			
		||||
           ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
           ->from(m_wl_alice.get(), 0)
 | 
			
		||||
           ->compute_sources(boost::none, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1671,7 +1678,7 @@ bool gen_trezor_1utxo_paymentid_short::generate(std::vector<test_event_entry>& e
 | 
			
		|||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  TREZOR_SKIP_IF_VERSION_LEQ(hw::trezor::pack_version(2, 0, 9));
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(boost::none, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1688,7 +1695,7 @@ bool gen_trezor_1utxo_paymentid_short_integrated::generate(std::vector<test_even
 | 
			
		|||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  TREZOR_SKIP_IF_VERSION_LEQ(hw::trezor::pack_version(2, 0, 9));
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(boost::none, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1705,7 +1712,7 @@ bool gen_trezor_4utxo::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1720,7 +1727,7 @@ bool gen_trezor_4utxo_acc1::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 1)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1735,7 +1742,7 @@ bool gen_trezor_4utxo_to_sub::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1750,7 +1757,7 @@ bool gen_trezor_4utxo_to_2sub::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1766,7 +1773,7 @@ bool gen_trezor_4utxo_to_1norm_2sub::generate(std::vector<test_event_entry>& eve
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1783,7 +1790,7 @@ bool gen_trezor_2utxo_sub_acc_to_1norm_2sub::generate(std::vector<test_event_ent
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources_to_sub_acc(2, MK_COINS(1) >> 2, -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1800,7 +1807,7 @@ bool gen_trezor_4utxo_to_7outs::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1817,11 +1824,39 @@ bool gen_trezor_4utxo_to_7outs::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
  TREZOR_TEST_SUFFIX();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool gen_trezor_4utxo_to_15outs::generate(std::vector<test_event_entry>& events)
 | 
			
		||||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(4, MK_COINS(1), -1, -1)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({1, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({2, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 2}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 3}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 4}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({1, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({2, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 2}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 3}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 4}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 4}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve.get(), false, 1000)
 | 
			
		||||
      ->rct_config(m_rct_config)
 | 
			
		||||
      ->build_tx();
 | 
			
		||||
 | 
			
		||||
  TREZOR_TEST_SUFFIX();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool gen_trezor_many_utxo::generate(std::vector<test_event_entry>& events)
 | 
			
		||||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(TREZOR_TEST_MIXIN)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(110, MK_COINS(1), -1, -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1832,6 +1867,35 @@ bool gen_trezor_many_utxo::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
  TREZOR_TEST_SUFFIX();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool gen_trezor_many_utxo_many_txo::generate(std::vector<test_event_entry>& events)
 | 
			
		||||
{
 | 
			
		||||
  TREZOR_TEST_PREFIX();
 | 
			
		||||
  t_builder->cur_height(num_blocks(events) - 1)
 | 
			
		||||
      ->mixin(num_mixin())
 | 
			
		||||
      ->fee(TREZOR_TEST_FEE)
 | 
			
		||||
      ->from(m_wl_alice.get(), 0)
 | 
			
		||||
      ->compute_sources(40, MK_COINS(1), -1, -1)
 | 
			
		||||
      ->add_destination(m_eve_account, false, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({1, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({2, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 2}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 3}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 4}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({1, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({2, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 1}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 2}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({0, 3}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({1, 4}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({2, 4}), true, 1000)
 | 
			
		||||
      ->add_destination(m_wl_eve->get_subaddress({3, 4}), true, 1000)
 | 
			
		||||
      ->rct_config(m_rct_config)
 | 
			
		||||
      ->build_tx();
 | 
			
		||||
 | 
			
		||||
  TREZOR_TEST_SUFFIX();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wallet_api_tests::init()
 | 
			
		||||
{
 | 
			
		||||
  m_wallet_dir = boost::filesystem::unique_path();
 | 
			
		||||
| 
						 | 
				
			
			@ -1873,7 +1937,7 @@ bool wallet_api_tests::generate(std::vector<test_event_entry>& events)
 | 
			
		|||
  Monero::PendingTransaction * transaction = w->createTransaction(recepient_address,
 | 
			
		||||
                                                                  "",
 | 
			
		||||
                                                                  MK_COINS(10),
 | 
			
		||||
                                                                  TREZOR_TEST_MIXIN,
 | 
			
		||||
                                                                  num_mixin(),
 | 
			
		||||
                                                                  Monero::PendingTransaction::Priority_Medium,
 | 
			
		||||
                                                                  0,
 | 
			
		||||
                                                                  std::set<uint32_t>{});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,9 @@
 | 
			
		|||
#include "../core_tests/wallet_tools.h"
 | 
			
		||||
 | 
			
		||||
#define TREZOR_TEST_FEE 90000000000
 | 
			
		||||
#define TREZOR_TEST_MIXIN 11
 | 
			
		||||
#define TREZOR_TEST_CLSAG_MIXIN 11
 | 
			
		||||
#define TREZOR_TEST_HF15_MIXIN 16
 | 
			
		||||
#define TREZOR_TEST_MIXIN TREZOR_TEST_CLSAG_MIXIN
 | 
			
		||||
 | 
			
		||||
/************************************************************************/
 | 
			
		||||
/*                                                                      */
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +95,7 @@ public:
 | 
			
		|||
  bool heavy_tests() const { return m_heavy_tests; }
 | 
			
		||||
  void rct_config(rct::RCTConfig rct_config) { m_rct_config = rct_config; }
 | 
			
		||||
  uint8_t cur_hf() const { return m_hard_forks.size() > 0 ? m_hard_forks.back().first : 0; }
 | 
			
		||||
  size_t num_mixin() const { return  m_top_hard_fork >= HF_VERSION_BULLETPROOF_PLUS ? TREZOR_TEST_HF15_MIXIN : TREZOR_TEST_CLSAG_MIXIN; }
 | 
			
		||||
  cryptonote::network_type nettype() const { return m_network_type; }
 | 
			
		||||
  std::shared_ptr<mock_daemon> daemon() const { return m_daemon; }
 | 
			
		||||
  void daemon(std::shared_ptr<mock_daemon> daemon){ m_daemon = std::move(daemon); }
 | 
			
		||||
| 
						 | 
				
			
			@ -306,12 +309,24 @@ public:
 | 
			
		|||
  bool generate(std::vector<test_event_entry>& events) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class gen_trezor_4utxo_to_15outs : public gen_trezor_base
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  bool generate(std::vector<test_event_entry>& events) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class gen_trezor_many_utxo : public gen_trezor_base
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  bool generate(std::vector<test_event_entry>& events) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class gen_trezor_many_utxo_many_txo : public gen_trezor_base
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  bool generate(std::vector<test_event_entry>& events) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Wallet::API tests
 | 
			
		||||
class wallet_api_tests : public gen_trezor_base
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue