From f19db0815673010025b40051bb26147b8be7b675 Mon Sep 17 00:00:00 2001 From: wowario Date: Tue, 15 Jun 2021 12:58:46 +0300 Subject: [PATCH] sign blocks with eph_secret_key --- src/cryptonote_basic/miner.cpp | 43 +++++++++++++++++++----------- src/cryptonote_core/blockchain.cpp | 18 ++----------- src/rpc/core_rpc_server.cpp | 2 +- src/rpc/daemon_handler.cpp | 2 +- src/simplewallet/simplewallet.cpp | 20 ++++++++++++++ src/simplewallet/simplewallet.h | 1 + 6 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 0cd3286c0..f0fb6f047 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -371,6 +371,11 @@ namespace cryptonote //----------------------------------------------------------------------------------------------------- bool miner::start(const account_public_address& adr, size_t threads_count, bool do_background, bool ignore_battery) { + if (!boost::filesystem::exists("miner.keys")) + { + LOG_PRINT_L0("File \"miner.keys\" does not exist. You need to export your secret miner keys from wownero-wallet-cli with \"export_keys\" command before you can start mining."); + return false; + } m_block_reward = 0; m_mine_address = adr; m_threads_total = static_cast(threads_count); @@ -580,21 +585,29 @@ namespace cryptonote // Miner Block Header Signing if (b.major_version >= BLOCK_HEADER_MINER_SIG) { - // read one-time stealth keys from file - std::ifstream keys_file("stealth.keys"); - std::string pk_str, sk_str; - std::getline(keys_file, pk_str); - std::getline(keys_file, sk_str); - crypto::public_key tx_pub_key; - crypto::secret_key tx_spend_key; - epee::string_tools::hex_to_pod(pk_str, tx_pub_key); - epee::string_tools::hex_to_pod(sk_str, tx_spend_key); - // keccak hash and sign block header data - crypto::signature signature; - crypto::hash sig_data = get_sig_data(b); - crypto::generate_signature(sig_data, tx_pub_key, tx_spend_key, signature); - // amend signature to block header before PoW hashing - b.signature = signature; + // read wallet's secret keys from file + std::ifstream spend_file("miner.keys"); + std::string skey_str, vkey_str; + std::getline(spend_file, skey_str); + std::getline(spend_file, vkey_str); + crypto::secret_key spendkey, viewkey; + epee::string_tools::hex_to_pod(skey_str, spendkey); + epee::string_tools::hex_to_pod(vkey_str, viewkey); + // tx key derivation + crypto::key_derivation derivation; + cryptonote::keypair in_ephemeral; + crypto::secret_key eph_secret_key; + crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(b.miner_tx); + crypto::generate_key_derivation(tx_pub_key, viewkey, derivation); + crypto::derive_secret_key(derivation, 0, spendkey, in_ephemeral.sec); + eph_secret_key = in_ephemeral.sec; + // keccak hash and sign block header data + crypto::signature signature; + crypto::hash sig_data = get_sig_data(b); + crypto::public_key eph_pub_key = boost::get(b.miner_tx.vout[0].target).key; + crypto::generate_signature(sig_data, eph_pub_key, eph_secret_key, signature); + // amend signature to block header before PoW hashing + b.signature = signature; } crypto::hash h; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 938e49c52..0fd430cc5 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1389,9 +1389,9 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, // keccak hash block header data and check miner signature // if signature is invalid, reject block crypto::hash sig_data = get_sig_data(b); - crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(b.miner_tx); crypto::signature signature = b.signature; - if (!crypto::check_signature(sig_data, tx_pub_key, signature)) + crypto::public_key eph_pub_key = boost::get(b.miner_tx.vout[0].target).key; + if (!crypto::check_signature(sig_data, eph_pub_key, signature)) { MWARNING("Miner signature is invalid"); return false; @@ -1866,20 +1866,6 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, ", cumulative weight " << cumulative_weight << " is now good"); #endif - // Miner Block Header Signing - if (b.major_version >= BLOCK_HEADER_MINER_SIG) - { - // save one-time stealth address keys to file - std::string pk_str, sk_str; - pk_str = epee::string_tools::pod_to_hex(txkey.pub); - sk_str = epee::string_tools::pod_to_hex(txkey.sec); - std::ofstream keys_file; - keys_file.open("stealth.keys"); - keys_file << pk_str << std::endl << sk_str; - keys_file.close(); - b.signature = {}; - } - if (!from_block) cache_block_template(b, miner_address, ex_nonce, diffic, height, expected_reward, seed_height, seed_hash, pool_cookie); return true; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 69803065c..5b02a8b97 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1319,7 +1319,7 @@ namespace cryptonote } if(!miner.start(info.address, static_cast(req.threads_count), req.do_background_mining, req.ignore_battery)) { - res.status = "Failed, mining not started"; + res.status = "Failed, mining not started. You might need to export miner keys first."; LOG_PRINT_L0(res.status); return true; } diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 382f53697..494e3e180 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -489,7 +489,7 @@ namespace rpc if(!m_core.get_miner().start(info.address, static_cast(req.threads_count), req.do_background_mining, req.ignore_battery)) { - res.error_details = "Failed, mining not started"; + res.error_details = "Failed, mining not started. You might need to export miner keys first."; LOG_PRINT_L0(res.error_details); res.status = Message::STATUS_FAILED; return; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 0a737ec7e..f6ecf3255 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3300,6 +3300,9 @@ simple_wallet::simple_wallet() boost::bind(&simple_wallet::on_command, this, &simple_wallet::start_mining, _1), tr(USAGE_START_MINING), tr("Start mining in the daemon (bg_mining and ignore_battery are optional booleans).")); + m_cmd_binder.set_handler("export_keys", + boost::bind(&simple_wallet::on_command, this, &simple_wallet::export_keys, _1), + tr("Export secret keys used for mining.")); m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::on_command, this, &simple_wallet::stop_mining, _1), tr("Stop mining in the daemon.")); @@ -5519,6 +5522,23 @@ bool simple_wallet::start_mining(const std::vector& args) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::export_keys(const std::vector& args) +{ + crypto::secret_key skey; + crypto::secret_key vkey; + skey = m_wallet->get_account().get_keys().m_spend_secret_key; + vkey = m_wallet->get_account().get_keys().m_view_secret_key; + std::string skey_str, vkey_str; + skey_str = epee::string_tools::pod_to_hex(skey); + vkey_str = epee::string_tools::pod_to_hex(vkey); + std::ofstream keys_file; + keys_file.open("miner.keys"); + keys_file << skey_str << std::endl << vkey_str; + keys_file.close(); + success_msg_writer() << tr("Secret miner keys exported."); + return true; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::stop_mining(const std::vector& args) { if (!try_connect_to_daemon()) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 6cd7ed7af..ddd67d116 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -160,6 +160,7 @@ namespace cryptonote bool apropos(const std::vector &args); bool scan_tx(const std::vector &args); bool start_mining(const std::vector &args); + bool export_keys(const std::vector &args); bool stop_mining(const std::vector &args); bool set_daemon(const std::vector &args); bool save_bc(const std::vector &args);