From 4e4430603ffffb9212b3b94586bcf298fa83c95f Mon Sep 17 00:00:00 2001 From: Dusan Klinec Date: Thu, 3 Sep 2020 16:07:08 +0200 Subject: [PATCH] enable CLSAG support for Trezor client --- src/device_trezor/trezor/protocol.cpp | 29 +++++++++++-------- src/wallet/wallet2.cpp | 2 +- tests/trezor/daemon.cpp | 2 +- tests/trezor/trezor_tests.cpp | 40 +++++++++++++++++++++------ 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp index 25c3d816d..288f3ddca 100644 --- a/src/device_trezor/trezor/protocol.cpp +++ b/src/device_trezor/trezor/protocol.cpp @@ -561,11 +561,6 @@ namespace tx { assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end()); } - // TODO: use HF_VERSION_CLSAG after CLSAG is merged - if (tsx_data.hard_fork() >= 13){ - throw exc::ProtocolException("CLSAG is not yet implemented"); - } - // Rsig decision auto rsig_data = tsx_data.mutable_rsig_data(); m_ct.rsig_type = get_rsig_type(tx.rct_config, tx.splitted_dsts.size()); @@ -1017,14 +1012,24 @@ namespace tx { } } - // CLSAG support comes here once it is merged to the Monero - 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]"); + 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); } - m_ct.rv->p.MGs.push_back(mg); } m_ct.tx.rct_signatures = *(m_ct.rv); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 918b3fd41..359a12bc7 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -10682,7 +10682,7 @@ void wallet2::cold_sign_tx(const std::vector& ptx_vector, signed_tx_ hw::wallet_shim wallet_shim; setup_shim(&wallet_shim, this); aux_data.tx_recipients = dsts_info; - aux_data.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1; + aux_data.bp_version = (use_fork_rules(HF_VERSION_CLSAG, -10) ? 3 : use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1); aux_data.hard_fork = get_current_hard_fork(); dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data); tx_device_aux = aux_data.tx_device_aux; diff --git a/tests/trezor/daemon.cpp b/tests/trezor/daemon.cpp index aba835ae2..dd9fd49ee 100644 --- a/tests/trezor/daemon.cpp +++ b/tests/trezor/daemon.cpp @@ -247,7 +247,7 @@ bool mock_daemon::run_main() if (m_start_zmq) { - if (!zmq_server.addTCPSocket("127.0.0.1", m_zmq_bind_port)) + if (!zmq_server.init_rpc("127.0.0.1", m_zmq_bind_port)) { MERROR("Failed to add TCP Socket (127.0.0.1:" << m_zmq_bind_port << ") to ZMQ RPC Server"); diff --git a/tests/trezor/trezor_tests.cpp b/tests/trezor/trezor_tests.cpp index 6a92868cf..972a588f3 100644 --- a/tests/trezor/trezor_tests.cpp +++ b/tests/trezor/trezor_tests.cpp @@ -139,7 +139,7 @@ int main(int argc, char* argv[]) // Bootstrapping common chain & accounts const uint8_t initial_hf = (uint8_t)get_env_long("TEST_MIN_HF", 12); - const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", 12); + 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 << ")"); MINFO("Testing hardforks [" << (int)initial_hf << ", " << (int)max_hf << "], sync-test: " << sync_test); @@ -546,7 +546,7 @@ static void expand_tsx(cryptonote::transaction &tx) for (size_t n = 0; n < tx.vin.size(); ++n) rv.p.MGs[0].II[n] = rct::ki2rct(boost::get(tx.vin[n]).k_image); } - else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG) + else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2) { CHECK_AND_ASSERT_THROW_MES(rv.p.MGs.size() == tx.vin.size(), "Bad MGs size"); for (size_t n = 0; n < tx.vin.size(); ++n) @@ -555,6 +555,21 @@ static void expand_tsx(cryptonote::transaction &tx) rv.p.MGs[n].II[0] = rct::ki2rct(boost::get(tx.vin[n]).k_image); } } + else if (rv.type == rct::RCTTypeCLSAG) + { + if (!tx.pruned) + { + CHECK_AND_ASSERT_THROW_MES(rv.p.CLSAGs.size() == tx.vin.size(), "Bad CLSAGs size"); + for (size_t n = 0; n < tx.vin.size(); ++n) + { + rv.p.CLSAGs[n].I = rct::ki2rct(boost::get(tx.vin[n]).k_image); + } + } + } + else + { + CHECK_AND_ASSERT_THROW_MES(false, "Unsupported rct tx type: " + boost::lexical_cast(rv.type)); + } } static std::vector vct_wallets(tools::wallet2* w1=nullptr, tools::wallet2* w2=nullptr, tools::wallet2* w3=nullptr, tools::wallet2* w4=nullptr, tools::wallet2* w5=nullptr) @@ -708,7 +723,9 @@ bool gen_trezor_base::generate(std::vector& events) std::vector block_weights; generate_genesis_block(blk_gen, get_config(m_network_type).GENESIS_TX, get_config(m_network_type).GENESIS_NONCE); events.push_back(blk_gen); - generator.add_block(blk_gen, 0, block_weights, 0); + uint64_t rew = 0; + cryptonote::get_block_reward(0, get_transaction_weight(blk_gen.miner_tx), 0, rew, 1); + generator.add_block(blk_gen, 0, block_weights, 0, rew); // First event has to be the genesis block m_bob_account.generate(); @@ -926,7 +943,7 @@ void gen_trezor_base::fix_hf(std::vector& events) // If current test requires higher hard-fork, move it up auto current_hf = m_hard_forks.back().first; CHECK_AND_ASSERT_THROW_MES(current_hf <= m_top_hard_fork, "Generated chain hardfork is higher than desired maximum"); - CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version != 2 || m_top_hard_fork >= 10, "Desired maximum is too low for BPv2"); + CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version < 2 || m_top_hard_fork >= 10, "Desired maximum is too low for BPv2"); for(;current_hf < m_top_hard_fork; current_hf+=1) { @@ -1014,9 +1031,10 @@ void gen_trezor_base::test_trezor_tx(std::vector& events, std: setup_shim(&wallet_shim); aux_data.tx_recipients = dsts_info; aux_data.bp_version = m_rct_config.bp_version; + aux_data.hard_fork = m_top_hard_fork; dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data); - MDEBUG("Signed tx data from hw: " << exported_txs.ptx.size() << " transactions"); + MDEBUG("Signed tx data from hw: " << exported_txs.ptx.size() << " transactions, hf: " << (int)m_top_hard_fork << ", bpv: " << m_rct_config.bp_version); CHECK_AND_ASSERT_THROW_MES(exported_txs.ptx.size() == ptxs.size(), "Invalid transaction sizes"); for (size_t i = 0; i < exported_txs.ptx.size(); ++i){ @@ -1245,10 +1263,14 @@ void gen_trezor_base::set_hard_fork(uint8_t hf) m_top_hard_fork = hf; if (hf < 9){ throw std::runtime_error("Minimal supported Hardfork is 9"); - } else if (hf == 9){ + } else if (hf <= 11){ rct_config({rct::RangeProofPaddedBulletproof, 1}); - } else { + } else if (hf == 12){ rct_config({rct::RangeProofPaddedBulletproof, 2}); + } else if (hf == HF_VERSION_CLSAG){ + rct_config({rct::RangeProofPaddedBulletproof, 3}); + } else { + throw std::runtime_error("Unsupported HF"); } } @@ -1844,7 +1866,7 @@ bool wallet_api_tests::generate(std::vector& events) CHECK_AND_ASSERT_THROW_MES(w->refresh(), "Refresh fail"); uint64_t balance = w->balance(0); MDEBUG("Balance: " << balance); - CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok"); + CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok, " << w->errorString()); auto addr = get_address(m_eve_account); auto recepient_address = cryptonote::get_account_address_as_str(m_network_type, false, addr); @@ -1855,7 +1877,7 @@ bool wallet_api_tests::generate(std::vector& events) Monero::PendingTransaction::Priority_Medium, 0, std::set{}); - CHECK_AND_ASSERT_THROW_MES(transaction->status() == Monero::PendingTransaction::Status_Ok, "Status nok"); + CHECK_AND_ASSERT_THROW_MES(transaction->status() == Monero::PendingTransaction::Status_Ok, "Status nok: " << transaction->status() << ", msg: " << transaction->errorString()); w->refresh(); CHECK_AND_ASSERT_THROW_MES(w->balance(0) == balance, "Err");